微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 请问这个外部中断程序是否写错了?

请问这个外部中断程序是否写错了?

时间:10-02 整理:3721RD 点击:
实验:要求是开机的时候led1灯点亮闪烁,用杜邦线给P32(外部中断0)接低电平时,led2灯点亮,led1灯熄灭。去除杜邦线P32回到高电平时,led1点亮闪烁,led2灯熄灭。
问题:现在问题是当给P32低电平的时候led2点亮了,但led1没有熄灭,而是闪烁的速度变慢了?P32回到高电平时,led2还是一直亮着?
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
void delay(uint);
sbit led2=P2^7;                //中断时点亮这LED灯
        sbit led1=P2^0;
void main()
{
EA=1;
EX0=1;
led1=0;                     //点亮LED灯
delay(1000);  //延时
led1=1;                                //熄灭LED灯
delay(1000);        ////延时

}

void exter0() interrupt 0
{
        led2=0;        
}
void delay(uint z)
{
        uint x;
        uchar y;
        for(x=z;x>0;x--)
                for(y=1000;y>0;y--);        
}

中断触发方式勒   寄存器都没配置全

你好,选用外部中断时需要选择是触发方式,你这里用低电平触发,应该在初始化加一句IT0=0;  //为1是高电平触发。
第二点,不管写任何程序都需要写大循环while(1);这里的led1=0; delay,led1=1;delay(1000); 应该写在while(1)里面循环。
第三点,你在外部中断里面只写了点亮led2。并没有写熄灭led1.   暂时只看出这三点,慢慢改吧。

上面说错了,为1是下降沿触发。

错误比较多。
中断触发没有设置。中断函数内你只点亮了led2,并没有熄灭led1,退出中断后你并没有让led2熄灭。

还需在while(1)大循环中加入led2=1;这样退出中断后就可以将led2熄灭

                二楼说的对

你最好别用电平触发,因为,你要知道,假如我们借助键盘或者直接把你的中断管脚弄成低电平,则进入你的中断程序,如果你一直让它处于低电平,它就一直进中断出不来了,本来这是应该有的情况,但是不知怎么的,系统会过一小段时间自己退出中断,于是就是你说的等闪烁变慢了,本来不该闪烁,但是程序停留时间一长,自己就跳出中断,然后灯就亮了,于是这个过程反反复复,最后就成了这样。建议采用跳变沿触发,说了一圈,发现2楼说得对

书上说,要是不设置触发方式就默认是低电平触发的。

我把“led1=0; delay,led1=1;delay(1000); ”“放在while(1)大循环里。退出外部中断时也写了熄灭led2,现在给低电平时,led2灯亮了,但led1还是闪着,但闪烁的速度比之前慢了,
我在中断服务程序内容里面加上led1=1时,给低电平时,led2亮时,led1就可以熄了,但为什么要在中断服务里加上led1=1才能让led1灯熄呢?不是一直给中断低电平时,led2就一直亮着,led1不是已经中断了,为什么还会亮着的?
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
void delay(uint);
sbit led2=P2^7;                //中断时点亮这LED灯
sbit led1=P2^0;
void main()
{
EA=1;
EX0=1;
IT0=0;
while(1)
{
led2=1;
led1=0;                    //点亮LED灯
delay(1000);  //延时
led1=1;                                //熄灭LED灯
delay(1000);        ////延时
}
}

void exter0() interrupt 0
{
        led2=0;
led1=1;                //为什么要写led1=1才能让中断时led1灯灭呢,不是中断启动的时候已经把led1灯灭了吗?      
}
void delay(uint z)
{
        uint x;
        uchar y;
        for(x=z;x>0;x--)
                for(y=1000;y>0;y--);        
}

char flag=1;// 定义一个变量 规定值为1时led1亮 值为0时led1不亮  flag在中断中赋值为0 就是说当中断执行的时候 main里边的while就不要管led了  
                //这个在理论上是多余的  但是单片机运行的比较快 会给我们错觉 按下按键触发中断时 感觉上是按了一次 实际上处理了好几次
               //感觉上正在执行中断代码 实际上在一段很短的时间内 执行了N个中断 b*N个while里的点led1 现象就是led1在那里闪
               //led点亮也是要有电流 且持续一段时间才可以的 时间不足会暗或闪 呼吸灯就是这么搞得 可以利用占空比控制你的led成为呼吸灯
                //所以实际应用要用好点的按键不要用生锈的、程序上注意消抖、等等
sbit KEY1 = P3^2;// p32可能是接的按键
。(此处略去几个字)
void main()
{
    EA=1;
    EX0=1;
    IT0=0;
    while(1)
    {
        if(flag==1)//正常执行循环点灯
        {
        led2=1;
        led1=0;                    //点亮LED灯
        delay(1000);  //延时
        led1=1;                                //熄灭LED灯
        delay(1000);        ////延时
        }
    }
}
void exter0() interrupt 0
{
    Delay(2);  //为了按键按下消抖
    if(KEY1 == 0)  //低电平了
    {  
        flag=0;// while循环里 led1不可以亮了
        led2=0;//点led
        flag=1;//while又起作用了
    }  
    Delay(30);    为了按键抬起消抖
}
.(此处略去一些字)
还可以利用定时中断让led1闪烁,在外中断里控制定时中断的使能

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top