HC HCS 08
HC HCS 08
HC HCS 08
BIBLIOGRAFIA:
Microcontroladores HC908Q Teoria e prtica Editora Erica / Fbio Pereira Microcontroladores HCS08 Teoria e prtica Editora Erica / Fbio Pereira Apostila - HC_908.PDF Manual HC08DEBUGGERRM.PDF Manual MC68HC908QY4.PDF Manual MCS9S08QG8.PDF Manual CPU08RM.PDF Manual NITRON TECHNICAL DATA BOOK.PDF
MICROCONTROLADORES
Everywhere!
MICROCONTROLADORES ENCAPSULAMENTOS
MICROCONTROLADORES - CARACTERISTICAS
Memory
KBI 1.5K or 4K bytes of in-application re-programmable Flash 128 bytes of RAM
Peripherals
2-ch, 16-bit Timer with selectable IC, OC, or PWM Computer Operating Properly and LVI with selectable trip point Analog to Digital Converter (QT2/QT4/QY2/QY4 only) Keyboard Interrupts Up to 13 general purpose I/O and 1 input
128 RAM
LVI
Target Applications:
Discrete replacement, appliances, control systems, home and industrial security systems, fluorescent light ballasts, electromechanical replacement, consumer and appliances
Cria um novo projeto com auxilio do programa (recomendvel) Carrega exemplos de programas existentes
Carrega o tutorial do Code Warrior Inicia o programa normalmente sem nenhum auxilio.
Este o local onde ser gravado o projeto O caminho pode ser alterado pelo boto SET
Obs. Ainda no foi escolhido Familia de microcontroladores da FREESCALE Ao escolher click em avanar
Gravadores de microcontroladores
Microcontrolador escolhido
Click duas vezes em MAIN para aparecer a tela de CODIGO ASSEMBLY no lado direito
Nesta janela podemos trocar a funo de simulao para gravao. Os nossos gravadores so configurados em MON08INTERFACE
Para simular deixe em FULL CHIP SIMULATION Para gravar deixe em MON08INTERFACE
Esta janela informa em que linha o microcontrolador esta. Aqui voc v o seu programa original o qual foi escrito. Para acionar a simulao use o comando passo a passo
Esta janela mostra o resultado da simulao. se usar o passo a passo voc tem o resultado linha a linha, caso contrrio s ir ver o comando running. Ela tambm informa erros, d propostas de solues e podemos inserir comandos como por exemplo acionar uma chave ou ver uma sada energizada (pinos)
Nesta janela voc v o seu programa escrito anteriormente mas de maneira mais detalhada. Ele fornece o endereo do contador de programa (PC), os cdigos digitados e os dados ou endereos o qual foram as instrues
Nesta janela possvel ver todos os dados dentro da memria flash do microcontrolador desde 0000 a FFFF
Valores contidos no acumulador Valores contidos no Stack Pointer Registrador de Status, onde este informa como esta o microcontrolador em negrito. V =Indicador de estouro (+127 ou 128) H = Half Carry entre os bits 3 e 4 I = Interrupo habilitada N = Resultado negativo na operao Z = Resultado zero na operao C = Transporte ou emprestimo Carry/Borrow, onde ocorre operaes de soma acima de 255, resultados menores que zero e deslocamento / rotao
Registrador HX de 16 bits
Linhas de comentrios so importantes para lembrar do que foi programado. Isto necessrio pois esta linguagem abstrata. Para compilar e simular use os cones
A linha em AZUL MARINHO Informa que ser SIMULADA aps O comando STEP
MICROCONTROLADORES COMANDOS
Nestas pginas futuras estaremos mostrando alguns comandos importantes para a devida programao de um microcontrolador Maiores informaes consultem o manual CPU08RM.PDF e o livro Microcontroladores HC908Q Teoria e prtica Editora Erica / Fbio Pereira
REGRAS IMPORTANTES # = Indica valor decimal #$ = Indica valor hexadecimal #% = Indica valor binrio $ = Indica endereo
LDA Carrega um valor de imediato ou pela memria Ex. LDA #08 LDA #$08 LDA #%00001000 LDA $80 - Carregamento do numero 08 em decimal para o acumulador - Carregamento do numero 08 em hexadecimal para o acumulador - Carregamento do nmero 08 em binrio para o acumulador - Carregamento de um nmero contido na memria na posio $0080 para o acumulador
STA Carrega o valor do acumulador para a memria Ex. STA $80 - Carrega o valor contido no acumulador para a posio de memria 0080
MOV Movimenta um valor para a memria, e valores entre reas de memria Ex. MOV #02,$82 MOV $82, $80 - Movimenta o valor 02 decimal para a rea de memria $0082 - Copia o valor na rea de memria$ 0082 para $0080
MICROCONTROLADORES COMANDOS
Existe tambm a possibilidade de alterar somente um bit, como mostra abaixo com os comandos BSET e BCLR Exemplo: MOV #%00001111, $80 BCLR 0,$80 BSET 7,$80
COLOCANDO O NUMERO HEXA 0F NA POISO $80 DA RAM APAGANDO O BIT 0 DA MEMRIA $80 INCREMENTANDO O BIT 7 DA MEMRIA $80
Tambm possvel fazer na porta de sada do microcontrolador. Exemplo: BCLR 1, PTB BSET 6, PTB NO TER TENSO NO PINO 1 TER TENSO NO PINO 6
Para o apagamento total de um determinado endereo de memria usamos o CLR Exemplo: MOV #FF,$80 CLR $80 COLOCA O NUMERO FF EM HEXA NA MEMRIA $80 APAGA TODO CONTEDO COLOCADO NO ENDEREO $80
Tambm possvel fazer na porta de sada do microcontrolador. Exemplo: CLR PTA CLR PTB LIMPA TODA A PORTA A DO MICROCONTROLADOR LIMPA TODA A PORTA B DO MICROCONTROLADOR
MICROCONTROLADORES COMANDOS
Existe a possibilidade de fazer deslocamento de um determinado bit para a direita ou esquerda tanto na memria como no acumulador.
CARREGA 2 NO ACUMULADOR PROMOVE O DESLOCAMENTO DOS BITS PARA A ESQUERDA PROMOVE O DESLOCAMENTO DOS BITS PARA A DIREITA
Obs. Observamos que quando deslocamos para a esquerda, ocorre uma multiplicao do valor, enquanto que quando o deslocamento para direita ocorre uma diviso
No simulador do CODE WARRIOR existe a possibilidade de analisar os dados em vrias bases numricas. Faa a anlise do exemplo em HEXA, DECIMAL e BINRIO na interface do registrador. CLICK COM O BOTO DIREITO DO SEU MOUSE
MICROCONTROLADORES COMANDOS
O recurso de deslocamento pode ser feito tambm na rea de memria do microcontrolador Exemplo: MOV #$4,$80 LSL $80 LSL $80 LSR $80 LSR $80 CLR $80
CARREGA 4 EM HEXA NA RAM DE ENDEREO $80 PROMOVE O DESLOCAMENTO A ESQUERDA DO VALOR PROMOVE O DESLOCAMENTO A DIREITA DO VALOR LIMPA A POSIO $0080 DA RAM
MICROCONTROLADORES COMANDOS
Podemos fazer lgica AND e OR com os comando AND e ORA pelo carregamento direto ou valor contido na memria Exemplo LDA #$55 AND #$33 LDA #%11001100 ORA #%10100100 CARREGA 55 NO ACUMULADOR EM HEXA FAZ AND NO ACUMULADOR COM O VALOR IMEDIATO 33 EM HEXA CARREGA O VALOR CC EM HEXA OU 11001100 NO ACUMULADOR FAZ OR NO ACUMULADOR COM O VALOR A4 EM HEXA OU 10100100
Operaes matemticas tambm so possveis na programao assembly com os comandos ADD e SUB Exemplo MOV #$2,$80 LDA #$5 ADD $80 SUB #$3 ADD #$4 CARREGA 2 NA RAM CARREGA 5 NO ACUMULADOR SOMA A RAM COM O ACUMULADOR SUBTRAI IMEDIATAMENTE 3 DO ACUMULADOR SOMA 4 IMEDIATAMENTE COM O ACUMULADOR
O Code Warrior consegue facilitar a estrutura do programa como mostra abaixo Exemplo MOV #$2+5,$80 MOV #$3-2,$81 ;SOMA NA MEMORIA RAM 80 <2+5> ;SUBTRACAO NA MEMORIA 81 <3-2>
MICROCONTROLADORES COMANDOS
Multiplicaes e divises so tambm possveis com este microcontrolador usando os comandos MUL e DIV Devemos ficar ciente de que este microcontrolador no consegue fazer clculos com virgula Exemplo de multiplicao: LDA #$3 LDX #$2 MUL Exemplo de diviso: LDA #$6 LDX #$2 DIV CARREGA O NUMERO 3 EM HEXA NO ACUMULADOR CARREGA O NUMERO 2 EM HEXA NO REGISTRADOR DIVIDE O ACUMULADOR COM O REGISTRADOR CARREGA O NUMERO 3 EM HEXA NO ACUMULADOR CARREGA O NUMERO 2 EM HEXA NO REGISTRADOR MULTIPLICA O ACUMULADOR COM O REGISTRADOR O ACUMULADOR uma rea de trabalho do microcontrolador que esta sempre com novos valores a medida que o programa executado Por isso caso o valor seja Importante, este deve ser salvo na MEMRIA
Este tipo de construo de programa bsico para qualquer microcontrolador, onde os clculos so executados no no acumulador. O Code Warrior consegue simplificar calculos matemticos da seguinte forma Neste exemplo podemos ver soma, subtrao mutiplicao e diviso em uma nica linhas sendo executada dentro do acumulador LDA #((2*3)/(4-2))-1 CALCULO EXECUTADO NO ACUMULADOR
Uma caracteristica interessante neste componente a possibilidade de fazer os calculos diretamente na memria um recurso que poucos microcontroladores tem. MOV #2+((4*2)/2),$80 CALCULO EXECUTADO NO ENDEREO 0080 DA MEMRIA
ALGUNS COMANDOS PARA EXEMPLO CMP = Compara acumulador com a memria BEQ = Desvia se igual BNE = Desvia se diferente CBEQA = Compara o acumulador com um valor imediato e desvia caso seja igual BRSET = Desvia se o bit N estiver em 1 BRCLR = Desvia se o bit N estiver em 0
? S
PROCESSO: 1. 2. INICIO: LDA #$3 MOV #$3,$80 CMP $80 BEQ DESVIA BRA NAO_DESVIA DESVIA: MOV #$10,$88 BRA INICIO NAO_DESVIA: MOV #$5,$86 BRA INICIO COMPARAR - CMP DESVIAR - BEQ INICIO: LDA #$4 MOV #$3,$80 CMP $80 BEQ DESVIA BRA NAO_DESVIA DESVIA: MOV #$10,$88 BRA INICIO NAO_DESVIA: MOV #$5,$86 BRA INICIO
PROCESSO: 1. 2. INICIO: LDA #$4 MOV #$3,$80 CMP $80 BNE DESVIA BRA NAO_DESVIA DESVIA: MOV #$10,$88 BRA INICIO NAO_DESVIA: MOV #$5,$86 BRA INICIO COMPARAR - CMP DESVIAR - BNE INICIO: LDA #$3 MOV #$3,$80 CMP $80 BNE DESVIA BRA NAO_DESVIA DESVIA: MOV #$10,$88 BRA INICIO NAO_DESVIA: MOV #$5,$86 BRA INICIO
INICIO: LDA #$4 CBEQA #$4, DESVIA BRA NAO_DESVIA DESVIA: MOV #$10,$88 BRA INICIO NAO_DESVIA: MOV #$5,$86 BRA INICIO
INICIO: LDA #$3 CBEQA #4, DESVIA BRA NAO_DESVIA DESVIA: MOV #$10,$88 BRA INICIO NAO_DESVIA: MOV #$5,$86 BRA INICIO
INICIO: MOV #%00000100,$80 BRSET 2,$80, DESVIA BRA NAO_DESVIA DESVIA: MOV #$10,$88 BRA INICIO NAO_DESVIA: MOV #$5,$86 BRA INICIO
INICIO: MOV #%00000000,$80 BRSET 2,$80, DESVIA BRA NAO_DESVIA DESVIA: MOV #$10,$88 BRA INICIO NAO_DESVIA: MOV #$5,$86 BRA INICIO
INICIO: MOV #%11111011,$80 BRCLR 2,$80, DESVIA BRA NAO_DESVIA DESVIA: MOV #$10,$88 BRA INICIO NAO_DESVIA: MOV #$5,$86 BRA INICIO
INICIO: MOV #%11111111,$80 BRCLR 2,$80, DESVIA BRA NAO_DESVIA DESVIA: MOV #$10,$88 BRA INICIO NAO_DESVIA: MOV #$5,$86 BRA INICIO
MICROCONTROLADORES PORTAS
Nvel 0 em DDRB libera este buffer e temos a porta configurada como entrada. Nvel 1 em DDRB libera este buffer e temos a porta configurada como sada. Configuramos o PULL UP para garantir o nvel baixo na porta
PTB, pode enviar um nvel lgico para sada do microcontrolador ou receber um nvel e envi-lo para CPU
Para fazer a configurao da porta devemos usar o DDR antes de enviar um comando PT. DDRA, estaremos configurando a porta A do microcontrolador DDRB, estaremos configurando a porta B do microcontrolador PTA, estaremos enviando (1) ou recebendo (0) uma informao pela porta A PTB, estaremos enviando (1) ou recebendo (0) uma informao pela porta B
MICROCONTROLADORES PORTAS
Todos estes registradores so programveis por software, sendo este programados individualmente.
Nvel: 1 = Pull up Ativado 0 = Pull up Desativdado Obs. Quando o DDRB, for configurado como sada o PTBPUE desabilitado automticamente.
Nvel 1 = Porta configurada como sada. 0 = Porta configurada como entrada. Nvel para DDRB = 1 1 = Porta esta enviando 5V para o exterior 0 = Porta esta enviando 0V para o exterior Nvel para DDRB = 0 1 = Porta esta recebendo 5V para o exterior 0 = Porta esta recebendo 0V para o exterior
MICROCONTROLADORES PORTAS
MICROCONTROLADORES PORTAS
Este programa ir configurar as portas PTB 0 como entrada e PTB 1 a 7 como sadas. Ao acionar a chave observaremos os leds trocarem a sua iluminao. O comando BRSET fica testando a chave para poder tomar a devida deciso Nos DEMO 1 e 2, podemos acionar ou desativar as portas pelos comandos MOV, BSET e BCLR
BSET 0,CONFIG1 MOV #%11111110, DDRB MOV #$00, PTBPUE CLR PTB
BRSET 0,PTB,DEMO1 BRA DEMO2 MOV #$02, PTB BRA PRINCIPAL BSET 2 , PTB BCLR 1, PTB BRA PRINCIPAL
Tambm deve ser acionada a CHAVE do VISUALIZATION TOOLS para o correto funcionamento
PTB=1 PTA=1
Com o comando INPUTA=01, podemos perceber a chave vermelha levantar, o LED trocar de cor e pela memria, ver o estado das portas mudar.
O primeiro passo e sair do modo FULL CHIP SIMULATION para MON08 INTERFACE
MODO DE SIMULAO
MODO DE GRAVAO
Acione o comando REFRESH para limpeza total da porta Acione ADD CONECTION para selecionar a classe do dispositivo
Quando acionamos ADD CONECTION teremos a tela ao lado INTERFACE SELECTION onde devemos selecionar em Power Swiching CLASS 1 Uma vez configurado o resultado fica em INTERFACE DETAILS
Configure a porta COM e o BAUD RATE para que ocorra a transmisso do firmware Obs. Estes ajustes dependem do tipo do computador e do gravador.
Aps a tela anterior teremos esta abaixo, que tem a finalidade de monitorar o processo da gravao. Uma vez gravado o microcontrolador ela automaticamente desaparecer e o firmware estar residente no chip
Para ativar o cdigo criado pelo PROCESSADOR EXPERT devemos fazer os seguintes procedimentos
MICROCONTROLADORES HARDWARE
7448
CONFIGURAES
Desabilitar COP para no dar RESET na CPU Habilitar interrupo TOIE para informar que a temporizao terminou. Quando isto acontece TOF vai para 1 Ajustar o PREESCALER velocidade de contagem Usar TMODH e TMODL para colocar o valor de temporizao em hexa desejada no programa
CARREGAMENTO DO TIMER
O TEMPO ACABOU?
Caso o valor de TMODH e TMODL for igual ao contador interno de 16bit ($21 e $22) a temporizao termina.
S TOF fica em 1 ao terminar a temporizao, para APAGAR TOF E que ocorra uma nova devemos apaga-lo RETORNE PARA O CARREGAMENTO DO TIMER
DELAY:
S SAIR_DELAY: BCLR 7, TSC BRA TIMER APAGA TOF RETORNA AO CARREGAMENTO DO TIMER
CONFIGURAES
LED 1 ON?
CARREGAMENTO DO TIMER
PISCA PISCA
APAGAR LED 1 LIGAR LED 2 DELAY MANTENHA A CONTAGEM
O TEMPO ACABOU?
S ENTRADA DO DELAY
PISCA PISCA
LED1: MOV #%00000001, PTB BRA DELAY
DELAY:
INICIO: BSET 0,CONFIG1 MOV #%01000110,TSC MOV #%00000011, DDRB MOV #$00, PTBPUE CLR PTB MOV #$FF,TMODH MOV #$20,TMODL TIMER: BRA CONDICAO CONDICAO: BRSET 0,PTB,LED2 BRA LED1 LED1: MOV #%00000001, PTB BRA DELAY LED2: MOV #%00000010, PTB BRA DELAY
DELAY: BRCLR 7,TSC,DELAY BRSET 7,TSC, SAIR_DELAY SAIR_DELAY: BCLR 7, TSC BSET 4,TSC BRA TIMER
APS DIGITAR O PROGRAMA Localize a linha INCLUDE e abaixo dela adicione as duas linhas como Indicado. Isto far o tratamento da interrupo do TIMER
SUB-ROTINA
Em alguns casos observamos subrotinas chamarem outra sub-rotinas. Mas o que devemos saber que o retorno do programa sempre ser para um ponto a frente do seu inicio de partida.
SUB-ROTINA 1
SUB-ROTINA 2
JSR Efetua o desvio do fluxo do programa para uma sub-rotina. O JSR pode ser feito por endereo ou label. Ex. JSR $20 JSR SUB_ROTINA RTS Provoca o retorno do fluxo do programa ao ponto seguinte ao de onde ocorreu a chamada da sub-rotina
JSR SUB-ROTINA 1
SUB-ROTINA 1
SUB-ROTINA 2
RTS
O CAMINHO CRIADO PELOS COMANDOS JSR e RTS Pelo caminho azul, temos o primeiro salto para a sub-rotina. J o caminho em verde mostra o segundo salto para a sub-rotina Lembrando que podemos usar a mesma sub-rotina para diversas aplicaes, mas nada impede de usarmos sub-rotinas diferentes
CARREGAMENTO DOS REGISTRADORES TMODH E TMODL ACIONAMENTO DO LED 1 E DESVIA PARA DELAY
O TEMPO ACABOU? N S APAGAR TOF E RETORNE PARA A ULTIMA CHAMADA DE SUB ROTINA
INICIO BSET 0,CONFIG1 MOV #%01000110,TSC MOV #%00000011, DDRB MOV #$00, PTBPUE CLR PTB TIMER: MOV #$FF,TMODH MOV #$20,TMODL
PISCA: MOV #%00000001, PTB JSR DELAY MOV #%00000010, PTB JSR DELAY BRA PISCA
DELAY:
N S
CHANNEL SELECT Responsvel para habilitar os pinos do HC para fazer a converso A/D ADC Conversor Analgico Digital de 8 bits ADC DATA REGISTER Local onde ficar registrado o valor Convertido em HEXADECIMAL CLOCK GENERATOR Responsvel pela velocidade de converso do ADC INTERRUPT LOGIC Ao termino da converso habilitada uma interrupo avisando que o dado esta no ADC DATA REGISTER
CONVERSO SIMPLES O conversor realiza apenas uma nica converso Aps o seu termino, ativa o flag COCO e fica aguardando o usurio iniciar nova converso CONVERSO CONTINUA Este inicia automaticamente uma nova converso aps o termino da outra. O registrador ADSCR informa o processo de Converso pelos flags COCO e AIEN COCO 0 = Converso no completada 1 = Converso completada AIEN 0 = Interrupo desabilitada 1 = Interrupo habilitada
ADICLK Neste registrador podemos controlar a velocidade de converso do conversor AD. Este pega o valor do clock do barramento e dividir de 1 a 16 vezes Os valores devem ser colocados nos flags ADV2, ADV1 e ADV0 do ADICLK respeitando a tabela ao lado
ADR Este registrador contm a informao do conversor AD que pode ser movimentado para a memria ou acumulador
EXEMPLO: - Configure um conversor AD utilizando a porta PTA 0 usando a converso continua e com a mxima velocidade de converso. RESPOSTA: MOV #%00100000,ADSCR MOV #%00000000,ADICLK
Converso em modo continuo Porta PTA0 como entrada para o conversor A/D Velocidade mxima de converso
Carregar no acumulador
INICIO
TESTE DO TECLADO
LINHAS DE PROGRAMA O problema deste fluxograma que este sempre estar gastando tempo testando o teclado, mesmo sem estar sendo usado.
LINHAS DE PROGRAMA
LINHAS DE PROGRAMA
- O programa roda livremente sem a rotina de teclado - Ao tocar no teclado o programa para imediatamente e vai para a rotina de Interrupo. - Ao termino da interrupo esta retorna a sua origem
INICIO
LINHAS DE PROGRAMA
LINHAS DE PROGRAMA
TESTE DO TECLADO
LINHAS DE PROGRAMA
MODEK Flag de sensibilidade do teclado ACKK Bit de reconhecimento de teclado 0 = Sensibilidade a borda de descida 1 = Sensibilidade a borda de descida e nvel baixo
KBIER Registrador responsvel pela habilitao individual dos pinos que faro parte da entrada do mdulo KBI AWUIE Habilita a interrupo do mdulo auto acordar 0 = Interrupo desabilitada 1 = Interrupo habilitada KBIE0 a KBIE5 habilita os pinos PTA0 a PTA5 como entradas do mdulo KBI (interrupes) 0 = O pino no esta habilitado como interrupo 1 = O pino esta habilitado como interrupo
Ao fazer uma interrupo de teclado devemos fazer o tratamento do vetor de interrupo. Na tabela abaixo temos estes vetores. Cada interrupo em especifico (teclado, conversor ADC, TIM e outro), possui sua prioridade. A interrupo ir lanar para estes endereos, onde por atravs de um tratamento ORG ou ajustando o PROJECT.PRM em PROJECT SETTINGS- LINKER FILES na tela a esquerda FILE
Estes tratamentos por ORG ou alterando o PROJECT.PRM, e Incluindo um LABEL, nada mais do que orientanto o programa a Ter um fluxo organizado. Para terminar devemos sempre colocar um comando RTI para que o programa saia do tratamento da interrupo e volte ao programa principal
As interrupes tem prioridades e podemos ter vrias, mas sendo cada uma tratada por vez respeitanto a tabela de prioridades ao lado.
Programa principal Local onde esta acontecendo a interrupo Comando de retorno p/ o programa principal
Lembrando que o numero 14 retirado da tabela de vetores de interrupo. J o INTERRUPT o LABEL encontrado no arquivo MAIN, para o correto funcionamento
A diretiva ORG utilizada para especificar um endereo onde ocorre um evento a ser tratado logo em seguida por um label
FBD define uma constante de memria. O tamanho da memria a ser utilizada ser a constante a ser escolhida
Programa principal Local onde esta acontecendo a interrupo Comando de retorno p/ o programa principal
MICROCONTROLADORES LINGUAGEM C
#include <hidef.h> #include "derivative.h" int a,b,c,d; void main(void) { a=2; b=3; c=a+b; d=b-a;}
Quando declaramos as varveis antes de uma funo, esta fica considerada como global, onde esta ser aproveitada em todo momento do programa.
#include <hidef.h> #include "derivative.h" void main(void) { int a,b,c,d; a=2; b=3; c=a+b; d=b-a; inicio: if (c) goto inicio; }
Quando declaramos as varveis dentro de uma funo, esta fica considerada como local, onde esta ser aproveitada somente dentro da funo de origem.
TIPOS DE DADOS
TIPO signed char char int unsigned int unsigned long int long int float double long double
FAIXA DE VALORES -128 a 127 0 a 255 -32.768 a 32767 0 a 65.535 0 a 4.294.967.295 -2147483647 a 2147483647 1.17549e-38 a 3.40282e38 2.23e-308 a 1.7e308 2.23e-308 a 1.7e308
TAMANHO EM BYTES 1 1 2 2 4 4 4 8 8
TIPOS DE DADOS
#include <hidef.h> #include "derivative.h" signed char a,b; char c; int d,e; unsigned int f; unsigned long int i; long int j,k; float m,n; double q,r; long double s,t; void main(void) { //Estes so os valores mximos para as variveis declaradas acima //Caso ocorra alterao do valor para maior, teremos valores incorretos a=-128; b=127; c=255; d=-32768; e=32767; f=65535; i=4294967295; j=-2147483647; k=2147483647; m=1.17549e-38; n=3.40282e38; q=2.23e-308; r=1,7e308; s=2.23e-308; t=1.7e308; }
Escreva este programa no Code Warrior e confirme os valores das variveis. Logo em seguida altere o valor de algumas para maior do que permitido e veja o resultado.
TIPOS DE DADOS
No programa abaixo podemos analisar o comportamento dentro da memria do microcontrolador #include <hidef.h> /* for EnableInterrupts macro */ #include "derivative.h" /* include peripheral declarations */ char int long double memoria_80 memoria_81 memoria_83 memoria_88 @0x80; @0x81; @0x83; @0x88; // char // int // long // double - ocupa 1 byte de espao - ocupa 2 bytes de espao - ocupa 4 bytes de espao - ocupa 8 bytes de espao
void main(void) { inicio: memoria_80=5; //Carrega na memria memoria_81=6; //Carrega na memria memoria_83=7; //Carrega na memria memoria_88=8; //Carrega na memria __RESET_WATCHDOG(); goto inicio; } A funo do @ e o endereo logo em seguida, informa a varivel o inicio de seu armazenamento. O esquecimento no permitir a gravao na rea de memria desejada tornar-se- uma varivel local ou global. $80 $81 a $82 $83 a $86 $88 a $8F o valor 5 o valor 6 o valor 7 o valor 8
TIPOS DE DADOS
Podemos fazer programas e guardar informaes na memria
#include <hidef.h> /* for EnableInterrupts macro */ #include "derivative.h" /* include peripheral declarations */ char a @0x80; // Direciona a varivel a para a posio $80 char b @0x81; // Direciona a varivel b para a posio $81 char c @0x82; // Direciona a varivel c para a posio $82 void main(void) { inicio: a=2+1; // Salva o valor na memria $80 b=a*2; // Salva o valor na memria $81 c=b/3; // Salva o valor na memria $82 __RESET_WATCHDOG(); goto inicio; }
PONTEIROS
Ponteiro uma varivel que contm um endereo de memria. Esse endereo normalmente a posio de uma outra varivel de memria. Se uma varivel contm o endereo de uma outra, ento a primeira varivel dita apontar para a segunda.
O programa abaixo orienta que a varivel X comece a gravar os valores na memria de posio 88, logo em seguida verifica se a varivel X esta em 88 pelo ponteiro p1.
#include <hidef.h> /* for EnableInterrupts macro */ #include "derivative.h" /* include peripheral declarations */ char x @0x88; char *p; void main(void) { p=&x; } // Esta linha retorna o valor de endereo da varivel X // Orienta X estar no endereo 88 // Criao de um ponteiro *p
PONTEIROS
Os ponteiros podem ser orientados a determinadas posies para trabalharem. Caso o programador no definir eles comeam a trabalhar na posio 0x80 (Primeira posio da RAM). O programa abaixo orienta o uma varivel X a guardar suas constantes no endereo 88. O ponteiro foi criado para armazenar endereos solicitados na posio de memria A0. Ao executar este programa o nmero 1, ser colocado em $88, o ponteiro ser dirigido ao endereo $88 e ir resgatar o valor da memria $88 e salvar em $90
#include <hidef.h> /* for EnableInterrupts macro */ #include "derivative.h" /* include peripheral declarations */ char x @0x88; char s @0x90; char *p @0xA0; void main(void) { x=1; p=&x; s=*p; } // Constante 1 sendo gravada na posio de memria 88 // Posio de memria 88 colocada no ponteiro A0. // Valor contido na memria 88 da posio do ponteiro AO ser armazenado no endereo 90 // Orienta a varivel X a guardar os seus valores na posio 88 // Orienta a varivel S a guardar os seus valores na posio 90 // Orienta o ponteiro *p a guardar posies de memria no endereo A0
PONTEIROS
Os ponteiros so muito utilizados para apontar para uma rea de memria e descarregar o seu contedo em outro local. No programa abaixo foram declarada as variveis x,t,u e v. O ponteiro foi direcionado para a varivel x e ira descarregar todo o contedo serialmente na varivel s por um comando de incremento p++ do prprio ponteiro. Mas tome muito cuidado pois quando perdemos o controle do ponteiro o programa para de funcionar
#include <hidef.h> /* for EnableInterrupts macro */ #include "derivative.h" /* include peripheral declarations */ char x,t,u,v; char s @0x90; char *p @0xA0; void main(void) { x=1; t=2; u=3; v=4; p=&x; ponteiro_varredura: s=*p; p++; goto ponteiro_varredura; } PROGRAMA PARA HC908QY4 // Armazena os valores de x,t,u e v na varivel s. // Incrementa para a prxima varivel. // Inicializa o ponteiro pela varivel x
MATRIZES
Matriz uma coleo de variveis do mesmo tipo que referenciada por um nome comum. Em C todas as matrizes consistem em posies continuas na memria. O endereo mais baixo corresponde ao primeiro elemento e o mais alto ao ltimo elemento. Uma vez a matriz criada, podemos usar os valores em outras variveis criadas no programa. A leitura de uma matriz comea pelo zero como mostra o programa abaixo. O programa exemplo, ira carregar os valores da matriz nas variveis a,b,c e d.
#include <hidef.h> /* for EnableInterrupts macro */ #include "derivative.h" /* include peripheral declarations */ char matriz [4]={6,7,8,9}; char a,b,c,d; void main(void) { a= matriz [0]; b= matriz [1]; c= matriz [2]; d= matriz [3]; } // cada varivel armazena um valor da matriz // carrega uma matriz de uma dimenso com 4 valores
MATRIZES
Podemos fazer um carregamento automtico de valores em uma matriz, neste caso o carregamento sequncial como mostra o programa abaixo #include <hidef.h> /* for EnableInterrupts macro */ #include "derivative.h" /* include peripheral declarations */ char matriz [8]; char carga; void main(void) { for (carga=0;carga<8;carga++) matriz[carga]=carga; } // carrega de um em um a matriz 8X1
MATRIZES
Sabendo que podemos com uma matriz colocar diversos valores rapidamente em um programa sem ficar usando inmeras variveis, tambm podemos usar o recurso do ponteiro para trabalhar com estes dados. O programa abaixo constri uma matriz 4X1. Foi orientado um ponteiro para ler a matriz e descarregar todo o seu contedo no endereo de memria $88. Isto muito interessante para aplicaes que necessitamos lanar valores para as portas de um microcontrolador. #include <hidef.h> /* for EnableInterrupts macro */ #include "derivative.h" /* include peripheral declarations */ char matriz [4]={6,7,8,9}; char posiciona_ponteiro @0x80; char recebe_ponteiro @0x88; char *ponteiro @0xA0; void main(void) { posiciona_ponteiro=matriz[0]; ponteiro=&posiciona_ponteiro; ponteiro_varredura: recebe_ponteiro=*ponteiro; ponteiro++; goto ponteiro_varredura; } // o ponteiro descarrega os valores da matriz no endereo 88 // incrementa o ponteiro para o prximo valor da matriz //carrega a matriz do comeo // posiciona o ponteiro no inicio da matriz
1 IF
COMANDO
COMANDOS CONDICIONAIS - IF
#include <hidef.h> /* for EnableInterrupts macro */ #include "derivative.h" /* include peripheral declarations */ void main (void) { SOPT1=0; PTADD_PTADD0=0; PTBDD_PTBDD7=1; //desliga o COP //configura PTA0 como uma entrada //configura PTB7 como uma sada O comando IF s ativa quando estiver em nvel 1 caso contrrio este ser ignorado e o programa continuar na prxima linha.
inicio: if (PTAD_PTAD0) goto liga; //Verifica a condio da entrada PTA0 PTBD_PTBD7=0; //desativa a sada PTB7 goto inicio; liga: PTBD_PTBD7=1; goto inicio; } //ativa a sada PTB7
CASE (E1)
COMANDOS
BREAK
COMANDOS
BREAK
COMANDOS
Este comando permite a escolha de uma opo entre vrias variveis. Uma vez escolhida comparada a SWITCH com o devido CASE. Uma vez escolhido, os comandos contidos no CASE sero executados at a chegada do comando BREAK. Logo em seguida retorna novamente ao comando SWITCH para novo teste. Caso no exista nenhuma relao do SWITCH com os CASES disponveis o programa ir para o comando DEFAULT e executar um ou mais comandos determinado pelo programador
#include <hidef.h> /* for EnableInterrupts macro */ #include "derivative.h" /* include peripheral declarations */ char S; void main (void) { SOPT1=0; //desliga o cop PTADD=0; //configura todos os bits da PTA como entrada PTBDD=255; //configura todos os bits da PTB como sada inicio: S=PTAD; //transfere o valor de PTA para a varivel S switch(S) { //avalia o valor de S para o devido CASE case (1): PTBD_PTBD0=1;goto inicio;break; //ativa PTB0 case (2): PTBD_PTBD1=1;goto inicio;break; //ativa PTB1 case (3): PTBD_PTBD2=1;goto inicio;break; //ativa PTB2 case (4): PTBD_PTBD3=1;goto inicio;break; //ativa PTB3 case (5): PTBD_PTBD4=1;goto inicio;break; //ativa PTB4 case (6): PTBD_PTBD5=1;goto inicio;break; //ativa PTB5 case (7): PTBD_PTBD6=1;goto inicio;break; //ativa PTB6 case (8): PTBD_PTBD7=1;goto inicio;break; //ativa PTB7 default: PTBD=0;goto inicio; //desativa PTB } } CONCEITO DO PROGRAMA Neste programa a combinao de chaveamento em PTA ser convertido em um nmero decimal e carregada em uma varivel (S). Esta varivel ser analisada pelo comando SWITCH e logo em seguida comparada com um dos CASE possveis. Caso ocorra a igualdade o determinado comando ir funcionar. PROGRAMA PARA HCS908QG
INCREMENTO
COMANDO
INICIALIZAO = CONDIO
? S
#include <hidef.h> /* for EnableInterrupts macro */ #include "derivative.h" /* include peripheral declarations */ int S,T; void main (void) { SOPT1=0; //Desliga o COP PTADD=0; //Configura todos os bits da PTA como entrada PTBDD=255; //Configura todos os bits da PTB como sada inicio: S=T=PTAD*10000; //Transfere PTA para as variveis S,T e multiplica por 10000 for(0;S;S--) PTBD=255; //Porta PTB ativada for(0;T;T--) PTBD=0; //Porta PTB desativada goto inicio; }
Este programa faz as portas PTB oscilarem mediante informao contida em PTA. O valor recebido em PTA ser multiplicado por 10.000 e lanado nas variveis S e T o qual esto contidas no lao FOR. Referente a temporizao, observamos um DUTY CICLE de 50%. Este tipo de estrutura interessante, pois podemos alterar o DUTY CICLE e construir um PWM.
WHILE 1 COMANDO
O comando WHILE s ativa quando estiver em nvel 1 caso contrrio este ser ignorado e o programa continuar na prxima linha.
DO
COMANDO
1 WHILE 0
//Desliga o COP //Configura todos os bits da PTA como entrada //Configura todos os bits da PTB como sada
C e ASM
O Code Warrior pode fazer programas onde temos as duas linguagens, C e Assembler. Para isto devemos colocar a palavra reservada asm. Esta tecnologia chamada de HLI (High Level Inline). O programa abaixo executa uma equao de multiplicao e guarda o resultado na varivel S, como os calculos so feitos no acumulador, com um comando asm podemos salvar o seu contedo na memria 0x80. #include <hidef.h> /* for EnableInterrupts macro */ #include "derivative.h" /* include peripheral declarations */ char s,t; void MCU_init(void); /* Device initialization function declaration */ void main(void) { for(;;) { t=2; s=2*t; asm { sta $80 } __RESET_WATCHDOG(); /* feeds the dog */ } } IMPORTANTE: Caso escrevermos o cdigo assembler asm { sta $80 } linearmente sem respeitar as linhas puladas o Code Warrior considera errado, portanto devemos respeitar a estrutura do exemplo. PROGRAMA PARA HCS908QG FOR INFINITO um processo onde as linhas do programa ficam em loop infinito quando usamos a estrutura abaixo. FOR (; ;) { } O programa ao lado encontra-se desta maneira com explicado
DEFINE
Para deixar o programa mais inteligvel, podemos com o comando DEFINE, alterar o nome de alguns dados deixando assim o programa mais amigvel.
#include <hidef.h> /* for EnableInterrupts macro */ #include "derivative.h" /* include peripheral declarations */ #define CHAVE PTA_PTA0 #define LED PTB_PTB0 #define ENTRADA DDRA_DDRA0 #define SAIDA DDRB_DDRB0 void main(void) { ENTRADA=0; SAIDA=1; for(;;) { if(CHAVE) LED=1; //LIGA O LED else LED=0; //DESLIGA O LED __RESET_WATCHDOG(); /* feeds the dog */ } }
Neste programa trocamos a porta PTA0 que conhecida como PTA_PTA0 para ser chamada de CHAVE, logo a porta PTB0 que conhecida como PTB_PTB0 ser chamada de LED. Para a configurao da porta, chamaremos DDRA_DDRA0 como ENTRADA e DDRB_DDRB0 como SAIDA Desta maneira o programa principal ficar mais fcil de entender
FUNES
Quando necessitamos de um determinado sub programa, ou uma rotina especifica no programa principal, ns usamos funes na linguagem C. Em comparao com assembler, esta pode ser chamada de SUB ROTINA.
#include <hidef.h> /* for EnableInterrupts macro */ #include "derivative.h" /* include peripheral declarations */ #define CHAVE PTA_PTA0 #define LED PTB_PTB0 void configuracao () { DDRA_DDRA0=0; DDRB_DDRB0=1; } void main(void) { configuracao (); for(;;) { if(CHAVE) LED=1; //LIGA O LED else LED=0; //DESLIGA O LED __RESET_WATCHDOG(); /* feeds the dog */ } } PROGRAMA PARA HC908QY4 Quando simulamos o programa, este sempre comea pelo void main (void), mas quando ele v a funo configuracao () logo o programa d um salto para void configuracao () e a executa, e quando termina, este continua na linha que parou do programa principal
#include <hidef.h> /* for EnableInterrupts macro */ #include "derivative.h" /* include peripheral declarations */ #define LED PTB_PTB0 #define CHAVE PTA_PTA0 unsigned int a; void main(void) { CONFIG1_COPD=1; DDRA_DDRA0=0; DDRB_DDRB0=1; for (;;) { while (CHAVE) { for (a=60000;a>0;a--) LED=1; for (a=60000;a>0;a--) LED=0; }}}
#include <hidef.h> /* for EnableInterrupts macro */ #include "derivative.h" /* include peripheral declarations */ #define LED PTB_PTB0 #define CHAVE PTA_PTA0 void temporizar () { delay: if(!TSC_TOF) goto delay;} void interrupt 6 transbordo_do_timer () { TSC_TOF=0; TSC_TRST=1;} void main(void) { EnableInterrupts; CONFIG1_COPD=1; DDRA_DDRA0=0; DDRB_DDRB0=1; TMODH=0x18; TMODL=0x69; TSC=0x46; for(;;){ while(CHAVE) { LED=1; temporizar(); LED=0; temporizar(); }}}
HCS1
+5V 1 2 3 4 5 6 7 PTA5 PTA4 VDD+5 VSS/GND PTB7 PTB6 PTB5 PTB4 HCS908QG8 PTA0 PTA1 PTA2 PTA3 PTB0 PTB1 PTB2 PTB3 16 15 14 13 12 11 10 9
SW1
SW-SPST
R1
1k
R2
150
D1
LED
+5V
HCS1
+5V 1 2 3 4 5 +5V 6 7 8 +5V PTA5 PTA4 VDD+5 VSS/GND PTB7 PTB6 PTB5 PTB4 HCS908QG8 PTA0 PTA1 PTA2 PTA3 PTB0 PTB1 PTB2 PTB3 16 15 14 13 12 11 10 9 1 2 3 4 5 6 7 8
HCS2
PTA5 PTA4 VDD+5 VSS/GND PTB7 PTB6 PTB5 PTB4 HCS908QG8 PTA0 PTA1 PTA2 PTA3 PTB0 PTB1 PTB2 PTB3 16 15 14 13 12 11 10 9
R1
1k
R3
150
R2
150
CONEXO SERIAL
D1
LED
D2
LED
TRANSMISSO SERIAL - TX
#include <hidef.h> /* for EnableInterrupts macro */ #include "derivative.h" /* include peripheral declarations */ #define CHAVE PTBD_PTBD4 void interrupt 15 TX(void) { SCIS1_TDRE=0; //Desabilita a interrupo do TX da SCI } void main (void) { EnableInterrupts; SOPT1=0; // Watch dog desligado PTBDD_PTBDD4=0; //pino configurado como entrada SCIBD=26; //velocidade de 9600 - Velocidade(bps)=(BUSCLK)/(BR*16) - padro sem cristal => BUSCLK=4MHz SCIC2_TIE=0; //desabilitado a interrupo de transmisso de caracteres SCIC2_TE=1; //habilita o bit TE - faz o transmissor funcionar for (;;) { while(SCIS1_TDRE) //verificar buffer de transmisso se esta livre if (CHAVE==1) SCID=5; //carregando o buffer com o numero 5 para ser transmitido caso a chave esteja acionada else SCID=1; //carregando o buffer com o nmero 1 para ser transmitido caso a chave no esteja acionada. }}
TRANSMISSO SERIAL - RX
#include <hidef.h> /* for EnableInterrupts macro */ #include "derivative.h" /* include peripheral declarations */ #define LED1 PTBD_PTBD2 #define LED2 PTBD_PTBD3 unsigned char S,T; void interrupt 15 RX(void) { SCIS1_RDRF=0; //Desabilita a interrupo do RX da SCI while(!SCIS1_RDRF); //aguarda o buffer ficar vazio T=SCIS1; //leitura do registrador para apagar todos os indicadores existentes S=SCID; //leitura do contedo do SCID para complementar o apagamento e retirada do dado recebido if (S==5) //caso o valor da recepo seja o desejado ele altera a condio dos leds { LED1=1; LED2=0; } else { LED1=0; LED2=1; } } void main (void) { EnableInterrupts; SOPT1=0; // Watch dog desligado PTBDD_PTBDD2=1; //pino PTB2 configurado como sada PTBDD_PTBDD3=1; //pino PTB3 configurado como sada SCIBD=26; //velocidade de 9600 - Velocidade(bps)=(BUSCLK)/(BR*16) - padro sem cristal => BUSCLK=4MHz SCIC2_RIE=1; //habilitao da interrupo de recepo de caracteres SCIC2_RE=1; //habilita o bit RE - faz o receptor funcionar for(;;){ } } PROGRAMA PARA HCS908QG
ATIVIDADES
1. Em linguagem assembler crie um programa que execute: a) Carregar o acumulador diretamente com o valor 04H b) Armazenar o valor do acumulador na RAM ($0080) c) Carregar o registrador X com o valor 02H d) Armazenar o valor do registrador X na RAM ($0081) e) Armazenar o nmero 03H na RAM ($0088) f) Fazer um SHIFT RIGHT no acumulador, registrador e nas posies de memria ($0080 e $0081) g) Fazer um SHIFT LEFT no acumulador, registrador e nas posies de memria ($0080 e $0081) h) Somar imediatamente 02H no acumulador e subtrair com o valor contido em($0088) i) Limpar acumulador e registrador X. j) Transferir o valor de RAM ($0080) para o acumulador k) Transferir o valor de RAM ($0081) para o registrador X
2. Dada a equao implemente no HC908QY4 via software em: a. Linguagem assembler. b. Linguagem C
f ( x) =
2 ((5 + 3) (8 6)) (5 3)
ATIVIDADES
3. Dada a equao desenvolva um programa que use as variveis globais:
r=
a b c+d
4. Faa um programa usando as variveis int, char e float e propositalmente coloque valores acima do permitido e relate o que acontece com os dados.
5. Construa um programa em C onde podemos colocar valores numricos dentro da memria do HC908QY4 na seguinte ordem: a) char usar endereo $80 b) int usar endereo $81 c) long usar endereo $83 d) double usar endereo $88 Ao termino observe o espao que ocupam estas variveis dentro da rea de memria
6. Dada a equao abaixo monte um programa em C na seguinte ordem: a) As variveis a, b, c e d devem conter nmeros inteiros b) As variveis devem estar relacionadas nos seguintes endereos; a em $80, b em $82, c em $84 e d em $86. c) O resultado da equao deve estar salvo na memria $86
d=
a+b c2
ATIVIDADES
7. Usando a tcnica do ponteiro, coloque os nmeros 1,2,3,4 e 5 a partir do endereo de memria $80 e faa com que o contedo destes nmeros sejam deslocado para o endereo $88. 8. Construa uma matriz {0,1,2,3,4,5,6,7,8,9} e transfira o seu valor para as variveis na seguinte seqncia: a=0, b=1, c=2, d=3, e=4, f=5, g=6, h=7, i=8 e j=9. 9. Construa uma matriz {0,1,2,3,4,5,6,7,8,9} sendo que esta seja de preenchimento automtico via software. 10. Dada a matriz {0,1,2,3,4,5,6,7,8,9}, com um ponteiro, faa que ela seja descarregada na porta PTB do microcontrolador. 11. Com o HCS908QG8, faa um Hardware usando o PROTEUS onde os pinos PTB0 e PTB1 sejam considerado entradas onde recebero nveis lgicos da seguinte ordem: Nvel 1 = +5V Nvel 0 = 0V Obs. Para garantir 0V coloque um resistor de 1K nos pinos determinados, e que os mesmos fiquem em relao ao terra. Tambm deixem os PULL UPS desabilitados. Com os pinos PTB2 e PTB3 deixem-os como sada e ligue LEDs nestas portas. Mas ateno, pois um LED trabalha entre 1,5V a 2,0V por 20mA. Deve ser colocado um resistor de proteo, favor calcular e deixar os clculos para serem analisados pelo professor. Estes pinos devem trabalhar da seguinte forma: PTB2 = Ligado indica nvel 0 PTB3 = Ligado indica nvel 1 Desenvolva trs firmwares (em verso ASM e C) distintos onde promovam as lgicas AND, OR e EXOR gravem no HC908 e comprovem o seu funcionamento.
ATIVIDADES
12. Dado o circuito abaixo, os seguintes programas que respeitem a tabela abaixo
SW1 0 0 1 1 SW2 0 1 0 1 LED1 / LED2 Piscando as duas portas ao mesmo tempo em intervalo de 1 segundo Piscando as duas portas ao mesmo tempo em intervalo de 0,5 segundo Piscando as duas portas alternadamente em intervalo de 1 segundo Os dois leds ficaro permanentemente acessos sem piscar
a) O primeiro programa deve ser feito somente por software. b) O segundo programa deve ser feito usando o timer interno do HCS908QG8
HCS1
+5V 1 2 3 4 5 6 7 PTA5 PTA4 VDD+5 VSS/GND PTB7 PTB6 PTB5 PTB4 HCS908QG8 PTA0 PTA1 PTA2 PTA3 PTB0 PTB1 PTB2 PTB3 16 15 14 13 12 11 10 9 SW -SPST +5V
SW1
SW -SPST
SW2
R1
1k
R3
1k
R2
150
R4
150
D1
LED
D2
LED
ATIVIDADES
13. Dado o circuito abaixo faa um programa que respeite a tabela abaixo
+5V
SW1 0 0 1 1
SW2 0 1 0 1
HCS1
+5V 1 2 3 4 5 6 7 8 PTA5 PTA4 VDD+5 VSS/GND PTB7 PTB6 PTB5 PTB4 HCS908QG8 3 5 4 6 2 1 7 PTA0 PTA1 PTA2 PTA3 PTB0 PTB1 PTB2 PTB3 16 15 14 13 12 11 10 9
SW1
SW -SPST
SW2
SW -SPST
R8
1k
R9
1k
14 15 9 10 11 12 13
QG QF QE QD QC QB QA
LT RBI BI/RBO D C B A
R1
150
R2
150
R3
150
R4
150
R5
150
R6
150
R7
150