Continuing the STM8 Expedition

STM8S105 Discovery

Auto Wakeup Mode (AWU)

Imagine that you have to design a data acquisition system like a solar-powered weather station that will log data periodically. You can guess that there is a limitation of available energy to keep up the system and continuous monitoring is unnecessary. Thus weather data is periodically obtained and the system has no other task rather than to sleep. In situations like this we have to rely on STM8’s low power mode with auto wakeup feature.

ATMega328P Weather Station (2)

The Auto Wakeup Unit (AWU) of STM8 microcontrollers is like an alarm clock. All we have to do is to set the time for wake up and put our device to sleep. Time ticks and the CPU wakes up to do assigned tasks once the time is over.

Hardware Connection

Hardware

Code Example

 

#include "STM8S.h"


void clock_setup(void);
void GPIO_setup(void);
void AWU_setup(void);


void main(void)
{
       unsigned char s = 0x00;

       clock_setup();
       GPIO_setup();
       AWU_setup();

       while(TRUE)
       {
              for(s = 0x00; s < 0x04; s++)
              {
                     GPIO_WriteLow(GPIOD, GPIO_PIN_0);
                     delay_ms(60);
                     GPIO_WriteHigh(GPIOD, GPIO_PIN_0);
                     delay_ms(60);
              }

              halt();                          
       };
}


void clock_setup(void)
{
       CLK_DeInit();

       CLK_HSECmd(DISABLE);

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

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

       CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSI,
       DISABLE, CLK_CURRENTCLOCKSTATE_ENABLE);

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


void GPIO_setup(void)
{            
       GPIO_DeInit(GPIOD);
       GPIO_Init(GPIOD, GPIO_PIN_0, GPIO_MODE_OUT_OD_HIZ_FAST);
}


void AWU_setup(void)
{
       AWU_IdleModeEnable();    
       AWU_DeInit();
       AWU_LSICalibrationConfig(128000);
       AWU_Init(AWU_TIMEBASE_2S);
       AWU_Cmd(ENABLE);
       enableInterrupts();
}

 

Explanation

To keep things simple, again the on-board LED of Discovery board is used.

The main clock settings are not that important as AWU usually uses LSI as clock source. However, the AWU peripheral clock must be enabled.

CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV8);
CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);

CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSI, DISABLE, CLK_CURRENTCLOCKSTATE_ENABLE);

CLK_PeripheralClockConfig(CLK_PERIPHERAL_AWU, ENABLE);

AWU setup is simple as shown below:

void AWU_setup(void)
{
       AWU_IdleModeEnable();    
       AWU_DeInit();
       AWU_LSICalibrationConfig(128000);
       AWU_Init(AWU_TIMEBASE_2S);
       AWU_Cmd(ENABLE);
       enableInterrupts();
}

First, we enable idle mode. Then the AWU peripheral is deinitialized. Optionally LSI can be calibrated but in most cases, this is not needed and can be avoided. Initializing the AWU requires only the wake-up time. This time value can be some of the prefixed time values only and it dictates the time for wake up after the CPU has gone sleeping. Lastly, we have to enable the AWU unit.

With these settings, we will see that the on-board LED will blink briefly and then remain turned off for about 2 seconds. Since the AWU is set for 2 seconds, the CPU wakes up after 2 seconds from halted state and the process repeats over and over again.

for(s = 0x00; s < 0x04; s++)
{
       GPIO_WriteLow(GPIOD, GPIO_PIN_0);
       delay_ms(60);
       GPIO_WriteHigh(GPIOD, GPIO_PIN_0);
       delay_ms(60);
}

halt();

 

Demo

AWU (1) AWU (2)

Related Posts

Leave a Reply

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