2023-03-21 03:49 AM
Hello,
I'm counting a 10MHz oscillator(with external clock mode 1) for 1 second using the stm32f0 processor's TIM1. I get about 10 000 000 pulses.
Then the system has a starting point and I start the 1s counting process here. The timer counts a maximum of 16 bits. I make 152 full rounds (update overflow) and stop and reset the Timer with the remaining 38680(152*65535+38680 = 10000000) with capture compare interrupt. However, the system is constantly shifting from the starting point (up to 70 microseconds). As a result of the tests I made with the logic analyzer, there is a problem where I reset the Timer. How do you think I can fix it and do you have any suggestions? I've been trying for a long time but couldn't solve it. Thanks everyone in advance.
2023-03-21 04:53 AM
Well, it is not a good idea to manage the overflow with an interrupt at such an input frequency. You may well be wasting time in the interrupt routine while the next clock is already coming in.
Better to couple two timers by chaining and have a 32bit timer?
A similar question for chaining has been discussed here before, there is also AN2592 which discusses this in section 1: Timer synchronization.
Does it answer your question?
Regards
/Peter
2023-03-21 05:16 AM
I have to use only TIM1
2023-03-21 05:19 AM
@Community member , @Community member ?
2023-03-21 05:25 AM
You set the TIM1 interrupt to fire every say, 1mS then inside the interrupt routine you have a uint32_t counter that you increment every time the interrupt fires. You don't need to reset anything.
Disregard my insanity, I read and replied to the post before a sufficient intake of coffee.
2023-03-21 06:47 AM
Not sure why I'm being tagged in here.
Devices with 32-bit TIM would be a better choice.
Perhaps use the prescaler here, so the count can register 10000, or 50000 counts, ie ARR = N-1
Prescaler has less visibility, but might be easier to reset or nudge the CNT register up/down a count if you're trying to adjust or sync things.
Generally I'd avoid stopping/starting as you're apt to miss a lot of counts at 10 MHz.
Not exactly clear what the goal is.
2023-03-21 07:31 AM
right. 10 Mhz will overflow 16bit counter in about 6ms , so if count uint32_t ++ in INT,
you get 32b + 16b -> 48bit count , always actual counts without any stop; for about 300 days...
or: what you want to do ? measure frequency?
2023-03-21 01:37 PM
Post a minimal but complete compilable program exhibiting the problem. Describe the expected behaviour and also how the observation departs from the expectation.
JW
2023-03-23 12:30 AM
void External_Clock_Config(){
TIM_ICInitTypeDef TIM_ICInitStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); //Clock enable
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = ExternalOSCpin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(ExternalOSCport, &GPIO_InitStructure);
GPIO_PinAFConfig(ExternalOSCport, GPIO_PinSource8, GPIO_AF_2); //alternate func
// GPIO_PinAFConfig(ExternalOSCport, GPIO_PinSource9, GPIO_AF_2); //alternate func
/* TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; //TIM_Channel_3
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_TRC;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICFilter = 0x0;
TIM_ICInit(ExternalOSCTimer, &TIM_ICInitStructure);
*/
NVIC_InitStructure.NVIC_IRQChannel = TIM1_BRK_UP_TRG_COM_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPriority = 0x00;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPriority = 0x01;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle ;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
//TIM_OCInitStructure.TIM_Pulse = TIM16to32_Handler.DelayOverFlow;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OC2Init(TIM1, &TIM_OCInitStructure);
TIM1->CCER |= TIM_CCER_CC2E | TIM_CCER_CC3E ;
TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Disable);
TIM1->CR2 &= 0XFF7F; //TIM1 Channel1
TIM1->PSC = 0; //set prescale value
TIM1->SMCR |= (uint16_t)(TIM_TS_TI1FP1 | TIM_SMCR_SMS ); // external mode 1
TIM1->CR1 &= (uint16_t)(~((uint16_t)TIM_CR1_CEN)); //disable timer counting
TIM1->CR1 &= (uint16_t)(~((uint16_t)TIM_CR1_ARPE));
TIM1->SR &= (uint16_t)~TIM_SR_CC2IF ;
TIM1->DIER |= TIM_IT_Update; //???
NVIC_EnableIRQ(TIM1_CC_IRQn);
}
void EXTI4_15_IRQHandler(){
if(EXTI_GetITStatus(EXTI_Line5) != RESET){
EXTI_ClearITPendingBit(EXTI_Line5);
TIM1->CR1 |= TIM_CR1_CEN ; //starrt with GPS based clock falling edge
}
}
void setvariable(){
ExactOSCCount = 10000000;
EOSCloopVal = ExactOSCCount / 0xFFFF ;
EOSCOverVal =ExactOSCCount % 0XFFFF;
UPEventCount = EOSCloopVal ;
}
void TIM1_BRK_UP_TRG_COM_IRQHandler(){ /*OverFlow interrupt **/
if(TIM_GetITStatus(TIM1,TIM_IT_Update) != RESET){
UPEventCount-- ;
TIM_ClearITPendingBit(TIM1 ,TIM_IT_Update) ;
if(UPEventCount == 0 ) {
TIM1->CCR3 = EOSCOverVal ;
TIM1->SR &= (uint16_t)~TIM_SR_CC3IF ;
TIM1->DIER |= TIM_IT_CC3;
}
}
}
void TIM1_CC_IRQHandler(){
if(TIM_GetITStatus(TIM1, TIM_IT_CC3) != RESET){
TIM1->CNT = 0;
TIM1->SR = 0;
UPEventCount = EOSCloopVal;
TIM1->DIER &= (uint16_t)~TIM_IT_CC3;
}
}
2023-03-23 12:42 AM
I try to count 1second 10 MHz high accuracy crystal oscilator with stm32f030cst6.Timer starts GPS based clock falling edge(starting paint of my system, Line 65). However, the system is constantly shifting from the starting point
Thats my calculation ;
152*65535+38680 = 10000000
channel 1 : GPS based clcok 1 second
channel 0 : My 1 second
After a while ;
What do you think :grinning_face_with_sweat: ? Thanks
@Community member