OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6445|回复: 38

STM32直接驱动数码管问题。

[复制链接]

17

主题

181

帖子

0

精华

高级会员

Rank: 4

积分
503
金钱
503
注册时间
2017-7-24
在线时间
117 小时
发表于 2017-8-11 11:18:06 | 显示全部楼层 |阅读模式
5金钱
本人尝试着自己写直接驱动数码管代码,但是发现了一个很无语的问题,就是四个数第一个总是不亮,且带有轻微鬼影,网上查到的许多方法实验后没用。比如显示2981,981正常显示,但是2就特别暗且带鬼影。求大神指点!!

附上代码:
SMG.c 代码
#include "SMG.h"
#include "stm32f10x.h"
#include "delay.h"

void SMG_Init(void)
{
            //为方便大家看,此处代码省略,其作用是定义IO口 PB4-PB15,其中PB4-PB7是位选,PB8-PB15是段选
}

void DisPlayNum(int n)  
{  
    if (n < 9999)  
    { int i;  
        int s;   
        s = n;  
        i=0;  
        for (i=0;i<4;i++)  
        {  
            GPIO_ResetBits(GPIOB,        GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|                      //Reset所有IO口
                                                                                                                                                    GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11|
                                                                                                                                                    GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15 );  
            switch (i)                                                 //位选
            {  
                case 0:  
                    GPIO_SetBits(GPIOB,GPIO_Pin_7);  
                    break;  
                case 1:  
                    GPIO_SetBits(GPIOB,GPIO_Pin_6);  
                    break;  
                case 2:  
                    GPIO_SetBits(GPIOB,GPIO_Pin_5);  
                    break;  
                case 3:  
                    GPIO_SetBits(GPIOB,GPIO_Pin_4);  
                    break;  
                        }  
            switch (s % 10)                                    //段选
            {  
                case 0:  
                    GPIO_SetBits(GPIOB,GPIO_Pin_14|GPIO_Pin_15);                                                                   // 0
                                                                                break;  
                case 1:  
                    GPIO_SetBits(GPIOB,GPIO_Pin_8|GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15); // 1
                    break;  
                case 2:  
                    GPIO_SetBits(GPIOB,GPIO_Pin_10|GPIO_Pin_13|GPIO_Pin_15);                                                                                                                                          // 2
                    break;  
                case 3:  
                    GPIO_SetBits(GPIOB,GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_15);                                                                                                                                          // 3
                    break;  
                case 4:  
                    GPIO_SetBits(GPIOB,GPIO_Pin_8|GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_15);                                                                                                  // 4
                    break;  
                case 5:  
                    GPIO_SetBits(GPIOB,GPIO_Pin_9|GPIO_Pin_12|GPIO_Pin_15);                                                                                                                                                  // 5
                    break;  
                case 6:  
                    GPIO_SetBits(GPIOB,GPIO_Pin_9|GPIO_Pin_15);                                                                                                                                                                                                  // 6
                    break;  
                case 7:  
                    GPIO_SetBits(GPIOB,GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);                                          // 7
                    break;  
                case 8:  
                    GPIO_SetBits(GPIOB,GPIO_Pin_15);                                                                                                                                                                                                                                          // 8
                    break;  
                case 9:  
                    GPIO_SetBits(GPIOB,GPIO_Pin_12|GPIO_Pin_15);                                                                                                                                                                                          // 9
                    break;  
            }     
            s = s / 10;  
            delay_ms(5);

                                                if (s==0)  
                break;  
        }      
    }  
}

main.c代码:
此处省略include部分和Init部分

int main(void)
{
while(1)
{
        DisPlayNum(2981);
        delay_ms(5);
}
}


862356133023315574.jpg

最佳答案

