You are on page 1of 35

EXEMPLOS DE USO DOS REGISTRADORES DO

MICROCONTROLADOR AT90S8515
Manipulao das entradas e sadas do microcontrolador
AT90S8515
1 - Programa que configura os pinos 0, 1, 2 e 3 do PORTB como sadas:
.equ PORTB = 0x18 ; substitui o endereo pelo nome (PORTB)
.equ DDRB = 0x17 ; substitui o endereo pelo nome (DDRB)
.def Aux = r16 ; renomeia r16 como Aux
ldi Aux, 0b00001111 ; Carrega valor 0x0F em Aux
Out DDRB, Aux ; Move valor de Aux para DDRB (PB0, PB1, P2 e PB3; so sadas)
VOLTA:
rjmp VOLTA ; Salta para VOLTA
2 - Programa que l os pinos do PORTD e escreve o valor no PORTB: 2 - Programa que l os pinos do PORTD e escreve o valor no PORTB:
.include "8515def.inc ; arquivo que contm informaes do AT90S8515
ldi r16, 0xFF ; Carrega valor 0xFF em r16
out DDRB, r16 ; Move valor de r16 para DDRB (PORTB sada)
VOLTA:
in r16, PIND ; Move o valor de PIND para r16
out PORTB, r16 ; Move o valor de r16 para o PORTB
rjmp VOLTA ; Salta para VOLTA
3 - Programa que l os pinos do PORTA e escreve o valor no PORTC:
.include "8515def.inc ; arquivo que contm informaes do AT90S8515
ldi r16, 0x00 ; Carrega valor 0x00 em r16
out DDRA, r16 ; Move valor de r16 para DDRA (PORTA entrada)
ldi r16, 0xFF ; Carrega valor 0xFF em r16
out DDRC, r16 ; Move valor de r16 para DDRC (PORTC sada)
VOLTA:
in r16, PINA ;Move o valor de PINA para r16
out PORTC, r16 ; Move o valor de r16 para o PORTC
rjmp VOLTA ; Salta para VOLTA
4 - Programa que configura os pinos 4, 5, 6 e 7 do PORTC como sadas e PORTD como entrada: 4 - Programa que configura os pinos 4, 5, 6 e 7 do PORTC como sadas e PORTD como entrada:
.equ PORTC = 0x15 ; substitui o endereo pelo nome (PORTC)
.equ DDRC = 0x14 ; substitui o endereo pelo nome (DDRC)
.def Aux = r16 ; renomeia r16 como Aux
ldi Aux, 0b11110000 ; Carrega valor 0xF0 em Aux
Out DDRC, Aux ; Move valor de Aux para DDRC (PC4, PC5, PC6 e PC7; so sadas)
ldi Aux, 0b00000000 ; Carrega valor 0x00 em Aux
out DDRD, r16 ; Move valor de Aux para DDRD (PORTD entrada)
VOLTA:
rjmp VOLTA ; Salta para VOLTA
5 - Programa que faz LEDs colocados no PORTB piscarem:
.include "8515def.inc ; arquivo que contm informaes do AT90S8515
.def Aux = r16 ; renomeia r16 como Aux
ldi Aux, 0xFF ; Carrega valor 0xFF em Aux
out DDRB, Aux ; Move valor de Aux para DDRB (PORTB sada)
VOLTA:
out PORTB, Aux ; Move valor de Aux para PORTB (LEDs)
com Aux ; Complementa o valor de Aux
DELAY:
dec r17 ; decrementa r17
brne DELAY ; pula para DELAY se Tempo1 for diferente de 0 brne DELAY ; pula para DELAY se Tempo1 for diferente de 0
dec r18 ; decrementa r18
brne DELAY ; pula para DELAY se Tempo2 for diferente de 0
rjmp VOLTA ; Salta para VOLTA
6 - Programa de demonstrao de acionamento de chaves e LEDs no STK-500:
.include "8515def.inc ; arquivo que contm informaes do AT90S8515
.def Temp = r16 ; renomeia r16 como Temp
.def Delay = r17 ; renomeia r17 como Delay
.def Delay2 = r18 ; renomeia r18 como Delay2
ser Temp ; seta todos os bits de Temp
out DDRB, Temp ; seta PORTB como sada
LOOP:
out PORTB, temp ; escreve o valor de temp no PORTB (LEDS) out PORTB, temp ; escreve o valor de temp no PORTB (LEDS)
sbis PIND, 0 ; pula a prxima instruo se o bit 0 do PIND (pino do PORTD) for1
inc Temp ; se for 0, incrementa temp
sbis PIND, 1 ; pula a prxima instruo se o bit 1 do PIND (pino do PORTD) for 1
dec Temp ; se for 0, decrementa temp
sbis PIND, 2 ; pula a prxima instruo se o bit 2 do PIND (pino do PORTD) for 1
ror Temp ; se for 0, desloca bits de temp para a direita
sbis PIND, 3 ; pula a prxima instruo se o bit 3 do PIND (pino do PORTD) for 1
rol Temp ; se for 0, desloca bits de temp para a esquerda
sbis PIND, 4 ; pula a prxima instruo se o bit 4 do PIND (pino do PORTD) for 1
com Temp ; se for 0, inverte os bits de temp
sbis PIND, 5 ; pula a prxima instruo se o bit 5 do PIND (pino do PORTD) for 1
neg Temp ; se for 0, faz o complemento de 2 de temp
sbis PIND, 6 ; pula a prxima instruo se o bit 5 do PIND (pino do PORTD) for 1
swap Temp ; se for 0, troca os nibbles de temp
DLY: ; rotina de delay
dec Delay ; decrementa varivel de delay
brne DLY ; pula para DLY se a varivel delay for diferente de 0 (Z=0)
dec Delay2 ; decrementa varivel de delay2
brne DLY ; pula para DLY se a varivel delay2 for diferente de 0 (Z=0)
rjmp LOOP ; pula para LOOP
manipulao do contador/temporizador 0 do
microcontrolador AT90S8515
1 - Programar o Contador/Temporizador 0 como contador de pulsos externos na transio de
descida em T0 (PB0) e mostrar o valor do contador em PORTC:
.include 8515def.inc
ldi r16, 0xFF ; carrega valor 0xFF em r16
out DDRC, r16 ; move valor 0xFF para DDRC (8 bits do PORTC como sadas)
ldi r16, 0x06 ; carrega valor 0x06 em r16
out TCCR0, r16 ; move valor 0x06 para TCCR0 (T0, transio de descida)
LOOP:
in r16, TCNT0 ; move valor do Contador/Temporizador 0 para r16
out PORTC, r16 ; move valor de r16 para PORTC
rjmp LOOP ; pula para LOOP
2 Idem, com transio de subida em T0 (PB0) e mostrar o valor do contador em PORTA:
.include 8515def.inc
ldi r17, 0xFF ; carrega valor 0xFF em r17
out DDRA, r17 ; move valor 0xFF para DDRA (8 bits do PORTA como sadas)
ldi r17, 0x07 ; carrega valor 0x07 em r17
out TCCR0, r17 ; move valor 0x07 para TCCR0 (T0, transio de subida)
LOOP:
in r17, TCNT0 ; move valor do Contador/Temporizador 0 para r17
out PORTA, r17 ; move valor de r17 para PORTA
rjmp LOOP ; pula para LOOP
3 - O programa abaixo gera um atraso de 1 segundo utilizando o Contador/Temporizador 0. A
frequncia do cristal 3,69 MHz. Usando a varredura do bit TOV0 (bit de overflow):
Este exemplo utiliza as seguintes caractersticas:
- Temporizao atravs da contagemde pulsos do oscilador (fosc = 3,69 MHz).
- Uso de sub-rotina.
A idia bsica fornecer uma frequncia conhecida e contar pulsos at que o tempo desejado
seja alcanado. O nmero de pulsos pode ser monitorado pelo flag de overflow do
Contador/Temporizador 0 (TOV0).
Temporizador
No caso do exemplo, temos os seguintes parmetros: No caso do exemplo, temos os seguintes parmetros:
Frequncia do cristal (sada do oscilador) = 3,69 MHz.
necessrio dividir a frequncia do oscilador para que possamos alcanar 1 segundo (diviso
por 1024 TCCR0 = 5)
Frequncia na entrada do Contador/Temporizador 0 = 3,69 MHz / 1024 = 3,6 kHz.
Perodo = 277, 5 s.
O Contador/Temporizador 0 pode contar valor de 0 a 255 at 256 valores. Depois disso
acontece o overflow (bit TOV0 colocado emUM) e o Contador/Temporizador 0 reiniciado.
O intervalo de tempo entre cada overflow do Contador/Temporizador 0 = 256 * 277,5 s = 71
ms (aproximadamente). Ou seja, a cada 71 ms ocorre o estouro do Contador/Temporizador 0.
O programa deve contar 14 overflows para ter 1 segundo.
Sub-rotinas
As sub-rotinas so trechos de cdigo chamados vrias vezes durante a execuo de um
programa. A sub-rotina chamada atravs da instruo rcall (por exemplo, rcall DELAY) e deve
existir, no fim da sub-rotina, a instruo ret (retorna para o endereo onde a sub-rotina foi
chamada).
O retorno para o endereo de onde a sub-rotina foi chamada s possvel se esse endereo
tiver sido salvo. A pilha o local na RAM onde o microcontrolador salva automaticamente o
endereo de retorno. O programador s precisa indicar onde comea a pilha. A figura abaixo
mostra a rea na RAM utilizada pela pilha.
rea da RAM utilizada pela pilha.
Os dados so empilhados a partir do ltimo endereo da RAM (RAMEND). Para o
microcontrolador 8515, o endereo RAMEND o ltimo endereo da RAM interna, ou seja,
0x25F.
Esse endereo armazenado em umregistrador chamado ponteiro de pilha (SP Stack Pointer),
que temcomo funo indicar umlocal disponvel na RAMpara armazenamento de dados.
SP
SPH (8 bits) SPL (8 bits)
Quando umdado colocado na pilha, o ponteiro de pilha SP decrementado. Quando umdado
retirado da pilha, o ponteiro de pilha SP incrementado.
Por exemplo, quando a instruo rcall DELAY executada, o endereo atual do programa
armazenado na RAM, no endereo indicado por SP. Depois disso, SP decrementado e o
programa vai para o novo endereo (DELAY).
Quando o programa encontra a instruo ret, a unidade de controle busca na pilha o endereo
de retorno. Assim, SP incrementado e o programa salta para o endereo salvo anteriormente
(dado retirado da pilha).
.include 8515def.inc
.def Aux = r16 ; renomeia r16 como Aux
.def Contador = r17 ; renomeia r17 como Contador
.def LEDS = r18 ; renomeia r18 como LEDS
ldi Aux, HIGH(RAMEND) ; definindo o fim da SRAM como incio da pilha
out SPH, Aux ; escreve endereo no ponteiro da pilha (parte alta)
ldi Aux, LOW(RAMEND)
out SPL, Aux ; escreve endereo no ponteiro da pilha (parte baixa)
ldi Aux, 0xFF ; carrega valor 0xFF em Aux ldi Aux, 0xFF ; carrega valor 0xFF em Aux
out DDRC, Aux ; move valor 0xFF para DDRC (todos bits do PORTC so sadas)
ldi r16, 0x05 ; carrega valor 0x05 em Aux
out TCCR0, r16 ; a frequncia do Timer/Counter0 ser CK / 1024 = 3,6 KHz
ldi Contador, 14 ; carrega Contador com valor 14 (contador de estouros)
VOLTA:
out PORTC, LEDS ; escreve valor de LEDS no PORTC
rcall DELAY ; chama sub-rotina DELAY
rjmp VOLTA ; pula para VOLTA
; Sub-rotina DELAY
DELAY:
in Aux, TIFR ; copia TIFR para Aux
sbrs Aux, TOV0 ; testa bit TOV0. Se for 1 salta a prxima instruo
rjmp FIM ; se o bit for 0 vai para o FIM
out TIFR, Aux ; escreve o valor UM no bit TOV 0 de TIFR para zerar o bit.
dec Contador ; decrementa contador de estouros do Timer/Counter0
brne FIM ; vai para FIM se no chegou a 0
ldi Contador, 14 ; carrega Contador com o valor 14
com LEDS ; complementa valor nos LEDS
FIM: ret ; retorno da sub-rotina DELAY FIM: ret ; retorno da sub-rotina DELAY
manipulao de interrupes do microcontrolador AT90S8515
Endereo Fonte de Interrupo
0x0000 Reset
0x0001 Interrupo Externa 0
0x0002 Interrupo Externa 1
... ...
0x0007 Overflow Contador/Temporizador 0
... ...
MCUCR
7 6 5 4 3 2 1 0
SRE SRW SE SM ISC11 ISC10 ISC01 ISC00
ISC01 ISC00 Evento em INT0
0 0 Nvel baixo
0 1 Reservado 0 1 Reservado
1 0 Borda de descida
1 1 Borda de subida
GIFR
7 6 5 4 3 2 1 0
INTF1 INTF0 - - - - - -
SREG
7 6 5 4 3 2 1 0
I T H S V N Z C
GIMSK
7 6 5 4 3 2 1 0
INT1 INT0 - - - - - -
TIMSK
7 6 5 4 3 2 1 0
TOIE1 OCIE1A OCIE1B - TICIE1 - TOIE0 -
1 - O programa abaixo rola os bits de r16 a cada transio de subida no pino INT0. Usando
interrupo:
.include 8515def.inc
.org 0
rjmp RESET
.org 1
rjmp INT_0
RESET:
ldi r16, high(RAMEND) ; definindo o fim da SRAM como incio da pilha
out SPH, r16 ; escreve endereo no ponteiro da pilha (parte alta)
ldi r16, low(RAMEND) ldi r16, low(RAMEND)
out SPL, r16 ; escreve endereo no ponteiro da pilha (parte baixa)
ldi r16, 0xFF ; carrega valor 0xFF em r16
out DDRC, r16 ; programa os bits do PORTC como sadas
ldi r16, 3 ; carrega valor 0x03 em r16
out MCUCR, r16 ; transio de subida em INT0
ldi r16, 0x40 ; carrega valor 0x40 em r16
out GIMSK, r16 ; habilita interrupo externa 0
ldi r16, 1 ; move valor 1 para r16
sei ; habilita interrupes (bit I em SREG setado)
VOLTA:
rjmp VOLTA ; pula para VOLTA (espera acontecer a interrupo)
; Sub-rotina de tratamento de interrupo externa 0
INT_0:
rol r16 ; rotaciona os bits de r16 para a esquerda
out PORTC, r16 ; move valor de r16 para o PORTC (LEDs)
reti ; retorno de interrupo
2 - O programa abaixo gera um atraso de 1 segundo utilizando o Contador/Temporizador 0. A
frequncia do cristal 3,69 MHz. Usando interrupo por Overflow do Contador/Temporizador
0:
; frequncia do cristal = 3,69 MHz
; frequncia do Contador/Temporizador 0 = 3,69 MHz / 1024 = 3,6 KHz Perodo = 277,5 s
; intervalo de tempo at o estouro do Contador/Temporizador 0 = 256 * 277,5 s = 71 ms
; nmero de estouros do Contador/Temporizador 0 durante 1 segundo 14
.include 8515def.inc
.def Aux = r16 ; renomeia r16 como Aux
.def Contador = r17 ; renomeia r17 como Contador
.def LEDS = r18 ; renomeia r18 como LEDS .def LEDS = r18 ; renomeia r18 como LEDS
.org 0
rjmp RESET
.org 7
rjmp TIMER0_OVF
RESET:
ldi Aux, HIGH(RAMEND) ; definindo o fim da SRAM como incio da pilha
out SPH, Aux ; escreve endereo no ponteiro da pilha (parte alta)
ldi Aux, LOW(RAMEND)
out SPL, Aux ; escreve endereo no ponteiro da pilha (parte baixa)
ldi Aux, 0xFF ; carrega valor 0xFF em Aux
out DDRC, Aux ; move valor 0xFF para DDRC (PORTC como sadas)
ldi r16, 0x05 ; carrega valor 0x05 em Aux
out TCCR0, r16 ; a frequncia do Timer/Counter0 ser CK / 1024 = 3,6 KHz
ldi Contador, 14 ; carrega Contador com valor 14 (contador de estouros)
ldi r16, 0x02 ; carrega valor 0x02 em r16
out TIMSK, r16 ; habilita interrupo por overflow do Contador/Temporizador 0
sei ; habilita interrupes (bit I em SREG setado) sei ; habilita interrupes (bit I em SREG setado)
VOLTA: rjmp VOLTA ; pula para VOLTA
; Sub-rotina de tratamento de interrupo por Overflow do Contador/Temporizador 0
TIMER0_OVF:
dec Contador ; decrementa contador de estouros do Contador/Temporizador 0
brne FIM ; vai para FIM se no chegou a 0
ldi Contador, 14 ; carrega Contador com o valor 14
com LEDS ; complementa valor nos LEDS
out PORTC, LEDS ; atualiza PORTC com o valor dos LEDS
FIM: reti ; retorno de interrupo
MANIPULAO DE DADOS NA FLASH E NA RAM DO 8515
Leitura
- Fornecer o endereo a ser acessado;
- Indicar a operao (leitura);
- Receber o dado lido.
Escrita
- Fornecer o endereo a ser acessado;
- Fornecer o dado a ser escrito;
-Indicar a operao (escrita). -Indicar a operao (escrita).
Constantes Armazenadas na Memria
FLASH
Dados armazenados na memria de
programa (FLASH) so gravados junto
com o programa e s podem ser lido
durante a execuo do programa. Os
valores constantes armazenados na
FLASH podem ser acessados utilizando-se
a instruo LPM(Load ProgramMemory).
Definir o endereo o endereo da FLASH a ser lido deve ser colocado em um registrador
especial de 16 bits chamado Z, combinao dos registradores r31:r30 (ZH:ZL). Cada endereo da
FLASH pode armazenar dados de 16 bits (2 bytes) e, por isso, um label (endereo) definido na
FLASH deve ser multiplicado por 2 para a localizao do dado a ser lido.
Executar a instruo LPM a instruo LPM busca o dado (byte) apontado por Z que est
armazenado na FLASH. O byte colocado no registrador r0.
A memria de programa (FLASH) organizada em palavras de 16 bits e a instruo de leitura da
FLASH (lpm) consegue manipular dados de 8 bits. Assim, para a leitura de constantes na FLASH
necessrio indicar o endereo do BYTE.
Cada endereo da FLASH pode armazenar 2 bytes. Por exemplo, o endereo 0 da FLASH pode
armazenar os bytes 0 e 1, o endereo 1 pode armazenar os bytes 2 e 3. Dessa forma, o endereo
TAB pode armazenar os bytes 2*TAB e 2*TAB+1. TAB pode armazenar os bytes 2*TAB e 2*TAB+1.
Ento, para a leitura de um byte da FLASH necessrio indicar o endereo desse byte
em Z (ponteiro para a FLASH) e executar a instruo lpm. O byte lido estar disponvel no
registrador r0.
1- Ler o contedo do endereo TAB da FLASH, conforme a tabela anterior:
ldi ZL, LOW(2*TAB) ; parte baixa do endereo do byte
ldi ZH, HIGH(2*TAB+1) ; parte alta do endereo do byte
lpm ; instruo de leitura da FLASH
; o dado lido est disponvel em r0
2 - O programa abaixo busca valores constantes na FLASH a cada 1 segundo (temporizao por
interrupo) e mostra no display de 7 segmentos colocado no PORTC:
.include "8515def.inc"
.def Aux = r16 ; renomeia r16 como Aux
.def Contador = r17 ; renomeia r17 como Contador
.def Numero = r18 ; renomeia r18 como numero
.cseg ;seguimento de cdigo
.org 0
rjmp INICIO
.org 7
rjmp TIMER0_OVF rjmp TIMER0_OVF
INICIO:
ldi Aux, HIGH(RAMEND) ; definindo o fim da SRAM como incio da pilha
out SPH, Aux ; escreve endereo no ponteiro da pilha (parte alta)
ldi Aux, LOW(RAMEND) ; definindo o fim da SRAM como incio da pilha
out SPL, Aux ; escreve endereo no ponteiro da pilha (parte baixa)
ldi Aux, 0xFF ; carrega valor 0xFF em Aux
out DDRC, Aux ; move valor 0xFF para DDRC (PORTC como sadas)
ldi r16, 0x05 ; carrega valor 0x05 em Aux
out TCCR0, r16 ; a frequncia do Timer/Counter0 ser CK / 1024 = 3,6 KHz
ldi Contador, 14 ; carrega Contador com valor 14 (contador de estouros)
ldi r16, 0x02 ; carrega valor 0x02 em r16
out TIMSK, r16 ; habilita interrupo por overflow do Timer/Counter0
ldi ZL, LOW(2*TABELA) ; carrega parte baixa do endereo de TABELA em ZL
ldi ZH, HIGH(2*TABELA) ; carrega parte alta do endereo de TABELA em ZH
ldi Numero, 0 ; carrega Numero com valor 0
sei ; habilita interrupes (bit I em SREG setado)
VOLTA:
rjmp VOLTA ; pula para VOLTA
; Sub-rotina de tratamento de interrupo por Overflow do Timer/Counter0
TIMER0_OVF: TIMER0_OVF:
dec Contador ; decrementa contador de estouros do Timer/Counter0
brne FIM ; vai para FIM se no chegou a 0
ldi Contador, 14 ; carrega Contador com o valor 14
lpm ; instruo para buscar na FLASH o dado apontado por Z
out PORTC, r0 ; atualiza PORTC com o valor da tabela indicado por numero
adiw ZL, 1 ; soma o valor 1 em ZL, se ocorrer vai um, ser somado em ZH
inc Numero ; incrementa numero
cpi Numero, 10 ; verifica se chegou a 10
brne FIM ; se no , vai para FIM
ldi Numero, 0 ; se sim, retorna a 0
ldi ZL, LOW(2*TABELA) ; carrega parte baixa do endereo de TABELA em ZL
ldi ZH, HIGH(2*TABELA) ; carrega parte alta do endereo de TABELA em ZH
FIM: reti ; retorno de interrupo
; Tabela de constantes na FLASH para o display de 7 segmentos.
TABELA: .db 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F
Dados Armazenados na RAM
O acesso aos dados da RAM feito atravs dos registradores X, Y ou Z. As instrues de leitura
ou carregamento LD ou as instrues de escrita ou armazenamento ST manipulam os
registradores X, Y e Z como ponteiros para a RAM.
Z Y X
ZH ZL YH YL XH XL
3 - Escrever o valor 0x53 no endereo 0x100 da RAM:
ldi XL, LOW(0x100) ; parte baixa do endereo do byte
ldi XH, HIGH(0x100) ; parte alta do endereo do byte
ldi r16, 0x53 ; carrega o valor 0x53 em r16
st X, r16 ; armazena o contedo de r16 no endereo apontado por X
4 - Ler o contedo do endereo 0x60 da RAM:
ldi YL, LOW(0x60) ; parte baixa do endereo do byte
ldi YH, HIGH(0x60) ; parte alta do endereo do byte
ld r17, Y ; l o contedo da RAM apontado por Y e armazena em Y
ZH ZL YH YL XH XL
r31 r30 r29 r28 r27 r26
5 - O programa abaixo busca valores constantes na FLASH e copia para a SRAM. A cada 1
segundo (temporizao por interrupo) um dado da SRAM mostrado no display de 7
segmentos colocado no PORTC:
.include "8515def.inc
.def Aux = r16 ; renomeia r16 como Aux
.def Contador = r17 ; renomeia r17 como Contador
.def numero = r18 ; renomeia r18 como numero
.dseg ; segmento de dados (RAM), usado para organizar a RAM
NUM: .BYTE 10 ; reserva 10 bytes na RAM a partir do endereo NUM
.cseg ; segmento de cdigo (FLASH) .cseg ; segmento de cdigo (FLASH)
.org 0
rjmp RESET
.org 7
rjmp TIMER0_OVF
RESET:
ldi Aux, HIGH(RAMEND) ; definindo o fim da SRAM como incio da pilha
out SPH, Aux ; escreve endereo no ponteiro da pilha (parte alta)
ldi Aux, LOW(RAMEND) ;
out SPL, Aux ; escreve endereo no ponteiro da pilha (parte baixa)
ldi Aux, 0xFF ; carrega valor 0xFF em Aux
out DDRC, Aux ; move valor 0xFF para DDRC (PORTC como sadas)
ldi r16, 0x05 ; carrega valor 0x05 em Aux
out TCCR0, r16 ; a frequncia do Timer/Counter0 ser CK / 1024 = 3,6 KHz
ldi Contador, 14 ; carrega Contador com valor 14 (contador de estouros)
ldi r16, 0x02 ; carrega valor 0x02 em r16
out TIMSK, r16 ; habilita interrupo por overflow do Timer/Counter0
ldi numero, 10 ; carrega numero com valor 10
ldi XL, LOW(NUM) ; carrega parte baixa do endereo de NUM em XL
ldi XH, HIGH(NUM) ; carrega parte alta do endereo de NUM em XH
ldi ZL, LOW(2*TABELA) ; carrega parte baixa do endereo de TABELA em ZL
ldi ZH, HIGH(2*TABELA) ; carrega parte alta do endereo de TABELA em Z
LOOP:
lpm ; instruo para buscar na FLASH o dado apontado por Z
st X+, r0 ;armazena dado de r0 no endereo da SRAM apontado por X e incrementa X
adiw ZL, 1 ; soma o valor 1 em ZL, se ocorrer vai um, ser somado em ZH
dec numero ; decrementa numero de dados
brne LOOP ; se no chegou a 0 volta
ldi numero, 10 ; carrega numero com o valor 10
ldi XL, LOW(NUM) ; carrega parte baixa do endereo de NUM em XL
ldi XH, HIGH(NUM) ; carrega parte alta do endereo de NUM em XH
sei ; habilita interrupes (bit I em SREG setado)
VOLTA:
rjmp VOLTA ; pula para VOLTA
; Sub-rotina de tratamento de interrupo por Overflow do Timer/Counter0
TIMER0_OVF:
dec Contador ; decrementa contador de estouros do Timer/Counter0
brne FIM ; vai para FIM se no chegou a 0
ldi Contador, 14 ; carrega contador com o valor 14 ldi Contador, 14 ; carrega contador com o valor 14
ld r0, X+ ; carrega em r0 um valor da SRAM apontado por X e incrementa X
out PORTC, r0 ; atualiza PORTC com o valor da SRAM
dec numero ; decrementa numero
brne FIM ; se no chegou a 0 vai para FIM
ldi numero, 10 ; carrega numero com valor 10
ldi XL, LOW(NUM) ; carrega parte baixa do endereo de NUM em XL
ldi XH, HIGH(NUM) ; carrega parte alta do endereo de NUM em XH
FIM: reti ; retorno de interrupo
; Tabela de constantes na FLASH
TABELA: .db 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F
COMUNICAO SERIAL NO 8515
Transmisso do caractere a (TTL e RS-232C)
Velocidade
status
configurao
Registrador de dados
1) (UBRR 16
clock
f
Rate Baud
+
=
Registrador de dados
Registrador de Baud Rate
UBRR
7 6 5 4 3 2 1 0
MSB LSB
Registrador de Dados
Registrador de Controle
- RXCIE: Bit que habilita a interrupo por recepo de dados;
- TXCIE: Bit que habilita a interrupo por transmisso de dados;
- UDRIE: Bit que habilita a interrupo quando o registrador de dados est vazio;
- RXEN: Bit que habilita o mdulo receptor da UART;
- TXEN: Bit que habilita o mdulo transmissor da UART;
- CHR9: Indica que so transmitidos ou recebidos 9 bits de dados;
- RXB8: Indica o 9 bit recebido;
UDR
7 6 5 4 3 2 1 0
MSB LSB
UCR
7 6 5 4 3 2 1 0
RXCIE TXCIE UDRIE RXEN TXEN CHR9 RXB8 TXB8
- RXB8: Indica o 9 bit recebido;
-TXB8: Indica o 9 bit a ser transmitido.
Registrador de Status
- RXC: Indica que um dado foi recebido;
- TXC: Indica que um dado foi transmitido;
- UDRE: Indica que um dado foi transferido para o registrador de deslocamento (UDR est
vazio);
- FE Framing Error: Indica que o Stop Bit foi amostrado como 0;
- OR Overrun: Indica que dados foram perdidos no UDR (sobreposio de dados).
USR
7 6 5 4 3 2 1 0
RXC TXC UDRE FE OR - - -
1 - O programa abaixo envia o caracter a pela serial a uma taxa de 9600 bps quando a chave
PA0 acionada. Qualquer caracter recebido pela serial mostrado no PORTC (usando
interrupo por recepo completa):
; Usar o PORTA como entrada nas CHAVES
; Usar o PORTC como sada nos LEDS
; Clculo de UBRR para a Taxa de Transmisso de 9600 bps
; BAUD RATE = fclock / (16*(UBRR + 1))
; UBRR = fclock / (16 * BAUD) 1 = 3690000 / (16 * 9600) 1 = 23
.include "8515def.inc
.org 0
rjmp INICIO rjmp INICIO
.org 9
rjmp UART_RXC
INICIO:
ldi r16, HIGH(RAMEND) ; definindo o fim da SRAM como incio da pilha
out SPH, r16 ; escreve endereo no ponteiro da pilha (parte alta)
ldi r16, LOW(RAMEND) ;
out SPL, r16 ; escreve endereo no ponteiro da pilha (parte baixa)
ldi r16, 0xFF ; carrega valor 0xFF em r16
out DDRC, r16 ; move valor 0xFF para DDRC (PORTC sada)
ldi r16, 23 ; carrega valor 23 para r16
out UBRR, r16 ; move valor 23 para UBRR => Taxa de Transmisso = 9600
ldi r16, 0b10011000 ; carrega valor 0x98 em r16
out UCR, r16 ; habilita interrupo por recepo completa
; e habilita transmissor e receptor serial (8 bits de dados)
sei ; habilita interrupes (bit I em SREG setado)
VOLTA:
sbis PINA, 0 ; pula a prxima instruo se o bit 0 (PA0) do PortA for 1
rcall TRANSMITE ; sub-rotina para transmisso serial
rjmp VOLTA ; pula para VOLTA
; Sub-rotina de transmisso serial ; Sub-rotina de transmisso serial
TRANSMITE:
ldi r16, 'a' ; carrega o caracter a em r16
out UDR, r16 ; envia r16
WAIT_TX:
in r16, USR ; l registrador de status
sbrs r16, 6 ; verifica se terminou de transmitir (TXC)
rjmp WAIT_TX ; se no, vai para WAIT_TX
out USR, r16 ; escreve 1 no bit de transmisso completa para zerar o bit
Ret ; retorno de sub-rotina
; Sub-rotina de tratamento de interrupo por Recepo completa
UART_RXC:
in r17, UDR ; l caracter recebido
out PORTC, r17 ; atualiza PORTC
reti ; retorno de interrupo

You might also like