STM8 – Embedded Lab http://embedded-lab.com/blog Embedded Systems tutorials, projects, and more ... Wed, 25 Nov 2020 03:49:55 +0000 en-US hourly 1 https://wordpress.org/?v=5.1.8 STM8 Microcontrollers – the Final Chapters http://embedded-lab.com/blog/stm8-microcontrollers-final-chapters/ http://embedded-lab.com/blog/stm8-microcontrollers-final-chapters/#comments Sun, 14 Jan 2018 04:54:28 +0000 http://embedded-lab.com/blog/?p=14060 This post is the sequel of the posts on STM8 microcontrollers here and here.

Hardware

Software I2C – DS1307

Software-based I2C is not a big requirement in case of STM8s because STM8 chips have hardware I2C blocks. However, for some reason if we are unable to use hardware I2C blocks, we can implement software-based I2C by bit-banging ordinary GPIOs. I2C protocol is itself slow compared to SPI and other protocols and so implementing software-based I2C will not significantly affect communication speed and overall throughput in most applications. However, extra coding is required and this in turn adds some coding and resource overheads.

Hardware Connection

sw_i2c

Code Example

SW_I2C.h

#include "STM8S.h"


#define SW_I2C_port              GPIOD

#define SDA_pin                  GPIO_PIN_6
#define SCL_pin                  GPIO_PIN_7

#define SW_I2C_OUT()             do{GPIO_DeInit(SW_I2C_port); GPIO_Init(SW_I2C_port, SDA_pin, GPIO_MODE_OUT_PP_LOW_FAST); GPIO_Init(SW_I2C_port, SCL_pin, GPIO_MODE_OUT_PP_LOW_FAST);}while(0)

#define SW_I2C_IN()              do{GPIO_DeInit(SW_I2C_port); GPIO_Init(SW_I2C_port, SDA_pin, GPIO_MODE_IN_FL_NO_IT); GPIO_Init(SW_I2C_port, SCL_pin, GPIO_MODE_OUT_PP_LOW_FAST);}while(0)

#define SDA_HIGH()               GPIO_WriteHigh(SW_I2C_port, SDA_pin)
#define SDA_LOW()                GPIO_WriteLow(SW_I2C_port, SDA_pin)
#define SCL_HIGH()               GPIO_WriteHigh(SW_I2C_port, SCL_pin)
#define SCL_LOW()                GPIO_WriteLow(SW_I2C_port, SCL_pin)

#define SDA_IN()                 GPIO_ReadInputPin(SW_I2C_port, SDA_pin)

#define I2C_ACK                  0xFF
#define I2C_NACK                 0x00

#define I2C_timeout              1000


void SW_I2C_init(void);
void SW_I2C_start(void);
void SW_I2C_stop(void);
unsigned char SW_I2C_read(unsigned char ack);
void SW_I2C_write(unsigned char value);
void SW_I2C_ACK_NACK(unsigned char mode);
unsigned char SW_I2C_wait_ACK(void);

SW_I2C.c

#include "SW_I2C.h"


void SW_I2C_init(void)
{
    SW_I2C_OUT();
    delay_ms(10);
    SDA_HIGH();
    SCL_HIGH();
}


void SW_I2C_start(void)
{
    SW_I2C_OUT();
    SDA_HIGH();
    SCL_HIGH();
    delay_us(40);
    SDA_LOW();
    delay_us(40);
    SCL_LOW();
}


void SW_I2C_stop(void)
{
    SW_I2C_OUT();
    SDA_LOW();
    SCL_LOW();
    delay_us(40);
    SDA_HIGH();
    SCL_HIGH();
    delay_us(40);
}


unsigned char SW_I2C_read(unsigned char ack)
{
    unsigned char i = 0x08;
    unsigned char j = 0x00;

    SW_I2C_IN();

    while(i > 0x00)
    {
        SCL_LOW();
        delay_us(20);
        SCL_HIGH();
        delay_us(20);
        j <<= 1;

        if(SDA_IN() != 0x00)
        {
            j++;
        }

        delay_us(10);
        i--;
    };

    switch(ack)
    {
        case I2C_ACK:
        {
            SW_I2C_ACK_NACK(I2C_ACK);;
            break;
        }
        default:
        {
            SW_I2C_ACK_NACK(I2C_NACK);;
            break;
        }
    }

    return j;
}


