单片机/MCUwilliam hill官网
直播中

陈诺

7年用户 112经验值
擅长:EDA/IC设计
私信 关注
[问答]

新手请教大神关于51单片机数码管闪烁程序

51单片机C语言程序想要控制四个数码管同时亮,并且其中一个闪烁并可通过键盘调节,通过按键使可调节的位(也就是闪烁的位)移动到下一位,类似于电子钟的程序。新手不知道应该把延时加在动态显示的什么位置。

回帖(6)

武林

2017-7-13 14:52:00
//给你一个思路,例程片段参考一下,昨天发的有错误,改动后要审核但丢失了,重发一次。
unsigned char a;                           //键值变量0~6,0为初始态,不控制闪烁
unsigned char count;                //数码管轮流显示计数变量
unsigned int Cnt_ms;                //1ms中断计数变量
/******定时器0初始化程序******/
void Timer0Init(void)                //1毫秒@12.000MHz
{
        TMOD = 0x01;                        //设置定时器模式
        TL0 = 0x18;                                //设置定时初值
        TH0 = 0xFC;                                //设置定时初值
        TR0 = 1;                                //定时器0开始计时
        EA=1;                                        //开总中断
        ET0=1;                                        //开定时器0中断       
}
/******定时器0中断服务程序******/
void timer0() interrupt 1       
{
        TL0 = 0x18;                                //设置定重载值
        TH0 = 0xFC;                                //设置定重载值
        Cnt_ms++;                                //1ms变量自+1
        count++;                                //轮流显示计数
        if(Cnt_ms>=1000)                //1秒,可根据闪烁频率修改
                Cnt_ms=0;
        if(count>=4)                        //显示程序,1ms显示一位
        {
                count=0;
                switch(count)
                {
                        case 0:
                        //显示段语句
                        if((a==1)&(count<500))//满足两个条件执行以下语句。
                        {
                        //关闭位语句
                        }
                        else
                        {
                        //显示位语句
                        }
                        break;

                        case 1:                               
                        //显示段语句
                        if((a==2)&(count<500))//满足两个条件执行以下语句,a=键值
                        {
                        //关闭位语句
                        }
                        else
                        {
                        //显示位语句
                        }
                        break;

                        case 2:                               
                        //显示段语句
                        if((a==3)&(count<500))//满足两个条件执行以下语句,a=键值
                        {
                        //关闭位语句
                        }
                        else
                        {
                        //显示位语句
                        }
                        break;

                        case 3:                                       
                        //显示段语句
                        if((a==4)&(count<500))//满足两个条件执行以下语句,a=键值
                        {
                        //关闭位语句
                        }
                        else
                        {
                        //显示位语句
                        }
                        break;
                }
        }
}
举报

人中狼

2017-7-13 15:36:22
你这不是加延时的问题,而是要增加一个闪烁用的定时,然后在正常的数码管显示程序里根据闪烁定时和需要闪烁的位来控制该位数码管的亮与不亮,来形成闪烁
举报

武林

2017-7-13 16:59:44
本帖最后由 wulinwl 于 2017-7-13 17:51 编辑

正常数码管动态显示为避免闪烁需要每一位显示时间约1ms,8位显示一轮约10ms。如果刻意需要某一位数码管在特定时间处于1s周期闪烁,也就是说该位数码管500ms同其他一样发光,500ms处于熄灭状态。这最好用定时器中断来处理数码管动态显示程序。由按键程序得到的设定位置变量与数码管动态显示的位变量加时间变量来确定某一位数码管发光或熄灭。这个程序不难,但切不可用delay软件延时处理。否则所有数码管都闪烁或不亮。给你一个思路例程参考。/******定时器0初始化程序******/
void Timer0Init(void)                //1毫秒@12.000MHz
{
        TMOD = 0x01;                        //设置定时器模式
        TL0 = 0x18;                                //设置定时初值
        TH0 = 0xFC;                                //设置定时初值
        TR0 = 1;                                //定时器0开始计时
        EA=1;                                        //开总中断
        ET0=1;                                        //开定时器0中断       
}
/******定时器0中断服务程序******/
void timer0() interrupt 1       
{
        TL0 = 0x18;                                //设置定重载值
        TH0 = 0xFC;                                //设置定重载值
        Cnt_ms++;                                //1ms变量自+1
        if(Cnt_ms>=1000)                //1秒
        {
                Cnt_ms=0;
                count++;                        //轮流显示计数
                if(count>=4)                //显示程序
                {
                        count=0;
                        switch(count)
                        {
                                case 0:
                                //显示段语句
                                //显示位前先判断条件,下同
                                if((a==1)&(count<500))//满足两个条件执行以下语句,a=键值0~4,0为初始态,这里无效
                                {
                                //关闭位语句
                                }
                                else
                                {
                                //显示位语句
                                }
                                break;

                                case 1:                               
                                //显示段语句
                                if((a==2)&(count<500))//满足两个条件执行以下语句,a=键值
                                {
                                //关闭位语句
                                }
                                else
                                {
                                //显示位语句
                                }
                                break;

                                case 2:                               
                                //显示段语句
                                if((a==3)&(count<500))//满足两个条件执行以下语句,a=键值
                                {
                                //关闭位语句
                                }
                                else
                                {
                                //显示位语句
                                }
                                break;

                                case 3:                                       
                                //显示段语句
                                if((a==4)&(count<500))//满足两个条件执行以下语句,a=键值
                                {
                                //关闭位语句
                                }
                                else
                                {
                                //显示位语句
                                }
                                break;
                        }
                }
        }
}



补充内容 (2017-7-14 15:54):
程序有错误,5楼是更改后的程序。
举报

人中狼

2017-7-13 21:44:40
这里先定义一个概念,闪烁就是指需要闪烁的数码管在固定的周期内进行显示和关闭的交替动作。
这里有一个时间,就是闪烁周期,这个周期可以自己定义,并进行调节,以达到合适的效果。
闪烁的实现就是在数码管正常的显示过程中要判断是否需要闪烁,需要闪烁的是哪一位数码管,当前需要进行的是显示需要闪烁的数码管,还是要关闭需要闪烁的数码管。
至于闪烁动作的移动,也就是更改需要闪烁的数码管的位号即可。
举报

曲终人散

2017-7-15 12:57:17
楼上各位回答都很棒
举报

houjue

2017-10-5 08:08:59
意思表达清晰,思路也就出来了~~~~~
举报

更多回帖

发帖
×
20
完善资料,
赚取积分