查看完整内容[请看2#楼]

好好看看PB4他的功能 PB4 I/O FT NJTRST 你不知道调试端口是不能直接作为IO口的么?
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

4

主题

349

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1046
金钱
1046
注册时间
2017-5-19
在线时间
335 小时
发表于 2017-8-11 11:18:07 | 显示全部楼层
好好看看PB4他的功能    PB4 I/O FT NJTRST    你不知道调试端口是不能直接作为IO口的么?
回复

使用道具 举报

17

主题

181

帖子

0

精华

高级会员

Rank: 4

积分
503
金钱
503
注册时间
2017-7-24
在线时间
117 小时
 楼主| 发表于 2017-8-11 12:41:14 | 显示全部楼层
经测试,初步断定是GPIOB_PIN4管脚的问题,但是为什么我用PB4管脚就会暗,而用其他的就没有问题,有没有可能和管脚复用有关系?但是我没开启管脚复用啊。求解答
回复

使用道具 举报

4

主题

349

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1046
金钱
1046
注册时间
2017-5-19
在线时间
335 小时
发表于 2017-8-11 13:19:42 | 显示全部楼层
本帖最后由 wxjhby 于 2017-8-11 13:21 编辑

PB4 I/O FT NJTRST  
回复

使用道具 举报

0

主题

207

帖子

0

精华

高级会员

Rank: 4

积分
959
金钱
959
注册时间
2017-5-27
在线时间
108 小时
发表于 2017-8-11 13:56:32 | 显示全部楼层
wxjhby 发表于 2017-8-11 13:20
好好看看PB4他的功能    PB4 I/O FT NJTRST    你不知道调试端口是不能直接作为IO口的么?

也不能说 不能当IO口用,在关掉调试功能的时候还是可以用的吗
回复

使用道具 举报

17

主题

181

帖子

0

精华

高级会员

Rank: 4

积分
503
金钱
503
注册时间
2017-7-24
在线时间
117 小时
 楼主| 发表于 2017-8-11 13:59:16 | 显示全部楼层
wxjhby 发表于 2017-8-11 13:20
好好看看PB4他的功能    PB4 I/O FT NJTRST    你不知道调试端口是不能直接作为IO口的么?

非常感谢,我还有个疑问,我看有人提议说用定时器来驱动数码管显示,两者有什么区别么?
回复

使用道具 举报

4

主题

349

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1046
金钱
1046
注册时间
2017-5-19
在线时间
335 小时
发表于 2017-8-11 14:27:06 | 显示全部楼层
q247341184 发表于 2017-8-11 13:59
非常感谢,我还有个疑问,我看有人提议说用定时器来驱动数码管显示,两者有什么区别么?

5ms 可以做好多事情了,定时器定时,程序可以做其他事情
回复

使用道具 举报

6

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
124
金钱
124
注册时间
2017-8-7
在线时间
26 小时
发表于 2017-8-11 15:10:12 | 显示全部楼层
q247341184 发表于 2017-8-11 13:59
非常感谢,我还有个疑问,我看有人提议说用定时器来驱动数码管显示,两者有什么区别么?

定时器驱动数码管,数码管的变化会非常准确,比如说设计个数字钟呀之类的。
回复

使用道具 举报

6

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
124
金钱
124
注册时间
2017-8-7
在线时间
26 小时
发表于 2017-8-11 15:18:20 | 显示全部楼层
看了一下你的程序,第一位才是最后处理的。那会不会是因为延时短了呀?delay_ms(10)试试。
回复

使用道具 举报

17

主题

181

帖子

0

精华

高级会员

Rank: 4

积分
503
金钱
503
注册时间
2017-7-24
在线时间
117 小时
 楼主| 发表于 2017-8-11 15:24:55 | 显示全部楼层
3314lzp 发表于 2017-8-11 15:18
看了一下你的程序,第一位才是最后处理的。那会不会是因为延时短了呀?delay_ms(10)试试。

我试过很多次了,5,、10、15、20都是一样的现象,差别在于闪烁与否。而且我试了一下其他的IO口,我发现在其他IO口时候是没问题的。所以我才觉得管脚问题,但是由于布线,我必须放在这,那如果我要是关了GPIO的复用功能就是NJTRST功能的话有用嘛?
回复

使用道具 举报

17

主题

181

帖子

0

精华

高级会员

Rank: 4

积分
503
金钱
503
注册时间
2017-7-24
在线时间
117 小时
 楼主| 发表于 2017-8-11 15:26:02 | 显示全部楼层
wxjhby 发表于 2017-8-11 14:27
5ms 可以做好多事情了,定时器定时,程序可以做其他事情

求指点思路!!!!
回复

使用道具 举报

17

主题

181

帖子

0

精华

高级会员

Rank: 4

积分
503
金钱
503
注册时间
2017-7-24
在线时间
117 小时
 楼主| 发表于 2017-8-11 15:27:15 | 显示全部楼层
3314lzp 发表于 2017-8-11 15:10
定时器驱动数码管,数码管的变化会非常准确,比如说设计个数字钟呀之类的。

我用的是内部的时钟源,内部的时钟源本身就会具备相对较大的误差,而且我在做的应该不会太精确的要求时钟,那是不是可以就用我现在写出的这种方法来执行呢?
回复

使用道具 举报

81

主题

1002

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1876
金钱
1876
注册时间
2014-9-10
在线时间
208 小时
发表于 2017-8-11 15:31:13 | 显示全部楼层
不亮的时候,是拉高阴极还是拉低阳极
小小蜗牛
回复

使用道具 举报

4

主题

349

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1046
金钱
1046
注册时间
2017-5-19
在线时间
335 小时
发表于 2017-8-11 15:32:04 | 显示全部楼层
q247341184 发表于 2017-8-11 15:26
求指点思路!!!!

把显示函数放到定时器中断里面,多少ms自己试试, 然后把软件延时去掉  你试试看呗   消影应该也要做一下的
回复

使用道具 举报

17

主题

181

帖子

0

精华

高级会员

Rank: 4

积分
503
金钱
503
注册时间
2017-7-24
在线时间
117 小时
 楼主| 发表于 2017-8-11 15:35:10 | 显示全部楼层
wxjhby 发表于 2017-8-11 15:32
把显示函数放到定时器中断里面,多少ms自己试试, 然后把软件延时去掉  你试试看呗   消影应该也要做一下 ...

我看网上例程的消影,好像都是把段选置1,或者位选置0,就是熄灭了,再点亮,我的函数里在位选之前有个大的resetbits(),思路大概就是这样= =,能当做消影吗?
回复

使用道具 举报

17

主题

181

帖子

0

精华

高级会员

Rank: 4

积分
503
金钱
503
注册时间
2017-7-24
在线时间
117 小时
 楼主| 发表于 2017-8-11 15:36:11 | 显示全部楼层
jiutianshenjian 发表于 2017-8-11 15:31
不亮的时候,是拉高阴极还是拉低阳极

正常的推挽输出就不亮,确切的说是不是很亮,没有外接上拉或者下拉。
回复

使用道具 举报

6

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
124
金钱
124
注册时间
2017-8-7
在线时间
26 小时
发表于 2017-8-11 15:37:43 | 显示全部楼层
q247341184 发表于 2017-8-11 15:27
我用的是内部的时钟源,内部的时钟源本身就会具备相对较大的误差,而且我在做的应该不会太精确的要求时钟 ...

不太清楚,不过还是建议使用外部晶振。
回复

使用道具 举报

17

主题

181

帖子

0

精华

高级会员

Rank: 4

积分
503
金钱
503
注册时间
2017-7-24
在线时间
117 小时
 楼主| 发表于 2017-8-11 15:37:53 | 显示全部楼层
q247341184 发表于 2017-8-11 15:35
我看网上例程的消影,好像都是把段选置1,或者位选置0,就是熄灭了,再点亮,我的函数里在位选之前有个大 ...

还有,我看手册上,好像PB4的主要功能是NJTRST,而复用功能是个其他的,remap里才是PB4。那我如果要用PB4的话是不是在显示代码里 配置一下重映射就行?
回复

使用道具 举报

17

主题

181

帖子

0

精华

高级会员

Rank: 4

积分
503
金钱
503
注册时间
2017-7-24
在线时间
117 小时
 楼主| 发表于 2017-8-11 15:38:20 | 显示全部楼层
wxjhby 发表于 2017-8-11 13:20
好好看看PB4他的功能    PB4 I/O FT NJTRST    你不知道调试端口是不能直接作为IO口的么?

我看手册上,好像PB4的主要功能是NJTRST,而复用功能是个其他的,remap里才是PB4。那我如果要用PB4的话是不是在显示代码里 配置一下重映射就行?
回复

使用道具 举报

17

主题

181

帖子

0

精华

高级会员

Rank: 4

积分
503
金钱
503
注册时间
2017-7-24
在线时间
117 小时
 楼主| 发表于 2017-8-11 15:38:31 | 显示全部楼层
lanlzp 发表于 2017-8-11 13:56
也不能说 不能当IO口用,在关掉调试功能的时候还是可以用的吗

我看手册上,好像PB4的主要功能是NJTRST,而复用功能是个其他的,remap里才是PB4。那我如果要用PB4的话是不是在显示代码里 配置一下重映射就行?
回复

使用道具 举报

81

主题

1002

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1876
金钱
1876
注册时间
2014-9-10
在线时间
208 小时
发表于 2017-8-11 15:39:24 | 显示全部楼层
本帖最后由 jiutianshenjian 于 2017-8-11 15:42 编辑
q247341184 发表于 2017-8-11 15:36
正常的推挽输出就不亮,确切的说是不是很亮,没有外接上拉或者下拉。

亮和灭如何控制的?你第一位数字2,间隔10ms其他间隔5ms。
break判断放到延时前面。
小小蜗牛
回复

使用道具 举报

17

主题

181

帖子

0

精华

高级会员

Rank: 4

积分
503
金钱
503
注册时间
2017-7-24
在线时间
117 小时
 楼主| 发表于 2017-8-11 15:39:36 | 显示全部楼层
3314lzp 发表于 2017-8-11 15:37
不太清楚,不过还是建议使用外部晶振。

0.0.。。。非常感谢。。
回复

使用道具 举报

17

主题

181

帖子

0

精华

高级会员

Rank: 4

积分
503
金钱
503
注册时间
2017-7-24
在线时间
117 小时
 楼主| 发表于 2017-8-11 15:40:22 | 显示全部楼层
jiutianshenjian 发表于 2017-8-11 15:39
亮和灭如何控制的?

就是IO口置0或者1.直接连的板子。
回复

使用道具 举报

81

主题

1002

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1876
金钱
1876
注册时间
2014-9-10
在线时间
208 小时
发表于 2017-8-11 15:46:11 | 显示全部楼层
q247341184 发表于 2017-8-11 15:40
就是IO口置0或者1.直接连的板子。

你没懂我的意思,我以前做的也有微亮,但是本来应该灭的。
当初找到原因是灭时我拉高了阴极,这样是不合适的。灭时拉低阳极就好了。
你的可能是延时问题,可能没碰到我那种情况。
小小蜗牛
回复

使用道具 举报

17

主题

181

帖子

0

精华

高级会员

Rank: 4

积分
503
金钱
503
注册时间
2017-7-24
在线时间
117 小时
 楼主| 发表于 2017-8-11 15:55:52 | 显示全部楼层
jiutianshenjian 发表于 2017-8-11 15:46
你没懂我的意思,我以前做的也有微亮,但是本来应该灭的。
当初找到原因是灭时我拉高了阴极,这样是不合 ...

可能是不太一样,不过也算长见识了,也许会遇到你的情况,到时候就用你的方法解决就好了
回复

使用道具 举报

81

主题

1002

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1876
金钱
1876
注册时间
2014-9-10
在线时间
208 小时
发表于 2017-8-11 16:02:04 | 显示全部楼层
你用的哪个型号数码管,为什么都是输出高呢?
小小蜗牛
回复

使用道具 举报

4

主题

349

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1046
金钱
1046
注册时间
2017-5-19
在线时间
335 小时
发表于 2017-8-11 16:02:25 | 显示全部楼层
本帖最后由 wxjhby 于 2017-8-11 16:03 编辑

GPIO_PinRemapConfig(GPIO_Remap_SWJ_NoJTRST, ENABLE);     

把JTRST关掉  你试试
回复

使用道具 举报

5

主题

48

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
333
金钱
333
注册时间
2015-2-9
在线时间
92 小时
发表于 2017-8-11 16:08:10 | 显示全部楼层
PB4上电默认是JTAG功能。。你配置IO口前先把JTAG关掉就可以了

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable , ENABLE);
// 改变指定管脚的映射 GPIO_Remap_SWJ_JTAGDisable ,JTAG-DP 禁用 + SW-DP 使能
2.png
回复

