cancel
Showing results for 
Search instead for 
Did you mean: 

PWM capture using Rising, falling EXTI

gladdy
Associate II

Hi all,

I am capturing 10 pwm pulses from proximity sensors by making the all pwm pins in rising falling interrupt mode.

PWM is captured by a timer at every 100us interrupt.

some times pulses are missing, I don't know why this is happening.

I am sharing code ISRs:

 
 
/*
 * @name        interrupts_Timer_50usCallback
 * @brief       Timer6 period elapsed Callback at every 50us
 * 				to capture the time of input pulses.
 * 				(50us will also be treated as resolution of input pulse capturing).
 * @param       none
 * @retvalue    none
 */
void interrupts_Timer_100usCallback(void){
	//====	For Pulse Input1	====
	if(pulseCaptureFlags.pulse1Present != 0){
		if(++pulse1_1ms_cntr > 17){
			pulse1_1ms_cntr = 0;
			if(pulseCaptureFlags.pulse1TimerSet == 0){
				if(++pulse1_Capture_Thrshld > inputCaptureTime[0]){
					pulse1_Capture_Thrshld = 2;
					pulseCaptureFlags.pulse1TimerSet = 1;
					pulseInput_1.counter++;
					pulseInput_1.timer = pulseInput_1.timer + inputCaptureTime[0];
				}
 
			}
			else{
				pulseInput_1.timer++;
			}
		}
	}
 
	//====	For Pulse Input2	====
	if(pulseCaptureFlags.pulse2Present != 0){
		if(++pulse2_1ms_cntr > 17){
			pulse2_1ms_cntr = 0;
			if(pulseCaptureFlags.pulse2TimerSet == 0){
				if(++pulse2_Capture_Thrshld > inputCaptureTime[1]){
					pulse2_Capture_Thrshld = 2;
					pulseCaptureFlags.pulse2TimerSet = 1;
					pulseInput_2.counter++;
					pulseInput_2.timer = pulseInput_2.timer + inputCaptureTime[1] - 2;
				}
 
			}
			else{
				pulseInput_2.timer++;
			}
		}
	}
 
	//====	For Pulse Input3	====
	if(pulseCaptureFlags.pulse3Present != 0){
		if(++pulse3_1ms_cntr > 17){
			pulse3_1ms_cntr = 0;
			if(pulseCaptureFlags.pulse3TimerSet == 0){
				if(++pulse3_Capture_Thrshld > inputCaptureTime[2]){
					pulse3_Capture_Thrshld = 1;
					pulseCaptureFlags.pulse3TimerSet = 1;
					pulseInput_3.counter++;
					pulseInput_3.timer = pulseInput_3.timer + inputCaptureTime[2] - 2;
				}
 
			}
			else{
				pulseInput_3.timer++;
			}
		}
	}
 
	//====	For Pulse Input4	====
	if(pulseCaptureFlags.pulse4Present != 0){
		if(++pulse4_1ms_cntr > 17){
			pulse4_1ms_cntr = 0;
			if(pulseCaptureFlags.pulse4TimerSet == 0){
				if(++pulse4_Capture_Thrshld > inputCaptureTime[3]){
					pulse4_Capture_Thrshld = 1;
					pulseCaptureFlags.pulse4TimerSet = 1;
					pulseInput_4.counter++;
					pulseInput_4.timer = pulseInput_4.timer + inputCaptureTime[3] - 2;
				}
 
			}
			else{
				pulseInput_4.timer++;
			}
		}
	}
 
	//====	For Pulse Input5	====
	if(pulseCaptureFlags.pulse5Present != 0){
		if(++pulse5_1ms_cntr > 17){
			pulse5_1ms_cntr = 0;
			if(pulseCaptureFlags.pulse5TimerSet == 0){
				if(++pulse5_Capture_Thrshld > inputCaptureTime[4]){
					pulse5_Capture_Thrshld = 1;
					pulseCaptureFlags.pulse5TimerSet = 1;
					pulseInput_5.counter++;
					pulseInput_5.timer = pulseInput_5.timer + inputCaptureTime[4] - 2;
				}
 
			}
			else{
				pulseInput_5.timer++;
			}
		}
	}
 
	//====	For Pulse Input6	====
	if(pulseCaptureFlags.pulse6Present != 0){
		if(++pulse6_1ms_cntr > 17){
			pulse6_1ms_cntr = 0;
			if(pulseCaptureFlags.pulse6TimerSet == 0){
				if(++pulse6_Capture_Thrshld > inputCaptureTime[5]){
					pulse6_Capture_Thrshld = 1;
					pulseCaptureFlags.pulse6TimerSet = 1;
					pulseInput_6.counter++;
					pulseInput_6.timer = pulseInput_6.timer + inputCaptureTime[5] - 2;
				}
 
			}
			else{
				pulseInput_6.timer++;
			}
		}
	}
 
	//====	For Pulse Input7	====
	if(pulseCaptureFlags.pulse7Present != 0){
		if(++pulse7_1ms_cntr > 17){
			pulse7_1ms_cntr = 0;
			if(pulseCaptureFlags.pulse7TimerSet == 0){
				if(++pulse7_Capture_Thrshld > inputCaptureTime[6]){
					pulse7_Capture_Thrshld = 1;
					pulseCaptureFlags.pulse7TimerSet = 1;
					pulseInput_7.counter++;
					pulseInput_7.timer = pulseInput_7.timer + inputCaptureTime[6] - 2;
				}
 
			}
			else{
				pulseInput_7.timer++;
			}
		}
	}
 
	//====	For Pulse Input8	====
	if(pulseCaptureFlags.pulse8Present != 0){
		if(++pulse8_1ms_cntr > 17){
			pulse8_1ms_cntr = 0;
			if(pulseCaptureFlags.pulse8TimerSet == 0){
				if(++pulse8_Capture_Thrshld > inputCaptureTime[7]){
					pulse8_Capture_Thrshld = 1;
					pulseCaptureFlags.pulse8TimerSet = 1;
					pulseInput_8.counter++;
					pulseInput_8.timer = pulseInput_8.timer + inputCaptureTime[7] - 2;
				}
 
			}
			else{
				pulseInput_8.timer++;
			}
		}
	}
 
	//====	For Pulse Input9	====
	if(pulseCaptureFlags.pulse9Present != 0){
		if(++pulse9_1ms_cntr > 17){
			pulse9_1ms_cntr = 0;
			if(pulseCaptureFlags.pulse9TimerSet == 0){
				if(++pulse9_Capture_Thrshld > inputCaptureTime[8]){
					pulse9_Capture_Thrshld = 1;
					pulseCaptureFlags.pulse9TimerSet = 1;
					pulseInput_9.counter++;
					pulseInput_9.timer = pulseInput_9.timer + inputCaptureTime[8] - 2;
				}
 
			}
			else{
				pulseInput_9.timer++;
			}
		}
	}
}
 
 
/*
 * @name        interrupts_FallingCallback
 * @brief       sets the flags that pulse is present when faling edge detected on a particular pin
 * @param       none
 * @retvalue    none
 */
