找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2585|回复: 9
收起左侧

单片机中断按键显示计数程序问题

[复制链接]
ID:656213 发表于 2020-11-30 00:13 | 显示全部楼层 |阅读模式
我原来的程序功能是,两个按键,一个按键总控制,另外一个按键按一下数码管显示加1,这个已经实现了, 我现在想改进的功能是,按键单按加1,长按加10,以下是我修改的程序,有问题(单按一次,个位,十位均加1),求助各位师兄指点。

/****************************************************************************
         两个按键,一按键控制数码管显示加1,一按键暂停,加1.清零
                   P0口接数码管,
*****************************************************************************/
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint  unsigned int
uchar led_tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};   //共阴数码管段码        0-9
uchar led_num;                                                     //LED计数值
uchar num_L,num_H;                                                                                                   //LED计数值高低位分离
uchar a;                                                                                                                   // 记录按键二的次数
uchar b;                                                                                                                  
sbit P20=P2^0;
sbit P21=P2^1;                                                                        // 数码管位选控制
void delayms(uint ms)
{
        uint i;
        while(ms--)
        {
                for(i=0;i<120;i++);
        }
}
void display(void)
{        
        if(led_num<10)
        {
                P20=0;
                P21=1;
                P0=led_tab[led_num];
                delayms(10);
        }
        else
        {
        num_L=led_num%10;
        num_H=led_num/10;
        P20=1;
           P21=0;
        P0=led_tab[num_H];
        delayms(5);
        P20=0;
           P21=1;
        P0=led_tab[num_L];
        delayms(5);
        }
}
void int0() interrupt 0
{
        b=0;
        delayms(10);
        if(INT0==0)
                {
                        led_num++;                                                   //单按加1
                        delayms(10);                                 
                        if(INT0==0)                                                     //进入长按的延时循环
                        {
                                b++;
                                delayms(50);
                                if(b=50)
                                {
                                        led_num+=10;
                                        b=30;        
                                }
                        }
                        if(led_num>99)
                        {
                                led_num=0;
                        }
                }
}
void int1() interrupt 2
{
        delayms(10);
        if(INT1==0)
                {
                        a++;
                        if(a>3)
                        {
                                a=1;
                        }
                }
}
void INT1_init(void)
{
        EX1=1;
        IT1=1;
        EA=1;
}
void main(void)
{
        a=0;
        led_num=0;
        INT1_init();
        while(1)
        {
                switch(a)
                {
                        case 0: led_num=0; break;
                        case 1: EX0=1;IT0=1; break;
                        case 2: EX0=0; break;
                        case 3: led_num=0; break;
                }
                display();
        }
}

回复

使用道具 举报

ID:65956 发表于 2020-11-30 09:05 | 显示全部楼层
你要解决的是单个按键要有短按、长按如何区分的功能,坛里有这方面的,可以参考一下就行了
回复

使用道具 举报

ID:790408 发表于 2020-11-30 09:21 来自手机 | 显示全部楼层
可以判断时间来实现短按和长按的区别
回复

使用道具 举报

ID:140489 发表于 2020-11-30 10:46 | 显示全部楼层
你去看看这篇关于长短按键识别的文章,包你有收获 https://blog.csdn.net/yuanmeixiang/article/details/53990353
回复

使用道具 举报

ID:140489 发表于 2020-11-30 13:40 | 显示全部楼层
按你的要求,写了下,仿真通过
/****************************************************************************
      
                   P0口接数码管,
*****************************************************************************/
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint  unsigned int
uchar led_tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};   //共阴数码管段码        0-9
uchar led_num;                                                     //LED计数值
uchar num_L,num_H;  //LED计数值高低位分离

uint key_cont; //按键消抖计数
bit key_lock;  //按键自锁标志
sbit P20=P2^0;                //数码管 个位
sbit P21=P2^1;      // 数码管 十位

sbit key = P3^0;        //按键
//////////////////////////////////
void delayms(uint ms)
{
        uint i,j;
   
               for(j = 0; j < ms; j--)
                 for(i = 0;i < 120; i++);
        
}
//////////////////////////////
void display()
{        
        if(led_num<10)
        {
                P20=0;
                P21=1;
                P0=led_tab[led_num];
                delayms(10);
        }
        else
        {
                num_L=led_num%10;
                num_H=led_num/10;
               
                    P20=1;
                P0=led_tab[num_H];
                P21=0;
                delayms(5);
               
                P21=1;
                P0=led_tab[num_L];
                        P20=0;
                delayms(5);
        }
}
////////////////////////////
void keyscan()
{
        if(key)                   //按键没按下
        {
                key_cont = 0;
                key_lock = 0;
        }
        else if(key_lock == 0)         //短按
        {
                key_cont++;
                if(key_cont>100)
                {
                        key_lock = 0;       
                }
                key_lock = 1;
                led_num++;
                if(led_num>100)
                        led_num=0;
        }
        else if(key_cont<1000) //长按
        {
                key_cont++;
                if(key_cont==1000)
                {
                        key_cont=900; //这里调节长按连加的速度
                        led_num+=10;
                        if(led_num>100)
                                led_num=0;       
                }       
        }               
}
///////////////////////////

void main(void)
{
        led_num=21;
        while(1)
        {
                display();
                                keyscan();
        }
}
数码管.png

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:656213 发表于 2020-11-30 13:50 | 显示全部楼层
1922323908 发表于 2020-11-30 09:21
可以判断时间来实现短按和长按的区别

我就是判断时间长短来进行的呀,不过就是没有达到我实际想要的效果。
回复

使用道具 举报

ID:140489 发表于 2020-11-30 16:28 | 显示全部楼层
jiahz2019 发表于 2020-11-30 13:50
我就是判断时间长短来进行的呀,不过就是没有达到我实际想要的效果。

/****************************************************************************
      
                   P0口接数码管,
*****************************************************************************/
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint  unsigned int
uchar led_tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};   //共阴数码管段码        0-9
uchar led_num;                                                     //LED计数值
uchar num_L,num_H;  //LED计数值高低位分离

uint key_cont; //按键消抖计数
bit key_lock;  //按键自锁标志
sbit P20=P2^0;                //数码管 个位
sbit P21=P2^1;      // 数码管 十位

sbit key = P3^0;        //按键
//////////////////////////////////
void delayms(uint ms)
{
        uint i,j;
   
               for(j = 0; j < ms; j++)
                 for(i = 0;i < 120; i++);
        
}
//////////////////////////////
void display()
{        
        if(led_num<10)
        {
                P20=0;
                P21=1;
                P0=led_tab[led_num];
                delayms(10);
        }
        else
        {
                num_L=led_num%10;
                num_H=led_num/10;
               
                    P20=1;
                P0=led_tab[num_H];
                P21=0;
                delayms(5);
               
                P21=1;
                P0=led_tab[num_L];
                        P20=0;
                delayms(5);
        }
}
////////////////////////////
void keyscan()
{
        if(key)                   //按键没按下
        {
                key_cont = 0;
                key_lock = 0;
        }
        else if(key_lock == 0)         //短按
        {
                key_cont++;
                if(key_cont>50)
                {
                        key_lock = 0;       
                }
                key_lock = 1;
                led_num++;
                if(led_num>100)
                        led_num=0;
        }
        else if(key_cont<200) //长按
        {
                key_cont++;
                if(key_cont==200)
                {
                        key_cont=150; //这里调节长按连加的速度
                        led_num+=10;
                        if(led_num>100)
                                led_num=0;       
                }       
        }               
}
///////////////////////////

void main(void)
{
        led_num=21;
        while(1)
        {
                display();
                                keyscan();
        }
}

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:656213 发表于 2020-11-30 22:04 | 显示全部楼层
lids 发表于 2020-11-30 16:28
/****************************************************************************
      
           ...

想请教 一下   if(key)    这个语句怎么理解, 按我的理解是,如果表达按键没按下,那不是应该 if (key==1) 吗?
回复

使用道具 举报

ID:656213 发表于 2020-11-30 22:42 | 显示全部楼层
lids 发表于 2020-11-30 16:28
/****************************************************************************
      
           ...

这个效果太好了,不过程序我还没看懂,需要再慢慢理解一下,谢谢!
回复

使用道具 举报

ID:140489 发表于 2020-12-1 08:14 | 显示全部楼层
jiahz2019 发表于 2020-11-30 22:04
想请教 一下   if(key)    这个语句怎么理解, 按我的理解是,如果表达按键没按下,那不是应该 if (key== ...

if(key) 就是if (key==1)的简写,表达的意思是一样的
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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