2013-10-16 02:08 PM
I've been trying to solve this issue for way too long now. I've looked at other similar posts, but I am still unable to enter my ISR when the timer rolls over.
void init_interface(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
//init pin for output
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_40MHz;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOC, &GPIO_InitStruct);
}
void init_timer(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable the TIM9 global Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM9_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_TimeBaseStructure.TIM_Period = 160;
TIM_TimeBaseStructure.TIM_Prescaler = 1124;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM9, &TIM_TimeBaseStructure);
TIM_ClearFlag(TIM9, TIM_FLAG_Update);
TIM_ITConfig(TIM9, TIM_IT_Update, ENABLE);
TIM_Cmd(TIM9, ENABLE);
}
void main()
{
RCC_Config();
init_interface();
init_timer();
while(1);
}
Below is my ISR:
void TIM9_IRQHandler(void)
{
if(TIM_GetITStatus(TIM9, TIM_IT_Update) != RESET)
{
//clear interrupt
TIM_ClearITPendingBit(TIM9, TIM_IT_Update|TIM_IT_CC1|TIM_IT_CC2);
//toggle 'clock'
GPIO_ToggleBits(GPIOC, GPIO_Pin_1);
}
}
Basically, all I'm trying to do is toggle an output pin every X ms (or us or whatever. it doesn't really matter until the interrupt triggers), but I know I want to use the peripheral timers instead of the SysTick. When I run the debugger, I see that the code enters the NMI handler, and the disassembly says something about a 'bus error' which causes my program to hang. Everywhere I look says that this is how you set up a timebase, but I haven't had any luck whatsoever.
Any suggestions? Did I just miss something?
Thanks.
2013-10-16 02:27 PM
What tools are you using, is this a CPP file?
Where you're saying it ends up is a dumping ground for lost interrupts. Review startup_stm32f1xx.s, or .LD file for weak fixups. If compiling as C++ then you will get the handler name mangled and it won't link up with the vector table. Review your .MAP file for TIM9_IRQHandler2013-10-16 03:12 PM
Thanks for the quick response clive. You're a lifesaver. I am using IAR for ARM 6.60, and yes I was compiling as a c++ project.
You comment led me to a much more serious issue, however. I completely forgot to add the startup_stm32l1xx_md.s and system_stm32l1xx.c files to my project. Works like a charm now.Now excuse my while I hang my head in embarrasment.2013-10-17 12:27 AM
Just a thought: if you remmap the ivec to ram then you can install dynamically those isr handlers. It's also handy to remap because you can then plug'n'play a class' static isr handler into the ram vec.
If you using IAR, then you might also using embOS. SeeOS_ARM_InstallISRHandler
. If not you can create your own ram table (seeNVIC_SetVectorTable
). (And reason i noticed your thread is because I'm also currently on a low-power one :) )