UART 115200 with serial terminal
Quote from lvivgeorge on November 18, 2024, 6:37 amHi!
I was wondering if there are any known issues or limitations with simulating UART at a 115200 baud rate.
I've tested 9600, 19200, 38400, and 57600—all of them work fine. However, higher baud rates like 115200 and 230400 do not seem to work.
My code
#include <avr/io.h>#include <util/delay.h>#include <stdio.h>#include <stdbool.h>#define F_CPU 16000000UL // Clock speed#define BAUD 115200#define BAUDRATE ((F_CPU / (BAUD * 16UL)) - 1)#define LED PB5void uartInit(void);void uartTransmit(char data);char uartReceive(void);void uartSendString(const char *str);void lightLed(uint8_t n);int main(void) {DDRB|=1<<LED;charbuffer[50]; // Buffer to hold the messageuartInit(); // Initialize UARTboolisCorrect=false;while (1) {charreceived=uartReceive(); // Receive a byte// Check if the received byte is between '1' and '9'if (received>='1'&&received<='9') {isCorrect=true;// Prepare a message with the numbersprintf(buffer, "Success! You entered: %c\r\n", received);} else {isCorrect=false;sprintf(buffer, "Invalid input. Please send a number between 1-9.\r\n");}uartSendString(buffer);if (isCorrect) {uint8_tn=received-'0';lightLed(n);}_delay_ms(1000);}}// Initialize UARTvoid uartInit(void) {// Set baud rateUBRR0H= (BAUDRATE>>8);UBRR0L=BAUDRATE;// Enable transmitter and receiverUCSR0B= (1<<RXEN0) | (1<<TXEN0);// Set frame format: 8 data bits, 1 stop bitUCSR0C= (1<<UCSZ01) | (1<<UCSZ00);}// Send a byte via UARTvoid uartTransmit(char data) {// Wait for empty transmit bufferwhile (!(UCSR0A& (1<<UDRE0)));// Put data into buffer, sends the dataUDR0=data;}// Receive a byte via UARTchar uartReceive(void) {// Wait for data to be receivedwhile (!(UCSR0A& (1<<RXC0)));// Get and return received data from bufferreturnUDR0;}// Send a string via UARTvoid uartSendString(const char *str) {while (*str) {uartTransmit(*str++);}}void lightLed(uint8_t n) {for (uint8_ti=0; i<n; i++) {PORTB|=1<<LED;_delay_ms(200);PORTB&=~(1<<LED);_delay_ms(200);}}
Hi!
I was wondering if there are any known issues or limitations with simulating UART at a 115200 baud rate.
I've tested 9600, 19200, 38400, and 57600—all of them work fine. However, higher baud rates like 115200 and 230400 do not seem to work.

My code
#include <avr/io.h>#include <util/delay.h>#include <stdio.h>#include <stdbool.h>#define F_CPU 16000000UL // Clock speed#define BAUD 115200#define BAUDRATE ((F_CPU / (BAUD * 16UL)) - 1)#define LED PB5void uartInit(void);void uartTransmit(char data);char uartReceive(void);void uartSendString(const char *str);void lightLed(uint8_t n);int main(void) {DDRB|=1<<LED;charbuffer[50]; // Buffer to hold the messageuartInit(); // Initialize UARTboolisCorrect=false;while (1) {charreceived=uartReceive(); // Receive a byte// Check if the received byte is between '1' and '9'if (received>='1'&&received<='9') {isCorrect=true;// Prepare a message with the numbersprintf(buffer, "Success! You entered: %c\r\n", received);} else {isCorrect=false;sprintf(buffer, "Invalid input. Please send a number between 1-9.\r\n");}uartSendString(buffer);if (isCorrect) {uint8_tn=received-'0';lightLed(n);}_delay_ms(1000);}}// Initialize UARTvoid uartInit(void) {// Set baud rateUBRR0H= (BAUDRATE>>8);UBRR0L=BAUDRATE;// Enable transmitter and receiverUCSR0B= (1<<RXEN0) | (1<<TXEN0);// Set frame format: 8 data bits, 1 stop bitUCSR0C= (1<<UCSZ01) | (1<<UCSZ00);}// Send a byte via UARTvoid uartTransmit(char data) {// Wait for empty transmit bufferwhile (!(UCSR0A& (1<<UDRE0)));// Put data into buffer, sends the dataUDR0=data;}// Receive a byte via UARTchar uartReceive(void) {// Wait for data to be receivedwhile (!(UCSR0A& (1<<RXC0)));// Get and return received data from bufferreturnUDR0;}// Send a string via UARTvoid uartSendString(const char *str) {while (*str) {uartTransmit(*str++);}}void lightLed(uint8_t n) {for (uint8_ti=0; i<n; i++) {PORTB|=1<<LED;_delay_ms(200);PORTB&=~(1<<LED);_delay_ms(200);}}Quote from arcachofo on November 18, 2024, 9:55 amHi.
Serial Terminal does not have any limitations other that the minimum time in the simulation = 1ps.
So theoretically it could run well beyond thouthands of Gbps.Seems that the problem is in the calculation of UBRR.
This formula: UBRR0 = (F_CPU / (BAUD * 16)) - 1 has an error, it is a truncated integer.
In this case the actual value is 7.68, so it should be rounded to 8.In the datasheet you can see the example value for 16 MHz, 115200 is 8:
Hi.
Serial Terminal does not have any limitations other that the minimum time in the simulation = 1ps.
So theoretically it could run well beyond thouthands of Gbps.
Seems that the problem is in the calculation of UBRR.
This formula: UBRR0 = (F_CPU / (BAUD * 16)) - 1 has an error, it is a truncated integer.
In this case the actual value is 7.68, so it should be rounded to 8.
In the datasheet you can see the example value for 16 MHz, 115200 is 8:

