单片机高手,帮我看看这个反转发循环扫描矩阵键盘程序,帮我详细的解释哈。
菜鸟智商太低,纸上画了N次了种感觉不对。看不懂!!#include<reg52.h>//包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义#defineuch...
菜鸟智商太低,纸上画了N次了 种感觉不对。看不懂!!
#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#define uchar unsigned char
#define uint unsigned int
unsigned char const dofly[]={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=dofly[0];break;//0 按下相应的键显示相对应的码值
case 0x7d:P0=dofly[1];break;//1
case 0x7b:P0=dofly[2];break;//2
case 0x77:P0=dofly[3];break;//3
case 0xbe:P0=dofly[4];break;//4
case 0xbd:P0=dofly[5];break;//5
case 0xbb:P0=dofly[6];break;//6
case 0xb7:P0=dofly[7];break;//7
case 0xde:P0=dofly[8];break;//8
case 0xdd:P0=dofly[9];break;//9
case 0xdb:P0=dofly[10];break;//a
case 0xd7:P0=dofly[11];break;//b
case 0xee:P0=dofly[12];break;//c
case 0xed:P0=dofly[13];break;//d
case 0xeb:P0=dofly[14];break;//e
case 0xe7:P0=dofly[15];break;//f
}
}
}
/*------------------------------------------------
键盘扫描程序
------------------------------------------------*/
uchar keyscan(void) //键盘扫描函数,使用行列反转扫描法
{
uchar cord_h,cord_l;//行列值中间变量
P3=0x0f; //行线输出全为0
cord_h=P3&0x0f; //读入列线值
if(cord_h!=0x0f) //先检测有无按键按下
{
delay(100); //去抖
if(cord_h!=0x0f)
{
cord_h=P3&0x0f; //读入列线值
P3=cord_h|0xf0; //输出当前列线值
cord_l=P3&0xf0; //读入行线值
return(cord_h+cord_l);//键盘最后组合码值
}
}return(0xff); //返回该值
}
/*------------------------------------------------
延时程序
------------------------------------------------*/
void delay(uint i) //延时函数
{
while(i--);
} 展开
#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#define uchar unsigned char
#define uint unsigned int
unsigned char const dofly[]={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=dofly[0];break;//0 按下相应的键显示相对应的码值
case 0x7d:P0=dofly[1];break;//1
case 0x7b:P0=dofly[2];break;//2
case 0x77:P0=dofly[3];break;//3
case 0xbe:P0=dofly[4];break;//4
case 0xbd:P0=dofly[5];break;//5
case 0xbb:P0=dofly[6];break;//6
case 0xb7:P0=dofly[7];break;//7
case 0xde:P0=dofly[8];break;//8
case 0xdd:P0=dofly[9];break;//9
case 0xdb:P0=dofly[10];break;//a
case 0xd7:P0=dofly[11];break;//b
case 0xee:P0=dofly[12];break;//c
case 0xed:P0=dofly[13];break;//d
case 0xeb:P0=dofly[14];break;//e
case 0xe7:P0=dofly[15];break;//f
}
}
}
/*------------------------------------------------
键盘扫描程序
------------------------------------------------*/
uchar keyscan(void) //键盘扫描函数,使用行列反转扫描法
{
uchar cord_h,cord_l;//行列值中间变量
P3=0x0f; //行线输出全为0
cord_h=P3&0x0f; //读入列线值
if(cord_h!=0x0f) //先检测有无按键按下
{
delay(100); //去抖
if(cord_h!=0x0f)
{
cord_h=P3&0x0f; //读入列线值
P3=cord_h|0xf0; //输出当前列线值
cord_l=P3&0xf0; //读入行线值
return(cord_h+cord_l);//键盘最后组合码值
}
}return(0xff); //返回该值
}
/*------------------------------------------------
延时程序
------------------------------------------------*/
void delay(uint i) //延时函数
{
while(i--);
} 展开
1个回答
展开全部
以S10被按下为例说明:
uchar keyscan(void) //键盘扫描函数,使用行列反转扫描法
{
uchar cord_h,cord_l;//行列值中间变量
P3=0x0f; //行线输出全为0
cord_h=P3&0x0f; //读入列线值
if(cord_h!=0x0f) //先检测有无按键按下,如果cord_h=0x0f说明无键按下
{
delay(100); //去抖
if(cord_h!=0x0f)//确实有键按下
{
cord_h=P3&0x0f; //开始P3=0x0f,S10按下后P3.1=0,所以P3=0x0d,列线值cord_h=P3&0x0f即cord_h=0x0d;
P3=cord_h|0xf0; //cord_h=0x0d,因为S10闭合,所以P3.5和P3.1都为0,P3=0xdd;
cord_l=P3&0xf0; //cord_l=0xdd&0xf0即cord_l=0xd0
return(cord_h+cord_l);//键盘最后组合码值0xdd;对应case 0xdd:P0=dofly[9];break;显示9
}
}return(0xff); //无键按下返回该值,不显示
}
uchar keyscan(void) //键盘扫描函数,使用行列反转扫描法
{
uchar cord_h,cord_l;//行列值中间变量
P3=0x0f; //行线输出全为0
cord_h=P3&0x0f; //读入列线值
if(cord_h!=0x0f) //先检测有无按键按下,如果cord_h=0x0f说明无键按下
{
delay(100); //去抖
if(cord_h!=0x0f)//确实有键按下
{
cord_h=P3&0x0f; //开始P3=0x0f,S10按下后P3.1=0,所以P3=0x0d,列线值cord_h=P3&0x0f即cord_h=0x0d;
P3=cord_h|0xf0; //cord_h=0x0d,因为S10闭合,所以P3.5和P3.1都为0,P3=0xdd;
cord_l=P3&0xf0; //cord_l=0xdd&0xf0即cord_l=0xd0
return(cord_h+cord_l);//键盘最后组合码值0xdd;对应case 0xdd:P0=dofly[9];break;显示9
}
}return(0xff); //无键按下返回该值,不显示
}
追问
P3=cord_h|0xf0; //cord_h=0x0d,因为S10闭合,所以P3.5和P3.1都为0,P3=0xdd;
这补还是有点糊涂, cord-h==0x0d 0x0d|0xf0==0xfd啊 所以这步P3被赋值了0xfd啊??
追答
是的,如果S10没有闭合0x0d|0xf0是等于0xfd,此处相当于P3一开始等于0xfd,但是由于S10闭合了,瞬间由于外电路的作用P3变成了0xdd。此处要结合电路来理解。
意法半导体(中国)投资有限公司
2021-01-14 广告
2021-01-14 广告
推荐STC的抗干扰很好。用9块钱的STC89C54RD+,16K的ROM,1K的RAM。我用过的,实现你的功能不成问题。如果环境恶劣,也可以选择工业级的STC89C54RD+,14块钱。而且这个单片机带AD,10位分辨率。可以用来接你的压力...
点击进入详情页
本回答由意法半导体(中国)投资有限公司提供
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询