Starting STM8 Microcontrollers

STM8S003K3 Discovery

General Purpose Input Output (GPIO)

The very first “Hello World” project that we do with every new embedded device is a simple LED blinking program. Here we do the same. We will be basically testing both input and output function by making a variable flash rate blinking LED. Check the schematic of the Disco board. Check the pins with which the on-board LED and the push button are connected.

Disco Schematic

You can also use the STM8CubeMX in board selector mode for this too.

Shown below is the internal block diagram of GPIO pins:

Schematic

Because each I/O is independently configurable and have many options associated with it, its block looks complex at first sight. Check the various options every I/O possess:

Functionality

Shown below are the SPL functions associated with the GPIO module.

Functions

Observe the code below. This is the power of the ST’s SPL. The code is written with no traditional register access. Everything here has a meaningful nomenclature, just like regular naming/words of the reference manual/comments. There shouldn’t be any issue understanding the code. The code is almost Arduino-like. Here we are polling an input pin’s state to alter the blink rate of a LED.

Hardware Connection

CubeMX

Code Example

#include "STM8S.h"
 
 
void main (void)
{
   bool i = 0;
     
   GPIO_DeInit(GPIOB);
   GPIO_DeInit(GPIOD);
 
   GPIO_Init(GPIOB, GPIO_PIN_7, GPIO_MODE_IN_FL_NO_IT);
   GPIO_Init(GPIOD, GPIO_PIN_0, GPIO_MODE_OUT_PP_LOW_FAST);
   
   for(;;) 
   {
      if(GPIO_ReadInputPin(GPIOB, GPIO_PIN_7) == FALSE)
      {
         while(GPIO_ReadInputPin(GPIOB, GPIO_PIN_7) == FALSE);
         i ^= 1;
      }
                                
      switch(i)
      {
         case 0:
         {
             delay_ms(1000);
             break;
         }
         case 1:
         {
             delay_ms(200);
             break;
         }
      }
                                
      GPIO_WriteReverse(GPIOD, GPIO_PIN_0);
   }
}

 

Explanation

The following lines deinitialize the GPIOs we used. Every time you reconfigure or setup a hardware peripheral for the first time you must deinitialize it before using it. Though it is not mandatory, it will remove any chance of wrong/conflicting configurations.

 GPIO_DeInit(GPIOB);
 GPIO_DeInit(GPIOD);

After deinitialization, we are good to go for initializing or setting up the GPIOs. Inputs can be with or without internal pull-up resistors. Outputs can be either push-pull totem-pole or open drain types. Each pin can be individually configured and does not have any dependency on another. The following codes set GPIO PB7 as a floating input with no interrupt capability and GPIO PD0 as a fast push-pull output. PB7 is set up as a floating input rather than an internally pulled-up input because the button on the Disco board is already pulled up externally.

GPIO_Init(GPIOB, GPIO_PIN_7, GPIO_MODE_IN_FL_NO_IT);
GPIO_Init(GPIOD, GPIO_PIN_0, GPIO_MODE_OUT_PP_LOW_FAST);

The remaining part of the code in the main loop is just polling the button’s state and

for(;;) 
{
      if(GPIO_ReadInputPin(GPIOB, GPIO_PIN_7) == FALSE)
      {
         while(GPIO_ReadInputPin(GPIOB, GPIO_PIN_7) == FALSE);
         i ^= 1;
      }
                                
      switch(i)
      {
         case 0:
         {
             delay_ms(1000);
             break;
         }
         case 1:
         {
             delay_ms(200);
             break;
         }
      }
                                
      GPIO_WriteReverse(GPIOD, GPIO_PIN_0);
}

 

Demo

IMG_20170402_221924 IMG_20170402_221928

GPIO

Video link: https://www.youtube.com/watch?v=Rr1vpfoze4w 

 

Clock System (CLK)

The internal network of STM8 clock system allows us to tune up operating speeds of peripherals and CPU according to our needs. Software delays and power consumption depend on how the clock system is set.

