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

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 牛人業(yè)話 > CAN總線學(xué)習(xí)筆記二:CAN自收發(fā)程序解讀

          CAN總線學(xué)習(xí)筆記二:CAN自收發(fā)程序解讀

          作者: 時(shí)間:2015-01-06 來源:網(wǎng)絡(luò) 收藏

            花了一整個(gè)下午的時(shí)間,徹頭徹尾的把 PIAE小組提供的源程序解讀了一遍。解讀別人的程序是一件挺費(fèi)時(shí)費(fèi)力的一件事,但是在對(duì)某項(xiàng)技術(shù)或者說某個(gè)芯片的入門階段參考別人的程序又是一項(xiàng)必不可少的任務(wù)。

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

            對(duì)于這個(gè)程序,頭一個(gè)任務(wù)當(dāng)然是把頭文件先瀏覽一遍,能弄明白的還是先弄明白,對(duì)后面程序的解讀有好處。C文件里給出了三個(gè)頭文件:

            #include

            #include

            #include

            第一個(gè)reg52.h我就不廢話了,下一個(gè)intrins.h我在上一篇日志里也詳細(xì)的作了說明,這里也不提了。can_selfdef.h是程序員自己定義的一個(gè)頭文件,在這個(gè)頭文件里除了一些宏定義和管腳的一些說明外,最重要的就是要弄明白“總線SJA1000寄存器地址定義”。這個(gè)我開始也沒弄明白,后來反復(fù)琢磨,才發(fā)現(xiàn)作者在這個(gè)程序里吧SJA1000的寄存器作為單片機(jī)的外部擴(kuò)展RAM尋址了,從而省去了編寫一些底層的驅(qū)動(dòng)程序,這就讓大家連SJA1000的datasheet的時(shí)序圖都不用看了(不過下一步我想用驅(qū)動(dòng)程序來控制SJA1000)。

            看完頭文件,可不能從第一個(gè)程序依次往下看。應(yīng)該直接找到主程序main()解讀:

            void main(void)

            {

            //MCU初始化(主要是各中斷寄存器的初始化)

            SJA_RST = 1; //總線復(fù)位管腳復(fù)位無效

            SJA_CS = 0; //CAN總線片選有效

            EX1 = 1; //開MCU外部中斷INT1

            IT1 = 0; //MCU外部中斷INT1為電平觸發(fā),也是CAN總線接收中斷口

            IT0 = 1; //MCU外部中斷INT0為下降沿觸發(fā)

            EX0 = 1; //開MCU外部中斷INT0

            EA = 1; //開MCU總中斷

            SJA_CS = 1; //CAN總線片選無效,使得對(duì)數(shù)據(jù)總線的操作不會(huì)影響SJA1000。

            //SJA1000初始化

            CAN_init(); //對(duì)SJA1000寄存器的讀寫是采用外部寄存器尋址方式,

            //所以不需要程序單獨(dú)控制片選有效無效

            _nop_();

            _nop_();

            //主循環(huán)

            while(1)

            {

            _nop_();

            _nop_();

            Rxd_deal(); //接收處理程序

            Txd_deal(); //發(fā)送處理程序

            led_seg7(0,Txd_data); //數(shù)碼管1-2顯示發(fā)送數(shù)據(jù)子程序

            led_seg7(1,Rxd_data+3); //數(shù)碼管3-4顯示接收數(shù)據(jù)子程序

            }

            }

            上面的注釋是本人詳細(xì)做了加工的,先是單片機(jī)中斷寄存器的初始化,打開了單片機(jī)的INT0和INT1兩個(gè)外部中斷。INT0是外接按鍵的,所以是下降沿觸發(fā)。這個(gè)按鍵每按下一次,待發(fā)送的數(shù)據(jù)的第一個(gè)字節(jié)就會(huì)加一,這個(gè)數(shù)據(jù)同時(shí)會(huì)顯示在數(shù)碼管上。而INT1是外界著SJA1000的發(fā)送數(shù)據(jù)中斷端口的,采用電平觸發(fā),也就是說當(dāng)SJA1000發(fā)送數(shù)據(jù)時(shí),就會(huì)觸發(fā)中端口INT1,從而讓單片機(jī)進(jìn)行數(shù)據(jù)的接收工作。

            接下來是SJA1000的各個(gè)寄存器的初始化,主要是在CAN_init();這個(gè)程序里完成的,主要是設(shè)置一些寄存器使得滿足本次試驗(yàn)的要求。

            最后就進(jìn)入了主循環(huán)中。不斷的進(jìn)行接收數(shù)據(jù)處理、發(fā)送數(shù)據(jù)處理以及將數(shù)據(jù)的頭一個(gè)字節(jié)的數(shù)值顯示在數(shù)碼管上。每當(dāng)按鍵被按下后就會(huì)置位發(fā)送數(shù)據(jù)狀態(tài)標(biāo)志位,這時(shí)就進(jìn)入發(fā)送狀態(tài),無非就是把ID碼和數(shù)據(jù)等13個(gè)字節(jié)送入SJA1000的相應(yīng)寄存器里,其它的事情就交給SJA1000來完成就可以了。由于是進(jìn)行自傳送,所以SJA1000在接收到數(shù)據(jù)后會(huì)給單片機(jī)一個(gè)中斷,此時(shí)也就進(jìn)入了接收數(shù)據(jù)狀態(tài)下,同樣只要把SJA1000里相應(yīng)的寄存器讀出來就可以了。為了觀察發(fā)送和接收的數(shù)據(jù)是否一致,這個(gè)程序里就把發(fā)送的數(shù)據(jù)的頭一個(gè)字節(jié)通過數(shù)碼管顯示出來。發(fā)送數(shù)據(jù)正常顯示,而接收數(shù)據(jù)為了便于觀察,我把它+3,就是說顯示的接收數(shù)據(jù)會(huì)比發(fā)送數(shù)據(jù)大3。最后很好的得到驗(yàn)證了。



          關(guān)鍵詞: CAN 自收發(fā)

          評(píng)論


          技術(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); })();