新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > STM32_MDK_bxCAN

        STM32_MDK_bxCAN

        作者: 時間:2016-12-03 來源:網絡 收藏
        今天整理下CAN方面的資料,首先使用的是stm32f103vet6,只有一個CAN(2.0A & 2.0B)。CAN本身是工作的數據鏈路層的總線,有很多優勢就不再一一介紹了,隨便買本書看看都有。

        基礎的CAN的知識就不贅述了,這些是必要的可以自己去買書了解,現在來看下STM32下對CAN的驅動,STM32本身包括了CAN的數據鏈路層,然后物理層就是CAN收發器用的是TJA1050,是非容錯CAN。終端電阻用120歐姆。

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

        說道CAN最主要的是CAN的初始化,他包括兩個主要的部分,一個是基本屬性的聲明,另一部分就是過濾器的設置。見如下代碼:

        /*******************************************************************************
        * Function Name : bxCAN_Port_Configuration
        * Description : CAN端口設置
        * Input : None
        * Output : None
        * Return : None
        *******************************************************************************/
        void bxCAN_Port_Configuration(void)
        {
        GPIO_InitTypeDef GPIO_InitStructure_bxCAN;

        GPIO_PinRemapConfig(GPIO_Remap1_CAN1 , ENABLE); //端口復用為CAN1

        GPIO_InitStructure_bxCAN.GPIO_Pin = GPIO_Pin_8; //PB8:CAN-RX
        GPIO_InitStructure_bxCAN.GPIO_Mode = GPIO_Mode_IPU; //輸入上拉
        GPIO_InitStructure_bxCAN.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB, &GPIO_InitStructure_bxCAN);

        GPIO_InitStructure_bxCAN.GPIO_Pin = GPIO_Pin_9; //PB9:CAN-TX
        GPIO_InitStructure_bxCAN.GPIO_Mode = GPIO_Mode_AF_PP; //復用模式
        GPIO_InitStructure_bxCAN.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB, &GPIO_InitStructure_bxCAN);
        }

        /*******************************************************************************
        * Function Name : bxCAN_Property_Configuration
        * Description : CAN配置具體屬性
        * Input : None
        * Output : None
        * Return : None
        *******************************************************************************/
        void bxCAN_Property_Configuration(void)
        {
        CAN_InitTypeDef CAN_InitStructure;
        CAN_FilterInitTypeDef CAN_FilterInitStructure;

        /* CAN register init */
        CAN_DeInit(CAN1);
        CAN_StructInit(&CAN_InitStructure);

        /* CAN cell init */
        CAN_InitStructure.CAN_TTCM=DISABLE; //MCR-TTCM 禁止時間觸發通信模式
        CAN_InitStructure.CAN_ABOM=DISABLE;//MCR-ABOM 禁止自動離線管理
        CAN_InitStructure.CAN_AWUM=DISABLE;//MCR-AWUM 通過清除CAN_MCR_SLEEP位進入自動喚醒模式
        CAN_InitStructure.CAN_NART=DISABLE;//MCR-NART 禁止報文自動重傳 0-自動重傳 1-報文只傳一次
        CAN_InitStructure.CAN_RFLM=DISABLE;//MCR-RFLM 接收FIFO 鎖定模式 0-溢出時新報文會覆蓋原有報文 1-溢出時,新報文丟棄
        CAN_InitStructure.CAN_TXFP=DISABLE;//MCR-TXFP 發送FIFO優先級 0-優先級取決于報文標示符 1-優先級取決于發送請求的順序
        CAN_InitStructure.CAN_Mode=CAN_Mode_LoopBack;//BTR-SILM/LBKM CAN環回模式
        // CAN_InitStructure.CAN_Mode=CAN_Mode_Normal;// CAN正常模式
        CAN_InitStructure.CAN_SJW=CAN_SJW_1tq; //BTR-SJW 重新同步跳躍寬度 1個時間單元
        CAN_InitStructure.CAN_BS1=CAN_BS1_2tq;//BTR-TS1 時間段1 占用了2個時間單元
        CAN_InitStructure.CAN_BS2=CAN_BS2_3tq;//BTR-TS1 時間段2 占用了3個時間單元

        #if CAN_BAUDRATE == 1000 /* 1MBps *///BTR-BRP 波特率分頻器 定義了時間單元的時間長度 36/(1+2+3)/6=1Mbps
        CAN_InitStructure.CAN_Prescaler = 6;
        #elif CAN_BAUDRATE == 500 /* 500KBps */
        CAN_InitStructure.CAN_Prescaler = 12;
        #elif CAN_BAUDRATE == 250 /* 250KBps */
        CAN_InitStructure.CAN_Prescaler = 24;
        #elif CAN_BAUDRATE == 125 /* 125KBps */
        CAN_InitStructure.CAN_Prescaler = 48;
        #elif CAN_BAUDRATE == 100 /* 100KBps */
        CAN_InitStructure.CAN_Prescaler = 60;
        #elif CAN_BAUDRATE == 50 /* 50KBps */
        CAN_InitStructure.CAN_Prescaler = 120;
        #elif CAN_BAUDRATE == 20 /* 20KBps */
        CAN_InitStructure.CAN_Prescaler = 300;
        #elif CAN_BAUDRATE == 10 /* 10KBps */
        CAN_InitStructure.CAN_Prescaler = 600;
        #endif
        CAN_Init(CAN1, &CAN_InitStructure);//初始化CAN寄存器

        /* CAN filter init */
        CAN_FilterInitStructure.CAN_FilterNumber=1; // 選擇過濾器編號
        CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;// 選擇過濾器類型為屏蔽位模式
        CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; // 選擇過濾器位寬為一個32位過濾器
        CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;// 標識符匹配
        CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
        CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;// 標識符屏蔽位,1:必須匹配,0:不用關心
        CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
        CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0; // 選擇存放在關聯的FIFO為FIFO0
        CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;// 激活過濾器
        CAN_FilterInit(&CAN_FilterInitStructure);// 初始化過濾器

        /* CAN FIFO0 message pending interrupt enable */
        CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);// 設置CAN1,FIFO0接收中斷使能
        // CAN_ITConfig(CAN1, CAN_IT_FMP0, DISABLE);
        }

        /*******************************************************************************
        * Function Name : bxCAN_Configuration
        * Description : CAN初始化
        * Input : None
        * Output : None
        * Return : None
        *******************************************************************************/
        void bxCAN_Configuration(void)
        {
        bxCAN_Port_Configuration();
        bxCAN_Property_Configuration();
        }

        /*******************************************************************************
        * Function Name : Interrupt_Handle_bxCAN
        * Description : 中斷服務函數
        * Input : None
        * Output : None
        * Return : None
        *******************************************************************************/
        void Interrupt_Handle_bxCAN(void)
        {
        CanRxMsg RxMessage;

        RxMessage.StdId=0x00;
        RxMessage.ExtId=0x00;
        RxMessage.IDE=0;
        RxMessage.DLC=0;
        RxMessage.FMI=0;
        RxMessage.Data[0]=0x00;
        RxMessage.Data[1]=0x00;

        CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);
        }

        初始化第一部分基本屬性設置,要看下datasheet中,CAN的發送流程和接受流程,然后看下他相關的狀態寄存器就知道其意義了。在過濾器設置部分,要理解他兩種模式的不同之處,屏蔽位模式就是給出 一個參考值然后用屏蔽屬性去匹配,列表模式就是直接根據寄存器的參考值進行全匹配。這里對屏蔽位我也沒有做特殊的設置,就設置全部接受。
        本歷程只實現了發送標準幀,擴展幀,接受幀數據。
        接收程序使用中斷方式,見上面代碼函數Interrupt_Handle_bxCAN(),發送代碼如下:

        void Send_Std_KLS_KL15(unsigned char value)
        {
        CanTxMsg TxMessage;

        TxMessage.StdId=0x570;
        TxMessage.IDE=CAN_ID_STD;
        TxMessage.RTR=CAN_RTR_DATA;
        TxMessage.DLC=8;
        TxMessage.Data[0]=value;
        TxMessage.Data[1]=0x00;
        TxMessage.Data[2]=0x00;
        TxMessage.Data[3]=0x00;
        TxMessage.Data[4]=0x00;
        TxMessage.Data[5]=0x00;
        TxMessage.Data[6]=0x00;
        TxMessage.Data[7]=0x00;

        CAN_Transmit(CAN1, &TxMessage);
        }

        這個是發送一個標準幀,如果發送擴展幀 如下:

        void Send_Exd_message(void)
        {
        CanTxMsg TxMessage;

        TxMessage.StdId=0x0000;
        TxMessage.ExtId=0x1234;
        TxMessage.IDE=CAN_ID_EXT;
        TxMessage.RTR=CAN_RTR_DATA;
        TxMessage.DLC=2;
        TxMessage.Data[0]=0xDE;
        TxMessage.Data[1]=0xCA;
        CAN_Transmit(CAN1, &TxMessage);
        }

        由于CAN透明化了數據鏈路層,所以在實際應用中只要用好屏蔽位就能夠高效的使用CAN網絡。


        關鍵詞: STM32MDKbxCA

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 都兰县| 平昌县| 平利县| 司法| 芜湖县| 哈尔滨市| 时尚| 嘉兴市| 平武县| 景泰县| 克东县| 土默特左旗| 泉州市| 桃源县| 海南省| 思茅市| 米林县| 天峨县| 瓮安县| 上林县| 大余县| 永州市| 桐庐县| 闻喜县| 延长县| 南召县| 寿光市| 永吉县| 定安县| 兰溪市| 台中市| 蒙城县| 新和县| 南平市| 威宁| 新绛县| 潜山县| 谷城县| 保山市| 额敏县| 玉门市|