[其他ST产品] Stm32管脚控制共阳数码管LED数码管

[复制链接]
1123|14
 楼主| t60yz 发表于 2023-8-26 23:45 | 显示全部楼层 |阅读模式

Stm32管脚控制共阳数码管LED数码管
总体电路部分。

LED数码管驱动部分

2374664ea1e21dc450.png



 楼主| t60yz 发表于 2023-8-26 23:45 | 显示全部楼层
MCU控制部分
8326764ea1e306d2fc.png
 楼主| t60yz 发表于 2023-8-26 23:46 | 显示全部楼层
下面为程序部分
程序用定时器定时扫描出每一位的数码管。

对所需要的变量进行定义
  1. extern u32  Timer4_overrun;                //定时器自加计数值
  2. extern uint32_t Timer4_count;                //定时器自加计数值

  3. //--- 显示0~9笔段代码表 ---
  4. unsigned char  LEDSEG[] =                          
  5. {
  6. 0x03,0x9F,0x25,0x0D,0x99,0x49,0x41,0x1F,0x01,0x09,
  7. };

  8. //--- 数码管显示的位选通段代码表 ---
  9. unsigned char  LEDDIG[] =        
  10. {
  11. 0x80,0x40,0x20,0x10
  12. };

  13. unsigned char LEDBuffer[4];                               //--- 定义的显示缓冲区 ---
  14. unsigned char LEDPointer = 0;                             //--- 定义的扫描计数变量 ---

  15. unsigned int msCounter = 0;
  16. u32 Counter = 0;                                                                               //计数
  17. u16 Twinkle = 0;
  18. u16 Twinkle_ms = 0;
  19. u16 Twinkle_cq = 0;
yinxiangh 发表于 2023-8-26 23:54 | 显示全部楼层
定时器自加计数值
 楼主| t60yz 发表于 2023-8-27 00:00 | 显示全部楼层
将引脚和定时器进行初始化。
  1. /**
  2.   * 函数功能: 配置TIM4定时器初始化
  3.   * 输入参数: 无
  4.   * 返 回 值: 无
  5.   * 说    明:无
  6.   */
  7. void Tim4_init(void)
  8. {
  9.         TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  10.         NVIC_InitTypeDef NVIC_InitStructure;
  11.        
  12.         /*-------------------中断优先级配置初始化-------------------*/
  13.   /* 设置中断组为0 */
  14.   NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);               
  15.   /* 设置中断来源 */
  16.   NVIC_InitStructure.NVIC_IRQChannel = ADVANCE_TIM4_IRQ;       
  17.   /* 设置主优先级为 0 */
  18.   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;         
  19.   /* 设置抢占优先级为3 */
  20.   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  21.   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  22.   NVIC_Init(&NVIC_InitStructure);       
  23.        
  24.         /*-------------------TIM4配置初始化-------------------*/       
  25.   /* 开启TIM4_CLK即内部时钟CK_INT=72M */
  26.   RCC_APB1PeriphClockCmd(ADVANCE_TIM4_CLK, ENABLE);       
  27.   /* 自动重装载寄存器周的值(计数值) */
  28.   TIM_TimeBaseStructure.TIM_Period=ADVANCE_TIM4_PERIOD;
  29.   /* 累计 TIM_Period个频率后产生一个更新或者中断
  30.      时钟预分频数为71,则驱动计数器的时钟CK_CNT = CK_INT / (71+1)=1M */
  31.   TIM_TimeBaseStructure.TIM_Prescaler= ADVANCE_TIM4_PRESCALER;
  32.   /* 计数器计数模式,基本定时器TIM8向上计数 */
  33.   TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
  34.   /* 初始化定时器TIM4 */
  35.   TIM_TimeBaseInit(ADVANCE_TIM4, &TIM_TimeBaseStructure);

  36.   /* 清除计数器中断标志位 */
  37.   TIM_ClearITPendingBit(ADVANCE_TIM4, TIM_IT_Update);
  38.   /* 开启计数器中断 */
  39.   TIM_ITConfig(ADVANCE_TIM4,TIM_IT_Update,ENABLE);

  40.   /* 使能计数器 */
  41.   TIM_Cmd(ADVANCE_TIM4, ENABLE);       

  42. }

  43. /**
  44.   * 函数功能: LED灯管脚初始化
  45.   * 输入参数: 无
  46.   * 返 回 值: 无
  47.   * 说    明:此处用到了特殊引脚,需要将RTC和外部低速时钟引脚作为普通引脚定义。
  48.   */
  49. void Hxeled_init(void)
  50. {
  51. GPIO_InitTypeDef  GPIO_InitStructure;       
  52. RCC_APB2PeriphClockCmd(LED_SCK_CLK, ENABLE);                                          //使能PA端口时钟
  53. RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
  54. GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);//失能JTAG

  55. PWR_BackupAccessCmd( ENABLE );/* 允许修改RTC和后备寄存器*/
  56. RCC_LSEConfig( RCC_LSE_OFF ); /* 关闭外部低速时钟,PC14+PC15可以用作普通IO*/
  57. BKP_TamperPinCmd(DISABLE);  /* 关闭入侵检测功能,PC13可以用作普通IO*/
  58.        
  59. GPIO_InitStructure.GPIO_Pin = LED1_A_OUT | LED1_B_OUT | LED1_C_OUT | LED1_D_OUT |LED1_E_OUT |LED1_F_OUT | LED1_G_OUT | LED1_DP_OUT | LED2_G_OUT | LED2_DP_OUT | LED2_C_OUT | LED_WE1 | LED_WE2 | LED_WE3;
  60. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                  //推挽输出
  61. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                 //IO口速度为50MHz
  62. GPIO_Init(GPIOA, &GPIO_InitStructure);                                                                  //根据设定参数初始化

  63. GPIO_InitStructure.GPIO_Pin = LED2_A_OUT | LED2_B_OUT | LED2_D_OUT |LED2_E_OUT |LED2_F_OUT;
  64. GPIO_Init(GPIOB, &GPIO_InitStructure);                                                            //推挽输出 ,IO口速度为50MHz
  65. PWR_BackupAccessCmd(DISABLE);/* 禁止修改RTC和后备寄存器*/

  66. GPIO_InitStructure.GPIO_Pin = LED_WE4;
  67. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                  //推挽输出
  68. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                 //IO口速度为50MHz
  69. GPIO_Init(GPIOC,&GPIO_InitStructure);                                                            

  70.         DIG1=0;
  71.         DIG2=0;
  72.         DIG3=0;
  73.         DIG4=0;
  74.        
  75.         A_out = 0;
  76.         B_out = 0;
  77.         C_out = 0;
  78.         D_out = 0;
  79.         E_out = 0;
  80.         F_out = 0;
  81.         G_out = 0;
  82.         DP_out = 1;

  83. }
 楼主| t60yz 发表于 2023-8-27 00:00 | 显示全部楼层
