新聞中心

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

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

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

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

        本文引用地址:http://www.104case.com/article/267768.htm

          對于這個程序,頭一個任務當然是把頭文件先瀏覽一遍,能弄明白的還是先弄明白,對后面程序的解讀有好處。C文件里給出了三個頭文件:

          #include

          #include

          #include

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

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

          void main(void)

          {

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

          SJA_RST = 1; //總線復位管腳復位無效

          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總線片選無效,使得對數(shù)據(jù)總線的操作不會影響SJA1000。

          //SJA1000初始化

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

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

          _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ù)子程序

          }

          }

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

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

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



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

        評論


        技術專區(qū)

        關閉
        主站蜘蛛池模板: 江安县| 明星| 灵川县| 虎林市| 隆尧县| 汝城县| 集贤县| 邯郸县| 岱山县| 合阳县| 乐亭县| 铁岭市| 安远县| 东平县| 疏勒县| 郓城县| 大姚县| 揭西县| 兴文县| 周口市| 曲阜市| 六安市| 夹江县| 南乐县| 奉化市| 黄大仙区| 遂川县| 汾西县| 鸡泽县| 湛江市| 莱西市| 青海省| 北碚区| 准格尔旗| 台南市| 乌兰察布市| 太湖县| 陆河县| 彰化县| 土默特右旗| 金沙县|