// Literatur: AVR uController Manuals /****************************************************** * hal.h * ******************************************************/ #ifndef HAL_H #define HAL_H // UART baudrates typedef enum UART_BR_e { BR_4800, BR_9600, BR_19200, BR_38400, BR_57600, BR_115200, } UART_BR_t; // UART receiver callback typedef void (*UARTCALLBACK) (unsigned char data); // UART signals #define UART_PORT PORTE #define UART_DDR DDRE #define UART_RXD_PIN 0 #define UART_TXD_PIN 1 #define TX_BUFFER_SIZE 512 #define UART_TX_BUFFER_MASK (TX_BUFFER_SIZE - 1) #endif /****************************************************** * uart.h * ******************************************************/ #ifndef UART_H #define UART_H #include <avr/pgmspace.h> #include "hal.h" void uart_init(tUART_BR Baudrate); void uart_putHex(unsigned char); void uart_putByte(unsigned char); void uart_putInt(unsigned int); void uart_putLong(unsigned long); void uart_putStr(unsigned char *); void uart_putData(unsigned char *, unsigned char); void uart_putStrf(PGM_P); void uart_putChar(unsigned char); BOOL uart_dataAvailable(void); void uart_registerCallback(UARTCALLBACK CallBack); #endif /****************************************************** * uart.c * ******************************************************/ #include <avr/io.h> #include <avr/interrupt.h> #include <stdio.h> #include <string.h> #include "uart.h" // global variables static volatile unsigned char uart_TxBuf[TX_BUFFER_SIZE]; static volatile unsigned char uart_TxHead = 0; static volatile unsigned char uart_TxTail = 0; static volatile UARTCALLBACK UartRecCallback = NULL; void UART0_RegisterCallback(UARTCALLBACK CallBack) { UartRecCallback = CallBack; } void uart_init(UART_BR_t Baudrate) { unsigned int UBRRVAL = 0; switch (Baudrate) { case BR_4800: UBRRVAL = (F_CPU/(4800L*16L)-1); break; case BR_9600: UBRRVAL = (F_CPU/(9600L*16L)-1); break; case BR_19200: UBRRVAL = (F_CPU/(19200L*16L)-1); break; case BR_38400: UBRRVAL = (F_CPU/(38400L*16L)-1); break; case BR_57600: UBRRVAL = (F_CPU/(57600L*16L)-1); break; case BR_115200: UBRRVAL = (F_CPU/(115200L*16L)-1); break; default: UBRRVAL = (F_CPU/(9600L*16L)-1); break; } UBRR0H = (unsigned char)(UBRRVAL>>8); UBRR0L = (unsigned char)UBRRVAL; // enable receiver and transmitter UCSR0B = (1<<TXEN0)|(1<<RXEN0)|(1<<RXCIE0); // set frame format: 8data, 1stop bit UCSR0C = (3<<UCSZ00); UART0_TxHead = 0; UART0_TxTail = 0; } // send hex character via serial void uart_putHex(unsigned char data) { unsigned char buf[5]; sprintf((char *)buf, "%02x", data); uart_putStr(buf); } // send a byte void uart_putByte(unsigned char data) { unsigned char buf[5]; sprintf((char *)buf, "%02u", data); uart_putStr(buf); } // send an integer void uart_putInt(unsigned int data) { unsigned char buf[6]; sprintf((char *)buf, "%5u", data); uart_putStr(buf); } // send a long value void uart_putLong(unsigned long Value) { unsigned char Cnt; unsigned char Buf[20]; // convert Cnt = 10; do { Cnt--; Buf[Cnt] = Value % 10; Value /= 10; } while (Value > 0); // output while (Cnt < 10) { uart_putChar(Buf[Cnt] + '0'); Cnt++; } } // send a string void uart_putStr(unsigned char * pdata) { while (*pdata) { uart_putChar(*pdata++); } } // send a string void uart_putData(unsigned char * pdata, unsigned char Len) { while (Len--) { uart_putChar(*pdata++); } } // send a string from flash-memory void uart_putStrf(PGM_P pdata) { // while not 0 continue while (pgm_read_byte(pdata)) { uart_putChar(pgm_read_byte(pdata++)); } } // send a character via serial using a ringbuffer void uart_putChar(unsigned char data) { unsigned char tmphead; tmphead = (uart_TxHead + 1) & UART_TX_BUFFER_MASK; uart_TxBuf[tmphead] = data; uart_TxHead = tmphead; // enable UDRE signal UCSR0B |= (1<<UDRIE0); } // serial UART data register empty signal vector SIGNAL (SIG_USART0_DATA) { unsigned char tmptail; if (uart_TxHead != UART0_TxTail) { // calculate and store new buffer index tmptail = (uart_TxTail + 1) & UART_TX_BUFFER_MASK; uart_TxTail = tmptail; // get one byte from buffer and write it to UART UDR0 = uart_TxBuf[tmptail]; } else { // tx buffer empty, disable UDRE signal UCSR0B &= ~(1<<UDRIE0); } } // serial UART receive complete signal vector SIGNAL (SIG_USART0_RECV) { if (UartRecCallback != NULL) { UartRecCallback(UDR0); } }