STM32 microcontroller beginner 7-USART serial communication

USART is the English abbreviation of Universal Synchronous/Asynchronous Receiver/Transmitter, which means Universal Synchronous/Asynchronous Serial Receiver/Transmitter . It is also one of the most commonly used communication methods in microcontrollers.

It is often used for data transmission between single-chip microcomputer and host computer, Bluetooth module, GPS module and other equipment.

 

Similar to USART, there is also a communication method called UART, that is, Universal Asynchronous Serial Receiver/Transmitter. The difference is that it can only communicate asynchronously.

The difference between synchronous and asynchronous communication is whether there is a clock signal or not . The IIC and SPI mentioned above have clock lines. When transmitting, the clock lines need to be used to keep the timing consistent between the two parties.

Asynchronous communication does not require a clock line. The sender sends data at a set rate, and the receiver receives data at the same rate. Therefore, for the sake of simple wiring, asynchronous communication is often used. This article also uses asynchronous communication to explain the basic usage of USART.

In UART communication, the sender does not care whether the receiver receives the correct data after sending the data, and the receiver only confirms whether the data bit is wrong through data verification.

Therefore, in order to make the asynchronous communication go smoothly, the two parties must ensure consistent communication parameters: baud rate, data bits, stop digits, and verification methods.

Baud rate:

Baud is the modulation rate, which refers to the rate at which the effective data signal modulates the carrier, that is, the number of times the carrier modulation state changes per unit time. The baud rate indicates the number of symbol symbols transmitted per unit time . It is a measure of the symbol transmission rate. It is expressed by the number of carrier modulation state changes per unit time . The baud rate refers to a unit time The number of transmitted symbols. It is a measure of the symbol transmission rate, and the larger the value, the faster the transmission rate.

Pay attention to the difference between it and bit rate , which are two different concepts. The relationship between them is:

 In the formula, I is the amount of data, S is the baud rate, and N is the amount of data for each symbol.

For example:

The baud rate is 9600, a symbol has 10 data bits, then N= 2^{10}, the calculated result is 96000bit/s.

Data bits:

Data bits are the number of valid data bits carried by a symbol or a data frame. STM32 has two options of 8-bit and 9-bit. Generally, 8-bit is used more, because 8 bits are exactly equal to one Byte, and it is more convenient for data processing. The data is arranged in the order of low order first and high order.

Stop digits:

The data bits are followed by a stop bit, which marks the end of the symbol. STM32 has 4 kinds of stop bits to choose from, and you will find that the stop bits will be non-integer, such as 1.5 stop bits. In fact, this means that the maintenance time of the stop bit level is 1.5 times the unit time. Generally, more than one stop bit is used.

 Check method:

As mentioned above, in asynchronous communication, the data sender does not care whether the receiver receives the correct data after sending the data, so how does the receiver know that the received data is correct? This is judged by the check digit.

The principle is to check according to whether the number of "1" in the transmitted data bits is odd or even. The odd number is called odd parity , and the opposite is called even parity. For example, odd parity, that is, when the receiving end receives this set of data, it checks whether the number of "1" is odd to determine the state of the parity bit.

Suppose there is a set of data 10101100, the number of 1s is 4. 4 is an even number, if odd parity is used, the parity bit is 1, and the final data is 10101100 (1); if even parity is used, parity The bits are 0 and the last data is 10101100 (0). It can be found that after the parity bit is added, the number of 1 under the odd parity bit is odd, and the number of 1 is even under the even parity.

In addition to the parity check, it can also be set to no check, that is, no check is performed.

It can be found that this verification method has great limitations. First of all, it is impossible to confirm which bits of data are wrong. In addition, if two bits of data are wrong at the same time, it will also be judged as correct data by the receiver. Of course, this is A question of probability.

***********************************************************

The above four parameters must be set for serial communication. Next, use STM32F103C8T6 to transmit data with the computer host computer (serial port debugging tool) to explain the USART usage of STM32 in detail.

STM32F103C8T6 has three USART interfaces, as follows

 Among them, only USART1 has a CLK clock line, and the other two do not, so only USART1 supports asynchronous communication, and of course it also supports synchronous communication.

Let's take a look at its clock bus, as follows:

 USART1 hangs under the APB2 clock bus, and its clock frequency is 72MHz, while USART2 and USART3 hang under the APB1 bus, and its clock frequency is 36MHz. So USART1 can achieve a higher communication rate than the other two.

Here I use USART1 and the computer's serial debugging assistant to send and receive data.

