蓝桥杯单片机矩阵键盘消抖(利用三行代码)_二货跟班的博客-程序员ITS203_矩阵键盘消抖

技术标签: 蓝桥杯单片机  单片机  

三行代码

keycode = ~(keycloumn | keyrow);
key = keycode & (keycode ^ keybefore);
keybefore = keycode;

三行代码理解:

一般情况不会同时按下两个及以上的按键,以下不考虑同时按下不同按键的情况。

keycode为当前扫描得到的按键编码,有按键按下不为0,否则为0,keybefore为上一次扫描时得到的按键值。

第一行是按键编码取反,将按下的按键所在行和列二进制值取1,(如按下第一行第二列keycode为0x41, 高四位从高位到低位对应第一列到第四列,低四位从低位到高位对应第一行到第四行);

第二行是松手检测加消抖。当前和上一次扫描时按键的状态有四种情况,为消抖,只在情况②(刚刚按下按键)时读取按键编码
①:上一次未按下,当前未按下;
②:上一次未按下,当前按下;
③:上一次按下,当前按下;
④:上一次按下,当前已经松手;

异或运算即不相同为1,相同为0,只有②和④两种情况keycode与keybefore不相同,因此只有②和④两种情况keycode^keybefore不为0。这两种情况都是一个为0的值与一个不为0的值位异或,那么②和④两种情况下 keycode ^ keybefore的值等于不为0的那个值(比如0x87 ^ 0x00 = 0x87),所以只有情况②和④keycode ^ keybefore = keycode(当前扫描时按键编码)。异或得到的值还得与keycode进行位与操作,情况④keycode = 0,与(keybefore ^ keycode)位与结果为0,但是情况②keycode为当前按下按键编码,而(keybefore ^ keycode)也为当前按下按键编码,因此key也为当前按下按键编码。综上,只有情况②key的值为当前按下按键编码,其余三种情况key = 0。

第三行:
保存上一次按下按键编码。

源代码

#include<stc15f2k60s2.h>

#define uchar unsigned char

code uchar semg[12] = {
    0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90,
											 0xbf, 0xff};
