基于双缓冲器的UART无线模块设计
2015-03-31邬芝权靳桅
邬芝权 靳桅
摘 要: 在无线通信环境下,基于UART接口的无线模块可以释放CPU软硬件资源、使用方便、用途广泛。通过介绍一种廉价的无线模块设计方案,根据nRF24L01 封装无线数据包和UART接口速度慢的特点,设计了对UART数据的发送和接收双缓冲器,开发软硬件,实现了可靠的无线数据通信。实验表明无线模块UART接口的可靠通信速率可以达到128 000 b/s,达到预期效果,满足大部分网络化条件下无线通信功能要求。
关键词: UART; NRF24L01; 缓冲器; 无线模块
中图分类号: TN911?34; TP368.1 文献标识码: A 文章编号: 1004?373X(2015)05?0005?04
Design of UART wireless module based on double buffers
WU Zhi?quan, JIN Wei
(Department of Computer and Communication Engineering in Emei Branch, Southwest Jiaotong University, Emei 614202, China)
Abstract: In the wireless communication environment, the wireless module based on UART interface can release the hardware and software resources of CPU. It′s easy to use, and has a wide range of applications. A low cost scheme to design wireless module is introduced in this paper. According to the encapsulation wireless data packet of nRF24L01 and the slow?speed feature of the UART interface, the double?buffer transmitting and receiving the UART data was designed, the corresponding software and hardware were developed, and the reliable wireless data communication was realized. Experiments show that the wireless module with UART interface achieves the desired effect, which implements a reliable transmission rate of [128 000 b/s,]and meets the most requirements of wireless communication function.
Keywords: UART; NRF24L01; buffer; wireless module
0 引 言
随着物联网技术发展需要,2.4 GHz 频段的无线应用得到了空前发展,无线空中传输速率较快,无线模块提供给用户使用的大多为SPI接口。相对于UART接口来说,SPI接口采用同步串行传输,传输速度较快,但是通信时传输距离短、要占用更多的CPU、内存和I/O接口资源。UART接口是全双工异步接口,大部分MCU自带这种接口,使用时编程简单,占用内存少。根据用户需要,可以将UART接口转换为RS 232电平或RS 422电平,延长传输距离,所以UART接口在控制类领域仍大量使用。
基于UART接口的无线模块,不用设计额外的电路和程序,可以按有线方式使多个节点进行通信,并且受地理条件限制少、安装灵活。本文依据市场发展需求,研究和设计了一种基于STC15W204S单片机和nRF24L01无线射频收发芯片实现的小成本、低功耗UART无线模块。
1 UART无线模块传输数据面临的问题及解决
方案
UART无线模块接口示意如图1所示,单片机STC15W204S一方面接收UART接口的数据和配置命令,另一方面通过SPI接口与nRF24L01进行通信,传送数据、命令、启动发送和检测接收等功能。在设计时一方面要解决各种接口速度不匹配问题,另一方面还要尽量提高数据传输速度。
1.1 速度匹配问题
通过对UART、SPI和无线这三种通信模式的数据传输速度分析来看,SPI通信的速度是由STC15W204S提供的时钟信号决定的,可以达到5 Mb/s;nRF24L01的无线数据包空中速率可以设置为250 Kb/s,1 Mb/s和2 Mb/s,速度虽然快,但数据是以数据包方式在空中传输,不具备连续性;UART传送数据的速度范围为每秒几百位到1.5 Mb/s,其速率受发送和接收线对距离(线长度)的影响非常大,常用速度一般不会超过128 Kb/s。由于三种通信模式的数据传输速度不一致,在数据传输过程中难免会有部分数据积压,需要合理的设置一段存储区来处理数据。
1.2 无线通信有效数据传输速率问题
nRF24L01的无线数据包包含前导码、地址、标志位、数据(1~32 B)和校验,发射时消耗在启动、发送接收模式切换和应答时间较长。由于数据包中数据长度可以设置1~32 B,其有效数据传输率相差很大。下面以发送一包数据时序来分析其有效数据传输速率,如图2所示,为增强型SchockBurstTM模式发送一个有效字节的数据包所需时间为339 μs,每增加一个有效字节仅需4 μs,设发送一包数据的时间为[TECB,]MCU上传数据至nRF24L01的时间为[TUL,]发送的有效字节数为[N,]则根据时序图可以得到公式(1):
当STC15W204S的晶振设为22.118 4 MHz时,经编程测试,[TUL]消耗时间为250 μs,故[TECB=250+][335+4N=][585+4N。]
其有效数据通信频率设为[F,]则得到公式(2):
[F=106TECB?N×8] (2)
将[TECB]的值代入公式(2)得到:
[F=106(585+4N)?N×8] (3)
当[N=1 ]B时,[F=]13.582 Kb/s;
当[N=32 ]B时,[F=]359.04 Kb/s。
由此可见,数据长度的大小很大程度上影响了无线数据传输效率,一个数据包中数据长度越大,则数据传输效率越高。
为了提高数据传输速率,每个无线数据包尽量包含更多的有效数据,但是两个无线数据包之间会有一定时间间隔,如果每个数据包都按最大有效数据量来打包,当UART接收数据量达不到打包条件时,则会使程序处于等待打包状态,即使可以增加延时退出程序来解决,由于消耗CPU时间较长导致实时性差。
如果每从UART接收一个数据就打包发送,虽然实时性高,但传输效率很差,经测试,在这种情况下,UART速度最大可设置为4 800 b/s。
所以在无线数据打包时,变长长度的数据包可以有效地解决数据传输速度和实时性问题。
2 解决方案
STC15W204S单片机的UART为全双工通信方式,但发送和接收缓冲器只有1个字节,为了解决数据传输的速度匹配和无线数据实时性较差这两个问题,需要设计一个缓冲区对接收和发送的数据进行缓存。在设计缓冲区时,除了考虑其大小来满足通信需要,还要考虑如何减少CPU处理数据的时间。首先确定UART数据缓冲区大小,设置数据写入和读出操作指针,指针通过取模的方式循环指向缓冲区内的位置。当接收新数据时,数据写入指针通过加1取模调整,然后写入数据,当从缓冲区读数据时,数据读出指针通过加1取模调整,然后取出数据。这样,缓冲区内部数据不需要进行移动,大大节省了CPU处理数据的时间。
当UART向无线接口发送数据时,将无线数据包的数据长度设置为32个字节,最后1个字节定义为有效数据长度,为了保障通信的实时性,只要UART接收缓冲区中有数据就启动一次无线打包发送程序,将数据全部打包传输,数据包的长度是变长的,不超过31个字节,最后1个字节为有效数据长度。这样既提高了数据传输效率,又保证传输实时性。
3 程序设计
在RAM中定义两个存储区,一个为接收缓冲区,一个为发送缓冲区。接收缓冲区长度宏定义为RECV_BUF_ LEN,发送缓冲区长度定义为TRANS_BUF_LEN,具体值通过宏定义设置。定义变量Recv_In_Pointer和Recv_Out_Pointer分别为接收缓冲区数据写入和读出指针,Trans_In_Pointer和Trans_Out_Pointer为发送缓冲区数据写入和读出指针,调整指针后,对指针取模,则指针固定指向某个范围区域,构成循环缓冲区。下面讨论UART接收数据缓冲区工作原理。
为了避免UART的接收和发送数据时使CPU处于等待状态,UART的接收和发送采用中断模式,在中断服务程序中再判断是接收中断还是发送中断。如果是接收中断则将UART数据写入接收缓冲区,并调整写入数据指针,使之指向下一个空数据项。如果是发送中断,则调整数据读出指针,如果发送缓冲区没有数据,则将发送数据结束标志置位。
设置RECV_BUF_LEN=16,在接收数据缓冲区,其初始状态为输入指针Recv_In_Pointer和输出指针Recv_Out_职Pointer都指向接收缓冲区位置0处,如图3(a)所示。当UART接收到数据,进入UART中断服务程序,将数据写入接收缓冲区Recv_In_Pointer指向的位置,然后调整指针Recv_In_Pointer,使其指向空数据项,同时将位变量Recv_End置1,表示接收缓冲区已有新数据,如图3(b)所示。当接收缓冲区有数据(Recv_End=1),CPU处理UART数据时,从接收缓冲区Recv_Out_Pointer指向的位置读出数据,然后调整指针Recv_Out_Pointer,使其指向下一个数据项,当Recv_In_Pointer和Recv_ Out_Pointer的值相同则表示接收缓冲区中无数据,同时将Recv_End清1。如果CPU不及时处理接收缓冲区中的数据,当UART接收数据过多时,就会使接收缓冲区溢出,如图3(d)所示。
下面介绍从UART接收到无线发送的部分程序。
UART中断接收部分程序如下:
void Serial_Int(void) interrupt 4 //串行口中断服务程序
{
if (_testbit_(RI)) //接收中断
{
Recv_Buf[Recv_In_Pointer]=SBUF;
//接收数据入接收缓冲区
Recv_Data=Recv_Buf[Recv_In_Pointer]; Recv_In_Pointer=(Recv_In_Pointer+1)%RECV_BUF_LEN;
Recv_End=1; //置串行口接收完成标志
}
……
}
CPU从UART读出一个字节程序如下:
unsigned char Serial_In(void)
{
unsigned char Temp_Data;
while ( Recv_Out_Pointer==Recv_In_Pointer ) ;
//无数据等待
Temp_Data=Recv_Buf[Recv_Out_Pointer];
//从接收缓冲区中读数据
Recv_Out_Pointer=(Recv_Out_Pointer+1)%RECV_BUF_ LEN;
if (Recv_Out_Pointer==Recv_In_Pointer )
Recv_End=0;
return Temp_Data; //返回接收数据
}
在无线打包程序设计过程中,数据包最大数据长度为32 B,采用变长数据发送模式,将数据包的最后1个字节用来表示有效数据长度,有效数据长度宏定义为TX_PLOAD_WIDTH,可以在编译之前设置,最大长度为31 B,无线打包发送程序如下:
if (Recv_End) //判断串行口缓冲器中是否有接收数据
{
if (nRF24L01_Tx_End==1)
{
Recv_Char = Serial_In(); //读UART接收数据
Tx_Buf[0] = Recv_Char; //写入无线发送缓冲区
nRF24L01_Tx_Len=1; //无线初始发送设置为1
while (Recv_End==1) //判断接收缓冲器还有数据
{
Tx_Buf[nRF24L01_Tx_Len]=Serial_In();
//写无线缓冲区
nRF24L01_Tx_Len++;
//无线发送有效数据长度加1
if (nRF24L01_Tx_Len>=(TX_PLOAD_WIDTH-1))
//过长
{
break;
}
}
Tx_Buf[TX_PLOAD_WIDTH-1]=Nrf24L01_Tx_Len;
//将无线发送缓冲区最后一个字节置为无线
发送的有效数据长度
nRF24L01_TxPacket(Tx_Buf);
//将启动nRF24L01发送
nRF24L01_Tx_End=0; //无线发送模式结束
}
对于UART发送数据缓冲区,它的工作是接收无线数据包至无线接收缓冲区,然后对数据进行分析,提取有效数据,通过UART口发出。由于无线数据包数据项的最后一个字节表示有效数据长度,通过这个字节就可以知道应该从无线接收缓冲区取出多少字节的数据。单片机在这方面处理的速度远远高于无线打包程序处理速度,所以这方面程序不需要过多优化。
4 测 试
测试时采用长数据串连续传输,传输时会将数据分成多个数据包,根据UART接收数据量的多少变长打包,当UART接收数据速度越快,则无线数据包中含有的有效数据量越大。由于无线数据包中的数据长度设置为32个字节,最后1个字节表示有效数据个数,只要有效数据量不超过31,就说明缓冲区不会溢出。
将两个UART无线模块连接至计算机,在程序代码中插入测试代码,将数据包中有效数据量返回,使用串口调试软件进行数据通信测试。其中一个无线模块用于接收数据,如图4(a)所示,串口号为COM8,另一个无线模块用于发送数据,如图4(b)所示,串口号是COM9,串口速率都设置为128 000 b/s,连续发送1 000个字符数据用于测试。测试结果表明,无线数据发送时封装为70个数据包,其中数据包最大有效数据长度为15,小于31个,从COM8接收到的数据也是1 000个字符,说明无线模块在该速率下传输是准确、可靠的。
根据这个方法对不同速率情况下,数据传输和打包情况测试结果如表1所示。
该结果说明当速率设置为4 800 b/s及以下时,可以实现串口数据实时打包传输,即每接收一个串口数据就立刻打包从无线端口送出,不需要设置缓冲区。当速率设置为9 600 b/s及以上时,会出现几个数据封装为一个无线数据包的情况,这种情况就必须要设置UART接收和发送缓冲区,才能实现可靠传输。
5 结 语
本无线模块经过多次测试检验是非常可靠的。考虑到无线模块不同的使用用户,作者为无线模块编写了配置程序,配置信息保存在E2PROM。配置内容包括波特率、无线频道、发送和接收通道地址、接收运行和自动应答等,用户在使用时只需配置一次即可。作者设计时采用了STC新款宽电压1T单片机STC15W204S,工作可靠,速度快,价格便宜。由于无线模块采用UART接口后,用户只需要安装UART接口编程即可,不用考虑无线数据收发问题,使用非常方便。
参考文献
[1] 李辉,宋诗,周建江.基于ARM和nRF24L01的无线数据传输系统[J].国外电子元器件,2008(12):44?46.
[2] 曾勇,杨涛,冯月晖.基于nRF24L01的超低功耗无线传感器网络节点设计[J].电子技术应用,2008(7):45?48.
[3] 刘志平,赵国良.基于nRF24L01的近距离无线数据传输[J].应用科技,2008(3):55?58.
[4] 刘超伟,赵俊淋,易卫东.基于nRF24L01的无线图像传感器节点设计实现[J].电子测量技术,2008(6):136?139.
[5] 黄秀节,颜可煌,赵伟.基于nRF24L01的无线USB控制系统[J].国外电子测量技术,2009(12):43?46.
[6] 韦积慧.基于nRF24L01的无线网络设计与实现[D].长春:吉林大学,2012.
[7] 郝文延,焦明华.基于DSP和nRF24L01的无线环境监测系统设计[J].单片机与嵌入式系统应用,2011(3):51?54.
[8] 杨旭,李德敏,张谦益.基于nRF24L01的一种无线通信协议设计[J].通信技术,2011(7):57?59.
[9] 朱慧彦,林林.基于MCU和nRF24L01的无线通信系统设计[J].电子科技,2012(4):81?83.