STM32F429 input capture experiment: cubemx realizes the input capture of timer to the changing edge

This experiment was done more than a month ago, but I didn 't write a blog. Now I need to use the input capture change edge to start the infrared remote control experiment, but I forgot all about this part. So review the experiment again.

Put aside the book, input capture is to capture the time from the timer enable to trigger the rising edge or falling edge. Generally speaking, the timing of timer is realized by counter, and the hardware can detect the change edge of corresponding pin, and calculate the time by triggering.

t1 is the time from start to trigger to rising edge, t2 is the time from timer to trigger to falling edge. ARR is the full value of the counter. In this experiment, we set it as 0xffffffff, count up, so t1 is the time of counting CCRx1 timer cycles.

In this figure, we want to calculate the time from rising edge to falling edge, that is, the interval of t2-t1.

The maximum counter value is no more than 0xFFFFFF, but only one cycle can be recorded when the maximum value is reached, and then counting starts from 0.

cubemx configures TIM5CH1 as the input capture. In this experiment, we want to obtain the high-level pulse time of key UUP, so TIM5CH1 is selected according to the pin.

It should be noted that the frequency division coefficient is 90, which is convenient for calculating time, because the clock APB1 of timer is 90MHZ, and if the frequency division is 90, the clock of timer is 10MHZ. That is to say, one timer is triggered, which is 1s/10M=1us.

To calculate the time, interrupt is needed to count and enable interrupt.

The IO port of key up is configured with multiplexing function and pull-down.

After generating the code, we turn on the timer first

HAL_TIM_IC_Start_IT(&htim5,TIM_CHANNEL_1);       //Turn on capture channel 1 of TIM5, and turn on capture interrupt 
__HAL_TIM_ENABLE_IT(&htim5,TIM_IT_UPDATE);       //Enable update interrupt

After that, learn about two interrupt service functions. The first function is the input capture interrupt callback function, which will enter when there is a change edge.

//Timer input capture interrupt handling callback function, which will be called in Hal Tim irqhandler
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)//Capture when interrupt occurs

The second function is the interrupt callback function triggered by the timer counter counting for a cycle, that is, when the counter reaches 0xffffffff from 0, it enters the function. There are two situations to enter the function. One is that when the timer is on, it will enter the interrupt every time the counter value is full without triggering the change edge. The other is that when the rising edge is triggered, the high level holding time exceeds the cycle of the counter, so we need to calculate the high level by accumulating the number of times of entering the interrupt Total time of level pulse.

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
//Timer input capture interrupt handling callback function, which will be called in Hal Tim irqhandler
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)//Capture when interrupt occurs
{
	if(htim == &htim5)
	{
		if((TIM5CH1_CAPTURE_STA&0X80)==0)//A complete high level pulse has not been successfully captured. (after a high-level pulse is successfully captured, it is prevented that a change edge is captured before main processes the calculation time.)
		{
			if(TIM5CH1_CAPTURE_STA&0X40)		//If the change edge is triggered, and there has been a rising edge before, it must be a falling edge. Then it is considered that the high level duration has been fully captured 		
			{	  			
				TIM5CH1_CAPTURE_STA|=0X80;		//The mark successfully captures a high level pulse width
				TIM5CH1_CAPTURE_VAL=HAL_TIM_ReadCapturedValue(&htim5,TIM_CHANNEL_1);//Gets the current capture value
				TIM_RESET_CAPTUREPOLARITY(&htim5,TIM_CHANNEL_1);   //Be sure to clear the original settings first!!
				TIM_SET_CAPTUREPOLARITY(&htim5,TIM_CHANNEL_1,TIM_ICPOLARITY_RISING);//Configure TIM5 channel 1 rising edge capture
			}else  								//The first time to capture the rising edge
			{
				TIM5CH1_CAPTURE_STA=0;			//empty
				TIM5CH1_CAPTURE_VAL=0;
				TIM5CH1_CAPTURE_STA|=0X40;		//Mark triggered to rising edge
				__HAL_TIM_DISABLE(&htim5);      //Turn off timer 5 to reconfigure the timer to capture the falling edge. The next time the falling edge is captured, it will be a complete high-level pulse
				__HAL_TIM_SET_COUNTER(&htim5,0);
				TIM_RESET_CAPTUREPOLARITY(&htim5,TIM_CHANNEL_1);   //Be sure to clear the original settings first!!
				TIM_SET_CAPTUREPOLARITY(&htim5,TIM_CHANNEL_1,TIM_ICPOLARITY_FALLING);//Timer 5 channel 1 set to falling edge capture
				__HAL_TIM_ENABLE(&htim5);		//Enable timer 5
			}		    
		}	
	}	
	
}

