嵌入式设计应用
摘 要: 本文讨论了UART的软件实现方法,介绍了Holtek单片机在工业应用中用软件构成UART的接口电路。
在各种MCU应用系统中,经常需要与其他的设备或系统进行数据通讯,UART是比较常用的一种通讯模式。当应用系统要求多路UART,或者基于性能、成本综合考虑选用了不带UART的MCU时,我们可以考虑用软件构建UART以实现系统的数据通讯要求。
有人对软件UART工作效率和可靠性持否定态度。事实上系统要求的各项功能的实现是采用软件还是硬件,通常要综合考虑系统要求、可支配资源、成本。最后的结果总是在考虑上述因素之后的一个折衷。如果系统本身实时性要求不是很高,而MCU的其他资源又允许的话,完全可以以软件的方式构造合乎使用要求的软件UART。
图1 复费率电表中的485接口电路
图2 起始位确认、数据采样
图3 发送准备
图4 按位发送
图5 UART接收状态转换图
UART
串行数据通讯时,数据按位传送,任何时候线上仅有一位数据。因此收、发双方必须同步,以从二进制位流中正确地读出每一位数据。异步串行通讯中,收、发方的同步不采用时钟线来进行,而是由通讯双方约定一个波特率,每一个传送单元通过一个“起始位”来同步。当接收方监测到一个有效起始位,便按照约定的波特率的一个倍频(例如16倍频)对数据进行采样接收。由于每一个传送单元的位数较少(通常不超过11位),而接收采样的频率要高于通讯波特率,即使收发双方的时基存在一定误差,仍然可以保证准确的通讯。
在空闲状态,传送线为逻辑“1”状态。数据的传送总是以一个“起始位”开始的,接着是要传送的若干数据位,低位先行,最后是一个“1”状态的“停止位”。例如在文档中用“9600 N.8.1”描述一个UART,就表示UART使用9600bps的波特率,帧格式为一个起始位、8个数据位、一个停止位。
当接收方检测到一个“1”向“0”的跳变,便视为可能的起始位。起始位被确认后,依次接收数据位和停止位,若检测不到正确的停止位,可视为传送出错而放弃。
下面以Holtek的HT49R70在复费率电表中的应用为例,说明如何实现一个符合实际使用要求的软件UART。
硬件接口
HT49R70片内集成了41×3或40×4段的LCD驱动器,特别适用于多种LCD低功耗应用。单周期指令和二级流水线结构使得HT49系列适合各种高速处理的应用。
HT49R70其他资源有:8K×16位的程序存储器ROM, 224×8位的数据存储器RAM,16级堆栈,8位输入口,16位双向输入/输出口,2个外部中断输入,一个8位和一个16位的带PFD(可编程分频器)功能可编程定时/计数器,看门狗定时器,带8位前置分频器的RTC,蜂鸣器输出,内置晶振、RC和32768Hz的振荡电路,低电压复位电路。
图1为复费率电表中的485接口电路。这里使用了3根口线,配合MAX481实现一个半双工的485接口。
由于应用中的其他任务对实时性的要求,这里使用了一个外部中断作为接收线,用来捕捉起始位。有的完全使用普通口线实现软件UART,这种做法从原理上是可能的,但是必须以查询方式捕捉起始位,要求有较高的MCU时钟,并且对主程序的运行效率有较大的影响。在使用外部中断后,UART部分仅在通讯发生时才占用MCU,空闲时对主程序没有影响。
软件实现
用软件实现UART时,本机发送相对容易,只要按UART时序要求在发送线上维持正确的电平即可。关键是数据接收,对接收方而言,接收事件的发生完全是随机的。必须监视接收线上任何时刻的电平变化,一旦确认收到有效的起始位,软件UART即开始接收数据。
波特率发生
使用一个定时器为接收和发送产生波特率。由于使用的是软件UART,发送和接收时的时基频率是不一样的。发送时的时基频率与通讯波特率相同,而接收时接收数据的采样频率实际为波特率的16倍频。这里最终实现的是一个半双工的485接口,发送和接收不会同时发生,因而可以用一个定时器来产生发送和接收所需的时间基准。
例如,对应1200bps的波特率,数据每一位的宽度为Td=s=833ms。发送数据时,每一位数据的电平都必须维持这个宽度。接收数据时以波特率的16倍频采样,采样周期为Tw==52ms。(见图2)。
发送
数据发送只需按照UART时序在发送线上产生波形即可。 图3中Send函数准备好发送数据,Timer1设为833ms定时,并且开放中断,同时将通讯状态置为忙。
图4中ISRTimer1Send为Timer1中断服务程序中处理发送的函数,ISRTimer1Send函数将包括起始位、数据位、停止位的数据按规定的顺序和宽度,按位发送到发送端上。直到所有位发送完毕,将通讯状态置为空闲。
接收
接收不是由本机启动,而是由一个外部事件触发的。 在空闲状态时,若接收线上出现一个下降沿,即视为一个可能的起始位,应该对其再次采样加以确定。一个真实的起始位,其低电平维持时间为Td。我们在起始位的中间时刻,以波特率的16倍频对接收线采样三次,经多数表决确认其电平状态。状态为高,表明是一个干扰信号,UART仍回到空闲状态。若确认接收线的状态为低,则这个起始位得到确认,UART开始接收后续数据。每一位的接收方式与起始位确认方式一样,UART对接收线的采样时序参见图2。接收完毕UART又回到空闲状态。如果最后的停止位出错,则这一帧数据接收失败,放弃接收到的数据。UART的接收状态转换图见图5。
在UART的空闲状态,Rx的下降沿触发外部中断INT0,INT0中断服务程序将Timer1定时设为8Tw。时间到,Timer1定时改为Tw,以Tw为周期对Rx连续采样3次以确认起始位。
当起始位被确认,UART进入数据接收状态,Timer1定时改为14Tw以采样下一位数据,每一位数据也是以Tw为周期对Rx连续采样3次。这期间Timer1的定时会根据需要设为Tw或14Tw,参见图2。停止位接收完毕,标记接收有效或出错,同时UART回到空闲状态。
结语
本文介绍了用软件方式构建UART的一种方法,占用的MCU资源包括一个外部中断和一个定时/计数器。这种方法可以实现较高的通讯波特率,并且在通讯过程中仍可以保证主任务的实时性。采用8M晶振时,通讯波特率可以达到9600bps。以上方案在复费率电子电能表中得到了很好的验证。
全部0条评论
快来发表一下你的评论吧 !