LPC2294-CAN调试:不可理喻的地方
1、LPC2294板子(优龙YL_LPC2294)的外部晶振14.7456MHz,CAN通讯波特率怎么也配不到的一个整数的份上,俺凑了一个122.8kHz的和CAN232卡(CAN转串口)通讯,CAN232卡的CAN波特率设置为125kHz;
2、LPC2294选择CAN1进行发送,开启CAN1的Error Warning Interrupt(EIE=1),Philips对EI标识位的解释是这样的:(EI:Error Warning Interrupt) -- this bit is set on every change (set or clear) of the Error Status or Bus Status bit in CANSR, if the EIE bit in CAN is 1 at the time of the change.
程序用EI中断来捕获BusOff状态,因为Philips对网络错误累计导致CAN控制器与CAN-Bus脱离的解释是这样的:The CAN Controllers count and handle transmit and receive errors as specified in CAN Spec 2.0B. The Transmit and Receive Error Counters are incremented for each detected error and are decremented when operation is error-free. If the Transmit Error counter contains 255 and another error occurs, the CAN Controller is forced into a state called Bus-Off. In this state, the following register bits are set: BS in CANSR, BEI and EI in CANICR if these are enabled, and RM in CANMOD. RM resets and disables much of the CAN Controller. Also at this time the Transmit Error Counter is set to 127 and the Receive Error Counter is cleared. Software must next clear the RM bit. Thereafter the Transmit Error Counter will count down 128 occurrences of the Bus Free condition (11 consecutive recessive bits). Software can monitor this countdown by reading the Tx Error Counter. When this countdown is complete, the CAN Controller clears BS and ES in CANSR, and sets EI in CANICR if EIE in IER is 1.
CAN232卡设置为照单全收。
2、CAN网络的容错性不是吹出来的,LPC2294发送的数据可以完整的在我的CRT屏幕上显示出来(如下屏幕抓图):
当循环发送至第13个数据帧(帧ID为0x0E)时,崩溃出现了,同一个数据帧竟然被接收到6次,接着跳进了EI中断(本人在语句(1)处设置了断点):
__irq void CAN_Err_ISR(void)
{
if(CAN1GSR & 0x080) // (1)总线脱离,BS=1?
{
CAN1MOD = 0x00; // (2)退出复位状态
}
while(CAN1GSR & 0xFF000000); // (3)等待发送错误计数器清零
while(CAN1GSR & 0x080); // (4)检查BS位(CAN1GSR)是否复位
}
在语句(1)时的调试截图(CAN1相关寄存器):
CAN1MOD=0x01:CAN1此时为复位状态;
CAN1ICR = 0x00580004:EI=1,发生Error Warning中断,Form Error,并且CAN1为发送器时检测到的错误,ErrorBits=11000,标识为CRC界定场检测到错误;
CAN1SR=0x00FCFCF4:TCS1=0(TxBuffer1发送未完成),TBS1=1(TxBuffer1可以写入下一帧待发送数据帧)。
疑惑之一--->这是一对矛盾,矛盾一旦激发,瘫痪是唯一的可选项,若发送函数查询TxBuffer1可写,于是写入下一帧,完了必然会置命令字:CAN1CMR=0x21(选择TxBuffer1发送!);这样一来,上一帧还没发育完全,下一帧又已启动发送,这是一个怎样的世道?!!
单步执行至语句(4)时的调试截图(CAN1相关寄存器值):
接着全速运行,CAN232卡除了将同一个数据帧(帧ID为0x0F)接收6次之后就再也没有反应,我纳闷着停止AXD调试,发现CAN1居然无声无息的进入了复位态(见下截图),而且这一次的Reset,就再也跳不出来了!
疑惑之二--->按理说CAN1退出复位进入Normal态再次Reset必然会被EI中断程序捕获!!
3、为了查明CAN1是什么时候“招呼没打一个”就再次复位的,本人重新装载映像程序再次调试,结果发现:退出CAN_Err_ISR中断函数进入主函数循环发送例程后,CAN_PushMsg函数的语句“CAN1CMR=0x21;”执行完毕,CAN1立马进入复位态,而且这一次复位并不产生EI中断,EI标识位并没有置1。
4、为什么会不打招呼(没中断)就复位?有一个解释是:这是因为TCS1和TBS1的矛盾而引起的CAN控制器复位,并不是因错误累加而导致CAN控制器复位。
5、写到这里,本日志的结论是:利用Lpc2294构造的CAN节点,一旦错误累加进入BusOff态,除非硬件复位,否则该节点将永远瘫痪!