标题: 51单片机中INT0中断程序请教大家 [打印本页]

作者: 秋风凉    时间: 2020-1-9 21:05
标题: 51单片机中INT0中断程序请教大家
之前的一个按键控制两个状态。 我想把按键中断最优先。
程序移植到中断后,不能运行。但是中断还是有的。
这两天学习中断,请大家给些指点。

#include <STC15Wxx.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long

sbit key=P3^2;               
sbit LED1=P3^0;                        
sbit LED2=P3^1;                        
                                
bit key_flag = 0;//按键有效标志位变量
uchar count = 0;//中断计数变量

void delayms(uint xms) //添加延时
{
        uint i, j;
        for(i=xms;i>0;i--)
                for(j=1150;j>0;j--);//1T单片机
}

void Int0Init()
{
        TMOD= 0x01;                //设置定时器模式
        TH0 = 0xDC;                //10毫秒@11.0592MHz
        TL0 = 0x00;                //10毫秒@11.0592MHz
        TR0 = 0;                        //定时器0关闭
        ET0 = 1;                        //开定时器0中断
            IT0 = 1;        //设置外部中断的触发方式为下降沿触发。
             EX0 = 1;        //开启外部中断0
             EA = 1;                //中断总开关
}

void main()
{        
        Int0Init();              
        while(1);
}

void Int0() interrupt 0
{
  if(key == 0)//判断键按下
                {
                        delayms(10);//延时10ms防抖
                        if(key == 0)//确认键按下
                        {
                                key_flag = 1; //有效标志位置1
                                TR0 = 1;                        //开定时器
                                while(!key);        //等待松手
                                TR0 = 0;                        //关定时器
                        }
                }
                if(key_flag)                        //判断按键有效
                {
                        if(count>=100)        //超过1秒算长按
                        {
                                LED1=~LED1;        //LED1取反
                        }
                        else                                //小于1秒算短按
                        {
                                LED2=~LED2;        //LED2取反
                        }
                }
                count=0;                                //中断计数变量清0
                key_flag = 0;                //按键有效标志位清0
   
                              LED2=~LED2;          //测试中断反应
   }



//定时器0 中断服务函数
void Timer0Interrupt(void) interrupt 1
{
        TH0 = 0xDC;                //10毫秒@11.0592MHz
        TL0 = 0x00;                //10毫秒@11.0592MHz
        if(count<250)        //防止溢出
                count++;                //中断计数变量自+1
}
作者: 秋风凉    时间: 2020-1-9 21:18
#include <STC15Wxx.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long

sbit key        =P1^7;               
sbit LED1=P3^0;                        
sbit LED2=P3^1;                        
                                
bit key_flag = 0;//按键有效标志位变量
uchar count = 0;//中断计数变量
/*
void delayms(uint xms) //添加延时
{
        uint i, j;
        for(i=xms;i>0;i--)
                for(j=110;j>0;j--);//12T单片机
}*/
void delayms(uint xms) //添加延时
{
        uint i, j;
        for(i=xms;i>0;i--)
                for(j=1150;j>0;j--);//1T单片机
}

void main()
{        
        //初始化定时器0
        TMOD= 0x01;                //设置定时器模式
        TH0 = 0xDC;                //10毫秒@11.0592MHz
        TL0 = 0x00;                //10毫秒@11.0592MHz
        TR0 = 0;                        //定时器0关闭
        ET0 = 1;                        //开定时器0中断
        EA  = 1;                        //开总中断
        while(1)
        {
                if(key == 0)//判断键按下
                {
                        delayms(10);//延时10ms防抖
                        if(key == 0)//确认键按下
                        {
                                key_flag = 1; //有效标志位置1
                                TR0 = 1;                        //开定时器
                                while(!key);        //等待松手
                                TR0 = 0;                        //关定时器
                        }
                }
                if(key_flag)                        //判断按键有效
                {
                        if(count>=100)        //超过1秒算长按
                        {
                                LED1=~LED1;        //LED1取反
                        }
                        else                                //小于1秒算短按
                        {
                                LED2=~LED2;        //LED2取反
                        }
                }
                count=0;                                //中断计数变量清0
                key_flag = 0;                //按键有效标志位清0
        }
}
//定时器0 中断服务函数
void Timer0Interrupt(void) interrupt 1
{
        TH0 = 0xDC;                //10毫秒@11.0592MHz
        TL0 = 0x00;                //10毫秒@11.0592MHz
        if(count<250)        //防止溢出
                count++;                //中断计数变量自+1
}

这个是高手写的原程序
作者: 秋风凉    时间: 2020-1-9 21:24
这个主要是模糊在   1要计时  2要判断     网上的教程大都是直接执行一个指令
作者: hantu    时间: 2020-1-10 01:11
第二份代码,那是在主循环中用轮询的方法来检测按键。

你的代码是想在外部中断中判断按键,这种通常是使用接在MCU的INT0和INT1引脚上的按键才行,只要按下相应的键,就会产生外部中断,所以在中断服务程序中不用象轮询那样两次判断if(key==0),因为只要进中断,就说明已经是按键被按下、产生外部中断了,只需保留确认按下的那个if就行了。而且中断服务最好要尽快执行完了马上中断返回,不要用while去等待按键放开,这是中断法不一样的地方。
作者: 笨笨兔    时间: 2020-1-10 09:34
1要计时  2要判断
------
这个首先是你模糊了: 你程序里面有中断嵌套, 程序必死无疑!
作者: Y_G_G    时间: 2020-1-10 11:02
P3.2为外部中断INT0,优先等级默认为最高等级,只要你不去设定中断的优先等级,你这按键就是最高等级:按键默认为最优先等级.
作者: 秋风凉    时间: 2020-1-10 15:09
hantu 发表于 2020-1-10 01:11
第二份代码,那是在主循环中用轮询的方法来检测按键。

你的代码是想在外部中断中判断按键,这种通常是使 ...

怎么计时呢
作者: 笨笨兔    时间: 2020-1-13 10:26
秋风凉 发表于 2020-1-10 15:09
怎么计时呢

按键这么慢的设备,你为什么一定要 把按键中断最优先 呢?
  你的程序,想计时,只能软延时计时,或者查询定时器标志计时,总之,就是什么也不干,只是等待;一般产品不会这么做的.




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1