Last active
March 6, 2023 18:40
-
-
Save shiva-karthick/a65e2ed496131185abe6fbd482680784 to your computer and use it in GitHub Desktop.
USART initialisation for ATmega48A/PA/88A/PA/168A/PA/328/P
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
/* An example that shows how to use the above USART functions */ | |
/* | |
* main.c | |
* Links for Further learning : | |
* 1) https://www.youtube.com/watch?v=1mmkA-m4aKU&list=PLtQdQmNK_0DRhBWYZ32BEILOykXLpJ8tP&index=21 | |
* 2) https://www.avrfreaks.net/forum/tut-soft-using-usart-serial-communications?page=all | |
* 3) https://www.avrfreaks.net/forum/how-use-printf-uart | |
* 4) https://stackoverflow.com/questions/42744280/error-unknown-type-name-file/42744341 | |
* Author : Shankar | |
*/ | |
#include <avr/io.h> | |
#include <avr/delay.h> | |
#include <stdio.h> | |
#include "USART.h" | |
// ******************************************************************************** | |
// Global Variables | |
// ******************************************************************************** | |
static FILE mystdout = FDEV_SETUP_STREAM(usart_putchar_printf, NULL, _FDEV_SETUP_WRITE); | |
int main(void) | |
{ | |
initUSART(); | |
// setup our stdio stream | |
stdout = &mystdout; | |
uint8_t var = 10; | |
while (1) | |
{ | |
printf("HI %u\r\n", var); | |
_delay_ms(100); | |
} | |
} |
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
/* | |
Quick and dirty functions that make serial communications work. | |
Note that receiveByte() blocks -- it sits and waits _forever_ for | |
a byte to come in. If you're doing anything that's more interesting, | |
you'll want to implement this with interrupts. | |
initUSART requires BAUDRATE to be defined in order to calculate | |
the bit-rate multiplier. 9600 is a reasonable default. | |
May not work with some of the older chips: | |
Tiny2313, Mega8, Mega16, Mega32 have different pin macros | |
If you're using these chips, see (e.g.) iom8.h for how it's done. | |
These old chips don't specify UDR0 vs UDR1. | |
Correspondingly, the macros will just be defined as UDR. | |
*/ | |
#include <avr/io.h> | |
#include "USART.h" | |
#include "setbaud.h" | |
#include <stdio.h> | |
#define F_CPU 8000000 | |
#define BAUD 9600 | |
void initUSART(void) { /* requires BAUD */ | |
UBRR0H = UBRRH_VALUE; /* defined in setbaud.h */ | |
UBRR0L = UBRRL_VALUE; | |
#if USE_2X | |
UCSR0A |= (1 << U2X0); | |
#else | |
UCSR0A &= ~(1 << U2X0); | |
#endif | |
/* Enable USART transmitter/receiver */ | |
UCSR0B = (1 << TXEN0) | (1 << RXEN0); | |
UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); /* 8 data bits, 1 stop bit */ | |
} | |
void transmitByte(uint8_t data) { | |
/* Wait for empty transmit buffer */ | |
//loop_until_bit_is_set(UCSR0A, UDRE0); | |
//UDR0 = data; /* send data */ | |
// Wait for empty transmit buffer | |
while ( !(UCSR0A & (_BV(UDRE0))) ); | |
// Start transmission | |
UDR0 = data; | |
} | |
uint8_t receiveByte(void) { | |
loop_until_bit_is_set(UCSR0A, RXC0); /* Wait for incoming data */ | |
return UDR0; /* return register value */ | |
} | |
/* Here are a bunch of useful printing commands */ | |
/*The function printString() just loops through all the characters in a string until the end, | |
transmitting them one at a time.*/ | |
void printString(const char myString[]) { | |
uint8_t i = 0; | |
while (myString[i]) { // Test for a null character | |
transmitByte(myString[i]); | |
i++; | |
} | |
} | |
void readString(char myString[], uint8_t maxLength) { | |
char response; | |
uint8_t i; | |
i = 0; | |
while (i < (maxLength - 1)) { /* prevent over-runs */ | |
response = receiveByte(); | |
transmitByte(response); /* echo */ | |
if (response == '\r') { /* enter marks the end */ | |
break; | |
} | |
else { | |
myString[i] = response; /* add in a letter */ | |
i++; | |
} | |
} | |
myString[i] = 0; /* terminal NULL character */ | |
} | |
void printByte(uint8_t byte) { | |
// Input : Numeric value of an 8-bit byte | |
// Output : 3 ASCII digits | |
/* For example : if a = 56; printByte() sends "0" an then "5" and then "6" across the serial line*/ | |
/* Converts a byte to a string of decimal text, sends it */ | |
transmitByte('0' + (byte / 100)); /* Hundreds */ | |
transmitByte('0' + ((byte / 10) % 10)); /* Tens */ | |
transmitByte('0' + (byte % 10)); /* Ones */ | |
} | |
void printWord(uint16_t word) { | |
transmitByte('0' + (word / 10000)); /* Ten-thousands */ | |
transmitByte('0' + ((word / 1000) % 10)); /* Thousands */ | |
transmitByte('0' + ((word / 100) % 10)); /* Hundreds */ | |
transmitByte('0' + ((word / 10) % 10)); /* Tens */ | |
transmitByte('0' + (word % 10)); /* Ones */ | |
} | |
void printBinaryByte(uint8_t byte) { | |
/* Prints out a byte as a series of 1's and 0's */ | |
uint8_t bit; | |
for (bit = 7; bit < 255; bit--) { | |
if (bit_is_set(byte, bit)) | |
transmitByte('1'); | |
else | |
transmitByte('0'); | |
} | |
} | |
char nibbleToHexCharacter(uint8_t nibble) { | |
/* Converts 4 bits into hexadecimal */ | |
if (nibble < 10) { | |
return ('0' + nibble); | |
} | |
else { | |
return ('A' + nibble - 10); | |
} | |
} | |
void printHexByte(uint8_t byte) { | |
/* Prints a byte as its hexadecimal equivalent */ | |
uint8_t nibble; | |
nibble = (byte & 0b11110000) >> 4; | |
transmitByte(nibbleToHexCharacter(nibble)); | |
nibble = byte & 0b00001111; | |
transmitByte(nibbleToHexCharacter(nibble)); | |
} | |
uint8_t getNumber(void) { | |
// Gets a numerical 0-255 from the serial port. | |
// Converts from string to number. | |
char hundreds = '0'; | |
char tens = '0'; | |
char ones = '0'; | |
char thisChar = '0'; | |
do { /* shift over */ | |
hundreds = tens; | |
tens = ones; | |
ones = thisChar; | |
thisChar = receiveByte(); /* get a new character */ | |
transmitByte(thisChar); /* echo */ | |
} while (thisChar != '\r'); /* until type return */ | |
return (100 * (hundreds - '0') + 10 * (tens - '0') + ones - '0'); | |
} | |
// this function is called by printf as a stream handler | |
int usart_putchar_printf(char var, FILE *stream) { | |
// translate \n to \r for br@y++ terminal | |
if (var == '\n') transmitByte('\r'); | |
transmitByte(var); | |
return 0; | |
} |
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
/* Functions to initialize, send, receive over USART | |
initUSART requires BAUD to be defined in order to calculate | |
the bit-rate multiplier. | |
*/ | |
#include <stdio.h> | |
#ifndef BAUD /* if not defined in Makefile... */ | |
#define BAUD 9600 /* set a safe default baud rate */ | |
#endif | |
/* These are defined for convenience */ | |
#define USART_HAS_DATA bit_is_set(UCSR0A, RXC0) | |
#define USART_READY bit_is_set(UCSR0A, UDRE0) | |
/* Takes the defined BAUD and F_CPU defined in setbaud.h, | |
calculates the bit-clock multiplier, | |
and configures the hardware USART */ | |
void initUSART(void); | |
/* Blocking transmit and receive functions. | |
When you call receiveByte() your program will hang until | |
data comes through. We'll improve on this later. Hint : Use an interrupt*/ | |
void transmitByte(uint8_t data); | |
uint8_t receiveByte(void); | |
void printString(const char myString[]); | |
/* Utility function to transmit an entire string from RAM */ | |
void readString(char myString[], uint8_t maxLength); | |
/* Define a string variable, pass it to this function | |
The string will contain whatever you typed over serial */ | |
void printByte(uint8_t byte); | |
/* Prints a byte out as its 3-digit ascii equivalent */ | |
void printWord(uint16_t word); | |
/* Prints a word (16-bits) out as its 5-digit ascii equivalent */ | |
void printBinaryByte(uint8_t byte); | |
/* Prints a byte out in 1s and 0s */ | |
char nibbleToHex(uint8_t nibble); | |
char nibbleToHexCharacter(uint8_t nibble); | |
void printHexByte(uint8_t byte); | |
/* Prints a byte out in hexadecimal */ | |
uint8_t getNumber(void); | |
/* takes in up to three ascii digits, | |
converts them to a byte when press enter */ | |
int usart_putchar_printf(char var, FILE *stream); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment