#include <intrins.h>
sbit SPK=P3^4 //SPK定义为P3口的第4位,就是驱动蜂鸣器的那个脚
sbit JDQ=P3^5 //JDQ定义为P3口的第5位,就是驱动继电器的那个脚
code unsigned char table[]=
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
0x77,0x7c,0x39,0x5e,0x79,0x71}
//共阴数码管 0-9 a-f 表
code unsigned char key_tab[17]={0xed,0x7e,0x7d,0x7b,
0xbe,0xbd,0xbb,0xde,
0xdd,0xdb,0x77,0xb7,
0xee,0xd7,0xeb,0xe7,0XFF}//========================此数组为键盘编码,
//本人采用类式类似电话按键的编码方式,方便以后设计
// 1 2 3 a 0x01 0x02 0x03 0x0a
// 4 5 6 b 对应16进制码: 0x04 0x05 0x06 0x0b
// 7 8 9 d 0x07 0x08 0x09 0x0d
// * 0 # f 0x0c 0x00 0x0e 0x0f
//打个比方,如果你按下0键,P0口读到数据为0xed
//如果你按下2键,P0口读到数据为0x7d,按下9键为0xdb,
//我们将读到的P0口数据经过查表法就能得到相应的16进制码
//键盘的读取,我们采用分时扫描
unsigned char l_tmpdate[8]={0,0,0,0,0,0,0,0}//定义数组变量
unsigned char l_key=0x0 //定义变量,存放键值
unsigned char l_keyold=0xFF //做为按键松开否的凭证
void ReadKey(void) //扫描键盘 获取键值
void delay()//延时子函数,5个空指令
void display(unsigned char *lp,unsigned char lc)//数字的显示函数;lp为指向数组的地址,lc为显示的个数
//这个函数在第二节用过不用再说了吧!
void main(void) //入口函数
{
while(1){
ReadKey() //调用键盘扫描
display(&l_key,1) //输出显示获取的键值码
if(l_key==0x0e) //这里我们检测是否按了0x0e键,
JDQ=0 //是,我们就驱动继电器打开
if(l_key==0x0c) //闭毁检测是否按下了0x0c键,
JDQ=1 //是,我们就驱动继电器断开
}
}
void ReadKey(void) //读键盘值
{
unsigned char i,j,key
//分三个部份来理解,
//第一部份,用扫描来读取键盘,
j=0xfe
key=0xff //设定初值
for (i=0i<4i++){
P0=j //乎态空P0口低4位循环输出0,扫描键盘
//leday()
if ((P0&0xf0)!=0xf0){ //如果有键按下,P0口高4位不会全为1,
key=P0 //读取P0口,退出循环,否则循环下次
break
}
j=_crol_(j,1) //此函数功能为左循环移位
}
//第二部份,检测是否干扰或按键放开
if (key==0xff){ //如果读取不到P0口的值,比如是干扰或是键盘又松开,我们做相应复位,返回
l_keyold=0xff
SPK=1 //按键有松开,停止蜂鸣器响
return
}
else
SPK=0 //打开蜂鸣器
//第三部份,检测是新按键按下,获取新的键盘编码值
if(l_keyold!=key){ //检测按键放开否,如果一样表明没放开,不做处理,不一样表时另一岁瞎个键按下做编码转换
l_keyold=key //获取键码做为放开下次的凭证
for(i=0i<17i++){ //查表获得相应的16进制值存放l_key变量中
if (key==key_tab[i]){
l_key=i
break
}
}
}
//程序运行到这里,就表明有键值被读取存放于l_key变量中,主程序就可以检测此变量做相应外理,
//此时我们回到主程序
}
void display(unsigned char *lp,unsigned char lc)//显示
{
unsigned char i //定义变量
P2=0 //端口2为输出
P1=P1&0xF8 //将P1口的前3位输出0,对应138译门输入脚,全0为第一位数码管
for(i=0i<lci++){ //循环显示
P2=table[lp[i]] //查表法得到要显示数字的数码段
delay() //延时5个空指令
if(i==7) //检测显示完8位否,完成直接退出,不让P1口再加1,否则进位影响到第四位数据
break
P2=0 //清0端口,准备显示下位
P1++ //下一位数码管
}
}
void delay(void) //空5个指令
{
_nop_()_nop_()_nop_()_nop_()_nop_()
}
1.设置一个状态变量,如flag,定义flag=0为开状态,flag=1为关状态。2.因为是按键(不是开拦扰猜关),所以实际上单片机读取的应该是脉冲形式的输入。设按键接单片机P01引脚,故可采用以下程序实现按键扫描
if(P01==0)//李茄按下按键,进入下降沿
{
delay2()//20ms延时去按键前抖动
while(P01==0)//等待上升沿到
来,即按键d起
flag=~flag//flag取反,实现状态切换
}
void
delay2()//20ms延时子程序
{
unsigned
char
i,k
for(i=0i<100i++)
for(k=0k<100k++)
}
注:根据按键的具体接法,若简型按下按键向单片机输入低电平,则采用以上程序;若按下按键向单片机输入高电平,则将两处P01==0均改为P01==1。
我给你一个我自己写的吧 有注释假设按下的是S1键进行如下检测(4*4键盘)
先在P3口输出
p3 00001111
低四位 行会有变化
cord_h =00001111&00001110 =00001110
if !=00001111
延时0.1us
cord_h=00001110&00001111=00001110
if !=00001111
P3再输出11111110
P3=00001110|11110000=11111110
输出高四位
cord_l=P3&0xf0 //此时P3口就是输入值厅裤01111110 而不是上面扮昌简的11111110
cord_l=01111110&11110000=01110000
cord_h+cord_l=00001110+01110000=01111110=0x7e //此编码即为S1的编码
#include <reg52.h>//包含头文件
#define uchar unsigned char
#define uint unsigned int
unsigned char const table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
0x77,0x7c,0x39,0x5e,0x79,0x71}//0-F
uchar keyscan(void)
void delay(uint i)
void main()
{
uchar key
P2=0x00//1数码管亮 按相应的按键,会显示按键上的迅樱字符
while(1)
{
key=keyscan()//调用键盘扫描,
switch(key)
{
case 0x7e:P0=table[0]break//0 按下相应的键显示相对应的码值
case 0x7d:P0=table[1]break//1
case 0x7b:P0=table[2]break//2
case 0x77:P0=table[3]break//3
case 0xbe:P0=table[4]break//4
case 0xbd:P0=table[5]break//5
case 0xbb:P0=table[6]break//6
case 0xb7:P0=table[7]break//7
case 0xde:P0=table[8]break//8
case 0xdd:P0=table[9]break//9
case 0xdb:P0=table[10]break//a
case 0xd7:P0=table[11]break//b
case 0xee:P0=table[12]break//c
case 0xed:P0=table[13]break//d
case 0xeb:P0=table[14]break//e
case 0xe7:P0=table[15]break//f
}
}
}
uchar keyscan(void)//键盘扫描函数,使用行列反转扫描法
{
uchar cord_h,cord_l//行列值
P3=0x0f //行线输出全为0
cord_h=P3&0x0f//读入列线值
if(cord_h!=0x0f)//先检测有无按键按下
{
delay(100) //去抖
cord_h=P3&0x0f //读入列线值
if(cord_h!=0x0f)
{
P3=cord_h|0xf0 //输出当前列线值
cord_l=P3&0xf0 //读入行线值
return(cord_h+cord_l)//键盘最后组合码值
}
}return(0xff)//返回该值
}
void delay(uint i)//延时函数
{
while(i--)
}
在P3口做的键盘
你的去抖检测没有做好
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)