<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 單片機(jī)C51編程幾個(gè)有用的模塊

          單片機(jī)C51編程幾個(gè)有用的模塊

          作者: 時(shí)間:2012-07-04 來源:網(wǎng)絡(luò) 收藏


          通訊模塊
          串口資源做為與外界通信的常用手段,通訊模塊提供了完全緩沖的串口通訊底層機(jī)制,適用于長(zhǎng)度不大的數(shù)據(jù)包的發(fā)送及接收。如果處理關(guān)鍵數(shù)據(jù),需要用戶自己提供糾錯(cuò)協(xié)議。
          通訊模塊由聲明文件SComm.h及實(shí)現(xiàn)文件SComm.c組成。
          初始化:調(diào)用函數(shù)InitSCommModule()來初始化通訊模塊:
          voidInitSCommModule(BYTEbyTimerReload,BITbitTurbo)
          參數(shù)說明:
          byTimerReload:定時(shí)器1的重裝載初始值。
          bitTurob:當(dāng)此參數(shù)為TRUE時(shí),串行通訊在定時(shí)器1的溢出速率基礎(chǔ)上加倍。為FALSE時(shí),串行通訊速率為定時(shí)器1的溢出速率。

          緩沖區(qū):模塊使用了由宏SCOMM_SENDBUFSIZE、SCOMM_RECEBUFSIZE及SCOMM_PKGBUFSIZE所指定長(zhǎng)度的三個(gè)緩沖區(qū),分別為發(fā)送、接收及數(shù)據(jù)包(用于處理接收到的數(shù)據(jù))緩沖區(qū)(如果沒有使用異步接收功能,則不需要使用數(shù)據(jù)包緩沖區(qū))。
          在缺省時(shí),這三個(gè)宏都被定義為10,但用戶可以自已按照系統(tǒng)的RAM資源占用情況在Config.h中重定義緩沖區(qū)的大小。需要注意的是,如果緩沖的長(zhǎng)度不夠,當(dāng)發(fā)送或接收長(zhǎng)數(shù)據(jù)包的時(shí)候可能會(huì)發(fā)生問題,關(guān)于數(shù)據(jù)緩沖區(qū)的最小值的設(shè)置可以參考下面的說明。
          注意:需要盡快取出接收緩沖區(qū)中的數(shù)據(jù),否則當(dāng)緩沖區(qū)滿之后,新的數(shù)據(jù)將被簡(jiǎn)單的丟掉。

          字節(jié)級(jí)服務(wù)函數(shù):在Config.h文件中定義了宏SCOMM_DriverInterface(如:#defineSCOMM_DriverInterface),則可以使用字節(jié)級(jí)服務(wù)函數(shù),即通訊模塊的底層函數(shù)。
          共有兩個(gè)函數(shù)可以使用:
          voidSendByte(BYTEbyData);
          發(fā)送一個(gè)字節(jié),如果當(dāng)前緩沖區(qū)滿,則等待。參數(shù)byData為要發(fā)送的數(shù)據(jù)。
          BYTEReceByte();
          接收一個(gè)字節(jié),如果當(dāng)前緩沖區(qū)中沒有數(shù)據(jù),則此函數(shù)阻塞,直到接收到數(shù)據(jù)為止。接收到數(shù)據(jù)通過返回值返回。
          可以通過調(diào)用IsSendBufEmpty()IsSendBufFull()IsReceBufEmpty()IsReceBufFull()宏來判斷緩沖區(qū)的空或滿,以防系統(tǒng)阻塞。
          不推薦直接使用這一級(jí)的服務(wù)函數(shù),應(yīng)該使用高層次上的服務(wù)函數(shù)或者在這一級(jí)服務(wù)函數(shù)的基礎(chǔ)上構(gòu)造自己的通訊函數(shù)。

          數(shù)據(jù)包級(jí)服務(wù)函數(shù):在Config.h文件中定義宏SCOMM_PackageInterface(如:#defineSCOMM_PackageInterface)則可以使用數(shù)據(jù)包級(jí)服務(wù)函數(shù)。
          共有兩個(gè)函數(shù)可以使用:
          voidSendPackage(BYTE*pbyData,BYTEbyLen);
          發(fā)送數(shù)據(jù)包,參數(shù)pbyData為將要發(fā)送的數(shù)據(jù)包緩沖區(qū)(數(shù)組)的指針,byLen為將要發(fā)送的數(shù)據(jù)包的長(zhǎng)度。
          當(dāng)沒有定義SCOMM_DriverInterface時(shí),數(shù)據(jù)被完全緩沖。即不能夠發(fā)送長(zhǎng)度超過發(fā)送緩沖區(qū)長(zhǎng)度的數(shù)據(jù)包。當(dāng)定義了SCOMM_DriverInterface時(shí),采用單字節(jié)發(fā)送,這時(shí)不限制需要發(fā)送的數(shù)據(jù)的長(zhǎng)度。

          BYTERecePackage(BYTE*pbyData,BYTEbyLen);
          接收數(shù)據(jù)包,參數(shù)pbyData為存放將要接收的數(shù)據(jù)的緩沖區(qū),byLen為緩沖區(qū)長(zhǎng)度。返回值為接收到的字節(jié)數(shù),當(dāng)模塊的接收緩沖區(qū)為空時(shí),函數(shù)非阻塞,立即返回,返回值為零。

          發(fā)送接收服務(wù)函數(shù):
          比如在一個(gè)串行總線多機(jī)通訊系統(tǒng)中,主機(jī)需要定時(shí)循檢各從機(jī)的狀態(tài),往往是發(fā)一個(gè)包含從機(jī)地址及指令的數(shù)據(jù)包給從機(jī),之后等待一定的時(shí)間,從機(jī)需要在這段時(shí)間之內(nèi)給主機(jī)一個(gè)應(yīng)答,如果沒有這個(gè)應(yīng)答,則認(rèn)為從機(jī)工作狀態(tài)出錯(cuò),轉(zhuǎn)去進(jìn)行相應(yīng)的處理。在這個(gè)模型里,主機(jī)不能夠不進(jìn)行等待而給另一臺(tái)從機(jī)發(fā)送指令,也不能夠不管從機(jī)在很久沒有應(yīng)答的情況下繼續(xù)等待。還有一種情況,比如當(dāng)使用485總線進(jìn)行通信時(shí),如果是兩條通訊線則系統(tǒng)只能工作在半雙工模式下,總線在同一時(shí)間內(nèi)只能工作在發(fā)送或接收,為了防止發(fā)送和接收相互干擾,這時(shí)的通訊常常需要使用發(fā)送和接收。
          當(dāng)在Config.h文件中定義宏SCOMM_SyncInterface后,則可以使用通訊模塊提供發(fā)送接收函數(shù):
          voidSendPackage(BYTE*pbyData,BYTEbyLen);
          發(fā)送數(shù)據(jù)包,參數(shù)pbyData為將要改善的數(shù)據(jù)包的緩沖區(qū)指針,byLen為將要發(fā)送的數(shù)據(jù)包的長(zhǎng)度。
          這個(gè)函數(shù)可以保證等待一個(gè)完整的數(shù)據(jù)包完全發(fā)送出去之后,它才返回,在這段時(shí)間內(nèi),它會(huì)阻塞運(yùn)行。

          BYTESyncRecePackage(BYTE*pbyBuf,BYTEbyBufLen,WORDwTimeout,BYTEbyParam);
          接收數(shù)據(jù)包。返回值為接收到的數(shù)據(jù)包長(zhǎng)度。參數(shù)pbyBuf為將要接收數(shù)據(jù)包的緩沖區(qū)的指針,byBufLen為提供的緩沖區(qū)的長(zhǎng)度,wTimeout為通信超時(shí)值,如果在發(fā)生了由wTimeout所指定次數(shù)的時(shí)鐘中斷而還沒有接收到或沒有接收到完整的數(shù)據(jù)包時(shí),函數(shù)返回零,最后一個(gè)參數(shù)byParam的含義見后面的解釋。

          異步發(fā)送接收服務(wù)函數(shù):
          在一個(gè)簡(jiǎn)單的系統(tǒng)或多機(jī)通訊系統(tǒng)中的從機(jī)上,一般情況下不需要復(fù)雜的停等的工作模式,而且往往需要對(duì)硬件進(jìn)行控制和檢測(cè),不允許長(zhǎng)時(shí)間的停下來檢測(cè)通訊,但又要求當(dāng)需要通訊時(shí)需要盡快的反應(yīng)速度,這時(shí)就需要使用異步發(fā)送和接收服務(wù)函數(shù)。
          使用異步發(fā)送和接收服務(wù)函數(shù)需要在Config.h文件中定義SCOMM_AsyncInterface宏。
          同樣提供兩個(gè)服務(wù)函數(shù):
          voidSendPackage(BYTE*pbyData,BYTEbyLen);
          發(fā)送數(shù)據(jù)包,參數(shù)pbyData為將要改善的數(shù)據(jù)包的緩沖區(qū)指針,byLen為將要發(fā)送的數(shù)據(jù)包的長(zhǎng)度。
          這里的函數(shù)的接口與同步發(fā)送和接收的服務(wù)函數(shù)相同。關(guān)于這里的細(xì)節(jié),見后面對(duì)同步和異步服務(wù)函數(shù)的說明。

          voidAsyncRecePackage(BYTEbyParam);
          接收數(shù)據(jù)包,參數(shù)byParam的意義見后面的描述。
          使用需要用戶定義一個(gè)回調(diào)函數(shù),原型如下:
          voidOnRecePackage(BYTE*pbyData,BYTEbyBufLen);
          當(dāng)異步接收服務(wù)函數(shù)接收到數(shù)據(jù)包之后,調(diào)用OnRecePackage回調(diào)函數(shù),在pbyData指定的緩沖區(qū)中存放數(shù)據(jù)包,byBufLen為數(shù)據(jù)包的長(zhǎng)度。
          在Config.h文件中定義宏SCOMM_TIMEOUT可以設(shè)定異步接收的超時(shí)值,當(dāng)開始接收數(shù)據(jù)包,但沒有收完數(shù)據(jù)而發(fā)生了SCOMM_TIMEOUT次時(shí)鐘中斷后,認(rèn)為接收超時(shí),將已接收到的數(shù)據(jù)刪除。

          同步和服務(wù)函數(shù):
          有些情況下,比如一個(gè)通訊系統(tǒng)中,由一臺(tái)計(jì)算機(jī)通過串口控制主機(jī),主機(jī)通過串口連接很多從機(jī),主機(jī)的串口采用分時(shí)復(fù)用,在這樣的模型中,主機(jī)和控制計(jì)算機(jī)之間的通訊可以使用,方式,而主機(jī)與從機(jī)可以使用同步通訊方式。而同步和異步的發(fā)送函數(shù)接口是相同的,在這樣的情況下,發(fā)送都是同步的。在這樣的模型中,當(dāng)使用不同的接收函數(shù)之前,需要注意清除接收緩沖區(qū)中的內(nèi)容,通訊模塊提供函數(shù):ClearReceBuffer來做到這一點(diǎn),此函數(shù)原型如下:
          voidClearReceBuffer();

          通訊過程中,數(shù)據(jù)包往往是有固定的格式的,這種格式需要根據(jù)用戶所使用的協(xié)議的不同而不同。同步和異步接收服務(wù)函數(shù)支持從接收到的數(shù)據(jù)中識(shí)別出一定格式的數(shù)據(jù)包。
          舉例說明:目前使用的協(xié)議決定數(shù)據(jù)包的格式為固定的包頭0xff,固定的長(zhǎng)度4個(gè)字節(jié)。其它的細(xì)節(jié)在這里不重要,所以忽略掉。


          評(píng)論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();