STM8S003F uses I/O port to simulate serial port (I) to send data

Publisher:RadiantSmileLatest update time:2020-02-24 Source: eefocusKeywords:STM8S003F Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

Recently I am using STM8S003F to simulate the serial port to send data. There are many resources on the Internet, but I didn’t find what I needed. So I wrote an article and made a summary. This article mainly implements the simple sending process without using library functions.


1. Principles of serial port communication and principles of simulating serial port data transmission

The standard serial port data format is: start bit (1 bit) + data bit (8 bits) + check bit (1 bit) + stop bit (1 bit). The start bit is low level and the stop bit is high level.


Serial communication requires setting the baud rate and checking the COM port.


The idea is this: we use timer TIM2 to send a bit every other time, thereby simulating the serial port to send data.


2. Get the value of timer ARR automatically loaded

For simplicity, we don't use the check bit, so there are 10 bits of data in total.


I take the process of calculating the baud rate of 9600bit/s in stm8 as an example (9600 bits are transmitted in 1 second).


It can be calculated that the time required to transmit 1 bit is T1 = 1/9600, which is approximately 104us.


The internal crystal frequency of stm8 is 16M. I use 16 division, which is 1M, so the MCU oscillation period is 1/1M = 1us.


From the above calculation, we know that to send one bit of data, the value of the automatic load in the timer should be set to 104/1 = 104.


3. Implementation process

During the implementation process, we divided the project folder SimUART into 4 folders (System: for storing system files; Project: for storing project files; User: for storing main.c and UserApp.c; My_Lib: for storing other commonly used files). According to the resources of the microcontroller we will use, we divided three files in My_Lib, namely - Delay: for storing files related to delay functions; IO: for storing files related to IO port functions; Time: for files related to timer functions. Below I paste the .c files of the relevant functions, and the .h files are omitted. Students in need can download and use them according to the URL at the end of the article. My programming environment is IAR, and I need to create an IAR project myself. MARK, which will be introduced later. The following is a detailed introduction (Project and System are omitted, and System only uses stm8s.h).


3.1. Everything starts from main.c

First, in main.c, we need to initialize the resources of the MCU. We write it in the All_Config() function [in UserApp.c], the code is as follows:


//head file 

#include "UserApp.h"

#include "IO.h"

#include "User.h"

#include "Time.h"

 

// Initialization function

void All_Config( void )

{

    Clock_Config();

    IO_Init();  

    TIM2_Heat();

}



Among them, User.h is a file in which I write my commonly used macros, corresponding to main.c.


When no external clock is connected, the main clock of STM8S003F defaults to 8-frequency division of HSI RC clock at startup. The initialization here only specifies 16MHZ high-speed internal RC oscillator (HSI), which can also be omitted. The function code of Clock_Config() [in UserApp.c] is as follows:

// Initialize the clock to select the internal 16M crystal oscillator

void Clock_Config()

{

    CLK->CKDIVR &= ~( BIT(4) | BIT(3) );

}



I choose PD2 of the microcontroller as the data transmission port of my simulated serial port. The IO_Init() function code in IO.c is as follows:




//head file

#include "IO.h"

#include "User.h"

 

void IO_Init()

{

    //TXD: TXD bit push-pull output PD2

    UART_PORT->ODR |= UART_PIN_TX; //0000 0000

    UART_PORT->DDR |= UART_PIN_TX; //0000 1000

    UART_PORT->CR1 |= UART_PIN_TX; //0000 1000  

    UART_PORT->ODR &= ~UART_PIN_TX;

    UART_PORT->ODR |= UART_PIN_TX;

}

The macro definition in IO.h is:




#define UART_PORT GPIOD

#define UART_PIN_TX 0X04 //  PD2

#define UART_PIN_RX 0X08 //  PD3


The following is the initialization of the timer. When using the timer, we divide it into the following steps:


a. Select the timer, we choose TIM2;


b. The clock division of the timer (pay attention to whether it is the default 8-division or has been changed). I did not have a division at the beginning and needed a 16-division.


c. Fill in the value that the timer automatically loads, in my case it is 104;


d. Start the timer;


Note that the counter CNTR is automatically reset to 0 when powered on. We still need to clear it to zero. After using the auto-reload register, the auto-reload register determines the overflow timing of the timer. When the value in the timer counter reaches the value specified by the auto-reload register, the counter will be reset to zero. In other words, the auto-reload register determines the period of the timer.