void SW_I2C_write(unsigned char value)
{
    unsigned char i = 0x08;

    SW_I2C_OUT();
    SCL_LOW();

    while(i > 0x00)
    {

        if(((value & 0x80) >> 0x07) != 0x00)
        {
            SDA_HIGH();
        }
        else
        {
            SDA_LOW();
        }


        value <<= 1;
        delay_us(20);
        SCL_HIGH();
        delay_us(20);
        SCL_LOW();
        delay_us(20);
        i--;
    };
}


void SW_I2C_ACK_NACK(unsigned char mode)
{
    SCL_LOW();
    SW_I2C_OUT();

    switch(mode)
    {
        case I2C_ACK:
        {
            SDA_LOW();
            break;
        }
        default:
        {
            SDA_HIGH();
            break;
        }
    }

    delay_us(20);
    SCL_HIGH();
    delay_us(20);
    SCL_LOW();
}


unsigned char SW_I2C_wait_ACK(void)
{
    signed int timeout = 0x0000;

    SW_I2C_IN();

    SDA_HIGH();
    delay_us(10);
    SCL_HIGH();
    delay_us(10);

    while(SDA_IN() != 0x00)
    {
        timeout++;

        if(timeout > I2C_timeout)
        {
            SW_I2C_stop();
            return 1;
        }
    };

    SCL_LOW();

    return 0x00;
}

DS1307.h

#include "SW_I2C.h"


#define sec_reg                0x00
#define min_reg                0x01
#define hr_reg                 0x02
#define day_reg                0x03
#define date_reg               0x04
#define month_reg              0x05
#define year_reg               0x06
#define control_reg            0x07

#define DS1307_addr            0xD0
#define DS1307_WR              DS1307_addr
#define DS1307_RD              0xD1


void DS1307_init(void);
unsigned char DS1307_read(unsigned char address);
void DS1307_write(unsigned char address, unsigned char value);
unsigned char bcd_to_decimal(unsigned char value);
unsigned char decimal_to_bcd(unsigned char value);
void get_time(void);
void set_time(void);

DS1307.c

#include "DS1307.h"


extern struct
{
   unsigned char s;
   unsigned char m;
   unsigned char h;
   unsigned char dy;
   unsigned char dt;
   unsigned char mt;
   unsigned char yr;
}time;


void DS1307_init(void)
{
    SW_I2C_init();
    DS1307_write(control_reg, 0x00);
}


unsigned char DS1307_read(unsigned char address)
{
    unsigned char value = 0x00;

    SW_I2C_start();
    SW_I2C_write(DS1307_WR);
    SW_I2C_write(address);

    SW_I2C_start();
    SW_I2C_write(DS1307_RD);
    value = SW_I2C_read(I2C_NACK);
    SW_I2C_stop();

    return value;
}


void DS1307_write(unsigned char address, unsigned char value)
{
    SW_I2C_start();
    SW_I2C_write(DS1307_WR);
    SW_I2C_write(address);
    SW_I2C_write(value);
    SW_I2C_stop();
}


unsigned char bcd_to_decimal(unsigned char value)
{
    return ((value & 0x0F) + (((value & 0xF0) >> 0x04) * 0x0A));
}


unsigned char decimal_to_bcd(unsigned char value)
{
    return (((value / 0x0A) << 0x04) & 0xF0) | ((value % 0x0A) & 0x0F);
}


void get_time(void)
{
       time.s = DS1307_read(sec_reg);
       time.s = bcd_to_decimal(time.s);

       time.m = DS1307_read(min_reg);
       time.m = bcd_to_decimal(time.m);

       time.h = DS1307_read(hr_reg);
       time.h = bcd_to_decimal(time.h);

       time.dy = DS1307_read(day_reg);
       time.dy = bcd_to_decimal(time.dy);

       time.dt = DS1307_read(date_reg);
       time.dt = bcd_to_decimal(time.dt);

       time.mt = DS1307_read(month_reg);
       time.mt = bcd_to_decimal(time.mt);

       time.yr = DS1307_read(year_reg);
       time.yr = bcd_to_decimal(time.yr);
}


