找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4653|回复: 7
打印 上一主题 下一主题
收起左侧

51单片机中INT0中断程序请教大家

[复制链接]
跳转到指定楼层
楼主
ID:634487 发表于 2020-1-9 21:05 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
之前的一个按键控制两个状态。 我想把按键中断最优先。
程序移植到中断后,不能运行。但是中断还是有的。
这两天学习中断,请大家给些指点。

#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
}
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:634487 发表于 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
}

这个是高手写的原程序
回复

使用道具 举报

板凳
ID:634487 发表于 2020-1-9 21:24 | 只看该作者
这个主要是模糊在   1要计时  2要判断     网上的教程大都是直接执行一个指令
回复

使用道具 举报

地板
ID:462827 发表于 2020-1-10 01:11 | 只看该作者
第二份代码,那是在主循环中用轮询的方法来检测按键。

你的代码是想在外部中断中判断按键,这种通常是使用接在MCU的INT0和INT1引脚上的按键才行,只要按下相应的键,就会产生外部中断,所以在中断服务程序中不用象轮询那样两次判断if(key==0),因为只要进中断,就说明已经是按键被按下、产生外部中断了,只需保留确认按下的那个if就行了。而且中断服务最好要尽快执行完了马上中断返回,不要用while去等待按键放开,这是中断法不一样的地方。
回复

使用道具 举报

5#
ID:158375 发表于 2020-1-10 09:34 | 只看该作者
1要计时  2要判断
------
这个首先是你模糊了: 你程序里面有中断嵌套, 程序必死无疑!
回复

使用道具 举报

6#
ID:401564 发表于 2020-1-10 11:02 | 只看该作者
P3.2为外部中断INT0,优先等级默认为最高等级,只要你不去设定中断的优先等级,你这按键就是最高等级:按键默认为最优先等级.
回复

使用道具 举报

7#
ID:634487 发表于 2020-1-10 15:09 | 只看该作者
hantu 发表于 2020-1-10 01:11
第二份代码,那是在主循环中用轮询的方法来检测按键。

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

怎么计时呢
回复

使用道具 举报

8#
ID:158375 发表于 2020-1-13 10:26 | 只看该作者

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

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表