1

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

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

在数据表中,他们提到了使用URSEL位在两个寄存器之间进行选择,但不知何故我不明白。

4

1 回答 1

5

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

当对该 I/O 位置进行写访问时,写入值的高位,即 USART 寄存器选择 (URSEL) 位,控制将写入两个寄存器中的哪一个。如果在写操作期间 URSEL 为零,则 UBRRH 值将被更新。如果 URSEL 为 1,则将更新 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/你得到。如果您立即再次阅读,您将阅读。但正如文档所暗示的,没有真正的理由去读取这些寄存器。您似乎不信任数据表,但这是一个错误:数据表是有关此类问题的最佳信息来源:没有数据表,我们将一事无成。UCSRCUBRRHUCSRC

于 2013-04-05T20:47:56.907 回答