/
矩阵按键实验
实现现象:下载程序后数码管显示0,按下矩阵按键上的按键显示对应的数字
S1-S4:0-3
S5-S8:4-7
S9-S12:8-B
S13-S16:C-F。
注意事项:如果不想让点阵模块显示,可以将74HC595模块上的JP595短接片拔掉。
/
#include "reg52h" //此文件中定义了单片机的一些特殊功能寄存器
typedef unsigned int u16; //对数据类型进行声明定义
typedef unsigned char u8;
#define GPIO_DIG P0
#define GPIO_KEY P1
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
u8 KeyValue; //用来存放读取到的键值
u8 code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//显示0~F的值
/
函 数 名 : delay
函数功能 : 延时函数,i=1时,大约延时10us
/
void delay(u16 i)
{
while(i--);
}
/
函 数 名 : KeyDown
函数功能 : 检测有按键按下并读取键值
输 入 : 无
输 出 : 无
/
void KeyDown(void)
{
char a=0;
GPIO_KEY=0x0f;
if(GPIO_KEY!=0x0f)//读取按键是否按下
{
delay(1000);//延时10ms进行消抖
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;
}
//测试行
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;
}
while((a<50)&&(GPIO_KEY!=0xf0)) //检测按键松手检测
{
delay(1000);
a++;
}
}
}
}
/
函 数 名 : main
函数功能 : 主函数
输 入 : 无
输 出 : 无
/
void main()
{
LSA=0; //给一个数码管提供位选
LSB=0;
LSC=0;
while(1)
{
KeyDown(); //按键判断函数
GPIO_DIG=smgduan[KeyValue]; //
}
}
矩阵键盘最好在IO口跟IO口之间加一个小电阻
数码管不亮很有可能是按键检测的时候进行了延时,延时时间过长导致数码管不亮。或者存在检测按下或松手的语句,导致一直在处于检测按键的状况
矩阵键盘可以参考下面的代码
获取一次按键扫描的值 ,如果是255代表没有按键按下,否则返回按键的值。
#define KEY P3#define K1 P3_4
#define K2 P3_5
#define K3 P3_6
#define K4 P3_7
unsigned char GetKey(void)
{
KEY=0xff;
K1=0;
swithc(KEY&0x0f)
{
case 0x0E:return 0;
case 0x0D:return 1;
case 0x0B:return 2;
case 0x07:return 3;
}
KEY=0xff;
K2=0;
swithc(KEY&0x0f)
{
case 0x0E:return 4;
case 0x0D:return 5;
case 0x0B:return 6;
case 0x07:return 7;
}
KEY=0xff;
K3=0;
swithc(KEY&0x0f)
{
case 0x0E:return 8;
case 0x0D:return 9;
case 0x0B:return 10;
case 0x07:return 11;
}
KEY=0xff;
K4=0;
swithc(KEY&0x0f)
{
case 0x0E:return 12;
case 0x0D:return 13;
case 0x0B:return 14;
case 0x07:return 15;
}
return 255;
}
放在整个程序的循环中 只要检测到按键做相应的动作即可。
如果要用到延时的地方
可以把显示函数当做延时函数来用,或者把显示函数放到中断里面。
这样都不会影响到正常的显示。
用按键等待程序 ,把第二次判断有无按键按下的if语句变为
while(P1!=0xf0); //若按键一直处于按下状态,则等待按键释放 ;若按键释放,则往下执行
Key_Value = Keyscan();
SBUF=Key_Value;
这样,把主循环while(1)变为
while(1)
{
P1 = 0xf0;
if(P1 != 0xf0) //判断有无按键按下
{
Delay_1ms(20); //按键消抖
while(P1!=0xf0); //若按键一直处于按下状态,则等待按键释放 ;若按键释放,则往下 执行
Key_Value = Keyscan();
SBUF=Key_Value;
}
}
但看了你的程序 , 虽然不知道你的按键扫描程序keyscan()写的怎么样,但是按照一般思路,按键消抖都在按键扫描程序里面,你这里把按键扫描程序
Key_Value = Keyscan();
SBUF=Key_Value;
放在目标执行程序位置,结构上感觉冗余了,希望能帮到你!
可以啊,可以根据按键时间的长短,和高低电平来实现。比如,长按1s为高电平是一个功能,长按2s是另一个功能。 步骤为:先读取某个io口的值,若为高电平(if 按键高电平有效),则延时1s,最后再读取一次该io口的值,若继续为高电平,则调用你要的功能即可。
以上就是关于求助程序:51单片机矩阵键盘是否按下检测程序全部的内容,包括:求助程序:51单片机矩阵键盘是否按下检测程序、用STC12C5A60S2单片机做矩阵键盘、请问如何用单片机 获取矩阵键盘各按键的按下与松开的状态等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)