题目:
实验板上电时,数码管不显示,顺序按下矩阵键盘后,在数码管上依次显示0~F,6个数码管同时静态显示即可。(来自郭天祥老师的51单片机练习)
代码:
初始化函数:
//初始化函数
void Init()
{
DLE = 1;
P0 = 0x00;//关闭数码管(共阴极)段选,数码管不显示
DLE = 0;
WLE = 1;
P0 = 0xc0;//打开所有数码管的位选
WLE = 0;
}
延时1ms函数:
//延时1ms函数
void delay_1ms(uint z)
{
uint x,y;
for(x = z;x > 0;x--)
{
for(y =110;y > 0;y--){}
}
}
矩阵键盘函数:
//矩阵键盘函数
void MatrixKeyboard()
{
uchar temp;
uint keyNum;
P3 = 0xfe;//第一排按键
temp = P3;
temp = temp & 0xf0;
while(temp != 0xf0)
{
delay_1ms(10);//消抖
temp = P3;
temp = temp & 0xf0;
if(temp != 0xf0)
{
temp = P3;
switch(temp)
{
case 0xee:
keyNum = 0;
break;
case 0xde:
keyNum = 1;
break;
case 0xbe:
keyNum = 2;
break;
case 0x7e:
keyNum = 3;
break;
}
//等待按键释放
while(temp != 0xf0)
{
temp = P3;
temp = temp & 0xf0;
}
display(keyNum);
}
}
P3 = 0xfd;//第二排按键
temp = P3;
temp = temp & 0xf0;
while(temp != 0xf0)
{
delay_1ms(10);//消抖
temp = P3;
temp = temp & 0xf0;
if(temp != 0xf0)
{
temp = P3;
switch(temp)
{
case 0xed:
keyNum = 4;
break;
case 0xdd:
keyNum = 5;
break;
case 0xbd:
keyNum = 6;
break;
case 0x7d:
keyNum = 7;
break;
}
//等待按键释放
while(temp != 0xf0)
{
temp = P3;
temp = temp & 0xf0;
}
display(keyNum);
}
}
P3 = 0xfb;//第三排按键
temp = P3;
temp = temp & 0xf0;
while(temp != 0xf0)
{
delay_1ms(10);//消抖
temp = P3;
temp = temp & 0xf0;
if(temp != 0xf0)
{
temp = P3;
switch(temp)
{
case 0xeb:
keyNum = 8;
break;
case 0xdb:
keyNum = 9;
break;
case 0xbb:
keyNum = 10;
break;
case 0x7b:
keyNum = 11;
break;
}
//等待按键释放
while(temp != 0xf0)
{
temp = P3;
temp = temp & 0xf0;
}
display(keyNum);
}
}
P3 = 0xf7;//第四排按键
temp = P3;
temp = temp & 0xf0;
while(temp != 0xf0)
{
delay_1ms(10);//消抖
temp = P3;
temp = temp & 0xf0;
if(temp != 0xf0)
{
temp = P3;
switch(temp)
{
case 0xe7:
keyNum = 12;
break;
case 0xd7:
keyNum = 13;
break;
case 0xb7:
keyNum = 14;
break;
case 0x77:
keyNum = 15;
break;
}
//等待按键释放
while(temp != 0xf0)
{
temp = P3;
temp = temp & 0xf0;
}
display(keyNum);
}
}
}
数码管显示函数:
//数码管显示函数
void display(uint keyNum)
{
DLE = 1;
P0 = Table[keyNum];
DLE = 0;
delay_1ms(5);
}
整个项目代码:
#include <reg52.h>
//【例4.2.1】实验板上电时,数码管不显示,顺序按下矩阵键盘后,在数码管上依次显示0~F,6个数码管同时静态显示即可。
//晶振为 11.0529MHz
#define uint unsigned int
#define uchar unsigned char
sbit WLE = P2^7;//位选
sbit DLE = P2^6;//段选
//数码管的编码表
uchar code Table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
void Init();
void delay_1ms(uint z);
void MatrixKeyboard();
void display(uint keyNum);
void main()
{
Init();
while(1)
{
MatrixKeyboard();
}
}
//初始化函数
void Init()
{
DLE = 1;
P0 = 0x00;//关闭数码管(共阴极)段选,数码管不显示
DLE = 0;
WLE = 1;
P0 = 0xc0;//打开所有数码管的位选
WLE = 0;
}
//延时1ms函数
void delay_1ms(uint z)
{
uint x,y;
for(x = z;x > 0;x--)
{
for(y =110;y > 0;y--){}
}
}
//矩阵键盘函数
void MatrixKeyboard()
{
uchar temp;
uint keyNum;
P3 = 0xfe;//第一排按键
temp = P3;
temp = temp & 0xf0;
while(temp != 0xf0)
{
delay_1ms(10);//消抖
temp = P3;
temp = temp & 0xf0;
if(temp != 0xf0)
{
temp = P3;
switch(temp)
{
case 0xee:
keyNum = 0;
break;
case 0xde:
keyNum = 1;
break;
case 0xbe:
keyNum = 2;
break;
case 0x7e:
keyNum = 3;
break;
}
//等待按键释放
while(temp != 0xf0)
{
temp = P3;
temp = temp & 0xf0;
}
display(keyNum);
}
}
P3 = 0xfd;//第二排按键
temp = P3;
temp = temp & 0xf0;
while(temp != 0xf0)
{
delay_1ms(10);//消抖
temp = P3;
temp = temp & 0xf0;
if(temp != 0xf0)
{
temp = P3;
switch(temp)
{
case 0xed:
keyNum = 4;
break;
case 0xdd:
keyNum = 5;
break;
case 0xbd:
keyNum = 6;
break;
case 0x7d:
keyNum = 7;
break;
}
//等待按键释放
while(temp != 0xf0)
{
temp = P3;
temp = temp & 0xf0;
}
display(keyNum);
}
}
P3 = 0xfb;//第三排按键
temp = P3;
temp = temp & 0xf0;
while(temp != 0xf0)
{
delay_1ms(10);//消抖
temp = P3;
temp = temp & 0xf0;
if(temp != 0xf0)
{
temp = P3;
switch(temp)
{
case 0xeb:
keyNum = 8;
break;
case 0xdb:
keyNum = 9;
break;
case 0xbb:
keyNum = 10;
break;
case 0x7b:
keyNum = 11;
break;
}
//等待按键释放
while(temp != 0xf0)
{
temp = P3;
temp = temp & 0xf0;
}
display(keyNum);
}
}
P3 = 0xf7;//第四排按键
temp = P3;
temp = temp & 0xf0;
while(temp != 0xf0)
{
delay_1ms(10);//消抖
temp = P3;
temp = temp & 0xf0;
if(temp != 0xf0)
{
temp = P3;
switch(temp)
{
case 0xe7:
keyNum = 12;
break;
case 0xd7:
keyNum = 13;
break;
case 0xb7:
keyNum = 14;
break;
case 0x77:
keyNum = 15;
break;
}
//等待按键释放
while(temp != 0xf0)
{
temp = P3;
temp = temp & 0xf0;
}
display(keyNum);
}
}
}
//数码管显示函数
void display(uint keyNum)
{
DLE = 1;
P0 = Table[keyNum];
DLE = 0;
delay_1ms(5);
}
实验板连接情况:
矩阵键盘与单片机的连接图:
心得/经验记录:
1.在处理矩阵键盘时,要巧用按位与&的使用,本实验中就时使用 P3 = 0xfe; temp = P3; temp = temp & 0xf0; 这三句话判断是否有按键按下。如果没有按键按下,P3 = 0xfe(1111 1110),它与0xf0(1111 0000)按位与之后,仍然是0xf0(1111 0000);如果有按键被按下(假如是S6被按下),那么P3 = 0xee(1110 1110),它与0xf0(1111 0000)按位与之后,结果是0xe0(1110 0000),不是0xf0(1111 0000)。此方法可以检测矩阵键盘是否有按键按下。
2.在实验的过程中,当使用的寄存器多了之后,要注意P0、P1、P3等是否会写错。
写此文章,记录自己学习51单片机过程中的一些思考和心得感悟,方便自己之后查阅,也供学习51单片机的小伙伴学习参考~