[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 */