ATMEGA32 UART 通信
Posted
技术标签:
【中文标题】ATMEGA32 UART 通信【英文标题】:ATMEGA32 UART Communication 【发布时间】:2013-03-28 06:56:03 【问题描述】:我正在尝试在 ATMEGA32 中进行串行通信,但我有一个问题:
在异步串行通信中,UBRRH
和 UCSRC
寄存器具有相同的位置。我不知道该位置将充当UBRRH
的哪些条件,以及对于哪些条件,它将充当UCSRC
。根据分配给这些寄存器的工作,我需要为每个寄存器设置不同的值
在数据表中,他们提到使用URSEL
位在两个寄存器之间进行选择,但不知何故我不明白。
【问题讨论】:
【参考方案1】:答案是:是的,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
。但正如文档所暗示的,没有真正的理由去读取这些寄存器。您似乎不信任数据表,但这是一个错误:数据表是此类问题的最佳信息来源:没有数据表,我们将一事无成。
【讨论】:
但是这怎么会发生,因为两个寄存器都有相同的位置,那么它们怎么会有不同的值............我试过 URSEL =1 和 0 并调试代码,但是当它为 0 时,两个寄存器写入相同的值,但是当它为 1 时,没有一个寄存器被写入............UCSRC = UCSRC = (1 我没有任何冒犯,但如果你误会了我,我很抱歉:)............我正在调试我的代码只是为了检查所有初始化是否都有是否正确完成,在这种情况下,我面临上述错误,所以我很困惑我的代码是否会工作............:(............但作为你已经说过我要为此问一个新的问题:)以上是关于ATMEGA32 UART 通信的主要内容,如果未能解决你的问题,请参考以下文章