按键按下时数码管显示会有些闪烁

2019-03-24 17:54发布

大侠们!
帮帮忙,按键按下时,数码管会有些闪烁不知道是怎么回事,要如何消除呢?另外该程序还有哪些不足之处请指出。
在此谢谢你们了!电路图在附件里,程序如下:
/*************************************************************
实验效果:用定时器定时来控制继电器的工作,初始时定时为150分钟、
继电器吸合、同时所定的时间在三位数码管上显示出来。开始时定时器
工作,按下S1定时器工作,每过1分钟时间减1,当所定的150分钟减为0时
继电器释放、定时器不工作、数码管不显示单片机进入掉电模式。按下S1、
S2、S3均可唤醒单片机。S1的作用是按下该键时定时器关闭或者启动之间
进行切换,同时数码管显示位置1;S2的作用是按下该键时数码管显示或者
不显示之间进行切换;S3的作用是只有定时器关闭和数码管显示位置1时按
下该键才起作用,每按该键定时时间减15分钟。同时每个按键按下时都会
发出滴的一声。晶振采用12MHZ.
****************************************************************/
#include"STC15F204EA.h"
#include<intrins.h>
#define GPIO_DIG P1
#define Fosc 12000000

sbit DS1=P3^7;
sbit DS2=P0^0;/*我所使用的单片机是A版本P0.0。B版本为P5.4*/
sbit DS3=P0^1;/*我所使用的单片机是A版本,所以这里用P0.1。B版本为P5.5*/      
sbit S3=P3^0;
sbit S2=P3^2;
sbit S1=P3^3;
sbit BZ=P3^4;
sbit RELAY=P3^5;
int Time, Num=150;
bit flag=1;/*数码管显示位置1显示*/
bit BZ_flag;
unsigned char code DIG[10]={0x7e,0x0c,0xb6,0x9e,0xcc,0xda,0xfa,0x0e,0xfe,0xde};
void Delay3ms();                //@12.000MHz
void display(unsigned int b);

main()
{       
    unsigned char n;
    BZ=0;
    /*喂狗*/
    WDT_CONTR=0x34;/*12.000MHz,看门狗溢出时间为1秒左右,溢出之后看门狗复位*/
    P5M0=0x30;
    P3M0=0xB0;
          P1M0=0XFF;

    IT1=1;/*外部中断1为下降沿触发方式*/
    IT0=1;/*外部中断0为下降沿触发方式*/
    INT_CLKO=0x40;/*允许外部中断4中断*/
    EX1=1;/*允许外部中断1中断*/
    EX0=1;/*允许外部中断0中断*/       
    PX1=1;/*设置外部中断1为高优先级*/

    TMOD=0x00;/*设定定时器0工作模式为0*/
        AUXR=0x00;/*设定定时器0工作在12T模式*/
        TH0=(65536-Fosc/12/20)>>8;/*给定时器0赋初值,定时50ms*/
        TL0=(65536-Fosc/12/20);
        ET0=1;/*开定时器0中断允许*/
        TR0=0;/*关闭定时器0*/
        EA=1;/*打开总中断*/



        while(1)
        {       

        WDT_CONTR=0x34;/*12.000MHz,看门狗溢出时间为1秒左右,溢出之后看门狗复位*/
        /*喂狗*/
        RELAY=1;/*打开继电器*/
        if(BZ_flag==1)
        {
            BZ=1;
            for(n=7;n>0;n--)
                display(Num);
            BZ=0;
            BZ_flag=0;   
        }
        if(flag==1)/*数码管显示*/
            display(Num);
        else/*关闭数码管显示*/
        {
           //DS1=1;DS2=1;DS3=1;
            GPIO_DIG=0;
        }
        }                          
}
void Timr0() interrupt 1
{
        Time++;
    if(Time==1200)
    {
        Time=0;
        Num--;
        if(Num<=0)
        {
            Num=180;
            RELAY=0;/*关闭继电器*/
            TR0=0;/*关闭定时器0*/
            GPIO_DIG=0;/*关闭数码管*/
            flag=1;
            PCON=0x02;/*掉电模式,单片机睡觉*/
        }   
    }
}

