哈哈,最近搬家加入职没空写笔记,现在还是工作时间写的。
拿出STM32,打算移植下 之前用的库函数,好吧先来个IO中断,纳尼,HAL库没有中断的demo,只有LL库有?好吧试下直接调库函数,好吧失败了。什么鬼居然不给个demo,我怎么知道怎么使用。经过一番资料查找,知道如何使用IO中断了。
IO中断使用方法。
STM32F103RB-Nucleo\Examples\GPIO\GPIO_IOToggle,在这个基础上改。
Nucleo 只有一个按键C13,且外部已经接了上拉,按下短接到地。
代码如下
main.c中 初始化:
USER_BUTTON_GPIO_CLK_ENABLE();
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
? GPIO_InitStruct.Pull = GPIO_NOPULL;
? GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
?
? GPIO_InitStruct.Pin = USER_BUTTON_PIN;
HAL_GPIO_Init(USER_BUTTON_GPIO_PORT, &GPIO_InitStruct);
HAL_NVIC_SetPriority(USER_BUTTON_EXTI_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USER_BUTTON_EXTI_IRQn);
// EXTI_HandleTypeDef button_exti_type;
// button_exti_type.Line = USER_BUTTON_EXTI_IRQn;
// button_exti_type.PendingCallback = NULL;
//
// EXTI_ConfigTypeDef button_exti_cfg;
// button_exti_cfg.GPIOSel = EXTI_GPIOC;//EXTI_GPIOC USER_BUTTON_GPIO_PORT
// button_exti_cfg.Line = EXTI_LINE_13;
// button_exti_cfg.Mode = EXTI_MODE_INTERRUPT;
// button_exti_cfg.Trigger = EXTI_TRIGGER_FALLING;
//
// HAL_EXTI_SetConfigLine(&button_exti_type,&button_exti_cfg);
//开始还以为调这个API注册中断,结果是调 NVIC 注册中断。
?
?
?
// 定义中断回调, 在 startup_stm32f103xb.s 中可以看见 所有的中断函数名称。
void EXTI15_10_IRQHandler(void)
{
HAL_GPIO_TogglePin(LED2_GPIO_PORT, LED2_PIN);
//HAL_GPIO_EXTI_IRQHandler(USER_BUTTON_PIN);
}
?
理论上按下USER 按键就能翻转LED状态。
实际按下按键,就会发现灯一直亮着,debug一下,会发现,按键按下触发中断后,再在中断函数处打上断点,程序还会进去。想到了之前看到的这段代码:
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
{
/* EXTI line interrupt detected */
if (__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != 0x00u)
{
? __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
? HAL_GPIO_EXTI_Callback(GPIO_Pin);
}
}
?
/**
* @brief EXTI line detection callbacks.
* @param GPIO_Pin: Specifies the pins connected EXTI line
* @retval None
*/
__weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(GPIO_Pin);
/* NOTE: This function Should not be modified, when the callback is needed,
? ? ? ? ? the HAL_GPIO_EXTI_Callback could be implemented in the user file
? */
}
需要清除中断标志位。无语~,我就想开个IO中断,还要整这么多东西,开时钟,使能NVIC,清除中断标志位,库函数能不能默认给我完成这些操作。
所以正确写法是:
在 stm32f1xx_it.c 中实现,
void EXTI15_10_IRQHandler(void)
{
HAL_GPIO_EXTI_IRQHandler(USER_BUTTON_PIN); //使用 hal_gpio的库函数,会清除中断标志位。
}
?
?
在 main.c 中重新实现 HAL_GPIO_EXTI_Callback
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
HAL_GPIO_TogglePin(LED2_GPIO_PORT, LED2_PIN);
}
然后按下USER 按键就能翻转LED状态,这就实现了想要的功能。在查找过程中发现
BSP_PB_Init(BUTTON_KEY, BUTTON_MODE_GPIO);
难道这个就是可以简单初始化 IO 中断的API?试一试。
果然将之前的代码屏蔽,替换为BSP_PB_Init,可以使按键中断生效。
// USER_BUTTON_GPIO_CLK_ENABLE();
//
// GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
// GPIO_InitStruct.Pull = GPIO_NOPULL;
// GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
?
// GPIO_InitStruct.Pin = USER_BUTTON_PIN;
//
// HAL_GPIO_Init(USER_BUTTON_GPIO_PORT, &GPIO_InitStruct);
//
// HAL_NVIC_SetPriority(USER_BUTTON_EXTI_IRQn, 0, 0);
// HAL_NVIC_EnableIRQ(USER_BUTTON_EXTI_IRQn);
BSP_PB_Init(BUTTON_KEY, BUTTON_MODE_EXTI);
?
但是这个BSP只有一个固定的按键,能否输入一个IO,来实现BSP_PB_Init,我写一下。
|