Continuing the STM8 Expedition

STM8S105 Discovery

One Pulse Mode (OPM)

One Pulse Mode (OPM) is an additional feature of STM8 timers. It is like a monostable multivibrator or a one-shot timer that can be used to generate a pulse of fixed width after a defined amount of delay. It has several uses like wake up command generator for other onboard devices/microcontrollers, trigger for sensors like DHT22, etc.

Hardware Connection

opm

Code Example

#include "STM8S.h"


void clock_setup(void);
void GPIO_setup(void);
void TIM1_setup(void);


void main(void)
{
       clock_setup();
       GPIO_setup();
       TIM1_setup();

       while(TRUE)
       {
       };
}


void clock_setup(void)
{
       CLK_DeInit();

       CLK_HSECmd(ENABLE);
       while(CLK_GetFlagStatus(CLK_FLAG_HSERDY) == FALSE);

       CLK_LSICmd(DISABLE);

       CLK_HSICmd(ENABLE);
       while(CLK_GetFlagStatus(CLK_FLAG_HSIRDY) == FALSE);

       CLK_ClockSwitchCmd(ENABLE);
       CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);
       CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);

       CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSE,
       DISABLE, CLK_CURRENTCLOCKSTATE_ENABLE);

       CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER1, ENABLE);
       CLK_PeripheralClockConfig(CLK_PERIPHERAL_SPI, DISABLE);
       CLK_PeripheralClockConfig(CLK_PERIPHERAL_I2C, DISABLE);
       CLK_PeripheralClockConfig(CLK_PERIPHERAL_ADC, DISABLE);
       CLK_PeripheralClockConfig(CLK_PERIPHERAL_AWU, DISABLE);
       CLK_PeripheralClockConfig(CLK_PERIPHERAL_UART2, DISABLE);
       CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER2, DISABLE);
       CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER3, DISABLE);
       CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER4, DISABLE);
}


void GPIO_setup(void)
{            
       GPIO_DeInit(GPIOC);
       GPIO_Init(GPIOC, GPIO_PIN_4, GPIO_MODE_OUT_PP_HIGH_FAST);
       GPIO_WriteHigh(GPIOC, GPIO_PIN_4);
       delay_ms(2000);
}


void TIM1_setup(void)
{
       TIM1_DeInit();

       TIM1_TimeBaseInit(160, TIM1_COUNTERMODE_UP, 10000, 1);

       TIM1_OC4Init(TIM1_OCMODE_PWM2,
                     TIM1_OUTPUTSTATE_ENABLE, 
                     6000,
                     TIM1_OCPOLARITY_HIGH, 
                     TIM1_OCIDLESTATE_RESET);

       TIM1_SelectOnePulseMode(TIM1_OPMODE_SINGLE);
       TIM1_CtrlPWMOutputs(ENABLE);
       TIM1_Cmd(ENABLE);
}

 

Explanation

Firstly, the peripheral and CPU clocks are set at max speed:

CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);
CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);
....  
CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER1, ENABLE);

TIM1 is setup is as simply as we would do for PWM generation. However, for one pulse mode (OPM) we must select one pulse mode.

void TIM1_setup(void)
{
       TIM1_DeInit();

       TIM1_TimeBaseInit(160, TIM1_COUNTERMODE_UP, 10000, 1);

       TIM1_OC4Init(TIM1_OCMODE_PWM2,
                     TIM1_OUTPUTSTATE_ENABLE, 
                     6000,
                     TIM1_OCPOLARITY_HIGH, 
                     TIM1_OCIDLESTATE_RESET);

       TIM1_SelectOnePulseMode(TIM1_OPMODE_SINGLE);
       TIM1_CtrlPWMOutputs(ENABLE);
       TIM1_Cmd(ENABLE);
}

At this point it is necessary to describe TIM1 PWM modes. There are two PWM mode – PWM mode 1 and PWM mode 2.

PWM Mode 1

In up-counting mode, the channel is active if the counter is less than CCR1 or else it is inactive.
The opposite is true in down-counting mode.

PWM Mode 2

The channel is inactive as long as the counter is less than CCR1 in up- counting mode.

For OPM example here, we need PWM mode 2.

In this example the pulse width time of the one pulse is about 0.25ms and has a delay of 0.375ms. The calculation is very simple. Since 16MHz clock is used, one cycle takes 62.5ns and so 10000 counts equal 0.625ms. Because we are using PWM mode 2, it will take more than 6000 counts or 0.375ms before the one pulse start. The pulse has a width of (10000 – 6000) = 4000 counts or 0.25ms and will end after this time.

Demo

OPM

opm

Related Posts

Leave a Reply

Your email address will not be published. Required fields are marked *