STM32 CAN错误管理
-【問題背景】-
在使用CAN交互過程中,如果短接CAN_H和CAN_L,或者CAN_H接地,或者CAN總線上有較大的干擾,接收方STM32出現了無法觸發CAN數據接收中斷,則程序無法再接收數據,MCU本身未死機。復位后能正常收發。
-【解決】-
CAN初始化時開啟自動離線管理功能即可
CAN_InitStructure.CAN_ABOM=ENABLE; //開啟自動離線管理
以上是標準庫的情況,使用HAL庫同理。
-【分析】-
根據ISO11898有如下幾個重要的與CAN相關的定義:
- Fault confinement(錯誤界定)
CAN nodes shall be able to distinguish short disturbances from permanent failures. Defective transmitting nodes shall be switched off. Switched off means a node is logically disconnected from the bus, so that it can neither send nor receive any frames.
CAN節點可以區分常規錯誤和永久故障。有故障的發送節點將切換到離線狀態。離線意味著在邏輯上與總線斷開,既不能發送也不能接收。
- Error-active(主動錯誤)
An error-active node shall normally take part in bus communication and send an active error flag when an error has been detected. The active error flag shall consist of six (6) consecutive dominant bits and shall violate the rule of bit stuffing and all fixed formats appearing in a regular frame .
處于主動錯誤狀態的節點能正常參與總線通信的收發和當檢測到錯誤時將發送錯誤標志,錯誤標志由6個連續的顯示位組成(這種連續的6個顯示位與常規的填充位和其它幀固定格式不相同,正因為如此,硬件才容易區別)。
- Error-passive(被動錯誤)
An error-passive node shall not send an active error flag. It takes part in bus communication, but when an error has been detected a passive error flag shall be sent. The passive error flag shall consist of six (6) consecutive recessive bits. After transmission, an error-passive node shall wait some additional time before initiating a further transmission .
處于被動錯誤狀態的節點不能發送主動錯誤標志。它能參與正常通信,但當檢測到錯誤時發送的是被動錯誤標志。被動錯誤標志由6個連續的隱性位組成。當發送結束后,處于被動錯誤狀態的節點在下一次再次發送時之前需要等待一些額外時間。
- Bus-off(離線)
A node shall be in the bus-off state when it is switched off from the bus due to a request of FCE. In the bus-off state, a node shall neither send nor receive any frames. A node shall start the recovery from bus-off state only upon a user request.
由于錯誤界定規則,一個節點可能處于離線狀態,當處于此狀態時,這個節點既不發送也不接收。至于何時離線恢復取決于何時用戶請求。
ISO11898中錯誤界定的規則
1.描述
當涉及到錯誤界定,一個節點必須處于下述三個錯誤狀態中的其中一個,至于具體是哪種錯誤狀態取決于節點的錯誤計數值:
主動錯誤狀態(Error-active)
被動錯誤狀態(Error-passive)
離線狀態(Bus-off)
2.錯誤計數
錯誤計數器當檢測下下述事件時將修改錯誤計數值:
當一接收節點檢測到一個錯誤時,錯誤計數器將加1.有一種情況可以排外,即當檢測到發送一主動錯誤標志或者重載標志時出現一位錯誤時除外。
當一接收節點發送一錯誤標志時,檢測到首位為顯性位時,錯誤計數器加8.
當一發送節后發送錯誤標志時,錯誤計數器加8,這時有兩種情況除外:1:當這個發送節點處于主動錯誤狀態下,且檢測到由于ACK域未有顯性位而造成的ACK錯誤,但是在發送時未檢測到被動錯誤標志;2:當發送節點發送一錯誤標志時,在仲裁時檢測到填充位錯誤(這些填充位原來應該是隱性,但檢測結果為顯性)。以上兩種異常錯誤計數值保留原值不變。
當發送節點發送一主動錯誤標志或重載標志時,檢測到位錯誤時,錯誤計數器加8.
當接收節點婁送一主動錯誤標志或重載標志時,檢測到位錯誤時,錯誤計數器加8.
任何節點在發送主動錯誤標志,被動錯誤標志,或重載標志時都應都忍受連續7個顯示位。當檢測到連接14個顯示位,或者被動錯誤標志后緊跟著連接8個顯示位,或者8個連續顯性位后緊跟著被動錯誤標志時,所有發送節點發送錯誤計數器加8,所有接收節點接收錯誤計數器加8.
發成功發送一幀報文后,發送計數器應減1,除非當前已經為0.
當成功接收一幀報文后,如果當前接收計數器的值大于1且小于127,則接收計數器減1;如果接收計數器的值為0,則保持為0;如果在于127,則接收計數器的值應設置 為119~127之間的值。
3.主動錯誤狀態和被動錯誤狀態之間的轉變
當發送錯誤計數器或者接收錯誤計數器的值大于127時,該節點變成被動錯誤狀態。
當節點從主動錯誤狀態變為被動錯誤狀態時,節點將發送一主動錯誤標志。
當被動錯誤節點的發送錯誤計數器和接收錯誤計數器的值都小于且等于127時,將再次變為主動錯誤狀態。
4.離線管理
如果一個節點的發送錯誤計數器的值超過255時,那么此節點將會處于離線狀態。處于離線狀態的節點不會對總線產生任何影響,它將不會發送消息幀,ACK,錯誤幀,過載幀等,至于會不會接收總線上的數據,取消于此節點的實現。
當一個處于離線狀態下的節點接收到128次連接11位隱性位時,將變成主動錯誤狀態,且同時設置發送錯誤計數器和接收錯誤計數器為0.
STM32的CAN錯誤管理機制詳見參考手冊:
從上圖可以看出,STM32的CAN錯誤管理機制與ISO11898基本一致。只是進入離線模式后,在STM32是有一開關來設置是否會自動還原到主動錯誤狀態,如果此功能禁止了,那么當處于離線狀態下的節點接收到128次連接11連隱性位時也不會不還原成主動錯誤狀態。
設置自動離線管理開關的寄存器在CAN_MCR中:
下面在STM32F103VET6上測試CAN總線正常通訊時讀取相關的寄存器狀態:
LEC=0
REC=0
TEC=0
CAN1->ESR=00000000
CAN1->TSR=1C000000
CAN1->RF0R=00000000
CAN1->RF1R=00000000
該段測試代碼是:
printf("LEC=%d\r\n",CAN_GetLastErrorCode(CAN1)); printf("REC=%d\r\n",CAN_GetReceiveErrorCounter(CAN1)); printf("TEC=%d\r\n",CAN_GetLSBTransmitErrorCounter(CAN1)); printf("CAN1->ESR=%08X\r\n",CAN1->ESR); printf("CAN1->TSR=%08X\r\n",CAN1->TSR); printf("CAN1->RF0R=%08X\r\n",CAN1->RF0R); printf("CAN1->RF1R=%08X\r\n",CAN1->RF1R);將CAN_H接地一段時間,使其進入離線狀態,讀取到相關的寄存器狀態:
LEC=80
REC=255
TEC=248
CAN1->ESR=FFF80057
CAN1->TSR=19000008
CAN1->RF0R=00000000
CAN1->RF1R=00000000
LEC=80是十進制,右移4位對應的是101錯誤代碼,即顯性位錯。
根據ISO11898定義,TEC>255則CAN控制器進入離線模式,測試發現TEC是248,由于248+8=256,已經超過了255,所以停在了248。
由CAN1->ESR=FFF80057可見,低三位都置位了,如下圖所示,而這幾位按時間順序應該是首先EWGF置位,然后是EPVF,最后是BOFF。
【關于CAN錯誤中斷】
CAN_IER中的ERRIE位是一個CAN出錯中斷總開關,只有當它被使能的前提下,EWG、EPV、BOF、LEC四個中的一個或幾個出錯事件配合各自的中斷使能位才能產生出錯中斷,并統一將CAN_MSR中的錯誤中斷請求ERRI位置1,從而申請CAN錯誤中斷。顯然,CAN錯誤中斷的請求標志位是ERRI@CAN_MSR,而不是CAN_ESR中的EWGF\EPVF\BOFF的任一位。
且注意,ERRI出錯中斷掛號標志需要軟件清除,否則會不停觸發中斷。
清中斷示例:
參考:
https://blog.csdn.net/flydream0/article/details/8161418
stm32_can錯誤中斷
https://blog.csdn.net/TOUGH_JIN/article/details/91345597
總結
以上是生活随笔為你收集整理的STM32 CAN错误管理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vi/vim使用教程
- 下一篇: C语言 十进制整数字符串转十六进制字符串