STM32 CAN 使用心得!
阿新 • • 發佈:2019-02-16
1.CAN最大的優點是可以實現多機通訊,適合工業控制組網的應用,有專門的PCI板卡可以將CAN連線的PC機上,對網路監控
2.CAN匯流排出了電源線之外就是CANH和CANL兩個線,CAN對總線上點評的解析靠這兩根線同時完成,即時
CAN總線上的電平分為隱形和現行兩種。
3.CAN匯流排的最大通訊速率,就是波特率,小於等於1Mbps
4.它的榮從能力較強,可以設定仲裁錯誤,自動重發等等高階操作。
5.CAN網路中多機通訊主要是通過標示符來分辨主從兩節點的。主機發總報文後,在總線上的所有CAN從機都能接收到報文,每個CAN模都配置有自己的過濾器組,他們最網路上的報文ID進行過濾,儲存需要的報文到郵箱裡面。非過濾規則的報文將會自動丟棄,不會存入郵箱。
下面介紹CAN的數據幀和標示符:
分為擴充套件幀和標準幀兩種,他們的區別主要在於標示符的長度。擴充套件幀中標示符ID程度有29為,標準幀中標示符長度只有11位。傳送郵箱標示符暫存器如下:
不論選擇那種模式,都會儲存在這個暫存器中。IDE是標示符型別的選擇位,置1選擇擴充套件RTR是幀型別,分資料幀和遠端幀,最後一位是傳送請求。
根據上面的暫存器,在初始化過濾器組的時候應該注意一下移位操作。
過濾器組配置分為來那個中模式,其一、就是遮蔽位模式,其二、標示符列表模式。首先共有27個過濾器組,F103有14個,而每個過濾器組有兩個標示符過濾的暫存器,可配置成16或32位。
遮蔽位模式下面,兩個暫存器一個用來裝期望得到標示符,一個用來裝遮蔽位配置,遮蔽位類似於掩碼的概念,遮蔽位置0的對應期望得到的標示符的該位在過濾時候不關心,置1的時候則要求該位要與對應的期望得到的標示符中的該位一致。另一種列表模式則要求,收到的報文的標示符必須與期望值完全一致。
同理對於標準幀模式下的設定一樣應該先左移21位,然後分別取出低16位。 其中CanFilter_Init.CAN_FilterNumber是初始化FAR暫存器啟用某個過濾器組。 CanFilter_Init.CAN_FilterMode是初始化FM1R模式選擇。 CAN_FilterInitStructure.CAN_FilterFIFOAssignment設定過濾完後關聯的FIFO。 至此基本可以完成過濾器組的初始化了! 波特率設定:
波特率是每個位的時間的倒數,在STM32中每一位的時長分為三段,在STM32中這些為的時長是可程式設計的:
設定每個段的時長,時長是實常數乘以時間單位,時間單位是CAN所使用的時鐘基準,即它所掛載的系統時鐘的分頻,而單位時間也是可程式設計的
BPR是對應的時間單元的程式設計位:tq= (BRP[9:0]+1) x tpclk
TS1和TS2就是是段1和時段2的長度的程式設計位:tBS2= t CAN x (TS2[2:0] + 1)。。
用庫函式程式設計:
CAN1主控制配置如下:
標示符和遮蔽位過濾組:
每次傳送資料之前都要先將資料資訊寫入到一個空的傳送郵箱的暫存器中,包括標識福暫存器和資料暫存器,時間戳資料長度暫存器,一幀資料的組成如下:配置時候的麻煩在於,使用庫函式時,由於對於IDH和IDHmask的處理是取低16位然後左移16位就直接賦值給了過濾器組的FIR暫存器;IDL和IDLmask也是直接取低16位然後賦值給了FIR,所以對於某個報文的ID需要做一位處理之後才能得到需要賦值給暫存器的數值。如果是擴充套件標示符,應該先將擴充套件ID左移3位得到在暫存器中的位置,然後將它分別移位得到高16和低16然後賦值,所以取高16位應先左移3位在右移16位合起來左移(3-16)是右移13位,而低16位是左移3位後直接取低16。MASK位也同理。如果出了想過濾ID還想過濾暫存器低三位一般是IDE,那麼取得低16位之後再或上CAN_Id_Extended就行了,IDmask對應的或上第三位的遮蔽位,就是0x04.CanFilter_Init.CAN_FilterNumber = 0; //過濾器組使能 CanFilter_Init.CAN_FilterMode = CAN_FilterMode_IdMask; // CanFilter_Init.CAN_FilterMode = CAN_FilterMode_IdList; CanFilter_Init.CAN_FilterScale = CAN_FilterScale_32bit; // CanFilter_Init.CAN_FilterFIFOAssignment = CAN_FilterFIFO0; CanFilter_Init.CAN_FilterIdHigh=(uint16_t)(ExCAN_ID>>13); CanFilter_Init.CAN_FilterIdLow= (uint16_t)(ExCAN_ID<<3)|CAN_Id_Extended|CAN_RTR_DATA; CanFilter_Init.CAN_FilterMaskIdHigh = 0x0000ffff; CanFilter_Init.CAN_FilterMaskIdLow = 0x0000ffff<<3|0x04; // CanFilter_Init.CAN_FilterIdHigh=(0x00000021<<(21-16)); // CanFilter_Init.CAN_FilterIdLow= (0x00000021<<21); // CanFilter_Init.CAN_FilterMaskIdHigh = 0x0000ffff<<(21-16); // CanFilter_Init.CAN_FilterMaskIdLow = 0x0000ffff<<21; CanFilter_Init.CAN_FilterActivation=ENABLE; //啟用過濾器 CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0; CAN_FilterInit(&CanFilter_Init);
同理對於標準幀模式下的設定一樣應該先左移21位,然後分別取出低16位。 其中CanFilter_Init.CAN_FilterNumber是初始化FAR暫存器啟用某個過濾器組。 CanFilter_Init.CAN_FilterMode是初始化FM1R模式選擇。 CAN_FilterInitStructure.CAN_FilterFIFOAssignment設定過濾完後關聯的FIFO。 至此基本可以完成過濾器組的初始化了! 波特率設定:
//CANµÄ²¨ÌØÂÊÉèÖÃ
Can_Init.CAN_Mode= CAN_Mode_LoopBack;
Can_Init.CAN_SJW=CAN_SJW_1tq;
Can_Init.CAN_BS1=CAN_BS1_8tq;
Can_Init.CAN_BS2=CAN_BS2_7tq;
Can_Init.CAN_Prescaler=5;
CAN_Init(CAN1, &Can_Init);
至此波特率設定完成。CAN1主控制配置如下:
//CANµÄÖ÷¿ØÖƼĴæÆ÷
Can_Init.CAN_TTCM = DISABLE;
Can_Init.CAN_ABOM=DISABLE;
Can_Init.CAN_AWUM=DISABLE;
Can_Init.CAN_NART=ENABLE;
Can_Init.CAN_RFLM=DISABLE;
Can_Init.CAN_TXFP=DISABLE;
可以按照CAN_InitTypeDef的內容進行配置。
中斷配置:
按照STM32的中斷配置方式將對應外設的中斷使能,然後將對應外設中斷連線的系統中斷通道使能,設定中斷優先順序即可。
在STM32中外設的某些中斷是共用一箇中斷通道的,而這些中斷的先後順序要等到進入對應中斷通道的服務函式之後軟體設定中斷的先後順序。
一般使用的就是傳送或者FIFO郵箱接收報文的中斷。使用接收中斷的配置如下:
//ʹÄÜCAN1µÄFIFO0ÖжÏFIFO0£¬ÏûÏ¢¹ÒºÅÖжÏ
CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);
//ÖжÏÓÅÏȼ¶µÄ·Ö×é
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
//NVIC³õʼ»¯ÖжÏ
nvic.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
nvic.NVIC_IRQChannelPreemptionPriority = 0x02;
nvic.NVIC_IRQChannelSubPriority = 0x02;
nvic.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&nvic);
中斷函式,和中斷向量名可以在啟動檔案startup_stm32f10x_hd.s查到。
而中斷的定義可以在stm32f10x.h中查到。