#C51按键处理(初阶基础)

系列文章目录

提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
例如:


提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

引入按键处理的思想过程
样例:按键处理系列,低配初阶最基本方法,按下有效


提示:以下是本篇文章正文内容,下面案例可供参考

一、单按键处理逻辑

1.等待按下
2.按键抖动
2.1 硬件消抖:R-S触发器、RC电路
2.2 软件消抖,延时消抖5-20ms
3.判断为有效按下
4.松开抖动
软件消抖
5.判断为松开按键
在这里插入图片描述

unsigned char key_num = 0;//充分考虑是否需要赋初始值0。任何局部变量建立后记得清0。标志法其它位置清0,或者每次进入函数体初始化清0。
	if(!KeyIn1)
	{
		Delay_xms(10); //消抖。缺点:进程占用,复杂程序影响其它时基。后续采用中断定时
		if(!KeyIn1)
		{
			fSW1= 1;
		}
		while(!KeyIn1);//松手等待,防止主循环内多次触发fStart = 1时带来的逻辑
	}

二、多按键处理逻辑

1.判断有按键按下
2.判断具体按键
3.按键标志

	if(!KeyIn1 || !KeyIn2 ||!KeyIn3 || !KeyIn4)
	{
		vKeyDelayCnt++;
		if(vKeyDelayCnt > 10)	//Delay_Xms(10);
		{
			vKeyDelayCnt = 0;
			if(!KeyIn1 || !KeyIn2 ||!KeyIn3 || !KeyIn4)
			{
				if(!KeyIn1)			//判断具体按键
					fSW1 = 1;
				if(!KeyIn2)
					fSW2 = 1;
				if(!KeyIn3)
					fSW3 = 1;
				if(!KeyIn4)
					fSW4 = 1;
			}
			while(!KeyIn1 || !KeyIn2  || !KeyIn3 || !KeyIn4);	//松手等待 
		}
	}

三、矩阵按键处理逻辑

例:4行4列矩阵
![在这里插入图片描述](https://img-blog.csdnimg.cn/63d64e29040d4fd3bfba0b1b0fd74758.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6K-35Y-r5oiReHVnZWdl,size_16,color_FFFFFF,t_70,g_se,x_16

方法1:逐行扫描/逐列扫描

#define KeyPort P3
sbit KeyIn4 = P3^7;		//第4列
sbit KeyIn3 = P3^6;
sbit KeyIn2 = P3^5;
sbit KeyIn1 = P3^4;
sbit keyOut4 = P3^3;	//第4行
sbit keyOut3 = P3^2;
sbit keyOut2 = P3^1;
sbit keyOut1 = P3^0;

其它列执行内容相同,列扫描输出配置4组(4列)–>for循环执行扫描

	KeyPort = 0xFE;			//第1行扫描
	if(!KeyIn1 || !KeyIn2 || !KeyIn3 || !KeyIn4)	//按键等待
	{	
		vKeyDelayCnt++;
		if(vKeyDelayCnt > 10)
		{
			vKeyDelayCnt = 0;
			if(!KeyIn1 || !KeyIn2 || !KeyIn3 || !KeyIn4)	//按键按下
			{
				if(!KeyIn1)	//按键识别
					fSW1 = 1;
				if(!KeyIn2)
					fSW2 = 1;
				if(!KeyIn3)
					fSW3 = 1;
				if(!KeyIn4)
					fSW4 = 1;
			}while(!KeyIn1 || !KeyIn2 || !KeyIn3 || !KeyIn4);//松手等待
		}
	}

方法2:线反转识别
原理:同时列(行)输出、行(列)输入 -->确定行号/列号 -->确定具体按键

	KeyPort = 0xF0;	//In输入,Out输出0
	if(KeyPort != 0xF0)		//1.按键按下
	{
		vKeyDelayCnt++;		
		if(vKeyDelayCnt > 10)	//2.消抖10ms
		{
			vKeyDelayCnt = 0;
			if(KeyPort != 0xF0)	//3.确定有按键按下
			{
				tempH = KeyPort & 0xF0;	//4.确定列号
				KeyPort = 0x0F;
				tempL = KeyPort & 0x0F;	//5.确定行号
			}
			while(KeyPort != 0x0F);		//6.松手等待
			gKey = tempH + tempL;
		}
	}

转载一个经典的按键处理算法,三行代码搞定:

核心算法:
unsigned char Trg;
unsigned char Cont;
void KeyRead( void )
{
    unsigned char ReadData = PINB^0xff;   // 1
    Trg = ReadData & (ReadData ^ Cont);      // 2
    Cont = ReadData;                                // 3
}

样例:trg是一次触发,Cont是长按

    if (Trg & KEY_BEEP) // 如果按下的是KEY_BEEP
    {
         Beep();            // 执行蜂鸣器处理函数
    }
void KeyProc(void)
{
       if (Trg & KEY_MODE) // 如果按下的是KEY_MODE,而且你常按这按键也没有用,
    {                    //它是不会执行第二次的哦 , 必须先松开再按下
         Mode++;         // 模式寄存器加1,当然,这里只是演示,你可以执行你想
                         // 执行的任何代码
    }
    if (Cont & KEY_PLUS) // 如果“加”按键被按着不放
    {
         cnt_plus++;       // 计时
         if (cnt_plus > 100) // 20ms*100 = 2S 如果时间到
         {
              Func();      // 你需要的执行的程序
         }          
    }
}

转载:经典的按键处理算法

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值