CAN通信的調試不單是軟體上的調試,也需要對硬體進行檢查。原文鏈接:https://www.cnblogs.com/Cloudcan/p/13358095.html 在調通之前一直有兩個疑惑干擾判斷:(結論在文末)1.不同的CAN晶元是否存在不相容。2.不同型號的STM32是否CAN通信是否存在差異 ...
CAN通信的調試不單是軟體上的調試,也需要對硬體進行檢查。
原文鏈接:https://www.cnblogs.com/Cloudcan/p/13358095.html
在調通之前一直有兩個疑惑干擾判斷:(結論在文末)
1.不同的CAN晶元是否存在不相容。
2.不同型號的STM32是否CAN通信是否存在差異。
STM32F1與STM32F4之間CAN通信的調試過程(僅以STM32F1作介紹[標準庫]):
1.確定引腳與資源
這裡我們使用PB8、PB9來作為CAN通信引腳,單片機上使用CAN1,註意更改引腳映射。
GPIO_PinRemapConfig(GPIO_Remap1_CAN1,ENABLE);
2.確定波特率
我們需要得到的波特率為1Mbps,用戶手冊上波特率的計算方法如下:
這裡看起來比較複雜,展開後為:BaudRate=1/((BRP[9:0]+1)*(1+TS1[3:0]+1+TS2[2:0] + 1)*tPCLK);
由於CAN1掛在在APB1上,tPCLK1為APB1的外設周期,需要知道其頻率fPCLK1。
a.求取頻率
如果使用標準庫可以採用在main函數加兩行代碼:
RCC_ClocksTypeDef get_rcc_clock;
RCC_GetClocksFreq(&get_rcc_clock);
併在調試界面中查看(右鍵去掉勾選即可查看10進位數)
PCLK1為36MHz即APB1外設頻率為36MHz。
如使用CubeMX生成代碼,可以方便查看時鐘樹配置(強烈建議入門STM32的新人嘗試CubeMX,可以直觀地理解STM32的時鐘樹)
b.設定波特率
在標準庫中CAN通信初始化中有:
CAN_InitStructure.CAN_SJW=CAN_SJW_1tq; CAN_InitStructure.CAN_BS1=CAN_BS1_9tq; CAN_InitStructure.CAN_BS2=CAN_BS2_8tq; CAN_InitStructure.CAN_Prescaler=2;
其中SJW、BS1、BS2分別對應(BRP[9:0]+1)、(TS[3:0]+1)、(TS2[3:0]+1);
當我們設定BRP[9:0]為0時公式可以簡化為,BaudRate=1/((1+TS[3:0]+1+TS2[2:0] + 1)*tPCLK)=1/(1+BS1+BS2)/tPCLK;(這就是為何SJW通常取CAN_SJW_1tq)
考慮分頻繫數Pre=fPCLK1/fPCLK,fPCLK為CAN1的頻率:
BaudRate=fPCLK1/((1+BS1+BS2)*Pre);前提SJW取CAN_SJW_1tq;
例如:系統主頻72MHz、APB1外設時鐘頻率fPCLK1=32MHz,當我取SJW=CAN_SJW_1tq,BS1=CAN_BS1_9tq,BS2=CAN_BS2_8tq時BaudRate=32/((1+9+8)*2)=1MHz;
關於疑惑:
由於STM32F1的板子是自己設計並選了新的CAN晶元(便宜),所以一開始會懷疑是CAN晶元的問題。如果兩個CAN都晶元支持我們所需求的波特率,實際上都能夠通信的,問題在於我的兩個設備CAN晶元都是5V供電,而我在調試時其中一個設備直接使用調試器3.3V供電,導致其無法正常工作,所以一直不能收發信息。當然後來發現這個問題之後,使用電源同時給兩個設備供電CAN通信就成功了。
另一個關於不同型號STM32無法進行CAN通信的疑惑主要來源於網上的某帖子,僅僅依據晶元主頻不一致而得出這樣的結論,完全是無稽之談。一般多個STM32之間CAN通信,只要硬體沒問題,同時保證波特率一致,通信上不會有太大問題。