cancel
Showing results for 
Search instead for 
Did you mean: 

Stm32f4 counting pulses (How can I adjust the rising edge voltage ?)

MKell.2
Associate II

Hello all, 

At the moment I use TIM2 on the stm32f4 - Discovery Board to count pulses (rising edges). How can I adjust the thresholds for the rising edges ? I want to count 1 V pulses. At the moment it is just possible to count 2V pulses.

Here is the code of my timer function.

If there is another way to count pulses really fast (interrupts are to slow) with an adjusted rising edge, please let me know.

void timer_2_pulse_counter_gpioa1_Init(){
	RCC->AHB1ENR |= 0x01; // 1: IO port A clock enabled
	//RCC->AHB1ENR |= 0x10; // 1: IO port E clock enabled
 
	// APB1 peripheral reset register
	RCC->APB1ENR |= 0x01; // 1: enable TIM2
 
	// GPIO port mode register (GPIOx_MODER)
	GPIOA->MODER |= 0x00000008; // 10: Alternate function mode PA1 => AF mode
	GPIOA->AFR[0] |= 0x00000010; // 1000: Must refer to AF1 (alternate function for TIM1/ TIm2)
	GPIOA->PUPDR |= 0x00000008; // Sets pull down resistor for PA1
 
	// CCMR!: capture/compare mode register 1
	TIM2->CCMR1 |= 0x0100; // CC2 channel is configured as input, IC2 is mapped on TI2
 
	// SMCR: Slave Mode control register
	TIM2->SMCR |= 0x0007; // Bits[2:0]  111: External Clock Mode 1 - Rising edges of the selected trigger clock the counter.
	TIM2->SMCR |= 0x0060; // Bits[6:4] 110: selected Trigger: Filtered Timer Input 2 (TI2FP2)
 
	TIM2->ARR = 0xFFFF; // Set the timer reset on the highest possible value
 
	TIM2->CR1 |= 0x0001; //0001 Enable Timer
}

Many thanks in advance for your support!

9 REPLIES 9
Mikhail Z
Senior II

With counters you cannot adjust threshold, you would need to use analog comparators for that.

MKell.2
Associate II

Thanks for the fast reply. You saved me a lot of time. Am I going to be able to count 6k pulses per second with an analog cooperator and an integer increase?

6kHz shouldn't be a problem. What is 'integer increase'?

I think I need a counter in my software: if ( voltage on pin > threshold ) ---> counter += 1; Or is there another more efficient way ?

Right, at 6kHz you can just use interrupt which increases an integer every call.

If you would need much higher frequency, there are internal connections between comparators and timers.

There are no analog comparators in the STM32F407, though.

You can try to use the ADC.

JW

MKell.2
Associate II

Thanks for your answer. Is an ADC normally not too sensitive for counting single pulses. There are also sometimes 0.5 V peaks in my signal which should not be counted ?.

You would process the ADC in software, so you determine the threshold there. In pseudocode:

uint32_t count;
_Bool current_level;
#define ADC_UPGOING_LEVEL (ADC_MAXIMUM * 1100 / 3300) // 1.1V at 3.3V VREF(VDDA)
#define ADC_DOWNGOING_LEVEL (ADC_MAXIMUM * 1000 / 3300) // 1.0V
 
void ProcessNextAdcSample(uint32_t adcVal) {
  if (current_level == 0) {
    if (adcVal >= ADC_UPGOING_LEVEL) {
      current_level = 1;
    }
  } else {
    if (adcVal < ADC_DOWNGOING_LEVEL) {
      current_level = 0;
      count++;
    }
  }
}

JW

Thanks for your answer. I'm going to implement it on that way. Maybe it will to be fast enough. If not, I have to implement an external circuit to change the signal.