【STM32CubeMX学习】数码管显示

1、原理

如下图所示LEDSEG1、LEDSEG2分别有4个数码管,共8个,编号0~7。

控制数码管显示需要用到74HC138、74HC595这两个芯片。

HC138_A0~A2控制LEDSEG_CH1~8,通过这8个引脚选中一位数码管、HC595_SCLK/HC595_LCLK/HC595_DATA控制HC595_QA~QH,这8位决定当前选中的数码管显示什么内容。因此,我们只需要控制MCU的HC138_A0~A2、HC595_SCLK/HC595_LCLK/HC595_DATA这6个引脚即可。

2、74HC138

        74HC138是一个3进8出的38译码器,通过A2、A1、A0这三位输入一个十进制数,转化为输出的8位二进制数。比如想选中第6位数码管,那么A2、A1、A0 = 110 = 0x6,此时Y6为低电平,其他为高电平,也就选中了第6位数码管,74HC138的真值表如下图。

 3、74HC595

各引脚作用分析:

HC595_DATA(SDI):串行数据输入引脚。

HC595_SCLK(SFTCLK):移位寄存器时钟引脚,当处于上升沿时,移位寄存器中的数据整体后移一位,并且新的数据从HC595_DATA输入。

HC595_LCLK(LCHCLK):存储寄存器时钟输入引脚。当处于上升沿时,数据从移位寄存器转存到存储寄存器。在通过HC595_SCLK将所有数据移完后,需要给HC595_LCLK一个上升沿,将数据存储起来。

4、代码

代码的思路如下:

①将数据写到HC595_DATA,然后拉高HC595_SCLK将数据移位,以此类推,将8位数据写入移位寄存器。

②分别写A2、A1、A0选中某一位数码管

③拉高HC595_LCLK将显示数据保存到存储寄存器,此使选中的那位数码管就会显示相应的内容。

使用STM32CubeMX设置6个引脚如下:

smg.h:

#ifndef _LED_SMG_H
#define _LED_SMG_H

#include"main.h"

#define HC138_A0_H   HAL_GPIO_WritePin(HC138_A0_GPIO_Port,HC138_A0_Pin,GPIO_PIN_SET)
#define HC138_A0_L   HAL_GPIO_WritePin(HC138_A0_GPIO_Port,HC138_A0_Pin,GPIO_PIN_RESET)
#define HC138_A1_H   HAL_GPIO_WritePin(HC138_A1_GPIO_Port,HC138_A1_Pin,GPIO_PIN_SET)
#define HC138_A1_L   HAL_GPIO_WritePin(HC138_A1_GPIO_Port,HC138_A1_Pin,GPIO_PIN_RESET)
#define HC138_A2_H   HAL_GPIO_WritePin(HC138_A2_GPIO_Port,HC138_A2_Pin,GPIO_PIN_SET)
#define HC138_A2_L   HAL_GPIO_WritePin(HC138_A2_GPIO_Port,HC138_A2_Pin,GPIO_PIN_RESET)

#define HC595_DATA_H   HAL_GPIO_WritePin(HC595_DATA_GPIO_Port, HC595_DATA_Pin, GPIO_PIN_SET)
#define HC595_DATA_L   HAL_GPIO_WritePin(HC595_DATA_GPIO_Port, HC595_DATA_Pin, GPIO_PIN_RESET)
#define HC595_LCLK_H   HAL_GPIO_WritePin(HC595_LCLK_GPIO_Port, HC595_LCLK_Pin, GPIO_PIN_SET)
#define HC595_LCLK_L   HAL_GPIO_WritePin(HC595_LCLK_GPIO_Port, HC595_LCLK_Pin, GPIO_PIN_RESET)
#define HC595_SCLK_H   HAL_GPIO_WritePin(HC595_SCLK_GPIO_Port, HC595_SCLK_Pin, GPIO_PIN_SET)
#define HC595_SCLK_L   HAL_GPIO_WritePin(HC595_SCLK_GPIO_Port, HC595_SCLK_Pin, GPIO_PIN_RESET)

void LED_Refresh(void);
void LED_Write_Data(uint8_t duan,uint8_t wei);

#endif

 smg.c:

#include "smg.h"

//共阴数字数组
//0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F, .,全灭
const uint8_t smg_num[]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6,0xee,0x3e,0x9c,0x7a,0x9e,0x8e,0x01,0x00};

//74HC138驱动
//数码管位选
//num:要显示的数码管编号 0-7(共8个数码管)
void LED_Wei(uint8_t num)
{
  if(num&0x01)HC138_A0_H;
  else HC138_A0_L;

  if(num&0x02)HC138_A1_H;
  else HC138_A1_L;

  if(num&0x04)HC138_A2_H;
  else HC138_A2_L;
}

//74HC595驱动
//数码管显示
//duan:显示的段码0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F, .,全灭
//wei:要显示的数码管编号 0-7(共8个数码管)
void LED_Write_Data(uint8_t duan,uint8_t wei)
{
	uint8_t i;
  uint8_t smg_duan = smg_num[duan];
	for( i=0;i<8;i++)//先选段
	{
    if((smg_duan>>i)&0x01)HC595_DATA_H;
    else HC595_DATA_L;
      
		HC595_SCLK_L;
		Delay_Us(5);
		HC595_SCLK_H;
	}
    LED_Wei(wei);//后选中位
}

/*74HC595驱动,数码管刷新显示*/
void LED_Refresh(void)
{
	HC595_LCLK_H;
	Delay_Us(5);
	HC595_LCLK_L;
}

在main.c文件加入#include"smg.h",在main函数加入下面代码:

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
    for(i=0;i<8;i++)
    {
    LED_Write_Data(i,i);
    LED_Refresh();
    Delay_Ms(2);
    }
  }

运行结果如下:

猜你喜欢

转载自blog.csdn.net/weixin_46183891/article/details/123157063