In STM8 micros, there are three main clock sources – High Speed Internal Clock (HSI), High Speed External Clock (HSE) and Low Speed Internal Clock (LSI). The HSI has an oscillating frequency of 16MHz and is an internal RC oscillator with good precision – about 1% tolerant over a wide temperature range. HSE can be an external clock circuitry, temperature-compensated crystal oscillator (TCXO) or ordinary crystal resonator. It accepts all frequencies from 1MHz to 24MHz. Lastly, LSI clock is also an independent internal RC oscillator-based clock source that is mainly intended for idle or low power operating modes and the independent watchdog timer (IWDG). It has a fixed factory calibrated operating frequency of 128kHz and is not as accurate as HSI or HSE. There are also clock dividers/prescalers at various points to scale clocks as per requirement. Mainly two prescalers are what we need – the HSI prescaler and the CPU divider. Peripherals are directly feed by the main clock source. Additionally, there is a clock output pin (CCO) that outputs a given clock frequency. It can be used to clock another micro, generate clock for other devices like logic ICs. It can also be used as a free oscillator or perform clock performance tests. There’s fail-safe clock security that makes HSI backup of HSE. Should HSE fail, HSI takes over automatically. Check the internal block diagram below:

Internal Block Diagram

CubeMX1


Hardware Connection

CubeMX2

Code Example

The code example below demonstrates how to run the CPU at 2 MHz clock using HSI and extract 500 kHz clock output from CCO pin using CCO output selection. HSE is divided by 8, i.e. 16 MHz divided by 8 equals 2 MHz. This 2 MHz is the master clock source and further divided four times to get 500 kHz.

Note CCO pin is only available in some pins. For example, in STM8S003K3 this pin is either PD0 pin or PC4. We will need to override the default function of PD0 pin to favour for CCO output. To do so, we will need to change Alternate Function (AFR5) configuration bit during code upload.


#include "STM8S.h"
 
 
#define LED_pin                      GPIO_PIN_0
#define LED_port                     GPIOD
 
 
void setup(void);
void clock_setup(void);
void GPIO_setup(void);
 
 
void main(void)
{
   setup();
   GPIO_WriteLow(LED_port, LED_pin);
                                                               
   while(TRUE)
   {
   };
}
 
 
void setup(void)
{
  clock_setup();
  GPIO_setup();
}
 
 
void clock_setup(void)
{
  CLK_DeInit();
                                
  CLK_HSECmd(DISABLE);
  CLK_LSICmd(DISABLE);
  CLK_HSICmd(ENABLE);
  while(CLK_GetFlagStatus(CLK_FLAG_HSIRDY) == FALSE);
                                
  CLK_ClockSwitchCmd(ENABLE);
  CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV8);
  CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV4);
                                
  CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSI, 
  DISABLE, CLK_CURRENTCLOCKSTATE_ENABLE);
                                
  CLK_PeripheralClockConfig(CLK_PERIPHERAL_I2C, DISABLE);
  CLK_PeripheralClockConfig(CLK_PERIPHERAL_SPI, DISABLE);
  CLK_PeripheralClockConfig(CLK_PERIPHERAL_UART1, DISABLE);
  CLK_PeripheralClockConfig(CLK_PERIPHERAL_AWU, DISABLE);
  CLK_PeripheralClockConfig(CLK_PERIPHERAL_ADC, DISABLE);
  CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER1, DISABLE);
  CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER2, DISABLE);
  CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER4, DISABLE);
                                
  CLK_CCOConfig(CLK_OUTPUT_CPU);
  CLK_CCOCmd(ENABLE);
  while(CLK_GetFlagStatus(CLK_FLAG_CCORDY) == FALSE);
}

void GPIO_setup(void)
{                               
  GPIO_DeInit(LED_port);
  GPIO_Init(LED_port, LED_pin, GPIO_MODE_OUT_OD_HIZ_FAST);
}

 

Explanation

The full explanation of this code is given in the last segment of this article. The only thing I’ll describe here is this part:

CLK_CCOConfig(CLK_OUTPUT_CPU);
CLK_CCOCmd(ENABLE);
while(CLK_GetFlagStatus(CLK_FLAG_CCORDY) == FALSE);

These lines select the clock source that the CCO pin will output, enable the CCO module and wait for it to stabilize. Here I selected the CCO to output CPU clock.

 

Demo

cco

Video link: https://www.youtube.com/watch?v=IeLUc_s3jBE

Continue Reading ...

Related Posts

5 comments

Leave a Reply

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