1 | /**************************************************************
|
2 | * *
|
3 | * UART.c *
|
4 | * *
|
5 | ***************************************************************/
|
6 |
|
7 | /* Include-Dateien
|
8 | -----------------*/
|
9 | #include <io8515.h> // Register Definition fuer AT90S8515
|
10 | #include <ina90.h> // Intrinsic Funktionen fuer ICCA90
|
11 |
|
12 |
|
13 | /* UCR - UART Control Register: Bit Definitionen
|
14 | -----------------------------------------------------------*/
|
15 | #define RXCIE 0x80 // Bit 7
|
16 | #define TXCIE 0x40 // Bit 6
|
17 | #define UDRIE 0x20 // Bit 5
|
18 | #define RXEN 0x10 // Bit 4
|
19 | #define TXEN 0x08 // Bit 3
|
20 | #define CHR9 0x04 // Bit 2
|
21 | #define RXB8 0x02 // Bit 1
|
22 | #define TXB8 0x01 // Bit 0
|
23 |
|
24 | /* USR - UART Status Register: Bit Definitionen
|
25 | ---------------------------------------------------------*/
|
26 | #define RXC 0x80 // Bit 7
|
27 | #define TXC 0x40 // Bit 6
|
28 | #define UDRE 0x20 // Bit 5
|
29 | #define FE 0x10 // Bit 4
|
30 | #define OVR 0x08 // Bit 3
|
31 |
|
32 | /* UBRR - UART Baudrate Register: Baud Definitionen fuer 4MHz
|
33 | ---------------------------------------------------------*/
|
34 | #define BAUD_1200 208
|
35 | #define BAUD_2400 103
|
36 | #define BAUD_9600 25
|
37 | #define BAUD_19200 12
|
38 |
|
39 | /* UART Daten-Puffer Definitionen
|
40 | ------------------------------*/
|
41 | #define BUFFER_SIZE 8 // Modulo 2 Groesse: nur 2,4,8,16,32 Bytes
|
42 | #define BUFFER_MASK (BUFFER_SIZE-1)
|
43 |
|
44 | /* Allgemeine typ-Definitionen
|
45 | -----------------------------------------------------------*/
|
46 | typedef enum{ FALSE=0, TRUE=1} Boolean_t ;
|
47 |
|
48 | typedef struct{ unsigned char UartData[ BUFFER_SIZE ];
|
49 | unsigned char NumberOfBytes;
|
50 | unsigned char UartStatus; } Uart_t;
|
51 |
|
52 | /* Static Variables
|
53 | -------------------*/
|
54 | static unsigned char RxBuf[ BUFFER_SIZE ];
|
55 | static volatile unsigned char RxProducer; // Empfang: Int-Service ist der Producer
|
56 | static volatile unsigned char RxConsumer; // Empfang: Hauptprogramm ist Consumer
|
57 | static unsigned char TxBuf[ BUFFER_SIZE ];
|
58 | static volatile unsigned char TxProducer; // Senden: Hauptprogramm ist der Producer
|
59 | static volatile unsigned char TxConsumer; // Senden: Int-Service ist Consumer
|
60 |
|
61 | /* Funktion-Prototypen
|
62 | ----------------------------*/
|
63 | void InitUart( unsigned char baudrate );
|
64 | Boolean_t ReceiveData( Uart_t * Data );
|
65 | Boolean_t TransmitData( Uart_t * Data );
|
66 | void Delay( void );
|
67 |
|
68 | /* Input Pins, Port B: sfrb PINB = 0x16;
|
69 | Data Direction Register, Port B: sfrb DDRB = 0x17;
|
70 | Data Register, Port B: sfrb PORTB = 0x18; */
|
71 | void Delay( void )
|
72 | {
|
73 | unsigned int i= 0x7FFF;
|
74 | while(--i);
|
75 | }
|
76 |
|
77 |
|
78 | /* Main - ein einfaches Anwendungsbeispiel fuer UART und Timer
|
79 | -------------------------------------------------------------*/
|
80 | void C_task main( void )
|
81 | {
|
82 | Uart_t UartData;
|
83 |
|
84 | DDRB = 0xFF ; // Konfiguriert Port B als Ausgang
|
85 | PORTB = 0xAA;
|
86 |
|
87 | InitUart( BAUD_9600 ); // Baudrate = 9600 Baud bei 4MHz Quarz
|
88 | _SEI(); // Freigabe aller Interrupts => Enable UART Interrupts
|
89 |
|
90 | for( ;; ) // Endlos-Schleife
|
91 | {
|
92 | if( ReceiveData( & UartData ) )
|
93 | {
|
94 | TransmitData( & UartData ); // Echo der empfangenen Bytes
|
95 | }
|
96 |
|
97 | PORTB++; // led switch
|
98 | Delay();
|
99 | }
|
100 | }
|
101 |
|
102 | /* Initialisierung der UART
|
103 | ------------------------------*/
|
104 | void InitUart( unsigned char baudrate )
|
105 | {
|
106 | UBRR = baudrate; // Baudrate setzen
|
107 |
|
108 | // Freigabe der UART Interrupts
|
109 | UCR = TXEN | RXEN | RXCIE; // ==> Senden/Empfangen/Empf.INT
|
110 |
|
111 | RxConsumer = 0; // Ruecksetzen der Puffer-Index
|
112 | RxProducer = 0;
|
113 | TxConsumer = 0;
|
114 | TxProducer = 0;
|
115 | }
|
116 |
|
117 | /* Empfangs-Interrupt Handler
|
118 | --------------------------- */
|
119 | interrupt [UART_RX_vect] void UartRxIntHandler( void )
|
120 | {
|
121 | unsigned char data;
|
122 |
|
123 | data = UDR; // Lesen der Empfangsdaten
|
124 | RxBuf[RxProducer] = data; // Empfangenes Byte in Puffer ablegen
|
125 | RxProducer++; // Bufferindex setzen
|
126 | RxProducer &=BUFFER_MASK; // Index begrenzen und evtl. auf Puffer-Anfang
|
127 |
|
128 | if (RxProducer == RxConsumer )
|
129 | {
|
130 | // Fehler! Ueberlauf Empfangspuffer
|
131 | }
|
132 | }
|
133 |
|
134 | /* Sende-Interrupt Handler
|
135 | --------------------------- */
|
136 | interrupt [UART_UDRE_vect] void UART_TX_interrupt( void )
|
137 | {
|
138 | // Test ob noch nicht fertig mit Senden
|
139 | if ( TxConsumer != TxProducer )
|
140 | {
|
141 | ++TxConsumer; // Pufferindex aktualisieren
|
142 | TxConsumer &=BUFFER_MASK; // Index begrenzen und evtl. auf Puffer-Anfang
|
143 | UDR = TxBuf[TxConsumer]; // Uebergabe eines Bytes
|
144 | }
|
145 | else
|
146 | {
|
147 | UCR &= ~UDRIE; // Disable UDRE interrupt
|
148 | }
|
149 | }
|
150 |
|
151 |
|
152 | /* UART Empfangsfunktion
|
153 | --------------------- */
|
154 | Boolean_t ReceiveData( Uart_t * Data )
|
155 | {
|
156 | unsigned char i=0;
|
157 |
|
158 | // Schleife zur Uebergabe der empfangenen Daten
|
159 | while (( RxConsumer != RxProducer ) && ( i < BUFFER_SIZE ) )
|
160 | {
|
161 | Data->UartData[i++] = RxBuf[RxConsumer++];
|
162 |
|
163 | RxConsumer &=BUFFER_MASK; // Consumer-Index begrenzen und evtl. auf Puffer-Anfang
|
164 | }
|
165 |
|
166 | Data->NumberOfBytes = i ;
|
167 |
|
168 | if( i ) return TRUE ;
|
169 | else return FALSE ;
|
170 | }
|
171 |
|
172 | /* Sendefunktion
|
173 | --------------------- */
|
174 | Boolean_t TransmitData( Uart_t * Data )
|
175 | {
|
176 | unsigned char i=0;
|
177 |
|
178 | while (( i < Data->NumberOfBytes ) && ( i < BUFFER_SIZE ) )// Uebergabe Empfangsdaten
|
179 | {
|
180 | TxBuf[TxProducer++] = Data->UartData[i++] ;
|
181 |
|
182 | TxProducer &=BUFFER_MASK; // Producer-Index begrenzen und evtl. auf Puffer-Anfang
|
183 | }
|
184 |
|
185 | UDR = TxBuf[TxConsumer]; // Senden Anstossen
|
186 | ++TxConsumer;
|
187 | TxConsumer &=BUFFER_MASK; // Consumer-Index begrenzen
|
188 |
|
189 | UCR |= UDRIE ;
|
190 | Data->NumberOfBytes = 0;
|
191 | return TRUE ;
|
192 | }
|