[HAL]STM32定时器和按键中断的使用

使用Clion+CubeMX开发,开发板为野火指南者,芯片为STM32F103ZET6.

简单实现使用定时器和按键中断点亮LED。

Cube MX设置

引脚设置

板载RGB-LED使用的引脚PB0,PB1,PB5设置为output push pull(推挽输出)。

板载微动开关使用的引脚PA0,PC13设置为外部中断且下降沿触发。同时NVIC设置EXTI0和EXTI15-10的使能。

时钟设置

选择TIM1,时钟源选择内部时钟(Internal Clock)。设置参数为预分频36000,计数为1000,此时频率为72MHz/36000/1000=2Hz。

NVIC开启TIM1 update interrupt中断。

其他设置

SYS中设置调试器模式.

RCC中设置HSE使用外部晶振,在Clock Configuration中设置时钟.

生成代码时选择根据外设生成对应的.C/.H文件.

Clion代码

在CubeMX设置时为GPIO指定user label。在生成的代码中就会自动定义对应的GPIO端口和引脚。

LED宏定义

/* USER CODE BEGIN Private defines */
#define ON  GPIO_PIN_RESET
#define OFF GPIO_PIN_SET

#define LED1(a) HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, a)
#define LED2(a) HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, a)
#define LED3(a) HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, a)

#define LED1_ON         LED1(ON)
#define LED1_OFF        LED1(OFF)
#define LED1_TOGGLE     HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin)

#define LED2_ON         LED2(ON)
#define LED2_OFF        LED2(OFF)
#define LED2_TOGGLE     HAL_GPIO_TogglePin(LED2_GPIO_Port, LED2_Pin)

#define LED3_ON         LED3(ON)
#define LED3_OFF        LED3(OFF)
#define LED3_TOGGLE     HAL_GPIO_TogglePin(LED3_GPIO_Port, LED3_Pin)

#define LED_RED {LED1_ON;LED2_OFF;LED3_OFF;}
#define LED_GREEN {LED1_OFF;LED2_ON;LED3_OFF;}
#define LED_BLUE {LED1_OFF;LED2_OFF;LED3_ON;}
#define LED_YELLOW {LED1_ON;LED2_ON;LED3_OFF;}
#define LED_PURPLE {LED1_ON;LED2_OFF;LED3_ON;}
#define LED_CYAN {LED1_OFF;LED2_ON;LED3_ON;}
#define LED_WHITE {LED1_ON;LED2_ON;LED3_ON;}
#define LED_BLACK {LED1_OFF;LED2_OFF;LED3_OFF;}

/* USER CODE END Private defines */

按键中断处理

在stm32f1xx_it.c文件中发现EXTI中断调用HAL_GPIO_EXTI_IRQHandler(void)函数,网上找到的资料说该函数调用弱定义的HAL_GPIO_EXTI_Callback()函数。(虽然我没找到在哪)

因此在main.c函数中重复定义该函数用于中断处理.

/* USER CODE BEGIN 4 */
/**
  * @brief EXTI Handler Callback: KEY Response
  * @retval None
  */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    // select target GPIO
    switch (GPIO_Pin)
    {
        case KEY1_Pin:LED1_TOGGLE;break;
        case KEY2_Pin:LED2_TOGGLE;break;
        default:break;
    }
}
/* USER CODE END 4 */

时钟中断处理

在stm32f1xx_it.c文件中发现TIM1中断调用HAL_TIM_IRQHandler(void)函数,网上找到的资料说该函数调用弱定义的HAL_TIM_PeriodElapsedCallback()函数。

因此在main.c函数中重复定义该函数用于中断处理.

/* USER CODE BEGIN 4 */
/**
  * @brief TIM Handler Callback: LED Blink
  * @retval None
  */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    // TIM1: LED3 blink
    if (htim->Instance == htim1.Instance)
    {
        LED3_TOGGLE;
    }
}

/* USER CODE END 4 */
Lei Yang
Lei Yang
PhD candidate

My research interests include visual speech recognition and semantics segmentation.