PIC单片机编程,程序运行总是出错,可能是程序跑飞了,求大虾指点迷津。还想加个定时器,

刚刚学PIC单片机编程,一个装置,在接受到中断时,装置不报警,没有接受到中断且检测到CGQ为1时,装置报警。但是程序出来总是出错,没有接受到中断,CGQ为1,它不报警。接... 刚刚学PIC单片机编程,一个装置,在接受到中断时,装置不报警,没有接受到中断且检测到CGQ为1时,装置报警。但是程序出来总是出错,没有接受到中断,CGQ为1,它不报警。接受到中断,它反而报警。总之结果不稳定,不是想要的结果,有些怀疑是不是程序跑飞了,程序如下,求大虾指点,哪个地方出错了。
#include<pic.h>
__CONFIG(0x3f3a);
#define uchar unsigned char
#define uint unsigned int

#define CGQ RD2 //CGQ通断信号
#define silencer RD0 //消音控制信号
#define TSIG RB0 //测试仪中断信号
volatile short s=0;

void inital_I0(); //IO口初始化
void INITinterrupt(); //中断初始化
void delay(int z); //延时程序
void alarm_silencer(); //报警程序

void inital_IO()
{
TRISD0=1; //RD0口设置为输入,消音控制信号输入
TRISD2=1; //RD2口设置为输入,CGQ通断信号输入
TRISB0=1; //RB0口为输入, 中断输入
TRISE1=0; //RE1口设置为输出,报警输出
}

void INITinterrupt() //B0口外部中断初始化
{
INTEDG=0; //下降沿触发
INTF=0;
INTE=1;
GIE=1;
}

void delay(int z)
{
int x,y;
for(x=z;x>0;x--);
for(y=10000;y>0;y--);
}

void alarm_silencer()
{
if(s==0&CGQ==1)
{
delay(100);
if(s==0&CGQ==1)
{
delay(100);
RE1=1; //报警控制信号输出
delay(1000);
while(silencer==1)
{
RE1=1;
delay(1000);
} //持续报警,直到消音信号出现
RE1=0;
delay(100);
}
}
}

void interrupt test(void) //中断服务程序
{
if(INTF)
{
count_s=count_s+1; //合格产品计数
s=1;
INTF=0; //中断标志位清零
CGQ=1;
}
}

void main(void)
{
inital_IO();
INITinterrupt();
while(1)
{
s=0;
if(CGQ==0)
{
delay(100);
if(!CGQ);
{
alarm_silencer();
}
}
delay(1000);
}
}
还有想在中断程序里加个定时器去抖,要怎么加,直接写个定时器程序吗?怎么写比较好呢?最好能有具体的程序。
如果切实可行,还会追加分数。谢谢各位帮忙了。
我用的是PIC16F877A
展开
 我来答
嘲讽帅哥
2011-08-01 · TA获得超过1186个赞
知道小有建树答主
回答量:113
采纳率:0%
帮助的人:185万
展开全部
不是跑飞的问题,其实是选择语句上的问题,回答者: 碱杯已经看出来了,他只是没指明掉
if(CGQ==0)
{
delay(100);
if(!CGQ); //注意这个分号,这里的意思是CGQ=0时候,空操作次,继续执行后面的
{
alarm_silencer(); //该指令不管CGQ为何值,都会被执行
}
}
delay(1000);
}
另外,CGQ值对alarm_silencer();影响的逻辑关系有点乱,所以我没看alarm_silencer();,但发现了以下问题,希望对你有帮助
1.中断服务不用判断,或加延迟判断,已经下降沿触发了,进入中断的时候INTF就已经是0了;
2.延迟
void delay(uint x) //#define uint unsigned int定义过,最大可以到65355,原来的int知道32677
{
uint y;
for(x;x>0;x--) //注意这里是没有分号的,加分号时间上就错了
for(y=10000;y>0;y--);
}
百度网友f14eb96
2011-08-01
知道答主
回答量:38
采纳率:0%
帮助的人:27.2万
展开全部
去抖程序就是比如说读一个寄存器,发现变化,延时一会,如果变化还在那就说明真的变化了,以51接键盘为例,给你一个去抖动的例子,你自己看看吧
if((P1&0xf0)!=0xf0) //判断是否有有键按下(键盘接P1初值为0xF0,如果有键按下值会变化),有往下执行
{
delays(); //延时去抖动(10ms)
if((P1&0xf0)!=0xf0) //再次判断列中是否是干扰信号,不是则向下执行
……

void delays(void)
{
uchar i;
for (i=300;i>0;i--);
}
一般去抖动不需要太精确的时间,大概10~200ms就行,没必要弄一个定时器的
追问
中断里面不能有延时程序的。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
匿名用户
2011-07-26
展开全部
硬件有问题吗?
追问
硬件没有问题
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
碱杯
2011-07-29
知道答主
回答量:25
采纳率:0%
帮助的人:20.5万
展开全部
你看一下你的while语句里的两个if语句,这样能行就怪了。
更多追问追答
追问
有两个if语句可以的。
追答
呵呵,你理解错了,不是不能有两个if,而是if里面的内容
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 2条折叠回答
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式