利用keil5,使用stc89c52,设计程序,利用4*4键盘和七段数码管,使得当某一按键按下时,数码管显示该按键按下键值。利用<reg52.h>。
#include <reg52.h>
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
sbit K1=P3^0;
sbit K2=P3^1;
sbit K3=P3^2;
sbit K4=P3^3;
sbit DULA=P2^5;
sbit WELA=P2^6;
unsigned char code table[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
//数码管显示0~F的值
void delay(unsigned int i)
{
while(i--);
}
void display(unsigned char first,unsigned char second,unsigned char third,unsigned char forth)
{
unsigned char i;
for(i=0;i<50;i++)
{
LSA=0;
P0=table[first];
delay(100);
LSA=1;
LSB=0;
P0=table[second];
delay(100);
LSB=1;
LSC=0;
P0=table[third];
delay(100);
LSC=1;
DULA=0;
P0=table[forth];
delay(100);
DULA=1;
WELA=0;
P0=0xfe;
delay(100);
WELA=1;
}
}
unsigned char key_scan()
{
unsigned char val=0;
if(K1==0)
{
delay(1000);
if(K1==0)
{
val=1;
display(val,0,0,0);
}
while(!K1);
}
else if(K2==0)
{
delay(1000);
if(K2==0)
{
val=2;
display(val,0,0,0);
}
while(!K2);
}
else if(K3==0)
{
delay(1000);
if(K3==0)
{
val=3;
display(val,0,0,0);
}
while(!K3);
}
else if(K4==0)
{
delay(1000);
if(K4==0)
{
val=4;
display(val,0,0,0);
}
while(!K4);
}
return val;
}
void main()
{
unsigned char key_val=0;
while(1)
{
key_val=key_scan();
if(key_val!=0)
{
display(0,0,0,key_val);
}
}
}
不知道你这个问题是否已经解决, 如果还没有解决的话:```markdown 下面是解答:
使用Keil5和STC89C52设计程序,使4*4键盘按下某个键时,七段数码管能正确地显示对应键值 1.首先需要连接硬件,将键盘和7段数码管接到开发板上 2.根据参考资料,以及STC89C52的硬件特性,使用reg52.h头文件,定义所需的引脚,其中要用到P0口、P2口和P3口,还要安装相应头文件 3.使用毫秒级延时函数定义,以在数码管动态显示时,确保每个数码管的亮灭有足够的长短来区分 4.定义共阴数码管段选表,建立相应的数组,以便代码中可以方便地调用 5.实现两位共阴数码管动态显示函数,包括第一次位选和第二位位选,利用段选锁存器,控制数码管的亮灭,先清除断码再进行锁存,然后调用相应的数组,在数组中查找灯序列,将对应的值赋给所要显示的数码管 6.在main函数中进行数码管的显示,制定具体按键的程序 7.每次按下独立按键S4,控制数码管显示数字减 1,当数码管数字变为 00 时, 按动按键 S4,会让数码管重新变为 10。
由于问题涉及较多的硬件连接及编程知识,编写一段完整的可运行代码,请见代码如下所示,仅供参考,并可能因具体硬件条件的不同而不同:
sbit DU = P2^6;//数码管段选 sbit WE = P2^7;//数码管位选 sbit key1 = P3^0; // 普通按键IO口 uchar array[4][4] = {{1,2,3,0x0A}, {4,5,6,0x0B}, {7,8,9,0x0C}, {0,0x0F,0,0x0E}}; // 数组记录按键值
//共阴数码管段选表0-9 uchar code tabel[]= {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71};
//毫秒级延时函数定义 void delay(uint z) { uint x,y; for(x = z; x > 0; x--) for(y = 114; y > 0 ; y--);
}
/***** 函数名: keycheck 功能描述: 用于检测44键盘是否有按键按下 入口参数: void 出口参数: 返回按键值 ********/ uchar keycheck() { uchar keyvalue; uchar i; P1 = 0xF0; if (P1 != 0xF0) { delay(100); if (P1 != 0xF0) { i = 0; P1 = 0xF0; switch (P1) { case(0xE0):keyvalue = array[0][i];break; case(0xD0):keyvalue = array[1][i];break; case(0xB0):keyvalue = array[2][i];break; case(0x70):keyvalue = array[3][i];break; }
} } return keyvalue; }
/==================================== 描述 :两位共阴数码管动态显示 ====================================/ void display(uchar num1, uchar num2) { P0 = 0XFF;//清除断码 WE = 1;//打开位选锁存器 P0 = 0XFE; //1111 1110 WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = tabel[num1];//
DU = 0;//锁存段选数据
delay(1);
/*第二位显示*/
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = 0XFD; //1111 1101
WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = tabel[num2];//
DU = 0;//锁存段选数据
delay(1);
}
void main() { uchar keyval; uint count = 0; uint num1 = 0, num2 = 0;
while (1)
{
keyval = keycheck();
if (keyval != 0xFF) // 判断是否有按键按下
{
if (keyval == 0x0E) //如果是按键D,表示清零
{
num1 = 0;
num2 = 0;
count = 0;
}
else if (keyval == 0x0A) //如果是按键A,表示转换为16进制数
{
count++;
count %= 3; //由于只有3种显示可能,超过3进入循环
}
else
{
if (count % 3 == 0) //如果当前进制为10
{
if (count == 0)
{
num1 = keyval / 10;
num2 = keyval % 10;
}
else
{
num1 = keyval % 10;
num2 = keyval / 10;
}
}
else if (count % 3 == 1) //如果当前进制为8
{
num1 = keyval / 8 / 8;
num2 = (