我正在尝试用ATMEGA32进行串行通信,我有一个问题:
在异步串行通信中,UBRRH和UCSRC寄存器具有相同的位置。我不知道该位置将在哪些条件下充当UBRRH,以及在哪些条件下,它将充当UCSRC。根据分配给这些寄存器的工作,我需要为每个寄存器指定不同的值
在数据表中,他们提到了使用URSEL位在两个寄存器之间进行选择,但不知何故,我不太理解。
发布于 2013-04-06 04:47:57
答案是:是的,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 setURSEL位只是一个高位。因此,无论您写入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。但正如文档所暗示的那样,没有真正的理由去读取这些寄存器。看起来您不信任数据表,但这是一个错误:数据表是关于这类问题的最佳信息来源:没有数据表,我们将一事无成。
https://stackoverflow.com/questions/15841050
复制相似问题