单片机键盘扫描程序
电路图是这样的。。请问键盘扫描程序应该怎么写啊??书上写的键盘扫描程序没看懂,谁帮我解释一下也可以啊。。程序如下(书上的图是4*4行列式键盘,部分程序省略)ucharco...
电路图是这样的。。请问键盘扫描程序应该怎么写啊??书上写的键盘扫描程序没看懂,谁帮我解释一下也可以啊。。程序如下(书上的图是4*4行列式键盘,部分程序省略)
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++)
{
P1=act[i];
delay(10);
in=P1;
in=in>>4;
in=in|0xf0;
for(j=0;j<4;j++)
{
if(act[j]==in)
{
find=1;
inj=j;ini=i;
}
}
}
if(find==0)return-1;
return(ini*4+inj);
}
这段程序没看懂什么意思,求解释
急急急急急!在线等。。。 展开
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++)
{
P1=act[i];
delay(10);
in=P1;
in=in>>4;
in=in|0xf0;
for(j=0;j<4;j++)
{
if(act[j]==in)
{
find=1;
inj=j;ini=i;
}
}
}
if(find==0)return-1;
return(ini*4+inj);
}
这段程序没看懂什么意思,求解释
急急急急急!在线等。。。 展开
6个回答
展开全部
2*3的键盘,太简单了,不值得用循环,特别是双重循环。
最简明、高效的程序如下:
sbit P10 = P1^0;
sbit P11 = P1^1;
sbit P12 = P1^2;
sbit P13 = P1^3;
sbit P14 = P1^4;
char scan_key(void)
{
P13 = 0;
if (!P10) return 0;
if (!P11) return 1;
if (!P12) return 2;
P13 = 1;
P14 = 0;
if (!P10) return 3;
if (!P11) return 4;
if (!P12) return 5;
}
本程序,使用的变量最少,也不涉及其它接口。
代码最少,执行效率最高。
最简明、高效的程序如下:
sbit P10 = P1^0;
sbit P11 = P1^1;
sbit P12 = P1^2;
sbit P13 = P1^3;
sbit P14 = P1^4;
char scan_key(void)
{
P13 = 0;
if (!P10) return 0;
if (!P11) return 1;
if (!P12) return 2;
P13 = 1;
P14 = 0;
if (!P10) return 3;
if (!P11) return 4;
if (!P12) return 5;
}
本程序,使用的变量最少,也不涉及其它接口。
代码最少,执行效率最高。
展开全部
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键盘)
追问
我P1.6,P1.7还有接有蜂鸣器,二极管。。。所以如果针对P1口扫描的话会影响别的电路的。。。所以不知道怎么改了。。。麻烦您根据我上面的图改下这段程序行么?谢谢
追答
你的 P2和P3有占用吗 没得话最简单的方法就是用P2,P3, 还有你要几个按键的 我现在只能给你理论的代码 没办法做实验 你hi下我 加下我Q 我晚点试试
char scan_key(void)
{
uchar i,j,in,ini,inj;
bit find=0;
P1.0=1;P1.1=1;P1.2=1;
P1.3=1;P1.4=1;P1.5=1;
p1.0=0;
delay(10);
if(p1.3==0)
{i=0;j=0;find=1;}
else if(p1.4==0)
{i=0;j=1;find=1;}
else if(p1.5==0)
{i=0;j=2;find=1;}
p1.0=1;p1.1=0;
delay(10);
if(p1.3==0)
{i=0;j=0;find=1;}
else if(p1.4==0)
{i=0;j=1;find=1;}
else if(p1.5==0)
{i=0;j=2;find=1;}
p1.1=1;p1.2=0;
delay(10);
if(p1.3==0)
{i=0;j=0;find=1;}
else if(p1.4==0)
{i=0;j=1;find=1;}
else if(p1.5==0)
{i=0;j=2;find=1;}
p1.2=1;
if(find==0)return-1;
return(i*3+j);
}
0 1 2 p1.0 6口9键 多接没事 鉴于你其他口有它用 我就不用数组循环了 你调试看看
3 4 5 p1. 2 有问题hi我 追问我
6 7 8 p1.3
p3 4 5
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
这书上的键盘扫描代码 本身就不是个高效代码。
键盘扫描基本的思路为,将整个键盘看作一个整体,用变量来存储其每个按键的状态,一个按键对应1bit。
例如:如果有8个按键 就设个unsigned char 的变量来存储其状态,
变量需设置3个,
一个为当前按键状态(定名cur) (全局变量)
一个用于第1次扫描按键(定名A)(临时变量)
一个用于去抖后扫描按键(定名B)(临时变量)
先取A,比较A、cur 是否相同,相同则说明按键无变化,退出按键扫描
否则延时10ms去抖,取B,比较A、B是否相同,
相同则按键变化有效,cur=A;执行按键变化处理代码。否则是按键误触发,退出按键扫描。
当然这是基本思路,代码延时还可优化,涉及定时器,说起来就多了。
键盘扫描基本的思路为,将整个键盘看作一个整体,用变量来存储其每个按键的状态,一个按键对应1bit。
例如:如果有8个按键 就设个unsigned char 的变量来存储其状态,
变量需设置3个,
一个为当前按键状态(定名cur) (全局变量)
一个用于第1次扫描按键(定名A)(临时变量)
一个用于去抖后扫描按键(定名B)(临时变量)
先取A,比较A、cur 是否相同,相同则说明按键无变化,退出按键扫描
否则延时10ms去抖,取B,比较A、B是否相同,
相同则按键变化有效,cur=A;执行按键变化处理代码。否则是按键误触发,退出按键扫描。
当然这是基本思路,代码延时还可优化,涉及定时器,说起来就多了。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
按照你图示的接线方法,你这个程序至少是4列的键盘。如果想改成你图示的键盘用的程序,我写一个吧,没调试可能有问题。尽量用你示例程序的风格。
uchar code act[3]={0xfe,0xfd,0xfb};
char scan_key(void)
{
uchar i,j,in,ini,inj;
bit find=0;
for(i=0;i<3;i++)
{
P1=act[i];
delay(10);
in=P1;
in=in>>3;
in=in|0xfc;
for(j=0;j<2;j++)
{
if(act[j]==in)
{
find=1;
inj=j;ini=i;
}
}
}
if(find==0)return-1;
return(ini*4+inj);
}
uchar code act[3]={0xfe,0xfd,0xfb};
char scan_key(void)
{
uchar i,j,in,ini,inj;
bit find=0;
for(i=0;i<3;i++)
{
P1=act[i];
delay(10);
in=P1;
in=in>>3;
in=in|0xfc;
for(j=0;j<2;j++)
{
if(act[j]==in)
{
find=1;
inj=j;ini=i;
}
}
}
if(find==0)return-1;
return(ini*4+inj);
}
追问
能加一下注释么?右移那段没看懂什么意思
追答
我看有人给了详细的解释了,就不多说了。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
单片机键盘扫描程序 简单的仿真实例,供参考
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询