2006-10-18 10:37 PM
Need code sample for timer interrupts.
2011-05-17 12:33 AM
I cannot figure out how to get a timer to generate an interrupt at a fixed interval. This question has been asked here at least twice recently, and both times was answered with an incomplete code fragment that I cannot compile (using the IAR dev kit). For example, I just want to configure TIM0 to interrupt every 10ms, and have its interrupt service routine increment a global counter that I can print out periodically in the main loop. Can someone please provide the code to do that?
2011-05-17 12:33 AM
Keil's STR9 ''Blinky'' example has a timer based interrupt example.
I think you can down load this from the keil website. I know thi sis not an IAR example, but maybe it will lead you down the correct path!2011-05-17 12:33 AM
Thanks for the pointer, but I'm looking for sample code using the STR91x library functions so that I can understand how they work (i.e what I'm doing wrong). The Keil example doesn't use the library.
2011-05-17 12:33 AM
Maybe if I just give my code, somebody can find the problem:
main.c ------ #include ''91x_lib.h'' #include int IRQ_counter = 0; main() { TIM_InitTypeDef TIM0_InitStructure; // usual clock & uart initialization, etc. omitted /* TIM0 Initialization */ #define TIM0Prescaler 0xFF #define PWMFreqInHz 100 #define PWMPulsePercent 33 SCU_APBPeriphClockConfig(__TIM01, ENABLE); TIM_DeInit(TIM0); TIM_StructInit(&TIM0_InitStructure); /* TIM0 Configuration in PWM Mode */ TIM0_InitStructure.TIM_Mode = TIM_PWM; TIM0_InitStructure.TIM_Clock_Source = TIM_CLK_APB; TIM0_InitStructure.TIM_Prescaler = TIM0Prescaler; TIM0_InitStructure.TIM_Pulse_Level_1 = TIM_HIGH; TIM0_InitStructure.TIM_Period_Level = TIM_LOW; TIM0_InitStructure.TIM_Full_Period = (SCU_GetMCLKFreqValue())*1000 / ((TIM0Prescaler + 1) * PWMFreqInHz); TIM0_InitStructure.TIM_Pulse_Length_1 = TIM0_InitStructure.TIM_Full_Period * PWMPulsePercent / 100; TIM_Init (TIM0, &TIM0_InitStructure); /* Enable and configure the priority of the IRQ Channel*/ SCU_AHBPeriphClockConfig(__VIC, ENABLE); VIC_DeInit(); VIC_Config(TIM0_ITLine, VIC_IRQ, 0); VIC_ITCmd(TIM0_ITLine, ENABLE); TIM_ITConfig(TIM0, TIM_IT_TO, ENABLE); TIM_CounterCmd(TIM0, TIM_START); while (1) { if (IRQ_counter % 100 == 0) putchar('.'); } } 91x_it.c --------- void TIM0_IRQHandler(void) { extern int IRQ_counter; IRQ_counter++; TIM_ClearFlag(TIM0, TIM_FLAG_TO); }2011-05-17 12:33 AM
hi jonny_h
I use a similar configuration but with a different irq event: /* Enable the Timer Overflow interrupt */ TIM_ITConfig(TIM0, TIM_IT_OC2, ENABLE); I'm not sure but for what I understand the pwm mode doesn't trig the Timer overflow (TO). If you like to use the TO event I suggest to you to use a different configuration for the timer, like output compare mode2011-05-17 12:33 AM
Quote:
On 18-10-2006 at 00:34, Anonymous wrote: The Keil example doesn't use the library. To me that's a positive. I find the ST lib stuff to be overly complicated and written in a way that is hard to figure out what its doing. I'm much more comfortable configuring my peripherals with simple writes to registers.2011-05-17 12:33 AM
hi jonny_h,
Are you all right? Try the following piece of code please. It works in my board. #include ''91x_lib.h'' #define TIM0Prescaler 0xFF #define PWMFreqInHz 100 #define PWMPulsePercent 33 TIM_InitTypeDef TIM_InitStructure; void TIM0_IRQHandlerInvoked(void) { // balah balah // ... /*Clear the TIM_TO flag for the next interrupt*/ TIM_ClearFlag(TIM0, TIM_FLAG_TO); } void main(void) { #ifdef DEBUG debug(); #endif /*-------------------- System Clock Config --------------------*/ SCU_MCLKSourceConfig(SCU_MCLK_OSC); // Someone said PLL = 96 MHz is unstable, so change PLL = 48 MHz //SCU_PLLFactorsConfig(0xC0, 0x19, 0x2); // PLL = 96 MHz SCU_PLLFactorsConfig(0xC0, 0x19, 0x3); // PLL = 48 MHz SCU_PLLCmd(ENABLE); SCU_MCLKSourceConfig(SCU_MCLK_PLL); /* Enable VIC clock */ SCU_AHBPeriphClockConfig(__VIC,ENABLE); VIC_DeInit(); /* Enable TIM0 clock */ SCU_APBPeriphClockConfig(__TIM01, ENABLE); TIM_DeInit(TIM0); TIM_StructInit(&TIM_InitStructure); TIM_InitStructure.TIM_Mode = TIM_PWM; TIM_InitStructure.TIM_Clock_Source = TIM_CLK_APB; TIM_InitStructure.TIM_Prescaler = 0xFF; TIM_InitStructure.TIM_Pulse_Level_1 = TIM_HIGH; TIM_InitStructure.TIM_Period_Level = TIM_LOW; TIM_InitStructure.TIM_Full_Period = (SCU_GetMCLKFreqValue())*1000 / ((TIM0Prescaler + 1) * PWMFreqInHz); TIM_InitStructure.TIM_Pulse_Length_1 = TIM_InitStructure.TIM_Full_Period * PWMPulsePercent / 100; /* Initialize the Timer 0 */ TIM_Init (TIM0, &TIM_InitStructure); /* Enable the Timer Overflow interrupt */ TIM_ITConfig(TIM0, TIM_IT_TO, ENABLE); VIC_Config(TIM0_ITLine, VIC_IRQ, 4); VIC_ITCmd(TIM0_ITLine, ENABLE); /* Start the Timer counter */ TIM_CounterCmd(TIM0, TIM_START); while(1) { // balah balah // ... } } in 91x_it.c --------- extern void TIM0_IRQHandlerInvoked(void); void TIM0_IRQHandler(void) { TIM0_IRQHandlerInvoked(); } 91x_it.h #ifndef __91x_CONF_H #define __91x_CONF_H #define DEBUG #define _VIC #define _VIC0 #define _TIM #define _TIM0 #define _SCU #ifndef _Main_Crystal #define _Main_Crystal 25000 #endif #endif2011-05-17 12:33 AM
I use following code on my KEIL STR9 evaluation board.
Timer 1 is used as a 1mS interrupt generator, 2 others are used a counters. Luc Vercruysse. Robosoft n.v. __irq void TIM1_IRQHandler (void) { test = test + 1; TIM_ClearFlag(TIM1,TIM_FLAG_OC1); //Clear pending interrupt flag VIC0->VAR = 0x0000; //End of interrupt VIC1->VAR = 0x0000; TIM1->OC1R += 200; //every 1mS } extern __irq void TIM1_IRQHandler(void); extern long test; TIM_InitTypeDef Timer ; GPIO_InitTypeDef GPIO; int main (void) { //Interrupt setup SCU_APBPeriphClockConfig(__VIC,ENABLE); VIC_DeInit(); VIC_Config(TIM1_ITLine,VIC_IRQ,1); VIC_ITCmd(TIM1_ITLine,ENABLE); //Timer Setup SCU_APBPeriphClockConfig(__TIM01, ENABLE); /* Enable the clock for TIM0 and TIM1 */ SCU_APBPeriphClockConfig(__TIM23, ENABLE); /* Enable the clock for TIM0 and TIM1 */ TIM_DeInit(TIM0); /* TIM0 Deinitialization */ TIM_DeInit(TIM1); /* TIM1 Deinitialization */ TIM_DeInit(TIM2); /* TIM2 Deinitialization */ SCU_TIMCLKSourceConfig(SCU_TIM01,SCU_TIMCLK_EXT); SCU_TIMCLKSourceConfig(SCU_TIM23,SCU_TIMCLK_EXT); //Init Counter 0 (as a counter) Timer.TIM_Mode = TIM_OCM_CHANNEL_1; Timer.TIM_Clock_Source = TIM_CLK_EXTERNAL; Timer.TIM_Clock_Edge = TIM_CLK_EDGE_RISING; TIM_Init (TIM0, &Timer); TIM_CounterCmd(TIM0,TIM_CLEAR); TIM_CounterCmd(TIM0,TIM_START); //Init Counter 2 (as a counter) Timer.TIM_Mode = TIM_OCM_CHANNEL_1; Timer.TIM_Clock_Source = TIM_CLK_EXTERNAL; Timer.TIM_Clock_Edge = TIM_CLK_EDGE_RISING; TIM_Init (TIM2, &Timer); TIM_CounterCmd(TIM2,TIM_CLEAR); TIM_CounterCmd(TIM2,TIM_START); //Init Timer 1 (1 mSinterrupt (FCLK = 96MHz) Timer.TIM_Mode = TIM_OCM_CHANNEL_1; Timer.TIM_Clock_Source = TIM_CLK_APB; Timer.TIM_Clock_Edge = TIM_CLK_EDGE_RISING; TIM_Init (TIM1, &Timer); TIM_PrescalerConfig(TIM1,240); TIM_CounterCmd(TIM1,TIM_START); TIM_ITConfig(TIM1,TIM_IT_OC1,ENABLE); //output capture ..... }