Departament de Microelectrònica i Sistemes Electrònics
AVR i FONAMENTS DE COMPUTADORS
Enginyeria en Informàtica (ETSE)
Transmissió amb USART per polling
El programa, en sí, té el següent funcionament:
- El PORTB es configura com a entrada i s'hi posarà la dada que es vol enviar
- Una interrupció INT0 per flanc de baixada (PORTD.2) indica al programa que es vol enviar la dada del PORTB.
- El pin de transmissió de dada TxD és el PORTD.1. Es configura com a sortida.
- Aleshores, el funcionament de la transmissió és molt simple. Davant una interrupció en INT0 la dada (PORTB) s'envia cap al buffer de transmissió, que només l'acceptarà si està buit per enviar una nova dada. Per això es s'ha de fer polling sobre el bit UDRE (Usart Data Register Empty).
Abans d'entrar a mirar el codi cal recordar que la seva mida no ha d'espantar. Sí, hi ha moltes línies, però moltes són comentaris. I les que no són comentaris estan agrupades en petites rutines fàcilment llegibles. Per tant, en sí, ...tampoc és tan llarg!
; Primer programa de comunicació
; Joan Oliver, desembre 2008
; INT0 captura el flanc de baixada d'un senyal extern...
; ...amb el que es carrega la dada present en el portB en la variable dada...
; ...que acta seguit es transmet pel port sèrie cap a l'hypertemirnal.INCLUDE "m8def.inc"
.DEF temp0 = R16 ;registre temporal
.DEF newtrans= R18 ;flag indicatiu de nova dada
.DEF dada = R19 ;registre per dada de transmissió
.DEF srri = R20 ;registre guarda SREG.CSEG
.ORG 0x000
rjmp main ;Servei interrupció inici
rjmp ext_int0 ;Servei interrupció timer0 per overflow
reti;*******************INICI PROGRAMA********************************
; Setup de ports d'E/S, UART i interrupcions externes
main:
ldi temp0,LOW(RAMEND) ;Setup del stack
out SPL,temp0
ldi temp0,HIGH(RAMEND)
out SPH,temp0;*******************INICIALITZACIONS****************************
ser temp0
out PORTB, temp0 ;Port B dades amb entrada pull-up
sbi DDRD, 1 ; D.1 sortida TxD; la resta entrades (D.2 interrupció externa)
ser temp0
out PORTD, temp0 ;sortides a 1 i entrades amb pull-uprcall setup_UART ;setup uart
rcall setup_EXT0 ;setup interrupció externa 0
sei ; Activació general d'interrupcions;-------PROGRAMA PRINCIPAL--------------------------------------------
bucle: cpi newtrans, 0
breq bucle ;si no hi ha interrupció esperem en bucle
ldi newtrans, 0
rcall transmit ;amb enviar a 1 es transmet pel port sèrie
rjmp bucle;;-------RUTINA DE SETUP DE LA UART------------------------------------
; a 4800 bauds i frame format: 8data,1stop bit
setup_UART:
ldi temp0,0
out UBRRH,temp0 ;baud rate a 4800
ldi temp0,12
out UBRRL,temp0
ldi temp0,(1<<TXEN) ;enable transmissió
out UCSRB,temp0
ldi temp0,(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0) ;frame format
out UCSRC,temp0
ret;-------RUTINA DE TRANSMISSIO-----------------------------------------
;Molt senzillament, aquesta rutina envia un byte cada cop que es crida
;No es pot enviar fins que el registre de trasmissió queda buit
transmit: sbis UCSRA, UDRE
rjmp transmit
out udr, dada
ret;-------RUTINA DE SETUP DE LA INTERRUPCIO EXT0-------------------
setup_EXT0:
ldi temp0, (1<<ISC01) ;ext0 per flanc baixada
out MCUCR, temp0
ldi temp0, (1<<INT0) ; Habilitació interrupcions externes
out GICR, temp0
ret;-------RUTINA DE SERVEI DE LA INT EXT0-------------------------------
;Rutina maneig interrupció externa 0
;Posa a 1 la variable enviar per a què es transmeti 'dada' en arribar a 'main'
;No convé fer-ho en la rutina de servei ja que aquesta pot estar transmetent
ext_int0:
in srri, SREG
in dada, PORTB
ldi newtrans, 1
out SREG, srri
reti