基于HAL库 STM32F103C8 控制3641ah八位数码管

stm32初学者,在一次比赛中运用stm32控制3641ah八位数码管的数字显示,在这里记录一下学习进度以及学习过程,以便日后回顾。
在这次比赛中我总共使用两种方式使stm32控制了数码管的显示,这里记录的是最基本的使用管脚直接控制数码管的显示。
运行环境是STM32CuBeMX Keil5 烧录方式是J-Link。
首先是在STM32CuBeMX里面进行基本的时钟设置以及管教的使能,具体用到哪些管脚需要视情况而定,我这里使用A0-A11管脚。

在这里插入图片描述

附上3641ah的原理图以及我设置的不同数字的显示方式,之后就可以一步一步完成代码了。
由于STM32CuBeMX已经设置好了管脚和时钟,直接编写要完成的程序即可。

在这里插入图片描述

void display(int m)
{ switch(m)
  {case 0:
        HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_SET);
        HAL_GPIO_WritePin(GPIOA,GPIO_PIN_6,GPIO_PIN_SET);
        HAL_GPIO_WritePin(GPIOA,GPIO_PIN_10,GPIO_PIN_SET);
        HAL_GPIO_WritePin(GPIOA,GPIO_PIN_8,GPIO_PIN_SET);
        HAL_GPIO_WritePin(GPIOA,GPIO_PIN_7,GPIO_PIN_SET);
        HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_SET);
        HAL_GPIO_WritePin(GPIOA,GPIO_PIN_11,GPIO_PIN_RESET);
        HAL_GPIO_WritePin(GPIOA,GPIO_PIN_9,GPIO_PIN_RESET);
        
        break;
   case 1:
     HAL_GPIO_WritePin(GPIOA,GPIO_PIN_6,GPIO_PIN_SET);
     HAL_GPIO_WritePin(GPIOA,GPIO_PIN_10,GPIO_PIN_SET);
     HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET);
     HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_RESET);
     HAL_GPIO_WritePin(GPIOA,GPIO_PIN_7,GPIO_PIN_RESET);
     HAL_GPIO_WritePin(GPIOA,GPIO_PIN_8,GPIO_PIN_RESET);
     HAL_GPIO_WritePin(GPIOA,GPIO_PIN_9,GPIO_PIN_RESET);
     HAL_GPIO_WritePin(GPIOA,GPIO_PIN_11,GPIO_PIN_RESET);
     break;
     ...
     }

先是一个display函数,根据设置的不同数字的显示方法进行不同管脚的电位拉高或拉低,这里简单给出0和1的例子来打个比方。
其次是用一个判断要显示数字范围的函数来架构起整体的框架。

void displaynumber(double n)
{  double s=n;
   if(s>=10000)
   {displaymore(n);} 
   if(s>=1000&&s<10000)
   {displaythousand(n);}
   if(s>=100&&s<1000)
   {displayhundred(n);}
   if(s>=10&&s<100)
   {displayten(n);}
   if(s>=0&&s<10)
   {displayone(n);}
   if(s<0)
   {displayless(n);}
}

随后便是根据不同的情况来编写不同的函数。

void displayone(double m)
{int a,b,c,d,n;
 n=m*1000;
 a=n/1000;
 b=(n-a*1000)/100;
 c=(n-a*1000-b*100)/10;
 d=(n-a*1000-b*100-c*10);
 while(1)
 {HAL_GPIO_WritePin(GPIOA,GPIO_PIN_3,GPIO_PIN_RESET);
  display(d);
  HAL_Delay(t);
  HAL_GPIO_WritePin(GPIOA,GPIO_PIN_3,GPIO_PIN_SET);
  HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2,GPIO_PIN_RESET);
  display(c);
  HAL_Delay(t);
  HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2,GPIO_PIN_SET);
  HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_RESET);
  display(b);
  HAL_Delay(t);
  HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_SET);
  HAL_GPIO_WritePin(GPIOA,GPIO_PIN_0,GPIO_PIN_RESET);
  display(a);
  display2();
  HAL_Delay(t);
  HAL_GPIO_WritePin(GPIOA,GPIO_PIN_0,GPIO_PIN_SET);
 }
}

这里给出了显示个位数时的函数,当判断要输入个位数时,算法将会将数字拆分然后通过扫描让不同位的数码管显示出来,这里我当时出现了问题在于没使用延时函数导致扫描速度太快,先扫描的数码管会对后扫描的数码管有干扰,使得最后显示出8.8.8.8.这样的情况,加上延时函数之后问题得以解决。
还有显示小数点的函数display2():

void display2(void)
{HAL_GPIO_WritePin(GPIOA,GPIO_PIN_9,GPIO_PIN_SET);
}

就是将对应的数码管三号管脚的单片机管脚点位拉高就好,但是小数点的显示在后来使用hc595来控制数码管的时候就出现的问题,那种情况我会再写一篇帖子来记录。

到这里整体的代码实现就记录完毕了,我还想单独说的一点就是在设置显示不同数字的display函数中要把没有用到的数码管对应的单片机的管脚电位拉低,这样再次调用的时候就不会出现互相影响的情况。我当时在写这个程序的时候难点在于将不同位数的数字拆分开,现在回过头来我发现理解了扫描这一方式的定义对我来说可能收获更大一些。
其实我这个程序没有完全实现功能,其实是可以实现显示三位负数的,但由于这次比赛的项目没有显示负数的需求也就没有考虑这个问题,而且大于10000和小于0的数我都把他们编成显示0.0.0.0.以及1.1.1.1.可以在调试的过程中传递一些信息。
最后欢迎各位对我的代码批评指正,我个人认为我的代码可能比较冗长,如果有更简洁的实现方式欢迎各位前来交流。

  • 6
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值