Skip to content

Instantly share code, notes, and snippets.

@aemarkov
Created July 30, 2016 14:33
Show Gist options
  • Save aemarkov/1934c9c68da06c6273d0896c8612e07c to your computer and use it in GitHub Desktop.
Save aemarkov/1934c9c68da06c6273d0896c8612e07c to your computer and use it in GitHub Desktop.
Simple AVR UART library
/*
* 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