Kar*_*hah 1 avr atmega serial-port atmel usart
我想在ATMEGA32中进行串行通信,我有一个问题:
在异步串行通信中,两者UBRRH和UCSRC寄存器具有相同的位置 我不知道该位置将作为UBRRH哪个条件以及哪些条件,它将充当UCSRC.根据分配给这些寄存器的工作,我需要为每个寄存器提供不同的值
在数据表中,他们已经提到在URSEL两个寄存器之间使用位进行选择,但不知怎的,我没有得到它.
答案是:是的,URSEL有点.根据数据表:
在对此I/O位置进行写访问时,写入的值的高位USART寄存器选择(URSEL)位控制将写入的两个寄存器中的哪一个.如果在写操作期间URSEL为零,则将更新UBRRH值.如果URSEL为1,则将更新UCSRC设置.
这意味着,当你写入时UCSRC,无论你想要放在什么值,也要设置URSEL位(确保URSEL是1):
UCSRC = (1<<URSEL)| ... whatever else ...
Run Code Online (Sandbox Code Playgroud)
写入时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
Run Code Online (Sandbox Code Playgroud)
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.但正如文档所示,没有真正的理由来阅读这些寄存器.您似乎不相信数据表,但这是一个错误:数据表是关于此类事项的最佳信息来源:没有数据表,我们将无处可去.