Generally, there are three steps in the operation of SCM: 1. System clock selection. 2. Initialize microcontroller peripherals. 3. Main program writing.

Also follow this step when lighting LED lights.

First select the system clock, open the STM8S Chinese reference manual, find the clock register



You can see that there are 13 clock registers, so which one to use. There are 4 main clock sources of STM8, we will use 16M internal RC oscillator.



So you only need to set the master clock switch register CLK_SWR register.



When the register value is 0XE1, HSI is the master clock, so the CLK_SWR value is set to 0XE1.

CLK_SWR = 0xe1; //HSI 16MHz CPU clock frequency of the primary clock source

Then set the clock division value



The default value of the clock divider register is 0x18, that is, 8 dividers. We want the single chip microcomputer 16M clock to run, regardless of frequency. So set the value of the crossover register to 0.

CLK_CKDIVR = 0x00; //CPU clock is 0, system clock is 0

Encapsulate the system clock setting as a function for future program calls

// System clock initialization void SysClkInit(void) {CLK_SWR = 0xe1; CLK_CKDIVR = 0x00; //CPU clock 0, system clock 0}Copy the code

After the system clock is set, you need to set the I/O port.

Find the GPIO related register in the Chinese reference manual.



LED control is the output, so you need to set the output data register, data direction register, control register.

First set the data direction of the selected port



The LED is connected to the PB5 port, so you need to set the PB5 port to 1

PB_DDR |= 1 << 5 ;

Then set up the control register



Through PB5 output high and low level to control LED lights on and off, so the output mode choose push-pull output.

PB_CR1 |= 1 << 5 ;

Control register 2 can set the output speed when it is in output mode. Since LED is connected to our output port, the output speed has little influence on the brightness and off of LED. This register can also be set without using the default value 0.



Output data register, write 1 to this register output is high, write 0 to register output is low.

This cycle to the register ODR5 position write 0, write 1, PB port connected to the LED light on, off, on, off. Cycle.

Here the register is set up, and then in the main program cycle change PB_ODR register ODR value can achieve LED flashing.

The program in LED.c is as follows:

/ / the LED port initialization void LED_GPIO_Init (void) {PB_DDR | = (1 < < 5); / / PB5 output led PB_CR1 | = (1 < < 5); //PB5 push-pull output}Copy the code

The program in main. c is as follows:

#include "iostm8s003f3.h" #include "led.h" // System clock initialization void SysClkInit(void) {CLK_SWR = 0xe1; CLK_CKDIVR = 0x00; Void delay_ms(unsigned int ms) {unsigned char I; while( ms ! = 0 ) { for( i = 0; i < 250; i++ ); for( i = 0; i < 75; i++ ); ms--; } } void main(void) { SysClkInit(); LED_GPIO_Init(); while(1) { PB_ODR |= ( 1 << 5 ); delay_ms(500); PB_ODR &= ~( 1 << 5 ); delay_ms(500); }}Copy the code

After entering the main function, the first clock selection, and then the LED port initialization, down into the loop, the loop changes the VALUE of the LED port. This allows the LED light to flash on and off.

The function of the program is to make the LED light blink, but it does not seem intuitive to operate the register directly from the code, you can use the macro definition, give the register a new intuitive name. Add the macro definition #define LED PB_ODR_ODR5 to the led.h header file to rename the 5th bit ODR5 in the PB_ODR register to LED, so that when assigning to LED, it is equivalent to assigning to PB_ODR_ODR5. So the loop in the program can be changed

void main( void ) { SysClkInit(); LED_GPIO_Init(); while( 1 ) { LED = 1; delay_ms( 500 ); LED = 0; delay_ms( 500 ); }}Copy the code

In this way, the readability of the program is greatly improved through macro definition processing.