STM32F4 中断处理程序用于捕获其未调用
STM32F4 interrupt handler for capture its not called
下面的代码使用 TIM1 通道 3 的捕获比较功能来捕获 PE10 的上升沿,但它不起作用,没有调用中断处理程序。我不太擅长这种嵌入式的东西,所以有人可以告诉我我的设置是否正确吗?
#include "STM32/stm32f4xx_tim.h"
void TIM1_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* TIM1 clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
/* GPIOA clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
/* TIM1 channel 3 pin (PE.10) configuration */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOE, &GPIO_InitStructure);
/* Connect TIM pins to AF2 */
GPIO_PinAFConfig(GPIOE, GPIO_PinSource10, GPIO_AF_TIM1);
/* Enable the TIM1 global Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_ICInitTypeDef TIM_ICInitStructure;
TIM_ICInitStructure.TIM_Channel = TIM_Channel_3;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICFilter = 0x0;
TIM_ICInit(TIM1, &TIM_ICInitStructure);
/* TIM enable counter */
TIM_Cmd(TIM1, ENABLE);
/* Enable the CC3 Interrupt Request */
TIM_ITConfig(TIM1, TIM_IT_CC3, ENABLE);
}
void TIM1_CC_IRQHandler(void)
{
// .................
}
int StartCapture()
{
TIM1_Config();
while(1); /* Infinite loop */
}
可能是中断进入了函数但是不知道怎么办,或者enter ant flag还在激活只进入了一次,你错过了clear interrupt flag,试试这个:
/**
* @brief Capture Compare Handler
* @param None
* @retval None
*/
void TIM1_CC_IRQHandler()
{
if (TIM_GetITStatus(TIM1, TIM_IT_CC3) != RESET) <-- Add this
{
TIM_ClearITPendingBit(TIM1, TIM_IT_CC3); <-- This is important!
//TODO
}
}
如果您的 TIM1_CC_IRQHandler()
被调用一次,那么 Dracog71 的答案是正确的。但是,如果您的 IRQHandler()
从不 触发,则说明初始化有问题。
这是您必须做对的事情的列表,否则 IRQ 不会触发。
1) 确保 GPIO[A:E]
时钟已为您正在使用的引脚启用。
2) 同样,确保为您正在使用的 TIMx
启用了时钟。检查您的 TIMx
住在哪里。如果您为 APB1
上的计时器调用 RCC_APB2PeriphClockCmd()
,编译器不会抛出错误,但您的计时器永远不会工作。
3) 仔细检查您的引脚的 AF 与数据表的替代功能映射 table(例如 AF1 == TIM1_CH3
)相匹配。
4) 在您的 TIM_ICInitStructure
中,确保 TIM_Channel
与您选择的频道匹配(在您的情况下 TIM_Channel_3
)。
5) 在 NVIC 中配置并启用正确的 IRQ 通道,例如。 NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;
6) 开启中断:TIM_ITConfig(TIM1, TIM_IT_CC3, ENABLE);
7) 启用定时器:TIM_Cmd(TIM1, ENABLE);
好吧,我想我的答案在 6 年后就不需要了。但也许其他面临同样问题的人会找到它。
如果你用c++写,可能会有名字冲突。如果中断函数的原始原型定义为 C 函数,而您的实现是 C++ 函数,那么它只是两个具有相同名称的不同函数,中断将尝试调用一个空的 C 函数,甚至可能堆栈在无限循环中.所以这就是为什么你的 c++ 函数可能被更新调用的原因。
要解决这个问题,只需将函数定义为 extern "C".
下面的代码使用 TIM1 通道 3 的捕获比较功能来捕获 PE10 的上升沿,但它不起作用,没有调用中断处理程序。我不太擅长这种嵌入式的东西,所以有人可以告诉我我的设置是否正确吗?
#include "STM32/stm32f4xx_tim.h"
void TIM1_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* TIM1 clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
/* GPIOA clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
/* TIM1 channel 3 pin (PE.10) configuration */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOE, &GPIO_InitStructure);
/* Connect TIM pins to AF2 */
GPIO_PinAFConfig(GPIOE, GPIO_PinSource10, GPIO_AF_TIM1);
/* Enable the TIM1 global Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_ICInitTypeDef TIM_ICInitStructure;
TIM_ICInitStructure.TIM_Channel = TIM_Channel_3;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICFilter = 0x0;
TIM_ICInit(TIM1, &TIM_ICInitStructure);
/* TIM enable counter */
TIM_Cmd(TIM1, ENABLE);
/* Enable the CC3 Interrupt Request */
TIM_ITConfig(TIM1, TIM_IT_CC3, ENABLE);
}
void TIM1_CC_IRQHandler(void)
{
// .................
}
int StartCapture()
{
TIM1_Config();
while(1); /* Infinite loop */
}
可能是中断进入了函数但是不知道怎么办,或者enter ant flag还在激活只进入了一次,你错过了clear interrupt flag,试试这个:
/**
* @brief Capture Compare Handler
* @param None
* @retval None
*/
void TIM1_CC_IRQHandler()
{
if (TIM_GetITStatus(TIM1, TIM_IT_CC3) != RESET) <-- Add this
{
TIM_ClearITPendingBit(TIM1, TIM_IT_CC3); <-- This is important!
//TODO
}
}
如果您的 TIM1_CC_IRQHandler()
被调用一次,那么 Dracog71 的答案是正确的。但是,如果您的 IRQHandler()
从不 触发,则说明初始化有问题。
这是您必须做对的事情的列表,否则 IRQ 不会触发。
1) 确保 GPIO[A:E]
时钟已为您正在使用的引脚启用。
2) 同样,确保为您正在使用的 TIMx
启用了时钟。检查您的 TIMx
住在哪里。如果您为 APB1
上的计时器调用 RCC_APB2PeriphClockCmd()
,编译器不会抛出错误,但您的计时器永远不会工作。
3) 仔细检查您的引脚的 AF 与数据表的替代功能映射 table(例如 AF1 == TIM1_CH3
)相匹配。
4) 在您的 TIM_ICInitStructure
中,确保 TIM_Channel
与您选择的频道匹配(在您的情况下 TIM_Channel_3
)。
5) 在 NVIC 中配置并启用正确的 IRQ 通道,例如。 NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;
6) 开启中断:TIM_ITConfig(TIM1, TIM_IT_CC3, ENABLE);
7) 启用定时器:TIM_Cmd(TIM1, ENABLE);
好吧,我想我的答案在 6 年后就不需要了。但也许其他面临同样问题的人会找到它。 如果你用c++写,可能会有名字冲突。如果中断函数的原始原型定义为 C 函数,而您的实现是 C++ 函数,那么它只是两个具有相同名称的不同函数,中断将尝试调用一个空的 C 函数,甚至可能堆栈在无限循环中.所以这就是为什么你的 c++ 函数可能被更新调用的原因。 要解决这个问题,只需将函数定义为 extern "C".