嘿嘿 系统中大约有几十个节点,用CAN连接,主控用AT91SAM7A3(内部带两个CAN接口),从节点用51+SJA1000。
AT91SAM7A3用IAR开发环境,初始化代码来自于TAMEL网站上的样例,用了两个文件:汇编的Cstartup.s79 和C语言的Cstartup_SAM7.c。 51用KEIL开发环境。
主控运行时打开看门狗,CAN通信按常规用中断方式接收,随机性的发生看门狗复位(间隔时间不定,数十分钟或几天,施加频繁的人为干扰,几分钟就复位),改查询方式接收则没问题(但可能丢失CAN数据!!),初步判断中断出问题了。
反复修改CAN的初始化代码和中断服务代码,无效。 在main()函数中首先关闭全部中断,然后仅仅打开CAN中断,无效。
查AT91SAM7A3的初始化代码,发现有个平时没有怎么留意的所谓“虚假中断”,仔细看数据手册,强烈怀疑CAN中断出问题和这个“虚假中断”有关!
“虚假中断”的中断服务代码是用汇编写的一个死循环: AT91F_Spurious_handler b AT91F_Spurious_handler
而在初始化代码C语言部分(文件Cstartup_SAM7.c)中,初始化了虚假中断的中断服务函数: AT91C_BASE_AIC->AIC_SPU = (int)AT91F_Spurious_handler;
其它中断也是这样:初始化以后默认的服务代码都是一个死循环,因为我后面把不用的中断都关闭了,而且也没有这样的中断事件发生,所以改不改就无所谓了
改虚假中断服务代码,在Cstartup_SAM7.c文件中写一个函数: void AT91F_Spurious_handler_C() {}
将Cstartup_SAM7.c文件中的 AT91C_BASE_AIC->AIC_SPU = (int)AT91F_Spurious_handler; 改为 AT91C_BASE_AIC->AIC_SPU = (int)AT91F_Spurious_handler_C;
恢复系统(让看门狗工作,以中断方式做CAN接收),运行正常。用ZLG的蓝盒子(USBCAN-II)当干扰源,反复连续发送数据,系统工作正常。
基本可以确定:问题解决了!
体会: 1、样例代码一定要仔细看,结合项目的要求,仔细修改。 2、没有用到的资源或者似乎与应用无关的问题,很可能影响系统运行,比如这里的虚假中断,原以为跟系统没什么关系,因为总觉得:中断需要有触发条件,我不给你这个条件,中断就不会发生,后来才知道:在AT91SAM7A3里,所有的中断都有可能“和平演变成”虚假中断!!!某些情况下,这种和平演变的几率还很大(几分钟一次)! 3、中断实在是个好玩意儿!呵呵 4、我明明在main()里一开始就关闭了所有中断,为什么这个“虚假中断”还是活的?还没搞明白,呵呵
|