This function will be entered at the first rising edge, then set to trigger the falling edge, and turn on the timer. It will enter again when the falling edge comes, and the mark has fully captured the high-level pulse.

 

//Update capture status
//[7] : 0, no successful capture; 1, one successful capture
//[6] : 0, the low level has not been captured; 1, the low level has been captured
//[5:0]: number of times of overflow after capturing low level (for 32-bit timer, 1us counter plus 1, overflow time: 4295 seconds)

uint8_t  	TIM5CH1_CAPTURE_STA=0;	//Input capture status		    				
uint32_t	TIM5CH1_CAPTURE_VAL;	//Enter the capture value (TIM2/TIM5 is 32-bit)

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim == &htim5)
	{
		if((TIM5CH1_CAPTURE_STA&0X80)==0)//Not captured yet
		{
			if(TIM5CH1_CAPTURE_STA&0X40)//It's high
			{
				if((TIM5CH1_CAPTURE_STA&0X3F)==0X3F)            //It has reached the maximum high level duration of software design, and it is considered that the complete high level duration has been captured
				{
					TIM5CH1_CAPTURE_STA|=0X80;		//The tag was captured successfully, but no falling edge was detected at this time
					TIM5CH1_CAPTURE_VAL=0XFFFFFFFF;
				}
				else 						//Generally, it will go to this position and let the number of cycles + 1
					TIM5CH1_CAPTURE_STA++;
			}	 
		}
	}
	
}

This function is used to count the number of times after the timer completes a cycle. We determine that the number of times will not be counted when the rising edge is triggered but not triggered.

 

	//TIM5 input the time when the capture implementation key "up" is pressed  
	if(TIM5CH1_CAPTURE_STA&0X80)        //Successfully captured a high level
	{
		temp=TIM5CH1_CAPTURE_STA&0X3F; 	//Bits 0 to 5 of tim5ch1 ﹣ capture ﹣ sta represent the number of high level continuous timer cycles
		temp*=0XFFFFFFFF;		 	    //The sum of overflow time. To calculate the time, multiply the number of cycles by the counter full value (0xffffffff)
		temp+=TIM5CH1_CAPTURE_VAL;      //To get the total high-level time, you need to add the count value less than one whole cycle on the above basis to get the total high-level duration
		printf("HIGH:%lld us\r\n",temp);//Print the total plateau time, because the TIM5 cycle is set to 1us (APB1 is 90MHZ, frequency division is 90, then it is 1/(90M/90)=0.000001s)
		TIM5CH1_CAPTURE_STA=0;          //Turn on next capture
	}

In the main() function, constantly query whether the timer has completed a complete high-level pulse acquisition. If it has completed, then we can calculate the duration of this high-level pulse, as shown above.

 

Conclusion: the input capture is indeed accurate, but the logic is somewhat complex, involving too many functions, which is not convenient to use. If you want to measure the high-level pulse time, you can judge whether it is high level through the pin input interrupt, then turn on the timer, and calculate the time when the interrupt is low level again.

 

Published 26 original articles, won praise and 2978 visitors
Private letter follow

Tags: less

Posted on Tue, 14 Jan 2020 03:33:20 -0800 by Roo