键盘(也就是按键)分为独立键盘和矩阵键盘:
1.独立键盘:一端接地GND或接高电平VCC,然后另外一端与单片机的某个IO口连接,通过检测IO口的电平高低就可以检测到该按键是否被按下。
2.矩阵键盘:优点是节省单片机的IO口,有逐行或逐列扫描法,还有行列反转法。
注意问题:注意延时消抖和按键的释放。
/***程序:独立键盘1***/
/***作者:爱因斯尼@SCUT***/
/***时间:2010.07.23***/
/***必要的头文件和宏定义***/
#include<reg52.h>//51单片机的头文件
#define uint unsigned int//两个常用的宏定义
#define uchar unsigned char
sbit duan=P1^5;//定义段选端
sbit wei=P1^6;//定义位选端
sbit key=P3^2;//定义独立按键,也就是外部中断0
uchar value=0;//用来计算按键值
/***数码管字模,放在程序的代码区***/
uchar code SMG[]={
0xfc,0x60,0xda,0xf2,//0,1,2,3,
0x66,0xb6,0xbe,0xe0, //4,5,6,7,
0xfe,0xf6,0xee,0x3e, //8,9,A,b,
0x9c,0x7a,0x9e,0x8E,0x01};//C,d,E,F
/*********带形参的延时子函数***************/
void delay_ms(uint ms)
{
uint i,j;
for(i=0;i<ms;i++)
for(j=0;j<141;j++);
}
void delay(uint ms)
{
uint i,j;
for(i=0;i<ms;i++)
for(j=0;j<1141;j++);
}
/*********数码管的初始化函数***************/
void Init_smg()
{
P0=0x00;
duan=1;
P0=0x00;//关段选端
duan=0;
P0=0xff;
wei=1;
P0=0xff;//关位选端
wei=0;
lie=1;
P0=0xff;//点阵全灭
lie=0;
}
/****带两个形参的数码管显示子函数****/
void show_smg(uchar num,uchar awei)
{
uchar A=0x80;//这个主要是为了后面的循环移位
P0=0x00;
duan=1; //开段选端
P0=SMG[num];//送段选
duan=0; //关段选端
P0=0xff;
wei=1; //开位选端
P0=~(A>>awei);//送位选
wei=0; //关位选端
delay_ms(1); //稍微延时一下,防止残影
}
/***带返回值的函数***/
uchar scan_key()
{
if(key==0)
{
delay(8);//延时消抖
if(key==0)//再次判断是否还是按下按键
{while(key==0);//一直按下按键的话,什么也不做
if(value<15)value++;
else value=0;
}
}
return value;
}
/*****主函数******/
void main()
{uchar i;
Init_smg();
while(1)
{i=scan_key();
show_smg(i,0);
}
}
/***程序:独立键盘2***/
/***作者:爱因斯尼@SCUT***/
/***时间:2010.07.23***/
/***必要的头文件和宏定义***/
#include<reg52.h>//51单片机的头文件
#define uint unsigned int//两个常用的宏定义
#define uchar unsigned char
sbit duan=P1^5;//定义段选端
sbit wei=P1^6;//定义位选端
sbit key=P2^0;//定义独立按键,也就是外部中断0
uchar value=0;//用来计算按键按下的次数
uchar code SMG[]={//数码管字模,放在程序的代码区
0xfc,0x60,0xda,0xf2,//0,1,2,3,
0x66,0xb6,0xbe,0xe0, //4,5,6,7,
0xfe,0xf6,0xee,0x3e, //8,9,A,b,
0x9c,0x7a,0x9e,0x8E,0x01};//C,d,E,F
/////////////////////////////
void delay_ms(uint ms)
{
uint i,j;
for(i=0;i<ms;i++)
for(j=0;j<141;j++);
}
void delay(uint ms)
{
uint i,j;
for(i=0;i<ms;i++)
for(j=0;j<1141;j++);
}
////////////////////////////////////////////
void Init_smg()//数码管的初始化函数,一开始让数码管什么也不显示
{
P0=0x00;
duan=1;
P0=0x00;
duan=0;
P0=0xff;
wei=1;
P0=0xff;
wei=0;
}
///////////////////////数码管的显示子函数
void show_smg(uchar num,uchar awei)//带两个形参的数码管显示函数
{
uchar A=0x80;//这个主要是为了后面的循环移位
P0=0x00;
duan=1;
P0=SMG[num];
duan=0;
P0=0xff;
wei=1;
P0=~(A>>awei);
wei=0;
delay_ms(1);
}
///////////////////////////带返回值的子函数
uchar scan_key()
{if(key==0)//判断按键是否按下
{
delay(8);//延时消抖
if(key==0)//再次判断是否按下
{while(key==0); //按键释放
if(value<15)value++;
else value=0;
}
}
return value;
}
/////////////////////
void main()
{P2=0x0f;
Init_smg();
while(1)
{
show_smg(scan_key(),0);
}
}
/***程序:矩阵键盘***/
/***作者:爱因斯尼@SCUT***/
/***时间:2010.07.23***/
/***必要的头文件和宏定义***/
#include<reg52.h>//51单片机的头文件
#define uint unsigned int//两个常用的宏定义
#define uchar unsigned char
sbit duan=P1^5;//定义段选端
sbit wei=P1^6;//定义位选端
/***数码管字模,放在程序的代码区***/
uchar code SMG[]={
0xfc,0x60,0xda,0xf2,//0,1,2,3,
0x66,0xb6,0xbe,0xe0, //4,5,6,7,
0xfe,0xf6,0xee,0x3e, //8,9,A,b,
0x9c,0x7a,0x9e,0x8E,0x01};//C,d,E,F
/*********带形参的延时子函数***************/
void delay_ms(uint ms)//毫秒级别
{uint i,j;
for(i=0;i<ms;i++)
for(j=0;j<141;j++);
}
/*********带形参的延时子函数***************/
void delay(uint m)
{uint i,j;
for(i=0;i<m;i++)
for(j=0;j<1148;j++); }
/*********数码管的初始化函数***************/
void Init_smg()
{
P0=0x00;
duan=1;
P0=0x00;//关段选端
duan=0;
P0=0xff;
wei=1;
P0=0xff;//关位选端
wei=0;
lie=1;
P0=0xff;//点阵全灭
lie=0;
}
/****带两个形参的数码管显示子函数****/
void show_smg(uchar num,uchar awei)
{
uchar A=0x80;//这个主要是为了后面的循环移位
P0=0x00;
duan=1; //开段选端
P0=SMG[num];//送段选
duan=0; //关段选端
P0=0xff;
wei=1; //开位选端
P0=~(A>>awei);//送位选
wei=0; //关位选端
delay_ms(1); //稍微延时一下,防止残影
}
/***带返回值的键盘扫描函数***、
uchar scan_matkey()
{
uchar key,pin;
P2=0xfe;//第一行扫描
pin=P2;//把P2口的电平状态读进来
pin&=0xf0;//判断高四位是否全部为1
while(pin!=0xf0)//初次判断有按键按下
{
delay(2);
pin=P2;//把P2口的电平状态读进来
pin&=0xf0;//判断高四位是否全部为1
while(pin!=0xf0)//再次判断有按键按下
{
pin=P2;//最后再把P2口读进来
switch(pin)
{
case 0xee:key=1;break;
case 0xde:key=2;break;
case 0xbe:key=3;break;
case 0x7e:key=4;break;
default:key=0;
}
while(pin!=0xf0)//是否释放按键
{
pin=P2;
pin&=0xf0;}
}}
P2=0xfd;//第二行扫描
pin=P2;//把P2口的电平状态读进来
pin&=0xf0;//判断高四位是否全部为1
while(pin!=0xf0)//初次判断有按键按下
{
delay(2);
pin=P2;//把P2口的电平状态读进来
pin&=0xf0;//判断高四位是否全部为1
while(pin!=0xf0)//再次判断有按键按下
{
pin=P2;//最后再把P2口读进来
switch(pin)
{
case 0xed:key=5;break;
case 0xdd:key=6;break;
case 0xbd:key=7;break;
case 0x7d:key=8;break;
default:key=0;
}
while(pin!=0xf0)//是否释放按键
{
pin=P2;
pin&=0xf0;}
}}
P2=0xfb;//第三行扫描
pin=P2;//把P2口的电平状态读进来
pin&=0xf0;//判断高四位是否全部为1
while(pin!=0xf0)//初次判断有按键按下
{
delay(2);
pin=P2;//把P2口的电平状态读进来
pin&=0xf0;//判断高四位是否全部为1
while(pin!=0xf0)//再次判断有按键按下
{
pin=P2;//最后再把P2口读进来
switch(pin)
{
case 0xeb:key=9;break;
case 0xdb:key=10;break;
case 0xbb:key=11;break;
case 0x7b:key=12;break;
default:key=0;
}
while(pin!=0xf0)//是否释放按键
{
pin=P2;
pin&=0xf0;}
}}
P2=0xf7;//第四行扫描
pin=P2;//把P2口的电平状态读进来
pin&=0xf0;//判断高四位是否全部为1
while(pin!=0xf0)//初次判断有按键按下
{
delay(2);
pin=P2;//把P2口的电平状态读进来
pin&=0xf0;//判断高四位是否全部为1
while(pin!=0xf0)//再次判断有按键按下
{
pin=P2;//最后再把P2口读进来
switch(pin)
{
case 0xe7:key=13;break;
case 0xd7:key=14;break;
case 0xb7:key=15;break;
case 0x77:key=16;break;
default:key=0;
}
while(pin!=0xf0)//是否释放按键
{
pin=P2;
pin&=0xf0;}
}}
return key-1;
}
/*****主函数******/
void main()
{Init_smg();
while(1)
{
show_smg(scan_matkey(),0);
}
}
欢迎光临我们的淘宝网店:http://item.taobao.com/auction/item_detail.htm?item_num_id=9447334857
文章评论(0条评论)
登录后参与讨论