In the method of simulating serial port data transmission introduced in this article, no interrupt is used. The function code of TIM2_Init() [in TIM2.c] is as follows:


//head file

#include "TIM2.h"

#include "User.h"

 

void TIM2_Init()

{

    CLK->PCKENR1 |= CLK_PCKENR1_TIM2;   //TIM2 enable  

    TIM2->PSCR = 0x04; //16-division 1MHZ 1us

    TIM2->ARRH = 104 >> 8; //Automatically load and reset TIM2 every 52us

    TIM2->ARRL = 104; //Decrease by 1 every 1us

    TIM2->CNTRH = 0;

    TIM2->CNTRL = 0; 

TIM2->CR1 |= TIM2_CR1_CEN; //Start the timer}

After completing the initialization, we should write the sending program. For simple sending, we choose to send 0x55 because it shows a square wave in the oscilloscope. We write our implementation of our simulated serial port sending in UserApp.c.

The rules for sending data are:


a. There are 10 bits of data in total (so 16 bits of data are needed, 8 bits are not enough). Since the data we send is 8 bits, there is a conversion process;


b. Send low digits first, then high digits;


c. There is a time delay code in the sending function to ensure that every data is a counting time (that is, a 104 count is completed)


The code of the sending function SimUART_TxByte() [in UserApp.c] is as follows


void SimUART_TxByte( u8 SendData )

{

    static u16 Send_All = 0;

    static u8 BitNum = 0; //bit count

    Send_All = SendData;

    Send_All = ( Send_All << 1 ) | 0X0200; //10 bits of data to be sent

    TIM2->CNTRH = 0;

    TIM2->CNTRL = 0;  

    TIM2->SR1 &= ~TIM2_SR1_UIF;

 

    //Send low bit first, then high bit

    for( BitNum = 0;  BitNum<10 ;  BitNum++ )

    {

        if( Send_All & 0X0001 ) //If it is a high level, send a high level

        {

            UART_PORT->ODR |= UART_PIN_TX;

        }

        else //If it is a low level, send a low level

        { 

            UART_PORT->ODR &= ~UART_PIN_TX;

        }

        Send_All >>= 1; //Move right one bit

        

        //Wait for baud rate time 

        while( (TIM2->SR1 & TIM2_SR1_UIF) == 0 );

        TIM2->SR1 &= ~TIM2_SR1_UIF;

    }

}

Among them, UART_PIN_TX is the macro definition in IO.c.


3.2. Complete the main() function

After completing the above code, we can test it. Now let's complete the main() function. The code is as follows:


//head file 

#include "User.h"

#include "UserApp.h"

#include "Delay.h"

 

int main( void )

{

    char Test = 0;

    //char Test = 0x55; //test data  

    All_Config(); // Initialization

 

    while(1) //Send loop

    {

        SimUART_TxByte( Test++ );

        Delay_50000(); //Delay to prevent excessive data

    }

    //return 0;

}


After 0x55 is sent correctly, we send 0x00 to 0xFF. If the baud rate is incorrect, the transmission will be discontinuous. In order to prevent too much data, we need a delay function. The function code of Delay_50000() [IO.C] is as follows:

//Head file

#include "Delay.h"

 

void Delay_50000()

{

    int a,b;

    for( a=0 ; a<100 ; a++ )

    {

        for( b=0 ; b<500 ; b++ );

    }

}

4 Conclusion

So far, we have realized the function of using the IO port to simulate the serial port (without using the library function) to send data. The relevant code can be downloaded and used at the following address. Everyone is welcome to learn and communicate with me.

Keywords:STM8S003F Reference address:STM8S003F uses I/O port to simulate serial port (I) to send data

Previous article:STM8S MCU serial port debugging
Next article:Usage of UART in stm8s (four types of UART interrupts)

Recommended ReadingLatest update time:2024-11-16 10:52

STVP programming error
When using STVP to burn the program to STM8S003F, an error message appears: Cannot communicate with the tool. In fact, the download tool was not selected correctly. After returning to the software interface, click Configure- Configure ST Visual Programmer, and the following window will pop up. We usually select th
[Microcontroller]
STVP programming error
Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号