void set_time(void)
{
       time.s = decimal_to_bcd(time.s);
       DS1307_write(sec_reg, time.s);

       time.m = decimal_to_bcd(time.m);
       DS1307_write(min_reg, time.m);

       time.h = decimal_to_bcd(time.h);
       DS1307_write(hr_reg, time.h);

       time.dy = decimal_to_bcd(time.dy);
       DS1307_write(day_reg, time.dy);

       time.dt = decimal_to_bcd(time.dt);
       DS1307_write(date_reg, time.dt);

       time.mt = decimal_to_bcd(time.mt);
       DS1307_write(month_reg, time.mt);

       time.yr = decimal_to_bcd(time.yr);
       DS1307_write(year_reg, time.yr);
}

main.c

#include "STM8S.h"
#include "lcd.h"
#include "SW_I2C.h"
#include "DS1307.h"


#define Button_port      GPIOB
#define Button_pin         GPIO_PIN_7


struct
{
   unsigned char s;
   unsigned char m;
   unsigned char h;
   unsigned char dy;
   unsigned char dt;
   unsigned char mt;
   unsigned char yr;
}time;

bool set = FALSE;

unsigned char menu = 0;
unsigned char data_value;


void clock_setup(void);
void GPIO_setup(void);
void show_value(unsigned char x_pos, unsigned char y_pos, unsigned char value);
void display_time(void);
void setup_time(void);
unsigned char adjust(unsigned char x_pos, unsigned char y_pos, signed char value_max, signed char value_min, signed char value);


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

       DS1307_init();

       LCD_init();
       LCD_clear_home();

       LCD_goto(0, 0);
       LCD_putstr("STM8 SW-I2C Test");

    while(1)
    {
       if((GPIO_ReadInputPin(Button_port, Button_pin) == FALSE) && (set == FALSE))
       {
              delay_ms(1000);
              if(GPIO_ReadInputPin(Button_port, Button_pin) == FALSE)
              {
                     while(GPIO_ReadInputPin(Button_port, Button_pin) == FALSE);
                     delay_ms(1000);

                     menu = 0;
                     set = TRUE;
              }
       }

       if(set)
       {
              setup_time();
       }
       else
       {
              get_time();
              display_time();
       }
    };
}


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_HSIDIV2);
       CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);

       CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSI,
       DISABLE, CLK_CURRENTCLOCKSTATE_ENABLE);

       CLK_PeripheralClockConfig(CLK_PERIPHERAL_SPI, ENABLE);
       CLK_PeripheralClockConfig(CLK_PERIPHERAL_I2C, DISABLE);
       CLK_PeripheralClockConfig(CLK_PERIPHERAL_ADC, DISABLE);
       CLK_PeripheralClockConfig(CLK_PERIPHERAL_AWU, 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(GPIOB);
       GPIO_Init(Button_port, Button_pin, GPIO_MODE_IN_PU_NO_IT);
}


void show_value(unsigned char x_pos, unsigned char y_pos, unsigned char value)
{
   char ch[0x03] = {0x20, 0x20, '\0'};

   ch[0] = (((value / 10) % 10) + 0x30);
   ch[1] = ((value % 10) + 0x30);

   LCD_goto(x_pos, y_pos);
   LCD_putstr(ch);
}


void display_time(void)
{     
       show_value(4, 1, time.h);
       show_value(7, 1, time.m);
       show_value(10, 1, time.s);

       LCD_goto(6, 1);
       LCD_putchar(':');
       LCD_goto(9, 1);
       LCD_putchar(':');  
       delay_ms(100);
}


void setup_time(void)
{
       switch(menu)
       {
              case 0:
              {
                     time.h = adjust(4, 1, 23, 0, time.h);
                     break;
              }            
              case 1:
              {
                     time.m = adjust(7, 1, 59, 0, time.m);
                     break;
              }
              case 2:
              {
                     time.s = adjust(10, 1, 59, 0, time.s);
                     break;
              }
       }
}


unsigned char adjust(unsigned char x_pos, unsigned char y_pos, signed char value_max, signed char value_min, signed char value)
{
       if(GPIO_ReadInputPin(Button_port, Button_pin) == FALSE)
       {
              delay_ms(900);

              if(GPIO_ReadInputPin(Button_port, Button_pin) == FALSE)
              {
                     while(GPIO_ReadInputPin(Button_port, Button_pin) == FALSE);
                     menu++;

                     if(menu >= 3)
                     {
                           LCD_goto(3, 1);
                           LCD_putchar(' ');
                           LCD_goto(12, 1);
                           LCD_putchar(' ');  
                           set_time();
                           set = FALSE;

                           return;
                     }
              }
       }

       else
       {
              value++;

              if(value > value_max)
              {
                  value = value_min;
              }
       }

       LCD_goto(3, 1);
       LCD_putchar('<');
       LCD_goto(12, 1);
       LCD_putchar('>');  

       LCD_goto(x_pos, y_pos);
       LCD_putstr("  ");
       delay_ms(90);

       show_value(x_pos, y_pos, value);
       delay_ms(90);

       return value;
}

 

