STM32 serial communication based on MDK 5

1, Serial port protocol and RS-232 standard

1. Serial port protocol

Serial communication refers to a communication mode between peripherals and computers that transmits data by bit through data signal line, ground wire, control line, etc.
Serial communication protocol refers to the relevant specifications that specify the content of data packet, including start bit, main data, check bit and stop bit. Both parties need to agree on a consistent data packet format to send and receive data normally. In serial communication, common protocols include RS-232, RS-422 and RS-485. The following mainly explains RS-232 standard.

The data packet of serial communication is transmitted from the transmitting device to the RXD interface of the receiving device through its own TXD interface. In the protocol layer of serial communication, the content of data packet is specified. It is composed of start bit, main data, check bit and stop bit. The data packet format of both sides of communication should be consistent before normal sending and receiving

The most important parameters of serial communication are baud rate, data bit, stop bit and parity bit. For two ports communicating, these parameters must match.
1. Baud rate
This is a parameter to measure the symbol transmission rate. It refers to the change in unit time after the signal is modulated, that is, the number of carrier parameter changes in unit time. For example, 240 characters are transmitted per second, and each character format contains 10 bits (1 start bit, 1 stop bit and 8 data bits). At this time, the baud rate is 240Bd, and the bit rate is 10 bits * 240 / S = 2400bps.
2. Data bits
This is a parameter that measures the actual data bits in communication. When a computer sends a packet, the actual data is often not 8 bits, and the standard values are 6, 7 and 8 bits. How you set it depends on the message you want to send. For example, the standard ascii code is 0 ~ 127 (7 bits). The extended ASCII code is 0 ~ 255 (8 bits). If the data uses simple text (standard ascii code), each packet uses 7 bits of data. Each packet refers to a byte, including start / stop bits, data bits and parity bits.
3. Stop bit
Used to represent the last bit of a single package. Typical values are 1, 1.5 and 2 bits. Because the data is timed on the transmission line and each device has its own clock, there may be a small synchronization between the two devices in the communication. Therefore, the stop bit not only indicates the end of transmission, but also provides an opportunity for the computer to correct clock synchronization. The more bits applicable to stop bits, the greater the tolerance of different clock synchronization, but the slower the data transmission rate.
4. Parity bit
A simple error detection method in serial communication. There are four error detection methods: even, odd, high and low. For even and odd parity, the serial port will set the parity bit (one bit after the data bit) and use a value to ensure that the transmitted data has even or odd logical high bits. If it is an odd check, the check bit is 1, so there are three logical high bits. The high and low bits do not really check the data. Simply set the logic high or logic low check.

2.RS-232 standard

RS-232 standard mainly specifies the purpose of signal, communication interface and signal level standard.
Common communication structures between serial devices using RS-232 standard are as follows:

In the above communication mode, the "DB9 interface" of two communication devices is connected through the serial port signal line, and the "RS-232 standard" is used in the serial port signal line to transmit data signals. Since the signals of RS-232 level standard can not be directly recognized by the controller, these signals will be converted into the level signal of "TTL calibration" recognized by the controller through a "level conversion chip", so as to realize communication.
2.1. Level standard
According to different level standards used in communication, serial port communication can be divided into TTL standard and RS-232 standard:

Communication standardLevel standard (transmitter)
5V TTLLogic 1: 2.4V~5V
Logic 0:0~0.5V
RS-232Logic 1: - 15V~-3V
Logic 0: + 3V~+15V

TTL level standard is often used in common electronic circuits. Ideally, 5V is used to represent binary logic 1 and 0V is used to represent logic 0; In order to increase the long-distance transmission and anti-interference ability of serial communication, it uses - 15V to represent logic 1 and + 15V to represent logic 0. The comparison when RS232 and TTL level calibration are used to represent the same signal is shown in the figure below

Because the controller generally uses TTL level standard, MA3232 chip is often used to convert TTL and RS-232 level signals to each other.

3. USART of stm32

3.1. Introduction
STM32 chip has several USART peripherals for serial communication. It is the abbreviation of Universal Synchronous Asynchronous Receiver and Transmitter, that is, the universal synchronous asynchronous transceiver can flexibly exchange full duplex data with external devices. Different from USART, it also has UART peripherals (Universal Asynchronous Receiver and Transmitter). It cuts out the synchronous communication function on the basis of USART, and only has asynchronous communication. The simple distinction between synchronous and asynchronous is to see whether the clock output needs to be provided during communication. The serial port communication we usually use is basically USART.
The USART of STM32 outputs TTL level signal. If RS-232 standard signal is required, MAX3232 chip can be used for conversion.
3.2. Functional block diagram
After mastering the functional block diagram, you will have an overall grasp of USART and have a clear idea when programming.

