2013-04-05 63 views
1

我试图做ATMEGA32串行通信和我有一个问题:ATMEGA32 UART通信

在异步串行通信都UBRRHUCSRC寄存器具有相同的位置。我不知道哪个位置将作为UBRRH的条件,并且在哪些条件下,它将作为UCSRC。根据分配给这些寄存器的工作,我需要为每个寄存器设置不同的值

在数据表中,他们提到使用URSEL位在两个寄存器之间进行选择,但不知何故,我没有那样做。

回答

5

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

做这件事时的I/O位置的写入权限,则 价值的书面高位,USART寄存器选择(URSEL)位,控制这两个寄存器的 一个将被写入。如果在写操作 期间URSEL为零,则UBRRH值将被更新。如果URSEL为1,则 将更新UCSRC设置。

这意味着,当你写UCSRC,无论你想放有什么价值,还设置了URSEL位(确保URSEL1):

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。但正如文档所述,读取这些寄存器没有真正的理由。看起来你不信任数据表,但这是一个错误:数据表是有关这些问题的最佳信息来源:没有数据表我们就无处可去。

+0

但如何发生这种情况,因为两个寄存器具有相同的位置,那么他们如何可以有不同的值...........我已经尝试过URSEL = 1和0并调试代码,但是当它是0,那么两个寄存器都写入相同的值,但是当它为1时,没有任何寄存器被写入UCSRC = UCSRC =(1 << URSEL)| (1 << UCSZ1)| (1 << UCSZ0)只是在我的AtmelStudio 6.0调试器中不做任何事情,虽然URSEL已经设置好了,但是如果它是0,那么两者都是用相同的值写成......... – 2013-04-06 11:26:47

+0

我没有犯任何冒犯,但如果你误解了我,我很抱歉:).........我正在调试我的代码,只是为了检查所有初始化是否已经正确完成,在这种情况下,我正面临着上述问题错误,所以我很困惑,不管我的代码是否会工作..........:(........但是,正如你曾经说过,我会问这个新的问题:) – 2013-04-06 17:46:54