我有一个ATMega16并且已经循环Rx Tx(只是将Rx连接到Tx),以便在循环中发送和接收一个char。但我似乎只接收0x00而不是我发送的字符。 我将CPU配置为1MHz。 但我的想法是,由于Rx和Tx只是循环,所以我设定的速度无关紧要,因为两者都是一样的?
所以基本上,我正在尝试在收到正确的字符时让一个LED在PORTC闪烁。
以下是代码:
#ifndef F_CPU
#define F_CPU 10000000
#endif
#define BAUD 9600
#define BAUDRATE ((F_CPU)/(BAUD*16)-1)
#include <avr/io.h>
#include <util/delay.h>
void uart_init(void){
UBRRH = (BAUDRATE>>8);
UBRRL = BAUDRATE;
UCSRB = (1<<TXEN) | (1<<RXEN);
UCSRC = (1<<URSEL) | (1<<UCSZ0) | (1<<UCSZ1);
}
void uart_transmit (unsigned char data){
while (!(UCSRA & (1<<UDRE)));
UDR = data;
}
unsigned char uart_recive(void){
while(!(UCSRA) & (1<<RXC));
return UDR;
}
int main(void)
{
uart_init();
unsigned char c;
PORTC = 0xff;
DDRC = 0xff;
while(1)
{
_delay_ms(200);
uart_transmit(0x2B);
c = uart_recive();
if(c==0x2B){
PORTC = PORTC ^ 0xff;
}
}
}
对我做错了什么的想法?
答案 0 :(得分:0)
代码似乎正确。
你可能需要检查:
'p'
之类的字符;现在您要发送'+'
我认为最后一个是问题。
您可以尝试使用ATMega手册中的代码:
/* Set frame format: 8data, 2stop bit */
UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
构建程序后,转到端口配置并确保它设置为8位数据格式和2个停止位。然后在你的微控制器上测试它,看看会发生什么。请回来看结果。
答案 1 :(得分:0)
考虑真实的波特率准确度。参见例如http://www.wormfood.net/avrbaudcalc.php?postbitrate=9600&postclock=1,AVR为9600波特@ 1MHz时钟提供7.5%的误差,这是一个相当高的误差。取决于您发送和接收的内容。 “通常”你可以看到垃圾,如果你永久收到0x00,它看起来像是另一个问题。
答案 2 :(得分:0)
您的F_CPU
设置为 10MHz 。
你很遗憾它被配置为1Mhz。
如果您确实激活了水晶,请检查您的保险丝。 如果你只是使用内部振荡器:它有一个相对较大的错误,因此你的UART时序可能会被破坏(我从来没有使用内部振荡器进行调试的问题)。
另一个错误来源可能是您的F_CPU
定义。大多数情况下,在Makefile(或IDE项目设置)中已经定义了此预处理器常量(可能也是错误的),因此自#define
#ifndef
没有影响
答案 3 :(得分:0)
PORTC引脚(TDI,TMS,TCK,SDA)始终为高电平,因为JTAG和JTAG的这些引脚默认使能。如果要在应用程序中使用PORTC,则必须通过设置熔丝位来禁用JTAG。对于atmega16,JTAGEN的熔丝位设置为1(表示未编程)。如果使用超过8MHz的熔丝位0(表示已编程)和1(表示未编程),则需要设置熔丝位,否则程序将产生意外或错误的结果,谢谢。