打印
[STC单片机]

单片机程序跑飞了,各路大神帮小菜找下BUG吧

[复制链接]
1023|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
qq470373513|  楼主 | 2016-10-26 13:31 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
先贴上部分代码://----------------------------    ADC   -----------------------------------//
unsigned int GET_ADC_Result(unsigned char ch)
{
        unsigned int ADC_VAL=0x0000;
        ADC_CONTR =  ADC_POWER | ADC_SPEEDHH | ch | ADC_START;
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        while(!(ADC_CONTR & ADC_FLAG));
        ADC_CONTR &= ~ADC_FLAG;
        ADC_VAL = ADC_RES;  //¸ß8λ        
        return ((ADC_VAL << 2)+ADC_RESL); //10λ
}


//-----------------     延迟0.5ms    18.432MHz   --------------------//
void Delay(unsigned int n)
{
        unsigned int x;
        while(n--)
        {
                x = 500;
                while(x--);
        }
}


//-------------------   定时计数器0中断服务函数   40ms   ------------------//
unsigned int Int_times,Zero_times = 0;
void timer0_isr() interrupt 1 using 1
{
        TF0 = 0;
        Int_times++;
        BEEP = !BEEP;
        if(GET_ADC_Result(CURT_SAMP)<0x02){
                Zero_times++;
                if(Zero_times>130){
                        BEEP = 1;
                        LED_R = 1;
                        LED_G = 0;
                }
                if((Int_times==Zero_times)&&(Zero_times==150)){
                        EA = 0;     //关中断
                        ET0 = 0;
                        TR0 = 0;
                        IAP_CONTR = 0x20;    //软复位
                }
        }
        else{
                Int_times = 0;
                Zero_times = 0;
        }        
}

,主函数里面主要是控制一些LED和一些开关,中间也要用上ADC。

情况是这样的: 我想通过单片机来检测一个管脚的电压信号,如果这个管脚的电压低于0x02那我就让单片机复位,也就是这个 定时计数器0中断服务函数 正常情况下完成的内容。


现在问题是:上面的程序正常运行起来的话程序会跑进一个BUG里面,有时候2分钟就进了BUG,有时候40分钟进BUG,但是BUG现象一致,BUG造成的现象是  单片机 会长期处于一个固定状态,比如说  LED 和开关都处于打开状态。  但是如果这个时候我把ADC采样输入那个脚电压设置为0的时候,程序又能正常进入 定时计数器0中断服务函数 ,然后程序重新跑起来,又过2分钟到40分钟,又会出现同样的情况。   
如果把 定时计数器0中断服务函数 中不用AD采样,那就不会出现这个BUG!!!
我查了2天了都没查出来什么问题,实在是查不到哪里出了问题了,还请坛子里大神帮我看看,跪谢~~~

相关帖子

沙发
1123489614| | 2017-4-14 09:28 | 只看该作者
要是我的话 肯定不会把这么些东西写在中断里

使用特权

评论回复
板凳
ayb_ice| | 2017-4-14 10:20 | 只看该作者
先去掉using 1再说

使用特权

评论回复
地板
xiaohua880123| | 2017-4-26 09:17 | 只看该作者
unsigned int GET_ADC_Result(unsigned char ch)
这个函数如果主程序用了,就别在中断中使用,因为会造成嵌套跑飞,如果主程序正好执行采样函数的内部逻辑,而此时进了定时中断中又再次使用该函数会造成跑飞。所以尽量中断中别放子函数!否则怎么跑飞都不知道。

使用特权

评论回复
5
libre01| | 2017-4-26 16:58 | 只看该作者
学习了

使用特权

评论回复
6
lnulibin| | 2017-4-26 22:23 | 只看该作者
如果主程序执行一遍的时间比40MS短的话.
最好在中断处理函数中设置一个标志,
在主程序中根据标志的情况进行AD转换.
即所谓的"前后台"方法处理问题.
如无特殊必要,建议不要在中断处理函数中,进行转换.因为转换需要时间,一旦转换完成标志始终不置位.就卡死了.

如果主程序里执行一遍的时间确实比较长,大于40MS,建议将消耗时间比较长的任务用状态机的方式分成多步执行.

使用特权

评论回复
7
ningling_21| | 2017-4-27 11:08 | 只看该作者
用裁剪法

使用特权

评论回复
8
linqing171| | 2017-4-27 13:44 | 只看该作者
两个程序都使用了ADC。一个程序破坏了另外一个程序正在使用的ADC。

用两个调试IO,一个调试IO进入ADC函数就输出高,退出ADC函数就输出低。如果硬件有 ADCBusy信号的话直接使用也可以。
另外一个调试,当进入中断后输出高,退出中断输出低。用示波器看这两个io,你就看到死机的时候是中断打断了主循环。

另外,using 1 这个bug也要删了。或者编译的时候把NARG勾上。

使用特权

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

本版积分规则

6

主题

19

帖子

0

粉丝