Created
July 30, 2016 14:33
-
-
Save aemarkov/1934c9c68da06c6273d0896c8612e07c to your computer and use it in GitHub Desktop.
Simple AVR UART library
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* UART.h | |
* | |
* General UART realization | |
* Now available UART0 only for all | |
* using printf\scanf. | |
* For debug use. | |
* | |
* NOTE: MUST DEFINE UART_RECEIVE_BUFFER_SIZE | |
* | |
* Created: 19.01.2016 22:35:09 | |
* Author: Garrus | |
*/ | |
#ifndef UART_H_ | |
#define UART_H_ | |
//RX enabled if only RX_ENABLED and USE_STDIO | |
#if defined(USE_STDIO) & defined(RX_ENABLED) | |
#define _rx_enabled | |
#endif | |
#ifdef USE_STDIO | |
#include <stdio.h> | |
#endif | |
/////////////////////////////// REGISTER SETTINGS ///////////////////////////// | |
#if defined(ATmega8) | |
#define _ucsra UCSRA | |
#define _ucsrb UCSRB | |
#define _udre UDRE | |
#define _udr UDR | |
#define _ubrrh UBRRH | |
#define _ubrrl UBRRL | |
#define _txen TXEN | |
#define _rxen RXEN | |
#define _rxcie RXCIE | |
#elif defined(ATmega2560) | |
#define _ucsra UCSR0A | |
#define _ucsrb UCSR0B | |
#define _udre UDRE0 | |
#define _udr UDR0 | |
#define _ubrrh UBRR0H | |
#define _ubrrl UBRR0L | |
#define _txen TXEN0 | |
#define _rxen RXEN0 | |
#define _rxcie RXCIE0 | |
#endif | |
/////////////////////////////// TRANSMITTING ////////////////////////////////// | |
#ifdef TX_ENABLED | |
//This function sends byte to UART | |
static int uart_putchar( | |
char c | |
#ifdef USE_STDIO //this using only in stdio stdout implementaion | |
,FILE* stream //if using simple no-std functions this doesn't need. | |
#endif | |
) | |
{ | |
_udr = c; | |
while(!((_ucsra >> _udre ) & 1)); | |
return 0; | |
} | |
#endif | |
/////////////////////////////// RECEIVING ///////////////////////////////////// | |
#ifdef _rx_enabled | |
//Receive UART Queue | |
//struct UartQueue rx_queue; | |
char Buffer[UART_RECEIVE_BUFFER_SIZE]; | |
uint8_t Head = 0; | |
uint8_t Tail = 0; | |
uint8_t Length = 0; | |
//This function take a byte from an input buffer | |
static int uart_getchar( | |
#ifdef USE_STDIO //for stdio stdin only | |
FILE* c | |
#endif | |
) | |
{ | |
int ret; | |
cli(); //disable interrupts | |
if(Length>0) | |
{ | |
//if receive queue isn't empty | |
ret = Buffer[Head]; | |
Length--; | |
Head = ++Head % UART_RECEIVE_BUFFER_SIZE; | |
} | |
else | |
//return EOF | |
#ifdef USE_STDIO | |
ret = EOF; | |
#else | |
ret = -1; //this is actually EOF | |
#endif | |
sei(); //enable queue | |
return ret; | |
} | |
//byte received interruption | |
ISR(USART0_RX_vect) | |
{ | |
if(Length<UART_RECEIVE_BUFFER_SIZE) | |
{ | |
Buffer[Tail]=_udr; | |
Length++; | |
Tail = ++ Tail % UART_RECEIVE_BUFFER_SIZE; | |
} | |
} | |
#endif | |
/////////////////////////////// INIT ////////////////////////////////////////// | |
//Setting up streams | |
//stdio only | |
#ifdef USE_STDIO | |
#if defined(_rx_enabled) & defined(TX_ENABLED) | |
static FILE uart_std = FDEV_SETUP_STREAM(uart_putchar, uart_getchar, _FDEV_SETUP_RW); | |
#elif defined(TX_ENABLED) | |
static FILE uart_std = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE); | |
#elif defined(_rx_enabled) | |
static FILE uart_std = FDEV_SETUP_STREAM(NULL, uart_getchar, _FDEV_SETUP_READ); | |
#endif | |
#endif | |
//UART initializing | |
void InitUart(uint16_t baud) | |
{ | |
//setup baud | |
uint16_t ubbr; | |
ubbr = F_CPU/baud/16-1; | |
_ubrrh = ubbr>>8; | |
_ubrrl = ubbr; | |
//init buffers | |
#ifdef _rx_enabled | |
//QueueInit(&rx_queue); | |
_ucsrb = (1<<_rxen) | (1<<_rxcie); | |
#endif | |
#ifdef TX_ENABLED | |
_ucsrb |= (1<<_txen); | |
#endif | |
//setup streams | |
//stdio only | |
#ifdef USE_STDIO | |
#ifdef TX_ENABLED | |
stdout = &uart_std; | |
#endif | |
#ifdef _rx_enabled | |
stdin = &uart_std; | |
#endif | |
#endif | |
} | |
/////////////////////////////// LITE IO FUNCTIONS ///////////////////////////// | |
//if stdio doesn't use | |
#ifndef USE_STDIO | |
//print string | |
void UartPrint_string(char* string) | |
{ | |
uint16_t i = 0; | |
while(string[i]!=0) | |
uart_putchar(string[i++]); | |
} | |
//print decimal number | |
void UartPrint_int(int number) | |
{ | |
int number_copy = number; | |
int divider = 1; | |
if(number>0) | |
{ | |
//Get the number of digits | |
while(number_copy>10) | |
{ | |
number_copy/=10; | |
divider *= 10; | |
} | |
//dividing number | |
while(number>0) | |
{ | |
uart_putchar('0'+number / divider); | |
number%=divider; | |
divider/=10; | |
} | |
} | |
else uart_putchar('0'); | |
} | |
#endif | |
#endif /* UART_H_ */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment