打印

595驱动数码管的问题

[复制链接]
5947|17
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
ddtx|  楼主 | 2010-4-16 14:27 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
今天写595驱动数码管程序,可以刷新显示,但是我突然想到,如果主程序中其他东西比价多,那么我的数码刷新频率不够的话,显示不是断断续续么,难道要专门做一个定时器中断去刷新数码管么,那样感觉很浪费资源呀。不知道大家都是怎么通过595控制数码管刷新的。

相关帖子

沙发
odqqdo| | 2010-4-16 14:34 | 只看该作者
静态的(就是一片595接一个数码管)多久刷一次都不会闪,动态的超过一定时间(20MS以上)刷一次会闪

使用特权

评论回复
板凳
ddtx|  楼主 | 2010-4-16 14:37 | 只看该作者
这个我也知道呀,我就是奇怪,我看别人的板子上没那么多595的,主程序运行的时候不会影响显示程序么,或者他们用的是别的芯片,我看有些芯片有自己的内部寄存器,可以存8个字节,自动刷新8个数码管。,

使用特权

评论回复
地板
123654789| | 2010-4-16 14:42 | 只看该作者
搞笑

使用特权

评论回复
5
ddtx|  楼主 | 2010-4-16 14:44 | 只看该作者
什么意思,问题太简单不愿意回答么

使用特权

评论回复
6
pinyione| | 2010-4-16 14:48 | 只看该作者
用BC7281

使用特权

评论回复
7
ddtx|  楼主 | 2010-4-16 14:52 | 只看该作者
其实我这边一直用的是CH452的数码管芯片,我就是想,有没有只用一个595实现数码管刷新不影响主系统运行的可行性

使用特权

评论回复
8
zusen| | 2010-4-16 15:01 | 只看该作者
呵呵,如果在主程序中刷新,必虽保证1S有50帧以上,程序的运行用不了多少时间,就是延时程序占时间比较多,可以用心跳时钟的方法来延时。

方法二就是用定时器了,以16行来说,1S/50/16约=1MS扫一行,如果单片机一指命是1uS 那么1S可执行500X1000条指命,那么效率也算不错的了

使用特权

评论回复
9
ddtx|  楼主 | 2010-4-16 15:05 | 只看该作者
我刚开始的想法就是用自动重装的定时器,然后写一个标志位,重装N次了就刷新一次,还没试过,不知道效果怎么样。

使用特权

评论回复
10
ddtx|  楼主 | 2010-4-16 15:06 | 只看该作者
心跳时钟的方法是什么方法,求教,没听过

使用特权

评论回复
11
znmcu| | 2010-4-16 16:10 | 只看该作者
你可以参见 《单片机基础外设9日通》视频教程的第5日课程《数码管》

595驱动4位数码管实验演示:
http://v.youku.com/v_playlist/f4300667o1p6.html

数字温度计实验演示:
http://v.youku.com/v_playlist/f4321694o1p0.html

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
ddtx + 1
12
老老实实| | 2010-4-16 16:26 | 只看该作者
哈哈,刚好前一段时间俺在琢磨模块化变成的时候,也是和LZ有一样的疑惑,但是后来经过高手的指点和自己的摸索,也有所感悟,在这里也介绍给LZ琢磨琢磨,同时也希望大家也点评点评哦!(欢迎大虾猛的拍砖)

对于数码管的刷新,我一般都是这么做的。首先先建立一个缓冲区,用来存放数码管要显示的数据
然后在定时器中设立一个标志位,譬如说10ms(当然这个时间,是需要自己调整的),然后隔10ms,刷新一次数码管的缓冲区。而数码管什么都不用管,只需要从缓冲区取出自己需要显示的内容就可以了。
当然,你的程序中如果有别的模块的话,譬如说led的闪烁等等这些,都需要用定时器设立标志位的方式,来进行刷新。否则别的模块必然会占用CPU过多的时间,而出现数码管刷新不够快而闪烁的问题啦
如果整个工程都是采取这种方式的话。数码管的刷新问题解决了,同时程序中别的模块也会很有序的依次执行,相互的影响也会大大的减小。
附代码(欢迎大虾拍砖哦!:))

#include"digi.h"
#include"timer0.h"
#include"mylib.h"
#include"led.h"


bit Digi_Flag_2Ms=0;
bit Digi_Flag_1S=0;
//uint counter = 0;
uchar Digi_Buffer[3]={0x5b,0x6d,0x3f};                 //定义的缓冲区

uchar code Digi_SegCode[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f };



void Digi_LoadValue(uint value)
{
        Timer0_Stop();
//        Led_1 = 0;
        Digi_Buffer[0] = Digi_SegCode[value%10];
        Digi_Buffer[1] = Digi_SegCode[(value/10)%10];
        Digi_Buffer[2] = Digi_SegCode[value/100];
        Timer0_Start();
}



void Digi_Display()
{
        static uchar s = 0;
        static uchar t = 0;
        if(Digi_Flag_2Ms == 1)
        {
                Digi_Flag_2Ms = 0;


                switch(s)
                {
                        case 0:
                                        {
                                                P1 = Digi_Buffer[0];
                                                Digi_W1 = 1;
                                                Digi_W2 = 1;
                                                Digi_W3 = 0;

                                        }
                        break;
                       
                        case 1:
                                        {
                                                P1 = Digi_Buffer[1];
                                                Digi_W1 = 1;
                                                Digi_W2 = 0;
                                                Digi_W3 = 1;

                                        }                               
                        break;

                        case 2:
                                        {
                                                P1 = Digi_Buffer[2];
                                                Digi_W1 = 0;
                                                Digi_W2 = 1;
                                                Digi_W3 = 1;
//                                                Led_2 = 0;
                                        }
                        break;
                }
               
                s++;
                t++;
                if(s == 3)
                {
                        s = 0;
                }
               
                if(t == 50)
                {
                        t=0;
                        Digi_Flag_1S = 1;

                }
                       
        }
}


void Digi_Run()                                                //简单的数码管计数函数
{
        static uint counter = 0;

        if(Digi_Flag_1S == 1)
        {
                Timer0_Stop();
                Digi_Flag_1S = 0;
                counter ++;

                Digi_LoadValue(counter);
                if(counter == 999)
                {
                        counter = 0;
                        Led_2 = 0;
                }
                Timer0_Start();

        }
}

主函数:
void main()
{
        Key_Init();
        Led_Init();
    Timer0_Init();
        while(1)
        {

                Key_Do();                                //按键的扫描
                Led1_State_Change();           
                Led1_Process();                      //led1的闪烁子函数
                Led2_State_Change();
                Led2_Process();
                Digi_Run();                //更新缓冲区
                Digi_Display();                //显示
        }
}

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
ddtx + 1
13
ddtx|  楼主 | 2010-4-16 16:50 | 只看该作者
谢谢,想明白了, 哈哈,这样省好多时间了。

使用特权

评论回复
14
maychang| | 2010-4-16 19:48 | 只看该作者
4楼说得好。
这与595有什么关系?

使用特权

评论回复
15
chxi| | 2010-4-17 17:50 | 只看该作者
要用定时刷新,定时刷新稳定没有闪烁现象。

使用特权

评论回复
16
epsmc| | 2010-4-17 18:43 | 只看该作者
595带有锁存器,显示内容不变就不需要刷新的。

使用特权

评论回复
17
efen| | 2010-4-17 19:21 | 只看该作者
mark

使用特权

评论回复
18
shuiqinghan2012| | 2016-1-22 17:17 | 只看该作者
mark

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

4

主题

312

帖子

1

粉丝