显示的数字和闪烁时间
  1. /**
  2.   * 函数功能: 将数据传递给数码管显示,
  3.   * 输入参数1: data:所显示的数据
  4.   * 输入参数2:twinkle:闪烁时间;单位
  5.   * 返 回 值: 无
  6.   * 说    明:无
  7.   */
  8. void Display_data(u32 data , u16 twinkle)       
  9. {
  10.         Counter = data;
  11.         Twinkle = twinkle;
  12. }
 楼主| t60yz 发表于 2023-8-27 00:00 | 显示全部楼层
此作为核心部分。
  1. /**
  2.   * 函数功能: Timer4定时器服务中断函数
  3.   * 输入参数: 无
  4.   * 返 回 值: 无
  5.   * 说    明:无
  6.   */
  7. void TIM4_IRQHandler(void)
  8. {
  9.         if(TIM_GetITStatus(ADVANCE_TIM4,TIM_IT_Update)!= RESET)          //检查指定的TIM中断发生与否:TIM 中断源
  10.         {
  11.                 Timer4_count++;
  12.                 Twinkle_ms++;
  13.                 TIM_ClearITPendingBit(ADVANCE_TIM4,TIM_IT_Update);                  //清除TIMx的中断待处理位:TIM 中断源
  14.         //-----------------------------------------------------------------------------------------------

  15.                 //--- 动态数码管显示扫描驱动程序段 ---
  16.                 //--- 显示数字 ---
  17.                 DIG1= 0;                                                        //数码管消影
  18.                 DIG2= 0;                                                        //数码管消影
  19.                 DIG3= 0;                                                        //数码管消影
  20.                 DIG4= 0;                                                        //数码管消影
  21.                 if(0==Twinkle)//不闪烁
  22.                 {
  23.                         A_out=((LEDSEG[LEDBuffer[LEDPointer]]>>7) & 0x01);
  24.                         B_out=((LEDSEG[LEDBuffer[LEDPointer]]>>6) & 0x01);
  25.                         C_out=((LEDSEG[LEDBuffer[LEDPointer]]>>5) & 0x01);
  26.                         D_out=((LEDSEG[LEDBuffer[LEDPointer]]>>4) & 0x01);
  27.                         E_out=((LEDSEG[LEDBuffer[LEDPointer]]>>3) & 0x01);
  28.                         F_out=((LEDSEG[LEDBuffer[LEDPointer]]>>2) & 0x01);
  29.                         G_out=((LEDSEG[LEDBuffer[LEDPointer]]>>1) & 0x01);
  30.                         //DP_out=((LEDSEG[LEDBuffer[LEDPointer]]>>0) & 0x01);
  31.                        
  32.                          //--- 数码管的位选段选择 ---
  33.                         DIG1= ((LEDDIG[LEDPointer]>>7) & 0x01);
  34.                         DIG2= ((LEDDIG[LEDPointer]>>6) & 0x01);
  35.                         DIG3= ((LEDDIG[LEDPointer]>>5) & 0x01);
  36.                         DIG4= ((LEDDIG[LEDPointer]>>4) & 0x01);               
  37.                 }
  38.                 else if(Twinkle_ms > Twinkle)
  39.                  {
  40.                         DIG1= 0;                                                        //数码管消影
  41.                         DIG2= 0;                                                        //数码管消影
  42.                         DIG3= 0;                                                        //数码管消影
  43.                         DIG4= 0;                                                        //数码管消影
  44.                        
  45.                         A_out  = 0;
  46.                         B_out  = 0;
  47.                         C_out  = 0;
  48.                         D_out  = 0;
  49.                         E_out  = 0;
  50.                         F_out  = 0;
  51.                         G_out         = 0;
  52.                         DP_out = 0;
  53.                        
  54.                         Twinkle_cq++;       
  55.                          if(Twinkle_cq > Twinkle)
  56.                          {
  57.                                 Twinkle_ms = 0;
  58.                                  Twinkle_cq = 0;
  59.                          }
  60.                  }
  61.                 else
  62.                  {
  63.                
  64.                 A_out=((LEDSEG[LEDBuffer[LEDPointer]]>>7) & 0x01);
  65.                 B_out=((LEDSEG[LEDBuffer[LEDPointer]]>>6) & 0x01);
  66.                 C_out=((LEDSEG[LEDBuffer[LEDPointer]]>>5) & 0x01);
  67.                 D_out=((LEDSEG[LEDBuffer[LEDPointer]]>>4) & 0x01);
  68.                 E_out=((LEDSEG[LEDBuffer[LEDPointer]]>>3) & 0x01);
  69.                 F_out=((LEDSEG[LEDBuffer[LEDPointer]]>>2) & 0x01);
  70.                 G_out=((LEDSEG[LEDBuffer[LEDPointer]]>>1) & 0x01);
  71.                 DP_out=((LEDSEG[LEDBuffer[LEDPointer]]>>0) & 0x01);
  72.                
  73.                  //--- 数码管的位选段选择 ---
  74.                 DIG1= ((LEDDIG[LEDPointer]>>7) & 0x01);
  75.                 DIG2= ((LEDDIG[LEDPointer]>>6) & 0x01);
  76.                 DIG3= ((LEDDIG[LEDPointer]>>5) & 0x01);
  77.                 DIG4= ((LEDDIG[LEDPointer]>>4) & 0x01);
  78.                  }
  79.                
  80.                 }
  81.                
  82.        
  83.                 LEDPointer++;                                           //--- 动态扫描计数变量加1 ---
  84.                 if(LEDPointer==3)
  85.                 {
  86.                         DP_out=0;
  87.                 }
  88.                 else
  89.                 {
  90.                         DP_out=1;
  91.                 }
  92.                 if(sizeof(LEDBuffer) == LEDPointer)LEDPointer = 0;      //--- 所有数码管扫描完,计数归0 ---
  93.                 //-----------------------------------------------------------------------------------------------
  94.                 //--- 毫秒计数变量加1,并判断1秒是否已到,若到则计数器变量加1并将结果送显示缓冲区 ---
  95.                 msCounter ++;                                           //--- 毫秒计数变量加1 ---
  96.                 if(1 == msCounter)                                                   //--- 加到1000,表示1秒时间到 ---
  97.                         {
  98.                                 msCounter = 0;
  99.                                 LEDBuffer[3] =   Counter % 10;                    //--- 将计数器变量的值送到显示缓冲区 ---
  100.                                 LEDBuffer[2] =  (Counter/10) % 10;
  101.                                 LEDBuffer[1] =  (Counter/100) % 10;
  102.                                 LEDBuffer[0] =  (Counter/1000) % 10;
  103.                         }
  104. }
Pulitzer 发表于 2024-9-11 07:30 | 显示全部楼层

需要靠近在外部添加一个钳位二极管
童雨竹 发表于 2024-9-11 09:26 | 显示全部楼层

ESD电压通过接地放掉
Wordsworth 发表于 2024-9-11 10:29 | 显示全部楼层

电阻消耗过电压的能量
公羊子丹 发表于 2024-9-11 12:25 | 显示全部楼层

当电路正常工作时,它处于截止状态(高阻态)
万图 发表于 2024-9-11 13:28 | 显示全部楼层

在信号线中串联小电阻其主要目的是对引脚的保护
帛灿灿 发表于 2024-9-11 16:27 | 显示全部楼层

并且衡量电阻受温度影响大小的物理量是温度系数
Bblythe 发表于 2024-9-11 17:30 | 显示全部楼层

需要更大的齐纳二极管来承受能量
周半梅 发表于 2024-9-11 19:26 | 显示全部楼层

就导通接地放掉
您需要登录后才可以回帖 登录 | 注册

本版积分规则

189

主题

1191

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部