Reputation: 20068
The code below uses the capture compare feature of TIM1 channel 3 to capture rising edge on PE10, but its not working, the interrupt handler its not called. I am not that good at this embedded stuff, so can somebody tell me if I am settings this correctly ?
#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 */
}
Upvotes: 1
Views: 6624
Reputation: 23
Well, I guess my answer isn't required after 6 years. But maybe somebody else facing same problem will find it. There may be a name conflict if you write in c++. If original prototype of interupt function is defined like C-function, and your implementation is C++function so it's just two different functions with the same name, and interupt will try to call an empty C-function or even may stack in endless loop. So that is why your c++ function may be newer called. To solve this, just define your function like extern "C".
Upvotes: 1
Reputation: 1545
If your TIM1_CC_IRQHandler()
is getting called ONCE, then Dracog71's answer is correct. However, if your IRQHandler()
is never firing, then there's something wrong in the initialization.
Here's a list of things you have to get right or the IRQ won't fire.
1) Make sure that the GPIO[A:E]
clock is enabled for the pin you are using.
2) Likewise, make sure the clock is enabled for the TIMx
you are using. Check where your TIMx
lives. If you call RCC_APB2PeriphClockCmd()
for a timer that lives on APB1
, the compiler won't throw an error, but your timer will never work.
3) Double-check your pin's AF matches the datasheet's Alternative Function Mapping table (eg. AF1 == TIM1_CH3
).
4) In your TIM_ICInitStructure
, make sure TIM_Channel
matches the channel you have chosen (in your case TIM_Channel_3
).
5) Configure and enable the correct IRQ channel in the NVIC, eg. NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;
6) Enable the interrupt: TIM_ITConfig(TIM1, TIM_IT_CC3, ENABLE);
7) Enable your timer: TIM_Cmd(TIM1, ENABLE);
Upvotes: 1
Reputation: 1
Maybe the interrupt enters the functions but does not know what to do, or enter ant he flag is still active and just enters once, you're missing the clear interrupt flag, try this:
/**
* @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
}
}
Upvotes: 0