For specific function overview, please refer to the link:

2, USART serial communication of STM32

Complete a USART serial port communication program of STM32. Requirements:
1) Set the baud rate to 115200, 1 stop bit and no check bit;
2) STM32 system continuously sends "hello windows!" to the upper computer (win10) (win10 receives it with the "serial port assistant" tool).

1. New construction

The download and installation of STM32cubeMX and the establishment of related projects have been covered in previous blogs. For details, please refer to:
Open the STM32cubeMX program and click New Project under File to create a New Project

Select STM32F103C8 in Part Number, click the information of a list of chips that will appear in the middle, and then click Start Project

Click System Core, enter SYS, and select Serial Wire in debug

Click RCC and set HES as Crystal/Ceramic Resonator

In the Clock Configuration interface, select PLLCLK on the right and change the crystal oscillator to 72

Then click connectivity, select USART1 serial port 1 (i.e. the RXD pin of the smallest chip is connected to A10, and the TXD pin is connected to A9), and select Asynchronous for Mode. At this time, you can see some configured information below, including baud rate, word length, check bit and stop bit.

TXD: transmit data output pin
RXD: receive data output pin

Go to the Project Manager interface, customize your Project name and Project path under Project, change the IDE item to MDK-ARM, and select the version according to your needs

Note: the Chinese name cannot appear in the path, otherwise an error will be reported!!!
Enter the Code Generate interface and check generate initialization. c/.h file

Finally, click GENERATE CODE to generate the code

2. Redirect printf function

Enter the path you just selected, open the MDK-ARM subfolder, and open the newly generated project through keil

If we want to use the input and output functions of C language standard function libraries such as printf and scanf, we need to make some configurations:
Click Options for Target

Check use MicroLIB in the Target interface and click OK

The redirect printf function code is as follows:

// Redirection function
int fputc(int ch,FILE *f)
    uint8_t temp[1]={ch};
    HAL_UART_Transmit(&huart1,temp,1,2);        //UartHandle is the handle of the serial port

Note: when defining the redirect printf function, remember to add the stdio.h header file.

3. Main code

3.1.usart.h file

#ifndef __USART_H__
#define __USART_H__
#include <stdio.h>
int fputc(int ch,FILE *f);	//User defined function declaration
#ifdef __cplusplus
extern "C" {
#include "main.h"
extern UART_HandleTypeDef huart1;
void MX_USART1_UART_Init(void);
#ifdef __cplusplus

3.2.usart.c file

#include "usart.h"
#include <stdio.h>

// Redirect printf function
int fputc(int ch,FILE *f)
    uint8_t temp[1]={ch};
    HAL_UART_Transmit(&huart1,temp,1,2);        //UartHandle is the handle of the serial port
UART_HandleTypeDef huart1;
void MX_USART1_UART_Init(void)
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 115200;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart1) != HAL_OK)

void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)

  GPIO_InitTypeDef GPIO_InitStruct = {0};


    GPIO_InitStruct.Pin = GPIO_PIN_9;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_10;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)



3.3.main.c file

#include "main.h"
#include "usart.h"
#include "gpio.h"

void SystemClock_Config(void);
int main(void)
  while (1)
	  HAL_Delay(1000);	//delayed
	  printf("hello windows!\n");	//Output hello windows!
void SystemClock_Config(void)
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)

void Error_Handler(void)
  while (1){}

void assert_failed(uint8_t *file, uint32_t line){}
#endif /* USE_FULL_ASSERT */

4. The compiler generates. hex files

Compile and run the program without error and generate the corresponding. hex file

Under the folder MDK-ARM, open the subfolder with the same project name to see the generated. hex file

5. Program burning

For the operation and software download of burning process, please refer to the link:
Select the. hex file just generated, start programming and burning code, and the result will be returned after success

6. Operation results of serial port tool

Wildfire serial port debugging assistant download link:
Extraction code: 1234
After the burning is successful, open the wildfire serial port debugging assistant program, and click to open the serial port

You can see that the serial port debugging assistant continues to output hello windows!

The development board sends data every 1s, and the serial port debugging assistant receives data every 1s.
Some data output is as follows:

3, Summary

Through this experiment, we understand the serial port protocol and RS-232 standard, as well as the difference between RS232 level and TTL level. Once again, we use stm32CubeMX to automatically generate code to complete a USART serial port communication program of STM32. We have a better understanding of the rational use of tools, which can enable us to write code faster and improve learning efficiency, although there are shortcomings, But the harvest is full.

4, References


Tags: network Single-Chip Microcomputer stm32

Posted on Mon, 25 Oct 2021 11:02:04 -0400 by sdotsen