使用道具 举报

17

主题

181

帖子

0

精华

高级会员

Rank: 4

积分
503
金钱
503
注册时间
2017-7-24
在线时间
117 小时
 楼主| 发表于 2017-8-11 16:10:52 | 显示全部楼层
wxjhby 发表于 2017-8-11 13:20
好好看看PB4他的功能    PB4 I/O FT NJTRST    你不知道调试端口是不能直接作为IO口的么?

老铁,我把PB4的 JTRST关了,发现另一个情况,就是原先不亮的变得最亮了,其他三位反倒暗淡了
回复

使用道具 举报

17

主题

181

帖子

0

精华

高级会员

Rank: 4

积分
503
金钱
503
注册时间
2017-7-24
在线时间
117 小时
 楼主| 发表于 2017-8-11 16:11:45 | 显示全部楼层
jiutianshenjian 发表于 2017-8-11 16:02
你用的哪个型号数码管,为什么都是输出高呢?

MT03641BR。
回复

使用道具 举报

81

主题

1002

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1876
金钱
1876
注册时间
2014-9-10
在线时间
208 小时
发表于 2017-8-11 16:13:01 | 显示全部楼层
q247341184 发表于 2017-8-11 16:10
老铁,我把PB4的 JTRST关了,发现另一个情况,就是原先不亮的变得最亮了,其他三位反倒暗淡了

