USART ATmega16的问题

时间:2014-03-08 09:17:39

标签: avr uart atmega

我有一个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;
        }
    }
}

对我做错了什么的想法?

4 个答案:

答案 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(表示未编程),则需要设置熔丝位,否则程序将产生意外或错误的结果,谢谢。