void interrupts_FallingCallback(u32 PulsePin){
	switch(PulsePin){
	case PULSE_INPUT_1_Pin:
		pulseCaptureFlags.pulse1Present = 1;
		break;
 
	case PULSE_INPUT_2_Pin:
		pulseCaptureFlags.pulse2Present = 1;
		break;
 
	case PULSE_INPUT_3_Pin:
		pulseCaptureFlags.pulse3Present = 1;
		break;
 
	case PULSE_INPUT_4_Pin:
		pulseCaptureFlags.pulse4Present = 1;
		break;
 
	case PULSE_INPUT_5_Pin:
		pulseCaptureFlags.pulse5Present = 1;
		break;
 
	case PULSE_INPUT_6_Pin:
		pulseCaptureFlags.pulse6Present = 1;
		break;
 
	case PULSE_INPUT_7_Pin:
		pulseCaptureFlags.pulse7Present = 1;
		break;
 
	case PULSE_INPUT_8_Pin:
		pulseCaptureFlags.pulse8Present = 1;
		break;
 
	case PULSE_INPUT_9_Pin:
		pulseCaptureFlags.pulse9Present = 1;
		break;
 
	default:
		break;
	}
}
 
 
 
/*
 * @name        interrupts_RisingCallback
 * @brief       Resets the flags that pulse has gone when rising edge detected on a particular pin
 * @param       PulsePin: input device pins at which pulse is present
 * @retvalue    none
 */
