我如何修复此代码以允许我的AVR通过串口通话?

时间:2009-05-10 22:03:04

标签: embedded serial-port avr

我最近一直在拔我的头发试图让我的STK200上的ATmega162通过RS232与我的电脑通话。我检查并确保STK200包含MAX202CPE芯片。

我已经将芯片配置为使用其内部8MHz时钟并将其除以8。

我试图将代码复制出数据表(并在编译器抱怨的地方进行了更改),但无济于事。

我的代码如下,有人可以帮我解决我遇到的问题吗?

我已经确认我的串口可以在其他设备上运行而且没有故障。

谢谢!

#include <avr/io.h>
#include <avr/iom162.h>

#define BAUDRATE 4800

void USART_Init(unsigned int baud)
{
    UBRR0H = (unsigned char)(baud >> 8);
    UBRR0L = (unsigned char)baud;

    UCSR0B = (1 << RXEN0) | (1 << TXEN0);

    UCSR0C = (1 << URSEL0) | (1 << USBS0) | (3 << UCSZ00);
}

void USART_Transmit(unsigned char data)
{
    while(!(UCSR0A & (1 << UDRE0)));

    UDR0 = data;
}

unsigned char USART_Receive()
{
    while(!(UCSR0A & (1 << RXC0)));

    return UDR0;
}

int main()
{

    USART_Init(BAUDRATE);

    unsigned char data;

    // all are 1, all as output
    DDRB = 0xFF;

    while(1)
    {
        data = USART_Receive();

        PORTB = data;

        USART_Transmit(data);


    }
}

4 个答案:

答案 0 :(得分:6)

我对Greg的回答发表了评论,但是想补充一点。对于这类问题,调试它的黄金标准方法是首先理解异步串行通信,然后获取示波器并查看线路上发生了什么。如果正在交换字符并且这只是一个波特率问题,这将特别有用,因为您可以计算您看到的波特率,然后相应地调整除数。

这是一篇超级快速入门书,毫无疑问,你可以在维基百科或其他地方找到更全面的内容。

假设8位,无奇偶校验,1位停止位(最常见的设置)。然后,如果传输的字符是0x3f(= ascii'?'),那么该行看起来像这样;

...--+   +---+---+---+---+---+---+       +---+--...
     | S | 1   1   1   1   1   1 | 0   0 | E
     +---+                       +---+---+

高(1)电平在芯片上为+ 5V,在转换为RS232电平后为-12V。

低电平(0)在芯片上为0V,在转换为RS232电平后为+ 12V。

S是起始位。

然后我们有8个数据位,最低有效位,所以这里00111111 = 0x3f ='?'。

E是停止(e表示结束)位。

时间从左向右前进,就像示波器显示一样,如果波特率是4800,那么每个位跨越(1/4800)秒= 0.21毫秒(大约)。

接收器的工作原理是对线路进行采样并寻找下降沿(静态线路始终是逻辑“1”)。接收器知道波特率和起始位数(1),因此它从下降沿开始测量一个半位时间以找到起始位的中间位置,然后在此之后连续采样该位线8位以收集数据位。接收器然后再等待一个位时间(直到停止位的一半)并开始寻找另一个起始位(即下降沿)。同时,字符读取可供系统的其余部分使用。发送器保证在停止位完成之前不会开始下一个下降沿。可以将发送器编程为始终等待更长时间(带有额外的停止位),但这是一个传统问题,只有非常慢的硬件和/或软件设置才需要额外的停止位。

答案 1 :(得分:5)

我没有方便的参考资料,但波特率寄存器UBRR通常包含一个除数值,而不是所需的波特率本身。 quick google search表示4800波特的正确除数值可能是239.所以试试:

divisor = 239;
UBRR0H = (unsigned char)(divisor >> 8);
UBRR0L = (unsigned char)divisor;

如果这不起作用,请查看特定芯片的参考文档,了解正确的除数计算公式。

答案 2 :(得分:5)

要调试UART通信,有两件有用的事情要做:

1)在连接器上做一个环回,并确保你可以回读你写的内容。如果您发送一个字符并准确地将其恢复,您就知道硬件连接正确,并且至少UART寄存器配置的基本设置是正确的。

2)重复发送字符0x55(“U”) - 二进制位模式01010101将允许您快速查看示波器上的位宽,这样可以验证速度设置是否正确。

答案 3 :(得分:2)

在更详细地阅读数据表之后,我错误地设置了波特率。 ATmega162数据手册中有一个时钟频率图表,根据波特率和相应的误差绘制。

对于4800波特率和1 MHz时钟频率,误差为0.2%,这对我来说是可以接受的。诀窍是将12传递给USART_Init()函数,而不是4800。

希望这可以帮助其他人!