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

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 嵌入式硬件通信接口協(xié)議-UART(四)設(shè)計(jì)起止式的應(yīng)用層協(xié)議

          嵌入式硬件通信接口協(xié)議-UART(四)設(shè)計(jì)起止式的應(yīng)用層協(xié)議

          作者: 時(shí)間:2019-03-20 來(lái)源:網(wǎng)絡(luò) 收藏

            解析思路是:

          本文引用地址:http://www.ex-cimer.com/article/201903/398678.htm

            1.確保環(huán)形緩沖區(qū)有足夠一個(gè)幀結(jié)構(gòu)的數(shù)據(jù)量,否則返數(shù)據(jù)量不足的錯(cuò)誤;

            2.接著讀出一個(gè)字節(jié)判斷幀頭標(biāo)志是否為0x55,否則返幀頭錯(cuò)誤;

            3.再次讀一個(gè)字節(jié)作為幀長(zhǎng)度數(shù)據(jù),且長(zhǎng)度至少3個(gè)字節(jié)(2個(gè)CRC校驗(yàn)值+至少1字節(jié)數(shù)據(jù)包),否則返幀長(zhǎng)度錯(cuò)誤;

            4.讀出幀長(zhǎng)度數(shù)據(jù),如果此時(shí)環(huán)形緩沖區(qū)的可讀數(shù)量比長(zhǎng)度數(shù)值小,出現(xiàn)這情況的原因可能是幀長(zhǎng)度字段在發(fā)送期間出現(xiàn)異常,或是對(duì)端設(shè)備串口傳輸慢而未完整傳輸一幀,此時(shí)可做適當(dāng)?shù)难訒r(shí)等待,如果超時(shí)退出,且返幀長(zhǎng)度錯(cuò)誤;

            5.繼續(xù)讀出2個(gè)字節(jié)作為CRC校驗(yàn)值,且需要注意先收到的是crc16L,先收到小端數(shù)值;

            6.緊接著把數(shù)據(jù)包讀出,此時(shí)讀的長(zhǎng)度應(yīng)該是第4步中的幀長(zhǎng)度數(shù)據(jù)少2個(gè)字節(jié);

            7.最后對(duì)數(shù)據(jù)包計(jì)算一個(gè)CRC校驗(yàn)值,對(duì)比接收到的校驗(yàn)值,校驗(yàn)值不一致則返錯(cuò)誤校驗(yàn)碼。

            函數(shù)返回值符合以下枚舉的錯(cuò)誤碼:

            被解析數(shù)據(jù)源

            看到這里也許仍有疑問(wèn),用于解析的數(shù)據(jù)源哪來(lái)?數(shù)據(jù)什么時(shí)候被寫(xiě)進(jìn)環(huán)形緩沖區(qū)內(nèi)?

            參考上一篇《嵌入式接口-使用RingBuffer處理數(shù)據(jù)(二)詳細(xì)設(shè)計(jì)過(guò)程》介紹的關(guān)于向環(huán)形緩沖區(qū)寫(xiě)入一個(gè)字節(jié),但dclib_ringbuffer這個(gè)模塊屬于應(yīng)用庫(kù)模塊層,而如果直接把dclib_rb_writebyte這一個(gè)接口放在串口接收中斷里執(zhí)行,這就破壞了系統(tǒng)的架構(gòu)層次,對(duì)工程代碼的維護(hù)和移植是個(gè)麻煩事,因此采用回調(diào)函數(shù)的方式。

            嵌入式開(kāi)發(fā)工程師都知道,一般在使用官方的庫(kù)時(shí),經(jīng)常會(huì)遇到需要自己實(shí)現(xiàn)一些回調(diào)函數(shù),從而利用注冊(cè)接口把回調(diào)函數(shù)傳遞給庫(kù)或者驅(qū)動(dòng)層,使庫(kù)或者驅(qū)動(dòng)層在執(zhí)行時(shí)調(diào)用該回調(diào)函數(shù)。

            根據(jù)這個(gè)思路,同樣的這里也采用回調(diào)函數(shù)的形式,回調(diào)函數(shù)內(nèi)完成了把串口接收到的數(shù)據(jù)寫(xiě)入環(huán)形緩沖區(qū)內(nèi)。

            回調(diào)函數(shù)的實(shí)現(xiàn)源碼截圖:

            事實(shí)上僅僅調(diào)用了dclib_ringbuffer功能里的寫(xiě)一字節(jié)接口dclib_rb_writebyte,回調(diào)函數(shù)傳進(jìn)來(lái)的參數(shù)dat就是串口接收到的數(shù)據(jù)。

            有了回調(diào)函數(shù),還要把這個(gè)回調(diào)函數(shù)的地址傳給底層驅(qū)動(dòng),這也就是常說(shuō)的“注冊(cè)”的過(guò)程,注冊(cè)接口在固件板級(jí)接口層里串口模塊dcbsp_uart實(shí)現(xiàn),注冊(cè)接口時(shí)dclib_uart_callback_reg函數(shù):

            

            又偏題了,關(guān)于回調(diào)函數(shù)在此不做深入論述。

            簡(jiǎn)而言之,環(huán)形緩沖區(qū)寫(xiě)入一字節(jié)的執(zhí)行過(guò)程,放在回調(diào)函數(shù)里,當(dāng)串口接收中斷觸發(fā)后,中斷里會(huì)根據(jù)注冊(cè)的回調(diào)函數(shù)地址,進(jìn)而執(zhí)行回調(diào)函數(shù),實(shí)現(xiàn)對(duì)環(huán)形緩沖區(qū)寫(xiě)入一個(gè)字節(jié)數(shù)據(jù)。如此操作的理由是不改變工程代碼的分層架構(gòu),并且便于維護(hù)與移植!

            為了縮減篇幅,最后貼上測(cè)試代碼的部分:

            

            


            最后也附上調(diào)試期間串口打印的解析結(jié)果:

            

            起止式幀結(jié)構(gòu)的講解稍有匆忙,篇幅也略大,文中基礎(chǔ)技術(shù)要點(diǎn)未能細(xì)致講解,后續(xù)統(tǒng)籌規(guī)劃再做單獨(dú)介紹!

            接下來(lái)在此幀結(jié)構(gòu)基礎(chǔ)上,講述如何設(shè)計(jì)在數(shù)據(jù)包放置應(yīng)用層的交互指令,敬請(qǐng)期待下回分!


          上一頁(yè) 1 2 下一頁(yè)

          關(guān)鍵詞: UART 硬件通信

          評(píng)論


          相關(guān)推薦

          技術(shù)專(zhuān)區(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); })();