微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 求问大神如何让本程序数码管稳定的显示?

求问大神如何让本程序数码管稳定的显示?

时间:10-02 整理:3721RD 点击:
PS:需要按一下按键加一或者减一,同时要保证数字的稳定显示
#include <reg52.h>
#define uchar unsigned char
#define uint  unsigned int
sbit we = P1^1;
sbit du = P1^2;
sbit lcden = P3^4;
uchar num1 = 1, num3=1;
uint  num2=1;
uchar leddata[]={
                        0xC0,  //"0"
                        0xF9,  //"1"
                        0xA4,  //"2"
                        0xB0,  //"3"
                        0x99,  //"4"
                        0x92,  //"5"
                        0x82,  //"6"
                        0xF8,  //"7"
                        0x80,  //"8"
                        0x90,  //"9"       
                                       };
void delay(uint z);
void KeyScan();        //带返回值的子函数
void show_num_2bit();                          //2位数码管显示程序
void show_num_3bit_1();                          //第一个3位数码管显示程序
void show_num_3bit_2();                          //第二个3位数码管显示程序
void show_num();
/*------------------------------------------------*/
void main()
{       
               
                lcden = 0;                                               
        TMOD = 0x01;                                       
        TH0 = (65536 - 0)/256;
        TL0 = (65536 - 0)%256;
        EA = 1;
        ET0 = 1;
        TR0 = 1;
               
                while(1)
                {
                        show_num();
                }
       
}
/*------------------------------------------------*/
void Interrupt_T0()interrupt 1
{
        TH0 = (65536 - 0)/256;
        TL0 = (65536 - 0)%256;
               KeyScan();       
}
void delay(uint z)
{
        uint x,y;
        for(x = z; x > 0; x--)
                for(y = 114; y > 0 ; y--);
}

void KeyScan()        //带返回值的子函数
{
        uchar cord_l,cord_h;//声明列线和行线的值的储存变量
        P2 = 0xf8;//1111 0000
        if( (P2 & 0xf8) != 0xf8)//判断是否有按键按下
        {
                delay(5);//软件消抖
                if( (P2 & 0xf8) != 0xf8)//判断是否有按键按下
                {
                          cord_l = P2 & 0xf8;// 储存列线值
                          P2 = cord_l | 0x07;
                          cord_h = P2 & 0x7;// 储存行线值
                         
                         switch( cord_l + cord_h )
                         {
                                         //第一行键值码         控制二位数码管
                                        case 0xf6: if(num1>=0&&num1<=98) num1++; break;                         //+1
                                        case 0xee: if(num1>=1&&num1<=99) num1--; break;                         //-1
                                        case 0xde:                 break;
                                        case 0xbe:                 break;
                                        case 0x7e:                 break;
                                       
                                        //第二行键值码         控制第一个三位数码管
                                        case 0xf5: if(num2>=1&&num2<=199) num2++; break;                         //+1
                                        case 0xed: if(num2>=2&&num2<=200) num2--; break;                         //-1
                                        case 0xdd:                 break;
                                        case 0xbd:                 break;
                                        case 0x7d:                 break;
                       
                       
                                        //第三行键值码         控制第二个三位数码管
                                        case 0xf3: if(num3>=1&&num3<=199) num3++; break;                         //+1
                                        case 0xeb: if(num3>=2&&num3<=200) num3--; break;                         //-1
                                        case 0xdb:         break;
                                        case 0xbb:         break;
                                        case 0x7b:         break;
               
                               
                         }       
                }
               
        }
               
}
void show_num_2bit()                          //2位数码管显示程序
{
        uchar ge, shi;
        shi =num1/10;
        ge =num1%10;         
        P0 = 0x01;                                                                 //十位显示
        we = 1;
        we = 0;
          if(shi==0)
                {
                        P0 = 0xFF;
                        du=1;
                        du=0;
                        delay(2);
                }
        else if(shi!=0)
                {
                        P0 = leddata[shi];
                        du=1;
                        du=0;
                        delay(2);
                }
        P0 = 0x02;                                                          //个位显示
        we = 1;
        we = 0;
       
        P0 = leddata[ge];
        du=1;
        du=0;
        delay(2);
                 
}
void show_num_3bit_1()                          //第一个3位数码管显示程序
{
        uchar ge, shi, bai;
        bai =num2/100;
        shi =num2%100/10;
        ge =num2%10;         
               
        P0 = 0x04;                                                //百位显示
        we = 1;
        we = 0;
          if(bai==0)
                {
                        P0 = 0xFF;
                        du=1;
                        du=0;
                        delay(2);
                }
        else if(bai!=0)
                {
                        P0 = leddata[bai];
                        du=1;
                        du=0;
                        delay(2);
                }
        P0 = 0x08;                                                                 //十位显示
        we = 1;
        we = 0;
          if(shi==0&&bai==0)
                {
                        P0 = 0xFF;
                        du=1;
                        du=0;
                        delay(2);
                }
        else if(shi!=0||bai!=0)
                {
                        P0 = leddata[shi];
                        du=1;
                        du=0;
                        delay(2);
                }
        P0 = 0x10;                                                          //个位显示
        we = 1;
        we = 0;
       
        P0 = leddata[ge];
        du=1;
        du=0;
        delay(2);
                 
}
void show_num_3bit_2()                          //第二个3位数码管显示程序
{
        uchar ge, shi, bai;
        bai =num3/100;
        shi =num3%100/10;
        ge =num3%10;         
               
        P0 = 0x20;                                                //百位显示
        we = 1;
        we = 0;
          if(bai==0)
                {
                        P0 = 0xFF;
                        du=1;
                        du=0;
                        delay(2);
                }
        else if(bai!=0)
                {
                        P0 = leddata[bai];
                        du=1;
                        du=0;
                        delay(2);
                }
        P0 = 0x40;                                                                 //十位显示
        we = 1;
        we = 0;
          if(shi==0&&bai==0)
                {
                        P0 = 0xFF;
                        du=1;
                        du=0;
                        delay(2);
                }
        else if(shi!=0||bai!=0)
                {
                        P0 = leddata[shi];
                        du=1;
                        du=0;
                        delay(2);
                }
        P0 = 0x80;                                                          //个位显示
        we = 1;
        we = 0;
       
        P0 = leddata[ge];
        du=1;
        du=0;
        delay(2);
                 
}
void show_num()
{
                show_num_2bit();
                show_num_3bit_1();
                show_num_3bit_2();
}

现在的问题是,数码管可以稳定显示,但是按一下按键数字会增加好多而不是一个。

软件消抖动的值设大一点试试!
delay(5);//软件消抖
希望对你有帮助!

应该是程序框架有问题。这么能把含有延时消抖的键扫描程序放在中断里呢?如果有必要把键扫描程序放在中断里,建议采用中断记数消抖,并且只把获取键值部分留下,键值服务部分放到主循环中处理。定时器中断时间1ms足以。

这个最好改成单次脉冲上调的方式

你的中断服务程序有问题,不知道你想多长时间产生一次中断?
TH0 = (65536 - 0)/256;   TH0 = 256   2进制= 1 0000 0000
TL0 = (65536 - 0)%256;  TL0 = 256   2进制= 1 0000 0000
8位寄存器能装下9位数吗?就算TH0 = TL0 = 0xFF,假如是12M晶振,1秒要进入中断1000000次,你的中断服务程序还有按键扫描程序,其中还包含5ms的延时,这个中断服务程序能正常工作吗?

所有延时都为定时器延时方式实现

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

网站地图

Top