Maker Pro
Maker Pro

5 V pulse board stm32f407

Hi,

Do you mean you want to generate pulses on a Pin by using a timer?

There are example projects provided by ST for their discovery board. You can use an example which causes an interrupt to be fired on timer overflow.

That way you can toggle a GPIO in the interrupt service routine and you can obtain your pulses. As far as I know the STM32F407 operates at 3.3V, so you would need a transistor to convert that 3.3V pulse to 5V. Plenty of circuits available online.

Look for "transistors as a switch controlled by MCU".

Feel free to ask any questions you may have.
 
Yes! I want to generate pulses on a pin using a timer!

I got the problem of the 5V solved configuring de GPIO in Open Drain and with an external resistor.

Actually what i want to configure with the timer is that the board make, for example, 10 pulses on a pin and then stop. How do I have to configure the timer to do so? Using the Counter Mode Down maybe? And how should the main look like?

Thank you very much for responses
 
What you can do is configure the timer in interrupt mode and have it toggle a pin.

To control the pulses, you could use a variable to keep track of the pulses. Increment the variable on each pulse; you can allow the timer to toggle the pin as long as the pulseCount is less than 10 (as illustrated below). If you need another 10 pulses, simply reset the pulseCount variable to 0.

The interrupts will still be fired but nothing will take place, you can make the code more efficient by disabling the timer and re-enabling it when you need another set of pulses.

Be sure to clear the timer count when you need another 10 pulses, that will ensure you get the exact time period you have set even for the first toggle.

This is what the ISR would look like for Timer 2.

Code:
void TIM2_IRQHandler(void)
{
   if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
   {
    TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
    if(pulseCount++ < 10)
    {
       GPIO_ToggleBits(GPIOD, GPIO_Pin_12);
    }
   }
}

In the while(1) loop in main, you can clear pulseCount to 0, and the timer will generate 10 pulses and stop.

Be sure to initialize the variable "pulseCount" as volatile, since it is being shared between an ISR and other functions. It should be initialized to 0 if you want the pulses on start-up.

Hope this helps.

P.S. Happy belated birthday :)
 
Thank you very very much!! That was very helpful!!
I just began programming with microcontrollers and i'm a bit lost. I wrote all what you said but I don't know what to call in the while(1) in addition to clearing the pulseCount to 0. I show you my entire code:

Code:
#include <stm32f4xx.h>
#include <stm32f4xx_gpio.h>
#include <stm32f4xx_tim.h>
#include <stm32f4xx_rcc.h>
GPIO_InitTypeDef  GPIO_InitStructure;

void InitializeGPIO()
{
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
        GPIO_Init(GPIOD, &GPIO_InitStructure);
}

TIM_TimeBaseInitTypeDef timerInitStructure;

void InitializeTimer()
{
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
    timerInitStructure.TIM_Prescaler = 20;
    timerInitStructure.TIM_CounterMode = TIM_CounterMode_Down;
    timerInitStructure.TIM_Period = 40;
    timerInitStructure.TIM_ClockDivision = 1;
    timerInitStructure.TIM_RepetitionCounter = 0;
    TIM_TimeBaseInit(TIM2, &timerInitStructure);
    TIM_Cmd(TIM2, ENABLE);
}
volatile int pulseCount;
void TIM2_IRQHandler(void)
{
   if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
   {
    TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
    if(pulseCount++ < 10)
    {
       GPIO_ToggleBits(GPIOD, GPIO_Pin_0);
    }
   }
}
int main()
{
    InitializeGPIO();
    InitializeTimer();


    while(1)
    {
        pulseCount=0;


    }
}


Hope you can help me again. Thank you very much.
 
So is the STM32F4 your first micro-controller? That's very neat!. It's a very very powerful MCU. A bit difficult to grasp if you are migrating from 8-bit MCUs. But good job!

What exactly are the errors that you are facing?
I've noticed the following:
1. You initialized Pin D12 for GPIO but are toggling pin D0

"GPIO_ToggleBits(GPIOD, GPIO_Pin_0);"

Change that to pin12

