cancel
Showing results for 
Search instead for 
Did you mean: 

Counting 10000000 with 16 bit TIMER

hazall
Associate III

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.

12 REPLIES 12
Peter BENSCH
ST Employee

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

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

I have to use only TIM1

hazall
Associate III

@Community member​ , @Community member​  ?

MHank.1
Associate III

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.

PartsBin - An Electronic Parts Organizer for Windows

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.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
AScha.3
Chief II

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?

If you feel a post has answered your question, please click "Accept as Solution".

Post a minimal but complete compilable program exhibiting the problem. Describe the expected behaviour and also how the observation departs from the expectation.

JW

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;
				 
			 
							}
 
	}
 
 
 

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

0693W00000aJYGoQAO.png 

After a while ;

0693W00000aJYHIQA4.png 

What do you think �� ? Thanks

@Community member​