你把延时先解决了,break放到延时前面。
小小蜗牛
回复

使用道具 举报

17

主题

181

帖子

0

精华

高级会员

Rank: 4

积分
503
金钱
503
注册时间
2017-7-24
在线时间
117 小时
 楼主| 发表于 2017-8-11 16:13:29 | 显示全部楼层
御剑江湖 发表于 2017-8-11 16:08
PB4上电默认是JTAG功能。。你配置IO口前先把JTAG关掉就可以了

RCC_APB2PeriphClockCmd(RCC_APB2Periph_A ...

老铁我给关了,但是出了另一个情况,就是原先不亮的PB4口,变成了最亮的,其他三位反而不亮了
回复

使用道具 举报

17

主题

181

帖子

0

精华

高级会员

Rank: 4

积分
503
金钱
503
注册时间
2017-7-24
在线时间
117 小时
 楼主| 发表于 2017-8-11 16:14:03 | 显示全部楼层
jiutianshenjian 发表于 2017-8-11 16:13
你把延时先解决了,break放到延时前面。

已经试过了,没有作用
回复

使用道具 举报

81

主题

1002

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1876
金钱
1876
注册时间
2014-9-10
在线时间
208 小时
发表于 2017-8-11 16:15:45 | 显示全部楼层
本帖最后由 jiutianshenjian 于 2017-8-11 16:16 编辑
q247341184 发表于 2017-8-11 16:14
已经试过了,没有作用

有没有作用你都得改啊,四个时间肯定得一样啊不然肯定有亮有暗
你第一个亮的时间是其他3个的2倍吧?
小小蜗牛
回复

使用道具 举报

17

主题

181

帖子

0

精华

高级会员

Rank: 4

积分
503
金钱
503
注册时间
2017-7-24
在线时间
117 小时
 楼主| 发表于 2017-8-11 16:16:58 | 显示全部楼层
jiutianshenjian 发表于 2017-8-11 16:15
有没有作用你都得改啊,四个时间肯定得一样啊不然肯定有亮有暗

明白你的意思了,做了微调已经显示出来了。非常感谢
回复

使用道具 举报

4

主题

349

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1046
金钱
1046
注册时间
2017-5-19
在线时间
335 小时
发表于 2017-8-11 16:18:21 | 显示全部楼层
int main(void)
{
while(1)
{
        DisPlayNum(2981);
        delay_ms(5);    //这个去掉  因为这个导致最后一个2 显示时间长了
}
}
回复

使用道具 举报

17

主题

181

帖子

0

精华

高级会员

Rank: 4

积分
503
金钱
503
注册时间
2017-7-24
在线时间
117 小时
 楼主| 发表于 2017-8-11 16:31:45 | 显示全部楼层
wxjhby 发表于 2017-8-11 16:18
int main(void)
{
while(1)

好。我试下、
回复

使用道具 举报

4

主题

349

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1046
金钱
1046
注册时间
2017-5-19
在线时间
335 小时
发表于 2017-8-11 16:36:48 | 显示全部楼层

我也就会点点数码管
回复

使用道具 举报

17

主题

181

帖子

0

精华

高级会员

Rank: 4

积分
503
金钱
503
注册时间
2017-7-24
在线时间
117 小时
 楼主| 发表于 2017-8-11 18:55:34 | 显示全部楼层
wxjhby 发表于 2017-8-11 16:36
我也就会点点数码管

不不不,,其实数码管还是挺关键的。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-4-20 15:06

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表