cancel
Showing results for 
Search instead for 
Did you mean: 

Nucleos and STBC02 (Load Switches)

octavian
Associate
Posted on October 20, 2015 at 05:13

Hi,

I am new to this forum, new to ST world.

Where I should start to look into programming

1 wire GPIO, generating bursts with custom

widths 100 .. 300 micro-seconds for STBC02 chip.

For example to turn one of the power switched

ON/OFF I have to buzz a pin:

(1 is 100 us, start/stop bit is 300us)

0690X00000605ahQAA.png

OFF:  ..00000111010111000000000..

1. Should I  go with PWM, brute GPIO pull/up

down or timers ?

Thank you. 

2 REPLIES 2
stm322399
Senior
Posted on October 20, 2015 at 10:08

Marius,

you can use both methods, they all are valid. To help you to take a decision you need to consider other requirements of your project: are there others functions to run into the MCU ? simultaneously ? are you in a hurry ? do you want to simply make it working, or do you want to implement an elegant solution ?

Well. Go with GPIO, it is fast, easy to code and debug. The timing of waveforms will probably not be perfect, but the end device might already manage large margin, and all should work anyway.

Or, go with timers. This should increase the difficulty (starting condition of timer outputs are sometime not easy to manage, timer documentation is well known to be unfriendly ) and the precision of timings as well.

Do not forget an alternative architecture: a timer triggers a DMA to update regularly GPIO output register. Note that this does not work when GPIO is located in (what ST call) IOPORT, which is the case for STM32L0.

octavian
Associate
Posted on October 23, 2015 at 22:34

Hi,

Thank you. I went with timers and looks pretty good.

For whom might be interested.

Prerequisites:

 Board: NUCLEO

STM32F411

compatible

 SDK: STM32Cube_FW_F4_V1.5.0

static  int     Toggles;

static  int     Startseq;

static TIM_HandleTypeDef    TimHandle;

void  Turn_SW1_OA(BOOL on)

{

    Toggles    = 4 + (on * 2);

    Startseq   = 3;

    tim_work();

}

// 10 Khz clock

void     tim_work(void)

{

    uint32_t    sysclock = SystemCoreClock;

    uint32_t    uwPrescalerValue = (uint32_t)

                                         ((SystemCoreClock /2) / 10000) - 1; // 10 Khz

    /// test 1 Hz with a LED

    Set_gpio(FALSE); // should be 0, but anyway

#ifdef TIMER_LED_TEST_1HZ

    uwPrescalerValue = (uint32_t) ((SystemCoreClock /2) / 10) - 1;

    HAL_Delay(3000);  //stop to see the LED

#endif

    __TIM4_CLK_ENABLE();

    /// 10 Khz 100us clock period = T_SYS_CLOCK/(prescaler+1)*(period+1)

    TimHandle.Instance = TIM4;

    TimHandle.Init.Period = 10000 - 1;

    TimHandle.Init.Prescaler = uwPrescalerValue;

    TimHandle.Init.ClockDivision = 0;

    TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;

    if(HAL_TIM_Base_Init(&TimHandle) != HAL_OK)

    {

        printf(''Err HAL_TIM_Base_Init\r\n'');

        return;

    }

    if(HAL_TIM_Base_Start_IT(&TimHandle) != HAL_OK)

    {

        HAL_TIM_Base_DeInit(&TimHandle);

        printf(''Err HAL_TIM_Base_Init\r\n'');

        return;

    }

    HAL_NVIC_SetPriority(TIM4_IRQn, 0, 1);

    HAL_NVIC_EnableIRQ(TIM4_IRQn);

    while(_toggles>=0)

    {

           HAL_Delay(1);

    };

#ifdef TIMER_LED_TEST_1HZ

    HAL_Delay(3000);  //stop see the LED

#endif

    HAL_Delay(1);          //more than 500us, stop LEVEL

    Set_gpio(FALSE);    // end STOP sequence started in IRQ last toggle

    HAL_NVIC_DisableIRQ(TIM4_IRQn);

    HAL_TIM_Base_Stop_IT(&TimHandle);

    HAL_TIM_Base_DeInit(&TimHandle);

    __TIM4_CLK_DISABLE();

}

void TIM4_IRQHandler(void)

{

    __HAL_TIM_CLEAR_FLAG(&TimHandle, TIM_FLAG_UPDATE);

    if(_startseq-->0)

    {

        Set_gpio(1);

        return;

    }

    if(--_toggles>0)

    {

        Toggle_gpio();

    }

    else

    {

        Set_gpio(1);    // put it up for STOP, (main will put it down)

    }

}