本應用筆記討論了MAX33011E的控制局域網(CAN)總線故障檢測特性,并通過示例代碼演示了如何在固件中實現(xiàn)故障檢測算法。
介紹
在數(shù)據(jù)未傳輸或接收時對控制區(qū)域網絡 (CAN) 進行故障排除可能會令人沮喪。Maxim在CAN收發(fā)器中開發(fā)了內置故障檢測機制,可幫助用戶快速確定根本原因。本應用筆記介紹了故障檢測機制的功能,解釋了其工作原理,并通過示例代碼演示了如何在固件中實現(xiàn)故障檢測算法。
使能故障檢測電路
MAX33011E CAN收發(fā)器需要100 TXD上升沿(通常為幾個CAN協(xié)議消息)來啟用故障檢測電路。故障檢測電路使能后,收發(fā)器仍可正常傳輸消息。
讀取和清除故障代碼
當檢測到故障情況時,發(fā)射器將被禁用,F(xiàn)AULT引腳將通過外部上拉電阻器拉高。當系統(tǒng)控制器接收到FAULT引腳信號時,TXD上需要16次從低到高的轉換來移出故障代碼,如表1所示。另外 10 個從低到高的 TXD 轉換可清除故障并禁用故障檢測電路。例如,過流故障代碼為101010,其時序圖如圖1所示。
圖1.過流故障報告時序圖
故障條件
MAX33011E是首款內置故障檢測電路的CAN收發(fā)器。當故障檢測電路使能時,它可以檢測CAN總線上的三種常見故障條件(過壓、過流和傳輸故障),如表1所示。
故障 | 條件(啟用故障檢測) | 故障代碼 | 可能的原因 |
過電流 | CANH 輸出電流和 CANL 輸入電流均> 85mA | 101010 |
CANH 縮短為 CANL CANH 連接到 GND 和 CANL 連接到 VDD |
電壓 | CANH > +29V 或 CANL < -29V | 101100 | CMR 故障 |
傳輸故障 | RXD 在 10 個連續(xù) TXD 脈沖內保持不變,建議最低頻率 = 200kHz | 110010 |
CANH 和 CANL 上的開路負載(兩個終端電阻器均缺失) 超出驅動器的共模范圍 連接到固定電壓源的 CANH 和/或 CANL |
過流故障
當CANH的源電流和CANL的灌電流均高于85mA(典型值)時,檢測到過流故障。故障的更可能原因是總線上的CANH和CANL短路。但是,如果短路遠離CAN節(jié)點,則由于電纜阻抗高,可能無法檢測到。減慢CAN信號頻率可以降低電纜阻抗,并有助于從更遠的距離檢測短路。但是,如果電纜的總電阻變得明顯高,即使CAN信號始終處于主導模式,也無法檢測到短路。圖2顯示了過流檢測的最大工作頻率與作為參考的電纜長度的關系。使用 Cat5E 銅包鋁電纜。最大頻率因電纜類型而異。
圖2.過流檢測的最大工作頻率與電纜長度的關系
過壓故障
MAX33011E共模輸入范圍(CMR)為±25V。當CANH高于29V或CANH低于-29V時,檢測到過壓故障。這是由于 CMR 超出規(guī)范造成的。
傳輸故障故障
故障檢測電路使能后,收發(fā)器仍可傳輸消息。在正常工作條件下,RXD 會回顯 TXD 信號。如果RXD連續(xù)10個脈沖沒有回顯TXD信號,則檢測電路會產生傳輸故障。有幾個常見的可能原因使 RXD 無法回顯 TXD:
如果CANH和CANL短路至電源,并且收發(fā)器無法過驅電源,則接收器將始終在CAN總線上看到固定信號。
當共模電壓超過驅動器的共模范圍(-5V至+10V)時,驅動器關斷。當驅動器關閉時,CANH/CANL輸出不會在TXD上反射信號,接收器將在CAN總線上看到固定信號。
如果終端電阻未連接到CAN節(jié)點,則可能導致傳輸故障。終端電阻在隱性模式下使CANH和CANL達到相同的電壓電平方面起著非常重要的作用。如果沒有端接電阻,收發(fā)器的內部共模電壓緩沖器仍然可以將CANH和CANL連接在一起,但速度要慢得多??偩€上的容性負載也會減慢CANH和CANL電壓的合并速度。當控制器向TXD發(fā)送脈沖時,如果隱性間隔不夠長,差分電壓(CANH – CANL)連續(xù)10個脈沖周期低于輸入低閾值(RXD在10個TXD脈沖中保持低電平),則將報告?zhèn)鬏敼收瞎收?。這也意味著如果TXD高電平時間過長,CAN總線信號可能進入隱性模式,RXD將變?yōu)楦唠娖?,不會報告?zhèn)鬏敼收瞎收稀z測傳輸故障故障的推薦最小TXD脈沖頻率為200kHz。
故障檢測算法
Maxim開發(fā)了一種算法,能夠利用MAX33011E可靠地檢測CAN總線上的故障條件,而不會中斷正常的CAN通信。以下所有示例 Mbed 代碼都是為 NUCLEO-F303K8 平臺開發(fā)的。?
通常,CAN網絡的每個節(jié)點都使用帶有CAN外設的微控制器。要執(zhí)行故障檢測,微控制器的 TXD 和 RXD 引腳必須配置為 GPIO,以對 TXD 信號進行位沖擊并從 RXD 讀取故障代碼。需要中斷引腳連接到MAX33011E的故障信號。
為避免中斷正常通信,該算法在進入故障檢測模式前需要對通信故障進行強指示。如果發(fā)生以下情況之一,算法將進入故障檢測模式:
故障很高。
發(fā)射器生成誤碼幀。
發(fā)射器錯誤計數(shù)器升至255以上,節(jié)點進入總線關閉狀態(tài)。
以下示例代碼在上述任何條件變?yōu)?GP 時將微控制器引腳配置為 GPIO。
我們使用STM32F303K8 MCU作為CAN控制器。此參考代碼是在 Mbed-OS 上開發(fā)的,Mbed-OS 是一個免費的開源嵌入式操作系統(tǒng)。有關更多詳細信息,請訪問:https://os.mbed.com/mbed-os/
Mbed 提供 API 將微控制器的 IO 配置為數(shù)字輸入/輸出引腳。也可以使用任何其他類似的低級 API。
DigitalOut txd (PA_12); // Configures PA_12 of MCU (TXD of CAN controller) as digital o/p pin DigitalIn rxd (PA_11); // Configures PA_11 of MCU (RXD of CAN controller) as digital i/p pin
在故障檢測模式下,應使用2μs TXD正脈沖。在正脈沖之后,只要需要處理算法,TXD 就可以保持低電平。這使得故障檢測電路能夠可靠地檢測過流和傳輸故障故障。為確保TXD脈沖寬度準確,應使用定時器。下面是設置計時器的示例代碼。
首選低級 API 來配置分辨率為 2μs 的定時器。Mbed 定時器提供最低 8μs 分辨率。在本例中,使用了STM2F32K303控制器中的TIM8定時器。有關寄存器設置說明的更多詳細信息,請參閱STM32F303K8編程手冊。
static TIM_HandleTypeDef s_TimerInstance = { //Creates a timer instance (TIM2) . Instance = TIM2 }; __HAL_RCC_TIM2_CLK_ENABLE (); //Enable TIM2 APB clock (72MHz) s_TimerInstance.Init.Period.Prescalar = 16; //Set the counter prescalar value s_TimerInstance.Init.CounterMode = TIM_COUNTERMODE_UP; // Set the counter in "UP" mode s_TimerInstance.Init.Period = 500; //Set the counter period s_TimerInstance.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; // Set the clock divisor value to none s_TimerInstance.Init.RepetitionCounter = 0; //Disable the auto-reload HAL_TIM_Base_Init(&s_TimerInstance); // Initializes TIM base unit according to specified parameters HAL_TIM_Base_Start(&s_TimerInstance); //Start the timer in time-base mode
如果故障變?yōu)楦唠娖?,則在CAN報文傳輸中,它隨時可能變?yōu)楦唠娖?。這意味著消息最有可能在 FAULT 為高電平后結束,因此從下一個故障檢測周期讀取錯誤代碼更可靠。故障變?yōu)楦唠娖胶?,CAN外設引腳配置為GPIO。故障檢測算法將重復產生2μs TXD正脈沖,直到FAULT引腳上升沿后RXD變?yōu)楦唠娖健=ㄗh在TXD的下降沿之后對RXD進行采樣。RXD變?yōu)楦唠娖胶螅€需要五個TXD脈沖來移出故障代碼。另外<>個TXD脈沖用于禁用故障檢測。下面是 FAULT 變高時的算法示例代碼:
InterruptIn fault (PA_0); //Configure Fault pin as interrupt pin fault.rise(&fault_init); // Attach an interrupt callback function when fault pin goes high int state=0; // This is the state of state machine for fault detection void fault_init() { fault.rise (NULL); //Detach an interrupt till state machine gets completed toggle_txd_i_ticker.attach_us(&toggle_txd_i,6); // Initiate a state machine to detect a fault, each cycle is 6us } void toggle_txd_i() { DigitalOut txd(PA_12); //Configure CAN TXD pin as digital o/p DigitalIn rxd(PA_11); // Configure CAN RXD pin as digital i/p DigitalIn fault_pin(PA_0); //Configure fault pin as digital i/p int status = fault_pin.read(); //Fault pin status is stored in status variable static int count,N; do { //This code toggles TXD for 2us duration using TIM2 timer txd = 1; } while (__HAL_TIM_GET_COUNTER(&s_TimerInstance) < 9); txd=0; count++; switch (state ){ //State machine for fault detection case 0: // Ignore the first high fault, giving txd pulses to clear the fault without reading fault code if (count >= 26 && status == 0 ) { count = 0; state = 1; } break; case 1: // Fault pin is low and giving 100 fault pulses/waiting for fault pin to go High for second time if (count>=100 && status == 1 ) { count = 0; state = 2; } break; case 2: // Second time fault activated, need to read the fault code(10 pulses + 6 pulses to read the rxd + +10 pulses to clear the fault if (status == 1){ if( (rxd.read() == 1 || rxd_read == 1) && i<6) { arr[k] = rxd.read(); //Read RXD (fault code bit) and store in array k++; rxd_read = 1; //Flag to indicate that fault has been read i++; } } else if ( status == 0 ) { // Once fault pin becomes 0, move to state 3 fault_read = 1; rxd_read = 1; count = 0; state = 3; } break; case 3: if (status == 0) { InterruptIn fault (PA_0); //Configure fault pin as interrupt pin Fault.rise(&fautl_init); //Enable fault interrupt toggle_txd_i_ticker.detach(); //Disable state machine } break; } }
對于其他兩種情況(誤碼幀和發(fā)射器錯誤計數(shù)>255),F(xiàn)AULT不一定會變高。該算法將CAN外設引腳配置為GPIO,并將重復產生2μs TXD正脈沖,直到RXD在故障上升沿后變?yōu)楦唠娖?。建議在TXD的下降沿之后對RXD進行采樣。RXD變?yōu)楦唠娖胶?,還需要五個TXD脈沖來移出故障代碼。另外 110 個 TXD 脈沖禁用故障檢測。如果 FAULT 在 <> TXD 脈沖后沒有變?yōu)楦唠娖?,則表示未檢測到故障,故障檢測模式將退出。下面是該算法的示例代碼:
在STM32F303K8 CAN控制器中,ESR(錯誤狀態(tài)寄存器)具有7:0的發(fā)送器錯誤計數(shù)器[TEC]位。如果此計數(shù)器超過 255,則啟動用于檢測故障的狀態(tài)機。此外,ESR 具有 2 位 LEC[2:0](最后一個錯誤代碼)來指示錯誤條件,例如誤碼幀。
Int tec_count= ((CAN1->ESR) && (0x00FF0000))>>16; //Get the transmit error counter value from ESR register Int error_code= ((CAN1->ESR) && (0X00000070)>>4; //Get the error code value from ESR register if((tec_count >255) || (error_code !=0 )) { fault_init(); //Run the fault detection algorithm as implemented in above section }
審核編輯:郭婷
-
寄存器
+關注
關注
31文章
5343瀏覽量
120376 -
發(fā)射器
+關注
關注
6文章
849瀏覽量
53473 -
CAN收發(fā)器
+關注
關注
2文章
165瀏覽量
25644
發(fā)布評論請先 登錄
相關推薦
評論