AVR UART 接收到错误的字节
AVR UART receives wrong bytes
经过长时间的停顿后,我再次开始对 AVR 进行编程。我能够在我的 Linux 计算机和 Atmega8 之间设置 UART 通信。不幸的是,当我发送大于 0x1f
的字节时,Atmega8 似乎接收到了错误的字节。
UART 是 运行 9600 BAUD 和数据格式 8N1.
// clock frequency 1Mhz
#define F_CPU 1000000UL
// baud rate
#define BAUD 9600
#define BAUDRATE ((F_CPU)/(BAUD*16UL)-1)
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdlib.h>
void uart_init (void);
void uart_putc (unsigned char data);
void uart_puts (unsigned char * str, uint8_t size);
// interrupt service routine for UART receiver interupt
ISR(USART_RXC_vect) {
// get received char
unsigned char received_char = UDR;
uart_puts("received=", 9);
if((received_char & (1<<7)) == (1<<7)) {
uart_putc('1');
} else {
uart_putc('0');
}
if((received_char & (1<<6)) == (1<<6)) {
uart_putc('1');
} else {
uart_putc('0');
}
if((received_char & (1<<5)) == (1<<5)) {
uart_putc('1');
} else {
uart_putc('0');
}
if((received_char & (1<<4)) == (1<<4)) {
uart_putc('1');
} else {
uart_putc('0');
}
if((received_char & (1<<3)) == (1<<3)) {
uart_putc('1');
} else {
uart_putc('0');
}
if((received_char & (1<<2)) == (1<<2)) {
uart_putc('1');
} else {
uart_putc('0');
}
if((received_char & (1<<1)) == (1<<1)) {
uart_putc('1');
} else {
uart_putc('0');
}
if((received_char & (1<<0)) == (1<<0)) {
uart_putc('1');
} else {
uart_putc('0');
}
uart_puts("\n\r",2);
}
// function to initialize UART
// dataformat 8N1
void uart_init (void) {
// shift the register right by 8 bits
UBRRH = (BAUDRATE>>8);
// set baud rate
UBRRL = BAUDRATE;
// enable receiver, transmitter and receiver interrupt
UCSRB|= (1<<TXEN)|(1<<RXEN)|(1<<RXCIE);
// 8bit data format
UCSRC|= (1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1);
}
// sends a single char over the UART
void uart_putc (unsigned char data) {
// wait while register is free
while (!( UCSRA & (1<<UDRE)));
// load data in the register
UDR = data;
}
// sends a string over the UART
void uart_puts (unsigned char * str, uint8_t size) {
uint8_t i;
for(i = 0; i < size; i++) {
uart_putc(str[i]);
}
}
// receives a single char over the UART
unsigned char uart_getc (void) {
// wait while data is being received
while(!(UCSRA) & (1<<RXC));
// return 8-bit data
return UDR;
}
uint8_t main (void) {
// enable interrupts
sei();
// enable uart
uart_init();
uart_puts("ready\n\r", 7);
while(1) {
}
return 0;
}
在 GtkTerm 中,我发送以下字节序列:0x01
、0x02
、0x03
、0x1d
、0x1e
、0x1f
、 0x20
中断服务例程 ISR 响应以下序列。
但是,我应该收到 received=00100000
0x20
怎么了?
来自我的评论:
可能是由于使用较慢的时钟速率/内部 RC 振荡器导致波特率关闭?波特率越慢,每个位与"middle"的偏移量就越大。这可能导致跳过位或控制器看到位两次。
经过长时间的停顿后,我再次开始对 AVR 进行编程。我能够在我的 Linux 计算机和 Atmega8 之间设置 UART 通信。不幸的是,当我发送大于 0x1f
的字节时,Atmega8 似乎接收到了错误的字节。
UART 是 运行 9600 BAUD 和数据格式 8N1.
// clock frequency 1Mhz
#define F_CPU 1000000UL
// baud rate
#define BAUD 9600
#define BAUDRATE ((F_CPU)/(BAUD*16UL)-1)
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdlib.h>
void uart_init (void);
void uart_putc (unsigned char data);
void uart_puts (unsigned char * str, uint8_t size);
// interrupt service routine for UART receiver interupt
ISR(USART_RXC_vect) {
// get received char
unsigned char received_char = UDR;
uart_puts("received=", 9);
if((received_char & (1<<7)) == (1<<7)) {
uart_putc('1');
} else {
uart_putc('0');
}
if((received_char & (1<<6)) == (1<<6)) {
uart_putc('1');
} else {
uart_putc('0');
}
if((received_char & (1<<5)) == (1<<5)) {
uart_putc('1');
} else {
uart_putc('0');
}
if((received_char & (1<<4)) == (1<<4)) {
uart_putc('1');
} else {
uart_putc('0');
}
if((received_char & (1<<3)) == (1<<3)) {
uart_putc('1');
} else {
uart_putc('0');
}
if((received_char & (1<<2)) == (1<<2)) {
uart_putc('1');
} else {
uart_putc('0');
}
if((received_char & (1<<1)) == (1<<1)) {
uart_putc('1');
} else {
uart_putc('0');
}
if((received_char & (1<<0)) == (1<<0)) {
uart_putc('1');
} else {
uart_putc('0');
}
uart_puts("\n\r",2);
}
// function to initialize UART
// dataformat 8N1
void uart_init (void) {
// shift the register right by 8 bits
UBRRH = (BAUDRATE>>8);
// set baud rate
UBRRL = BAUDRATE;
// enable receiver, transmitter and receiver interrupt
UCSRB|= (1<<TXEN)|(1<<RXEN)|(1<<RXCIE);
// 8bit data format
UCSRC|= (1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1);
}
// sends a single char over the UART
void uart_putc (unsigned char data) {
// wait while register is free
while (!( UCSRA & (1<<UDRE)));
// load data in the register
UDR = data;
}
// sends a string over the UART
void uart_puts (unsigned char * str, uint8_t size) {
uint8_t i;
for(i = 0; i < size; i++) {
uart_putc(str[i]);
}
}
// receives a single char over the UART
unsigned char uart_getc (void) {
// wait while data is being received
while(!(UCSRA) & (1<<RXC));
// return 8-bit data
return UDR;
}
uint8_t main (void) {
// enable interrupts
sei();
// enable uart
uart_init();
uart_puts("ready\n\r", 7);
while(1) {
}
return 0;
}
在 GtkTerm 中,我发送以下字节序列:0x01
、0x02
、0x03
、0x1d
、0x1e
、0x1f
、 0x20
中断服务例程 ISR 响应以下序列。
但是,我应该收到 received=00100000
0x20
怎么了?
来自我的评论:
可能是由于使用较慢的时钟速率/内部 RC 振荡器导致波特率关闭?波特率越慢,每个位与"middle"的偏移量就越大。这可能导致跳过位或控制器看到位两次。