OpenEdv-开源电子网

 找回密码
 立即注册

扫一扫,访问微社区

正点原子新作:阿波罗STM32F767&F429&探索者STM32F4开发板&赶快来下载资料哦。

查看: 3358|回复: 14

STM32数码管动态扫描

[复制链接]

  离线 

7

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
64
金钱
64
注册时间
2013-11-6
在线时间
2 小时
发表于 2013-11-6 12:11:04 | 显示全部楼层 |阅读模式
正点原子公众号

买了STM32 MINI板没有带屏的,做其他实验无法显示数据,今天没事弄了个8位数码管显示数据的程序,直接调用shuma_display()这个函数就行了,方便以后用啊,是控制BSRR寄存器实现的,断码用PA0-7口,位码用PB5-7口控制38译码器选择8位数码管,没有用到锁存器,是IO口直接驱动的,3.3V看着还行,能显示很清楚,现把主要代码粘上来,各位大虾请指点有没有更好的方法
/*************************shuma.c*********/

#include "stm32f10x.h"
#include "shuma.h"
#include "delay.h"

u32 str[8];
u32 wei_table[]={0x00E00000,0x00C00020,
                          0x00A00040,0x00800060,
                          0x00600080,0x004000A0,
                          0x002000C0,0x000000E0,
                         };     //PB5-7,数码管位码,8位数码管,138译码器控制选择,写入BSRR寄存器,用其他IO口该码需改变
u32 duan_table[]={0x00C0003F,0x00F90006,
                            0x00A4005B,0x00B0004F,
                            0x00990066,0x0092006D,
                            0x0082007D,0x00F80007,
                            0x0080007F,0x0090006F,
                           };   //PA0-7,数码管段码0-9,共阴,写入BSRR寄存器

void shuma_init()   //数码管IO管脚初始化,断码为PA0-7,位码为PB5-7,位码为3个IO口,通过38译码器控制8位数码管
{
      RCC->APB2ENR|=1<<2;  //使能GPIOA时钟
      RCC->APB2ENR|=1<<3;  //使能GPIOB时钟

      GPIOA->CRL&=0x00000000;
      GPIOA->CRL|=0x33333333; //设置PA0-7为推挽输出
      GPIOB->CRL&=0x000FFFFF;
      GPIOB->CRL|=0x33300000; //设置PB5-7为推挽输出

//   GPIOA->ODR|=0xFF; //设置PA0-7输出高,上拉
//   GPIOB->ODR|=0xE0; //设置PB5-7输出高,上拉 
}


void shuma_display(u32 value)    //显示8位数据,分离8次,即千万
{
 u8 i;

 str[0]=duan_table[value/10000000];            //千万位
 str[1]=duan_table[(value%10000000)/1000000];          //百万位
 str[2]=duan_table[((value%10000000)%1000000)/100000];        //十万位
 str[3]=duan_table[(((value%10000000)%1000000)%100000)/10000];      //万位
 str[4]=duan_table[((((value%10000000)%1000000)%100000)%10000)/1000];    //千位
 str[5]=duan_table[(((((value%10000000)%1000000)%100000)%10000)%1000)/100];      //百位
 str[6]=duan_table[((((((value%10000000)%1000000)%100000)%10000)%1000)%100)/10]; //十位
 str[7]=duan_table[((((((value%10000000)%1000000)%100000)%10000)%1000)%100)%10]; //个位

 for(i=0;i<8;i++)      //循环8次,动态扫描
 {
  GPIOA->BSRR|=str;
  GPIOB->BSRR|=wei_table;
  delay_ms(2);
 }

}
/***********************************************/

/*******************main.c****************************/
#include "stm32f10x.h"
#include "delay.h"
#include "sys.h"
#include "shuma.h"

int main(void)
{
 SystemInit();   //初始化系统时钟72MHZ
 delay_init(72);   //初始化延时函数
 NVIC_Configuration();  //设置中断分组
 shuma_init();

 while(1)
 {
  shuma_display(76543210);
 } 
}
/*********************************/





 

回复

使用道具 举报

  离线 

34

主题

1199

帖子

1

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1519
金钱
1519
注册时间
2012-6-15
在线时间
9 小时
发表于 2013-11-6 13:26:35 | 显示全部楼层
你这个代码 将来加入其他任务的时候 你就发现有问题了, 数码管闪烁、亮度不均匀等等


用定时器来做。
定时器 定时 1~5ms ,里面改变段码值,并位码循环+1;
{
 ......
 if(++cnt>=8) cnt=0; //计数循环+1  0~7共8段
 SegData =seg[cnt]; //赋值段码
 DigPin = 1<<cnt;    //相应的位码使能,其他位关闭。 具体看你位码配置
}

主程序 ,直接赋值即可。[你写的太复杂了。]

void  SetSeg(u32 x)
{
int i=0;
 for(i=0;i<8;i++)
{
     
      SegData [7-i] = SEG_TABLE(x%10);
      x/=10;
}
}>
回复 支持 反对

使用道具 举报

  离线 

34

主题

1199

帖子

1

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1519
金钱
1519
注册时间
2012-6-15
在线时间
9 小时
发表于 2013-11-6 13:29:59 | 显示全部楼层
此程序, 你主函数无论执行时间怎么样,只要你赋值有变化 ,相应中断自会显示, 不需要关心。  而且中断内部执行时间非常短。
将来代码移植起来也很方便。
回复 支持 反对

使用道具 举报

  离线 

38

主题

2069

帖子

