这个问题本来就计划在水潭里的尿童学堂里论述,想先听听楼主的高招,没想到楼主止步了,真倒塌了~~~
在程序的安全设计上,对于这些需要检测硬件的回控信号后再进一步运行的程序,有很多需要考虑的细节. 1.无硬件看门狗或有硬件看门狗时. 2.硬件次要或主要时. 3.中断或查询时.
先以楼主的程序为例: TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);//发送STAR while (!(TWCR&(1<<TWINT)));//就这里,如果总线为短路。得不到控制权,那么单片机就定在哪里了。
在无硬件看门狗时: 当发送START信号后,若出现TWINT一直低电平时,即使总中断开启并其他中断正常运行时,都将永远踏步死机. 如果系统设计为I2C数据很重要,无它系统没意义必须重新启动时,此程序片段就如PC蓝屏需要人工重新启动,倒也可行. 若数据不重要,即TWI接口坏可以放弃时,此程序就不对了. 应该用一个软件计数器或定时器在一定间隔内,若TWINT恒为0,就设置错误标志后退出while死循环. 即:
TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);//发送STAR while (!(TWCR&(1<<TWINT)));//就这里,如果总线为短路。得不到控制权,那么单片机就定在哪里了。
unsigned char TWStart(void) { unsigned char error = 1;//失败 unsigned int i; TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);//发送STAR for (i = 0; i < 0x....; i ++) {//时间间隔自定 if (TWCR&(1<<TWINT)) {//成功 error = 0; break; } } return error;//成功返回0 } 当系统检测不通过就无法继续运行需要复位时,基本如下所述的方法. 具体很难说清...
在有硬件看门狗时,喂狗信号的位置也比较有讲究,特别是在长等待时. 一般原则是喂狗信号不能套入while内,应该修改为: wdt_reset();// Watchdog复位 while(...){ };//只要保证测试时间不超过Watchdog定时器复位时间 如果测试时间不够,可修改为: for(i = 0;i < N;i++) { wdt_reset();// Watchdog复位 while(...){ };//只要保证测试时间不超过Watchdog定时器复位时间/N }
而不应该: while(...){ wdt_reset();// Watchdog复位 }
总之,我们养狗绝非害人甚至害自己!!! 因为即使器件硬件错误,我们只认为是I2C通讯失败但系统其他更重要的设备 还要正常地运行,不能因为局部错误而复位整个系统.
|
|
文章评论(0条评论)
登录后参与讨论