LED program design for learning of Blue Bridge Cup STM32G431

2, Detailed analysis of GPIO code

First put the main functions in main.c.

#include "main.h"
#include "BSP_LED.h"

void SystemClock_Config(void);

int main(void)
{
  HAL_Init();
  SystemClock_Config();
  LED_Init();
  while (1)
  {
//		HAL_GPIO_WritePin(GPIOC, GPIO_PIN_15, GPIO_PIN_RESET);
//		HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
//		HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
		LED_Show(0x00);
		HAL_Delay(500);
		
		LED_Show(0x01);
		HAL_Delay(500);
  }
}

void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  
  HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);
  
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV3;
  RCC_OscInitStruct.PLL.PLLN = 20;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
  RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}

void Error_Handler(void)
{
  while (1)
  {
  }
}

1. Header file

#include "main.h"

In "main.c"   This header file must be referenced in, and must also be referenced in the middle layer "BSP_LED.h". "main.h" contains the HAL library header file, which is indispensable for HAL library based programming.

#include "BSP_LED.h"

"BSP_LED.h" written by us should be referenced in "main.c"   Header file. In this way, the LED function in BSP_LED.c can be called.

2. Clock configuration (clock tree)

void SystemClock_Config(void);

This function is a clock tree function generated by STM32CubeMX and does not need to be entered manually.

3. Main function

int main(void)
{
  HAL_Init();
  SystemClock_Config();
  LED_Init();
  while (1)
  {
//		HAL_GPIO_WritePin(GPIOC, GPIO_PIN_15, GPIO_PIN_RESET);
//		HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
//		HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
		LED_Show(0x00);
		HAL_Delay(500);
		
		LED_Show(0x01);
		HAL_Delay(500);
  }
}

3.1 HAL_Init();

Jump to the file location where this function is located, and we can see such a description

 

Hal_ The init() function is required to be placed after reset and before clock configuration. So Hal_ The position of init() function has special meaning and cannot be changed at will.

3.2 SystemClock_Config();

This calls the clock configuration function (clock tree).

3.3 LED_Init();

GPIO_InitTypeDef GPIO_InitStruct = {0};
    data type           variable        initial value

This is a data type definition function, similar to   char a = ;   

Jump to   GPIO_InitTypeDef   Location, same:

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOF_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();
  • GPIOC: 573 latch input pin.
  • GPIOF: external high-speed crystal oscillator pin.
  • GPIOD: 573 latch switch pin.
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_8
                          |GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12, GPIO_PIN_SET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);

Jump to HAL_GPIO_WritePin() function:

There are three parameters:

  1. GPIOx: a GPIO in A~G.
  2. GPIO_Pin: a pin from 0 to 15.
  3. PinState: status of Pin - SET or RESET.

There are two registers:

  1. BSRR: port set / reset register.
  2. BRR: port bit reset register.

GPIO is configured when the stm32subemx configuration pin is used_ The default high and low level status of pin (SET/RESET). For example, when the power on light is off, set PC0~PC8 to high level (GPIO_PIN_SET) and latch off PD2 to low level (GPIO_PIN_RESET).

HAL_GPIO_WritePin() will judge

  • If GPIO_PIN_SET, BSRR is assigned;
  • If GPIO_PIN_RESET, BRR is assigned.

The values assigned to BSRR and BRR are from (uint32_t)GPIO_Pin, jump to GPIO_Pin.

Every GPIO_Pin corresponds to a 32-bit hexadecimal number, and only one bit is 1. In this way, the bit corresponding to BSRR and BRR can be assigned to 1.

From the reference manual, 0 or 1 assigned to BSRR and BRR is used to control the output data register OD.

  • After BSRR obtains 1, it is mapped to OD and the corresponding position bit (1);
  • After BRR gets 1, it is mapped to OD and the corresponding bit is reset (0).

Function of output data register OD: select to configure a pin in 0 ~ 15.

Summary:

  1. HAL_ GPIO_ (uint16_t) GPIO in writepin()_ Pin is determined by the output data register OD;
  2. The output data register OD is determined by BSRR and BRR;
  3. BSRR, BRR by (uint32_t)GPIO_Pin decision;
  4. (uint32_t)GPIO_Pin is determined by a 32-bit hexadecimal number.
/*Configure GPIO pins : PC13 PC14 PC15 PC8
                           PC9 PC10 PC11 PC12 */
GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_8
                          |GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

/*Configure GPIO pin : PD2 */
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

Configure PC0~PC15 and PD2, including which pins are used in stm32subemx configuration, push-pull output mode, no pull-up / pull-down and low speed.

/*
Function name: LED_Show
 Function: LD8-LD1 corresponds to 8 bits of ucLED
 Entrance parameters: LED
 Exit parameter: void
*/
void LED_Show(unsigned char ucLED)
{
	//Turn off all LED s
	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_8
                          |GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12, GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
	
	HAL_GPIO_WritePin(GPIOC, ucLED<<8, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
}

In the optimized code, a char type parameter ucLED is defined (char type is 1 byte and 8 bits, which exactly corresponds to 8 LED s). Use the ucLED parameter in the function instead of GPIO_PIN_8~15 configure register BRR.

Analyze the parameter settings of the following section of function: why ucled < < 8? Why GPIO_PIN_RESET ?

HAL_GPIO_WritePin(GPIOC, ucLED<<8, GPIO_PIN_RESET);

Summary:

Use char type ucLED parameters instead of GPIO_PIN_8~15 configure BRR and Hal_ GPIO_ The writepin() function is directly in BSP_LED.c to simplify the code in main.c.

Tags: Single-Chip Microcomputer stm32

Posted on Sat, 23 Oct 2021 11:38:26 -0400 by dominicd