2013-03-02 08:22 AM
Hello,
I want to use Timer2 to generate approx 1secs Pulse without interrupt. I want the code to sit in an endless loop while testing the TIM2 update interrupt flag or TIM2 CCP1 Flag (I plan to use Compare instead of Update in the future). The problem is I can not generate the pulse when view with Salae Logic Analyzer. it seems like the TIM2 update interrupt flag is always set or something is wrong with my code. Please I need help. const uint32_t Comm_Index[6] = {0x00001054,0x00001504,0x00001540,0x00001045,0x00001405,0x00001450}; uint32_t Ramp_Index; uint32_t NextCommutationStep; uint32_t CurrentCommutationStep; uint32_t BEMF_DETECTION_FLAG = FALSE; extern uint32_t Step_Count; void StartUp(void) { TIM1->CCER = Comm_Index[CurrentCommutationStep];/*Align Rotor to Step 1*/ TIM1->CCR1 = TIM1->CCR2 = TIM1->CCR3 = 1024; Ramp_Index = Step_Count = 0; NextCommutationStep = CurrentCommutationStep = 0;/*Align Rotor to Step 0 */ TIM2->PSC = 2199; /*Set Prescaler to (PSC + 1)*/ TIM2->ARR = 32727; /*Auto reload value 1000ms Alignment)*/ TIM2->DIER = TIM_DIER_UIE ; /*Enable update interrupt (timer level)*/ TIM2->CR1 = TIM_CR1_CEN; /*Start TIM2 (ALIGNMENT COUNTDOWN)*/ GPIOB->ODR ^= (1 << 8); while (!(TIM2->SR & TIM_SR_UIF)) { /*1000ms ALIGNEMENT TIME EXPIRE*/ } TIM2->SR &= ~TIM_SR_UIF; /*clear UIF flag */ GPIOB->ODR ^= (1 << 8); TIM1->CCER = Comm_Index[NextCommutationStep]; /*Align Rotor to Step 1*/ NextCommutationStep++; /*Increment to the Next Commutation Step*/ GPIOB->ODR ^= (1 << 8); /*Toggle PB8*/ } Regards Slim2013-03-02 09:02 AM
TIM2->SR = ~TIM_SR_UIF; // Just write, not RMW
2000-1 and 36000-1 might get you closer to 1 Hz2013-03-02 09:59 AM
Hello,
Thanks for your response.However, the code didn't work after I did your modification.What is possibly wrong? void StartUp(void) { NextCommutationStep = CurrentCommutationStep = 0;/*Align Rotor to Step 0 */ TIM2->PSC = 2199; /*Set Prescaler to (PSC + 1)*/ TIM2->ARR = 32727; /*Auto reload value 1000ms Alignment)*/ TIM2->DIER = TIM_DIER_UIE ; /*Enable update interrupt (timer level)*/ TIM2->CR1 = TIM_CR1_CEN; /*Start TIM2 (ALIGNMENT COUNTDOWN)*/ GPIOB->ODR ^= (1 << 8); while (!(TIM2->SR & TIM_SR_UIF)){ /*1000ms ALIGNEMENT TIME EXPIRE*/ } TIM2->SR = ~TIM_SR_UIF; /*clear UIF flag */ NextCommutationStep++; /*Increment to the Next Commutation Step*/ GPIOB->ODR ^= (1 << 8); /*Toggle PB8*/ } Regards2013-03-04 12:46 AM
You apparently assume, that the timer is in its reset state before entering this routine; e.g. you don't set the counter register itself TIMx_CNT, and you leave the timer running after the ''event''.
However, the timer may not be the in expected state especially if you use debug tools to ''reset'' the chip instead of true hardware reset. You might either properly set all the relevant registers/bits, or alternatively reset the timer through RCC's reset register at the beginning of above routine. JW2014-02-21 02:52 AM
a simple example for 250hz ,50% duty cycle it may help u
#include''stm8l15x.h''#include''stm8l15x_it.h''#include''stm8l15x_clk.h''#include''stm8l15x_gpio.h''#include''stm8l15x_tim2.h''void Timer2_isr(void){ while(TIM2_GetCounter()!=0xFF); TIM2_Cmd(DISABLE); GPIO_ToggleBits(GPIOE,GPIO_Pin_7); TIM2_SetCounter(0x01); }void main(void){ GPIO_DeInit(GPIOE); //port E GPIO_Init(GPIOE,GPIO_Pin_7,GPIO_Mode_Out_PP_Low_Slow); TIM2_DeInit(); CLK_SYSCLKDivConfig(CLK_SYSCLKDiv_2); CLK_PeripheralClockConfig(CLK_Peripheral_TIM2, ENABLE); TIM2_TimeBaseInit(TIM2_Prescaler_128,TIM2_CounterMode_Up ,0xFF); while (1) { TIM2_Cmd(ENABLE); Timer2_isr(); }}2014-02-21 05:04 AM
a simple example for 250hz ,50% duty cycle it may help u
Probably less than you think, this is the STM32 forum, not the STM8 one