单片机键盘扫描C程序
本人是个菜鸟。刚刚开始学习单片机,不会做独立键盘的扫描程序。请高手指点,具体要求是:P2_0~3用做键盘。一个是“设置”、“加”、“减”、“移位”不知道用C怎么些。请高手...
本人是个菜鸟。刚刚开始学习单片机,不会做独立键盘的扫描程序。请高手指点,具体要求是:P2_0~3用做键盘。一个是“设置”、“加”、“减”、“移位”不知道用C 怎么些。请高手帮忙!
回答我加分 展开
回答我加分 展开
展开全部
#include<reg51.h>
#define uint unsigned int
#define uchar unsigned char
void delay(uint z);
sbit LE=P1^4;
uchar code table[]={
0xfc,0x60,0xda,0xf2,
0x66,0xb6,0xbe,0xe0,
0xfe,0xf6,0xee,0x3e,
0x9c,0x7a,0x9e,0x8e
};
void main()
{
uchar temp;
uint num;
while(1)
{
P2=0xfe; //按键扫描第一行
temp=P2;
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(10); //消抖
temp=P2;
temp=temp&0xf0;
while(temp!=0xf0) //再次确认是否有键按下
{
temp=P2;
switch(temp)
{
case 0xee:num=0;break;
case 0xde:num=1;break;
case 0xbe:num=2;break;
case 0x7e:num=3;break;
}
while(temp!=0xf0) //松手检测
{
temp=P2;
temp=temp&0xf0;
}
delay(10); //消抖
LE=1;
P0=table[num];
LE=0;
P1=0x0f;
}
}
P2=0xfd; //按键扫描第二行
temp=P2;
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(10);
temp=P2;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P2;
switch(temp)
{
case 0xed:num=4;break;
case 0xdd:num=5;break;
case 0xbd:num=6;break;
case 0x7d:num=7;break;
}
while(temp!=0xf0)
{
temp=P2;
temp=temp&0xf0;
}
delay(10);
LE=1;
P0=table[num];
LE=0;
P1=0x0f;
}
}
P2=0xfb; //按键扫描第三行
temp=P2;
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(10);
temp=P2;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P2;
switch(temp)
{
case 0xeb:num=8;break;
case 0xdb:num=9;break;
case 0xbb:num=10;break;
case 0x7b:num=11;break;
}
while(temp!=0xf0)
{
temp=P2;
temp=temp&0xf0;
}
delay(10);
LE=1;
P0=table[num];
LE=0;
P1=0x0f;
}
}
P2=0xf7; //按键扫描第四行
temp=P2;
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(10);
temp=P2;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P2;
switch(temp)
{
case 0xe7:num=12;break;
case 0xd7:num=13;break;
case 0xb7:num=14;break;
case 0x77:num=15;break;
}
while(temp!=0xf0)
{
temp=P2;
temp=temp&0xf0;
}
delay(10);
LE=1;
P0=table[num];
LE=0;
P1=0x0f;
}
}
}
}
void delay(uint z) //延时子函数
{
uint x;
for(z;z>0;z--)
for(x=1000;x>0;x--);
}
展开全部
uchar code act[4]={0xfe,0xfd,0xfb,0xf7};
char scan_key(void)
{
uchar i,j,in,ini,inj;
bit find=0;
for(i=0;i<4;i++)
{ //额 ,先给你解释下4*4
P1=act[i]; //开通读取,并输出高电平
delay(10); //延时
in=P1; //读取单片机值并赋值给in,四种情况4个按键,
in=in>>4; //右移四位,去掉低位
in=in|0xf0; //位或运算,高四位补1,
for(j=0;j<4;j++)
{
if(act[j]==in) //判断具体哪个按键
{
find=1;
inj=j;ini=i;
}
}
}
if(find==0)return-1; //返回值 -1,return 1是正常返回,return -1是非正常返回 程序写法标准而已,即没按键
return(ini*4+inj); //i是判断高四位,j判断低4位
}
0 1 2 3 p1.0 p1.0为零 可判断0,1,2,3 如果开关0导通 p4即为0,即为1110 1110
4 5 6 7 p1.1 右移补1,得 1111 1110,及j为0
8 9 a b p1.2 开关1导通 p5为0, 即 1101 1110, 右移补1111 1101
c d e f p1.3 可判断j为1 同理可类推
p4 5 6 7
按这种思路4个端口只能实现4个开关4*4=16,2*2=4 得换思路,如果是因为端口紧张的话,可以用P3口,或者采用分压读取AD判断按键(AD键盘)
char scan_key(void)
{
uchar i,j,in,ini,inj;
bit find=0;
for(i=0;i<4;i++)
{ //额 ,先给你解释下4*4
P1=act[i]; //开通读取,并输出高电平
delay(10); //延时
in=P1; //读取单片机值并赋值给in,四种情况4个按键,
in=in>>4; //右移四位,去掉低位
in=in|0xf0; //位或运算,高四位补1,
for(j=0;j<4;j++)
{
if(act[j]==in) //判断具体哪个按键
{
find=1;
inj=j;ini=i;
}
}
}
if(find==0)return-1; //返回值 -1,return 1是正常返回,return -1是非正常返回 程序写法标准而已,即没按键
return(ini*4+inj); //i是判断高四位,j判断低4位
}
0 1 2 3 p1.0 p1.0为零 可判断0,1,2,3 如果开关0导通 p4即为0,即为1110 1110
4 5 6 7 p1.1 右移补1,得 1111 1110,及j为0
8 9 a b p1.2 开关1导通 p5为0, 即 1101 1110, 右移补1111 1101
c d e f p1.3 可判断j为1 同理可类推
p4 5 6 7
按这种思路4个端口只能实现4个开关4*4=16,2*2=4 得换思路,如果是因为端口紧张的话,可以用P3口,或者采用分压读取AD判断按键(AD键盘)
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
键盘部分发个截图吧,蚊子描述不太好理解。
键盘程序与硬件的链接有挺大关系的。
键盘程序与硬件的链接有挺大关系的。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
什么系列的单片机,有P4口?
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
呵呵
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询