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;
}
/*
函数功用:按键功用处理函数
在该函数中,收到按键后,就把相关的键值经过LCD1602显现;
并经过串口显现: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() interrupt 1
{
static unsigned char i;
TH0=(65536-TH0_NUM)/256;
TL0=(65536-TL0_NUM)%256;
i++;
if(i>2)
{
i=0;
Flag2Ms=1;
}
}
声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/xinpin/chanpin/267013.html