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 PB5
void 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 message
uartInit(); // Initialize UART
boolisCorrect=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 number
sprintf(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 UART
void uartInit(void) {
// Set baud rate
UBRR0H= (BAUDRATE>>8);
UBRR0L=BAUDRATE;
// Enable transmitter and receiver
UCSR0B= (1<<RXEN0) | (1<<TXEN0);
// Set frame format: 8 data bits, 1 stop bit
UCSR0C= (1<<UCSZ01) | (1<<UCSZ00);
}
// Send a byte via UART
void uartTransmit(char data) {
// Wait for empty transmit buffer
while (!(UCSR0A& (1<<UDRE0)));
// Put data into buffer, sends the data
UDR0=data;
}
// Receive a byte via UART
char uartReceive(void) {
// Wait for data to be received
while (!(UCSR0A& (1<<RXC0)));
// Get and return received data from buffer
returnUDR0;
}
// Send a string via UART
void 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 PB5
void 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 message
uartInit(); // Initialize UART
boolisCorrect=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 number
sprintf(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 UART
void uartInit(void) {
// Set baud rate
UBRR0H= (BAUDRATE>>8);
UBRR0L=BAUDRATE;
// Enable transmitter and receiver
UCSR0B= (1<<RXEN0) | (1<<TXEN0);
// Set frame format: 8 data bits, 1 stop bit
UCSR0C= (1<<UCSZ01) | (1<<UCSZ00);
}
// Send a byte via UART
void uartTransmit(char data) {
// Wait for empty transmit buffer
while (!(UCSR0A& (1<<UDRE0)));
// Put data into buffer, sends the data
UDR0=data;
}
// Receive a byte via UART
char uartReceive(void) {
// Wait for data to be received
while (!(UCSR0A& (1<<RXC0)));
// Get and return received data from buffer
returnUDR0;
}
// Send a string via UART
void 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: