OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5442|回复: 6

C51用定时器实现按键消抖。写得不好,还望各位指点

[复制链接]

6

主题

21

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
217
金钱
217
注册时间
2016-8-2
在线时间
27 小时
发表于 2016-8-5 07:29:49 | 显示全部楼层 |阅读模式
[mw_shl_code=c,true]/********************************
        按独立按键使数码管加1
********************************/
#include <reg52.h>

#define uchar unsigned char

sbit KEY = P1 ^ 0;                                                                                         //定义独立按键
bit KEYSTA = 1;                                                                                         //按键的初始状态
uchar code DispCode[] = {0xc0,0xf9,0xa4,0xb0,                                 //共阳数码管
                          0x99,0x92,0x82,0xf8,
                          0x80,0x90,0x88,0x83,
                          0xc6,0xa1,0x86,0x8e};
void Timer0Init();                                                                                        //定时器初始化函数
void KeyProcess();                                                                                        //按键处理函数

void main()
{
        Timer0Init();
        KeyProcess();
}

void Timer0Init()
{
        TMOD |= 0x01;
        TH0 = 0xF8;                          //定时2MS
        TL0 = 0xCD;
        EA =1;
        ET0 = 1;
        TR0 = 1;
}
void KeyProcess()
{
        bit lasttime = 1;                                                 //定义前一次按键值,初始化为1;
        uchar count = 0;                                                 //计数值初始化为0;
        KEY = 0x01;                                                                 //按键初始化;
        P0 =  DispCode[count];                                         //数码管初始化;
        while(1)
        {
                if (KEYSTA != lasttime)                                 //如果“当前按键状态”与“前一次按键状态”不同,说明按键有动作;
                {
                        if (lasttime == 1)                                 //如果按键有动作了,那么前一次按键状态为“弹起”(lasttime == 1),说明按键按下时,会响应动作;
                        {
                                count++;
                                if (count >= 16)                         //计数加到16清零,只用一个共阳数码管;
                                {
                                        count = 0;
                                }
                                P0 =  DispCode[count];                 //共阳数码管显示相应的值;
                        }
                        lasttime = KEYSTA;                                 //如果按键有动作,就更新前一次按键的值;
                }
        }
}

void Timer0IRQ() interrupt 1                                //2MS中断一次
{
        static keybuf = 0xFF;                                        //定义一个静态按键缓存变量,且值为FF;主要是暂存按键状态;
        TH0 = 0xF8;                                            //重新写入初值;
        TL0 = 0xCD;
       
        keybuf = (keybuf << 1) | KEY;                    //左移一位,使当前的按键状态移到按键缓存中;
        if (keybuf == 0)                                                //如果移8次,按键状态都为0,说明按键真正按下;
        {
                KEYSTA = 0;                                                    //确定按键状态为按键;
        }
        else if (keybuf == 0xFF)                                //如果移8次,按键状态都为1,说明按键未按下
        {
                KEYSTA = 1;
        }
}[/mw_shl_code]
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

36

主题

249

帖子

0

精华

高级会员

Rank: 4

积分
680
金钱
680
注册时间
2015-12-13
在线时间
243 小时
发表于 2016-8-5 23:33:27 | 显示全部楼层
我觉得你得想个办法不用定时器才好!又不需要精确延时,没必要浪费个定时器。。有时候51的资源很紧张的(实际应用的时候)……个人观点!
回复 支持 反对

使用道具 举报

17

主题

587

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4467
金钱
4467
注册时间
2013-6-27
在线时间
565 小时
发表于 2016-8-6 08:44:45 | 显示全部楼层
本帖最后由 DongInker 于 2016-8-6 08:46 编辑

输入接口相对于输出接口,输入接口需要做去斗,而按键对应输入接口不仅去斗很关键还得判断按键的属性,即按下执行,长按执行,释放执行,连续执行等。
可以了解前后台系统,定时器做为一个系统节拍,可以把一些按键输入,IO输入,蜂鸣器输出,指示灯输出,延时计数放到定时中断处理,中断处理任务有一个特性就是快速不等待,有事件改变时标记处理。截图是我蜂鸣器处理模块处理,按键可以根据思路编写。

蜂鸣器.h文件

#ifndef _BEEP_H
#define _BEEP_H

GLOBAL void ProF_10mS_Beeper(void);                              //提供定时中断10mS调用一次
GLOBAL void SetBeep(u8 num,u8 time_on,u8 time_off);        //用户API 参数1:蜂鸣器响的次数  参数2:蜂鸣器响的时长 参数3:蜂鸣器间隔时长。



#endif

定时中断处理函数

定时中断处理函数

蜂鸣器模块

蜂鸣器模块
让我们的思维驾驭在电的速度之上!
回复 支持 反对

使用道具 举报

32

主题

883

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3990
金钱
3990
注册时间
2015-11-14
在线时间
541 小时
发表于 2016-8-6 09:34:43 | 显示全部楼层
你这个思路是正确的,我也是用这样的方法扫面按键的,这样大大的节省了CPU的时间
回复 支持 反对

使用道具 举报

6

主题

21

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
217
金钱
217
注册时间
2016-8-2
在线时间
27 小时
 楼主| 发表于 2016-8-7 09:44:02 | 显示全部楼层
Electronic 发表于 2016-8-6 09:34
你这个思路是正确的,我也是用这样的方法扫面按键的,这样大大的节省了CPU的时间

如果,4X4这个就要费力了。
回复 支持 反对

使用道具 举报

10

主题

271

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1236
金钱
1236
注册时间
2015-5-14
在线时间
352 小时
发表于 2016-8-15 10:21:33 | 显示全部楼层
消抖思路正确,就是用定时器,如果改为软件定时器就会大大节省硬件资源。同时驱动和按键个数无关,楼主可自行测试。
30年众生牛马,60年诸佛龙象!
回复 支持 反对

使用道具 举报

6

主题

104

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
436
金钱
436
注册时间
2015-12-11
在线时间
53 小时
发表于 2016-8-17 13:58:27 | 显示全部楼层
思想确实可以借鉴,学到了
Try again and there is nothing left to say.
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-23 16:39

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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