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

          關(guān) 閉

          新聞中心

          EEPW首頁 > 工控自動(dòng)化 > 設(shè)計(jì)應(yīng)用 > CAN/RS 232接口卡的設(shè)計(jì)與實(shí)現(xiàn)

          CAN/RS 232接口卡的設(shè)計(jì)與實(shí)現(xiàn)

          作者: 時(shí)間:2010-03-18 來源:網(wǎng)絡(luò) 收藏

          2 的軟件
          2.1 232接口軟件
          單片機(jī)與PC端的數(shù)據(jù)通信需要一個(gè)通信協(xié)議,采用同步通信方式進(jìn)行。將通信協(xié)議分成命令幀、應(yīng)答幀和數(shù)據(jù)幀三種格式。每種幀都包含有起始字節(jié)、數(shù)據(jù)長度、校驗(yàn)字節(jié)和幀結(jié)束字節(jié)。具體格式如圖4所示。

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


          命令幀共6個(gè)字節(jié),傳輸方向?yàn)镻C機(jī)到單片機(jī)。以0X00H作為幀起始,數(shù)據(jù)長度為2,當(dāng)數(shù)據(jù)1和數(shù)據(jù)2同為0X00時(shí),表示啟動(dòng),單片機(jī)接收到該信號(hào)后.會(huì)初始化SJA1000,并將結(jié)果反饋給PC機(jī)(成功或失敗);當(dāng)數(shù)據(jù)1和數(shù)據(jù)2同為0XFFH時(shí),表示要求停止工作,單片機(jī)會(huì)讓SJA1000進(jìn)入睡眠模式,以退出總線;當(dāng)數(shù)據(jù)1為0X01H時(shí),表示PC機(jī)要求只接收某個(gè)節(jié)點(diǎn)的數(shù)據(jù),數(shù)據(jù)2則表示該接點(diǎn)的節(jié)點(diǎn)號(hào),單片機(jī)會(huì)重新設(shè)置SJA1000的驗(yàn)收濾波器,屏蔽掉其他不需要的節(jié)點(diǎn)數(shù)據(jù)。
          應(yīng)答幀共6個(gè)字節(jié),傳輸方向?yàn)閱纹瑱C(jī)到PC機(jī)。以0X11H作為幀起始,數(shù)據(jù)長度為2,當(dāng)單片機(jī)接收到PC機(jī)的啟動(dòng)或停止命令,并設(shè)置成功后,發(fā)送兩字節(jié)數(shù)據(jù)同為0X00H給PC,若設(shè)置失敗,則發(fā)送兩字節(jié)數(shù)據(jù)同為0XFFH給PC;對于PC要求讀取特定節(jié)點(diǎn)的命令,單片機(jī)以0X10H作為應(yīng)答起始,并以兩字節(jié)同為0X00H表示成功,兩字節(jié)同為0XFFH表示失敗。
          數(shù)據(jù)幀為接口卡從總線上讀到的數(shù)據(jù),因?yàn)榭偩€上數(shù)據(jù)有標(biāo)準(zhǔn)幀、遠(yuǎn)程幀等之分,而且每個(gè)幀中裝載的數(shù)據(jù)長度未知,所以數(shù)據(jù)幀的長度不定,其傳輸方向也為單片機(jī)到PC,起始字節(jié)為0X22H。SJA1000每次接收到有效數(shù)據(jù)后會(huì)讓單片機(jī)產(chǎn)生接收中斷,單片機(jī)則在中斷處理中將數(shù)據(jù)首先讀入到RAM中暫時(shí)存放,然后計(jì)算其數(shù)據(jù)長度和校驗(yàn)和,將數(shù)據(jù)封裝成幀,然后將幀通過串口送給PC處理和顯示。
          各種類型的幀以0X33H作為幀結(jié)束標(biāo)識(shí)。校驗(yàn)和字節(jié)用來保證數(shù)據(jù)的準(zhǔn)確性,單片機(jī)在發(fā)送數(shù)據(jù)前將各個(gè)字節(jié)相加,并將結(jié)果填人校驗(yàn)字節(jié)。PC端接收到數(shù)據(jù)后,重新計(jì)算校驗(yàn)和,并與單片機(jī)發(fā)送的校驗(yàn)和相比較,相同則正確接收,否則要求單片機(jī)重新發(fā)送。
          2.2 協(xié)議的透明性分析
          在同步傳輸數(shù)據(jù)的過程中,幀的起始字節(jié)和結(jié)束字節(jié)是非常重要的,它能夠保證數(shù)據(jù)幀的準(zhǔn)確性。但因?yàn)檫@兩個(gè)字節(jié)的存在,同時(shí)也引出了另一個(gè)待解決的問題,就是當(dāng)數(shù)據(jù)場中出現(xiàn)了與起始字節(jié)相同的數(shù)據(jù)時(shí),很有可能會(huì)導(dǎo)致PC端把它看成一個(gè)新的幀起始,從而導(dǎo)致數(shù)據(jù)的處理和顯示錯(cuò)誤,這也就是數(shù)據(jù)傳輸?shù)耐该餍詥栴}。針對串口的數(shù)據(jù)傳輸,有一種比較好的解決方案。該方法將數(shù)據(jù)轉(zhuǎn)換成為ASCII字符來進(jìn)行傳送,就是將每個(gè)字節(jié)的數(shù)據(jù)進(jìn)行拆分,將一個(gè)16進(jìn)制的字節(jié)拆分成兩個(gè)字節(jié),如5AH,5BH,5CH,…,可以拆分為50H,0AH,50H,0BH,50H,OCH,…,PC機(jī)再接收到數(shù)據(jù)后,再將數(shù)據(jù)進(jìn)行兩兩相或組合。這樣,只需要32個(gè)字節(jié)就可以組合成為00H~0FFH中任一個(gè)數(shù)據(jù)。但這種辦法的缺點(diǎn)也是顯而易見的,應(yīng)用它所發(fā)送的有效數(shù)據(jù)量是正常發(fā)送的兩倍,對于串口這種傳輸速度不高的通信介質(zhì)而言,在數(shù)據(jù)量較大的情況下,不是一種可取的方法。
          在該接口卡中作者采取了另一種轉(zhuǎn)義字符的方法。首先定義一個(gè)轉(zhuǎn)義字符標(biāo)識(shí)OXDBH。對于總線而言,其每個(gè)幀的最大數(shù)據(jù)長度為8,即使將的幀信息和識(shí)別碼全部當(dāng)作數(shù)據(jù)發(fā)送,其長度最大也只有13 B。這樣可以肯定的是,正常情況下數(shù)據(jù)幀中數(shù)據(jù)長度字節(jié)的高4位必然為0。因此在數(shù)據(jù)發(fā)送之前,首先檢查該數(shù)據(jù)中是否有與起始字節(jié)0X22H、結(jié)束字節(jié)0X33H和轉(zhuǎn)義標(biāo)識(shí)0XDBH相同的數(shù)據(jù),如果沒有,則正常發(fā)送;如果有,則檢測出與這兩個(gè)字節(jié)相同數(shù)據(jù)的個(gè)數(shù),并將該個(gè)數(shù)填充到數(shù)據(jù)長度字節(jié)的高4位中;同時(shí),將這些數(shù)據(jù)前添加轉(zhuǎn)義字符標(biāo)識(shí),并將該數(shù)據(jù)進(jìn)行轉(zhuǎn)義。如數(shù)據(jù)0X22H。0X33H,0XDBH…,則轉(zhuǎn)義成0XDBH。0XD2H。0XDBH,0XD3H,0XDBH,0XDDH…。PC機(jī)在接收到數(shù)據(jù)幀后,首先檢查數(shù)據(jù)長度字節(jié),看其高4位是否為0,如果為0,說明該數(shù)據(jù)組不存在轉(zhuǎn)義字符,可以直接處理;如果為N。則表明數(shù)據(jù)組中存在N個(gè)轉(zhuǎn)義字符,并且每個(gè)轉(zhuǎn)義字符都以0XDB開始,需要首先將它們重新修改回原始數(shù)據(jù)。相比而言,這種辦法有很好的穩(wěn)定性和接口利用率,其數(shù)據(jù)流量也不會(huì)很高。



          評論


          相關(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); })();