数码管显示4×4矩阵键盘的键号
电路图

分析
- P1.0 ~ P1.3控制键盘的列(置0代表按钮被按下)
- P1.4 ~ P1.7控制键盘的行(置0代表按钮被按下)
- 数码管为共阳极,低电平有效,P0.0 ~ P0.7置0对应数码管中的a,b,c,d,e,f,g,dp段亮
完整程序
方法一(推荐)
#include
#include
//段选segment 0 1 2 3 4 5 6 7 8 9 A b C d E F
unsigned char code seg[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xc6,0xA1,0x86,0x8e};
unsigned char temp,i; //临时变量temp,循环变量i
sbit k1=P1^0;//控制列
sbit k2=P1^1;
sbit k3=P1^2;
sbit k4=P1^3;void delay(int a)//延时函数,增大从一个状态到另一个状态之间的时间,避免因变化过快而超出人眼视觉停留的最佳时间
{while(a--);
}void main()
{ while(1){ P1=0xef;// 选择第一行P1.7~P1.4 e(1110) P1.3~P1.0 f(1111) for(i=0;i<=3;i++){if(k1==0)//k1=P1^0,k1=0,P1^0=0检查第一行第一列按钮是否有按钮被按下//第一次循环检查第一行第一列按钮//第二次循环检查第一行第二列按钮…… P0=seg[i*4+0]; //i=0 seg[0]为数字0 //i=1 seg[4]为数字4 //i=2 seg[8]为数字8 //i=3 seg[12]为字母Cif(k2==0)//检查第二行是否有按钮被按下//第一次循环检查第二行第一列按钮//第二次循环检查第二行第二列按钮…… P0=seg[i*4+1]; //i=0 seg[1]为数字1 //i=1 seg[5]为数字5 //i=2 seg[9]为数字9 //i=3 seg[13]为字母dif(k3==0)//检查第三行是否有按钮被按下//第一次循环检查第三行第一列按钮//第二次循环检查第三行第二列按钮…… P0=seg[i*4+2]; //i=0 seg[2]为数字2 //i=1 seg[6]为数字6 //i=2 seg[10]为字母A //i=3 seg[14]为字母Eif(k4==0)//检查第四行是否有按钮被按下//第一次循环检查第四行第一列按钮//第二次循环检查第四行第二列按钮…… P0=seg[i*4+3]; //i=0 seg[3]为数字3 //i=1 seg[7]为数字7 //i=2 seg[11]为字母b //i=3 seg[15]为字母Fdelay(300);//消抖temp=P1;//第一次循环为temp=0xef,第二次循环为temp=0xbf,……temp=temp<<1;//此左移并非函数_crol_() //第一次循环0xef左移1位 1101 1110 //第二次循环0xef再次左移1位 1011 1100 /……temp=temp | 0x0f;//第一次循环 1110 1111 0xef 第二次循环0xef左移一位后:1101 1110 // | |// 0000 1111 0x0f 0000 1111 0x0f// 1110 1111 0xef(选择第一行) 1101 1111 0xbf(选择第二行) P1=temp; //将临时量temp赋值给P1,以便下次循环,进入扫描下一行}}
}
方法二
#include
#include
//段选segment 0 1 2 3 4 5 6 7 8 9 A b C d E F
unsigned char code led[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xc6,0xA1,0x86,0x8e};
// unsigned char code led[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
unsigned char temp,i; //临时变量temp,循环变量i
sbit k4=P1^4;//控制行
sbit k5=P1^5;
sbit k6=P1^6;
sbit k7=P1^7;void delay(int a)//延时函数,增大从一个状态到另一个状态之间的时间,避免因变化过快而超出人眼视觉停留的最佳时间
{while(a--);
}void main()
{ while(1){ P1=0xfe;//P1.7~P1.4 (1111) P1.3~P1.0 (1110)选择第一列 1111 1101 1111 1011 1111 0111for(i=0;i<=3;i++){if(k4==0)//1110 1110 第一列第一行 数字1P0=led[0+i];//i=0 数字0 i=1 数字1 i=2 数字2 i=3 数字3if(k5==0)//1101 1110 第一列第二行 数字4P0=led[4+i];//i=0 数字4 i=1 数字5 i=2 数字6 i=3 数字7if(k6==0)//1011 1110 第一列第三行 数字8P0=led[8+i];//i=0 数字8 i=1 数字9 i=2 字母A(10) i=3 字母B(11)if(k7==0)//0111 1110 第一列第四行 字母CP0=led[12+i];//i=0 字母C(12) i=1 字母D(13) i=2 字母E(14) i=3 字母F(16)delay(25000);if(i!=3)//选列只需要移动三次(0,1,2)防止第4次左移{temp=P1; temp=temp<<1; //1111 1100 P1 1111 1010 P1 1111 0110 temp=temp | 0x01; //0000 0001 <<1 0000 0001 <<1 0000 0001P1=temp; //1111 1101 1111 1011 1111 0111} }}
}
方法三
#include
//段选segment 0 1 2 3 4 5 6 7 8 9 A b C d E F
unsigned char code seg[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xc6,0xA1,0x86,0x8e};
unsigned char temp,key; //临时变量temp,seg[key]下标
sbit k1=P1^0;
sbit k2=P1^1;
sbit k3=P1^2;
sbit k4=P1^3;void delay(int a)//延时函数,增大从一个状态到另一个状态之间的时间,避免因变化过快而超出人眼视觉停留的最佳时间
{while(a--);
}void display()
{delay(30000);P0=seg[key];}void main()
{ P0=0xff;//清屏while(1){ //选择第一行P1=0xef;//行P1.7~P1.4 1110 列P1.3~P1.0 1111 temp=P1;if( (temp&0xef)!=0xef ) //扫描第一行 { delay(15);//消抖 if((temp&0xef)!=0xef) //消抖后再次扫描第一行{switch(temp){case 0xee:key=0;break;//第一行第一列 P1.7~P1.4行1110 P1.3~P1.0列1110case 0xed:key=1;break;//第一行第二列 P1.7~P1.4行1110 P1.3~P1.0列1101case 0xeb:key=2;break;//第一行第三列 P1.7~P1.4行1110 P1.3~P1.0列1011case 0xe7:key=3;break;//第一行第四列 P1.7~P1.4行1110 P1.3~P1.0列0111}}display(); }//选择第二行P1=0xbf;//行P1.7~P1.4 1101 列P1.3~P1.0 1111temp=P1;if((temp&0xbf)!=0xbf) //扫描第二行 { delay(15); //消抖 if((temp&0xbf)!=0xbf){switch(temp){case 0xbe:key=4;break;//第二行第一列 P1.7~P1.4行1101 P1.3~P1.0列1110case 0xbd:key=5;break;//第二行第二列 P1.7~P1.4行1101 P1.3~P1.0列1101case 0xbb:key=6;break;//第二行第三列 P1.7~P1.4行1101 P1.3~P1.0列1011case 0xb7:key=7;break;//第二行第四列 P1.7~P1.4行1101 P1.3~P1.0列0111}}display();}//选择第三行P1=0x9f;//行P1.7~P1.4 1011 列P1.3~P1.0 1111temp=P1;if((temp&0x9f)!=0x9f) //扫描第三行 { delay(15); //消抖 if((temp&0x9f)!=0x9f){switch(temp){case 0x9e:key=8;break;//第三行第一列 P1.7~P1.4行1011 P1.3~P1.0列1110case 0x9d:key=9;break;//第三行第二列 P1.7~P1.4行1011 P1.3~P1.0列1101case 0x9b:key=10;break;//第三行第三列 P1.7~P1.4行1011 P1.3~P1.0列1011case 0x97:key=11;break;//第三行第四列 P1.7~P1.4行1011 P1.3~P1.0列0111}}display();}//选择第四行P1=0x7f;//行P1.7~P1.4 0111 列P1.3~P1.0 1111temp=P1;if((temp&0x7f)!=0x7f) //扫描第四行{delay(15); //消抖if((temp&0x7f)!=0x7f){switch(temp){case 0x7e:key=12;break;//第四行第一列 P1.7~P1.4行0111 P1.3~P1.0列1110case 0x7d:key=13;break;//第四行第二列 P1.7~P1.4行0111 P1.3~P1.0列1101case 0x7b:key=14;break;//第四行第三列 P1.7~P1.4行0111 P1.3~P1.0列1011case 0x77:key=15;break;//第四行第四列 P1.7~P1.4行0111 P1.3~P1.0列0111}}display();}}
}
效果图

本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
