ATMEGA32 UART通信

时间:2013-04-05 18:31:13

标签: serial-port avr atmel atmega usart

我正在尝试在ATMEGA32中进行串行通信,我有一个问题:

在异步串行通信中,UBRRHUCSRC寄存器具有相同的位置。我不知道该位置将作为UBRRH的哪些条件以及哪些条件,它将充当UCSRC。根据分配给这些寄存器的工作,我需要为每个寄存器提供不同的值

在数据表中,他们已经提到使用URSEL位来选择两个寄存器,但不知怎的,我没有得到它。

1 个答案:

答案 0 :(得分:5)

答案是:是的,URSEL位。根据数据表:

  

当对此I / O位置进行写访问时,该位的高位   写入的值,USART寄存器选择(URSEL)位,控制哪个   将要写入的两个寄存器之一。如果URSEL在期间为零   写操作时,UBRRH值将被更新。如果URSEL是一个,   UCSRC设置将更新。

这意味着,当您写信至UCSRC时,无论您希望将其放在哪个值,也请设置URSEL位(确保URSEL1 ):

UCSRC = (1<<URSEL)| ... whatever else ...

当您写入UBRRH时,请确保URSEL位必须为零。以下是一些不同的方法:

UBRRH = (0<<URSEL)| ... whatever else ...  // just showing that URSEL isn't set
UBRRH = ...some value...                   // simple not setting URSEL
UBRRH = (someValue)&(~(1<<URSEL)           // Ensuring that URSEL isn't set

URSEL位只是一个高位。因此,无论您写入UCSRC的任何值,请设置(打开,使1)高位(位7)。写入UBRRH时,请确保清除第7位。考虑它的另一种方式是,您写入UBRRH的每个值必须低于128.并且您想要写入UCSRC的每个值,向其添加128:这将打开第7位。只是作为解释的一种方式,上面的代码更清楚。


这是怎么做到的?我不知道,我不是uC设计师。似乎可能的是,相同的IO位置位置被映射到处理器中的两个不同寄存器。假设您有一个名为foo的寄存器,当您向其写入值时,uC会检查是否设置了高位。如果是,则将值写入内部存储单元1,如果不是,则将值写入内部存储单元2


如果正确使用URSEL位,则正确写入值。您的测试没有显示正确的值,因为您没有正确阅读它们。数据表的第162页:

  

对UBRRH或UCSRC寄存器进行读取访问更多   复杂的操作。然而,在大多数应用中,它很少   必须阅读任何这些寄存器。

     

读取访问由定时序列控制。读I / O.   位置一旦返回UBRRH寄存器内容。如果是注册   在先前的系统时钟周期读取位置,读取寄存器   在当前时钟周期中将返回UCSRC内容。注意   读取UCSRC的定时序列是原子操作。   因此必须控制中断(例如通过禁用   在读操作期间全局中断。

因此,当您第一次阅读UBRRH / UCSRC时,您会获得UBRRH。如果您立即再次阅读,请阅读UCSRC。但正如文档所示,没有真正的理由来阅读这些寄存器。您似乎不相信数据表,但这是一个错误:数据表是有关此类事项的最佳信息来源:没有数据表,我们将无处可去。