楊 炯, 曹金華, 王宜懷
(蘇州大學(xué) 計(jì)算機(jī)科學(xué)與技術(shù)學(xué)院,江蘇 蘇州 215006)
串行通信接口(簡(jiǎn)稱串行口或串口,可簡(jiǎn)寫為UART,或SCI)在USB未普及之前,是PC機(jī)必備的通信接口之一。作為設(shè)備之間簡(jiǎn)便的通信方式,在相當(dāng)長(zhǎng)的時(shí)間內(nèi),串行口還不會(huì)消失,并且在市場(chǎng)上也可很容易地購(gòu)買到USB到串行口的轉(zhuǎn)接器。因?yàn)楹?jiǎn)單且常用,該通信只需要三根線(發(fā)送線、接收線和地線),所以UART仍然是MCU與外界通信的簡(jiǎn)便方式之一,為現(xiàn)實(shí)中的開發(fā)帶來極大方便。正因?yàn)樵撏ㄐ藕?jiǎn)單,在實(shí)際應(yīng)用中卻常常不敢使用而采用復(fù)雜的通信方式,比如CAN、USB、以太網(wǎng)等,其實(shí)通信穩(wěn)定可靠不在于協(xié)議復(fù)雜,而是有問題能否解決,據(jù)統(tǒng)計(jì),通信中如果出錯(cuò),而一位出錯(cuò)的可能很大[1],大約90%的誤碼率,所以抑制一位出錯(cuò),可以大大解決通信帶來的錯(cuò)誤。利用UART自身帶有的奇偶校驗(yàn)方式,因?yàn)槠媾夹r?yàn)?zāi)軝z驗(yàn)、但不能糾正一位錯(cuò)等缺陷,所以采用能自動(dòng)糾正一位錯(cuò)且檢驗(yàn)兩位錯(cuò)的海明碼方式。
2012年3月14日,ARM公司于中國(guó)上海發(fā)布了一款擁有全球最低功耗的微處理器ARM Cortex-M0+[2-3]。該處理器采用低成本的90納米低功耗(Low Power,LP)工藝,耗電量?jī)H為9 μA/MHz;飛思卡爾公司在以該微處理器為核的MKL25Z128VLK4[4-6](簡(jiǎn)稱KL25)芯片中,仍然包含了三個(gè)UART模塊,其實(shí)飛思卡爾的芯片大多數(shù)包含二個(gè)以上,遠(yuǎn)比其他通信模塊高,因此探討UART高可靠性應(yīng)用的研究實(shí)現(xiàn)具有非常現(xiàn)實(shí)意義。
為了方便軟件編程和推廣應(yīng)用,本文將研究UART通信結(jié)合海明碼校驗(yàn)技術(shù)形成UHM構(gòu)件[7-8](結(jié)合海明碼校驗(yàn)技術(shù)的UART通信構(gòu)件的簡(jiǎn)寫)的實(shí)現(xiàn)問題。
以ARM公司最新微處理器ARM Cortex-M0+的飛思卡爾KL25芯片為硬件基礎(chǔ)。
UART的通信運(yùn)用具有初始化、接收和發(fā)送三種基本操作[3,9-10]。
初始化基本操作,完成UART通信工作所需的時(shí)鐘源選擇、傳輸方式選擇、是否奇偶校驗(yàn)、數(shù)據(jù)幀格式等工作模式設(shè)置,以及反映傳輸速度的波特率設(shè)置。
發(fā)送基本操作,是通過移位寄存器將數(shù)據(jù)寄存器中字節(jié)型一幀數(shù)據(jù)的變成一位位串行數(shù)字,輸送至數(shù)據(jù)線上,發(fā)送時(shí)機(jī)是通過判斷狀態(tài)寄存器UARTx_S1的第7位(TDRE)進(jìn)行的。
若該位為0,說明發(fā)送緩沖區(qū)還沒有空閑,待發(fā)送的數(shù)據(jù)還不能裝入其中,需繼續(xù)等待,若該位為1,說明發(fā)送緩沖區(qū)空閑了,待發(fā)送的數(shù)據(jù)能裝入發(fā)送緩沖區(qū)中,以便發(fā)送出去。
發(fā)送基本語句(以C語言為例):
while((UART0_S1&(1<<7))==0); //UART0循環(huán)等待發(fā)送緩沖區(qū)空閑,以便能夠發(fā)送數(shù)據(jù)
UART0_D=SendData;
接收基本操作,是將數(shù)據(jù)線上的一位位數(shù)據(jù),接收下來并通過移位寄存器變成字節(jié)型一幀數(shù)據(jù)存入數(shù)據(jù)寄存器,接收時(shí)機(jī)是通過判斷狀態(tài)寄存器UARTx_S1的第5位(RDRF)進(jìn)行的。若該位為0,說明所接收的一幀數(shù)據(jù)還沒有都裝入接收緩沖區(qū),需繼續(xù)等待,若該位為1,說明所接收的一幀數(shù)據(jù)都裝入接收緩沖區(qū)中,可以將該幀取走,以便繼續(xù)接收下一幀。
接收基本語句(以C語言為例):
while(UART0_S1&(1<<5)==0); //UART0循環(huán)等待接收緩沖區(qū)裝滿,以便取走所接收的數(shù)據(jù)
ReData =UART0_D;
海明碼校驗(yàn)技術(shù)[11]是由Richard Hamming于1950年提出的,其實(shí)現(xiàn)原理是在信息碼中加入幾個(gè)校驗(yàn)位,將信息碼的每個(gè)二進(jìn)制位分配在幾個(gè)奇偶校驗(yàn)組中,若某一位(不論信息碼還是校驗(yàn)碼)出錯(cuò)后,根據(jù)所接收的海明碼進(jìn)行偶校驗(yàn),計(jì)算出哪位出錯(cuò),并糾錯(cuò)。
比如8位信息碼,為了便于計(jì)算哪位出錯(cuò),將信息碼(D8…D2D1)和校驗(yàn)碼(P4…P2P1)一起組合在海明碼(H12…H2H1)中,注:海明碼下標(biāo)從1開始計(jì)數(shù),信息碼順序不變填入海明碼中,但其中海明碼的下標(biāo)為2m留給校驗(yàn)碼填寫,即1、2、4、8位。為了區(qū)別一位出錯(cuò)還是兩位出錯(cuò),增加一位校驗(yàn)碼P5,在海明碼中位據(jù)H13。
為了便于編程,在此稍作變動(dòng),上述海明碼(H13…H2H1)本來需占用兩個(gè)字節(jié),但讓其中一個(gè)字節(jié)保存信息碼,一個(gè)字節(jié)保存校驗(yàn)碼,即只是不讓信息碼與校驗(yàn)碼不混排,但關(guān)系保持不變,在編程中會(huì)體現(xiàn)。
比如發(fā)送方信息碼為D8…D2D1,檢驗(yàn)一位錯(cuò)誤并糾正需要校驗(yàn)碼四個(gè),即P4、P3、P2、P1
設(shè)海明碼為H12H11H10H9H8H7H6H5H4H3H2H1
P4、P3、P2、P1根據(jù)規(guī)則,分別位于:H8、H4、H2、H1
而D8、D7、D6、D5、D4、D3、D2、D1分別位于:H12、H11、H10、H9、H7、H6、H5、H3
據(jù)海明碼校驗(yàn)規(guī)則[2],校驗(yàn)碼的值由下列公式1~4計(jì)算:
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)
為了分清是兩位出錯(cuò)還是一位出錯(cuò),還要補(bǔ)充一個(gè)總校驗(yàn)位P5,使:
(5)
P5位于H13。
為了方便編程,信息碼單獨(dú)占用一個(gè)字節(jié),校驗(yàn)碼占用一個(gè)字節(jié)的后5位。
由此編程實(shí)現(xiàn)發(fā)送方由信息碼得到校驗(yàn)碼,然后一起發(fā)送。
該函數(shù)頭如下。
//函數(shù)名稱:send_hmma
//函數(shù)參數(shù):data:8位信息碼。
//函數(shù)返回:產(chǎn)生校驗(yàn)位編碼(低5位有效)
//功能概要:發(fā)送方對(duì)8位信息碼產(chǎn)生5位校驗(yàn)碼
uint_8 send_hmma(uint_8 data)
接收方收到的海明碼,根據(jù)海明碼校驗(yàn)規(guī)則進(jìn)行校驗(yàn),先由式10校驗(yàn)是一位出錯(cuò)還是兩位出錯(cuò)。若一位出錯(cuò)再由式(6)~(9),檢驗(yàn)出錯(cuò)位置,即S4S3S2S1組合值反映該出錯(cuò)位置值。
若由式(10)得到兩位出錯(cuò),丟失所得數(shù)據(jù)。
為了方便編程,信息碼單獨(dú)占用一個(gè)字節(jié),校驗(yàn)碼占用一個(gè)字節(jié)的后5位。
由此編程實(shí)現(xiàn)由所接收的海明碼根據(jù)海明碼檢驗(yàn)規(guī)則判斷所接收數(shù)據(jù)是否正確,檢查發(fā)送過程中因干擾而出現(xiàn)的一位錯(cuò)誤并糾正,而保證接收方所接收信息的準(zhǔn)確。若多位錯(cuò)誤只能丟棄。
該函數(shù)頭如下。
//函數(shù)名稱:re_hmma
//函數(shù)參數(shù):*data:數(shù)據(jù)位(通過指針可返回糾正后數(shù)據(jù)值);
// check:校驗(yàn)位。
//函數(shù)返回:0=正確;1=兩位錯(cuò)
//功能概要:接收方對(duì)13位海明碼糾錯(cuò)并產(chǎn)生8位正確接收數(shù)據(jù)
uint_8 re_hmma(uint_8 *data,uint_8 check)
根據(jù)UART的初始化、接收和發(fā)送三種基本操作,按照構(gòu)件的思想[7],可將它們封裝成三個(gè)獨(dú)立對(duì)外的功能函數(shù),而海明碼的形成和檢錯(cuò)糾正函數(shù)為內(nèi)部的功能函數(shù)。UART初始化函數(shù)完成對(duì)UART模塊的工作屬性的設(shè)定,接收和發(fā)送功能函數(shù)則完成實(shí)際的通信任務(wù),其通信過程中的驗(yàn)錯(cuò)糾錯(cuò)由海明碼形成和檢錯(cuò)糾正功能函數(shù)完成。對(duì)UART模塊進(jìn)行編程,其中涉及到對(duì)硬件底層寄存器的直接操作,因此,可將初始化、接收、發(fā)送三種基本操作所對(duì)應(yīng)的功能函數(shù)共同放置在命名為uart.c的文件中,海明碼形成和檢錯(cuò)糾正函數(shù)作為內(nèi)部函數(shù)也放置在uart.c中,并按照相對(duì)嚴(yán)格的構(gòu)件設(shè)計(jì)原則[2]對(duì)其進(jìn)行封裝,同時(shí)配以命名為uart.h的頭文件,用來定義模塊的基本信息和對(duì)外接口。
根據(jù)以上構(gòu)件思想,形成以下三個(gè)對(duì)外函數(shù),其中初始化函數(shù)實(shí)現(xiàn)流程圖見圖1。
圖1 UART的初始化
初始化函數(shù)頭如下:
//函數(shù)名稱:uart_init
//功能概要:初始化uart模塊
//參數(shù)說明:uartNo:串口號(hào):UART_0、UART_1、UART_2
// sel_clk:選擇串口0時(shí),時(shí)鐘源為MCGIRCLK(4 000 Khz)或MCGPLL(48 000 Khz)
// 選擇串口1、2時(shí),時(shí)鐘源為BUSCLK(24 000 Khz)
// baud:波特率:300、600、1 200、2 400、4 800、9 600、19 200、115 200 bps
//函數(shù)返回:函數(shù)執(zhí)行狀態(tài):0=正常;非0=異常
//說 明:sel_clk若選擇內(nèi)部時(shí)鐘MCGIRCLK,波特率需小于19 200
void uart_init (uint_8 uartNo,uint_32 sel_clk,uint_32 baud_rate);
發(fā)送函數(shù)實(shí)現(xiàn)流程圖如圖2所示。
函數(shù)頭如下:
//函數(shù)名稱:uart_send1
//參數(shù)說明:uartNo: 串口號(hào):UART_0、UART_1、UART_2
// ch :要發(fā)送的字節(jié)
// yn :是否要海明碼校驗(yàn): yn =0,不要;yn =1,要
//函數(shù)返回:函數(shù)執(zhí)行狀態(tài):0=正常;非0=異常。
//功能概要:UART發(fā)送1個(gè)或者2個(gè)字節(jié)(2個(gè)中第一個(gè)為海明校驗(yàn)碼)
uint_8 uart_send1(uint_8 uartNo, uint_8 ch, uint_8 yn);
接收函數(shù)實(shí)現(xiàn)流程圖如圖3所示,函數(shù)頭如下。
//函數(shù)名稱:uart_re1
//參數(shù)說明:uartNo: 串口號(hào):UART_0、UART_1、UART_2
// fp:接收成功標(biāo)志的指針:*fp=0,成功接收;*fp=1,接收失敗
// yn:是否要海明碼校驗(yàn): yn=0,不要;yn=1,要
//函數(shù)返回:接收返回1個(gè)字節(jié)
//功能概要:UART共接收1個(gè)或者2個(gè)字節(jié)
uint_8 uart_re1 (uint_8 uartNo,uint_8 *fp, uint_8 yn);
圖2 uart_send1函數(shù)流程圖 圖3 uart_re1函數(shù)流程圖
為了檢驗(yàn)UHM構(gòu)件的驗(yàn)錯(cuò)糾錯(cuò)功能,在即將發(fā)送的海明碼里,有意改變其中某一位,使之成為錯(cuò)誤的編碼,再發(fā)送,接收方接到編碼,由程序處理,若糾錯(cuò)成正確碼,則說明該程序編程沒有問題,否則程序要調(diào)試修正。
為了UHM構(gòu)件的測(cè)試,搭建PC與MCU通信,PC方用C#語言編程實(shí)現(xiàn)串行口通信含海明碼校驗(yàn)進(jìn)行接收發(fā)送數(shù)據(jù)的功能。
運(yùn)行界面如圖4所示。通信測(cè)試方式有兩種:
(1) MCU端形成海明碼并發(fā)送海明碼,PC端接收海明碼并驗(yàn)錯(cuò)糾錯(cuò)。點(diǎn)擊“發(fā)送信息(Send Info)”,PC機(jī)將信息碼D8…D1發(fā)送給MCU,并將海明碼是否校驗(yàn)和人工干預(yù)的某位出錯(cuò)位號(hào)等指令也發(fā)送給MCU,MCU接收到信息碼后,按照指令將信息碼轉(zhuǎn)換為海明碼,及海明碼對(duì)應(yīng)位號(hào)數(shù)字變動(dòng),成為出錯(cuò)的海明碼,然后將出錯(cuò)的海明碼,發(fā)送給PC機(jī),PC機(jī)將進(jìn)行海明碼驗(yàn)錯(cuò)糾錯(cuò)處理,并顯示。
(2) PC端形成海明碼并發(fā)送海明碼,MCU端接收海明碼并驗(yàn)錯(cuò)糾錯(cuò)。通過串行口,點(diǎn)擊“發(fā)送數(shù)據(jù)(Send Data)”按鈕,PC機(jī)將信息碼D8…D1和校驗(yàn)碼P5…P1一起發(fā)送給MCU,其中含人工干預(yù)的某一位出錯(cuò),MCU接收到編碼后進(jìn)行海明碼驗(yàn)錯(cuò)糾錯(cuò)處理,再回送給PC機(jī)顯示。
圖4 測(cè)試UHM構(gòu)件的工程運(yùn)行界面
通過以上的KL25的UART通信的融入海明碼校驗(yàn)技術(shù)的編程設(shè)計(jì),構(gòu)建了3個(gè)可移植并重用于Freescale. Kinetis L系列所有UART的構(gòu)件,通過了測(cè)試并進(jìn)行了封裝,使得該校驗(yàn)技術(shù)UART通信的應(yīng)用變得易用又可靠。但在抗干擾非常強(qiáng)的場(chǎng)合,引起多位錯(cuò)差,這將無法糾正與檢測(cè)出來,可考慮采用檢錯(cuò)能力更強(qiáng)的編碼(如循環(huán)冗余校驗(yàn)碼),但冗余度相應(yīng)會(huì)大大增加?;蛘咴谟布矫嫱瑫r(shí)使用差分方式完善UART通信,差分方式的使用并不影響軟件編程,如此將大大提高UART的應(yīng)用前景。
本測(cè)試工程不僅應(yīng)用于系統(tǒng)開發(fā)中,而且是理解和掌握海明碼校驗(yàn)概念的好實(shí)驗(yàn)題材方案[12-13],完成項(xiàng)目與實(shí)踐教學(xué)的轉(zhuǎn)換[14-15],所以該測(cè)試工程已應(yīng)用于硬件實(shí)驗(yàn)室[16],輔助學(xué)生理解掌握概念。
[1] 趙軍軍.海明碼在微機(jī)信息傳輸中的糾錯(cuò)原理與應(yīng)用[J].寶雞文理學(xué)院學(xué)報(bào)(自然科學(xué)版),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] 王宜懷,朱仕浪,郭 蕓.嵌入式技術(shù)基礎(chǔ)與實(shí)踐教程(第3版)[M].北京:清華大學(xué)出版社,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轉(zhuǎn)換動(dòng)態(tài)在線校正技術(shù)[J].實(shí)驗(yàn)室研究與探索,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] 蔣銀珍,王宜懷,王加俊. 基于硬件構(gòu)件的底層軟件構(gòu)件開發(fā)方法研究[J].微計(jì)算機(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構(gòu)件的設(shè)計(jì)與實(shí)現(xiàn)[J].實(shí)驗(yàn)技術(shù)與管理,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] 王宜懷,曹金華.嵌入式系統(tǒng)設(shè)計(jì)實(shí)踐——基于飛思卡爾S12X微控制器[M].北京:北京航空航天大學(xué)出版社,2011:157-165.
[10] 王宜懷,陳建明,蔣銀珍.基于32位ColdFire構(gòu)建嵌入式系統(tǒng)[M].北京:電子工業(yè)出版社,2009:82-92.
[11] 王愛英.計(jì)算機(jī)組成與結(jié)構(gòu)(第5版)[M].北京:清華大學(xué)出版社,2013:62-64.
[12] 張清祥.探索實(shí)驗(yàn)教學(xué)載體,培養(yǎng)學(xué)生實(shí)踐創(chuàng)新能力[J].實(shí)驗(yàn)技術(shù)與管理, 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ì)算機(jī)專業(yè)實(shí)踐能力的研究與探索[J].計(jì)算機(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] 徐 昊.以“項(xiàng)目”為引擎,探索“工學(xué)結(jié)合”實(shí)踐教學(xué)新方法[J].計(jì)算機(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] 官 頌,張 鵬,董艇艦,等.擴(kuò)招背景下提高實(shí)踐教學(xué)質(zhì)量的方法研究與實(shí)踐[J].實(shí)驗(yàn)技術(shù)與管理, 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] 馬漢達(dá),鮑可進(jìn).計(jì)算機(jī)硬件課程實(shí)驗(yàn)教學(xué)改革與實(shí)踐[J].實(shí)驗(yàn)室研究與探索,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.