Die USART Library ist ein Port der Application Note AVR306 für den avr-gcc. Die Library verwendet Interrupts und hat je einen Buffer für Receive und Transmit.
Die Library ist bewusst einfach gehalten und unterstützt nur AVRs mit USART, nicht jedoch ältere mit einem UART. Es sollten alle Controller ab dem ATmega8 bzw dem ATtiny2313 funktionieren. Ältere Modelle wurden nicht berücksichtigt.
Die Library enthält nur vier Funktionen
void usart0_init( void );
Die Funktion usart0_init() initialisiert den USART mit der angegebenen Baudrate, 8 Datenbits, 1 Stopbit und keine Parität.
char usart0_getc( void );
Die Funktion usart0_getc() liefert ein Zeichen aus dem Receive Buffer. Ist der Buffer leer wartet die Funktion bis ein Zeichen empfangen wurde.
void usart0_putc( char data );
Die Funktion usart0_putc() schreibt ein Zeichen in den Transmit Buffer. Sollte der Buffer voll sein wartet die Funktion bis ein Zeichen frei ist.
char usart0_data_received( void );
Die Funktion usart0_data_received() fragt ab ob der Buffer Daten empfangen hat. Ist der Buffer leer liefert die Funktion 0 (False).
In der Datei config.h kann die Buffergröße für Receive und Transmit angegeben werden. Die Buffergrößte kann 2, 4, 8, 16, 32, 64, 128 oder 256 Byte groß sein.
Die Defines definieren verschiedene Werte, die für die Funktion der Library wichtig sind. Die Angaben in der usart.h sind nur Default Werte. Die Einstellungen für das Projekt sollten an anderer Stelle erfolgen. Wird kein Wert definiert wird eine Warnung ausgegeben.
#define BAUD 9600 //definiert die Bautrate für den USART. #define USART0_RX_BUFFER_SIZE 32 //definiert die größe des Empfangsbuffers. Die Buffergröße kann 2, 4, 8, 16, 32, 64, 128 oder 256 Byte groß sein. #define USART0_TX_BUFFER_SIZE 32 //definiert die größe des Sendebuffers. Die Buffergröße kann 2, 4, 8, 16, 32, 64, 128 oder 256 Byte groß sein.
Dieser Code kann direkt in die config.h übernommen und angepasst werden.
#include <avr/io.h> #include <avr/interrupt.h> #include "usart.h" int main(void) { usart0_init( ); sei(); usart0_putc('C'); for (;;); /* loop forever */ }
Mit der Utils Library kann man auch Strings senden
#include <avr/io.h> #include <avr/interrupt.h> #include "usart.h" #include "utils.h" int main(void) { usart0_init( ); sei(); write (usart0_putc, "Hello World!"); for (;;); /* loop forever */ }
Damit lange Strings nicht im RAM stehen kann man sie auch als Konstante im Flash ablegen.
#include <avr/io.h> #include <avr/pgmspace.h> #include <avr/interrupt.h> #include "usart.h" #include "utils.h" const char HelloWorld[] PROGMEM = "Hello World!"; int main(void) { usart0_init( ); sei(); write_p (usart0_putc, HelloWorld); for (;;) ; /* loop forever */ }
Das letzte Beispiel zeigt wie man die Funktion usart0_data_received() verwendet. Würde man die Funktion usart0_getc() aufrufen, ohne vorher abzufragen ob bereits Zeichen vorhanden sind, würde das Programm warten bis das erste Zeichen empfangen wurde. Erst dann könnte der Taster abgefragt werden. Dieses Beispiel befindet sich auch in den Downloads
#include <avr/io.h> #include <avr/interrupt.h> #include <avr/pgmspace.h> #include <utils.h> #include <usart.h> /* Define a constant char in the Flash */ const char HelloFlash[] PROGMEM = "Hello Flash!"; int main(void) { DDRB=(1<<PB0); /* Set PB0 as Output for LED1 */ PORTB=(1<<PB1); /* Enable internal pullup for TASTER1 */ usart0_init(); /* Init USART */ sei(); writeln_p(usart0_putc, HelloFlash); /* Send a String from the Flash through the USART */ for (;;) /* loop forever */ { if (usart0_data_received()) /* If Data in Buffer then */ usart0_putc(usart0_getc()); /* Echo chat to the UART */ LED1=~(TASTER1); } }
Das letzte Beispiel benötigt diese config.h.
/* * USART Defines */ #define BAUD 9600 //definiert die Bautrate für den USART. #define USART0_RX_BUFFER_SIZE 32 //definiert die größe des Empfangsbuffers. Die Buffergröße kann 2, 4, 8, 16, 32, 64, 128 oder 256 Byte groß sein. #define USART0_TX_BUFFER_SIZE 32 //definiert die größe des Sendebuffers. Die Buffergröße kann 2, 4, 8, 16, 32, 64, 128 oder 256 Byte groß sein. /* * Utils Defines */ #define LINE_END 0 //Definiert das Zeilenende von writeln() und writeln_p() #define LED1 BIT(PORTB,0) #define TASTER1 BIT(PINB,1)
— burli 2008/12/30 15:19
Diskussion