void interrupts_RisingCallback(u32 PulsePin){
	switch(PulsePin){
	case PULSE_INPUT_1_Pin:
		pulseCaptureFlags.pulse1Present = 0;
		pulseCaptureFlags.pulse1TimerSet = 0;
		pulse1_1ms_cntr = 0;
		pulse1_Capture_Thrshld = 2;
		break;
 
	case PULSE_INPUT_2_Pin:
		pulseCaptureFlags.pulse2Present = 0;
		pulseCaptureFlags.pulse2TimerSet = 0;
		pulse2_1ms_cntr = 0;
		pulse2_Capture_Thrshld = 2;
		break;
 
	case PULSE_INPUT_3_Pin:
		pulseCaptureFlags.pulse3Present = 0;
		pulseCaptureFlags.pulse3TimerSet = 0;
		pulse3_1ms_cntr = 0;
		pulse3_Capture_Thrshld = 2;
		break;
 
	case PULSE_INPUT_4_Pin:
		pulseCaptureFlags.pulse4Present = 0;
		pulseCaptureFlags.pulse4TimerSet = 0;
		pulse4_1ms_cntr = 0;
		pulse4_Capture_Thrshld = 2;
		break;
 
	case PULSE_INPUT_5_Pin:
		pulseCaptureFlags.pulse5Present = 0;
		pulseCaptureFlags.pulse5TimerSet = 0;
		pulse5_1ms_cntr = 0;
		pulse5_Capture_Thrshld = 2;
		break;
 
	case PULSE_INPUT_6_Pin:
		pulseCaptureFlags.pulse6Present = 0;
		pulseCaptureFlags.pulse6TimerSet = 0;
		pulse6_1ms_cntr = 0;
		pulse6_Capture_Thrshld = 2;
		break;
 
	case PULSE_INPUT_7_Pin:
		pulseCaptureFlags.pulse7Present = 0;
		pulseCaptureFlags.pulse7TimerSet = 0;
		pulse7_1ms_cntr = 0;
		pulse7_Capture_Thrshld = 2;
		break;
 
	case PULSE_INPUT_8_Pin:
		pulseCaptureFlags.pulse8Present = 0;
		pulseCaptureFlags.pulse8TimerSet = 0;
		pulse8_1ms_cntr = 0;
		pulse8_Capture_Thrshld = 2;
		break;
 
	case PULSE_INPUT_9_Pin:
		pulseCaptureFlags.pulse9Present = 0;
		pulseCaptureFlags.pulse9TimerSet = 0;
		pulse9_1ms_cntr = 0;
		pulse9_Capture_Thrshld = 2;
		break;
 
/*	case PULSE_INPUT_10_Pin:
		pulseCaptureFlags.pulse10Present = 0;
		pulseCaptureFlags.pulse10TimerSet = 0;
		pulse10_1ms_cntr = 0;
		pulse10_Capture_Thrshld = 1;
		break;*/
 
	default:
		break;
	}
 
}
 
 

I have to measure both no. of pulses counts as well as how much time the pulse was high.

Please help me out.

Thanks.

1 ACCEPTED SOLUTION

Accepted Solutions

> the minimum pulse width is 100ms and max is 6 second.

Then forget completely about the EXTI.

Simply sample the *current* state of pins at the start of the timer interrupt, and process them in the exact same manner as you've processed the pulseCaptureFlags

struct (you'll need to add an "else" for the pin's state being low).

Measure the execution time of the ISR for the worst case; it has to be below the period (100us).

JW

View solution in original post

10 REPLIES 10

How fast are those pulses?

You hang this stuff on the back of some "library" such as Cube/HAL, I suppose?

Read the EXTI chapter as prerequisite and answer the questions.

JW

PS. Change your username to a normal nick.

gladdy
Associate II

Yes you are right, I am using HAL libraries generated through STM32Cube IDE.

There were two questions, and the first one is more important.

JW

the minimum pulse width is 100ms and max is 6 second.

STM32G071RB mcu used to process these tasks.

> the minimum pulse width is 100ms and max is 6 second.

Then forget completely about the EXTI.

Simply sample the *current* state of pins at the start of the timer interrupt, and process them in the exact same manner as you've processed the pulseCaptureFlags

struct (you'll need to add an "else" for the pin's state being low).

Measure the execution time of the ISR for the worst case; it has to be below the period (100us).

JW

yess, exactly what I was thinking and needed someone's opinion, that's what you gave me.

I have measured worst case that was 20us for timer when MCU is running @64MHz.

I am also going to increase the timer interrupt at 500us. There will be a resolution of 500us that is acceptable.

Thanks a lot😊

Gladdy

Hi waclawek.jan,

if I have to capture input PWM pulses from 10ms to 2000ms ON time.

Which method should I use EXTI, Polling of input pulses & Interrupt capture module?

I can change my hardware as well planning to do these tasks with cortex M4(STM32F4) series.

Please suggest me.

Piranha
Chief II

I would route those lines to pins 5-15 of a single port and write effective ISR, which sorts out state of those lines using XOR and CLZ (available on Cortex-M3 and higher) instructions.