求解惑:使用51单片机的独立按键实现数码管的显示控制,代码无报错,但是运行结果是错的
我写的程序代码如下:
#include<reg51.h>
typedef unsigned int uint;
typedef unsigned char uchar;
sbit key1=P1^4;
sbit key2=P1^5;
sbit key3=P1^6;
sbit key4=P1^7;
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
uchar code smg[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
uchar num,numt;
void delayms(uint);
void display(uint numdis)//显示子程序
{
uchar shi,ge; //分离为个位和十位
shi=numdis/10;
ge=numdis%10;
LSA=0;LSB=0;LSC=0; //十位赋值
P0=smg[shi];
P0=0xff;
delayms(5);
LSA=1;LSB=0;LSC=0; //个位赋值
P0=smg[ge];
P0=0xff;
delayms(5);
}
void delayms(uint xms) //延时程序
{
uint i,j;
for(i=xms;i>0;i--)
{
for(j=110;j>0;j--);
}
}
void init() //初始化程序
{
TMOD=0x01; //定时器0工作方式1
TH0=0x3c;
TL0=0xb0;
EA=1; //开总中断
ET0=1; //开定时器中断
}
void keyscan()
{
if(key1==0)
{
delayms(10); //去抖动
if(key1==0)
{
num++;
if(num==60) //当到60时重新归0
num=0;
while(!key1); //等待键盘释放
}
}
if(key2==0)
{
delayms(10);
if(key2==0)
{
if(num==0) //当num到0时重新置60
num=60;
num--;
while(!key2);
}
}
if(key3==0)
{
delayms(10);
if(key3==0)
{
num=0; //直接清零
while(!key3);
}
}
if(key4==0)
{
delayms(10);
if(key4==0)
{
while(!key4);
TR0=~TR0; //启动或停止定时器0
}
}
}
void main()
{
init(); //初始化函数
while(1)
{
keyscan();
display(num);
}
}
void Timer() interrupt 1
{
TH0=0x3c; //重装初值(50ms)
TL0=0xb0;
numt++;
if(numt==20) //一秒时间
{
numt=0; //清零
num++;
if(num==60)
num=0;
}
}
单片机的接线图

给你稍改一下试试
#include<reg51.h>
typedef unsigned int uint;
typedef unsigned char uchar;
sbit key1=P1^4;
sbit key2=P1^5;
sbit key3=P1^6;
sbit key4=P1^7;
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
uchar shi,ge;
uchar code smg[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
uchar num=0,numt=0;
bit sign=0;
void init() //5毫秒@12.000MHz
{
TMOD= 0x01; //设置定时器模式
TL0 = 0x78; //设置定时初值
TH0 = 0xEC; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
EA=1; //开总中断
ET0=1; //开定时器中断
}
void delayms(uint xms) //延时程序
{
uint i,j;
for(i=xms;i>0;i--)
{
for(j=110;j>0;j--);
}
}
void keyscan()
{
if(key1==0)
{
delayms(20); //去抖动
if(key1==0)
{
num++;
if(num>=60) //当到60时重新归0
num=0;
while(!key1); //等待键盘释放
}
}
if(key2==0)
{
delayms(20);
if(key2==0)
{
num--;
if(num>60) //当num到0时重新置60
num=59;
while(!key2);
}
}
if(key3==0)
{
delayms(20);
if(key3==0)
{
numt=0;
num=0; //直接清零
while(!key3);
}
}
if(key4==0)
{
delayms(20);
if(key4==0)
{
sign=~sign; //启动或暂停计数
while(!key4); }
}
}
void display()//显示子程序
{
static uchar count=0; //计数变量
switch(count)
{
case 0:
P0=0xff;
LSA=0;LSB=0;LSC=0; //十位赋值
P0=smg[shi];
count=1;
break;
case 1:
P0=0xff;
LSA=1;LSB=0;LSC=0; //个位赋值
P0=smg[ge];
count=0;
break;
}
}
void main()
{
init(); //初始化函数
while(1)
{
keyscan();
shi=num/10;
ge=num%10;
}
}
void Timer() interrupt 1
{
TL0 = 0x78; //设置定时初值(5ms)
TH0 = 0xEC; //设置定时初值
if(sign==1)
{
numt++;
if(numt>=200) //一秒时间
{
numt=0; //清零
num++;
if(num>=60)
num=0;
}
}
display();
}
在P0=smg[]和P0=0xff之间加时延就可以了,不过,为什么将P0=0x00的时候,数码管输出低电平,很暗的灯