Explanation

SW_I2C.h and SW_I2C.c files translate the entire I2C communication operations with the manipulation of ordinary GPIOs. Any GPIO pin pair can be used for software I2C. Just define the software I2C port, and the serial data (SDA) and serial clock (SDA) pins:

#define SW_I2C_port              GPIOD

 

#define SDA_pin                  GPIO_PIN_6
#define SCL_pin                  GPIO_PIN_7

The functions in these files are self-explanatory and so I’m not going to explain them here.

The rest of the code is about using the software I2C library with DS1307 real time clock (RTC) chip to make a real time clock.

Demo

SW-I2C

]]>
http://embedded-lab.com/blog/stm8-microcontrollers-final-chapters/feed/ 63
Continuing the STM8 Expedition http://embedded-lab.com/blog/continuing-stm8-microcontroller-expedition/ http://embedded-lab.com/blog/continuing-stm8-microcontroller-expedition/#comments Fri, 12 Jan 2018 15:54:58 +0000 http://embedded-lab.com/blog/?p=13976 This post is the continuation of the first post on STM8 microcontrollers here.

STM8S105 Discovery

ADC Interrupt

Instead of polling for ADC’s end of conversion (EOC) state, it is wise to use ADC interrupt. Just as with any hardware peripheral, interrupt methods make a system highly responsive. Interrupts like these free up the CPU for other tasks. However, it is up to the coder to determine interrupt priorities and look out for situation that may cause too many interrupts to be processed in a short while.

Hardware Connection

adc_isr

Code Example

 

stm8s_it.h (top part only)

#ifndef __STM8S_IT_H
#define __STM8S_IT_H

@far @interrupt void ADC_IRQHandler(void);

/* Includes ------------------------------------------------------------------*/
#include "stm8s.h"
....

 

stm8s_it.c (top part only)

#include "stm8s.h"
#include "stm8s_it.h"


extern unsigned int adc_value;


void ADC_IRQHandler(void)
{
       adc_value = ADC1_GetConversionValue();
       ADC1_ClearFlag(ADC1_FLAG_EOC);
}
....

 

stm8_interrupt_vector.c (shortened)

#include "stm8s_it.h"


typedef void @far (*interrupt_handler_t)(void);

struct interrupt_vector {
       unsigned char interrupt_instruction;
       interrupt_handler_t interrupt_handler;
};

//@far @interrupt void NonHandledInterrupt (void)
//{
       /* in order to detect unexpected events during development,
          it is recommended to set a breakpoint on the following instruction
       */
//     return;
//}

extern void _stext();     /* startup routine */


struct interrupt_vector const _vectab[] = {
       {0x82, (interrupt_handler_t)_stext}, /* reset */
       {0x82, NonHandledInterrupt}, /* trap  */
       {0x82, NonHandledInterrupt}, /* irq0  */
       ....
       {0x82, (interrupt_handler_t)ADC_IRQHandler}, /* irq22 */
       ....
       {0x82, NonHandledInterrupt}, /* irq29 */
};

 

main.c

#include "STM8S.h"
#include "lcd.h"


unsigned int adc_value;


unsigned char bl_state;
unsigned char data_value;


void clock_setup(void);
void GPIO_setup(void);
void ADC1_setup(void);
void lcd_print(unsigned char x_pos, unsigned char y_pos, unsigned int value);


