1 | // AVR306: Using the AVR UART in C
|
2 | // Routines for polled USART
|
3 | // Last modified: 02-06-21
|
4 | // Modified by: AR
|
5 |
|
6 | /* Includes */
|
7 | #include <avr/io.h>
|
8 |
|
9 | /* Prototypes */
|
10 | void USART0_Init( unsigned int baudrate );
|
11 | unsigned char USART0_Receive( void );
|
12 | void USART0_Transmit( unsigned char data );
|
13 |
|
14 |
|
15 |
|
16 | #ifndef F_CPU
|
17 | /* In neueren Version der WinAVR/Mfile Makefile-Vorlage kann
|
18 | F_CPU im Makefile definiert werden, eine nochmalige Definition
|
19 | hier wuerde zu einer Compilerwarnung fuehren. Daher "Schutz" durch
|
20 | #ifndef/#endif
|
21 |
|
22 | Dieser "Schutz" kann zu Debugsessions führen, wenn AVRStudio
|
23 | verwendet wird und dort eine andere, nicht zur Hardware passende
|
24 | Taktrate eingestellt ist: Dann wird die folgende Definition
|
25 | nicht verwendet, sondern stattdessen der Defaultwert (8 MHz?)
|
26 | von AVRStudio - daher Ausgabe einer Warnung falls F_CPU
|
27 | noch nicht definiert: */
|
28 | #warning "F_CPU war noch nicht definiert, wird nun nachgeholt mit 4000000"
|
29 | #define F_CPU 4000000UL // Systemtakt in Hz - Definition als unsigned long beachten
|
30 | // Ohne ergeben sich unten Fehler in der Berechnung
|
31 | #endif
|
32 |
|
33 | #define BAUD 4800UL // Baudrate
|
34 |
|
35 | // Berechnungen
|
36 | #define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) // clever runden
|
37 | #define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1))) // Reale Baudrate
|
38 | #define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
|
39 |
|
40 | #if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
|
41 | #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch!
|
42 | #endif
|
43 |
|
44 |
|
45 |
|
46 | /* Main - a simple test program*/
|
47 | int main( void )
|
48 | {
|
49 | USART0_Init( UBRR_VAL ); /* Set the baudrate to 19,200 bps using a 3.6864MHz crystal */
|
50 |
|
51 | for(;;) /* Forever */
|
52 | {
|
53 |
|
54 | USART0_Transmit( USART0_Receive() ); /* Echo the received character */
|
55 | }
|
56 | }
|
57 |
|
58 | /* Initialize UART */
|
59 | void USART0_Init( unsigned int baudrate )
|
60 | {
|
61 | /* Set the baud rate */
|
62 | UBRR0H = (unsigned char) (baudrate>>8);
|
63 | UBRR0L = (unsigned char) baudrate;
|
64 |
|
65 | /* Enable UART receiver and transmitter */
|
66 | UCSR0B = ( ( 1 << RXEN0 ) | ( 1 << TXEN0 ) );
|
67 |
|
68 | /* Set frame format: 8 data 2stop */
|
69 | UCSR0C = (1<<USBS0)|(1<<UCSZ01)|(1<<UCSZ00); //For devices with Extended IO
|
70 | //UCSR0C = (1<<URSEL)|(1<<USBS0)|(1<<UCSZ01)|(1<<UCSZ00); //For devices without Extended IO
|
71 | }
|
72 |
|
73 |
|
74 | /* Read and write functions */
|
75 | unsigned char USART0_Receive( void )
|
76 | {
|
77 | /* Wait for incomming data */
|
78 | while ( !(UCSR0A & (1<<RXC0)) )
|
79 | ;
|
80 | /* Return the data */
|
81 | return UDR0;
|
82 | }
|
83 |
|
84 | void USART0_Transmit( unsigned char data )
|
85 | {
|
86 | /* Wait for empty transmit buffer */
|
87 | while ( !(UCSR0A & (1<<UDRE0)) )
|
88 | ;
|
89 | /* Start transmittion */
|
90 | UDR0 = data;
|
91 | }
|