Last active
November 16, 2022 10:19
-
-
Save gshrikant/8549474 to your computer and use it in GitHub Desktop.
Routines for asynchronous UART communication on the ATMega328P
This file contains hidden or 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.c | |
* | |
* Asynchronous UART example tested on ATMega328P (16 MHz) | |
* | |
* Toolchain: avr-gcc (4.3.3) | |
* Editor: Eclipse Kepler (4) | |
* Usage: | |
* Perform all settings in uart.h and enable by calling initUART(void) | |
* Compile: | |
* make all | |
* | |
* Functions: | |
* - First call initUART() to set up Baud rate and frame format | |
* - initUART() calls macros TX_START() and RX_START() automatically | |
* - To enable interrupts on reception, call RX_INTEN() macros | |
* - Call functions getByte() and putByte(char) for character I/O | |
* - Call functions writeString(char*) and readString() for string I/O | |
* | |
* Created on: 21-Jan-2014 | |
* Author: Shrikant Giridhar | |
*/ | |
#include "uart.h" | |
// Debug Mode; comment out on Release | |
#define _DEBUG 0 | |
/*! \brief Configures baud rate (refer datasheet) */ | |
void initUART(void) | |
{ | |
// Not necessary; initialize anyway | |
DDRD |= _BV(PD1); | |
DDRD &= ~_BV(PD0); | |
// Set baud rate; lower byte and top nibble | |
UBRR0H = ((_UBRR) & 0xF00); | |
UBRR0L = (uint8_t) ((_UBRR) & 0xFF); | |
TX_START(); | |
RX_START(); | |
// Set frame format = 8-N-1 | |
UCSR0C = (_DATA << UCSZ00); | |
} | |
/*! \brief Returns a byte from the serial buffer | |
* Use this function if the RX interrupt is not enabled. | |
* Returns 0 on empty buffer | |
*/ | |
uint8_t getByte(void) | |
{ | |
// Check to see if something was received | |
while (!(UCSR0A & _BV(RXC0))); | |
return (uint8_t) UDR0; | |
} | |
/*! \brief Transmits a byte | |
* Use this function if the TX interrupt is not enabled. | |
* Blocks the serial port while TX completes | |
*/ | |
void putByte(unsigned char data) | |
{ | |
// Stay here until data buffer is empty | |
while (!(UCSR0A & _BV(UDRE0))); | |
UDR0 = (unsigned char) data; | |
} | |
/*! \brief Writes an ASCII string to the TX buffer */ | |
void writeString(char *str) | |
{ | |
while (*str != '\0') | |
{ | |
putByte(*str); | |
++str; | |
} | |
} | |
const char* readString(void) | |
{ | |
char rxstr[RX_BUFF]; | |
char* temp; | |
temp = rxstr; | |
while((*temp = getByte()) != '\n') | |
{ | |
++temp; | |
} | |
return rxstr; | |
} | |
#if _DEBUG | |
int main(void) | |
{ | |
initUART(); | |
while(1) | |
{ | |
writeString(readString()); | |
putByte('\r'); | |
putByte('\n'); | |
} | |
return 0; | |
} | |
#endif |
This file contains hidden or 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 | |
* | |
* UART example for ATMega328P clocked at 16 MHz | |
* | |
* TODO :- | |
* - Implement string read function | |
* - Optimize for size | |
* - Add helper routines and compile to .a file | |
* | |
* Created on: 22-Jan-2014 | |
* Author: Shrikant Giridhar | |
*/ | |
#ifndef UART_H_ | |
#define UART_H_ | |
#include <avr/io.h> | |
#include <stdint.h> | |
/* Probably already defined somewhere else. Define here, if isn't. */ | |
#ifndef FOSC | |
#define FOSC 16000000UL | |
#endif | |
/* Settings */ | |
#define _BAUD 9600 // Baud rate (9600 is default) | |
#define _DATA 0x03 // Number of data bits in frame = byte tranmission | |
#define _UBRR (FOSC/16)/_BAUD - 1 // Used for UBRRL and UBRRH | |
#define RX_BUFF 10 | |
/* Useful macros */ | |
#define TX_START() UCSR0B |= _BV(TXEN0) // Enable TX | |
#define TX_STOP() UCSR0B &= ~_BV(TXEN0) // Disable TX | |
#define RX_START() UCSR0B |= _BV(RXEN0) // Enable RX | |
#define RX_STOP() UCSR0B &= ~_BV(RXEN0) // Disable RX | |
#define COMM_START() TX_START(); RX_START() // Enable communications | |
/* Interrupt macros; Remember to set the GIE bit in SREG before using (see datasheet) */ | |
#define RX_INTEN() UCSR0B |= _BV(RXCIE0) // Enable interrupt on RX complete | |
#define RX_INTDIS() UCSR0B &= ~_BV(RXCIE0) // Disable RX interrupt | |
#define TX_INTEN() UCSR0B |= _BV(TXCIE0) // Enable interrupt on TX complete | |
#define TX_INTDIS() UCSR0B &= ~_BV(TXCIE0) // Disable TX interrupt | |
/* Prototypes */ | |
void initUART(void); | |
uint8_t getByte(void); | |
void putByte(unsigned char data); | |
void writeString(char *str); | |
const char* readString(void); | |
#endif /* UART_H_ */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment