打印

来看看这个按键防抖设计

[复制链接]
5430|26
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
duhemayi|  楼主 | 2012-9-17 18:13 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
void keyscan()
//
按键识别钟程序

{

while(modstate==0)


{


display();



if(key0==0)


{


display();


if(key0==0)modstate++;
//
这两句加在一起为延时10ms软件防抖设计。


while(key0==0)display001();
//
等待按键释放。


}


}



上程序中,“这两句加在一起为延时10ms软件防抖设”很是不解呀,有没有高手出来说说!









评分
参与人数 1威望 +1 收起 理由
yeqing625 + 1 好用

相关帖子

沙发
chenbb8| | 2012-9-17 22:15 | 只看该作者
比较基础的问题,我这种菜鸟也能回答:loveliness:
display();
if(key0==0)modstate++;这两句看不懂是么
第一句display();应该是延时10ms
首先在检查到key0==0后延时10ms(第一句),然后再判断key是否等于0,等于0则成立,并且modstate++;
不等于0,则说明是抖动。

使用特权

评论回复
板凳
anazel| | 2012-9-18 08:51 | 只看该作者
似乎延时函数取名delay更清晰一些

使用特权

评论回复
地板
chenbb8| | 2012-9-18 08:55 | 只看该作者
估计是display() 里面带了一个10ms的延时~~

使用特权

评论回复
5
lmeihui7296| | 2012-9-18 09:06 | 只看该作者
你的display()只是用来写延迟的吧。
写成delay()多好认。

使用特权

评论回复
6
xiaox314| | 2012-9-18 10:39 | 只看该作者
:o没有看到延时函数!

使用特权

评论回复
7
xiaox314| | 2012-9-18 10:43 | 只看该作者
这个没有啥好研究的,你按下按键,就有你那句if(key0==0),是否是真的按下按键display();

if(key0==0)就是你说的等待10ms,看是否还是在按下状态,如果是就说明是真的按了,因为人按键的速率不可能达到很高,所以用这个延时来判断是否是真的按下!

使用特权

评论回复
8
forgot| | 2012-9-18 10:51 | 只看该作者
这签名有点意思;P 7# xiaox314

使用特权

评论回复
9
woaichengdian| | 2012-9-18 12:36 | 只看该作者
6楼大神的签名太赞了

使用特权

评论回复
10
darlin520| | 2012-9-18 13:19 | 只看该作者
不知道楼主大神用的什么编程思想,是想用display()函数来延时去抖吗,但是又不想浪费这大概10ms的时间,于是调入了display()这个显示函数,用来刷新LCD或LED。但

使用特权

评论回复
11
sljzyjj| | 2012-9-18 13:45 | 只看该作者
调用display()函数,是为了让LED或数码管一直在显示,反正运行一遍是10ms左右,既延时了,又不影响显示效果,何乐而不为。

使用特权

评论回复
12
csl84| | 2012-9-18 14:27 | 只看该作者
调用显示延时。很好的方法

使用特权

评论回复
13
csl84| | 2012-9-18 14:27 | 只看该作者
调用显示延时。很好的方法

使用特权

评论回复
14
duhemayi|  楼主 | 2012-9-18 16:49 | 只看该作者
看来我需要多放点程序出来,呵 呵,不好意思!
/**** 本程序中,晶振为12MHz,           ****/
/**** 时间控制采用定时中断控制方式。  ****/
/**** 模式和时间调整采用查询方式。    ****/

#include<reg52.h>

sbit P20=P2^0;        //分个位控制端
sbit P21=P2^1;        //分十位控制端
sbit P22=P2^2;        //时个位控制端
sbit P23=P2^3;        //时十位控制端
sbit led=P2^7;        //second display led

sbit key0=P3^0;        //模式设置
sbit key1=P3^1;        //加
sbit key2=P3^2;        //减

unsigned char hour,min,sec,T50ms;
unsigned char modstate;        //模式状态

unsigned char code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};//段码

void init();                                //初始化子程序声明
void delay500us(unsigned char X);        //延时子程序声明
void display();                                //显示子程序声明
void display001();                        //显示子程序声明
void display002();                        //显示子程序声明
void keyscan();                                //按键识别子程序声明

void main()
{        
        init();
        while(1)
        {
                keyscan();       
        }
}

void init()        //初始化子程序
{       
        TMOD=0x01;
        TH0=(65536-49990)/256;
        TL0=(65536-49990)%256;
        ET0=1;
        EA=1;
        TR0=1;       
}

void delay500us(unsigned char X)
{
        unsigned char i,j;
        for(i=X;i>0;i--)
        for(j=248;j>0;j--);
}

void timer0() interrupt 1        //timer0中断服务子程序,定时时间为50ms,本程序加了10us的时间修正量
{
        TMOD=0x01;
        TH0=(65536-49990)/256;       
        TL0=(65536-49990)%256;

        T50ms++;
        if(T50ms>=20)
        {
                T50ms=0;
                sec++;
                if(sec>=60)
                {
                        sec=0;
                        min++;
                        if(min>=60)
                        {
                                min=0;
                                hour++;
                                if(hour>=24)hour=0;
                        }
                }
        }
}