2. Also you seem to have initialized the timer, but not the interrupt. You need to tell the MCU to call the timer interrupt and that is done by a few lines of code.
http://visualgdb.com/tutorials/arm/stm32/timers/

That tutorial will give you all the information you need (and more).

3. If you keep clearing pulseCount to 0 in while(1), you will get continuous pulses. The MCU will generate a continuous stream of pulses and will not stop after 10.

Hope it helps.
 
Hi again Frenoy! Thank you for reply. I looked for more info and I saw I could make that pulse only configurating the "hardware" of the board. I modified the following example:

Code:
#include "stm32f4xx.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_tim.h"

void TM_LEDS_Init(void) {
    GPIO_InitTypeDef GPIO_InitStruct;

    /* Clock for GPIOA */
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

    */
    /* Alternating functions for pins */
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_TIM13);

    /* Set pins */
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_OD;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_Init(GPIOA, &GPIO_InitStruct);
}

void TM_TIMER_Init(void) {
    TIM_TimeBaseInitTypeDef TIM_BaseStruct;

    /* Enable clock for TIM13 */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM13, ENABLE);

/*
    Set timer prescaler
    Timer count frequency is set with

    timer_tick_frequency = Timer_default_frequency / (prescaller_set + 1)

    In our case, we want a max frequency for timer, so we set prescaller to 0
    And our timer will have tick frequency

    timer_tick_frequency = 84000000 / (0 + 1) = 84000000
*/
    TIM_BaseStruct.TIM_Prescaler = 0; 
    /* Count up */
    TIM_BaseStruct.TIM_CounterMode = TIM_CounterMode_Up;
/*
    Set timer period when it have reset
    First you have to know max value for timer
    In our case it is 16bit = 65535
    To get your frequency for PWM, equation is simple

    PWM_frequency = timer_tick_frequency / (TIM_Period + 1)

    If you know your PWM frequency you want to have timer period set correct

    TIM_Period = timer_tick_frequency / PWM_frequency - 1

    In our case, for 40Khz PWM_frequency, set Period to

    TIM_Period = 84000000 / 40000 - 1 = 2099

    If you get TIM_Period larger than max timer value (in our case 65535),
    you have to choose larger prescaler and slow down timer tick frequency
*/
    TIM_BaseStruct.TIM_Period = 2099; /* 10kHz PWM */
    TIM_BaseStruct.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_BaseStruct.TIM_RepetitionCounter = 0;
    /* Initialize TIM13 */
    TIM_TimeBaseInit(TIM13, &TIM_BaseStruct);
    /* Start count on TIM13 */
    TIM_Cmd(TIM13, ENABLE);
}

void TM_PWM_Init(void) {
    TIM_OCInitTypeDef TIM_OCStruct;

    /* Common settings */

    /* PWM mode 2 = Clear on compare match */
    /* PWM mode 1 = Set on compare match */
    TIM_OCStruct.TIM_OCMode = TIM_OCMode_PWM2;
    TIM_OCStruct.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCStruct.TIM_OCPolarity = TIM_OCPolarity_Low;

/*
    To get proper duty cycle, you have simple equation

    pulse_length = ((TIM_Period + 1) * DutyCycle) / 100 - 1

    where DutyCycle is in percent, between 0 and 100%

    50% duty cycle:     pulse_length = ((2099 + 1) * 50) / 100 - 1 = 1049


    Remember: if pulse_length is larger than TIM_Period, you will have output HIGH all the time
*/
    TIM_OCStruct.TIM_Pulse = 1049; /* 50% duty cycle */
    TIM_OC1Init(TIM13, &TIM_OCStruct);
    TIM_OC1PreloadConfig(TIM13, TIM_OCPreload_Enable);
}

int main(void) {
    /* Initialize system */
    SystemInit();
    /* Init leds */
    TM_LEDS_Init();
    /* Init timer */
    TM_TIMER_Init();
    /* Init PWM */
    TM_PWM_Init();

    while (1) {

    }
}

This program should make a 5V pulse with 40kHz frequency. I tried that with an osciloscope and the results are pulse of 4V and frequency of 12,82 kHz... What is wrong?

Thank you
 
Top