sja1000 中断_SJA1000的错误中断处理
SJA1000的錯誤處理好似還是比較復雜的的啦,下面是我自己的一些理解,有不對之處還請各位大蝦多多指點啊!
SJA1000的錯誤有:
仲裁丟失;
數據溢出;
總線錯誤;
錯誤狀態有:
錯誤主動(Error Active)
錯誤被動 (Error Passive)
總線關閉;
錯誤中斷:
總線錯誤中斷;
仲裁丟失中斷;
錯誤消極中斷;
數據溢出中斷;
錯誤報警中斷;
涉及到的寄存器:
狀態寄存器(SR);
中斷寄存器(IR);
中斷使能寄存器(EIR);
仲裁丟失捕捉寄存器(ALC);
錯誤代碼捕捉寄存器(ECC);
錯誤報警限制寄存器(EWLR);
TX錯誤計數寄存器(TXERR);
RX錯誤計數寄存器(RXERR);
處理中斷當然是從中斷寄存器說起了;
中斷寄存器:只說和錯誤有關的位啦;
IR.7:BEI
總線錯誤中斷;
當CAN控制器檢測到總線錯誤且中斷使能寄存器(EIR)中的BEIE被置位時此位被置位
當前的錯誤代碼可以通過錯誤代碼捕捉寄存器(ECC)獲得;其中可以分為:
位錯誤;
格式錯誤;
填充錯誤;
其它錯誤;
IR.6:ALI
仲裁丟失中斷;
當CAN控制器丟失仲裁,變為接收器和中斷使能寄存器的ALIE為被置位時,此位被置位
當前仲裁丟失的位置可以通過讀仲裁丟失捕捉寄存器(ALC)獲得;
IR.5:EPI 錯誤消極中斷;
當CAN控制器到達錯誤消極狀態(Error
Passive)(至少一個錯誤計數器超過協議規定
的值127)或從錯誤消極狀態(Error
Passive)又進入錯誤活動狀態(Error Active)
以及中斷寄存器的EPIE位被置位時此位被置1
IR.3:DOI 數據溢出中斷;
數據溢出狀態位(狀態寄存器的SR.1位
DOS)有0-1 跳變且中斷寄存器的DOIE位被置
位時此位被置1
IR.2 EI 錯誤報警中斷;
錯誤狀態位(狀態寄存器的SR.6位
ES)和總線狀態位(狀態寄存器的SR.7位 BS)的
改變和中斷寄存器的EIE位被置位時此位被置1
影響錯誤狀態位的有:
1,錯誤計數器至少有一個錯誤計數器滿
2,超過錯誤報警限制寄存器(EWLR)設置的值時錯誤狀態位被置位;報警中斷。EWLR 硬
件復位后的默認值是96
3,當發送錯誤計數器超過限制255 總線狀態位被置為1
總線關閉
4,進入總線關閉后,再次進入錯誤主動狀態(Error Active)時,
也會產生中斷;
再說一下錯誤狀態:
1,當TX錯誤計數寄存器和RX錯誤計數寄存器中有一個計數大于127時,則就進入錯誤被動狀態(Error Passive)
2, 當TX錯誤計數寄存器和RX錯誤計數寄存器兩個計數都小于127時,則就進入錯誤主動狀態(Error Active)
2, 總線關閉狀態,當TX錯誤計數寄存器超過限制255 總線狀態位被置為1 總線關閉;
從上面來看錯誤報警中斷(EI)是由多個中斷源產生的,所以其處理也最為復雜;我只對總線關閉進行了處理,其它的未做處理;下面的圖有助于大家理解:
下面是我寫的程序:
void can_signal(void)
{
unsigned char data
can_irq;
unsigned char data temp;
x_wdgtime();
can_irq =
InterruptReg;
if(can_irq&ALI_Bit){ //
仲裁丟失位
++al_counter;
temp=ArbLostCapReg; // 讀仲裁丟失寄存器
alc_current=temp&0x1F; // 獲得當前仲裁丟失的位置
}
if(can_irq & BEI_Bit){ // 總線錯誤中斷
temp=ErrCodeCapReg;
buse_current=temp&0x3F;
temp=temp&0xD0; // 獲得總線錯誤的類型
switch (temp) {
case 0x00: ++bite_counter;
case 0x40: ++forme_counter;
case 0x80: ++stuffe_counter;
case 0xd0: ++othere_counter;
}
}
if(can_irq & EPI_Bit){ //
消極錯誤中斷,
// 接收或發送錯誤計數超過127時,錯誤狀態變為被動錯誤
if((RxErrCountReg>127)||(TxErrCountReg>127))
errstatus_current=ERR_PASSIVE;
// 接收或發送錯誤計數回到小于127時,錯誤狀態變為主動錯誤
if((RxErrCountReg<127)&&(TxErrCountReg<127))
errstatus_current=ERR_ACTIVE;
}
if(can_irq & DOI_Bit){ //
data overflow
CommandReg = (CDO_Bit|RRB_Bit);
return;
}
if(can_irq&EI_Bit){ //
錯誤報警中斷, 這里只對總線關閉錯誤做處理
if(StatusReg&BS_Bit){ // 檢測狀態寄存器的總線狀態位
++busoff_counter;
ModeControlReg = 0x00;
return;
}
}
if(can_irq & RI_Bit){ // 接收數據中斷
if(StatusReg & DOS_Bit){
CommandReg = (CDO_Bit|RRB_Bit);
return;
}
can_readmsg();
return;
}
return;
}
有不對的還請大家指出來哦!
總結
以上是生活随笔為你收集整理的sja1000 中断_SJA1000的错误中断处理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微型计算机原理与接口技术(周荷琴 冯焕清
- 下一篇: 一文读懂法拉第未来赴美上市:合并PSAC