打印

一个头疼的问题,PIC16F726约运行50分钟后会复位一次

[复制链接]
3928|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
MIKEZHONG|  楼主 | 2012-2-29 15:48 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
一个头疼的问题,PIC16F726约运行50分钟后会复位一次,再运行,过些时间又会复位.

我是一个控温的产品,使用了PIC16F726,运行约50分钟后会自动复位。为什么说是复位呢,我一直有用串口来监控运行的状态,我在程序的开始放了一个输出“START”的状态输出。约50分钟后就会复位输出一个“START”。

看门狗是处于关的状态。电源的话我也用过直流电源替代过。都会出现,苦于找不到问题。

一般复位由几个原因:
1,看门狗复位。----我已经关了。
2,电源不稳造成的复位,-----我有用直流电源替代。
3,堆栈溢出会不会复位? ----不知道怎么测试是否是这个复位造成。

请各位及版主给点提示。
沙发
asspeed| | 2012-2-29 16:47 | 只看该作者
BOR?

使用特权

评论回复
板凳
Ryanhsiung| | 2012-2-29 18:46 | 只看该作者
堆栈溢出?
越界操作?
都是50分钟吗,间隔一至?那可能是你CODE中有BUG!

使用特权

评论回复
地板
MIKEZHONG|  楼主 | 2012-2-29 19:36 | 只看该作者
时间不是完全固定,有时候是50,有时是40,没有规律。

越界操作?是指什么,,,

用的是C语言。

使用特权

评论回复
5
MIKEZHONG|  楼主 | 2012-2-29 21:19 | 只看该作者
向yewuyi版主求救!

使用特权

评论回复
6
ocon| | 2012-3-1 02:56 | 只看该作者
堆栈溢出风险一般在编译时就能报错,你简化一下程序,关掉大部分功能,测试一下是硬件还是软件引起的复位。

使用特权

评论回复
7
yewuyi| | 2012-3-1 09:43 | 只看该作者
一般这种问题常见的原因:
1、看门狗溢出,例如在特定情况下程序堵塞导致喂狗指令不被执行,并导致复位
2、晶体振荡不稳定,这个可能是晶体质量不好,也可能是电路配置不当,也可能是配置字设置不当等等,这个用示波器抓振荡波形可以大致判断
3、EMC设计太差,在外部电磁干扰下导致复位
4、周期性的堆栈溢出导致的复位,这个需要进行代码审查,很难三句两句说清楚。
5、代码中存在临界代码,在一定的触发条件下会导致逻辑混乱并导致函数返回乱跳,造成程序跳转到那个发送的入口
6、。。。。。。

使用特权

评论回复
8
MIKEZHONG|  楼主 | 2012-3-1 11:43 | 只看该作者
谢谢各位和YEWUYI,

我的程序中有部分串口代码,就是负责把测得的设定温度和实际温度和PID的输出值发出到串口,从而电脑通过串口助手可以看到实时运行情况,现在我把这段代码,全部去掉,机器就运行正常了。为什么呢,下面是代码。
我看了手册的刊误表,也没有串口的BUG问题。
//***************************************************
////串口输出数据,xxx_xxx_xxx_xxx,
//              PID次数_设定温度_实际温度_PWM输出值
//***************************************************
void uartputs(void)
{
     unsigned char testcnthun,testcntten,testcntone,i;
     unsigned int testtemp1;
     
     testcnthun= testpidcnt/100;
     testcntten= (testpidcnt/10)%10;
     testcntone= testpidcnt%10;
     uartout[0]= (testcnthun+48);
     uartout[1]=(testcntten+48);
     uartout[2]=(testcntone+48);
     uartout[3]=45; //-
     
     testcnthun= PID_Val.SetPoint/100; //settemp_buf/100;
     testcntten= (PID_Val.SetPoint/10)%10; //(settemp_buf/10)%10;
     testcntone= PID_Val.SetPoint%10; //settemp_buf%10;
     uartout[4]= (testcnthun+48);
     uartout[5]=(testcntten+48);
     uartout[6]=(testcntone+48);
     uartout[7]=45; //-
     
     testtemp1=TEMPRETURE_1[ntcavr-40];
     //testtemp1=testtemp1/100; //缩小100倍
     testcnthun= testtemp1/100; //得到百位
     testcntten= (testtemp1%100)/10; //得到十位
     testcntone= testtemp1%10;
     uartout[8]= (testcnthun+48);
     uartout[9]=(testcntten+48);
     uartout[10]=(testcntone+48);
     uartout[11]=45; //-
            
     testcnthun= pwmout/100;
     testcntten= (pwmout/10)%10;
     testcntone= pwmout%10;
     uartout[12]= (testcnthun+48);
     uartout[13]=(testcntten+48);
     uartout[14]=(testcntone+48);
     uartout[15]=32; //space
     asm("nop");
     for (i=0;i<16;i++)
     {
       Uart_TX(uartout[i]);
     }
}

/**************************************************
//串口初始化
**************************************************/
void UART_init(void)
{
   TXSTA = 0b00100100;  //异步通信方式,8位数据发送格式,
   RCSTA = 0b10010000;  //8位数据接收格式.禁止接收数据.
   SPBRG = 51 ; //103 ;//25 ;        //600 bps,4Mhz 晶振
   RCIE = 0;  //使能串口接收中断.
   RCIF = 0;
   TXIE = 0; //发送不中断.
   TXIF = 0;
}
void Uart_TX(unsigned char dcode)
{
   TXREG=dcode;
   while (TRMT ==0)
     ;
   
}

使用特权

评论回复
9
yewuyi| | 2012-3-1 12:24 | 只看该作者
谢谢各位和YEWUYI,

我的程序中有部分串口代码,就是负责把测得的设定温度和实际温度和PID的输出值发出到串口,从而电脑通过串口助手可以看到实时运行情况,现在我把这段代码,全部去掉,机器就运行正常了。为什么 ...
MIKEZHONG 发表于 2012-3-1 11:43


具体问题只能你自己去找。

但估计可能:
1、串口导致的堆栈溢出
2、PID计算时间较长,系统调度没有能很好的将任务分解,造成看门狗喂狗指令没有得到执行
3、各种计算和中断发生了临界代码

使用特权

评论回复
10
kenan6615| | 2013-7-10 16:58 | 只看该作者
各种计算和中断发生了临界代码是什么意思

使用特权

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

本版积分规则

51

主题

250

帖子

1

粉丝