c - Atmega32A 与 PC 上的 UART 通信

标签 c bit-manipulation uart

我是 AVR 微 Controller 编程的初学者,有时阅读数据表会让我感到非常头疼。 我正在尝试在我的 AVR 和 PC 之间进行通信,只是为了发送一些字符并在我的计算机上接收它。 整个程序中有两行我不明白,那就是:

 void USART_init(void)
{
    UBRRH = (uint8_t)(BAUD_PRESCALLER>>8); <---- this one!
    UBRRL = (uint8_t)(BAUD_PRESCALLER); <--- and this one
    UCSRB = (1<<RXEN)|(1<<TXEN);
    UCSRC = (1<<UCSZ0)|(1<<UCSZ1)|(1<<URSEL);
}

Datasheet

为什么我必须将 BAUD_PRESCALLER 改为 8?如果 BAUD_PRESCALLER 是一个数字,将该数字移动 8 并不意味着结果将为零?(因为我们移动它的次数太多了)

从数据表中我了解到UBRRH包含USART波特率的四个最高有效位,UBRRL包含USART波特率的八个最低有效位。(注:UBBR是一个12位寄存器)

那么我们实际上是如何将所有需要的数字放入 UBBR 寄存器中的呢?

最佳答案

您必须将其右移 8 位,因为 BAUD_PRESCALLER 的结果大于 8 位。将其右移 8 位即可得到 16 位值的最高有效字节。

例如,如果 BAUD_PRESCALAR 的值为 0x123,则 0x1 将分配给 UBRRH,0x23 将分配给 UBRRL。

如果库很聪明,它还可以对 BAUD_PRESCALAR 执行健全性检查,以确保它适合 16 位。如果不能,则意味着在给定您正在使用的时钟的情况下,您无法达到所需的波特率。如果您的 UBRRx 确实是 12 位,则健全性检查将如下所示:

#if BAUD_PRESCALAR > 0xFFF
#error Invalid prescalar
#endif

关于c - Atmega32A 与 PC 上的 UART 通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49348939/

相关文章:

c - PIC16F887 UART读取一个字符串,然后将该字符串切割成3个数组

linux - 为什么只有在按回车后才能在串行连接中接收到字符?

C++,协作 FILE* 和 std 流

c - 输入文件时出现 SegFault

更改 Char * 的内容

c++ - 有没有办法检测 C++ 中十六进制文字中输入了多少位数字?

c - 语句 if (counter & (1<<j)) 是什么意思,它是如何工作的?

usb - 为什么 usbser.sys 不与 USB CDC-ACM 设备一起使用?

c - C怎么知道我的字符串的结尾?

matlab - 在matlab中有效计算汉明权重