LPC1768的全双工UART的软件模拟实现※

2013-10-10 01:56郑志雄胡爱兰
单片机与嵌入式系统应用 2013年6期
关键词:数据位服务程序波特率

郑志雄,胡爱兰

(华北计算机系统工程研究所,北京100083)

引 言

在嵌入式系统开发过程中,用到UART串口的机率非常高,往往某些场合用到的个数还比较多,如笔者现在正在开发的项目,由于要具备多种上、下行通信方式,并且基本上都需要基于UART串口来实现,统计后发现至少需要6个串口,而市面上具备6个以上串口的价位适中的MCU又比较少见,这时串口的扩展往往就不可避免。还有一种情况,在某些低成本应用中,所选的MCU通常只有1~2个串口,此时如果MCU内部串口已作他用,但还想用串口实现某些功能,比较好的方法也只有通过串口扩展实现。

串口扩展有硬件扩展和软件扩展两种方式:硬件扩展主要是通过串口扩展芯片实现,常见的有16C550、SC16IS752/SC16IS762等,但会增加成本和占用板面空间;软件扩展就是利用MCU的GPIO引脚通过软件编程来模拟UART的发送和接收功能,该方式不仅灵活可靠,而且节约成本。本文主要是介绍UART串口的软件扩展方式。

目前有很多软件模拟串口的方案,其中大部分可以归结为两种实现方式:第一,采用软件延时来逐位输入、输出数据帧bit位;第二,利用MCU内部定时器定时输入、输出数据帧bit位。软件延时方式在发送或接收过程中会一直占用MCU,效率较低,这对于一些波特率要求不高、但实时性要求较高的工控场合并不适用;定时器方式在中断中接收,效率较高,但发送时往往还是采用阻塞式(持续判断定时器溢出标志位)的发送方式,总体上还是有些欠缺,而且两者都只能进行半双工通信。本文的实现方式也是采用定时器方式,但完全是在定时器中断服务中实现数据的发送和接收,经过测试发现,MCU的实际占用率可以降低到10%以下[1],具有较高的效率,很适合笔者所要开发的项目,并且还可以同时进行发送和接收,实现了全双工的异步串行通信方式。

1 UART串口简介

串行通信接口简称串口,分为异步和同步两种通信方式,这里用到的是异步串行通信接口,即UART。通常它的一帧数据帧是10位或11位,图1是一个11位的帧,包括1位起始位(0)、8位数据位、1位奇偶校验位和1位停止位(1)。通信双方必须采用相同的波特率(波特率即每秒收发的bit位数),严格按照双方约定的帧格式进行数据传输,且空闲状态下串口输入/输出线上保持高电平。

图1 UART串口11位帧结构

2 UART的软件模拟实现

2.1 模拟实现的基本思路

根据异步串行通信接口的工作方式,UART软件模拟实现的基本思路如下:在输入上,可以利用LPC1768定时器的捕获输入引脚(Capture Input)来捕捉起始位,在确定是起始位后,按照波特率设置好定时器匹配寄存器(Match Register),以一定的时间间隔来采样输入引脚上的电平,在确认校验位与停止位无误后,完成一帧数据的采样;在输出上,只要按照所需波特率设置好定时器,在每一个定时中断到来后,按照从低到高的顺序,逐位输出待发送数据帧的位即可,需要注意的是,空闲状态下输出引脚必须保持高电平。

基本思路是比较直接的、初步的实现方法,具体实现时,需要在基本思路的基础上做些改变。另外需要说明的是,在输入采样时,对每一数据位一般需要多次采样并确认一致后才完成输入,但经过实际测试与对其他方案[2-3]的研究发现,每一数据位仅采样一次也几乎没有错误发生,所以本文的程序仅在每一数据位传输的中间时刻采样一次。

2.2 具体的软件实现

选择 LPC1768[4]内部的定时器 Timer 0、相应的捕获输入引脚P1.26和通用GPIO口P1.28作为软件实现所需的硬件资源。让Timer 0工作在定时器模式(Timer Mode)下;开启P1.26引脚(CAP0.0)的下降沿捕获功能,使能其中断(在捕捉到起始位后,该引脚转换为GPIO输入模式);接收和发送共用匹配寄存器1(MR1),计数器(TC)值匹配(即溢出)后TC自动清零并中断;P1.28引脚配置为GPIO输出模式。

为了能在定时器中断服务程序中同时处理数据帧的接收和发送,作了以下设置:① 定义了两个全局变量Tx-Enable和RxEnable用于使能和停止发送、接收功能;②定时器溢出常数(写入MR1的值)设置为数据位宽度(波特率的倒数)的一半,即每半个bit周期中断一次;③ 定义两个全局变量,一个发送计数器TxCount和一个接收计数器RxCount。

在定时器中断服务程序中,主要处理两种类型的定时器中断:定时器捕获中断和定时器溢出中断。对前者的处理主要是开启数据接收功能,对后者的处理主要是进行数据的发送和接收。定时器中断服务程序的流程如图2所示。

图2 中断服务程序流程图

每次发送数据时使能发送功能(TxEnable=1)、启动定时器、TxCount赋值0,定时周期到后,从定时器中断服务程序中进入发送流程,判断TxCount的值,进行数据的发送,并相应地使发送计数器TxCount加1。发送程序流程如图3所示。

图3 发送程序流程图