void main(void)
{
       float mv = 0x00000000;

       clock_setup();
       GPIO_setup();
       ADC1_setup();

       LCD_init(); 
       LCD_clear_home();

       LCD_goto(2, 0);
       LCD_putstr("STM8 ADC ISR");
       LCD_goto(0, 1);
       LCD_putstr("A0/mV");

       while(TRUE)
       {
              ADC1_StartConversion();

              mv = (adc_value * 5000.0);
              mv /= 1023.0;

              lcd_print(7, 1, mv);            
              lcd_print(12, 1, adc_value);
              GPIO_WriteReverse(GPIOD, GPIO_PIN_0);
              delay_ms(160);
       };
}


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_HSIDIV4);
       CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);

       CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSI,
       DISABLE, CLK_CURRENTCLOCKSTATE_ENABLE);

       CLK_PeripheralClockConfig(CLK_PERIPHERAL_I2C, ENABLE);
       CLK_PeripheralClockConfig(CLK_PERIPHERAL_ADC, ENABLE);
       CLK_PeripheralClockConfig(CLK_PERIPHERAL_SPI, DISABLE);
       CLK_PeripheralClockConfig(CLK_PERIPHERAL_AWU, 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(GPIOB);
       GPIO_Init(GPIOB, ((GPIO_Pin_TypeDef)(GPIO_PIN_0 | GPIO_PIN_1)),      GPIO_MODE_IN_FL_NO_IT);

       GPIO_DeInit(GPIOD);
       GPIO_Init(GPIOD, GPIO_PIN_0, GPIO_MODE_OUT_OD_HIZ_FAST);
}


void ADC1_setup(void)
{
       ADC1_DeInit();     

       ADC1_Init(ADC1_CONVERSIONMODE_CONTINUOUS,
                 ADC1_CHANNEL_0,
                 ADC1_PRESSEL_FCPU_D18,
                 ADC1_EXTTRIG_GPIO,
                 DISABLE,
                 ADC1_ALIGN_RIGHT,
                 ADC1_SCHMITTTRIG_CHANNEL0,
                 DISABLE);

       ADC1_ITConfig(ADC1_IT_EOCIE, ENABLE);
       enableInterrupts();
       ADC1_Cmd(ENABLE);
}


void lcd_print(unsigned char x_pos, unsigned char y_pos, unsigned int value)
{
       char chr = 0x00;

       chr = ((value / 1000) + 0x30);  
       LCD_goto(x_pos, y_pos);
       LCD_putchar(chr);

       chr = (((value / 100) % 10) + 0x30);
       LCD_goto((x_pos + 1), y_pos);
       LCD_putchar(chr);

       chr = (((value / 10) % 10) + 0x30);
       LCD_goto((x_pos + 2), y_pos);
       LCD_putchar(chr);

       chr = ((value % 10) + 0x30);
       LCD_goto((x_pos + 3), y_pos);
       LCD_putchar(chr);
}

 

Explanation

This example and the first ADC example is all same except for the interrupt part. Note the last three lines below.

void ADC1_setup(void)
{
       ADC1_DeInit();     

       ADC1_Init(ADC1_CONVERSIONMODE_CONTINUOUS,
                 ADC1_CHANNEL_0,
                 ADC1_PRESSEL_FCPU_D18,
                 ADC1_EXTTRIG_GPIO,
                 DISABLE,
                 ADC1_ALIGN_RIGHT,
                 ADC1_SCHMITTTRIG_CHANNEL0,
                 DISABLE);

       ADC1_ITConfig(ADC1_IT_EOCIE, ENABLE);
       enableInterrupts();
       ADC1_Cmd(ENABLE);
}

As can be seen, End-of-Conversion (EOC) interrupt has been enabled along with global interrupt and the ADC itself.

In the vector mapping file, ADC interrupt is set.

{0x82, (interrupt_handler_t)ADC_IRQHandler}, /* irq22 */

When ADC EOC interrupt triggers, the ADC data buffer is read and the EOC flag is cleared.

void ADC_IRQHandler(void)
{
       adc_value = ADC1_GetConversionValue();
       ADC1_ClearFlag(ADC1_FLAG_EOC);
}

 

Demo

