我试图做ATMEGA32串行通信和我有一个问题:ATMEGA32 UART通信
在异步串行通信都UBRRH
和UCSRC
寄存器具有相同的位置。我不知道哪个位置将作为UBRRH
的条件,并且在哪些条件下,它将作为UCSRC
。根据分配给这些寄存器的工作,我需要为每个寄存器设置不同的值
在数据表中,他们提到使用URSEL
位在两个寄存器之间进行选择,但不知何故,我没有那样做。
我试图做ATMEGA32串行通信和我有一个问题:ATMEGA32 UART通信
在异步串行通信都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
。但正如文档所述,读取这些寄存器没有真正的理由。看起来你不信任数据表,但这是一个错误:数据表是有关这些问题的最佳信息来源:没有数据表我们就无处可去。
但如何发生这种情况,因为两个寄存器具有相同的位置,那么他们如何可以有不同的值...........我已经尝试过URSEL = 1和0并调试代码,但是当它是0,那么两个寄存器都写入相同的值,但是当它为1时,没有任何寄存器被写入UCSRC = UCSRC =(1 << URSEL)| (1 << UCSZ1)| (1 << UCSZ0)只是在我的AtmelStudio 6.0调试器中不做任何事情,虽然URSEL已经设置好了,但是如果它是0,那么两者都是用相同的值写成......... – 2013-04-06 11:26:47
我没有犯任何冒犯,但如果你误解了我,我很抱歉:).........我正在调试我的代码,只是为了检查所有初始化是否已经正确完成,在这种情况下,我正面临着上述问题错误,所以我很困惑,不管我的代码是否会工作..........:(........但是,正如你曾经说过,我会问这个新的问题:) – 2013-04-06 17:46:54