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:
- GPIOx: a GPIO in A~G.
- GPIO_Pin: a pin from 0 to 15.
- PinState: status of Pin - SET or RESET.
There are two registers:
- BSRR: port set / reset register.
- 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:
- HAL_ GPIO_ (uint16_t) GPIO in writepin()_ Pin is determined by the output data register OD;
- The output data register OD is determined by BSRR and BRR;
- BSRR, BRR by (uint32_t)GPIO_Pin decision;
- (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);