微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 求解惑:使用51单片机的独立按键实现数码管的显示控制,代码无报错,但是运行结果是错的

求解惑:使用51单片机的独立按键实现数码管的显示控制,代码无报错,但是运行结果是错的

时间:10-02 整理:3721RD 点击:
求解答:使用51单片机数码管的前两位显示一个十进制数,变化范围是00~59,开始时显示00,每按下s2键一次,数值增加一次,每按下s3键一次,数值减一,每按下s4键一次,数值归0,每按下s5键一次,利用定时器功能使数值开始自动每秒加1,再次按下s5,数值停止加1,保持显示原数。
我写的程序代码如下:
#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的时候,数码管输出低电平,很暗的灯

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top