新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > SJA1000 CAN驅動程序演示實驗

        SJA1000 CAN驅動程序演示實驗

        作者: 時間:2016-12-14 來源:網絡 收藏
        一.實驗目的

        驅動程序展示了如何在Small RTOS中編寫SJA1000 的驅動程序。通過調用CAN
        序庫SJA1000_PEI.LIB 的基本函數,實現實驗板上CAN 節點的初始化以及CAN 節點數據
        收發測試。
        二.實驗設備及器件
        PC 機 一臺
        DP-51PROC 單片機綜合仿真實驗儀 一臺
        CAN PARK 模塊 一臺
        CAN 連接線 一根
        三.實驗步驟
        1、 將CAN-bus PARK 插入到A6 區中,用導線連接A6 區的P1_IO2 到A2 區的P10,
        連接A6 區的P1_CS1 到A2 區的A15。
        2、 使用導線把A2 區的P16 和P17 分別于D5 區的SCL 和SDA 相連。使用導線把D5
        區的/RST 與VCC 相連。
        3、 由于本程序使用中斷方式響應SJA1000 中斷,故將A5 區的P1_INT 接到A2 區的
        INT0。
        4、 利用CAN 連接線將兩臺已經安裝了CAN-Bus 模塊的DP-51PROC 連接起來,以組
        成簡單的CAN 網絡實現CAN 的接收和發送。
        5、 本驅動程序已經將輸出文件路徑設置為“E:Temp”,用戶可自行更改輸出文件路徑。
        將路徑“E:Temp”中的CAN. hex 文件下載到兩臺DP-51PROC 中運行。
        四.實驗參考程序主要部分
        /******************************************************
        *描述: 獨立的CAN 控制器SJA1000PeliCAN 在small rtos 中的應用示例
        *文件名: PELIRTOS.c
        *應用語言: KEIL C51
        *應用系統: small rtos
        *版本 : V1.0
        *廣州周立功單片機發展有限公司 保留所有的版權
        ****************************************************/
        #define _TIME_MODULE_H
        #define _SERIAL_H
        /********************************************************
        ** 導入頭文件
        ******************************************************/
        #include "INCLUDES.h"
        #include "Sja1000_peli.h"
        sfr IPH=0xb7;

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

        sbit RESET_PIN=P1^0;
        // 驗收代碼/屏蔽寄存器的內容(4+4)
        uint8 xdata Send_CAN_Filter[8]={0xf0,0xf0,0xf0,0xff,0xff,0xff,0xff,0xff};
        // 幀信息和標示碼(1+4)分別對應 TX,TX1,TX2,TX3,TX4
        uint8 xdata Send_CAN_Info_ID[3]={0xc7,0x0A,0x0B};
        uint8 xdata Recv_CAN_Info_ID[3];
        // 待發送數據(8)
        uint8 xdata
        Send_CAN_Data[13]={0xc7,0x0A,0x0B,0x04,0x05,0x06,0x07,0x08,0x07,0x08,0x07,0x08,
        0x08};
        uint8 xdata Recv_CAN_Data[14];
        uint8 xdata time_Counter=0;
        uint8 xdata BTR0,BTR1;
        uint16 xdata *p;
        uint8 xdata disp_buf[8];
        void CAN_Send(void);
        void display(void);
        void CAN_Rcv(void);
        void TimeSum(void);
        void Delay_ms(uint8 j);
        void SJA1000_Config_Normal(void);
        void Init(void)
        {
        CKCON=1; //應用6clock
        TMOD = (TMOD & 0XF0) | 0X01;
        TCON=TCON|0x04; //MCU 的INT1 下降沿觸發,INT0 電平觸發
        TH0 = (65536 - (11059200 / 12) / 100) / 256;
        TL0 = (65536 - (11059200 / 12) / 100) % 256;
        TR0 = 1;
        ET0 = 1;
        TF0 = 0;
        }
        /****************************************************************
        **函數名稱:void CAN_Init(void)
        **功能描述:復位SJA1000,并設置其工作在正常模式
        *****************************************************************/
        void CAN_Init(void)
        {

        RESET_PIN=0; //將SJA1000 的復位線與P1.0 相連接
        Delay_ms(1);
        RESET_PIN=1; //控制P1.0 來實現SJA1000 的復位
        SJA_CS_Point=&CAN_SJA_BaseAdr;
        SJA1000_Config_Normal();
        WriteSJAReg(REG_CAN_IER,RIE_BIT); //使能SJA1000 接收中斷
        EX0=1;
        }
        /**************************************************************
        ** 函數原型: void Delay_ms(uchar j)
        ** 功能描述: 該函數用于不精確的延時。在12M,6CLK 下,大約延時j*1ms
        ***************************************************************/
        void Delay_ms(uint8 j)
        {
        uint8 k,l;
        for(l=0;l<=j;l++)
        {
        for(k=0;k<=250;k++)
        {
        ;
        }
        }
        }
        /************************************************************
        ** 函數原型: void SJA1000_Config_Normal(void)
        ** 功能描述: 對SJA1000 的正常模式的初始化配置
        ***************************************************************/
        void SJA1000_Config_Normal(void)
        {
        BTR0=0x00;
        BTR1=0x14; //設置為80k 波特率通信
        SJAEntryResetMode(); //進入復位模式
        WriteSJAReg(REG_CAN_CDR,0xc8); //配置時鐘分頻寄存器,選擇PeliCAN 模式
        WriteSJAReg(REG_CAN_MOD,0x01); //配置模式寄存器,選擇雙濾波、正常模式
        WriteSJARegBlock(16,Send_CAN_Filter,8); //配置驗收代碼/屏蔽寄存器
        WriteSJAReg(REG_CAN_BTR0,BTR0); //配置總線定時器0
        WriteSJAReg(REG_CAN_BTR1,BTR1); //配置總線定時器1
        WriteSJAReg(REG_CAN_OCR,0x1a); //配置輸出管腳
        SJAQuitResetMode(); //退出復位模式,進入工作模式
        }
        /*********************************************************** 函數原型: void CAN_Data_Send(void)
        ** 功能描述: SJA1000 的單次發送子函數(注意在這個函數的末尾要置位接收中斷)
        *************************************************************/
        void CAN_Data_Send(void)
        {
        // 發送數據
        WriteSJAReg(REG_CAN_IER,0x02); //使能SJA1000 發送中斷位
        WriteSJARegBlock(16,Send_CAN_Data,13);
        WriteSJAReg(REG_CAN_CMR,1); //使能發送請求
        Delay_ms(10);
        WriteSJAReg(REG_CAN_IER,RIE_BIT); //使能SJA1000 接收中斷
        }
        /**************************************************************
        ** 函數原型: void SJA1000_INT0 (void) interrupt 0
        ** 功能描述: SJA1000 中斷響應函數
        ***************************************************************/
        void SJA1000_INT0(void) interrupt 0
        {
        OS_INT_ENTER();
        EX0 = 0;
        OSIntSendSignal(0); //無條件的令CAN 接收中斷處理任務(CAN_Rcv ())處于就緒狀

        //由于CAN_Rcv ()的優先級最高,故中斷退出后立刻執行
        CAN_Rcv ().
        OSIntExit();
        }
        void main(void)
        {
        uint8 i ;
        OSInit();
        Init();
        CAN_Init();
        //初始化顯示緩存
        for(i=0;i<8;i++)
        {
        disp_buf[i]=31;
        }
        //創建任務
        OSTaskCreate(CAN_Rcv, NULL, 0);

        OSTaskCreate(display, NULL, 1);
        OSTaskCreate(CAN_Send, NULL, 2);
        OSTaskCreate(TimeSum, NULL, 3);
        while(1)
        {
        PCON = PCON | 0x01; //令CPU 進入睡眠狀態
        }
        }
        /*****************************************************************
        **鍵值發送任務
        *****************************************************************/
        void CAN_Send(void)
        {
        uint8 key_data;
        while(1)
        {
        key_data = ZLG7290_GetKey();
        if(key_data)
        {
        Send_CAN_Data[3] = key_data;
        CAN_Data_Send();
        disp_buf[4] = key_data % 10;
        disp_buf[5] = (key_data / 10) % 10;
        }
        OSWait(K_TMO,5);
        }
        }
        /****************************************************************
        **顯示任務
        *****************************************************************/
        void display(void)
        {
        while(1)
        {
        OSWait(K_TMO,5);
        OS_ENTER_CRITICAL();
        ZLG7290_SendBuf(&disp_buf[0], 8);
        OS_EXIT_CRITICAL();
        }
        }
        /***************************************************************
        **CAN 接收中斷處理任務

        ***************************************************************/
        void CAN_Rcv(void)
        {
        while(1)
        {
        OSWait(K_SIG, 0); //掛起當前任務,等待喚醒信號
        if(ReadSJAReg(REG_CAN_IR)&0x01)
        {
        //數據接收一定在釋放緩沖區之前,釋放后數據不確定
        ReadSJARegBlock(16,Recv_CAN_Data,13);
        WriteSJAReg(REG_CAN_CMR,4); //釋放SJA1000 接收緩沖區
        disp_buf[0] = Recv_CAN_Data[3] % 10;
        disp_buf[1] = (Recv_CAN_Data[3] / 10) % 10;
        }
        EX0 = 1;
        }
        }
        /*****************************************************
        * *計數任務
        ***************************************************************/
        void TimeSum(void)
        {
        while(1)
        {
        OSWait(K_TMO, 5);
        disp_buf[7]++;
        if(disp_buf[7] > 9)
        {
        disp_buf[7] = 0;
        }
        }
        }
        五.實驗例程簡析
        本驅動程序采用中斷方式接收CAN 總線數據。采用中斷的方式,可以提高系統的實時性。特別的在接收數據的時候,采用中斷方式可以在效率和實時性上比采用非中斷方式得到很大的提高。
        按下D5 區的按鍵時,左邊的LED 將顯示按鍵鍵值,同時程序調用CAN_Data_Send ( )
        將檢測到的鍵值通過CAN 總線發送到另一臺實驗儀上。實驗儀將從CAN 總線上接收到的
        鍵值數據顯示在D5 區的右邊LED 上。
        D5 區中最右邊的LED 管循環地顯示0~9,目的是為了顯示系統正在運行。
        有關SJA1000_PEI 庫的使用請閱讀配套光盤中的《SJA1000_PEI 庫說明及其使用》文檔。



        評論


        技術專區

        關閉
        主站蜘蛛池模板: 贺兰县| 乌苏市| 英超| 五华县| 招远市| 亚东县| 金乡县| 博客| 大渡口区| 墨脱县| 南木林县| 合肥市| 临澧县| 丹凤县| 都江堰市| 读书| 乌兰县| 富源县| 景德镇市| 兰考县| 大城县| 昭通市| 高青县| 宁晋县| 咸阳市| 松阳县| 绥江县| 宣化县| 东方市| 怀仁县| 丰城市| 万山特区| 云霄县| 肥城市| 从化市| 大埔区| 呼图壁县| 富裕县| 方山县| 东台市| 进贤县|