随着应用的需要,自动波特率已经不是什么新奇的概念了。在以前要实现自动波特率,一般都会用个定时器来计算数据长度,从而获取波特率。在NXP芯片的串口中直接添加了一个定时器,自动实现波特率的计算,只需要正确设置好寄存器就可以了,非常简单实用,下面我们就讲讲实现的方式以及注意事项。
下面我们以LPC1700系列芯片为例进行详细介绍说明:
lpc1700的四个UART都有UARTn Auto-baud控制寄存器寄存器,这个寄存器用于对自动波特率的设置,用户可以自由地读写。具体描述如下:
1.自动波特率(Auto-baud)
UARTn auto-baud功能可用于测量基于“AT”协议(Hayes命令)的输入波特率。如果auto-baud功能被使能,那么auto-baud功能部件将测量接收数据流中的1位所消耗的时间,并根据这个结果来设置除数锁存寄存器UnDLM和UnDLL。
Auto-baud功能是通过置位UnACR起始位来启动的,并通过清零UnACR起始位来停止。Auto-baud一旦结束,起始位就将自动清零,并且对该起始位进行读取将会返回auto-baud的状态(挂起/完成)。
可通过设置UnACR模式位来使用两种auto-baud测量模式。在模式0下,波特率是通过对UARTn RX管脚上两个连续的下降沿进行测量(起始位的下降沿和第一位的下降沿)来得到的。而在模式1下,波特率则是通过测量UARTn RX管脚上的下降沿和后续的上升沿之间的时间(起始位的长度)来得到的。
如果出现超时(速率测量计数器溢出),UnACR AutoRestart位可用于自动重启波特率测量。如果该位被置位,速率测量将会在UARTn RX管脚的下一个下降沿重新启动。
Auto-baud功能会产生两种中断:
UnIIR ABTOInt中断(UnIER ABToIntEn置位且自动波特率测量寄存器溢出);
UnIIR ABEOInt中断(UnIER ABEOIntEn置位且auto-baud已经成功完成)。
Auto-baud中断必须通过置位相应的UnACR ABTOIntClr位和ABEOIntEn位来清零。在auto-baud期间,小数波特率发生器通常被禁用(即DIVADDVAL = 0)。但是,如果波特率发生器被启动(即DIVADDVAL > 0),那么它将影响UARTn Rx管脚波特率的测量,但UnFDR寄存器的值在速率测量后不会被修改。此外,当使用auto-baud时,任何对UnDLM和UnDLL寄存器的写操作都必须在写UnACR寄存器之前完成。UARTn支持的最小和最大波特率受PCLK、数据的位数、停止位以及校验位的影响。
通过公式我们不难算出,外部晶振12MHz,CUP内核频率100MHz,外设频率为25MHz时,最小波特率为95,最大为142045。完全满足我们的所有需要。。。
2.Auto-baud模式
当软件执行“AT”命令时,它采用期望的字符格式对UARTn进行配置,并置位UnACR起始位。用户不必关心除数锁存器UnDLM和UnDLM内的初始值。由于字母“A”或“a”的ASCII编码(“A”= 0x41,“a”= 0x61)的关系,UART1 Rx管脚所发送的起始位以及期望字符的LSB是由两个下降沿来限定的。当UnACR起始位被置位时,auto-baud协议将执行以下阶段:
a) UnACR起始位一置位,波特率测量计数器立即复位,同时UARTn UnRSR复位。UnRSR波特率切换为最高速率。
b) UARTn Rx管脚上的下降沿触发起始位的开始。波特率测量计数器将开始对PCLK(可选择被小数波特率发生器预分频)进行计数。
c) 在接收起始位的过程中,RSR波特率输入端会产生16个脉冲,脉冲频率和(小数波特率发生器预分频)UARTn输入时钟相同,这样,保证了起始位存放在UnRSR中。
d) 在接收起始位的过程中(以及模式0下的字符LSB),速率计数器将随着被预分频的UART1输入时钟(PCLK)递增。
e) 如果是模式0,那么速率计数器将会在UARTn RX管脚的下一个下降沿停止。如果是模式1,那么速率计数器将会在UARTn RX管脚的下一个上升沿停止。
f) 速率计数器的值被载入到UnDLM/UnDLL中,并且波特率将会切换到正常操作模式。在设置完UnDLM/UnDLL后,如果auto-baud结束中断被使能,UnIIR ABEOInt将会被置位。接着UnRSR继续接受“A/a”字符剩下的其它位。