HAL_Init();
这是主函数中首要处理的函数:主要用来初始化HAL库,即用来初始化所有的外围设备,Flash接口和系统定时器,系统中断组,初始化低级别硬件这个函数不能修改,return HAL_OK向函数返回一个值,代表函数编译成功。
HAL_StatusTypeDef HAL_Init(void)
{
/* Configure Flash prefetch, Instruction cache, Data cache */
#if (INSTRUCTION_CACHE_ENABLE != 0U)
__HAL_FLASH_INSTRUCTION_CACHE_ENABLE();
#endif /* INSTRUCTION_CACHE_ENABLE */
#if (DATA_CACHE_ENABLE != 0U)
__HAL_FLASH_DATA_CACHE_ENABLE();
#endif /* DATA_CACHE_ENABLE */
#if (PREFETCH_ENABLE != 0U)
__HAL_FLASH_PREFETCH_BUFFER_ENABLE();
#endif /* PREFETCH_ENABLE */
/* Set Interrupt Group Priority */
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
/* Use systick as time base source and configure 1ms tick (default clock after Reset is HSI) */
HAL_InitTick(TICK_INT_PRIORITY);
/* Init the low level hardware */
HAL_MspInit();
/* Return function status */
return HAL_OK;
}
以上是HAL_Init()函数,通过以上的函数源代码我们可以看到HAL库的初始化函数是采用条件编译配置的方式进行初始化的,下面我们来逐个分析其条件编译:
INSTRUCTION_CACHE_ENABLE配置指令缓存使能;
#define INSTRUCTION_CACHE_ENABLE 1U
DATA_CACHE_ENABLE 配置数据缓存使能;
#define DATA_CACHE_ENABLE 1U
PREFETCH_ENABL配置Flash预读取使能;
#define PREFETCH_ENABLE 1U
return HAL_OK
这条语句向函数返回一个状态,在HAL库中,函数状态一共有四种状态,分别是:成功,错误,忙碌,超时;具体值如下:
typedef enum
{
HAL_OK = 0x00U,
HAL_ERROR = 0x01U,
HAL_BUSY = 0x02U,
HAL_TIMEOUT = 0x03U
} HAL_StatusTypeDef;
通过在stm32f4xx_hal_conf.h中可以查看每个条件编译的预定义值;
#define VDD_VALUE ((uint32_t)3300U) /*!< Value of VDD in mv */
#define TICK_INT_PRIORITY ((uint32_t)0U) /*!< tick interrupt priority */
#define USE_RTOS 0U
#define PREFETCH_ENABLE 1U
#define INSTRUCTION_CACHE_ENABLE 1U
#define DATA_CACHE_ENABLE 1U
接下是执行的函数是:
SystemClock_Config();//系统时钟配置
其函数源代码如下:
/** System Clock Configuration
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
/**Configure the main internal regulator output voltage
*/
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/**Initializes the CPU, AHB and APB busses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = 16;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLM = 8;
RCC_OscInitStruct.PLL.PLLN = 168;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 4;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/**Initializes the CPU, AHB and APB busses clocks
*/
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_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
{
Error_Handler();
}
/**Configure the Systick interrupt time
*/
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
/**Configure the Systick
*/
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
函数主要调用了和配置两个结构体RCC_OscInitTypeDef和
RCC_OscInitTypeDef结构体函数:
/**
* @brief RCC Internal/External Oscillator (HSE, HSI, LSE and LSI) configuration structure definition
*/
typedef struct
{
uint32_t OscillatorType; /*!< The oscillators to be configured.
This parameter can be a value of @ref RCC_Oscillator_Type */
uint32_t HSEState; /*!< The new state of the HSE.
This parameter can be a value of @ref RCC_HSE_Config */
uint32_t LSEState; /*!< The new state of the LSE.
This parameter can be a value of @ref RCC_LSE_Config */
uint32_t HSIState; /*!< The new state of the HSI.
This parameter can be a value of @ref RCC_HSI_Config */
uint32_t HSICalibrationValue; /*!< The HSI calibration trimming value (default is RCC_HSICALIBRATION_DEFAULT).
This parameter must be a number between Min_Data = 0x00 and Max_Data = 0x1F */
uint32_t LSIState; /*!< The new state of the LSI.
This parameter can be a value of @ref RCC_LSI_Config */
RCC_PLLInitTypeDef PLL; /*!< PLL structure parameters */
}RCC_OscInitTypeDef;
以上每个结构体元素都有其所对应的的参数;
OscillatorType 用来配置系统振荡器,有以下四个值:
#define RCC_OSCILLATORTYPE_NONE 0x00000000U //不使用
#define RCC_OSCILLATORTYPE_HSE 0x00000001U //采用外部高速时钟振荡器
#define RCC_OSCILLATORTYPE_HSI 0x00000002U //采用内部高速时钟振荡器
#define RCC_OSCILLATORTYPE_LSE 0x00000004U //采用外部低速时钟振荡器
#define RCC_OSCILLATORTYPE_LSI 0x00000008U //采用内部低速时钟振荡器
HSEState用来配置外部高速始终振荡器的的状态,有以下三种状态:
#define RCC_HSE_OFF 0x00000000U //关闭外部高速时钟
#define RCC_HSE_ON RCC_CR_HSEON //打开外部高速时钟
#define RCC_HSE_BYPASS ((uint32_t)(RCC_CR_HSEBYP | RCC_CR_HSEON))
HSIState/LSEState/LSIState这是结构体元素的参数可以依照以上示例都可以找到:
/** @defgroup RCC_LSE_Config LSE Config
* @{
*/
#define RCC_LSE_OFF 0x00000000U
#define RCC_LSE_ON RCC_BDCR_LSEON
#define RCC_LSE_BYPASS ((uint32_t)(RCC_BDCR_LSEBYP | RCC_BDCR_LSEON))
/**
* @}
*/
/** @defgroup RCC_HSI_Config HSI Config
* @{
*/
#define RCC_HSI_OFF ((uint8_t)0x00)
#define RCC_HSI_ON ((uint8_t)0x01)
#define RCC_HSICALIBRATION_DEFAULT 0x10U /* Default HSI calibration trimming value */
/**
* @}
*/
/** @defgroup RCC_LSI_Config LSI Config
* @{
*/
#define RCC_LSI_OFF ((uint8_t)0x00)
#define RCC_LSI_ON ((uint8_t)0x01)
/**
* @}
*/
/** @defgroup RCC_PLL_Config PLL Config
* @{
*/
#define RCC_PLL_NONE ((uint8_t)0x00)
#define RCC_PLL_OFF ((uint8_t)0x01)
#define RCC_PLL_ON ((uint8_t)0x02)
/**
* @}
*/
HSICalibrationValue是内部高速始终调整值:这个参数的取值为0~31之间的数;
RCC_PLLInitTypeDef PLL是结构体中调用的另一个结构体,代码如下:
typedef struct
{
uint32_t PLLState; /*!< The new state of the PLL.
This parameter can be a value of @ref RCC_PLL_Config */
uint32_t PLLSource; /*!< RCC_PLLSource: PLL entry clock source.
This parameter must be a value of @ref RCC_PLL_Clock_Source */
uint32_t PLLM; /*!< PLLM: Division factor for PLL VCO input clock.
This parameter must be a number between Min_Data = 0 and Max_Data = 63 */
uint32_t PLLN; /*!< PLLN: Multiplication factor for PLL VCO output clock.
This parameter must be a number between Min_Data = 50 and Max_Data = 432
except for STM32F411xE devices where the Min_Data = 192 */
uint32_t PLLP; /*!< PLLP: Division factor for main system clock (SYSCLK).
This parameter must be a value of @ref RCC_PLLP_Clock_Divider */
uint32_t PLLQ; /*!< PLLQ: Division factor for OTG FS, SDIO and RNG clocks.
This parameter must be a number between Min_Data = 2 and Max_Data = 15 */
#if defined(STM32F410Tx) || defined(STM32F410Cx) || defined(STM32F410Rx) || defined(STM32F446xx) || defined(STM32F469xx) ||\
defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) ||\
defined(STM32F413xx) || defined(STM32F423xx)
uint32_t PLLR; /*!< PLLR: PLL division factor for I2S, SAI, SYSTEM, SPDIFRX clocks.
This parameter is only available in STM32F410xx/STM32F446xx/STM32F469xx/STM32F479xx
and STM32F412Zx/STM32F412Vx/STM32F412Rx/STM32F412Cx/STM32F413xx/STM32F423xx devices.
This parameter must be a number between Min_Data = 2 and Max_Data = 7 */
#endif /* STM32F410xx || STM32F446xx || STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Vx || STM32F412Rx || STM32F412Cx || STM32F413xx || STM32F423xx */
}RCC_PLLInitTypeDef;
以上每个结构体元素的参数都定义在文件stm32f4xx_rcc.h文件夹里,具体代码如下:
/** @defgroup RCC_PLL_Config PLL Config锁相环时钟配置的参数
* @{
*/
#define RCC_PLL_NONE ((uint8_t)0x00)
#define RCC_PLL_OFF ((uint8_t)0x01)
#define RCC_PLL_ON ((uint8_t)0x02)
/**
* @}
*/
/** @defgroup RCC_PLLP_Clock_Divider PLLP Clock Divider锁相环分频
* @{
*/
#define RCC_PLLP_DIV2 0x00000002U
#define RCC_PLLP_DIV4 0x00000004U
#define RCC_PLLP_DIV6 0x00000006U
#define RCC_PLLP_DIV8 0x00000008U
/**
* @}
*/
/** @defgroup RCC_PLL_Clock_Source PLL Clock Source锁相环时钟的源
* @{
*/
#define RCC_PLLSOURCE_HSI RCC_PLLCFGR_PLLSRC_HSI
#define RCC_PLLSOURCE_HSE RCC_PLLCFGR_PLLSRC_HSE
/**
* @}
*/
/** @defgroup RCC_System_Clock_Type System Clock Type
* @{
*/
#define RCC_CLOCKTYPE_SYSCLK 0x00000001U
#define RCC_CLOCKTYPE_HCLK 0x00000002U
#define RCC_CLOCKTYPE_PCLK1 0x00000004U
#define RCC_CLOCKTYPE_PCLK2 0x00000008U
/**
* @}
*/
PLLQ是对OTG FS, SDIO and RNG clocks的分频因子,参数是2~15之间的数;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
以上代码是检测所调用的结构体函数RCC_OscInitStruct,是否编译成功;
RCC_ClkInitTypeDef结构体函数:
typedef struct
{
uint32_t ClockType; /*!< The clock to be configured.
This parameter can be a value of @ref RCC_System_Clock_Type */
uint32_t SYSCLKSource; /*!< The clock source (SYSCLKS) used as system clock.
This parameter can be a value of @ref RCC_System_Clock_Source */
uint32_t AHBCLKDivider; /*!< The AHB clock (HCLK) divider. This clock is derived from the system clock (SYSCLK).
This parameter can be a value of @ref RCC_AHB_Clock_Source */
uint32_t APB1CLKDivider; /*!< The APB1 clock (PCLK1) divider. This clock is derived from the AHB clock (HCLK).
This parameter can be a value of @ref RCC_APB1_APB2_Clock_Source */
uint32_t APB2CLKDivider; /*!< The APB2 clock (PCLK2) divider. This clock is derived from the AHB clock (HCLK).
This parameter can be a value of @ref RCC_APB1_APB2_Clock_Source */
}RCC_ClkInitTypeDef;
每个结构体所对应的的元素如下:
/** @defgroup RCC_System_Clock_Source System Clock Source
* @note The RCC_SYSCLKSOURCE_PLLRCLK parameter is available only for
* STM32F446xx devices.
* @{
*/
#define RCC_SYSCLKSOURCE_HSI RCC_CFGR_SW_HSI
#define RCC_SYSCLKSOURCE_HSE RCC_CFGR_SW_HSE
#define RCC_SYSCLKSOURCE_PLLCLK RCC_CFGR_SW_PLL
#define RCC_SYSCLKSOURCE_PLLRCLK ((uint32_t)(RCC_CFGR_SW_0 | RCC_CFGR_SW_1))
/**
* @}
*/
/** @defgroup RCC_System_Clock_Source_Status System Clock Source Status
* @note The RCC_SYSCLKSOURCE_STATUS_PLLRCLK parameter is available only for
* STM32F446xx devices.
* @{
*/
#define RCC_SYSCLKSOURCE_STATUS_HSI RCC_CFGR_SWS_HSI /*!< HSI used as system clock */
#define RCC_SYSCLKSOURCE_STATUS_HSE RCC_CFGR_SWS_HSE /*!< HSE used as system clock */
#define RCC_SYSCLKSOURCE_STATUS_PLLCLK RCC_CFGR_SWS_PLL /*!< PLL used as system clock */
#define RCC_SYSCLKSOURCE_STATUS_PLLRCLK ((uint32_t)(RCC_CFGR_SWS_0 | RCC_CFGR_SWS_1)) /*!< PLLR used as system clock */
/**
* @}
*/
/** @defgroup RCC_AHB_Clock_Source AHB Clock Source
* @{
*/
#define RCC_SYSCLK_DIV1 RCC_CFGR_HPRE_DIV1
#define RCC_SYSCLK_DIV2 RCC_CFGR_HPRE_DIV2
#define RCC_SYSCLK_DIV4 RCC_CFGR_HPRE_DIV4
#define RCC_SYSCLK_DIV8 RCC_CFGR_HPRE_DIV8
#define RCC_SYSCLK_DIV16 RCC_CFGR_HPRE_DIV16
#define RCC_SYSCLK_DIV64 RCC_CFGR_HPRE_DIV64
#define RCC_SYSCLK_DIV128 RCC_CFGR_HPRE_DIV128
#define RCC_SYSCLK_DIV256 RCC_CFGR_HPRE_DIV256
#define RCC_SYSCLK_DIV512 RCC_CFGR_HPRE_DIV512
/**
* @}
*/
/** @defgroup RCC_APB1_APB2_Clock_Source APB1/APB2 Clock Source
* @{
*/
#define RCC_HCLK_DIV1 RCC_CFGR_PPRE1_DIV1
#define RCC_HCLK_DIV2 RCC_CFGR_PPRE1_DIV2
#define RCC_HCLK_DIV4 RCC_CFGR_PPRE1_DIV4
#define RCC_HCLK_DIV8 RCC_CFGR_PPRE1_DIV8
#define RCC_HCLK_DIV16 RCC_CFGR_PPRE1_DIV16
/**
* @}
*/
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
HAL_SYSTICK_Config用来配置系统定时器中断时间;
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
配置系统定时器;
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
设置中断优先级;SysTick_IRQn代表终端类型是系统定时器中断,第一个0代表的是中断优先级,其取值范围是0~15,值越小其优先级越高;
第二个0代表子优先级,其取值范围是0~15,值越小其优先级越高;函数原型如下:
void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority)
接下来是才到初始化GPIO,MX_GPIO_Init();
具体代码如下:
void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
//首先需要使能GPIO组,这里一共有ABCDE五组GPIO组,
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOF, LED1_Pin|LED2_Pin|LED3_Pin|LED4_Pin, GPIO_PIN_RESET);
//调用函数HAL_GPIO_WritePin将F组的LED1_Pin(GPIO_PIN_6)等清零,LED1_Pin|LED2_Pin|LED3_Pin|LED4_Pin是宏定义,宏定义的定义在main.文件中,GPIO_PIN_RESET\参数的值是0,代表的是引脚的状态,清零表示当我们运行程序的时候这些引脚都被设置为低电平;;
/*Configure GPIO pins : PEPin PEPin PEPin */
GPIO_InitStruct.Pin = JOY_D_Pin|JOY_C_Pin|JOY_B_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
/*Configure GPIO pin : PtPin */
GPIO_InitStruct.Pin = JOY_A_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(JOY_A_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : PFPin PFPin PFPin PFPin */
GPIO_InitStruct.Pin = LED1_Pin|LED2_Pin|LED3_Pin|LED4_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
/*Configure GPIO pin : PtPin */
GPIO_InitStruct.Pin = KEY_USER_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(KEY_USER_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : PAPin PAPin */
GPIO_InitStruct.Pin = KEY_WAKEUP_Pin|JOY_CTR_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
以上这些结构体是设置引脚的状态,调用的是以下结构体:
typedef struct
{
uint32_t Pin; /*!< Specifies the GPIO pins to be configured.指定所需的引脚,有GPIO_PIN_0~15,16个引脚可以配置;
This parameter can be any value of @ref GPIO_pins_define */
uint32_t Mode; /*!< Specifies the operating mode for the selected pins.给这个引脚设置模式;模式有输入,普通上拉、下拉输出,复用上拉、下拉输出,模拟模式,外部中断上升沿、/下降沿触发模式,外部事件上升沿、/下降沿触发模式;
GPIO_MODE_INPUT
GPIO_MODE_OUTPUT_PP
GPIO_MODE_OUTPUT_OD
GPIO_MODE_AF_PP
GPIO_MODE_AF_OD
GPIO_MODE_ANALOG
GPIO_MODE_IT_RISING
GPIO_MODE_IT_FALLING
GPIO_MODE_IT_RISING_FALLING
GPIO_MODE_EVT_RISING
GPIO_MODE_EVT_FALLING
GPIO_MODE_EVT_RISING_FALLING
uint32_t Pull; /*!< Specifies the Pull-up or Pull-Down activation for the selected pins.指定的引脚是上拉还是下拉
GPIO_NOPULL 不处理
GPIO_PULLUP 上拉
GPIO_PULLDOWN 下拉
uint32_t Speed; /*!< Specifies the speed for the selected pins.指定引脚的速度
GPIO_SPEED_FREQ_LOW 低
GPIO_SPEED_FREQ_MEDIUM 中
GPIO_SPEED_FREQ_HIGH 高
GPIO_SPEED_FREQ_VERY_HIGH最高
uint32_t Alternate; /*!< Peripheral to be connected to the selected pins. 引脚是否是复用功能
This parameter can be a value of @ref GPIO_Alternate_function_selection */
}GPIO_InitTypeDef;
每个引脚配置完之后都执行函数:HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 来初始化所配置的引脚。
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
/* A - LED1 */
if(HAL_GPIO_ReadPin(JOY_A_GPIO_Port, JOY_A_Pin) == GPIO_PIN_RESET)
HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET);
else
HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET);
/* B - LED2 */
if(HAL_GPIO_ReadPin(JOY_B_GPIO_Port, JOY_B_Pin) == GPIO_PIN_RESET)
HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_SET);
else
HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_RESET);
/* C - LED3 */
if(HAL_GPIO_ReadPin(JOY_C_GPIO_Port, JOY_C_Pin) == GPIO_PIN_RESET)
HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, GPIO_PIN_SET);
else
HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, GPIO_PIN_RESET);
/* D - LED4 */
if(HAL_GPIO_ReadPin(JOY_D_GPIO_Port, JOY_D_Pin) == GPIO_PIN_RESET)
HAL_GPIO_WritePin(LED4_GPIO_Port, LED4_Pin, GPIO_PIN_SET);
else
HAL_GPIO_WritePin(LED4_GPIO_Port, LED4_Pin, GPIO_PIN_RESET);
/* PRESS - LED1 LED2 LED3 LED4 */
if(HAL_GPIO_ReadPin(JOY_CTR_GPIO_Port, JOY_CTR_Pin) == GPIO_PIN_RESET ||
HAL_GPIO_ReadPin(KEY_WAKEUP_GPIO_Port, KEY_WAKEUP_Pin) == GPIO_PIN_RESET ||
HAL_GPIO_ReadPin(KEY_USER_GPIO_Port, KEY_USER_Pin) == GPIO_PIN_RESET)
{
HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(LED4_GPIO_Port, LED4_Pin, GPIO_PIN_SET);
}
else
{
HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(LED4_GPIO_Port, LED4_Pin, GPIO_PIN_RESET);
}
}
/* USER CODE END 3 */
}
以上是对函数的操作,采用if—else结构先对所定义的引脚进行读操作,然后再进行写操作,然后再通过读取按键的值来操作LED 的状态。
以上就是Hal操作GPIO时所涉及到的知识;记录学习过程,与各位分享。