[STM32CubeMX learning] digital tube display

1. Principle

As shown in the figure below, LEDSEG1 and LEDSEG2 respectively have 4 digital tubes, 8 in total, numbered 0~7.

Two chips, 74HC138 and 74HC595, are needed to control the display of the digital tube.

HC138_A0~A2 control LEDSEG_CH1~8, select a nixie tube through these 8 pins, HC595_SCLK/HC595_LCLK/HC595_DATA control HC595_QA~QH, these 8 bits determine what the currently selected nixie tube displays. Therefore, we only need to control the 6 pins of HC138_A0~A2, HC595_SCLK/HC595_LCLK/HC595_DATA of the MCU.

2、74HC138

        74HC138 is a 38 decoder with 3 inputs and 8 outputs. It inputs a decimal number through the three bits of A2, A1 and A0, and converts it into an output 8-bit binary number. For example, if you want to select the 6th digital tube, then A2, A1, A0 = 110 = 0x6. At this time, Y6 is low level, and the others are high level, so the 6th digital tube is selected. The truth table of 74HC138 is as follows picture.

 3、74HC595

Analysis of the function of each pin:

HC595_DATA(SDI): Serial data input pin.

HC595_SCLK (SFTCLK): Shift register clock pin. When it is on the rising edge, the data in the shift register is shifted backward by one bit, and new data is input from HC595_DATA.

HC595_LCLK (LCHCLK): Storage register clock input pin. On the rising edge, data is dumped from the shift register to the storage register. After moving all the data through HC595_SCLK, you need to give HC595_LCLK a rising edge to store the data.

4. Code

The idea of ​​the code is as follows:

① Write the data to HC595_DATA, then pull up HC595_SCLK to shift the data, and so on, write 8-bit data into the shift register.

②Write A2, A1, A0 respectively to select a digital tube

③Pull up HC595_LCLK to save the display data to the storage register, so that the selected digital tube will display the corresponding content.

Use STM32CubeMX to set up 6 pins as follows:

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;
}

Add #include "smg.h" to the main.c file, and add the following code to the main function:

  /* 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);
    }
  }

The result of the operation is as follows:

Guess you like

Origin blog.csdn.net/weixin_46183891/article/details/123157063