我正在尝试在 ATMEGA32 中进行串行通信,但我有一个问题:
在异步串行通信中,寄存器UBRRH
和UCSRC
寄存器都具有相同的位置。我不知道该位置将充当UBRRH
哪些条件,以及对于哪些条件,它将充当UCSRC
. 根据分配给这些寄存器的工作,我需要每个寄存器的不同值
在数据表中,他们提到了使用URSEL
位在两个寄存器之间进行选择,但不知何故我不明白。
我正在尝试在 ATMEGA32 中进行串行通信,但我有一个问题:
在异步串行通信中,寄存器UBRRH
和UCSRC
寄存器都具有相同的位置。我不知道该位置将充当UBRRH
哪些条件,以及对于哪些条件,它将充当UCSRC
. 根据分配给这些寄存器的工作,我需要每个寄存器的不同值
在数据表中,他们提到了使用URSEL
位在两个寄存器之间进行选择,但不知何故我不明白。
答案是:是的,URSEL
有点。根据数据表:
当对该 I/O 位置进行写访问时,写入值的高位,即 USART 寄存器选择 (URSEL) 位,控制将写入两个寄存器中的哪一个。如果在写操作期间 URSEL 为零,则 UBRRH 值将被更新。如果 URSEL 为 1,则将更新 UCSRC 设置。
这意味着,当您写入 时UCSRC
,无论您想放什么值,也要设置该URSEL
位(确保URSEL
是1
):
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