我使用的是STM32F429I-Discovery板,板上有一个连接到PA0的按钮,PA0又连接到外部中断线0(EXTI0) .
使用HAL库,我可以使用外部中断在下降沿或上升沿切换LED . 例如,一旦我按下按钮,LED就会改变状态,或者只有在我松开按钮后才会改变状态 .
我想要做的是在上升沿中断,启动定时器,然后再次在下降沿中断,以停止定时器 . 我不知道如何实现这个目标?
还有一个选项可以在上升沿和下降沿触发 . 我不知道是否只应该有一个中断,然后我会弄清楚它是上升沿还是下降沿(可能直接访问寄存器),或者是否应该有两个配置的中断 - 一个作为上升沿,一个作为下降边缘?
以下是外部中断代码;首先将GPIO设置为外部中断,然后检测中断然后处理中断(回调) .
static void EXTILine0_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable GPIOA clock */
__HAL_RCC_GPIOA_CLK_ENABLE();
/* Configure PA0 pin as input floating */
GPIO_InitStructure.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Pin = GPIO_PIN_0;
HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Enable and set EXTI Line0 Interrupt to the lowest priority */
HAL_NVIC_SetPriority(EXTI0_IRQn, 2, 0);
HAL_NVIC_EnableIRQ(EXTI0_IRQn);
}
/* Clears the interrupt after calling this I think */
void EXTI0_IRQHandler(void)
{
HAL_GPIO_EXTI_IRQHandler(KEY_BUTTON_PIN);
}
/**
* @brief EXTI line detection callbacks
* @param GPIO_Pin: Specifies the pins connected EXTI line
* @retval None
*/
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if(GPIO_Pin == KEY_BUTTON_PIN)
{
/* Toggle LED3 */
BSP_LED_Toggle(LED3);
}
}
有人可以指出我是如何实现这一目标的吗?
3 回答
首先,你必须设置一个计时器,例如
代码来自STM32F1,所以也许你需要适应一点,只需查看HAL手册 .
上升沿和下降沿的中断是相同的,因此您必须检查中断处理程序中引脚的状态 .
启动计时器
并停下来
计数器值存储在
您正在寻找的是“输入捕获”,可以直接使用定时器实现,无需外部中断 . 在STM32F429上,PA0内部映射到定时器2通道1 .
sConfigIC结构负责处理与输入捕获相关的配置内容 .
初始化看起来像这样:
进一步的中断功能:
在中断期间,您必须检查CC1IF标志 . 定时器值存储在名为CCR1的捕获和比较寄存器中 .
/编辑
不要忘记启动计时器并输入捕获通道:
这使得定时器,输入捕获的相应通道和中断成为可能 .
一点背景:使用STM32F429I,下面的代码是显示按下蓝色用户按钮的时间,计数以毫秒为单位 . PCB具有硬件去抖电路,因此我能够获得的最快响应是大约50ms .
如前所述,PA0连接到EXTILine0 . 我将PA0线设置为在上升沿和下降沿上中断 .
当发生中断时,我读取当前存储在HAL_GetTick()中的计数量,此函数每1毫秒计时一次 . 我还读取引脚是高还是低,以确定中断是在下降还是在上升沿 .
最后,中断回调触发并切换板上的LED . 计数器只能达到65秒之后,之后它会溢出并且我的“计算”时间不正确 . 这种方法适用于我打算用它做的事情 . 我想测量20-300毫秒,精确度为几毫秒 . 如果计时器在两次测量之间溢出,我仍然需要进行捕获 .
这种方法有什么根本错误吗?我对C不太熟悉,而STM32则没有 .