我使用 Atmega 324p 每秒向 Arduino 发送字符“0”,但它收到的是:
串行监视器输出:
Char :⸮
Char :⸮
Char :⸮
Char :⸮
Char :⸮
Char :⸮
Char :⸮
Char :⸮
Char :⸮
Char :⸮
Char :⸮
Char :⸮
Char :⸮
使用的软件:
爱特梅尔7
Arduino 1.8.9
Arvdudess 2.11
爱特梅尔代码:
#include "avr/io.h"
#include "util/delay.h"
#define FOSC 1500000 //Clock speed
#define BAUD 9600
#define MYUBRR (FOSC/(16*BAUD-1))
void USART_Init(unsigned int ubrr){
/*Set baud rate */
UBRR0H = (unsigned char)(ubrr>>8);
UBRR0L = (unsigned char)ubrr;
/* Enable receiver and transmitter */
UCSR0B = (1<<RXEN0)|(1<<TXEN0);
/* Set frame format: 8data, 2stop bit */
UCSR0C = (1<<USBS0)|(3<<UCSZ00);
}
void USART_Transmit( unsigned char data ){
/* Wait for empty transmit buffer */
//while ( !( UCSR0A & (1<<UDRE)) );
/* Put data into buffer, sends the data */
UDR0 = data;
}
int main(void)
{
USART_Init(MYUBRR);
/* Replace with your application code */
while (1)
{
USART_Transmit('0');
_delay_ms(1000);
}
Arduino 代码:
char received_data; //variable to store read data
void setup() {
Serial.begin(9600);
}
void loop() {
if(Serial.available()>0) //check for any data received
{
Serial.print("Char :");
received_data = Serial.read(); //read received data
Serial.println(received_data); //display received data
}
}
Arvdudess配置:
电路草图:
编辑:当它得到简化并且其代码与网站引用的标签相关时,不理解愚蠢的问题关闭
更新:为了防止进一步混淆,我已将 arduino 代码更改为打印 3 次以及字符、十六进制和二进制结果
char received_data; //variable to store read data
unsigned long received_data2; //variable to store read data
byte received_data3; //variable to store read data
int printed=0;
void setup() {
Serial.begin(9600, SERIAL_8N2);
}
void loop() {
if(printed<3){
printed++;
Serial.print("Number of prints :");
Serial.println(printed); //display received data
while(Serial.available()<=0){ } //check for any data received
received_data = Serial.read(); //read received data
while(Serial.available()<=0) { } //check for any data received
received_data2 = Serial.read(); //read received data
while(Serial.available()<=0){ } //check for any data received
received_data3 = Serial.read(); //read received data
Serial.print("char :");
Serial.println(received_data); //display received data
Serial.print("hex :");
Serial.println (received_data2, HEX);
Serial.print("binary :");
Serial.println (received_data3);
}
}
这是 Serial.Monitor 输出:
Number of prints :1
char :
hex :0
binary :0
Number of prints :2
char :
hex :0
binary :0
Number of prints :3
char :
hex :0
binary :0
到目前为止在 atmega 上编辑代码
#include "avr/io.h"
#include "util/delay.h"
#define FOSC 1000000UL //Clock speed
#define BAUD 9600
#define MYUBRR (FOSC/(8*BAUD)-1)
void USART_Init(unsigned int ubrr){
/*Set baud rate */
UBRR0L = (unsigned char)ubrr; // First - low
UBRR0H = (unsigned char)(ubrr>>8); // Last - high
UCSR0A = (1<<U2X0);
/* Enable receiver and transmitter */
UCSR0B = (1<<RXEN0)|(1<<TXEN0);
/* Set frame format: 8data, 2stop bit */
UCSR0C = (1<<USBS0)|(3<<UCSZ00);
UBRR0 = ubrr;
}
void USART_Transmit( unsigned char data ){
/* Wait for empty transmit buffer */
while ( !( UCSR0A & (1<<UDRE0)) );
/* Put data into buffer, sends the data */
UDR0 = data;
}
int main(void)
{
USART_Init(MYUBRR);
/* Replace with your application code */
while (1)
{
USART_Transmit('0');
_delay_ms(1000);
}
}
尝试使用此代码试验“0”后的 30 个字符 >
Atmel code
#include "avr/io.h" #include "util/delay.h" #define FOSC 1000000UL //Clock speed #define BAUD 9600 #define MYUBRR (FOSC/(8*BAUD)-1) void USART_Init(unsigned int ubrr){ /*Set baud rate */ UBRR0L = (unsigned char)ubrr; // First - low UBRR0H = (unsigned char)(ubrr>>8); // Last - high UCSR0A = (1<<U2X0); /* Enable receiver and transmitter */ UCSR0B = (1<<RXEN0)|(1<<TXEN0); /* Set frame format: 8data, 2stop bit */ UCSR0C = (1<<USBS0)|(3<<UCSZ00); UBRR0 = ubrr; } void USART_Transmit( unsigned char data ){ /* Wait for empty transmit buffer */ while ( !( UCSR0A & (1<<UDRE0)) ); /* Put data into buffer, sends the data */ UDR0 = data; } int main(void) { USART_Init(MYUBRR); int i=0; /* Replace with your application code */ while (1) { USART_Transmit('0'+i); i++; _delay_ms(1000); } } **Arduino code** char received_data; //variable to store read data unsigned long received_data2; //variable to store read data byte received_data3; //variable to store read data int printed=0; void setup() { Serial.begin(9600, SERIAL_8N2); } void loop() { if(printed<30){ printed++; Serial.print("Number of prints :"); Serial.println(printed); //display received data while(Serial.available()<=0){} //check for any data received received_data = Serial.read(); //read received data while(Serial.available()<=0){} //check for any data received received_data2 = Serial.read(); //read received data while(Serial.available()<=0){} //check for any data received received_data3 = Serial.read(); //read received data Serial.print("char :"); Serial.println(received_data); //display received data Serial.print("hex :"); Serial.println (received_data2, HEX); Serial.print("binary :"); Serial.println (received_data3); } }
并在 Arduino 上给了我这个输出:
Number of prints :1 char :⸮ hex :C0 binary :0 Number of prints :2 char :⸮ hex :0 binary :0 Number of prints :3 char :⸮ hex :C0 binary :192 Number of prints :4 char : hex :C0 binary :0 Number of prints :5 char : hex :C0 binary :192 Number of prints :6 char : hex :C0 binary :0 Number of prints :7 char :⸮ hex :C0 binary :192 Number of prints :8 char : hex :C0 binary :192 Number of prints :9 char : hex :0 binary :192 Number of prints :10 char :⸮ hex :C0 binary :0 Number of prints :11 char :⸮ hex :C0 binary :0 Number of prints :12 char :⸮ hex :C0 binary :192 Number of prints :13 char :⸮ hex :C0 binary :192 Number of prints :14 char :⸮ hex :C0 binary :0 Number of prints :15 char :⸮ hex :C0 binary :192 Number of prints :16 char :⸮ hex :C0 binary :192 Number of prints :17 char :⸮ hex :0 binary :192 Number of prints :18 char :⸮ hex :C0 binary :0 Number of prints :19 char :⸮ hex :C0 binary :0 Number of prints :20 char :⸮ hex :C0 binary :192 Number of prints :21 char :⸮ hex :C0 binary :192 Number of prints :22 char :⸮ hex :0 binary :192 Number of prints :23 char :⸮ hex :C0 binary :192 Number of prints :24 char :⸮ hex :C0 binary :0 Number of prints :25 char :⸮ hex :C0 binary :192 Number of prints :26 char :⸮ hex :C0 binary :0 Number of prints :27 char :⸮ hex :C0 binary :0 Number of prints :28 char :⸮ hex :0 binary :0 Number of prints :29 char :⸮ hex :C0 binary :0 Number of prints :30 char :⸮ hex :0 binary :0
最佳答案
1) 在您的电路草图中,XTAL1
/XTAL2
上没有晶体。我假设它使用内部振荡器。
2) 内部振荡器为 8 MHz(请参阅数据表中的 10.6),并且由于您没有提供 FUSE 设置并且代码中没有预分频器设置,因此如果清除 CKDIV8 熔丝位,CPU 可能会以 8MHz 运行( = 1),或者如果该位被编程 (= 0),则为 1 MHz,在任何一种情况下,它都不能像 FOSC
中那样为 1500000
默认情况下,该位已编程,即它应该是:
#define FOSC 1000000UL // note the UL suffix for unsigned-long constants
3) 默认情况下,内部振荡器的工厂校准精度为±10%(参见数据表中的29.4.1.)
如果速度差异超过4%,UART将无法按预期工作,因此您需要校准速度或使用晶振。
4) 公式(FOSC/(16*BAUD-1))
有错误。除法后应减一。 IE。 (FOSC/(16 * BAUD) - 1)(另请记住,此公式将结果始终向下舍入,尽管这通常不是问题)
5) (FOSC/(16*BAUD)-1)
当 FOSC == 1000000
且 BAUD == 9600
时,结果将5,51 向下舍入为 5,导致有效波特率为 (1000000/(6 * 16)) = 10416 位每秒,这意味着 8.5% 的错误,导致 UART 无法使用。
要解决此问题,您可以在UCSR0A
寄存器中设置U2X
位:
UCSR0A = (1<<U2X);
并定义
#define MYUBRR (FOSC/(8*BAUD)-1)
这使得 MYUBRR = 12,02 向下舍入为 12,并将波特率设置为每秒 9615 位,误差小于 0.2%
已添加 6) 请参阅数据表8.6。访问 16 位寄存器:
For a write operation, the low byte of the 16-bit register must be written before the high byte. The low byte is then written into the temporary register. When the high byte of the 16-bit register is written, the temporary register is copied into the low byte of the 16-bit register in the same clock cycle.
因此而不是
UBRR0H = (unsigned char)(ubrr>>8);
UBRR0L = (unsigned char)ubrr;
应该是
UBRR0L = (unsigned char)ubrr; // First - low
UBRR0H = (unsigned char)(ubrr>>8); // Last - high
但是,由于 avr-gcc 可以为您处理这个问题,因此您可以在代码中使其更简单:
UBRR0 = ubrr;
关于c - 通过USART将数据从atmega324p发送到arduino,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59487494/