首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 嵌入开发 > 单片机 >

矩阵键盘,依据按下的是几行几列的键,然后用动态扫描的数码管方法显示行列。但是只要按下第一行的键之后第一行的所有键就没反应了,其他几行的就都还可以

2013-04-20 
矩阵键盘,根据按下的是几行几列的键,然后用动态扫描的数码管方法显示行列。但是只要按下第一行的键之后第一

矩阵键盘,根据按下的是几行几列的键,然后用动态扫描的数码管方法显示行列。但是只要按下第一行的键之后第一行的所有键就没反应了,其他几行的就都还可以
这个是源程序
#include <reg51.h>//头文件
#define uchar unsigned char//宏定义
#define uint unsigned int //宏定义
#define keyport P3//行列式键盘扫描口
sbit duansc=P1^1;//段锁存
sbit weisc=P1^0;//位锁存
uchar code duanma[17]={0x3F,0x06,0x5B,0x4F,0x66,0x6D, 0x7D, 0x07, 0x7F,0x6F,0x67,0x7C,0x39,0x5E,0x7B,0x71};
//共阴数码管0~f的断码
uchar code weima[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//位码,分别为第1~8位数码管
uchar tempduan[2];//用来存行列数的数组
uchar temp,num,row,line,flag;// temp为中间变量,num为那个键按下的标志,后边两个为行列,flag为标志位,用于判断是否有键按下了
void display(uchar ,uchar);//显示函数,第一个变量是指从第几位开始显示,第二个是指显示几个数
uchar scan();//键盘扫描函数
void delayms(uchar t);//延时t毫秒
void main()
{
//没有键按下时,什么都不显示
P0=0xff;//八个显示器都关闭
weisc=1;
weisc=0;

while(1)
{
num=scan();
if(flag!=0)
{
row=num/4+1;
line=num%4+1;
tempduan[0]=duanma[row];
tempduan[1]=duanma[line];
display(1,2);
}
}
}
uchar scan()//按键扫描函数
{
keyport=0xfe;//检测第一行
temp=keyport&0xf0;//与运算
if(temp!=0xf0)
{
delayms(10);//消抖
temp=keyport&0xf0;
if(temp!=0xf0)//确实有键按下
{
flag=1;//有键按下了
temp=keyport;//此时temp已经变化了,重新读回来
switch(temp)
{
case 0x7e:num=0;break;//第一个按键按下
case 0xbe:num=1;break;//二
case 0xde:num=2;break;//三
case 0xee:num=3;break;//四
}
}
while(temp!=0xfe)
temp=keyport;//最后消抖,如果放开按键后,则keyport=0xfe,此时temp=0xfe,判断条件为真,所以退出循环。
return num;//返回num值,退出程序
}

keyport=0xfd;//检测第二行
temp=keyport&0xf0;//与运算
if(temp!=0xf0)
{
delayms(10);//消抖
temp=keyport&0xf0;
if(temp!=0xf0)//确实有键按下
{
flag=1;//有键按下了
temp=keyport;//此时temp已经变化了,重新读回来
switch(temp)
{
case 0x7d:num=4;break;//第五个按键按下
case 0xbd:num=5;break;//六
case 0xdd:num=6;break;//七
case 0xed:num=7;break;//八
}
}
while(temp!=0xfd)
temp=keyport;//最后消抖,如果放开按键后,则keyport=0xfe,此时temp=0xfe,判断条件为真,所以退出循环。
return num;//返回num值,退出程序
}

keyport=0xfb;//检测第三行
temp=keyport&0xf0;//与运算
if(temp!=0xf0)
{
delayms(10);//消抖
temp&0xf0;
if(temp!=0xf0)//确实有键按下
{
flag=1;//有键按下了
temp=keyport;//此时temp已经变化了,重新读回来
switch(temp)
{
case 0x7b:num=8;break;//第九个按键按下
case 0xbb:num=9;break;//十
case 0xdb:num=10;break;//十一
case 0xeb:num=11;break;//十二
}
}
while(temp!=0xfb)
temp=keyport;//最后消抖,如果放开按键后,则keyport=0xfe,此时temp=0xfe,判断条件为真,所以退出循环。
return num;//返回num值,退出程序
}

keyport=0xf7;//检测第四行
temp=keyport&0xf0;//与运算
if(temp!=0xf0)
{
delayms(10);//消抖
temp=keyport&0xf0;
if(temp!=0xf0)//确实有键按下
{
flag=1;//有键按下了
temp=keyport;//此时temp已经变化了,重新读回来
switch(temp)
{
case 0x77:num=12;break;//第十三个按键按下
case 0xb7:num=13;break;//十四
case 0xd7:num=14;break;//十五
case 0xe7:num=15;break;//十六
}
}
while(temp!=0xf7)
temp=keyport;//最后消抖,如果放开按键后,则keyport=0xfe,此时temp=0xfe,判断条件为真,所以退出循环。
return num;//返回num值,退出程序
}
return num;//这个语句可以保持前一个键

}
void delayms(uchar t)
{
uchar i;
for(i=0;i<t;i++)//t个一毫秒
{
uint x=490;
while(--x);//延时一毫秒
}
}
void display(uchar beginnum,uchar hmanynum)//下面程序中的beginnum是从1开始计算的,要注意


{
uchar i;
for(i=0;i<hmanynum;i++)
{
P0=0x00;
duansc=1;
duansc=0;//清除段码,防止交替重影

P0=weima[beginnum+i-1];//位码
weisc=1;
weisc=0;

P0=tempduan[i];//段码
duansc=1;
duansc=0;
delayms(1);
}
}
相关电路图
矩阵键盘,依据按下的是几行几列的键,然后用动态扫描的数码管方法显示行列。但是只要按下第一行的键之后第一行的所有键就没反应了,其他几行的就都还可以
矩阵键盘,依据按下的是几行几列的键,然后用动态扫描的数码管方法显示行列。但是只要按下第一行的键之后第一行的所有键就没反应了,其他几行的就都还可以
根据按下的是几行几列的键,然后用动态扫描的数码管显示行列数,但是这里只要按下第一行的键之后第一行的所有键就没反应了,就是只要按下第一行的一个键,再去按第一行的键,就没反应了,不过第一下有反应,求高手解答。
上图是执行delay之前的截图,注意看PC指针和左边的SEC值。
矩阵键盘,依据按下的是几行几列的键,然后用动态扫描的数码管方法显示行列。但是只要按下第一行的键之后第一行的所有键就没反应了,其他几行的就都还可以
上图是执行delay之后的截图,注意看PC指针和左边的SEC值。
这样的话你还要把delay函数里面改一下。
void delay(unsigned int z)
{
unsigned int y=0,x=0;
for(;x<110;x++)
for(;y<z;y++)
;
}
这个函数每执行1次的时间大概是1ms。
    

热点排行