打印

请教串口通信收到干扰容易死机,是什么问题?

[复制链接]
8455|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
jony.z|  楼主 | 2013-3-24 22:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
做RS485通信,485总线上的干扰大了之后,PIC单片机死在中断里,是什么情况?
void interrupt clkint()   
{   
         if(RCIE&&RCIF)
         {
                   if(OERR||FERR)
                   {
                            SPEN=0;
                            CREN=0;
                            recdata_error=RCREG;   
                            CREN=1;
                            SPEN=1;
                   }
                   else
                            receive_ok=1;
                   if(receive_ok==1)              //接收数据中断
                   {
                            receive_ok=0;
                            recdata[recbyte_num1]=RCREG;
                            recbyte_num1++;
                            if((recdata[0]==0XA5)||(recdata[0]==0X0A))
                            {        
                                     ucharj;
                                     if((recbyte_num1>3)&&(recbyte_num1==recdata[2]+2))
                                     {        
                                               CREN=0;
                                               if(recbyte_num1<14)
                                               {
                                                        for(j=recbyte_num1;j<14;j++)
                                                                 recdata[j]=0;
                                               }
cheaksum=recdata[2]+recdata[3]+recdata[4]+recdata[5]+recdata[6]+recdata[7]+recdata[8]+recdata[9]+recdata[10]+recdata[11]+recdata[12]+recdata[13];
                                               if(cheaksum==0)
                                                        a=1;
                                               recbyte_num1=0;   
                                     }
                                     if(a==1)
                                     {        
                                               a=0;
                                              ……
                                     }        
                                     CREN=1;
                            }
                            else  recbyte_num1=0;   
                   }
         }
         asm("CLRWDT");  //收到干扰死在中断中,没办法,加了个看门狗,但不是解决问题的根本方法
         if(TMR1IF==1)   
         {
                   TMR1IF=0;                        //TMR1中断标志位清0
          TMR1L=0XDB;
             TMR1H=0X0B;                            //赋初始值
             con250ms++;                             
                   if(con250ms>=2)               
                   {
                            con250ms=0;
                            con500ms++;                     
                   }                 
         }
}

沙发
jony.z|  楼主 | 2013-3-24 23:01 | 只看该作者
朋友们帮看看,那种容错方**确吗?为什么会死在中断里?是因为中断中的哪个寄存器出错吗?

使用特权

评论回复
板凳
yklstudent| | 2013-3-24 23:04 | 只看该作者
有点不懂 在中断内喂狗 有什么用

使用特权

评论回复
地板
jony.z|  楼主 | 2013-3-24 23:12 | 只看该作者
yklstudent 发表于 2013-3-24 23:04
有点不懂 在中断内喂狗 有什么用

是因为没法真正解决中断死机的问题,为防止死机,只有下下策,喂狗,宁可重启也不能死机啊。

使用特权

评论回复
5
jony.z|  楼主 | 2013-3-24 23:15 | 只看该作者
jony.z 发表于 2013-3-24 23:12
是因为没法真正解决中断死机的问题,为防止死机,只有下下策,喂狗,宁可重启也不能死机啊。 ...

串口通信受到干扰,会死在中断里。不知道什么原因。

使用特权

评论回复
6
yklstudent| | 2013-3-25 06:38 | 只看该作者
jony.z 发表于 2013-3-24 23:12
是因为没法真正解决中断死机的问题,为防止死机,只有下下策,喂狗,宁可重启也不能死机啊。 ...

喂狗的作用是什么?能让mcu复位???

使用特权

评论回复
7
lr2131| | 2013-3-25 09:08 | 只看该作者
在ISR中喂狗不好。有时候,用户的main线程跑飞了,但ISR依然能够正常进入。那这个时候该喂狗都不会喂狗了,这样就出现大问题了。

使用特权

评论回复
评分
参与人数 1威望 +3 收起 理由
jony.z + 3
8
yewuyi| | 2013-3-25 09:18 | 只看该作者
1、不要在中断中写那么多代码,这不是一个好习惯,中断的现场保护会多了很多东西,而且执行这些代码也会造成中断再次响应变慢,规范的做法是在里面设置一个标志,在退出中断后根据标志状态再决定如何处理即可。
2、尽量不要在中断中写清狗指令,不管是在哪里写清狗指令,都应该有条件互驳形成连环套检测,只要连环套被打破,则就无**确清狗,此时才容许复位。
3、中断查询代码尽量写完成,例如if(TMR1IF==1),为什么不带容许位一起判断呢?
4、通信过程中因为干扰造成通信数据错误很正常,这个解决不了,只能说明你的程序没有足够的容错处理。
5、没有人有大把时间来给你看具体的程序代码,这一点也要牢牢记住。

