Zum Hauptinhalt springen

C - AVR UART Driver

  1// Literatur: AVR uController Manuals
  2
  3
  4/******************************************************
  5 * hal.h                                              *
  6 ******************************************************/
  7    #ifndef HAL_H
  8    #define HAL_H
  9    
 10    // UART baudrates
 11    typedef enum UART_BR_e
 12    {	
 13        BR_4800,
 14        BR_9600,
 15        BR_19200,
 16        BR_38400,
 17        BR_57600,
 18        BR_115200,
 19    } UART_BR_t;
 20
 21    // UART receiver callback
 22    typedef void (*UARTCALLBACK) (unsigned char data);
 23
 24    // UART signals
 25    #define UART_PORT               PORTE
 26    #define UART_DDR                DDRE
 27    #define UART_RXD_PIN            0
 28    #define UART_TXD_PIN            1
 29    
 30    #define TX_BUFFER_SIZE			512
 31    #define UART_TX_BUFFER_MASK 	(TX_BUFFER_SIZE - 1)
 32    
 33    #endif
 34
 35
 36/******************************************************
 37 * uart.h                                             *
 38 ******************************************************/
 39    #ifndef UART_H
 40    #define UART_H
 41
 42    #include <avr/pgmspace.h>
 43    #include "hal.h"
 44    
 45    void uart_init(tUART_BR Baudrate);
 46    void uart_putHex(unsigned char);
 47    void uart_putByte(unsigned char);
 48    void uart_putInt(unsigned int);
 49    void uart_putLong(unsigned long);
 50    void uart_putStr(unsigned char *);
 51    void uart_putData(unsigned char *, unsigned char);
 52    void uart_putStrf(PGM_P);
 53    void uart_putChar(unsigned char);
 54    BOOL uart_dataAvailable(void);
 55
 56    void uart_registerCallback(UARTCALLBACK CallBack);
 57
 58    #endif
 59
 60
 61/******************************************************
 62 * uart.c                                             *
 63 ******************************************************/
 64    #include <avr/io.h>
 65    #include <avr/interrupt.h>
 66    #include <stdio.h>
 67    #include <string.h>
 68    #include "uart.h"
 69
 70    // global variables
 71    static volatile unsigned char uart_TxBuf[TX_BUFFER_SIZE];
 72    static volatile unsigned char uart_TxHead = 0;
 73    static volatile unsigned char uart_TxTail = 0;
 74
 75    static volatile UARTCALLBACK UartRecCallback = NULL;
 76
 77    void UART0_RegisterCallback(UARTCALLBACK CallBack)
 78    {
 79        UartRecCallback = CallBack;
 80    }
 81
 82    void uart_init(UART_BR_t Baudrate)
 83    {
 84        unsigned int UBRRVAL = 0;
 85	
 86        switch (Baudrate)
 87        {
 88        case BR_4800:
 89            UBRRVAL = (F_CPU/(4800L*16L)-1);
 90            break;
 91        case BR_9600:
 92            UBRRVAL = (F_CPU/(9600L*16L)-1);
 93            break;
 94        case BR_19200:
 95            UBRRVAL = (F_CPU/(19200L*16L)-1);
 96            break;
 97        case BR_38400:
 98            UBRRVAL = (F_CPU/(38400L*16L)-1);
 99            break;
100        case BR_57600:
101            UBRRVAL = (F_CPU/(57600L*16L)-1);
102            break;
103        case BR_115200:
104            UBRRVAL = (F_CPU/(115200L*16L)-1);
105            break;
106        default:
107            UBRRVAL = (F_CPU/(9600L*16L)-1);
108            break;
109        }	
110
111        UBRR0H = (unsigned char)(UBRRVAL>>8);
112        UBRR0L = (unsigned char)UBRRVAL;
113	
114        // enable receiver and transmitter
115        UCSR0B = (1<<TXEN0)|(1<<RXEN0)|(1<<RXCIE0);
116        // set frame format: 8data, 1stop bit
117        UCSR0C = (3<<UCSZ00);
118	
119        UART0_TxHead = 0;
120        UART0_TxTail = 0;
121    }
122
123    // send hex character via serial
124    void uart_putHex(unsigned char data)
125    {
126        unsigned char buf[5];
127        sprintf((char *)buf, "%02x", data);
128        uart_putStr(buf);
129    }
130
131    // send a byte
132    void uart_putByte(unsigned char data)
133    {
134        unsigned char buf[5];
135        sprintf((char *)buf, "%02u", data);
136        uart_putStr(buf);
137    }
138
139    // send an integer
140    void uart_putInt(unsigned int data)
141    {
142        unsigned char buf[6];
143        sprintf((char *)buf, "%5u", data);
144        uart_putStr(buf);
145    }
146
147    // send a long value
148    void uart_putLong(unsigned long Value)
149    {
150        unsigned char Cnt;
151        unsigned char Buf[20];
152        
153        // convert
154        Cnt = 10;
155        do 
156        {
157            Cnt--;
158            Buf[Cnt] = Value % 10;
159            Value /= 10;
160        } while (Value > 0);
161
162        // output
163        while (Cnt < 10)
164        {
165            uart_putChar(Buf[Cnt] + '0');
166            Cnt++;
167        }
168    }
169
170    // send a string
171    void uart_putStr(unsigned char * pdata)
172    {
173        while (*pdata) 
174        {
175            uart_putChar(*pdata++);
176        }
177    }
178
179    // send a string
180    void uart_putData(unsigned char * pdata, unsigned char Len)
181    {
182        while (Len--) 
183        {
184            uart_putChar(*pdata++);
185        }
186    }
187
188    // send a string from flash-memory
189    void uart_putStrf(PGM_P pdata)
190    {
191        // while not 0 continue
192        while (pgm_read_byte(pdata))
193        {
194            uart_putChar(pgm_read_byte(pdata++));
195        }
196    }                                   
197
198    // send a character via serial using a ringbuffer
199    void uart_putChar(unsigned char data)
200    {
201        unsigned char tmphead;
202        
203        tmphead = (uart_TxHead + 1) & UART_TX_BUFFER_MASK;
204    
205        uart_TxBuf[tmphead] = data;
206        uart_TxHead = tmphead;
207    
208        // enable UDRE signal
209        UCSR0B |= (1<<UDRIE0);
210    }
211
212
213    // serial UART data register empty signal vector
214    SIGNAL (SIG_USART0_DATA)
215    {
216        unsigned char tmptail;
217    
218        if (uart_TxHead != UART0_TxTail) 
219        {
220            // calculate and store new buffer index
221            tmptail = (uart_TxTail + 1) & UART_TX_BUFFER_MASK;
222            uart_TxTail = tmptail;
223            
224            // get one byte from buffer and write it to UART
225            UDR0 = uart_TxBuf[tmptail];
226        }
227        else
228        {
229            // tx buffer empty, disable UDRE signal
230            UCSR0B &= ~(1<<UDRIE0);
231        }
232    }
233
234    // serial UART receive complete signal vector
235    SIGNAL (SIG_USART0_RECV)
236    {
237        if (UartRecCallback != NULL)
238        {
239            UartRecCallback(UDR0);
240        }
241    }