-----------------------------------------------------------------

Hardware connection between computer and STM32

If you are using a desktop computer, you need to find the DB9 interface on the back of the host, find its RXD and TXD pins, and then connect the RXD of the computer to the TXD of the single-chip microcomputer, and the TXD of the computer to the RXD of the single-chip microcomputer. Connect to GND.

The DB9 pins are defined as follows:

 If you are using a laptop, it does not have a DB9 interface, so you need a USB to TTL tool. In this way, the serial port communication with the STM32 can be performed through the USB interface of the laptop.

The chip CH340 is commonly used for USB to TTL conversion.

CH340 has many specifications, and its pins are defined as follows.

 The following is the actual application circuit of CH340N. When making a circuit board, the chip and the microcontroller can be placed on the PCB together.

 

If you don't want to put CH340 on the board, or only have a STM32 bare board, you need a USB-to-TTL module, the core of which is still CH340. When using, plug the module into the USB port of the computer, then find the GND, RXD and TXD of the module, and connect it to the pins of the single-chip microcomputer according to the previous DB9 method.

-----------------------------------------------------------------------------

software part

On the computer side, we need a serial port debugging tool. There are many serial port debugging tools on the Internet, and the usage methods are basically the same. Here I am using XCOM of punctual atom, and its interface is as follows.

It is very simple to use, open the serial port after setting the communication parameters. Enter the data you want to send in the data sending area, and click "Send". The data received by the computer serial port will be displayed in the data receiving area.

Both sent and received data can be displayed in hexadecimal, just check "Send/Display in hexadecimal".

"Black text on white background" can set the background color of the window. RTS (Request To Send) and DTR (Data Terminal Ready) can generally be unchecked.

In addition to sending a single piece of data manually, it can also be set to send a single or multiple pieces of data automatically.

---------------------------------------------------------------

Next, I will explain how to use USART with a simple function: STM32 sends back the data received by the serial port intact.

1. USART initialization

void USART_Userinit(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);        //打开GPIOA时钟总线

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;		//设置PA9为复用推挽输出(TX)
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;							
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;								
    GPIO_Init(GPIOA, &GPIO_InitStructure);
	
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;		//设置PA10为浮空输入(RX)				
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;							
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;								
    GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	USART_InitTypeDef USART_InitStructure;					//初始化USART1					
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);		
	USART_InitStructure.USART_BaudRate = 115200; 			//波特率设为115200							
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;		//数据位8位
	USART_InitStructure.USART_StopBits = USART_StopBits_1; 			//停止位1位	
	USART_InitStructure.USART_Parity = USART_Parity_No; 			//校验方式:无校验		
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; 	
	USART_InitStructure.USART_Mode = USART_Mode_Tx| USART_Mode_Rx ; 	//收发模式	
	USART_Init(USART1, &USART_InitStructure);	
    USART_Cmd(USART1,ENABLE);		                    //使能USART1
	
	
	USART_ITConfig(USART1,USART_IT_RXNE, ENABLE);		//使能USART1接收中断
	
	NVIC_InitTypeDef NVIC_InitStructure;                //USART1中断初始化
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;			
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;	
	NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;				
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;					
	NVIC_Init(&NVIC_InitStructure);													
	
}

The following is annotated

 The first is to initialize the IO port of USART1. TX is data transmission, set as push-pull output, RX is data reception, set as floating input.

Then there is the initialization of USART1. In the same way as IIC and SPI, define a parameter configuration structure and open its corresponding clock bus, then assign values ​​to the members in the structure, and then call the initialization function to complete the initialization of the USART.

The parameters that need to be set are the same as those introduced above. For details, please refer to the STM32 standard library manual.

Then the receive interrupt of USART1 needs to be enabled, and when the STM32 receives data, it will jump to the interrupt function.

There are many interrupt sources of USART, which can be used flexibly according to the needs.

So also need to initialize the interrupt. Regarding the usage of interrupts, I will introduce them in detail later.

 2. Main function

The main function can be written very simply. In order to intuitively know whether the MCU is executing the main function or the interrupt function, an indicator light is specially used, which is controlled by PC13 and initialized first.

void GPIO_UserInit(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;            //推挽输出
	GPIO_Init(GPIOC,&GPIO_InitStructure);

}

When the CPU is executing the main function, the indicator light flashes quickly; when the CPU executes the interrupt function, the indicator light flashes slowly.

So get the main function as follows:

