STM32F103的CAN通讯接收过滤器过滤分析
前言
STM32 的標識符過濾是一個比較復(fù)雜的東東,它的存在減少了 CPU 處理 CAN 通信的開銷。STM32 的過濾器組最多有 28 個(互聯(lián)型),但是 STM32F103ZET6 只有 14 個(增強型),每個濾波器組 x 由 2 個 32 為寄存器, CAN_FxR1 和 CAN_FxR2 組成。學習了CAN通訊,底層的東東CAN控制器已經(jīng)幫你處理完成,也就是CAN通訊協(xié)議已經(jīng)做好,你按協(xié)議格式往對應(yīng)的位扔數(shù)據(jù)發(fā)送就好,所以使用CAN通訊,我們只需要去關(guān)心制定發(fā)送的數(shù)據(jù)間的協(xié)議,也就是給每個數(shù)據(jù)加上有標識符的協(xié)議。
CAN過濾器的分析
因為STM32在非互聯(lián)網(wǎng)型產(chǎn)品中CAN控制器提供了14個位寬可變、可配置的過濾器組(13~0),每個過濾器組x由2個32位寄存器,CAN_FxR0和CAN_FxR1組成,而1個過濾器組的位寬設(shè)置可以分成四種工作模式,工作模式取決于兩個寄存器FBMx,FSCx的設(shè)置,如下圖所示:
看到過濾器的四種工作模式,工作模式中標識符屏蔽和列表模式,如何去理解,舉個例子,假如我們發(fā)送的標識IDCanTxMsg.StdId是0x000~0x00f,接收過濾先用標識符屏蔽模式來過濾標識的ID,如下所示:
ID : 000 0000 0000 xxxx 屏蔽 : 111 1111 1111 0000x代表0或者1都是可以通過,0000到1111的任意組合,這樣就可以過濾出0x000~0x00f的數(shù)據(jù)的,所以屏蔽的意思就是讓某個范圍的標識符ID可以通過,目的是過濾出一組標志符。那么如果想過濾出一個數(shù)據(jù)0x003,用標識符屏蔽模式實現(xiàn)方式如下
ID : 000 0000 0000 0011 屏蔽 : 111 1111 1111 1111如果接收過濾使用標識符列表模式來過濾標識ID,如下所示,
ID : 000 0000 0001 ID : 000 0000 0010CAN 接收過濾器的四種工作模式的程序配置`
1、32位標識符屏蔽模式
假如要發(fā)送的標示符IDCanTxMsg.StdId范圍為0x010~0x01f
程序配置如下
CAN_RxFilerconfig(0,CANRX32IDMASK); //32位標識符屏蔽模式 void CAN_RxFilerconfig(u8 FilterNum,u8 FilterMode) {CAN_FilterInitTypeDef CAN_FilterInitStructure;CAN_FilterInitStructure.CAN_FilterNumber=FilterNum; //過濾器號0~13可選if(FilterMode==CANRX32IDMASK){CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; //標識符屏蔽模式CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //32位寬 }else if(FilterMode==CANRX32IDLIST){CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdList; //標識符列表模式CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //32位寬 }else if(FilterMode==CANRX16IDMASK){CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; //標識符屏蔽模式CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_16bit; //16位寬 }else if(FilterMode==CANRX16IDLIST){CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdList; //標識符列表模式CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_16bit; //16位寬}//標識符寄存器FxR1CAN_FilterInitStructure.CAN_FilterIdHigh=0x010<<5; //32位ID,高16位CAN_FilterInitStructure.CAN_FilterIdLow=0x0000; //低16位//屏蔽寄存器FxR2CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0xfe1f; //32位MASK,高16位CAN_FilterInitStructure.CAN_FilterMaskIdLow=0xffff; //低16位CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0; //過濾器0關(guān)聯(lián)到FIFO0CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //激活過濾器0CAN_FilterInit(&CAN_FilterInitStructure); //濾波器初始化 }2、32位標識符列表模式
假如要發(fā)送的標示符IDCanTxMsg.StdId為0x011和0x012兩個。
程序配置
CAN_RxFilerconfig(0,CANRX32IDLIST); //32位標識符列表模式 void CAN_RxFilerconfig(u8 FilterNum,u8 FilterMode) {CAN_FilterInitTypeDef CAN_FilterInitStructure;CAN_FilterInitStructure.CAN_FilterNumber=FilterNum; //過濾器號0~13可選if(FilterMode==CANRX32IDMASK){CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; //標識符屏蔽模式CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //32位寬 }else if(FilterMode==CANRX32IDLIST){CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdList; //標識符列表模式CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //32位寬 }else if(FilterMode==CANRX16IDMASK){CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; //標識符屏蔽模式CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_16bit; //16位寬 }else if(FilterMode==CANRX16IDLIST){CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdList; //標識符列表模式CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_16bit; //16位寬}//標識符寄存器FxR1CAN_FilterInitStructure.CAN_FilterIdHigh=0x011<<5; //32位ID,高16位CAN_FilterInitStructure.CAN_FilterIdLow=0x0000; //低16位//屏蔽寄存器FxR2CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x012<<5; //32位MASK,高16位CAN_FilterInitStructure.CAN_FilterMaskIdLow=0xffff; //低16位CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0; //過濾器0關(guān)聯(lián)到FIFO0CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //激活過濾器0CAN_FilterInit(&CAN_FilterInitStructure); //濾波器初始化 }3、16位標識符屏蔽模式
假如要發(fā)送的標示符IDCanTxMsg.StdId范圍為0x0100x01f,0x0000x00f。
程序配置如下
CAN_RxFilerconfig(0,CANRX16IDMASK); //16位標識符屏蔽模式 void CAN_RxFilerconfig(u8 FilterNum,u8 FilterMode) {CAN_FilterInitTypeDef CAN_FilterInitStructure;CAN_FilterInitStructure.CAN_FilterNumber=FilterNum; //過濾器號0~13可選if(FilterMode==CANRX32IDMASK){CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; //標識符屏蔽模式CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //32位寬 }else if(FilterMode==CANRX32IDLIST){CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdList; //標識符列表模式CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //32位寬 }else if(FilterMode==CANRX16IDMASK){CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; //標識符屏蔽模式CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_16bit; //16位寬 }else if(FilterMode==CANRX16IDLIST){CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdList; //標識符列表模式CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_16bit; //16位寬}//標識符寄存器FxR1CAN_FilterInitStructure.CAN_FilterIdHigh=0xfe1f; //32位ID,高16位CAN_FilterInitStructure.CAN_FilterIdLow=0x010<<5; //低16位//屏蔽寄存器FxR2CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0xfe1f; //32位MASK,高16位CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x000<<5; //低16位CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0; //過濾器0關(guān)聯(lián)到FIFO0CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //激活過濾器0CAN_FilterInit(&CAN_FilterInitStructure); //濾波器初始化 }4、16位標識符列表模式
假如要發(fā)送的標示符IDCanTxMsg.StdId 有0x010,0x01f,0x001,0x00f四個。
程序配置如下
CAN_RxFilerconfig(0,CANRX16IDLIST); //16位標識符列表模式 void CAN_RxFilerconfig(u8 FilterNum,u8 FilterMode) {CAN_FilterInitTypeDef CAN_FilterInitStructure;CAN_FilterInitStructure.CAN_FilterNumber=FilterNum; //過濾器號0~13可選if(FilterMode==CANRX32IDMASK){CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; //標識符屏蔽模式CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //32位寬 }else if(FilterMode==CANRX32IDLIST){CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdList; //標識符列表模式CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //32位寬 }else if(FilterMode==CANRX16IDMASK){CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; //標識符屏蔽模式CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_16bit; //16位寬 }else if(FilterMode==CANRX16IDLIST){CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdList; //標識符列表模式CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_16bit; //16位寬}//標識符寄存器FxR1CAN_FilterInitStructure.CAN_FilterIdHigh=0x01f<<5; //32位ID,高16位CAN_FilterInitStructure.CAN_FilterIdLow=0x010<<5; //低16位//屏蔽寄存器FxR2CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x00f<<5; //32位MASK,高16位CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x001<<5; //低16位CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0; //過濾器0關(guān)聯(lián)到FIFO0CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //激活過濾器0CAN_FilterInit(&CAN_FilterInitStructure); //濾波器初始化 }總結(jié)
以上是生活随笔為你收集整理的STM32F103的CAN通讯接收过滤器过滤分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 免费沙箱软件模拟支付_沙箱模拟公众号支付
- 下一篇: intel realsense 使用代碼