我正在尝试在ATMEGA32中进行串行通信,我有一个问题:
在异步串行通信中,UBRRH
和UCSRC
寄存器具有相同的位置。我不知道该位置将作为UBRRH
的哪些条件以及哪些条件,它将充当UCSRC
。根据分配给这些寄存器的工作,我需要为每个寄存器提供不同的值
在数据表中,他们已经提到使用URSEL
位来选择两个寄存器,但不知怎的,我没有得到它。
答案 0 :(得分:5)
答案是:是的,URSEL
位。根据数据表:
当对此I / O位置进行写访问时,该位的高位 写入的值,USART寄存器选择(URSEL)位,控制哪个 将要写入的两个寄存器之一。如果URSEL在期间为零 写操作时,UBRRH值将被更新。如果URSEL是一个, 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
。但正如文档所示,没有真正的理由来阅读这些寄存器。您似乎不相信数据表,但这是一个错误:数据表是有关此类事项的最佳信息来源:没有数据表,我们将无处可去。