杨 炯, 曹金华, 王宜怀
(苏州大学 计算机科学与技术学院,江苏 苏州 215006)
串行通信接口(简称串行口或串口,可简写为UART,或SCI)在USB未普及之前,是PC机必备的通信接口之一。作为设备之间简便的通信方式,在相当长的时间内,串行口还不会消失,并且在市场上也可很容易地购买到USB到串行口的转接器。因为简单且常用,该通信只需要三根线(发送线、接收线和地线),所以UART仍然是MCU与外界通信的简便方式之一,为现实中的开发带来极大方便。正因为该通信简单,在实际应用中却常常不敢使用而采用复杂的通信方式,比如CAN、USB、以太网等,其实通信稳定可靠不在于协议复杂,而是有问题能否解决,据统计,通信中如果出错,而一位出错的可能很大[1],大约90%的误码率,所以抑制一位出错,可以大大解决通信带来的错误。利用UART自身带有的奇偶校验方式,因为奇偶校验能检验、但不能纠正一位错等缺陷,所以采用能自动纠正一位错且检验两位错的海明码方式。
2012年3月14日,ARM公司于中国上海发布了一款拥有全球最低功耗的微处理器ARM Cortex-M0+[2-3]。该处理器采用低成本的90纳米低功耗(Low Power,LP)工艺,耗电量仅为9 μA/MHz;飞思卡尔公司在以该微处理器为核的MKL25Z128VLK4[4-6](简称KL25)芯片中,仍然包含了三个UART模块,其实飞思卡尔的芯片大多数包含二个以上,远比其他通信模块高,因此探讨UART高可靠性应用的研究实现具有非常现实意义。
为了方便软件编程和推广应用,本文将研究UART通信结合海明码校验技术形成UHM构件[7-8](结合海明码校验技术的UART通信构件的简写)的实现问题。
以ARM公司最新微处理器ARM Cortex-M0+的飞思卡尔KL25芯片为硬件基础。
UART的通信运用具有初始化、接收和发送三种基本操作[3,9-10]。
初始化基本操作,完成UART通信工作所需的时钟源选择、传输方式选择、是否奇偶校验、数据帧格式等工作模式设置,以及反映传输速度的波特率设置。
发送基本操作,是通过移位寄存器将数据寄存器中字节型一帧数据的变成一位位串行数字,输送至数据线上,发送时机是通过判断状态寄存器UARTx_S1的第7位(TDRE)进行的。
若该位为0,说明发送缓冲区还没有空闲,待发送的数据还不能装入其中,需继续等待,若该位为1,说明发送缓冲区空闲了,待发送的数据能装入发送缓冲区中,以便发送出去。
发送基本语句(以C语言为例):
while((UART0_S1&(1<<7))==0); //UART0循环等待发送缓冲区空闲,以便能够发送数据
UART0_D=SendData;
接收基本操作,是将数据线上的一位位数据,接收下来并通过移位寄存器变成字节型一帧数据存入数据寄存器,接收时机是通过判断状态寄存器UARTx_S1的第5位(RDRF)进行的。若该位为0,说明所接收的一帧数据还没有都装入接收缓冲区,需继续等待,若该位为1,说明所接收的一帧数据都装入接收缓冲区中,可以将该帧取走,以便继续接收下一帧。
接收基本语句(以C语言为例):
while(UART0_S1&(1<<5)==0); //UART0循环等待接收缓冲区装满,以便取走所接收的数据
ReData =UART0_D;
海明码校验技术[11]是由Richard Hamming于1950年提出的,其实现原理是在信息码中加入几个校验位,将信息码的每个二进制位分配在几个奇偶校验组中,若某一位(不论信息码还是校验码)出错后,根据所接收的海明码进行偶校验,计算出哪位出错,并纠错。
比如8位信息码,为了便于计算哪位出错,将信息码(D8…D2D1)和校验码(P4…P2P1)一起组合在海明码(H12…H2H1)中,注:海明码下标从1开始计数,信息码顺序不变填入海明码中,但其中海明码的下标为2m留给校验码填写,即1、2、4、8位。为了区别一位出错还是两位出错,增加一位校验码P5,在海明码中位据H13。
为了便于编程,在此稍作变动,上述海明码(H13…H2H1)本来需占用两个字节,但让其中一个字节保存信息码,一个字节保存校验码,即只是不让信息码与校验码不混排,但关系保持不变,在编程中会体现。
比如发送方信息码为D8…D2D1,检验一位错误并纠正需要校验码四个,即P4、P3、P2、P1
设海明码为H12H11H10H9H8H7H6H5H4H3H2H1
P4、P3、P2、P1根据规则,分别位于:H8、H4、H2、H1
而D8、D7、D6、D5、D4、D3、D2、D1分别位于:H12、H11、H10、H9、H7、H6、H5、H3
据海明码校验规则[2],校验码的值由下列公式1~4计算:
P1=D1⨁D2⨁D4⨁D5⨁D7
(1)
P2=D1⨁D3⨁D4⨁D6⨁D7
(2)
P3=D2⨁D3⨁D4⨁D8
(3)
P4=D5⨁D6⨁D7⨁D8
(4)
为了分清是两位出错还是一位出错,还要补充一个总校验位P5,使:
(5)
P5位于H13。
为了方便编程,信息码单独占用一个字节,校验码占用一个字节的后5位。
由此编程实现发送方由信息码得到校验码,然后一起发送。
该函数头如下。
//函数名称:send_hmma
//函数参数:data:8位信息码。
//函数返回:产生校验位编码(低5位有效)
//功能概要:发送方对8位信息码产生5位校验码
uint_8 send_hmma(uint_8 data)
接收方收到的海明码,根据海明码校验规则进行校验,先由式10校验是一位出错还是两位出错。若一位出错再由式(6)~(9),检验出错位置,即S4S3S2S1组合值反映该出错位置值。
若由式(10)得到两位出错,丢失所得数据。
为了方便编程,信息码单独占用一个字节,校验码占用一个字节的后5位。
由此编程实现由所接收的海明码根据海明码检验规则判断所接收数据是否正确,检查发送过程中因干扰而出现的一位错误并纠正,而保证接收方所接收信息的准确。若多位错误只能丢弃。
该函数头如下。
//函数名称:re_hmma
//函数参数:*data:数据位(通过指针可返回纠正后数据值);
// check:校验位。
//函数返回:0=正确;1=两位错
//功能概要:接收方对13位海明码纠错并产生8位正确接收数据
uint_8 re_hmma(uint_8 *data,uint_8 check)
根据UART的初始化、接收和发送三种基本操作,按照构件的思想[7],可将它们封装成三个独立对外的功能函数,而海明码的形成和检错纠正函数为内部的功能函数。UART初始化函数完成对UART模块的工作属性的设定,接收和发送功能函数则完成实际的通信任务,其通信过程中的验错纠错由海明码形成和检错纠正功能函数完成。对UART模块进行编程,其中涉及到对硬件底层寄存器的直接操作,因此,可将初始化、接收、发送三种基本操作所对应的功能函数共同放置在命名为uart.c的文件中,海明码形成和检错纠正函数作为内部函数也放置在uart.c中,并按照相对严格的构件设计原则[2]对其进行封装,同时配以命名为uart.h的头文件,用来定义模块的基本信息和对外接口。
根据以上构件思想,形成以下三个对外函数,其中初始化函数实现流程图见图1。
图1 UART的初始化
初始化函数头如下:
//函数名称:uart_init
//功能概要:初始化uart模块
//参数说明:uartNo:串口号:UART_0、UART_1、UART_2
// sel_clk:选择串口0时,时钟源为MCGIRCLK(4 000 Khz)或MCGPLL(48 000 Khz)
// 选择串口1、2时,时钟源为BUSCLK(24 000 Khz)
// baud:波特率:300、600、1 200、2 400、4 800、9 600、19 200、115 200 bps
//函数返回:函数执行状态:0=正常;非0=异常
//说 明:sel_clk若选择内部时钟MCGIRCLK,波特率需小于19 200
void uart_init (uint_8 uartNo,uint_32 sel_clk,uint_32 baud_rate);
发送函数实现流程图如图2所示。
函数头如下:
//函数名称:uart_send1
//参数说明:uartNo: 串口号:UART_0、UART_1、UART_2
// ch :要发送的字节
// yn :是否要海明码校验: yn =0,不要;yn =1,要
//函数返回:函数执行状态:0=正常;非0=异常。
//功能概要:UART发送1个或者2个字节(2个中第一个为海明校验码)
uint_8 uart_send1(uint_8 uartNo, uint_8 ch, uint_8 yn);
接收函数实现流程图如图3所示,函数头如下。
//函数名称:uart_re1
//参数说明:uartNo: 串口号:UART_0、UART_1、UART_2
// fp:接收成功标志的指针:*fp=0,成功接收;*fp=1,接收失败
// yn:是否要海明码校验: yn=0,不要;yn=1,要
//函数返回:接收返回1个字节
//功能概要:UART共接收1个或者2个字节
uint_8 uart_re1 (uint_8 uartNo,uint_8 *fp, uint_8 yn);
图2 uart_send1函数流程图 图3 uart_re1函数流程图
为了检验UHM构件的验错纠错功能,在即将发送的海明码里,有意改变其中某一位,使之成为错误的编码,再发送,接收方接到编码,由程序处理,若纠错成正确码,则说明该程序编程没有问题,否则程序要调试修正。
为了UHM构件的测试,搭建PC与MCU通信,PC方用C#语言编程实现串行口通信含海明码校验进行接收发送数据的功能。
运行界面如图4所示。通信测试方式有两种:
(1) MCU端形成海明码并发送海明码,PC端接收海明码并验错纠错。点击“发送信息(Send Info)”,PC机将信息码D8…D1发送给MCU,并将海明码是否校验和人工干预的某位出错位号等指令也发送给MCU,MCU接收到信息码后,按照指令将信息码转换为海明码,及海明码对应位号数字变动,成为出错的海明码,然后将出错的海明码,发送给PC机,PC机将进行海明码验错纠错处理,并显示。
(2) PC端形成海明码并发送海明码,MCU端接收海明码并验错纠错。通过串行口,点击“发送数据(Send Data)”按钮,PC机将信息码D8…D1和校验码P5…P1一起发送给MCU,其中含人工干预的某一位出错,MCU接收到编码后进行海明码验错纠错处理,再回送给PC机显示。
图4 测试UHM构件的工程运行界面
通过以上的KL25的UART通信的融入海明码校验技术的编程设计,构建了3个可移植并重用于Freescale. Kinetis L系列所有UART的构件,通过了测试并进行了封装,使得该校验技术UART通信的应用变得易用又可靠。但在抗干扰非常强的场合,引起多位错差,这将无法纠正与检测出来,可考虑采用检错能力更强的编码(如循环冗余校验码),但冗余度相应会大大增加。或者在硬件方面同时使用差分方式完善UART通信,差分方式的使用并不影响软件编程,如此将大大提高UART的应用前景。
本测试工程不仅应用于系统开发中,而且是理解和掌握海明码校验概念的好实验题材方案[12-13],完成项目与实践教学的转换[14-15],所以该测试工程已应用于硬件实验室[16],辅助学生理解掌握概念。
[1] 赵军军.海明码在微机信息传输中的纠错原理与应用[J].宝鸡文理学院学报(自然科学版),1997,17(1):54-58.
ZHAO Jun-jun. Error-correcting Principle And Applications In Microcomputer Information Transmission With Hamming code[J].Baoji University of Arts and Sciences Journals Press(Natural Science Edition),1997,17(1):54-58.
[2] ARM. Cortex-M0+ Technical Reference Manual Rev.r0p0[EB/OL]. http://www.freescale.com.cn,2012.
[3] 王宜怀,朱仕浪,郭 芸.嵌入式技术基础与实践教程(第3版)[M].北京:清华大学出版社,2013:26-155.
[4] Freescale. Kinetis L Peripheral Module Rev.0[EB/OL]. http://www.freescale.com.cn,2012.
[5] Freescale Inc. KL25 Sub-Family Reference Manual Rev.3[EB/OL]. http://www.freescale.com.cn,2012.
[6] 曹金华,贺黎潇,沈安东,等.基于KL25的AD转换动态在线校正技术[J].实验室研究与探索,2013,212(10):249-252.
CAO Jinhua,He Li-xiao,Shen An-dong.AD Conversion Technique of Online Dynamic Reviser Based on KL25[J].Research and Exploration in Laboratory, 2013,212(10):249-252.
[7] 蒋银珍,王宜怀,王加俊. 基于硬件构件的底层软件构件开发方法研究[J].微计算机信息, 2010,309(14):77-79.
JIANG Yin-zhen, WANG Yi-huai, WANG Jia-jun. Development Method Research for Bottom Driver Based on EHC[J].Microcomputer Information, 2012,185(2):91-94.
[8] 曹金华,李 映,沈安东,等. 基于XS128的P-Flash之ICP构件的设计与实现[J].实验技术与管理,2012(2):91-94.
CAO Jinhua,LI Ying,SHEN An-dong.Design And Implementation Based On XS128 P-Flash ICP Compents[J]. Experimental Technology and Management,2012(2):91-94.
[9] 王宜怀,曹金华.嵌入式系统设计实践——基于飞思卡尔S12X微控制器[M].北京:北京航空航天大学出版社,2011:157-165.
[10] 王宜怀,陈建明,蒋银珍.基于32位ColdFire构建嵌入式系统[M].北京:电子工业出版社,2009:82-92.
[11] 王爱英.计算机组成与结构(第5版)[M].北京:清华大学出版社,2013:62-64.
[12] 张清祥.探索实验教学载体,培养学生实践创新能力[J].实验技术与管理, 2012,29(2):130-133.
ZHANG Qing-xiang.Exploring A Carrier For Exercising Experiment And Practice And Cultivating Students’ Innovative Practice Ability[J]. Experimental Technology and Management, 2012,29(2):130-133.
[13] 李晓勇,周丽涛.提升计算机专业实践能力的研究与探索[J].计算机教育,2010(1):116-118.
LI Xiao-yong,ZHOU Li-tao. Research And Exploration Of Enhancing Computer Professional Practice.Competer Education, 2010(1):116-118.
[14] 徐 昊.以“项目”为引擎,探索“工学结合”实践教学新方法[J].计算机教育,2010(17):126-128.
XU Hua.Discussion on Work-integrated Learning Method Based on Engine of Projects[J].Competer Education,2010(17):126-128.
[15] 官 颂,张 鹏,董艇舰,等.扩招背景下提高实践教学质量的方法研究与实践[J].实验技术与管理, 2011,28(8):126-128,132.
GUAN Song,ZHANG Peng,DONG Tingjian,etal.Research and practice on improving quality of practical teaching under background of enrollment expansion[J].Experimental Technology and Management,2011,28(8):126-128,132.
[16] 马汉达,鲍可进.计算机硬件课程实验教学改革与实践[J].实验室研究与探索,2013(10):360-362.
MA Han-da,BAO Ke-jin.Reform and practice of experimental teaching of computer hardware[J].Research and Exploration in Laboratory, 2013(10):360-362.