2013-05-17 03:23 PM
Since 4 day I'm trying write code which will be able to count external pulses. I tried to use encoder mode but i supposed that this work only with 2 quadrature encoders. I have only one pulse signal and i have no idea how to do it. Could you help me or show examples how to count external pulses using timer?
#counter #timer #off-topic #pulce2015-04-06 09:17 AM
I cannot figure out why i do not get the external pulse values print in my USART. please help.
float x_dot;void TIM3_Configuration(void){ GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; /* GPIOC clock enable */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); /* TIM3 clock enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); /* GPIOA Configuration: TIM3 CH1 (PD12) */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; // Input/Output controlled by peripheral GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; // Button to ground expectation GPIO_Init(GPIOD, &GPIO_InitStructure); /* Connect TIM3 pins to AF */ GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_TIM4); TIM_TimeBaseStructure.TIM_Period = 65535; TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); TIM_TIxExternalClockConfig(TIM4, TIM_TIxExternalCLK1Source_TI1, TIM_ICPolarity_Rising, 0); TIM_Cmd(TIM4, ENABLE);}int main(){ char str[120]; SystemInit(); TM_DELAY_Init(); /* Initialize USART, TX: PB6 */ TM_USART_Init(USART1, TM_USART_PinsPack_2, 9600); while(1){ /* Every 500ms */ if (TM_DELAY_Time() >= 500) { /* Reset time */ TM_DELAY_SetTime(0); x_dot = TIM_GetCounter(TIM4); sprintf(str, ''x_dot- %f\r\n'', x_dot); TM_USART_Puts(USART1, str); } }}2015-04-06 11:02 AM
I cannot figure out why i do not get the external pulse values print in my USART. please help.
I'm not using that library, inconsistent TIM3 and TIM4 references, but nothing that's obviously fatal. So what can you tell about what's happening via the debugger, and oscilloscope?2015-04-07 08:39 AM
hi clive1. thank you for responding. i have done a stupid mistake. have not called the TIM4_Configuration(); inside the ''main''. after i get values.
my external signal is a frequency varying from around 30 to 200Hz for different motor speeds. its coming from my motor controller. i need the frequency value to then get the speed and use the speed to control my motor. now i get the frequency but for a particular motor speed frequency is not constant. it gives varying values on my usart. i cannot figure out the problem in my code. please help. thank you in advance.float x;int CaptureNumber = 0;float counter;float Time;float freq;void TIM4_Configuration(void){ GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; TIM_ICInitTypeDef TIM_ICInitStructure; /* GPIOC clock enable */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); /* TIM4 clock enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); /* GPIOA Configuration: TIM4 CH1 (PD12) */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; // Input/Output controlled by peripheral GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; // Button to ground expectation GPIO_Init(GPIOD, &GPIO_InitStructure); /* Connect TIM4 pins to AF */ GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_TIM4); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);// //Time initialization TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; //Control with dead zone. TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //Counter direction TIM_TimeBaseInitStructure.TIM_Prescaler = 84-1; //Timer clock = sysclock /(TIM_Prescaler+1) = 2M TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInitStructure.TIM_Period = 0xFFFF;//Period = (TIM counter clock / TIM output clock) - 1 = 40Hz TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStructure); TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; TIM_ICInitStructure.TIM_ICFilter = 0; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInit(TIM4,&TIM_ICInitStructure); TIM_Cmd(TIM4,ENABLE);}int main(){ char str[120]; SystemInit(); TM_DELAY_Init(); /* Initialize USART, TX: PB6 */ TM_USART_Init(USART1, TM_USART_PinsPack_2, 9600); TIM4_Configuration(); while (1) { /* Every 500ms */ if (TM_DELAY_Time() >= 500) { /* Reset time */ TM_DELAY_SetTime(0); if(TIM_GetFlagStatus(TIM4,TIM_FLAG_CC1)==SET) { TIM_ClearFlag(TIM4,TIM_FLAG_CC1); if(CaptureNumber == 0) { counter = TIM_GetCapture1(TIM4); //The first capture CaptureNumber = 1; } else if(CaptureNumber == 1) //Treatment of second capture { if(TIM_GetFlagStatus(TIM4,TIM_FLAG_Update) != SET)//Treatment of two capture no overflow occurs { Time = TIM_GetCapture1(TIM4); Time = Time - counter; } else { TIM_ClearFlag(TIM4,TIM_FLAG_Update); //The update event Time = 0xFFFF - counter + TIM_GetCapture1(TIM4)+1; //If the calculation mode update events } CaptureNumber = 0; if(Time!=0) { freq= 2000000/Time; //Calculation of frequency } freq = freq; //To avoid the freq variable is compiler optimization. } } sprintf(str, ''freq\n- %f\r\n'', freq); /* Show to usart */ TM_USART_Puts(USART1, str); } }}2015-05-08 03:37 AM
Hi clive1
is it possible i use ch4 for external clock input ? and if yes how ?Regards2015-05-08 10:20 AM
No, you need to refer to the Timer Block Diagram in the Reference Manual
You can use an TIMx_ETR pins, internal sources (ITRx from other timers), TI1FP1 (CH1 side), TI2FP2 (CH2 side), TI1F_EDYou could perhaps use an EXTI interrupt for low bandwidth applications2015-05-10 11:43 PM
Hi Clive1
Thank you very much2015-10-14 07:13 PM
Hi all,
I am a beginner in this arena. If I use TIM5 (32-bit) CH1(PA.0) of STML1 to count external pulses in 10ms period (10ms active count, 10ms interval, again 10ms active), How to configure interrupt routine? Please educate me in this regard.I've followed the earlier posts and started like this:#include ''stm32l1xx.h''#include ''misc.h''#include ''stm32l1xx.h''#include ''stm32l1xx_gpio.h''#include ''stm32l1xx_rcc.h''#include ''stm32l1xx_tim.h''# define sample 20 int count[sample];int i;int main(void){ GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; TIM_ICInitTypeDef TIM_ICInitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; /* TIM5 clock enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE); /* GPIOA clock enable */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); /* TIM5 channel 1 pin (PA.0) configuration */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_TIM5); /* TIM5 configuration: Input Capture mode */ TIM_TimeBaseStructure.TIM_Period = 0xF9FF; // To generate interrupt in .01s (Count 64000-1) TIM_TimeBaseStructure.TIM_Prescaler = 4; // 32MHz/(4+1) = 6.4MHz TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM5, & TIM_TimeBaseStructure); TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; 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(TIM5, &TIM_ICInitStructure); /* TIM enable counter */ TIM_Cmd(TIM5, ENABLE); /* Enable the TIM5 global Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* Enable the CC1 Interrupt Request */ TIM_ITConfig(TIM5, TIM_IT_CC1, ENABLE); while (1) { // How to read total ticks in 10ms window and put sleep for another 10ms ? count[i] = TIM5->CNT; i++; }}2015-10-14 10:00 PM
Honestly this seems off-topic, can we not do that.
The TIM5_IRQHandler() would have to read consecutive captures of CNT stored in TIM5->CCR1, and do a delta computation between the two, of ticks at the timebase frequency. Using a 0-63999 count is going to make the math unduly complicated. If you just go with the maximal mode (Period = 0xFFFFFFFF), deltaticks = b - a; Where deltaticks, a, b are all uint32_tIn some situations PWM Input mode might be more helpful for period/duty, a single interrupt, and the timebase is automatically reset.2015-10-25 08:36 PM
Sorry, I misunderstood my requirements. I need to count pulses for consecutive 10ms period. Can I use RTC auto-wakeup interrupt to store TIM5-> CNT value after 10ms, reset CNT and re-count after 10ms? In that case, do I still need to configure TIM5 time-base interrupt?
Also, to store in a SD card text file (using FATFS), how to design a storage format for comma separated count values. I request some guidelines or
an example link, if available
.2015-10-26 05:43 AM
Or to store in a .csv log file.