6

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3260
金钱
3260
注册时间
2012-1-16
在线时间
34 小时
发表于 2013-11-6 15:20:33 | 显示全部楼层
回复【3楼】aleda303:
---------------------------------
学习了。。。
站在巨人的肩膀上不断的前进。。。
回复 支持 反对

使用道具 举报

  离线 

110

主题

7325

帖子

12

精华

资深版主

Rank: 8Rank: 8

积分
10559
金钱
10559
注册时间
2013-9-10
在线时间
309 小时
发表于 2013-11-6 15:43:51 | 显示全部楼层
回复【楼主位】火焰山:
---------------------------------
同一一楼做法

楼主的显示数据处理那里计算那么长干嘛,浪费时间,尽量缩短,看起来都爽点,呵呵
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复 支持 反对

使用道具 举报

  离线 

7

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
64
金钱
64
注册时间
2013-11-6
在线时间
2 小时
 楼主| 发表于 2013-11-6 18:10:25 | 显示全部楼层
回复【3楼】aleda303:
---------------------------------
按照大侠的指导改了一下,用TIM2定时2ms,感谢啊,并且实现了是几位就显示几位数据,高位没用的0就不在显示了,感觉上更美观一点,再次感谢!!

void TIM2_IRQHandler(void)

{
static u8   cnt=8;

if(TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)         //产生溢出中断
{
if(--cnt ==0 | SegData[cnt-1]==0x00C0003F) cnt=8; //控制循环并判断第几位为0高位就不再显示0
GPIOA->BSRR|=SegData[cnt-1];    //段数据
GPIOB->BSRR|=wei_table[cnt-1];     //位数据

TIM_ClearITPendingBit(TIM2, TIM_IT_Update);  //清除中断标志
}
}  

void  Shuma_Display(u32 value) 

u8 i=0;

for(i=0;i<8;i++) 
{      
SegData[7-i] = duan_table[value%10];  //将值分离
value/=10; 

}
回复 支持 反对

使用道具 举报

  离线 

6

主题

545

帖子

0

精华

高级会员

Rank: 4

积分
651
金钱
651
注册时间
2013-4-22
在线时间
29 小时
发表于 2013-11-6 19:17:24 | 显示全部楼层
代码书写不规范,最好用table键对齐
回复 支持 反对

使用道具 举报

  离线 

485

主题

8万

帖子

30

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
118299
金钱
118299
注册时间
2010-12-1
在线时间
923 小时
发表于 2013-11-6 22:32:26 | 显示全部楼层
谢谢分享
回复 支持 反对

使用道具 举报

  离线 

34

主题

1199

帖子

1

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1519
金钱
1519
注册时间
2012-6-15
在线时间
9 小时
发表于 2013-11-7 12:28:58 | 显示全部楼层
回复【7楼】三叶草:
---------------------------------
粘贴过来 自动就退回去了。是纯文本格式的, TAB键就被忽略 了
回复 支持 反对

使用道具 举报

  离线 

0

主题

1

帖子

0

精华

新手上路

Rank: 1

积分
13
金钱
13
注册时间
2016-11-8
在线时间
1 小时
发表于 2016-11-8 13:27:22 | 显示全部楼层
学习了
回复 支持 反对

使用道具 举报

  离线 

0

主题

33

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
416
金钱
416
注册时间
2017-4-14
在线时间
49 小时
发表于 2017-9-4 10:37:34 | 显示全部楼层
学习了
回复 支持 反对

使用道具 举报

  离线 

49

主题

452

帖子

0

精华

高级会员

Rank: 4

积分
790
金钱
790
注册时间
2014-11-18
在线时间
135 小时
发表于 2017-9-4 11:56:46 | 显示全部楼层
aleda303 发表于 2013-11-6 13:29
此程序,&nbsp;你主函数无论执行时间怎么样,只要你赋值有变化&nbsp;,相应中断自会显示,&nbsp;不需要关心 ...

你这个思想就是把刷led的代码放到定时器中断里面做的。

我的老大,一直和我争,不要把代码放到定时器里面,我说这个时间很短的。

他说出了事,我不管。   你想说什么。
自己选择的路,成家前走完。
回复 支持 反对

使用道具 举报

  离线 

0

主题

6

帖子

0

精华

初级会员

Rank: 2

积分
54
金钱
54
注册时间
2015-4-1
在线时间
5 小时
发表于 2017-12-7 17:26:03 | 显示全部楼层
lz,能不能把你的shuma.h文件贴出来
回复 支持 反对

使用道具 举报

  离线 

9

主题

240

帖子

0

精华

高级会员

Rank: 4

积分
509
金钱
509
注册时间
2017-5-21
在线时间
224 小时
发表于 7 天前 来自手机 | 显示全部楼层
aiyeba 发表于 2017-9-4 11:56
你这个思想就是把刷led的代码放到定时器中断里面做的。

我的老大,一直和我争,不要把代码放到定时器 ...

主要是处理好优先级
回复 支持 反对

使用道具 举报

  离线 

14

主题

375

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1936
金钱
1936
注册时间
2013-6-27
在线时间
254 小时
发表于 7 天前 | 显示全部楼层
aiyeba 发表于 2017-9-4 11:56
你这个思想就是把刷led的代码放到定时器中断里面做的。

我的老大,一直和我争,不要把代码放到定时器 ...

处理好变量定义volatile修饰,基本问题不大。
让我们的思维驾驭在电的速度之上! 承接各种电子产品设计。 659396825
回复 支持 反对

使用道具 举报

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

本版积分规则




QQ|联系我们|手机版|官方淘宝店|新浪微博|微信公众平台|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2017-12-15 20:20

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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