單片機C51編程幾個(gè)有用的模塊
通訊模塊
串口資源做為單片機與外界通信的常用手段,通訊模塊提供了完全緩沖的串口通訊底層機制,適用于長(cháng)度不大的數據包的發(fā)送及接收。如果處理關(guān)鍵數據,需要用戶(hù)自己提供糾錯協(xié)議。
通訊模塊由聲明文件SComm.h及實(shí)現文件SComm.c組成。
初始化:調用函數InitSCommModule()來(lái)初始化通訊模塊:
voidInitSCommModule(BYTEbyTimerReload,BITbitTurbo)
參數說(shuō)明:
byTimerReload:定時(shí)器1的重裝載初始值。
bitTurob:當此參數為T(mén)RUE時(shí),串行通訊在定時(shí)器1的溢出速率基礎上加倍。為FALSE時(shí),串行通訊速率為定時(shí)器1的溢出速率。
緩沖區:模塊使用了由宏SCOMM_SENDBUFSIZE、SCOMM_RECEBUFSIZE及SCOMM_PKGBUFSIZE所指定長(cháng)度的三個(gè)緩沖區,分別為發(fā)送、接收及數據包(用于處理接收到的數據)緩沖區(如果沒(méi)有使用異步接收功能,則不需要使用數據包緩沖區)。
在缺省時(shí),這三個(gè)宏都被定義為10,但用戶(hù)可以自已按照系統的RAM資源占用情況在Config.h中重定義緩沖區的大小。需要注意的是,如果緩沖的長(cháng)度不夠,當發(fā)送或接收長(cháng)數據包的時(shí)候可能會(huì )發(fā)生問(wèn)題,關(guān)于數據緩沖區的最小值的設置可以參考下面的說(shuō)明。
注意:需要盡快取出接收緩沖區中的數據,否則當緩沖區滿(mǎn)之后,新的數據將被簡(jiǎn)單的丟掉。
字節級服務(wù)函數:在Config.h文件中定義了宏SCOMM_DriverInterface(如:#defineSCOMM_DriverInterface),則可以使用字節級服務(wù)函數,即通訊模塊的底層函數。
共有兩個(gè)函數可以使用:
voidSendByte(BYTEbyData);
發(fā)送一個(gè)字節,如果當前緩沖區滿(mǎn),則等待。參數byData為要發(fā)送的數據。
BYTEReceByte();
接收一個(gè)字節,如果當前緩沖區中沒(méi)有數據,則此函數阻塞,直到接收到數據為止。接收到數據通過(guò)返回值返回。
可以通過(guò)調用IsSendBufEmpty()IsSendBufFull()IsReceBufEmpty()IsReceBufFull()宏來(lái)判斷緩沖區的空或滿(mǎn),以防系統阻塞。
不推薦直接使用這一級的服務(wù)函數,應該使用高層次上的服務(wù)函數或者在這一級服務(wù)函數的基礎上構造自己的通訊函數。
數據包級服務(wù)函數:在Config.h文件中定義宏SCOMM_PackageInterface(如:#defineSCOMM_PackageInterface)則可以使用數據包級服務(wù)函數。
共有兩個(gè)函數可以使用:
voidSendPackage(BYTE*pbyData,BYTEbyLen);
發(fā)送數據包,參數pbyData為將要發(fā)送的數據包緩沖區(數組)的指針,byLen為將要發(fā)送的數據包的長(cháng)度。
當沒(méi)有定義SCOMM_DriverInterface時(shí),數據被完全緩沖。即不能夠發(fā)送長(cháng)度超過(guò)發(fā)送緩沖區長(cháng)度的數據包。當定義了SCOMM_DriverInterface時(shí),采用單字節發(fā)送,這時(shí)不限制需要發(fā)送的數據的長(cháng)度。
BYTERecePackage(BYTE*pbyData,BYTEbyLen);
接收數據包,參數pbyData為存放將要接收的數據的緩沖區,byLen為緩沖區長(cháng)度。返回值為接收到的字節數,當模塊的接收緩沖區為空時(shí),函數非阻塞,立即返回,返回值為零。
同步發(fā)送接收服務(wù)函數:
比如在一個(gè)串行總線(xiàn)多機通訊系統中,主機需要定時(shí)循檢各從機的狀態(tài),往往是發(fā)一個(gè)包含從機地址及指令的數據包給從機,之后等待一定的時(shí)間,從機需要在這段時(shí)間之內給主機一個(gè)應答,如果沒(méi)有這個(gè)應答,則認為從機工作狀態(tài)出錯,轉去進(jìn)行相應的處理。在這個(gè)模型里,主機不能夠不進(jìn)行等待而給另一臺從機發(fā)送指令,也不能夠不管從機在很久沒(méi)有應答的情況下繼續等待。還有一種情況,比如當使用485總線(xiàn)進(jìn)行通信時(shí),如果是兩條通訊線(xiàn)則系統只能工作在半雙工模式下,總線(xiàn)在同一時(shí)間內只能工作在發(fā)送或接收,為了防止發(fā)送和接收相互干擾,這時(shí)的通訊常常需要使用同步發(fā)送和接收。
當在Config.h文件中定義宏SCOMM_SyncInterface后,則可以使用通訊模塊提供同步發(fā)送接收函數:
voidSendPackage(BYTE*pbyData,BYTEbyLen);
發(fā)送數據包,參數pbyData為將要改善的數據包的緩沖區指針,byLen為將要發(fā)送的數據包的長(cháng)度。
這個(gè)函數可以保證等待一個(gè)完整的數據包完全發(fā)送出去之后,它才返回,在這段時(shí)間內,它會(huì )阻塞運行。
BYTESyncRecePackage(BYTE*pbyBuf,BYTEbyBufLen,WORDwTimeout,BYTEbyParam);
接收數據包。返回值為接收到的數據包長(cháng)度。參數pbyBuf為將要接收數據包的緩沖區的指針,byBufLen為提供的緩沖區的長(cháng)度,wTimeout為通信超時(shí)值,如果在發(fā)生了由wTimeout所指定次數的時(shí)鐘中斷而還沒(méi)有接收到或沒(méi)有接收到完整的數據包時(shí),函數返回零,最后一個(gè)參數byParam的含義見(jiàn)后面的解釋。
異步發(fā)送接收服務(wù)函數:
在一個(gè)簡(jiǎn)單的系統或多機通訊系統中的從機上,一般情況下不需要復雜的停等的工作模式,而且往往單片機需要對硬件進(jìn)行控制和檢測,不允許長(cháng)時(shí)間的停下來(lái)檢測通訊,但又要求當需要通訊時(shí)需要盡快的反應速度,這時(shí)就需要使用異步發(fā)送和接收服務(wù)函數。
使用異步發(fā)送和接收服務(wù)函數需要在Config.h文件中定義SCOMM_AsyncInterface宏。
同樣提供兩個(gè)服務(wù)函數:
voidSendPackage(BYTE*pbyData,BYTEbyLen);
發(fā)送數據包,參數pbyData為將要改善的數據包的緩沖區指針,byLen為將要發(fā)送的數據包的長(cháng)度。
這里的函數的接口與同步發(fā)送和接收的服務(wù)函數相同。關(guān)于這里的細節,見(jiàn)后面對同步和異步服務(wù)函數的說(shuō)明。
voidAsyncRecePackage(BYTEbyParam);
接收數據包,參數byParam的意義見(jiàn)后面的描述。
使用異步通訊需要用戶(hù)定義一個(gè)回調函數,原型如下:
voidOnRecePackage(BYTE*pbyData,BYTEbyBufLen);
當異步接收服務(wù)函數接收到數據包之后,調用OnRecePackage回調函數,在pbyData指定的緩沖區中存放數據包,byBufLen為數據包的長(cháng)度。
在Config.h文件中定義宏SCOMM_TIMEOUT可以設定異步接收的超時(shí)值,當開(kāi)始接收數據包,但沒(méi)有收完數據而發(fā)生了SCOMM_TIMEOUT次時(shí)鐘中斷后,認為接收超時(shí),將已接收到的數據刪除。
同步和異步通訊服務(wù)函數:
有些情況下,比如一個(gè)通訊系統中,由一臺計算機通過(guò)串口控制主機,主機通過(guò)串口連接很多從機,主機的串口采用分時(shí)復用,在這樣的模型中,主機和控制計算機之間的通訊可以使用,異步通訊方式,而主機與從機可以使用同步通訊方式。而同步和異步的發(fā)送函數接口是相同的,在這樣的情況下,發(fā)送都是同步的。在這樣的模型中,當使用不同的接收函數之前,需要注意清除接收緩沖區中的內容,通訊模塊提供函數:ClearReceBuffer來(lái)做到這一點(diǎn),此函數原型如下:
voidClearReceBuffer();
通訊過(guò)程中,數據包往往是有固定的格式的,這種格式需要根據用戶(hù)所使用的協(xié)議的不同而不同。同步和異步接收服務(wù)函數支持從接收到的數據中識別出一定格式的數據包。
舉例說(shuō)明:目前使用的協(xié)議決定數據包的格式為固定的包頭0xff,固定的長(cháng)度4個(gè)字節。其它的細節在這里不重要,所以忽略掉。
評論