发新帖本帖赏金 10.00元(功能说明)我要提问
12
返回列表
打印
[STM32]

求助各位坛友:定时器2ms数码管动态显示 3位数只显示最...

[复制链接]
楼主: qmmdzd
手机看帖
扫描二维码
随时随地手机跟帖
21
qmmdzd 发表于 2018-4-7 20:52
不用驱动芯片是不是会麻烦很多呢?求显示程序上的指点

显示中的delayms(1)与定时器中断时间可能木有协调好:
建议:把变量i去掉,把显示函数直接放在中断里面,调试成功后,再选取恰当的时间平衡点加入变量I

使用特权

评论回复
22
qmmdzd|  楼主 | 2018-4-7 21:31 | 只看该作者
本菜菜把程序发上来,麻烦各位坛友有时间帮忙看下,堵在这一段时间了,谢谢大家了

数码管显示.zip

2.69 MB

使用特权

评论回复
23
jinglixixi| | 2018-4-8 08:22 | 只看该作者
qmmdzd 发表于 2018-4-7 13:04
也就是把K设置为全局变量?Display中的K的for循环也用改吗?

把K设置为全局变量,将for循环改为if(k<3)判别处理,if(k==3) k=0.来试一试,如果无变化说明问题在其它地方。

使用特权

评论回复
24
qmmdzd|  楼主 | 2018-4-8 09:28 | 只看该作者
jinglixixi 发表于 2018-4-8 08:22
把K设置为全局变量,将for循环改为if(k

请问坛友,如果我中断一次显示一个数码管程序该如何写呢?我试了下你说的这种,还是不行,我现在的程序是中断一次扫描三只管 可能这样有问题

使用特权

评论回复
25
m564522634| | 2018-4-8 09:41 | 只看该作者
这驱动写的太差了不想看了

使用特权

评论回复
26
qmmdzd|  楼主 | 2018-4-8 10:11 | 只看该作者
m564522634 发表于 2018-4-8 09:41
这驱动写的太差了不想看了

麻烦坛友直接给写个显示三位数的函数吧

使用特权

评论回复
27
qmmdzd|  楼主 | 2018-4-8 10:40 | 只看该作者
山东电子小菜鸟 发表于 2018-4-7 20:56
显示中的delayms(1)与定时器中断时间可能木有协调好:
建议:把变量i去掉,把显示函数直接放在中断里面 ...

麻烦坛友给配置个一次中断显示一位数码管的程序吧  可能我这种写法本身就有问题

使用特权

评论回复
28
datouyuan| | 2018-4-8 13:49 | 只看该作者
本帖最后由 datouyuan 于 2018-4-8 13:50 编辑
qmmdzd 发表于 2018-4-6 22:00
void Isr_Init()
{
        NVIC_InitTypeDef NVIC_InitStructure;
u8 DisPlayBuff[3];//
void DisPlayDrv(void)//3位数码驱动,间隔1~5mS执行一次
{  
        static u8 k=0;

        GPIO_SetBits(GPIOF,GPIO_Pin_13|GPIO_Pin_12|GPIO_Pin_11);//关闭段选
        GPIO_SetBits(GPIOE,GPIO_Pin_15|GPIO_Pin_14|GPIO_Pin_13|GPIO_Pin_12|GPIO_Pin_11|GPIO_Pin_9|GPIO_Pin_8|GPIO_Pin_7);//关闭位选
        switch (k)  
        {  
                case 0:  
                GPIO_ResetBits(GPIOF,GPIO_Pin_13);  //GPIO_Write(GPIOE,table[n % 10]); n=n/10; //显示个位
                break;  
               
                case 1:  
                GPIO_ResetBits(GPIOF,GPIO_Pin_12); //GPIO_Write(GPIOE,table[n % 10]); n=n/10; //显示十位
                break;  
               
                case 2:  
                GPIO_ResetBits(GPIOF,GPIO_Pin_11); //GPIO_Write(GPIOE,table[n % 10]); n=n/10; //显示百位
                break;                 
        }
        switch (DisPlayBuff[k])  //分别取余写入段选
        {  
                case 0:  
                GPIO_Write(GPIOE,table[0]);   
                break;  
                case 1:                                                      
                GPIO_Write(GPIOE,table[1]);
                break;  
                case 2:  
                GPIO_Write(GPIOE,table[2]);  
                break;  
                case 3:  
                GPIO_Write(GPIOE,table[3]);  
                break;  
                case 4:  
                GPIO_Write(GPIOE,table[4]);
                break;  
                case 5:  
                GPIO_Write(GPIOE,table[5]);  
                break;  
                case 6:  
                GPIO_Write(GPIOE,table[6]);  
                break;  
                case 7:  
                GPIO_Write(GPIOE,table[7]);  
                break;  
                case 8:  
                GPIO_Write(GPIOE,table[8]);  
                break;  
                case 9:  
                GPIO_Write(GPIOE,table[9]);  
                break;  
                default:
                //空显示的IO口操作
                break;
        }
        k++;
        if(3==k) k=0;
}  

帮你改成了每次显示一段。
假如某一段不显示,这个时间不能省略,否则会造成显示亮度变化。如显示“1”比显示“100”亮3倍。

使用特权

评论回复

打赏榜单

qmmdzd 打赏了 5.00 元 2018-04-09
理由:感谢相助

29
datouyuan| | 2018-4-8 14:29 | 只看该作者
本帖最后由 datouyuan 于 2018-4-8 14:41 编辑
void DisPlayNum(u16 n) 
{  
        u8 k;
        if (n < 1000)  
        {
                //关中断
                for (k=0;k<3;k++)  //位选择循环,K=0对应个位数据,K=1对应十位数据,K=2对应百位
                {  
                        DisPlayBuff[k]=(n % 10);
                        n = n / 10;
                }  

                //前面的0不显示
                if(DisPlayBuff[2]==0)
                {
                        DisPlayBuff[2]=255;//
                        if(DisPlayBuff[1]==0) DisPlayBuff[1]=255;
                }
                //开中断
        }

}


另外,显示驱动把“ switch (DisPlayBuff[k])”放到“ switch (k)”前面要好些,先准备好数据再切换显示。

使用特权

评论回复
30
datouyuan| | 2018-4-8 14:50 | 只看该作者
楼主的“ switch (DisPlayBuff[k])”这么有规律,
改成“if(DisPlayBuff[k]<10) GPIO_Write(GPIOE,table[DisPlayBuff[k]]);”
看着多舒服。

使用特权

评论回复
31
qmmdzd|  楼主 | 2018-4-8 22:31 | 只看该作者
datouyuan 发表于 2018-4-8 14:29
另外,显示驱动把“ switch (DisPlayBuff[k])”放到“ switch (k)”前面要好些,先准备好数据再切换显示 ...

感谢坛友相助  明天早上去试试,今天有事来着回复晚了,再次感谢

使用特权

评论回复
32
xch| | 2018-4-8 23:32 | 只看该作者
qmmdzd 发表于 2018-4-6 22:00
void Isr_Init()
{
        NVIC_InitTypeDef NVIC_InitStructure;

改成这样子
void DisPlayNum(int n)
{
        static int k=0;
        int digi =0;
       
    if (n >= 1000){k=0;return} ;  

        GPIO_SetBits(GPIOF,GPIO_Pin_13|GPIO_Pin_12|GPIO_Pin_11);//关闭所有数码管位选
        GPIO_SetBits(GPIOE,GPIO_Pin_15|GPIO_Pin_14|GPIO_Pin_13|GPIO_Pin_12|GPIO_Pin_11|GPIO_Pin_9|GPIO_Pin_8|GPIO_Pin_7);//关闭所有段选

        switch (k)  //0-2循环,选中位选
        {  
                case 0:  
                        GPIO_ResetBits(GPIOF,GPIO_Pin_13);
                        digi = n %10;
                       
                        break;  
                case 1:  
                        GPIO_ResetBits(GPIOF,GPIO_Pin_12);  
                        digi = (n/10)%10;
                       
                        break;  
                case 2:  
                        GPIO_ResetBits(GPIOF,GPIO_Pin_11);
                        digi = (n/100)%10;
                        break;                 
        }
       
        GPIO_Write(GPIOE,table[digi]);
        k++;
        if (k>2) k=0;
}

使用特权

评论回复

打赏榜单

qmmdzd 打赏了 5.00 元 2018-04-09
理由:采用你的这个写法,成功了,感谢相助

评论
xch 2018-4-9 11:59 回复TA
这个程序不够优化。还可以化简些。 
33
qmmdzd|  楼主 | 2018-4-9 09:33 | 只看该作者
调试成功了,采用了xch写法,一会再试试datouyuan的写法,再次感谢所有回帖的坛友

使用特权

评论回复
34
jinglixixi| | 2018-4-9 11:35 | 只看该作者
qmmdzd 发表于 2018-4-8 09:28
请问坛友,如果我中断一次显示一个数码管程序该如何写呢?我试了下你说的这种,还是不行,我现在的程序是 ...

将显示位置的计时器K放到中断中,中断一次,变更一下显示位置可能会管用。

使用特权

评论回复
35
datouyuan| | 2018-4-9 17:21 | 只看该作者
qmmdzd 发表于 2018-4-9 09:33
调试成功了,采用了xch写法,一会再试试datouyuan的写法,再次感谢所有回帖的坛友 ...

你那种写法非标,是通过给全局变量n赋值来改变显示。

我的这种写法是通用的方法,需要更改显示内容就调用DisPlayNum(x)函数来改变显示缓存,不需要全局变量n。

使用特权

评论回复
36
sum123456| | 2018-4-11 14:41 | 只看该作者

几十个us够了吗?你有个delayms的函数,起码执行一次,最少3ms,程序的可读性太差了,i居然当做全局变量,你这样写,只要i为0的时候,才执行扫描一遍显示函数,都超过定时器时间了,太乱了。

使用特权

评论回复
37
logical_lu| | 2018-4-11 15:26 | 只看该作者
     很简单啊,显示123,点亮第一个数码管,然后输入1,延时2ms,然后点亮第二个数码管显示2,延时2ms,再点亮第三个数码管,延时2ms, 数码管需要循环刷新,不像液晶直接点亮就可以了。

使用特权

评论回复
38
logical_lu| | 2018-4-11 15:36 | 只看该作者
sum123456 发表于 2018-4-11 14:41
几十个us够了吗?你有个delayms的函数,起码执行一次,最少3ms,程序的可读性太差了,i居然当做全局变量, ...

大概500us就可以了

使用特权

评论回复
39
qmmdzd|  楼主 | 2018-4-12 21:26 | 只看该作者
z273286744 发表于 2018-4-12 13:36
这个好贴千万别沉了

这驱动写不好,不过坛友的回复都给力

使用特权

评论回复
发新帖 本帖赏金 10.00元(功能说明)我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则