新闻中心

EEPW首页>嵌入式系统>设计应用> 51单片机4X4矩阵键盘驱动与应用程序(C语言)

51单片机4X4矩阵键盘驱动与应用程序(C语言)

作者: 时间:2016-11-18 来源:网络 收藏
1、keydrive.c
#include
#include
/*
程序功能: 本程序用于测试4X4 矩阵键盘驱动;
程序算法:
每2MS检测一次按键的状态,若连续8次检测都为相同,
说明现在是一个稳定的状态,否就是干扰不与理采 ;
按键有三种状态:1、按下 2、松开 3、干扰或 抖动
其中前两种都是稳态,后一种为抖动。
接着若判断按键的状态是否改变,
若改变--》判断原来的状态是否为松开---是--说明
现在按键为按下,那么就把键值算出来;---返回0;
若改变--》判断原来的状态是否为松开---否--说明
现在按键为松开,那么就把键值返回;
*/
/*
矩阵键盘硬件引脚连接关系
*/
/*
keyin4 ----- P2^7;
keyin3 ----- P2^6;
keyin2 ----- P2^5;
keyin1 ----- P2^4;
keyout1 ----- P2^3;
keyout2 ----- P2^2;
keyout3 ----- P2^1;
keyout4 ----- P2^0;
*/
/*
定义外部变量
*/// lcd1602显示数组
unsigned char keynum[]="keynum:k ";
//键值查询数组
//k1,k2,k3,k4,k5,k6,k7,k8,
unsigned char code keytabel[]={0xe7,0xd7,0xb7,0x77,0xeb,0xdb,0xbb,0x7b,
//k9,k10,k11,k12,k13,k14,k15,k16,
0xed,0xdd,0xbd,0x7d,0xee,0xde,0xbe,0x7e};
unsigned char status1;
/*
外部函数声明
*/
extern bit Flag2Ms; //2ms到标志 键盘驱动中要用到这个外部变量
extern void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str);
/*
函数功能:N毫秒延时
*/
void DelayMs(unsigned int ms)
{
unsigned int i,j;
for(i=0;i
for(j=0;j<113;j++);
}
/*
函数功能:矩阵键盘扫描
在该函数只是判断按键的状态,即按下还是弹起;设置按键状态标置位;
算法:采用状态机的机制
*/
void keyscan()
{
static unsigned char num1,keyon_num,num2; //设置为局部静态变量
/*
num1---保存P2口状态
num2---保存次数 ,每次时间为2ms;
keyon_num----保存按下次数
*/
if(Flag2Ms==1) //2MS时间到
{
Flag2Ms=0;
num2++;
P2 = 0xf0;
num1=P2;
if(num1!=0xf0)
keyon_num++;
if(num2==8) //若连续8次检测都为同一个状态说明按键是一个稳定的状态;
{ //否则就是一个干扰,或者说是一次抖动; 时间为16MS;
num2=0;
if(keyon_num==8)
status1=1; //按键已按下
else if(keyon_num==0)
status1=0; //按键已弹起
else
status1=2; //按键无效,是干扰
keyon_num=0; // 一定要复位该值;
}
}
}
/*
函数功能:获取键值
算法: 先判断按键的状态是否改变,若改变--》判断原来的状态是否为松开---是--说明
现在按键为按下,那么就把键值算出来;---返回0;
若改变--》判断原来的状态是否为松开---否--说明
现在按键为松开,那么就把键值返回;
若按键的状态没有变化,就返回0;
*/
unsigned char getkey()
{
static unsigned char backstatus=0; //原来按键的状态,初始设为0,即松开状态;
static unsigned char temp,num3; //定义两个局部静态变量;
if((backstatus!=status1)&&(status1!=2))
{
if(backstatus==0) //若原来状态为松开,就求出键值,但返回0;
{
P2=0xf0;
num3=P2;
temp=num3;
P2 = 0x0f;
num3=P2;
temp =temp|num3;
backstatus=status1; //备份按键状态
return 0;
}
backstatus=0; //若原来状态为按下,说明现在为松开
return temp; //返回键值;
}
return 0; //若状态没有改变,则返回0;
}
/*
函数功能:按键功能处理函数
在该函数中,收到按键后,就把相关的键值通过LCD 1602显示;
并通过串口显示:keynum:kxx” xx为按k1-k16;
*/
void key_functoin(unsigned char keynum1)
{
unsigned char i;
if(keynum1!=0) //有键按下并松手
{
for(i=0;i<16;i++) // 循环查表,获取按键编号
{
if(keynum1==keytabel[i])
break;
}
keynum[8]=(i+1)/10+0x30; //把编号转换成字符放到显示数 组中;
keynum[9]=(i+1)%10+0x30;
TI=1; //把按键值发送到串口;
printf("%s",keynum); //在串口上显示“keynum:kxx” xx为按k1-k16;
while(TI!=1); //每次发送完毕,要手动清TI标志;
TI=0;
LcdShowStr(0,0,keynum); //1602显示按键编号
}
}
2、keytest.c
#include
#include
/*
程序功能: 本程序用于测试4X4矩阵键盘;
当按下按键后,在LCD1602上显示出按下的键号如:K1 K2.... K16;
同时把键值通过串口发送到口上显示;
在串口上显示“keynum:kxx” xx为按k1-k16;
程序用到的资源:1、定时器T0、T1 2、P2口 3、LCD1602 4、串行口
程序作者:王庐山
程序编制日期:2015年3月13日
地址:湖北工业职业技术学院 电子工程系电子创新中心
注意:在本程序中,把键盘相关的处理函数都写在键盘驱动中;
使用模块化编程;本程序在金沙滩开发板上测试通过。
*/
//宏定义
#define TH0_NUM 1000 //便于程序的移植;
#define TL0_NUM 1000
bit Flag2Ms; //2ms到标志
unsigned char code demo[]="key_4x4 " ;
unsigned char code demo1[]="scaning..." ;
/*
外部函数声明
*/
extern void InitLcd1602();
extern void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str);
extern void ConfigUART(unsigned int baud);
extern void DelayMs(unsigned int ms);
extern void keyscan();
extern unsigned char getkey();
extern void key_functoin(unsigned char keynum1);
//内部函数声明
void InitTimer0();
/*
主程序
*/
void main()
{
InitTimer0(); //定时0初始化
ConfigUART(9600); //串口初始化
InitLcd1602(); //1602初始化
LcdShowStr(0,0,demo); // 显示字符串
LcdShowStr(0,1,demo1); // 显示字符串
while(1)
{
keyscan(); //按键扫描
key_functoin(getkey());//根据获取的键,进行相关的处理;
}
}
/*
函数功能:定时器0初始化,设定每1MS中断一次
*/
void InitTimer0()
{
TMOD &=0xf0; //这种操作模式,不会破坏寄存器的其它设置;
TMOD |=0x01; //方式1,16位定时器
TH0/=(65536-TH0_NUM)/256;
TL0=(65536-TL0_NUM)%256;
EA=1;
ET0=1;
TR0=1;
}
/*
函数功能:定时器0中断服务程序
*/
void Timer0_Interrupt() interrupt1
{
static unsigned char i;
TH0=(65536-TH0_NUM)/256;
TL0=(65536-TL0_NUM)%256;
i++;
if(i>2)
{
i=0;
Flag2Ms=1;
}
}



关键词:51单片机矩阵键

评论


技术专区

关闭