; **************************************************************************************** ; ; File: AVR_UART1.ASM * ; Data: 31.Mar.2004 * ; Version: 1.0 * ; IDE: AVR-Studio 4.0 * ; * ; Autore: Giuseppe Franco - giuseppe.franco@chilab.polito.it * ; Riferimenti: Politecnico di Torino - Laboratorio Materiali e Microsistemi * ; ; **************************************************************************************** ; Questo programma serve ad imparare come utilizzare la periferica ; integrata della seriale asincrona (UART), in particolare: ; ; --> come configurare i registri della periferica seriale. ; --> come inviare e ricevere caratteri con l'utilizzo dei flags di stato. ; ; **************************************************************************************** .NOLIST ;.INCLUDE "C:\programmi\atmel\avr tools\avrassembler\appnotes\8515def.inc" .INCLUDE "C:\usr\develop\atmel\avr tools\avrassembler\appnotes\8535def.inc" .LIST ; Definizione dei registri utilizzati .DEF mp = R16 .DEF char = R17 .DEF n1 = R18 .DEF n2 = R19 .EQU RED_LED = PC0 .EQU YELLOW_LED = PC1 .EQU GREEN_LED = PC2 .EQU XTAL_FREQ = 4000 ; frequenza del quarzo esterno in KHz .EQU BAUD = 9600 ; baud rate main: ; Viene impostato lo stack-pointer ed azzerato il registro di stato (tutti gli interrupt sono mascherati) ldi mp,HIGH(RAMEND) out SPH,mp ldi mp,LOW(RAMEND) out SPL,mp ldi mp,0x00 out SREG,mp ldi mp,0b00000111 out DDRC,mp ; Abilito la porta C in uscita sul bit 0,1 e 2 per pilotare tre led con ; il metodo di scrittura diretta sul pin della porta. ldi mp,0b00000010 out DDRD,mp ; Abilito la porta D sul bit 1 in uscita per avere la trasmissione ; sul pin quando avviene la scrittura nel registro della seriale. rcall delay ldi mp,(1 << RXEN) | (1 << TXEN) out UCR,mp ldi mp,( (XTAL_FREQ *1000 ) / ( 16 * BAUD ) - 1 ) out UBRR,mp ; Vengono impostati i registri di controllo della UART: in particolare ; sono abilitati il ricevitore ed il trasmettitore, e viene ; selezionato il baud-rate, che dipende dalla frequenza del quarzo esterno. ldi char, 'C' rcall PutChar ldi char, 'I' rcall PutChar ldi char, 'A' rcall PutChar ldi char, 'O' rcall PutChar ldi char, 13 rcall PutChar ldi char, 10 rcall PutChar main_loop: rcall GetChar ; Si verifica se un carattere è stato ricevuto. rcall PutChar ; Si genera l'echo del carattere ricevuto. rjmp main_loop ; Attende un carattere dalla seriale in polling: se nessun carattere arriva ; viene generato un loop infinito. In genere per evitare questo incoveniente ; si utilizza una routine sotto la gestione dell'interrupt, in modo da gestire ; gli arrivi dei caratteri in maniera asincrona, solo quando sono disponibili ; nel buffer di ricezione. GetChar: in mp, USR sbrs mp, RXC rjmp GetChar in char, UDR ret ; Invia un carattere, quando il buffer di trasmissione è vuoto; in caso contrario ; si attende in un loop infinito. PutChar: in mp, USR sbrs mp, UDRE rjmp PutChar out UDR, char ret ; complicatissima routine per generare un ritardo. delay: ldi n2,0xff delay_loop2: ldi n1,0xff delay_loop1: dec n1 brne delay_loop1 dec n2 brne delay_loop2 ret