#include<stm32f10x.h>
#include<stm32f10x_gpio.h>
#include<stm32f10x_rcc.h>
#include<stm32f10x_usart.h>

int main(void)

{	
	USART_Userinit( );                                 //调用USART初始化函数
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);    //设置中断优先级分2组
	GPIO_UserInit();                                   //调用GPIO初始化函数
	
	while(1)                //主函数循环
	{
			GPIO_SetBits(GPIOC,GPIO_Pin_13);            //指示灯200ms闪烁周期
			Delay_ms(100);
			GPIO_ResetBits(GPIOC,GPIO_Pin_13);
			Delay_ms(100);
	}		
}

For the convenience of understanding, the timer is not used here, just Delay.

Delay function:

void Delay_ms(int Time)
{
	int i=0;
	while(Time--)
	{
		i=8000;
		while(i--);
	}
	return;
}

Then there is the interrupt function, its execution condition is: when but USART receives data.

After receiving the data, send it out, then clear the interrupt flag, exit the interrupt function, and return to the main function. Until the data is received again and enter the interrupt function. cycle like this

The interrupt function is as follows:

void USART1_IRQHandler(void)                						//USART中断函数
{
	u16 Data;
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)           //如果USART1接收中断SET
	{
		GPIO_SetBits(GPIOC,GPIO_Pin_13);
		Data =USART_ReceiveData(USART1);					//将USART接收到的数据赋值给Data
		USART_SendData(USART1,Data);						//将Data的值发送出去
		Delay_ms(400);										
		GPIO_ResetBits(GPIOC,GPIO_Pin_13);
		Delay_ms(400);	
	}
	USART_ClearITPendingBit(USART1,USART_IT_RXNE);        //清除USART1的接收中断标志位
} 	

In this way, the program part is completed

-----------------------------------------------------

After burning the program, connect the MCU to the computer (or connect to the computer through the USB to TTL tool), and open XCOM.

The first is to select the serial port. If the serial port cannot be selected (the drop-down menu has no options), you need to confirm that the microcontroller is correctly connected to the computer. If the connection is correct and still cannot be selected, it may be because the computer does not have the relevant driver. You need to download and install a CH340 driver (you can find it online). You can check whether it is connected and identify the driver in the device manager. If it is connected, but the serial port cannot be opened, it shows that an unrecognized device is plugged in.

Below is the interface when it is properly connected and the driver is working.

Then set 4 communication parameters, which need to be consistent with the parameters initialized by USART in the program.

 Then click "Open Serial Port", the button turns red, indicating that the opening is successful.

When no data is sent, the indicator light flashes quickly, indicating that the main while loop is being executed at this time.

Then, we input a 2-digit hexadecimal number in the data sending area (since the return value of the USART_ReceiveData(USART1) function is 16-bit, so only 2-digit hexadecimal number can be input), and then send, you can see the indication The light flashed once, and at the same time, the data sent just now appeared in the data receiving area. It shows that the cpu is executing the interrupt function at this time.

Note : Do not check "Send new line", otherwise you will not be able to jump out of the interrupt function, and will be permanently stuck in the interrupt function.

After a short delay, the indicator light starts to flash again, indicating that the CPU returns to the main function and continues to execute the previous while loop.

At this time, if new data is sent, the interrupt will be executed again, and then the main function will be returned.

Note : The sending speed should not be too fast. If the next data sent by the serial port is received when the STM32 is executing the interrupt function and the receiving interrupt flag is not cleared, the interrupt function will be stuck and cannot jump back to the main function. Checking "Send New Line" is also the reason why it will be stuck, because after checking "Send New Line", after sending the content of the data input window, a carriage return will be automatically sent, resulting in the receiving interrupt flag being too late to be cleared and stuck.

Strings can also be sent continuously using "Multiple Send".

Note: If you want to send characters, you need to uncheck "Hexadecimal Display" and "Hexadecimal Send"

---------------------------------------------------------

In fact, in addition to using the interrupt function, you can also use the USART status flag to determine whether data is received or perform other processing.

 For example: USART_FLAG_RXNE is the flag bit of whether data is received, and the state of this register can be used to judge whether the serial port has sent data. It should be noted that USART_ClearFlag (USART1, USART_FLAG_RXNE) should be used to clear the flag bit in time after getting the value from this register.

 The above is a simple use of USART. If you want to achieve more complex functions, such as real-time monitoring, you need the software support of the host computer.

 

 

It's not easy to create, if you find it useful, just like it!

Guess you like

Origin blog.csdn.net/qq_55203246/article/details/125953359