void Int0() interrupt 0
{
    display(Num);/*这个函数执行大约10毫秒时间  按键延时消抖*/
    if(S2==0)
    {
        BZ_flag=1;
        flag=~flag;/*数码管显示位取反*/
    }
}

void Int1() interrupt 2
{   
    display(Num);/*这个函数执行大约10毫秒时间  按键延时消抖*/
    if(S1==0)
    {
        BZ_flag=1;
        TR0=~TR0;/*定时器0启动关闭切换*/
            Num--;/*显示时间减1说明定时器0是已经启动或者关闭进行了切换*/
        flag=1;
    }

}

void Int4() interrupt 16
{
    display(Num);/*这个函数执行大约10毫秒时间  按键延时消抖*/
    if(S3==0)
    {   
        BZ_flag=1;
        if((TR0==0)&&(flag==1))/*当定时器0关闭和数码管显示时才可以进行调节时间*/
        {
            Num=Num-15;
            if(Num<=0)
            Num=180;
        }
    }
}
void display(unsigned int b)
{
    unsigned char bit100,bit10,bit1;
    unsigned int a;
        a=b;
        bit100=a/100;/*提取百位*/
        a=a%100;

        bit10=a/10;/*提取十位*/

        bit1=a%10;/*提取个位*/

    if(b>=100)
    {  
        DS1=1;
            /*送出数字段码*/
            GPIO_DIG=DIG[bit100];
            DS3=0; /*打开第一个数码的位选*/
        Delay3ms();
            DS3=1;
            /*送出数字段码*/
            GPIO_DIG=DIG[bit10];
            DS2=0;/*打开第二个数码的位选*/
        Delay3ms();
        DS2=1;
            /*送出数字段码*/
            GPIO_DIG=DIG[bit1];
            DS1=0;/*打开第三个数码的位选*/
        Delay3ms();
    }
    else if((b>=10)&&(b<100))
    {   
        DS1=1;
        Delay3ms();
            /*送出数字段码*/
            GPIO_DIG=DIG[bit10];
            DS2=0;/*打开第二个数码的位选*/
        Delay3ms();
        DS2=1;
            /*送出数字段码*/
            GPIO_DIG=DIG[bit1];
            DS1=0;/*打开第三个数码的位选*/
        Delay3ms();
    }
    else
    {
        DS1=1;
        Delay3ms();
        Delay3ms();
            /*送出数字段码*/
            GPIO_DIG=DIG[bit1];
            DS1=0;/*打开第三个数码的位选*/
        Delay3ms();
    }

}        

void Delay3ms()                //@12.000MHz
{
        unsigned char i, j;

        _nop_();
        _nop_();
        i = 36;
        j = 1;
        do
        {
                while (--j);
        } while (--i);
}


此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
19条回答
dcexpert
1楼-- · 2019-03-25 00:03
 精彩回答 2  元偷偷看……
werjufour
2楼-- · 2019-03-25 05:50
那要怎么弄呢?
按键按下不是要延时消抖吗?
sting_yang
3楼-- · 2019-03-25 06:29
werjufour 發表於 2015-1-31 23:05
那要怎麼弄呢?
按鍵按下不是要延時消抖嗎?
多想想,延时要怎么写,才不会在循环绕,将mcu都耗在循环了



zhaojun_xf
4楼-- · 2019-03-25 06:46
 精彩回答 2  元偷偷看……
sun1238898
5楼-- · 2019-03-25 10:18
这个比较麻烦,中断里面占用的时间太多,导致没时间刷屏。
ljj3166
6楼-- · 2019-03-25 13:34
中断的处理,越简短越好

一周热门 更多>