使用特权

评论回复
9
jony.z|  楼主 | 2013-3-26 20:20 | 只看该作者
yklstudent 发表于 2013-3-25 06:38
喂狗的作用是什么?能让mcu复位???

是的,因为受到干扰,程序死在中断里,没有办法,才在这里加看门狗。实则不是本意。

使用特权

评论回复
10
jony.z|  楼主 | 2013-3-26 20:34 | 只看该作者
yewuyi 发表于 2013-3-25 09:18
1、不要在中断中写那么多代码,这不是一个好习惯,中断的现场保护会多了很多东西,而且执行这些代码也会造 ...

谢谢你的指导!
1.知道中断越短越好,执行完能快速推出。但本程序的比较复杂,在主程序还有好几个 go to ,串口通信数据量比较大,有些数据还必须在中断中处理,处理完才能推出。所以就都放在中断里了。
2.中断里的看门狗不是愿意加的,因为受到杂波干扰,是程序就死在中断里,所以不得已加中断。这也是我想解决的问题:为什么会死在中断里?本人感觉好像是串口的某个寄存器出现错误,但已经加了错误清串口的程序,但为什么无效?
3.以后会规范写程序的。
4.对于容错的处理,yewuyi兄是否能指点几招?
5,那段中断代码其实很简单,一个串口中断,一个定时器中断。串口中断开始时容错程序,然后是数据识别和校验。校验正确a=1。
再次感谢yewuyi的指导!

使用特权

评论回复
11
yewuyi| | 2013-3-27 08:57 | 只看该作者
jony.z 发表于 2013-3-26 20:34
谢谢你的指导!
1.知道中断越短越好,执行完能快速推出。但本程序的比较复杂,在主程序还有好几个 go to  ...

1、没看到有什么复杂的地方,goto是被严格限制使用的,在某些行业,例如汽车电子的行业标准里面,goto是严格禁止使用的,我想你这个产品复杂度应该还不至于超过一辆汽车主控单元的软件复杂度吧?如果你自我评价还不会超过的话,那就自己检讨一下为什么不可以不用goto ?
2、通信数据量大和在中断中写代码没有任何相关性,工程师应当知道什么时候开启合理的buf空间能有助于自己的工作
3、从另一方面而言,对于水平不够的工程师来说,在中断中出现越多的代码,其代码出现BUG的几率也基本越高,例如对于年轻工程师而言的一些临界代码形成的陷阱,年轻工程师往往很难找出BUG所在。
4、对于通信的接受方来说,因为发送方是在不停的发送,而接受方的UART模块也在不停的接受数据并传到UART模块的接受缓存里面,当进入中断响应程序时,如果中断函数执行时间较长,则退出中断时可能又会立即进入接受中断,此时对于主函数来说,相当于死在了中断函数里面。
5、你现在和数据纠错、容错还没啥关系,你先解决了以上的问题,再能再谈这些。

使用特权

评论回复
12
兰天白云| | 2013-3-28 09:29 | 只看该作者
写代码,应该1/3的工作量实现功能,2/3的工作量处理异常问题

使用特权

评论回复
13
jony.z|  楼主 | 2013-3-29 11:42 | 只看该作者
yewuyi 发表于 2013-3-27 08:57
1、没看到有什么复杂的地方,goto是被严格限制使用的,在某些行业,例如汽车电子的行业标准里面,goto是 ...

谢谢了,我刚从事这样的程序编写,没有经验,确实很多东西都不太懂,写程序过程中没有注意这些,只注重先让程序能跑起来,在测试中发现了问题再不断修改。公司也没有人能给个指点,全是自己一个人调试。谢谢你们的指导了!

使用特权

评论回复
14
守望刺客| | 2014-4-15 22:14 | 只看该作者
yewuyi 发表于 2013-3-25 09:18
1、不要在中断中写那么多代码,这不是一个好习惯,中断的现场保护会多了很多东西,而且执行这些代码也会造 ...

你好  请问 可以举例说明一下 怎么做到 互驳 连环套检测吗? 为什么尽量不要在中断中喂狗呢? 谢谢

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

9

主题

56

帖子

2

粉丝