STM32 CAN错误管理
-【問(wèn)題背景】-
在使用CAN交互過(guò)程中,如果短接CAN_H和CAN_L,或者CAN_H接地,或者CAN總線上有較大的干擾,接收方STM32出現(xiàn)了無(wú)法觸發(fā)CAN數(shù)據(jù)接收中斷,則程序無(wú)法再接收數(shù)據(jù),MCU本身未死機(jī)。復(fù)位后能正常收發(fā)。
-【解決】-
CAN初始化時(shí)開(kāi)啟自動(dòng)離線管理功能即可
CAN_InitStructure.CAN_ABOM=ENABLE; //開(kāi)啟自動(dòng)離線管理
以上是標(biāo)準(zhǔn)庫(kù)的情況,使用HAL庫(kù)同理。
-【分析】-
根據(jù)ISO11898有如下幾個(gè)重要的與CAN相關(guān)的定義:
- Fault confinement(錯(cuò)誤界定)
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節(jié)點(diǎn)可以區(qū)分常規(guī)錯(cuò)誤和永久故障。有故障的發(fā)送節(jié)點(diǎn)將切換到離線狀態(tài)。離線意味著在邏輯上與總線斷開(kāi),既不能發(fā)送也不能接收。
- Error-active(主動(dòng)錯(cuò)誤)
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 .
處于主動(dòng)錯(cuò)誤狀態(tài)的節(jié)點(diǎn)能正常參與總線通信的收發(fā)和當(dāng)檢測(cè)到錯(cuò)誤時(shí)將發(fā)送錯(cuò)誤標(biāo)志,錯(cuò)誤標(biāo)志由6個(gè)連續(xù)的顯示位組成(這種連續(xù)的6個(gè)顯示位與常規(guī)的填充位和其它幀固定格式不相同,正因?yàn)槿绱?#xff0c;硬件才容易區(qū)別)。
- Error-passive(被動(dòng)錯(cuò)誤)
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 .
處于被動(dòng)錯(cuò)誤狀態(tài)的節(jié)點(diǎn)不能發(fā)送主動(dòng)錯(cuò)誤標(biāo)志。它能參與正常通信,但當(dāng)檢測(cè)到錯(cuò)誤時(shí)發(fā)送的是被動(dòng)錯(cuò)誤標(biāo)志。被動(dòng)錯(cuò)誤標(biāo)志由6個(gè)連續(xù)的隱性位組成。當(dāng)發(fā)送結(jié)束后,處于被動(dòng)錯(cuò)誤狀態(tài)的節(jié)點(diǎn)在下一次再次發(fā)送時(shí)之前需要等待一些額外時(shí)間。
- 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.
由于錯(cuò)誤界定規(guī)則,一個(gè)節(jié)點(diǎn)可能處于離線狀態(tài),當(dāng)處于此狀態(tài)時(shí),這個(gè)節(jié)點(diǎn)既不發(fā)送也不接收。至于何時(shí)離線恢復(fù)取決于何時(shí)用戶(hù)請(qǐng)求。
ISO11898中錯(cuò)誤界定的規(guī)則
1.描述
當(dāng)涉及到錯(cuò)誤界定,一個(gè)節(jié)點(diǎn)必須處于下述三個(gè)錯(cuò)誤狀態(tài)中的其中一個(gè),至于具體是哪種錯(cuò)誤狀態(tài)取決于節(jié)點(diǎn)的錯(cuò)誤計(jì)數(shù)值:
主動(dòng)錯(cuò)誤狀態(tài)(Error-active)
被動(dòng)錯(cuò)誤狀態(tài)(Error-passive)
離線狀態(tài)(Bus-off)
2.錯(cuò)誤計(jì)數(shù)
錯(cuò)誤計(jì)數(shù)器當(dāng)檢測(cè)下下述事件時(shí)將修改錯(cuò)誤計(jì)數(shù)值:
當(dāng)一接收節(jié)點(diǎn)檢測(cè)到一個(gè)錯(cuò)誤時(shí),錯(cuò)誤計(jì)數(shù)器將加1.有一種情況可以排外,即當(dāng)檢測(cè)到發(fā)送一主動(dòng)錯(cuò)誤標(biāo)志或者重載標(biāo)志時(shí)出現(xiàn)一位錯(cuò)誤時(shí)除外。
當(dāng)一接收節(jié)點(diǎn)發(fā)送一錯(cuò)誤標(biāo)志時(shí),檢測(cè)到首位為顯性位時(shí),錯(cuò)誤計(jì)數(shù)器加8.
當(dāng)一發(fā)送節(jié)后發(fā)送錯(cuò)誤標(biāo)志時(shí),錯(cuò)誤計(jì)數(shù)器加8,這時(shí)有兩種情況除外:1:當(dāng)這個(gè)發(fā)送節(jié)點(diǎn)處于主動(dòng)錯(cuò)誤狀態(tài)下,且檢測(cè)到由于ACK域未有顯性位而造成的ACK錯(cuò)誤,但是在發(fā)送時(shí)未檢測(cè)到被動(dòng)錯(cuò)誤標(biāo)志;2:當(dāng)發(fā)送節(jié)點(diǎn)發(fā)送一錯(cuò)誤標(biāo)志時(shí),在仲裁時(shí)檢測(cè)到填充位錯(cuò)誤(這些填充位原來(lái)應(yīng)該是隱性,但檢測(cè)結(jié)果為顯性)。以上兩種異常錯(cuò)誤計(jì)數(shù)值保留原值不變。
當(dāng)發(fā)送節(jié)點(diǎn)發(fā)送一主動(dòng)錯(cuò)誤標(biāo)志或重載標(biāo)志時(shí),檢測(cè)到位錯(cuò)誤時(shí),錯(cuò)誤計(jì)數(shù)器加8.
當(dāng)接收節(jié)點(diǎn)婁送一主動(dòng)錯(cuò)誤標(biāo)志或重載標(biāo)志時(shí),檢測(cè)到位錯(cuò)誤時(shí),錯(cuò)誤計(jì)數(shù)器加8.
任何節(jié)點(diǎn)在發(fā)送主動(dòng)錯(cuò)誤標(biāo)志,被動(dòng)錯(cuò)誤標(biāo)志,或重載標(biāo)志時(shí)都應(yīng)都忍受連續(xù)7個(gè)顯示位。當(dāng)檢測(cè)到連接14個(gè)顯示位,或者被動(dòng)錯(cuò)誤標(biāo)志后緊跟著連接8個(gè)顯示位,或者8個(gè)連續(xù)顯性位后緊跟著被動(dòng)錯(cuò)誤標(biāo)志時(shí),所有發(fā)送節(jié)點(diǎn)發(fā)送錯(cuò)誤計(jì)數(shù)器加8,所有接收節(jié)點(diǎn)接收錯(cuò)誤計(jì)數(shù)器加8.
發(fā)成功發(fā)送一幀報(bào)文后,發(fā)送計(jì)數(shù)器應(yīng)減1,除非當(dāng)前已經(jīng)為0.
當(dāng)成功接收一幀報(bào)文后,如果當(dāng)前接收計(jì)數(shù)器的值大于1且小于127,則接收計(jì)數(shù)器減1;如果接收計(jì)數(shù)器的值為0,則保持為0;如果在于127,則接收計(jì)數(shù)器的值應(yīng)設(shè)置 為119~127之間的值。
3.主動(dòng)錯(cuò)誤狀態(tài)和被動(dòng)錯(cuò)誤狀態(tài)之間的轉(zhuǎn)變
當(dāng)發(fā)送錯(cuò)誤計(jì)數(shù)器或者接收錯(cuò)誤計(jì)數(shù)器的值大于127時(shí),該節(jié)點(diǎn)變成被動(dòng)錯(cuò)誤狀態(tài)。
當(dāng)節(jié)點(diǎn)從主動(dòng)錯(cuò)誤狀態(tài)變?yōu)楸粍?dòng)錯(cuò)誤狀態(tài)時(shí),節(jié)點(diǎn)將發(fā)送一主動(dòng)錯(cuò)誤標(biāo)志。
當(dāng)被動(dòng)錯(cuò)誤節(jié)點(diǎn)的發(fā)送錯(cuò)誤計(jì)數(shù)器和接收錯(cuò)誤計(jì)數(shù)器的值都小于且等于127時(shí),將再次變?yōu)橹鲃?dòng)錯(cuò)誤狀態(tài)。
4.離線管理
如果一個(gè)節(jié)點(diǎn)的發(fā)送錯(cuò)誤計(jì)數(shù)器的值超過(guò)255時(shí),那么此節(jié)點(diǎn)將會(huì)處于離線狀態(tài)。處于離線狀態(tài)的節(jié)點(diǎn)不會(huì)對(duì)總線產(chǎn)生任何影響,它將不會(huì)發(fā)送消息幀,ACK,錯(cuò)誤幀,過(guò)載幀等,至于會(huì)不會(huì)接收總線上的數(shù)據(jù),取消于此節(jié)點(diǎn)的實(shí)現(xiàn)。
當(dāng)一個(gè)處于離線狀態(tài)下的節(jié)點(diǎn)接收到128次連接11位隱性位時(shí),將變成主動(dòng)錯(cuò)誤狀態(tài),且同時(shí)設(shè)置發(fā)送錯(cuò)誤計(jì)數(shù)器和接收錯(cuò)誤計(jì)數(shù)器為0.
STM32的CAN錯(cuò)誤管理機(jī)制詳見(jiàn)參考手冊(cè):
從上圖可以看出,STM32的CAN錯(cuò)誤管理機(jī)制與ISO11898基本一致。只是進(jìn)入離線模式后,在STM32是有一開(kāi)關(guān)來(lái)設(shè)置是否會(huì)自動(dòng)還原到主動(dòng)錯(cuò)誤狀態(tài),如果此功能禁止了,那么當(dāng)處于離線狀態(tài)下的節(jié)點(diǎn)接收到128次連接11連隱性位時(shí)也不會(huì)不還原成主動(dòng)錯(cuò)誤狀態(tài)。
設(shè)置自動(dòng)離線管理開(kāi)關(guān)的寄存器在CAN_MCR中:
下面在STM32F103VET6上測(cè)試CAN總線正常通訊時(shí)讀取相關(guān)的寄存器狀態(tài):
LEC=0
REC=0
TEC=0
CAN1->ESR=00000000
CAN1->TSR=1C000000
CAN1->RF0R=00000000
CAN1->RF1R=00000000
該段測(cè)試代碼是:
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接地一段時(shí)間,使其進(jìn)入離線狀態(tài),讀取到相關(guān)的寄存器狀態(tài):
LEC=80
REC=255
TEC=248
CAN1->ESR=FFF80057
CAN1->TSR=19000008
CAN1->RF0R=00000000
CAN1->RF1R=00000000
LEC=80是十進(jìn)制,右移4位對(duì)應(yīng)的是101錯(cuò)誤代碼,即顯性位錯(cuò)。
根據(jù)ISO11898定義,TEC>255則CAN控制器進(jìn)入離線模式,測(cè)試發(fā)現(xiàn)TEC是248,由于248+8=256,已經(jīng)超過(guò)了255,所以停在了248。
由CAN1->ESR=FFF80057可見(jiàn),低三位都置位了,如下圖所示,而這幾位按時(shí)間順序應(yīng)該是首先EWGF置位,然后是EPVF,最后是BOFF。
【關(guān)于CAN錯(cuò)誤中斷】
CAN_IER中的ERRIE位是一個(gè)CAN出錯(cuò)中斷總開(kāi)關(guān),只有當(dāng)它被使能的前提下,EWG、EPV、BOF、LEC四個(gè)中的一個(gè)或幾個(gè)出錯(cuò)事件配合各自的中斷使能位才能產(chǎn)生出錯(cuò)中斷,并統(tǒng)一將CAN_MSR中的錯(cuò)誤中斷請(qǐng)求ERRI位置1,從而申請(qǐng)CAN錯(cuò)誤中斷。顯然,CAN錯(cuò)誤中斷的請(qǐng)求標(biāo)志位是ERRI@CAN_MSR,而不是CAN_ESR中的EWGF\EPVF\BOFF的任一位。
且注意,ERRI出錯(cuò)中斷掛號(hào)標(biāo)志需要軟件清除,否則會(huì)不停觸發(fā)中斷。
清中斷示例:
參考:
https://blog.csdn.net/flydream0/article/details/8161418
stm32_can錯(cuò)誤中斷
https://blog.csdn.net/TOUGH_JIN/article/details/91345597
總結(jié)
以上是生活随笔為你收集整理的STM32 CAN错误管理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: vi/vim使用教程
- 下一篇: C语言 十进制整数字符串转十六进制字符串