ADC ISR (2) ADC ISR (1)

]]>
http://embedded-lab.com/blog/continuing-stm8-microcontroller-expedition/feed/ 45
Starting STM8 Microcontrollers http://embedded-lab.com/blog/starting-stm8-microcontrollers/ http://embedded-lab.com/blog/starting-stm8-microcontrollers/#comments Mon, 24 Apr 2017 18:14:11 +0000 http://embedded-lab.com/blog/?p=13303 STM8 microcontrollers are 8-bit general purpose microcontrollers from STMicroelectronics (STM). STM is famous mainly for its line of 32-bit ARM Cortex microcontrollers – the STM32s. STM8 microcontrollers are rarely discussed in that context. However, STM8 MCUs are robust and most importantly they come packed with lots of hardware features. Except for the ARM core, 32-bit architecture, performance and some minor differences, STM8s have many peripheral similarities with STM32s. In my opinion, STM8s are equally or sometimes more matched than the popular PICs and AVRs in all areas. Unlike PICs and AVRs however, I have seen STM8s mostly in various SMD packages. Only a handful of STM8 chips are available in Plastic Dual-Inline Package (PDIP)/through-hole packages. I think it is a big reason for which most small industries and hobbyists don’t play with them as much as with other 8-bit families. People like to setup their test projects in breadboards, trial PCBs or strip-boards first, prototype and then develop for production. To cope with this issue, STM has provided several affordable STM8 Discovery (Disco) boards to get started with. Besides there are many cheap STM8 breakout-boards from China.STM8S003K3 Discovery

I have experience playing with AVRs, PICs, 8051s, STM32s, MSP430s, TivaC and so on. To be honest, I thought learning about STM8 micros is a pure waste of time and energy. The learning curve will be steep. Things and tools would be different and thus difficult. However, gradually I found these MCUs very useful and there is literally no complexity at all. The main drive factor for learning STM8s is the price factor. They are very cheap. When it comes down to other things, I have not found any book on STM8s written in English. There is literally no 100% complete blog post on the internet that shows the basics. Similarly, same story with tools. I have been using MikroC for AVRs, 8051s and ARMs and it is my favourite but at the time of writing, there’s no MikroC compiler for STM8 family. I have also not stumbled upon any Arduino-like IDE that supports STM8 micros. Arduino-based solutions are also not my favourite as they don’t go deep and have several limitations. Maybe it is not my luck. After much study and search, I found out that there are a few C compilers for STM8s. However, any new tool is both different and difficult at first. It is not always easy to adapt to new environments. You may never know what unanticipated challenges and harshness a new environment may throw at you even when you reach certain levels of expertise. I also don’t want to use any pirated software and so a free compiler was a major requirement. I found out ST Visual Develop and Cosmic COSC compiler are both free tools. Cosmic used to be a paid tool but now it is absolutely free. The only easy thing till then was buying the STM8S Value Line Discovery board for just a few dollars and downloading the stuffs.

The STM8 Family

There are over a hundred STM8 microcontrollers available today. The STM8 family can be simplified into three categorical groups as shown below.STM8 Family

There are subgroups within these groups but broadly speaking these three groups are what by which we can define the entire family. STM8S micros are general purpose robust and reliable micros that can be employed in almost all scopes. This is the most commonly used group and in fact we will be exploring it in this article. They are also cheap and smart. The second group – the STM8A family is intended mainly for automotive industries. This group is packed with additional hardware interfaces like CAN and LIN that are musts according to present-day automotive industry doctrine. The STM8As are also very versatile and are designed to withstand the harsh extremes of an automobile. For instance, STM8As can withstand high temperatures, in excess of 100°C. The last group consists of STM8L micros which are crafted for low power or battery-backed applications. Virtually they consume no power in idle mode. Thus, if you need high power savings or energy cuts in your projects, this group is the right choice. There are also low power editions of automotive-standard STM8 micros that are labelled STM8AL. Apart from all these there is also one variant of STM8 micros that are specifically designed for capacitive touch applications. These are called STM8Ts.

The features and benefits of STM8 micros are numerous and can’t simply be expressed in few words. The more you explore, the more you will know. STM8s can be powered with 3.3V or 5V DC power supplies and have built-in brownout detection circuitry. The low power editions can operate at much lower voltages than these values. Official STM8 Discovery boards come with voltage selection jumpers to allow users to select operating voltage level as required. There is very minimum risk of program corruption due to EMI or some other similar unprecedented factors. There is a fail-safe security system for the clock system which ensures that a system based on a STM8 micro won’t stop working or get stuck up should its external clock source fail. All internal hardware possesses more features than any other competitive 8-bit microcontroller families that are widely available in the market. The best part is the price benefit. You pay less for most. All these features are well-suited for extremely harsh industrial environments. STM8s are designed with maximum possible combinations of features. Beyond your wildest wet dream, there are many extraordinary stuffs waiting to be unboxed.

]]>
http://embedded-lab.com/blog/starting-stm8-microcontrollers/feed/ 242