void display()
{
        P20=1;
        P21=1;
        P22=1;
        P23=1;
        P0=table[hour/10];
        P23=0;
        delay500us(5);

        P20=1;
        P21=1;
        P22=1;
        P23=1;
        P0=table[hour%10];
        P22=0;
        delay500us(5);

        P20=1;
        P21=1;
        P22=1;
        P23=1;
        P0=table[min/10];
        P21=0;
        delay500us(5);

        P20=1;
        P21=1;
        P22=1;
        P23=1;
        P0=table[min%10];
        P20=0;
        delay500us(5);

        if(T50ms<=10)led=0;
        if(T50ms>10)led=1;
}

void display001()
{
        P20=1;
        P21=1;
        P22=1;
        P23=1;
        P0=table[hour/10];
        P23=0;
        delay500us(10);

        P20=1;
        P21=1;
        P22=1;
        P23=1;
        P0=table[hour%10];
        P22=0;
        delay500us(10);
}

void display002()
{
        P20=1;
        P21=1;
        P22=1;
        P23=1;
        P0=table[min/10];
        P21=0;
        delay500us(10);

        P20=1;
        P21=1;
        P22=1;
        P23=1;
        P0=table[min%10];
        P20=0;
        delay500us(10);
}


void keyscan()                //按键识别钟程序
{
        while(modstate==0)
        {
                display();
                if(key0==0)
                {
                        display();
                        if(key0==0)modstate++;                //这两句加在一起为延时10ms软件防抖设计。
                        while(key0==0)display001();        //等待按键释放。
                }
        }
//****************************************************************************//
        while(modstate==1)
        {
                display001();
                if(key0==0)
                {
                        display001();
                        if(key0==0)modstate++;                //这两句加在一起为延时10ms软件防抖设计。
                        while(key0==0)display002();        //等待按键释放。
                }

                if(key1==0)
                {
                        display001();
                        if(key1==0)
                        {
                                hour++;
                                if(hour>=24)hour=0;
                                while(key1==0)display001();
                        }       
                }
                if(key2==0)
                {
                        display001();
                        if(key2==0)
                        {
                                hour--;
                                if(hour>=24)hour=0;
                                while(key2==0)display001();
                        }
                }
        }
//****************************************************************************//
        while(modstate==2)
        {
                display002();
                if(key0==0)
                {
                        display002();
                        if(key0==0)modstate=0;                //这两句加在一起为延时10ms软件防抖设计。
                        while(key0==0)display();        //等待按键释放。
                }

                if(key1==0)
                {
                        display002();
                        if(key1==0)
                        {
                                min++;
                                if(min>=60)min=0;
                                while(key1==0)display002();
                        }       
                }
                if(key2==0)
                {
                        display002();
                        if(key2==0)
                        {
                                min--;
                                if(min>=60)min=0;
                                while(key2==0)display002();
                        }
                }
        }
}
这个源程序是一个大学老师写的,我觉得比较好,大家再看看哈!

使用特权

评论回复
15
duhemayi|  楼主 | 2012-9-18 16:55 | 只看该作者
我觉得十二楼、十一楼的同志说的很好,调用显示程序来代替延时,让CPU不要在那空转,即显示又延时了,很好的方法,只是不解他这DSPLAY里总共才4个500US的延时,也就是2MS的延时,怎么代替10MS的延时呢?
这个程序我已经烧到芯片里实际测试了,运行很好,没有发现什么问题!

使用特权

评论回复
16
amwrdfe| | 2012-9-18 17:09 | 只看该作者
咱觉得好程序,应该让人通俗易懂。
按键程序中嵌入显示... ...
其实很多人都是用查询的方式来处理按键。延时处理按键这种方式,教科书上说得比较多而已。

使用特权

评论回复
17
zq1987731| | 2012-9-19 00:04 | 只看该作者
要是维持这种风格将程序扩大到100万行...这程序BUG必定多如牛毛,等LZ什么时候搞明白什么是“架构”了,才能说编程真正入门了...
比如这个例子中,按键扫描阶段穿插显示动作,无论如何都是小打小闹的下下策,定时器+状态机才是较为推荐的做法,定时器设为10ms触发一次,按键任务每10ms进入一次视情况改变状态,即不用浪费“消抖”所占10ms又能达到比“延时”更好的效果

使用特权

评论回复
18
zxcscm| | 2012-9-19 09:44 | 只看该作者
17楼才是正解啊
无论是按键还是显示的程序延时,只适合小段程序使用,等程序上一定规模了还是状态机好用,且利于结构化。
建议研究下状态机

使用特权

评论回复
19
chenbb8| | 2012-9-19 11:23 | 只看该作者
严格的10ms触发比较死板,假设任务队列里既有执行时间10ms左右的任务,又有100us就可以执行完的任务,甚至还有LCD显示函数需要几百ms才能发送完的。
然后如何利用CPU时间会比较合理,特别是任务多且比较重(任务执行时间不等,实时性要求高)的时候~

使用特权

评论回复
20
duhemayi|  楼主 | 2012-9-19 13:38 | 只看该作者
什么是状态机?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

10

主题

1656

帖子

8

粉丝