2016-07-08 03:10 PM
I'm writing code for STM32F4.
I'm trying to set interrupt handler for TIM1 which is configured as PWM1 output.The timer itself works, but I'm unable to configure the interrupt handler static void initTimer(void){ TIM_TimeBaseInitTypeDef TIM_BaseStruct; RCC_APB2PeriphClockCmd(MOTOR_TIM_CLK, ENABLE); TIM_BaseStruct.TIM_Prescaler = (APBx_FREQ/CNT_FREQ) - 1; TIM_BaseStruct.TIM_CounterMode = TIM_CounterMode_Up; TIM_BaseStruct.TIM_ClockDivision = TIM_CKD_DIV1; TIM_BaseStruct.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(MOTOR_TIM, &TIM_BaseStruct);}static void initPWM(void){ TIM_OCInitTypeDef TIM_OCStruct; /* PWM mode 1 = Set on compare match */ TIM_OCStruct.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCStruct.TIM_OutputState = TIM_OutputState_Enable; TIM_OCStruct.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCStruct.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCStruct.TIM_OCNPolarity = TIM_OCNPolarity_Low; TIM_OCStruct.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OCStruct.TIM_OCNIdleState = TIM_OCNIdleState_Reset; TIM_OC1Init(MOTOR_TIM,&TIM_OCStruct); }static void initInterrupt(void){ NVIC_InitTypeDef nvic_init; TIM_ITConfig(MOTOR_TIM, TIM_IT_Update, DISABLE); nvic_init.NVIC_IRQChannel = TIM1_UP_TIM10_IRQn; nvic_init.NVIC_IRQChannelPreemptionPriority = 0; nvic_init.NVIC_IRQChannelSubPriority = 1; nvic_init.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&nvic_init);/* enables the device and sets interrupt priority */ TIM_ClearITPendingBit(MOTOR_TIM, TIM_IT_Update); TIM_ITConfig(MOTOR_TIM, TIM_IT_Update, ENABLE);}void MotorDriver_Init(void){ RCC_ClocksTypeDef rccClocks; RCC_GetClocksFreq(&rccClocks); APBx_FREQ = rccClocks.PCLK2_Frequency * 2; initGpio(); initTimer(); initPWM(); initInterrupt();}void MotorDriver_Isr(void){ if (TIM_GetITStatus(MOTOR_TIM, TIM_IT_Update) != RESET) { if (number_of_steps > 0) { number_of_steps--; if(number_of_steps == 0){ TIM_ITConfig(MOTOR_TIM,TIM_IT_Update, DISABLE); stopMotor(); } } TIM_ClearITPendingBit(MOTOR_TIM, TIM_IT_Update); }}void TIM1_UP_TIM10_IRQHandler(void){ MotorDriver_Isr();}When I run the code it executes without any errors/warnings, but I'm unable to set breakpoints in the handler or Driver_Isr. After all the configurations it jumps to the HardFault handler. If I disable the interrupt configuration, everything else works fine. It seems to me like the firmware is just unable to jump to the handler code.I also cannot see anything about the handler in the map file. I re verified that the vector address and handler definitions are correct in the startup and stm32f4xx.h files.The systick interrupt seems to be working fine. Any other handler I tried to configure introduced similar behavior What am I doing wrong/missing?2016-07-08 05:10 PM
Parameters missing, and you don't enable timer
TIM_BaseStruct.TIM_Prescaler = 0;
TIM_BaseStruct.TIM_Period = (APBx_FREQ/CNT_FREQ) - 1;
TIM_BaseStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_BaseStruct.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_BaseStruct.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM1, &TIM_BaseStruct);
...
/* TIM enable counter */
TIM_Cmd(TIM1, ENABLE);
/* Main Output Enable, and Input */
TIM_CtrlPWMOutputs(TIM1, ENABLE);
2016-07-08 05:23 PM
Sorry, forgot the function that starts the timer.
void MotorDriver_Start(MotorDirection_t direction, uint32_t speed, MotorDuty_t duty, uint32_t steps){ setDirection(direction); number_of_steps = steps; TIM_SetAutoreload(MOTOR_TIM, CNT_FREQ/speed - 1); TIM_SetCompare1(MOTOR_TIM, ((CNT_FREQ/speed - 1) * duty) / 100); TIM_Cmd(MOTOR_TIM,ENABLE); TIM_CtrlPWMOutputs(MOTOR_TIM,ENABLE);}As I said, the timer itself works as expected. The issue is only with the interrupt and it seems like it is not only that interrupt. In addition, optimization is disabled.2016-07-08 05:51 PM
Are you using a .CPP file?
Does the name exactly match the one in the startup.s file's vector table?2016-07-10 06:52 AM
No, I'm using a .c file.
Yes, the name matches exactly the name in the startup.s file.2016-07-10 01:12 PM
Perhaps you can present this as a complete and concise project. I don't want to have to play 20 questions to figure out what's wrong.
2016-07-10 02:34 PM
I'd start with this...
// STM32F4-Discovery TIM1 40KHz PWM, modulating 1 second ON, 10 seconds OFF (PA.08 TIM1_CH1) - sourcer32@gmail.com
#include ''stm32f4_discovery.h''
/**************************************************************************/
void RCC_Configure(void)
{
/* GPIOA clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
/* TIM1 clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
}
/**************************************************************************/
void NVIC_Configure(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable the TIM1 global Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_TIM10_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/**************************************************************************/
void GPIO_Configure(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* GPIOA Configuration: TIM1 CH1 (PA8) */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
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_UP ;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Connect TIM1 pins to AF */
GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_TIM1);
}
/**************************************************************************/
uint32_t Period;
void TIM1_Configure(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
Period = SystemCoreClock / 40000; // 40 KHz, from APB2 clock *2, nominally 168 MHz
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_Period = Period - 1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
/* PWM1 Mode configuration: Channel1 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_Pulse = Period / 2; // 50/50 duty
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
TIM_OC1Init(TIM1, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
/* TIM Interrupts enable */
TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);
/* Main Output Enable, and Input */
TIM_CtrlPWMOutputs(TIM1, ENABLE);
/* TIM enable counter */
TIM_Cmd(TIM1, ENABLE);
}
/**************************************************************************/
void TIM1_UP_TIM10_IRQHandler(void) // 40KHz
{
static int modulatingcount = 0;
// 1 Second On - 40000 ticks
// 10 Seconds Off - 400000 ticks
// full cycle 440000 ticks
if (TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET) // Validate source
{
TIM_ClearITPendingBit(TIM1, TIM_IT_Update); // Clear source
modulatingcount = (modulatingcount + 1) % 440000;
if (modulatingcount > 40000)
TIM1->CCR1 = 0; // Off
else
TIM1->CCR1 = Period / 2; // 50/50 duty
}
}
/**************************************************************************/
int main(void)
{
RCC_Configure();
NVIC_Configure();
GPIO_Configure();
TIM1_Configure();
while(1); // Do not exit
}
/**************************************************************************/
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t* file, uint32_t line)
{
/* User can add his own implementation to report the file name and line number,
ex: printf(''Wrong parameters value: file %s on line %d
'', file, line) */
while (1)
{}
}
#endif
/**************************************************************************/