即将独立按键进行重新组合。
按键IO口前都有加上拉电阻。
扫描原理:
方法一:
逐行扫描:通过高四位轮流输出低电平来对矩阵键盘进行逐行扫描,当低四位接收到的数据不全为1的时候,说明有按键按下,然后通过接收到的数据是哪一位为0来判断是哪一个按键被按下。
方法二:
行列扫描:我们可以通过高四位全部输出低电平,低四位输出高电平。当接收到的数据,低四位不全为高电平时,说明有按键按下,然后通过接收的数据值,判断是哪一列有按键按下,然后再反过来,高四位输出高电平,低四位输出低电平,然后根据接收到的高四位的值判断是那一行有按键按下,这样就能够确定是哪一个按键按下了。
由矩阵按键变为独立按键:
将连接四个按键的一条线持续输出低电平,其他都输出高电平(避免对所用线路影响)
通过矩阵按键控制数码管最后一位显示矩阵按键对应的数字,程序如下:
横向依次为0123,4567,89AB,CDEF:
#include<reg51.h>
typedef unsigned char u8;
typedef unsigned int u16;
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
#define GPIO_KEY P1//定义矩阵按键IO口为P1
#define GPIO_DIG P0//定义静态数码管IO口为P0
u8 KeyValue;//每一个按键用一个用KeyValue指代
u8 a;//为下面按下时间检测做准备
u8 code smgduanxuan[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
void delay(u16 i)
{
while(i--);
}
void KeyDown()
{
GPIO_KEY=0x0f;//先给高四位低电平,低四位高电平,根据低四位哪一位不是高电平来判断是哪一列
if(GPIO_KEY!=0x0f)
{
delay(1000);//消抖
if(GPIO_KEY!=0x0f)
{
GPIO_KEY=0x0f;//重新赋值
switch(GPIO_KEY)
{
case 0x07: KeyValue=0;break;
case 0x0b: KeyValue=1;break;
case 0x0d: KeyValue=2;break;
case 0x0e: KeyValue=3;break;
}//记下列数,0123
GPIO_KEY=0xf0;//再给高四位高电平,低四位电平,根据高四位哪一位不是高电平来判断是哪一行
switch(GPIO_KEY)
{
case 0x70: KeyValue=KeyValue;break;
case 0xb0: KeyValue=KeyValue+4;break;
case 0xd0: KeyValue=KeyValue+8;break;
case 0xe0: KeyValue=KeyValue+12;break;
}//记下行数,+0+4+8+12
while((a<50)&&(GPIO_KEY!=0xf0))
{
delay(1000);
a++;
}//程序跳出循环的条件是,松手或者按下足够一段时间(避免CPU的持续占用)
}
}
}
void main()
{
LSA=0;
LSB=0;
LSC=0;//选择静态数码管显示
while(1)
{
KeyDown();
GPIO_DIG=smgduanxuan[KeyValue];//给静态数码管一个显示的值
}
}
#可以通过修改KeyValuede的赋值来实现纵向。
???如何测试出松手检测的效果
???使用矩阵按键时蜂鸣器同时会发出响声,具体分析原因
谨记程序编写要严谨,避免因为程序输入的错误而浪费时间,本次编写过程出现了#define结束末尾加了分号,导致程序一直报错!!!