首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ATMEGA32串口通信

ATMEGA32串口通信
EN

Stack Overflow用户
提问于 2013-04-06 02:31:13
回答 1查看 2.2K关注 0票数 1

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

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

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-04-06 04:47:57

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

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

这意味着,当您写入UCSRC时,无论您想要放入什么值,也要设置URSEL位(确保URSEL1):

代码语言:javascript
复制
UCSRC = (1<<URSEL)| ... whatever else ...

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

代码语言:javascript
复制
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清0。从另一种角度来看,您写入UBRRH的每个值都必须小于128。你想写到UCSRC的每一个值,加128 :这将打开第7位。这只是一种解释方式,上面的代码更清晰。

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

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

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

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

所以当你第一次读UBRRH / UCSRC的时候,你会得到UBRRH。如果你马上再读一遍,你就读到了UCSRC。但正如文档所暗示的那样,没有真正的理由去读取这些寄存器。看起来您不信任数据表,但这是一个错误:数据表是关于这类问题的最佳信息来源:没有数据表,我们将一事无成。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15841050

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档