I decided to create a simple C library for USART and AVR microcontrollers for the purpose of studying the USART serial interface.
This library is likely to be often updated. Open source code on my github:
https://github.com/xdth/AVR_dthUSART
Below is an example application. It will echo back strings received via serial at 9600 bit rate (defined in dthUSART.h), using the internal oscillator at 1 Mhz.
dthUSART.h
/*
* dthUSART C library for AVR microcontrollers (beta)
* dthlabs.com - July 30, 2017
*/
/*
* Defines
*/
#ifndef F_CPU
#define F_CPU 1000000UL // CPU frequency is 1 Mhz
#endif
#ifndef BAUD
#define BAUD 0x0C // or 12, for 9600.00 bit rate at 1.000 MHz, U2Xn = 1 (asynchronous), error 0.2%
#endif
#ifndef USE_2X
#define USE_2X 1
#endif
/*
* Functions prototypes
*/
// USART_init
void USART_init(void);
// byte_transmit
void byte_transmit(unsigned char);
// byte_receive
unsigned char byte_receive(void);
// string_print
void string_print(const char myString[]);
// string_read
void string_read(char myString[], uint8_t maxLength);
dthUSART.c
/*
* dthUSART C library for AVR microcontrollers (beta)
* dthlabs.com - July 30, 2017
*/
/*
* Includes
*/
#include <avr/io.h>
#include "dthUSART.h"
/*
* USART_init
*/
void USART_init(void) {
// Set baud rate
UBRRH = (unsigned char)(BAUD>>8);
UBRRL = (unsigned char)BAUD;
// Set U2X
#if USE_2X
UCSRA |= (1 << U2X);
#else
UCSRA &= ~(1 << U2X);
#endif
// Enable receiver and transmitter
UCSRB = (1 << RXEN) | (1 << TXEN);
// Set frame format
UCSRC = (1 << UCSZ1) | (1 << UCSZ0); // 8 data bits, 1 stop bit
}
/*
* byte_transmit
*/
void byte_transmit(unsigned char data) {
// Wait for empty transmit buffer
while ( !( UCSRA & (1 << UDRE)) );
// Put data into buffer, sends the data
UDR = data;
}
/*
* byte_receive
*/
unsigned char byte_receive(void) {
// Wait for data to be received
while ( !(UCSRA & (1 << RXC)) );
// Get and return received data from buffer
return UDR;
}
/*
* string_print
*/
void string_print(const char myString[]) {
uint8_t i = 0;
while (myString[i]) {
byte_transmit(myString[i]);
i++;
}
}
/*
* string_read
*/
void string_read(char myString[], uint8_t maxLength) {
char response;
uint8_t i;
i = 0;
while (i < (maxLength - 1)) { // avoid overun
response = byte_receive();
byte_transmit(response);
if (response == '\r') { // enter for ending
break;
}
else {
myString[i] = response; // add char
i++;
}
}
myString[i] = 0; // end with terminal NULL char
}
main.c
/*
* UART echo demo
* Using dthUSART C library for AVR microcontrollers (beta)
* dthlabs.com - July 30, 2017
*/
/*
* CPU frequency
*/
#define F_CPU 1000000UL // CPU frequency is 1 Mhz
/*
* Includes
*/
#include <avr/io.h>
#include <string.h> // strcmp()
#include <util/delay.h>
#include "dthUSART.h" // dthUSART library
/*
* Main
*/
int main(void){
// Initialize USART
USART_init();
_delay_ms(1000); // delay for a second
// Send hello strings
string_print("\r\n");
string_print("+--------------------------------+ \r\n");
string_print("| dthlabs.com +\r\n");
string_print("+--------------------------------+ \r\n");
string_print("\r\n");
string_print("\r\n");
string_print("\r\n");
string_print("Type string to be echoed >\r\n");
// declare buffer
char data[100];
// Loop forever
for(;;) {
// Read data
string_read(data,100);
// Echo data back
string_print(data);
string_print("\r\n");
}
// the program executed successfully
return 0;
}