code uchar semg_bit[8] = {
    0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
uchar semg_temp[8] = {
    11, 11, 11, 11, 11, 11, 11, 11};

//自定义按键排列,-1表示按键无效显'-'
code char keymap[4][4] = {
    {
    0, 1, 2, -1}, {
    3, 4, 5, -1}, {
    6, 7, 8, -1}, {
    9, 10, 11, -1}};


void allinit()
{
    
	P2 = 0x80;	P0 = 0xff;
	P2 = 0xa0;	P0 = 0x00;
	P2 = 0xc0;	P0 = 0xff;
	P2 = 0xe0;	P0 = 0xff;
}


void Timer0Init(void)		//2毫秒@11.0592MHz
{
    
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0x9A;		//设置定时初值
	TH0 = 0xA9;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	EA = 1;
	ET0 = 1;
}


void display()
{
    
	uchar i;
	
	P2 = 0xe0;	P0 = semg[semg_temp[i]];
	P2 = 0xc0;	P0 = semg_bit[i];
	P2 = 0x00;	P0 = 0xff;
	
	i++;
	if(i == 8)
		i = 0;
}


void fun() interrupt 1
{
    
	display();
}


char keyscan()
{
    
	static uchar keybefore = 100;
	char keyvalue = 100;
	uchar keyrow = 0, keycloumn = 0, keycode = 0, key = 0, i = 0, j = 0;
	
	P3 = 0x0f;	P44 = 0;	P42 = 0;	P35 = 0;
	keyrow = P3 & 0x0f;
	P3 = 0xf0;	P44 = 1;	P42 = 1;	P35 = 1;
	if(P44 == 0)				keycloumn = 0x70;
	else if(P42 == 0)		keycloumn = 0xb0;
	else								keycloumn = P3 & 0xf0;
	
	//以下为三行代码
	keycode = ~(keycloumn | keyrow);
	key = keycode & (keycode ^ keybefore);
	keybefore = keycode;
	
	if(key)
	{
    
		for(i = 0; i < 4; i++)
			for(j = 0; j < 4; j++)
				if(key == (0x80 >> j | 0x01 << i))
				{
    
					keyvalue = keymap[i][j];
					break;
				}
	}
	
	return keyvalue;
}


void menu(char keyvalue)
{
    
	if(keyvalue >= 0 && keyvalue <= 11)
	{
    
		if((keyvalue / 10) > 0)
			semg_temp[6] = keyvalue / 10;
		else
			semg_temp[6] = 11;
		semg_temp[7] = keyvalue % 10;
	}
	else if(keyvalue == -1)
	{
    
		semg_temp[6] = 11;
		semg_temp[7] = 10;
	}
	else	;
}


void main()
{
    
	allinit();
	Timer0Init();
	
	while(1)
	{
    
		menu( keyscan() );
	}
}
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_44106838/article/details/114550804

智能推荐

【综述翻译】Deep Learning for 3D Point Clouds: A Survey_冯子材的博客-程序员ITS203

Deep Learning for 3D Point Clouds: A Survey为国防科技大学发布的综述文章,这里只翻译摘要,第一章与第三章。下载链接:https://arxiv.org/abs/1912.12033;仓库链接:https://github.com/QingyongHu/SoTA-Point-Cloud。摘要由于点云学习在计算机视觉,自动驾驶和机器人等许多领域的广泛应...

java读取文件(read与readFully)_liguanyi11111的博客-程序员ITS203

          在socket通信中,经常会有传送大量字节数组的时候,在一般情况下,直接用read(byte[] b)读取数组不会出现问题,但是当文件传输速度很快,或者量特别大的情况下。就可能导致传送的字节不完整。原因如下:          由于我们用的是基于TCP/IP的socket传输。发送端的数据首先进入缓存区被分割成TCP/IP报文,然后排队进入管道中,通过管道在进入接收端的...

c++中WaitForSingleObject函数解析_聆一的博客-程序员ITS203_c++ waitforsingleobject

函数的原型:DWORD WaitForSingleObject( HANDLE&nbsp;hHandle,&nbsp;// handle to object&nbsp;DWORD&nbsp;dwMilliseconds&nbsp;// time-out interval&nbsp;);hHandle:(事件)对象的句柄;dwMilliseconds:时间间隔,毫秒级WaitForS...

python爬虫--租房信息_当当和嘟嘟的博客-程序员ITS203_python爬虫租房

对小猪住房网站的信息爬取一、准备二、爬取的内容明细三、这里直接写代码四、输出结果一、准备谷歌浏览器打开http://bj.xiaozhu.com/fangzi/37609773603.html前面几节已经说了,快速安装库,编译器选择,soup.select()中的填写headers内容的更改,(如果不写headers则运行几次代码,浏览器就会限制你访问。)二、爬取的内容明细...

SpringBoot+Mybatis 配置多个数据库_糖醋里脊丶的博客-程序员ITS203

SpringBoot+Mybatis 配置多个数据库pom.xmlapplication.properties数据源的config文件建一个包config ,里面放两个数据源的配置文件首先是第一个数据源的config.然后是第二个数据源的config.DaoXML最后给大家看下结构大概就是这个样子了...功能需要同时连接两个数据库,然后去百度,但是没搞通,就一点一点试…就终于成功了,写个demo记录一下,第一次写csdn,欢迎大家指出问题(命名什么的请忽略)。pom.xml首先肯定是jar包,如果有

bzoj 1003 [ZJOI2006]物流运输trans 最短路+DP_DJS_K_D的博客-程序员ITS203

bzoj 1003 物流运输trans传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1003Description物流公司要把一批货物从码头A运到码头B。由于货物量比较大,需要n天才能运完。货物运输过程中一般要转停好几个码头。物流公司通常会设计一条固定的运输路线,以便对整个运输过程实施严格的管理和跟踪。由于各种因素的

随便推点

体系结构: RISC, CISC, x86, ARM, MIPS_gaijf的博客-程序员ITS203_cisc x86

硬件体系结构(Architecture)软件操作系统(Operating System)一、RISC与CISC 1.CISC(Complex Instruction SetComputer,复杂指令集计算机)复杂指令集(CISC,Complex Instruction Set Computer)是一种微处理器指令集架构(ISA),每个指令可执行若干低阶操作,诸如从内存读取、储存

最小二乘法曲线拟合(代码环境:matlab)_zZzzzZ_ZzzZzi的博客-程序员ITS203_matlab最小二乘法曲线拟合

题目一:1.用表1-1中的世界人口统计数值估计1980年的人口,求最佳最小二乘法数值估计:表 1-1:年人口19603 039 585 53019703 707 475 88719905 281 653 82020006 079 603 571(a) 直线;(b) 抛物线。它们都通过这些数据点,并求这些拟合的RMSE。在每一种情形下,估计1...

[AD]常见错误1_弑梦空间-涛的博客-程序员ITS203

AD16同一个元件中封装焊盘间距可能会小于整体规则设置,从而导致报错:现实的错误:方法一. 在间距规则中增加对“元件”规则的约束:在Query Helper中选择元件判断规则:按错误信息所示把元件标号填写进去:再运行DRC,就不再有错误了:...

让Win7做DHCP服务器_sean908的博客-程序员ITS203_win7搭建dhcp服务器

直接安装软件即可http://www.dhcpserver.de/cms/有网络基础知识即可自行设置, 不清楚的可以参照→https://wenku.baidu.com/view/1bba2bc6f7ec4afe05a1df0c.html

【转】 StringUtils中 isNotEmpty 和isNotBlank的区别_weixin_30814223的博客-程序员ITS203

【转自】http://blog.csdn.net/foamflower/article/details/5713604isNotEmpty将空格也作为参数,isNotBlank则排除空格参数StringUtils方法的操作对象是java.lang.String类型的对象,是JDK提供的String类型操作方法的补充,并且是null安全的(即如果输入参数String为null...

Java学习之网络编程实例_weixin_30911809的博客-程序员ITS203

转自:http://www.cnblogs.com/springcsc/archive/2009/12/03/1616413.html多谢分享网络编程 网络编程对于很多的初学者来说,都是很向往的一种编程技能,但是很多的初学者却因为很长一段时间无法进入网络编程的大门而放弃了对于该部分技术的学习。 在学习网络编程以前,很多初学者可能觉得网络编程是比较复杂的系统工程,需要了解很...