这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » 请教MCU系统中单个按键实现多功能操作的3个问题

共6条 1/1 1 跳转至

请教MCU系统中单个按键实现多功能操作的3个问题

工程师
2021-08-20 22:51:19     打赏

我想做一个按键切换模式的功能,首先是5S长按进入模式切换状态,然后同一个按键短按选择模式1.2.3....,最后保存当前模式退出切换模式状态。那么有三个问题跟大家请教:
1.选择完模式后要怎么做保存选择的当前模式要执行的代码呢?
2.假如1模式代码里面有while和for循环在运行的时候, 外部按键长按5S能中断当前程序进入模式选择吗?
3.同一个按键,5S长按加中断功能,短按没有中断功能,怎么实现只有先长按5S进入模式切换状态,短按才有效?




关键词: 按键     多功能    

工程师
2021-08-20 23:02:55     打赏
2楼

按层层递进,层层退出的方式做,每一层都是一个死循环。用查询方式,中断方式是分不出按键长短的。


工程师
2021-08-20 23:06:43     打赏
3楼

首先你要弄清模式切换模式是否必需的
长按五秒才进入模式切换模式,代表该键在非模式切换模式有其它用途
如该键只用于模式切换,那么模式切换模式就是多此一举
又或者模式不能频烦转换,必需选好模式,作出确认,才可运行
但此例子又需要另外显示(LCD1602,数码管等)所选的模式才能确认,不然只是盲猜

1. 只在模式切换模式中对某变数赋值
2. 尽量不要在大循环以外的地方再用while(),请善用大循环
3. 不一定要用中断,中断是用来处理并即时反应高速重要讯号,硬件按键一定有跳动讯号,需加消抖,引致按键讯号不高速,而即时反应,尽量不要在内用长时间延时(>1ms),请善用定时中断

以下是一个小例子:

#include <reg52.h>

#define uint unsigned int

#define uchar unsigned char

        

sbit KeyIn = P1^0;

sbit Led = P1^7;

uint Delayms_Key, Delayms_mode;

char LedPatten[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

bit KeyIn_O;

void Timer0_Init()

{

        //定时器0初始化,16位,1ms中断,12T 8051

        TMOD &= 0xF0;

        TMOD |= 0x01;

        TL0 = 0x18;

        TH0 = 0xFC;

        TF0 = 0;

  ET0 = 1;

        TR0 = 1;

        EA = 1;

}

void Timer0() interrupt 1//定时器0

{

        TL0 = 0x18;

        TH0 = 0xFC;

        if(Delayms_Key)Delayms_Key--;

        if(Delayms_mode)Delayms_mode--;

}


void main()

{


        uchar mode=0, index=0;

        bit Swap=1;

        Timer0_Init();

        while (1)

        {

                if(!Delayms_Key)

                {

                        Delayms_Key=10;//10ms

                        if(KeyIn_O && !KeyIn)//下降沿触发

                        {

                                mode++;

                        }KeyIn_O = KeyIn;

                }

                switch(mode)

                {

                        case 0:

                                if(!Delayms_mode)

                                {

                                        //1Hz Led 闪烁

                                        Delayms_mode = 500;

                                        Led = !Led;

                                }break;

                        case 1:

                                if(!Delayms_mode)

                                {

                                        //2.5Hz Led 闪烁

                                        Delayms_mode = 200;

                                        Led = !Led;

                                }break;

                        case 2:

                                if(!Delayms_mode)

                                {

                                        //1Hz Led 短闪烁

                                        if(Swap)

                                        {

                                                Delayms_mode = 100;

                                                Led = 0;//Led 亮

                                        }else{

                                                Delayms_mode = 900;

                                                Led = 1;//Led 灭

                                        }

                                        Swap = !Swap;

                                }

                                break;

                        case 3:

                                if(!Delayms_mode)

                                {

                                        //8Led 流水灯

                                        Delayms_mode = 200;

                                        P2 = ~LedPatten[index];

                                        if(++index==8)index=0;

                                }break;

                        default:

                                mode=0;

                                index=0;

                                P2=0xFF;

                                Swap=1;

                                break;

                }

        }

}





工程师
2021-08-20 23:11:32     打赏
4楼

我觉得,也可以用中断的。


用中断是不需要在死循环中等待的。

中断中的计数也是可以用于防抖动的。

所以:

1.选择完模式后用一个变量来标志,如果需要断电也保存,用EPROM写入开机读标志。

2.假如1模式代码里面有while和for循环在运行的时候, 外部按键长按5S能中断当前程序进入模式选择。

3.同一个按键5S长按加中断功能短按取消中断功能,可以用条件语句实现(感觉这个很变态但可以做)。




工程师
2021-08-20 23:17:04     打赏
5楼

如果需要断电也保存,用EPROM写入开机读标志啊


专家
2021-08-21 00:02:44     打赏
6楼

感谢楼主的分享,很实用了。


共6条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]