cancel
Showing results for 
Search instead for 
Did you mean: 

Configure stm32 timer as a counter of a RPM of a rolling gear

medraouf
Associate II

good morning

 

i was trying for sometime now to configure stm32 timer as a counter to count the pulses in order to count the RPM of a rolling gear and then show it on a lcd screen, and no matter what i do or change in the code or the timer configuration, the number of pulses is always stuck at 0. can anyone please help me with it? i really need it for my studies. (by the way, i am using a proteus simulation to test it).

5 REPLIES 5
AScha.3
Chief III

Hi,

how you get the pulses to the counter ?

You need select the ETRx as input to count external pulses. 

Or TIMxx input capture, to measure just one pulse-pulse timing and calculate speed then.

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

@AScha.3 i already tried that...

 

Hello @medraouf ,

As stated by @AScha.3 ETR is a serious candidate for your use case.


@medraouf wrote:

@AScha.3 i already tried that...

 


No one here can imagine what you did ..

You need to share your code to let community members to help you efficiently + your HW connections.

It could be an issue with your IO configuration or even with the timer itself ..

 

 

 

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.

Capture.PNGCapture1.PNGCapture2.PNGCapture3.PNG

#include "main.c"
#include "stm32f1xx.h"
#include "lcd8.h"

// Global variables to store pulse counts for each channel
volatile uint32_t channel1_count = 0;
volatile uint32_t channel2_count = 0;
volatile uint32_t channel3_count = 0;
volatile uint32_t channel4_count = 0;

// LCD configuration
#define LCD_PORT GPIOB
#define LCD_RS_PIN GPIO_PIN_0
#define LCD_EN_PIN GPIO_PIN_1
#define LCD_D0_PIN GPIO_PIN_2
#define LCD_D1_PIN GPIO_PIN_3
#define LCD_D2_PIN GPIO_PIN_4
#define LCD_D3_PIN GPIO_PIN_5
#define LCD_D4_PIN GPIO_PIN_6
#define LCD_D5_PIN GPIO_PIN_7
#define LCD_D6_PIN GPIO_PIN_8
#define LCD_D7_PIN GPIO_PIN_9

void TIM2_IRQHandler(void) {
    if (TIM2->SR & TIM_SR_CC1IF) {
        // Channel 1 capture event occurred
        channel1_count++;
    }
    if (TIM2->SR & TIM_SR_CC2IF) {
        // Channel 2 capture event occurred
        channel2_count++;
    }
    if (TIM2->SR & TIM_SR_CC3IF) {
        // Channel 3 capture event occurred
        channel3_count++;
    }
    if (TIM2->SR & TIM_SR_CC4IF) {
        // Channel 4 capture event occurred
        channel4_count++;
    }
    // Clear interrupt flags
    TIM2->SR = 0;
}
void TIM2_Init(void) {
    // Enable TIM2 clock
    RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;

    // Set TIM2 prescaler for 1 us resolution (assuming HCLK = 64MHz)
    TIM2->PSC = 64 - 1;

    // Configure TIM2 channels as input capture
    TIM2->CCMR1 |= (TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_0);
    TIM2->CCMR2 |= (TIM_CCMR2_CC3S_0 | TIM_CCMR2_CC4S_0);

    // Enable capture on both rising and falling edges
    TIM2->CCER |= (TIM_CCER_CC1P | TIM_CCER_CC1NP | TIM_CCER_CC2P | TIM_CCER_CC2NP |
                   TIM_CCER_CC3P | TIM_CCER_CC3NP); // Remove TIM_CCER_CC4P | TIM_CCER_CC4NP

    // Enable interrupts on capture events
    TIM2->DIER |= (TIM_DIER_CC1IE | TIM_DIER_CC2IE | TIM_DIER_CC3IE | TIM_DIER_CC4IE);

    // Enable TIM2 interrupts
    NVIC_EnableIRQ(TIM2_IRQn);

    // Enable TIM2
    TIM2->CR1 |= TIM_CR1_CEN;
}
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM2_Init(void);

int main(void)
{

  SystemClock_Config();


  MX_GPIO_Init();
  MX_TIM2_Init();

  lcdSetup(GPIOA, GPIO_PIN_8, GPIO_PIN_9, GPIO_PIN_0, GPIO_PIN_1, GPIO_PIN_2, GPIO_PIN_3, GPIO_PIN_4, GPIO_PIN_5, GPIO_PIN_6, GPIO_PIN_7);
     lcdInit();

     TIM2_Init();

     while (1) {
         // Display pulse counts on LCD
         lcdCommand(lcdClear); // Clear the LCD screen
         lcdSetCursor(0, 0);
         lcdString("Channel 1: ");
         lcdWriteInt("%d", channel1_count);
         lcdSetCursor(1, 0);
         lcdString("Channel 2: ");
         lcdWriteInt("%d", channel2_count);
         lcdSetCursor(2, 0);
         lcdString("Channel 3: ");
         lcdWriteInt("%d", channel3_count);
         lcdSetCursor(3, 0);
         lcdString("Channel 4: ");
         lcdWriteInt("%d", channel4_count);
         HAL_Delay(1000); // Update LCD every second
     }
 }

as you can see, the pulse number is stuck at 0 although i'm giving it a pulse signal from the the pulse generator. (note: i tried the same thing but without using the timer, only the interrupts of the stm32 and it worked, but there was a difference between the 4 channels, i guess because of the high frequency of the pulses, that's why i'm using the timer.)

Frankly, I'm not in favor using this kind of simulation. Sometimes it does not work but when you switch to a real HW it does.

I recommend you to use a real HW.

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.