接收数据由捕获中断触发开始,在定时器捕获中断服务程序中禁止捕获功能、启动定时器、使能接收、RxCount赋值0,定时周期到后,由定时器中断服务程序中进入接收流程,判断RxCount值,进行数据的采样接收,并使接收计数器RxCount加1。接收程序流程如图4所示。

图4 接收程序流程图

这里需要指出的是,在将方案用于实际系统时,一般需要将定时器中断设为最高的优先级,以保证发送、接收过程不会因为其他中断的长时间延时而受到影响从而导致数据丢失。

2.3 偶校验的实现

根据实际项目需要,在模拟串口中实现了偶校验功能。发送时,直接将偶校验输出位填入数据帧中;接收时,当接收到第10位时,将其与程序对前8位数据的偶校验输出进行对比,若一致则继续接收下一位,否则丢弃本次数据,重新开始下一帧的接收。偶校验程序如下:

2.4 发送、接收缓冲区的设计

为了给应用程序提供一个友好方便的接口,设计了发送和接收缓冲区,这样软件模拟串口就和硬件UART在使用上很接近了。缓冲区是两个先入先出(FIFO)的循环队列,其本质是两个无符号char型数组。为两个缓冲区分别定义了3个全局变量,对发送有:发送位置索引TxRdIndex,用于指示模拟串口下一个要发送的数据的位置;发送缓冲区写索引SWTxIndex,用于指示应用程序下一个要写入发送缓冲区的数据的写入位置;发送缓冲区数据个数TxByteCnt,用于指示发送缓冲区中待发送的数据个数,示例如图5所示(方格左下角为数组下标)。接收缓冲区原理类似,不再赘述。

图5 发送缓冲区示例图

发送一个字节时,首先判断发送缓冲区是否满,若是则阻塞等待,直到有空的位置,否则写入数据。接着判断发送是否使能,否则开启发送功能、启动定时器、TxCount赋值0。然后即可退出发送字节函数,去执行其他程序,由定时器中断服务程序去执行数据的发送。

接收是在定时中断服务程序中完成的,接收完一字节就将它存入接收缓冲区,并置位相应的接收标志位。应用程序通过查询接收标志位和接收字节个数变量来读取接收到的数据。若存储数据时发现缓冲区已满,则放弃该字节的存储并置位接收缓冲区溢出标志位。

需要指出的是,实际测试发现,缓冲区的长度对系统的整体运行效率影响很大[5],所以实际应用时应根据需要定义合适长度的缓冲区。

源程序见本刊网站 www.mesnet.com.cn——编者注。

3 测试结果

编写了以下程序来对软件模拟串口代码进行测试:

软件UART测试如图6所示。测试时,上位机打开两个串口调试助手,一个通过串口1与UART0连接,另一个通过USB转的串口8与软件UART连接,准备一系列随机的字节数据用于向软件UART发送。下位机电路板运行时,可以通过连接串口8的调试助手看到不断收到数据“88”,同时通过发送区将准备的一系列数据发送出去,马上就会看到连接串口1的调试助手收到刚发送出去的数据。仔细比对后,没有发现错误。然后将发送区的数据连续多次发送出去,对比发送、接收的数据个数,发现二者是一致的,再选取发送、接收的部分数据进行对比,也无错误发生。测试结果可以看出,该软件串口在全双工通信状态下的运行是稳定和可靠的。另外,经测试,该软件串口在“背靠背”传输模式(发送、接收引脚短接)下工作也是正常的。表1为在LPC1768几个工作主频下软件UART正常稳定工作的波特率范围(定时器的PCLK=CCLK)。

表1 LPC1768几个工作主频下的软件UART正常稳定工作的波特率范围

结 语

对比本文,参考文献[5]也实现了一种全双工UART的软件模拟方案,但该方案实现方式比较复杂,代码量较大,移植也不方便,且不允许“背靠背”模式传输(无法在较严格的全双工模式下运行)。与之相比,本文的实现方案具有较大的突破,具有较强的使用价值。另外值得一提的是,若不要求在全双工方式下通信,可以对方案稍加修改,可最终使得软件UART达到很高的波特率要求。

图6 软件UART测试结果

[1]广州致远电子有限公司.I/O模拟 UART实现[EB/OL].[2013-01-21].http:www.zlgmcu.com.

[2]吕刚,李强.AVR单片机软件模拟UART通信接口[J].单片机与嵌入式系统应用,2003(2):73-76.

[3]刘亚平,刑济收,刘相权.AVR单片机串行口的软件扩展技术[J].北京信息科技大学学报:自然科学版,2010,25(4):53-56.

[4]NXP Semiconductors.LPC17xx User manual[EB/OL].[2012-12-02].http:www.nxp.com.

[5]NXP Semiconductors.Application Note:Full-duplex software UART for LPC111xand LPC13xx[EB/OL].[2012-12-02].http:www.nxp.com/documents/application_note/AN10955.pdf.

猜你喜欢
数据位服务程序波特率
UART 波特率检测电路的FPGA 设计算法与实现
A320飞机大气数据的采集和计算在排故中的应用
SylixOS系统的中断嵌套机制研究与实现
CAN 总线波特率自适应程序设计
基于C#的进程守护程序的设计
UDP穿透NAT技术实现数据唤醒车联网T-Box设备的方案
波特率自适应的CAN驱动在嵌入式Linux下的实现①
微弱GPS信号避开比特跳变的捕获算法
一种适用于FPGA系统中的变速箱电路设计
详解lAP15W4K58S4单片机的串行口通信