[STM32 learning] - serial communication protocol & STM32-USART peripherals & data frame / input data strategy / baud rate generator & serial port sending / receiving practical operation


Disclaimer: The study notes are edited according to the stm32 introductory tutorial of Jiangke University of Science and Technology of China, and are only for learning and communication!

foreword

This section learns two codes, the first is for serial port sending, and the second is for serial port sending+receiving.


1. Serial communication

1. Communication interface

(1) The purpose of communication : to transfer the data of one device to another device and expand the hardware system. For example, the STM32 chip integrates many functional modules, such as timer counting, PWM output, AD acquisition, etc. These are the internal circuits of the chip, and their configuration registers and data registers are all in the chip. The operation is simple, just read and write directly. . However, some functions are not available inside STM32 , such as the function of Bluetooth wireless remote control , the function of gyroscope accelerometer to measure attitude , which can only be completed by external chip , and the data is all outside STM32, which requires the communication line to send or receive data to complete the data exchange.


(2) Communication protocol : formulate the rules of communication, and the two parties in communication will send and receive data according to the rules of the agreement. The communication protocol in STM32 has the following table: (The pins listed are only the simplest and most commonly used ones worth noting.)
insert image description here
Full-duplex means that input and output can be performed simultaneously, and half-duplex means that both input and output can be performed but not simultaneously. Simplex means only output or input.

I2C and SPI have a clock line SCL for synchronous communication, and those without a clock line for asynchronous communication. Both parties need to agree on a sampling frequency, and some frame headers and tails need to be added to align the sampling positions.

Level characteristics, single-ended means that the high and low levels of their pins are the voltage difference to GND, so the two sides of single-ended signal communication must share the ground, that is, connect GND together. The latter two types of CAN and USB are differential data communications, which rely on the voltage difference between two differential pins to transmit signals. GND can be used during communication, but there are some places in the USB protocol that require single-ended signals, and it still needs a common ground. Differential signals have good anti-interference characteristics, so generally its transmission speed and distance will be relatively high, and high performance is also good.

USART and USB belong to point-to-point communication , and the middle three can mount multiple devices , requiring an addressing process (device number).


2. Serial communication

(1) Introduction to serial port

The serial port is a widely used communication interface. The serial port is low in cost, easy to use, and simple in communication lines, and can realize mutual communication between two devices.

The serial port of the single-chip microcomputer can make the single -chip microcomputer communicate with the single-chip microcomputer , the single-chip microcomputer and the computer , and the single-chip microcomputer and various modules , which greatly expands the application range of the single-chip microcomputer and enhances the hardware strength of the single-chip microcomputer system. The main feature is that it is used between the microcontroller and the computer. Other more complex communication protocols such as I2C and SPI are mostly used between chips. The gyroscope accelerometer measures the attitude chip and STM32, MPU6050 and STM32.
insert image description here
The picture on the left is a USB-to-serial port module with a CH340 chip on it, which can convert the serial port protocol to the USB protocol, because the most popular computer interface is the USB port.
The middle picture shows a gyroscope sensor module , which can measure attitude parameters such as angular velocity and acceleration. There are four pins on the left and right sides, one side is a serial port pin, and the other side is an I2C pin.
The picture on the right is a Bluetooth serial port module , the bottom 4 pins are the pins of serial port communication, and the chip on the top can be interconnected with the mobile phone to realize the function of the mobile phone to remotely control the single-chip microcomputer.


(2) Serial port hardware circuit

Simple two-way serial communication has two communication lines (transmitter TX and receiver RX), and TX and RX should be cross-connected. When only one-way data transmission is required, only one communication line can be connected.
insert image description here
When the level standards are inconsistent, a level conversion chip needs to be added . There are many level standards for serial ports. The signals that come directly from the controller like ours are generally at TTL level, and the same level can communicate with each other. Several evaluation standards are introduced as follows.

The level standard is the expression of data 1 and data 0. It is the corresponding relationship between the artificially specified voltage and data in the transmission cable. There are three commonly used level standards for serial ports: (1) TTL level:
+ 3.3V or +5V means 1, 0V means 0. Low-voltage small devices, such as microcontrollers.
(2) RS232 level : -3 to -15V means 1, +3 to +15V means 0. Generally used in large-scale machines, due to the relatively harsh environment and relatively large electrostatic interference, the voltage is relatively large and the range of allowable fluctuations is relatively wide.
(3) RS485 level : Two-wire voltage difference +2 to +6V means 1, -2 to -6V means 0 (differential signal). The communication distance can reach thousands of meters, and the distance of the above two types is tens of meters.


(3) Serial software part

insert image description here
In the serial port, each byte is loaded in a data frame (10 or 11 bits), each data frame is composed of start bit , data bit and stop bit in bold style , and 8 data bits represent a byte of 8 bits. The 9-bit data on the right has one more parity bit, which follows the payload (byte). The parameters are as follows :
①Baud rate : The rate of serial port communication. The baud rate originally means the number of symbols transmitted per second, the unit is symbol/s, or directly called baud (Baud), there is also a rate called bit rate, the number of bits transmitted per second, the unit is bit /s, or bps. Under binary modulation, one symbol is one bit. At this time, the baud rate is equal to the bit rate. The serial port communication of the microcontroller is basically binary modulation (high level means 1, low level means 0, and one bit is 1 bit), so The baud rate of the serial port is often mixed with the bit rate.
②Start bit : marks the beginning of a data frame, fixed at low level. The idle state is high level, and the start bit generates a falling edge to tell the device to start sending data
③Data bit : the payload of the data frame, 1 is high level, 0 is low level, and the low bit comes first .
Check digit : used for data verification, calculated according to the data bit. Here, the serial port uses the data verification method of parity check, which can judge whether the data transmission is wrong. If there is an error, you can choose to discard or retransmit. There are three ways to choose, no parity, odd parity, even parity. Odd parity, there will be an odd number of 1s in the 9 data bits including the parity bit. According to the 8-bit data situation, the odd parity bit will be filled with 0 or 1 to ensure that the number of 1 bits is odd. When the receiver receives the data, it will verify the data bits and Check bit, the detection rate is not high. For example, if two bits are wrong at the same time, it cannot be detected only by checking the parity feature. The same is true for even parity , which can only guarantee a certain detection rate. If you want a higher detection rate, you can use CRC check .
Stop bit : used for data frame interval, fixed at high level. It is also preparing for the next start bit (switching to a high-level idle state).
insert image description here
The above is the actual waveform of the serial communication measured with an oscilloscope!


2. USART peripherals of STM32

1. Introduction to USART

USART (Universal Synchronous/Asynchronous Receiver/Transmitter) Universal Synchronous/Asynchronous Receiver/Transmitter. The synchronous mode is just an extra clock output, which only supports clock output but not clock input. Generally, it is rarely used, so USART and UART are basically the same. Synchronous mode is more designed for compatibility with other protocols or special purposes .


USART is a hardware peripheral integrated in STM32 . It can automatically generate data frame timing according to a byte of data in the data register, send it from the TX pin, and automatically receive the data frame timing of the RX pin, splicing it into a byte of data. , stored in the data register. That is, the peripheral is a hardware support circuit for serial communication .


Built-in baud rate generator , up to 4.5Mbits/s, commonly used 9600 or 115200 . The one used to configure the baud rate is actually a frequency divider. For example, if the APB2 bus gives a frequency of 72MHz, the baud rate generator performs a frequency division to obtain the desired baud rate clock, and transmits and receives under this clock, that is Specifies the communication baud rate.


Support configuration parameters :
configurable data bit length (8 or 9, generally choose 8 without parity), stop bit length (0.5 or 1 or 1.5 or 2, generally choose 1 bit).
Optional parity bit (no parity/odd parity/even parity).
Supports synchronous mode, hardware flow control, DMA, smart card, IrDA, LIN . There is an additional clock CLK output in synchronous mode . Hardware flow control . For example, device A has a TX to send data to device B’s RX. Device A sends data so fast that B cannot handle it. If there is no hardware flow control, B can only discard new data or overwrite the original data. If there is Hardware flow control, there will be an extra line on the hardware circuit. If B is not ready to receive, it will be set to
high level, and if it is ready, it will be set to low level. A will only send data when B is ready. DMA means that the serial port supports DMA for data transfer. When sending and receiving a large amount of data, DMA can be used to reduce the burden on the CPU. Smart card, IrDA, LIN , these are some other protocols, these protocols are very similar to the serial port, so STM32 has added some changes to the USART to be compatible with these protocols. IrDA is used for infrared communication, one side is infrared light-emitting tube, and the other side is infrared receiving tube, which communicates by flashing infrared light, which is different from the infrared of the remote control. LIN is a communication protocol for local area networks.


STM32F103C8T6 USART resources: USART1, USART2, USART3. USART1 is a device on the APB2 bus, and USART2 and USART3 are devices on the APB1 bus. Pay attention when turning on the clock RCC.


2. Graphical explanation

insert image description here
TX and RX in the upper left corner are sending and receiving pins, and SW_RX and IRDA_OUT/IN are pins for smart card and IrDA communication (not used for now). TX is sent out by the transmit shift register, RX leads to the receive shift register.
In the gray part, TDR and RDR are the data registers of the serial port. The bytes sent and received are stored here. The two registers occupy the same address (same as the SBUF register of the serial port of the 51 single-chip microcomputer), so in the program it only appears as a register DR . The transmit data register is write-only, and the receive data register is read-only.
For example, write 0x55 in TXD at a certain moment, which is 01010101 in binary. At this time, the hardware detects the written data, and it will check whether there is data shifting in the current sending shift register. If not, all 01010101 will be moved to the register preparation. Send, at this time, a flag bit TXE (TX Empty) will be set to send the register to be empty. If this flag bit is set to 1, the next data can be written in TDR (note that the data has not been sent out when TXE is set to 1), Then the sending shift register starts to shift to the right under the control of the transmitter below, and sends the data to the TX pin bit by bit (shifting to the right is consistent with the low bit first specified by the serial port).


The lower part of the figure is mainly the control section and enhancements. Hardware data flow control , also called hardware flow control, referred to as flow control, as introduced before, the pin nRTS (request to send) is a request to send, which is an output pin, and the CTS connected to the external device is used to tell the external device whether it can now Receive; pin nCTS (clear to send) is clear to send, is an input pin, connected to the RTS of the external device is used to receive other people's nRTS signal, check whether others can receive it (that is, the other party is also required to have a flow control pin) . "n" means active low. (Generally not needed, let’s find out)
SCLK control and SCLK are used to generate synchronous clock signals, which cooperate with the output of the sending shift register. Every time the sending register is shifted, the level of the synchronous clock jumps for one cycle, and the clock tells the other party I One bit of data has been shifted out, and only supports output but not input, so synchronous serial communication cannot be realized between two USARTs. Its first purpose is to be compatible with other protocols . For example, the serial port with a clock is very similar to the SPI protocol. The serial port with the clock output can be compatible with SPI; this clock can also be used for adaptive baud rate , such as the receiving device does not To determine the baud rate given by the sending device, you can measure the clock cycle to calculate the baud rate (generally not used, understand it)
and wake up the unit , which is to realize the serial port to mount multiple devices. I said before that the serial port is generally point-to-point communication (only two devices are supported, just send and receive data directly), while multi-device communication can connect multiple slave devices on one bus, each device is assigned an address, and the communication must be addressed first. Communication object, and then send and receive data. The wake-up unit can enable it to obtain this function. Assign an address to the serial port at the USART address. When the specified address is sent, the device wakes up and starts working. When sending other device addresses, other devices work, and the device that does not receive the address does not wake up. remain silent. (Generally not needed, find out)


Interrupt (output) control , the application interrupt bit is the various flag bits of the status register SR, among which the TXE sending register is empty and the RXNE receiving register is not empty is more important and necessary. Interrupt control is to configure whether interrupts can lead to NVIC.
The bottom part is the baud rate generator . The baud rate generator is actually a frequency divider. The APB clock is divided to obtain the shifted clock for sending and receiving. The clock input is fPCLKx (x=1 or 2), USART1 is mounted on APB2 so it is the PCLK2 clock, generally 72MHz; other USARTs are mounted on APB1, which is the clock of PCLK1, generally 36MHz. The clock is divided by a USARTDIV frequency division coefficient for frequency division. USARTDIV is a value in the dashed box, which is divided into DIV_Mantissa integer part and DIV_Fraction fractional part, and the frequency division is more accurate.
After the frequency division, divide by 16 to get the transmitter clock and receiver clock, which lead to the transmitter and receiver control section. If TE (TX Enable) is 1, the transmitter is enabled, the baud rate of the sending part is valid, if RE (RX Enable) is 1, the receiver is enabled, and the baud rate of the receiving part is valid.


The rest are some register indications, such as which bit of each CR control register controls which part of the circuit, which flag bits of the SR status register, etc., can refer to the introduction of the registers in the chip manual.
After simplifying the block diagram, the blogger of Jiangke University Self-Chemical Association obtained the following basic structure :
insert image description here


3. Details

1. Data frame

insert image description here
The clock wave under the data frame is the function of the synchronous clock output mentioned earlier. There is a clock rising edge in the middle of each data bit. The clock frequency is the same as the data rate. The receiving end can sample at the rising edge of the clock, so that Each bit of data can be precisely positioned. The last bit of the clock (dotted line) can be controlled by the LBCL bit to output or not. The polarity and phase of the clock can also be configured through the configuration register.


The idle frame is 1 from the beginning to the end, and the disconnection frame is 0 from the beginning to the end. They are used in the LAN protocol, and the serial port is not used. You can understand it.


The 8-bit word length can also be set with or without parity. Generally, no parity is selected in order to send complete bytes. The 9-bit word length is often selected with checksum.


insert image description here
The above are the waveform changes of different stop bits. The STM32 serial port can be configured with stop bit lengths of 0.5, 1, 1.5, and 2. The essence is that the duration is different. Generally choose 1.


2. Enter data strategy

The output TX of the serial port is much simpler than the input RX, and the output will periodically flip the high and low levels of the TX pin; but the input must ensure that the sampling frequency is consistent with the baud rate, and the position of each input sampling must be exactly at the correct position of each bit. In the middle, the level read in this way is the most reliable. In addition, the input must have a certain ability to judge noise. If it is noise, it is best to set a flag to remind it.

(1) Start bit detection

insert image description here
When the input circuit detects the start bit of a data frame, it will continuously sample a frame of data at the baud rate. At the same time, starting from the start bit, the sampling position must be aligned to the middle of the bit. After alignment, it must be aligned.


First of all, the input circuit subdivides the sampling clock, and will sample at 16 times the baud rate, that is, 16 samples are performed in 1 bit time . The strategy is that the idle state is high at the beginning, then the sampling is always 1, and a sudden sampling of 0 at a certain position indicates that there is a falling edge between two samplings. If there is no noise, then it should be the start bit. , 16 consecutive samples will be taken at the start bit, and if there is no noise, 16 times will be 0.
In fact, there will be noise , so even if there is a falling edge, it needs to be sampled several times later, just in case, according to the manual, the receiving circuit will also perform a batch of sampling for the third, fifth, and seventh times after the falling edge appears. At the 8th, 9th, and 10th time, a batch of samples will be taken again, and these two batches of samples must have at least 2 0s in every three bits (as shown in the figure) before the start bit is detected. If the three bits are 0, then there is no noise, and the start bit is detected; if there are two 0 , the start bit is also detected, but a NE (Noise Error) noise flag bit will be set in the status register for The reminder data is received but has noise, so pay attention when using it; if there is only one 0 in the three bits , it is not counted as the detection of the start bit, and the falling edge is captured again.
If the start bit detection is passed, the receiving state changes from idle to receiving the start bit, and the positions of the 8th, 9th, and 10th samples are exactly in the middle of the start bit , and when receiving data bits, they are all at the Sampling is performed 8, 9, and 10 times to ensure that it is in the middle.


(2) Data sampling

insert image description here
From 1 to 16 is the time length of a data bit, that is, a data bit has 16 sampling clocks. Since the start bit detection has been aligned with the sampling clock, the data bits are directly sampled at the 8th, 9th, and 10th times here. In order to ensure data reliability, three consecutive samples (8, 9, 10), if there is no noise, the three times are 1 or 0, then it is considered to be 1 or 0; if there is noise, there are 0 in the 3 times There is also 1, according to the 2:1 rule, according to the occurrence of 2 times, in this case the NE noise flag will also be set to 1.


3. Baud rate generator

The detailed explanation of the above block diagram is also learned.
insert image description here

The baud rate of the transmitter and receiver is determined by the DIV in the baud rate register BRR (integer and fractional parts), the calculation formula : baud rate = f PCLK2/1 / (16 * DIV), if not divided by 16 For the sample clock mentioned above, it is 16 times the baud rate, so divide by 16.
For example, if you want to configure the USART with a baud rate of 9600 , then the configuration of the BRR register is: Substituting the formula 9600=72M/(16xDIV), the solution is DIV=468.75, and the binary number is 111010100.11, so the integer part of the DIV is written to 111010100 (before Zero-padded bits that are not full), and 11 is written in the fractional part of DIV (zero-padded bits that are not full). But it is very convenient to use library functions.


4. Expansion - USB to serial port module circuit diagram

insert image description here
The leftmost is the USB port , USB has four lines GND, D+, D-, VCC, the standard power supply is 5V, D+, D- is the communication line using the USB protocol, converted by the CH340 chip, the output after conversion is The TXD and RXD serial port protocols are led out to the 2nd and 3rd pins of CON6 through pin headers.
Power supply strategy , all electricity comes from VCC+5V (one pin of USB, usually plugged into the computer), and then VCC+5V is stepped down through the voltage regulator circuit to get VCC+3.3V, and then VCC+5V and VCC+ 3.3V is led out through pin headers to the 4th and 6th pins as voltage output pins, and the 5th pin is led to CH340G_VCC, which is the power input pin of CH340. Generally, the pin headers of this module will have some jumper caps, and the jumper caps need to be inserted On pins 4 and 5, or pins 5 and 6 (choose 5V or 3.3V according to the power supply requirements of the microcontroller, as described in the text in the upper right corner). The actual wiring performance is:
insert image description here
more about the USART, see Chapter 25 of the chip manual!


4. Practical cases

1. Serial port sending

insert image description here
Note that first, there will be the following logo in the computer device manager. If the COM number appears and there is no exclamation mark in front of the icon, it means that the serial port driver is ok, otherwise you need to install the serial port driver: According to the pin definition table, PA9 is USART1_TX multiplexing
insert image description here
, PA10 is multiplexed for USART1_RX and cross-connected with USB TX and RX. When GPIO is initialized in the program, configure TX as multiplexed push-pull output, and configure RX as input mode. The input is not divided into ordinary input and multiplexed input. One line can only have one output, but it can have multiple inputs, so the input pin peripherals and GPIO can be used at the same time. Generally, RX is configured as a floating input or a pull-up input. .

//Serial.c
#include "stm32f10x.h"                  // Device header
//老样子根据基本结构图打通:
//1、开启时钟,打开USART和GPIO时钟都打开
//2、GPIO初始化,把TX配置成复用输出,RX配置为输入(本代码没用到接收功能)
//3、配置USART,使用一个结构体即可配置所有相关参数
//4、如果只需要发送功能,直接开启USART初始化就结束了
//(5、如果需要接收功能,可能需要配置中断,在开启USART之前加上ITConfig和NVIC的代码就行)
//初始化完成后,如果需要发送数据调用一个发送函数就行,接收数据同理,如果要获取发送和接收标志位也是调用一个函数
void Serial_Init(void){
    
    
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//USART1为APB2总线上的外设
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP ;//复用推挽输出模式
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;//供串口外设TX脚使用
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	USART_InitTypeDef USART_InitStructure;
	USART_InitStructure.USART_BaudRate= 9600;//Init函数内部会自动计算需要的分频系数写入BRR寄存器
	USART_InitStructure.USART_HardwareFlowControl= USART_HardwareFlowControl_None;//无流控
	USART_InitStructure.USART_Mode= USART_Mode_Tx;//输出发送
	USART_InitStructure.USART_Parity= USART_Parity_No;//Odd奇、Even偶、No无校验
	USART_InitStructure.USART_StopBits= USART_StopBits_1;//停止位长度
	USART_InitStructure.USART_WordLength= USART_WordLength_8b;//字长8位
	USART_Init(USART1,&USART_InitStructure);
	
	USART_Cmd(USART1,ENABLE);
}

void Serial_SendByte(uint8_t Byte){
    
    
	USART_SendData(USART1,Byte);
	while (USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);//等待置1
	//该标志位不需要手动清零,下一次SendData这个标志位会自动清零
}

void Serial_SendArray(uint8_t* Array,uint16_t Length){
    
    
	//第一个参数为uint8_t*类型指向数组首地址,传递数组需要用到指针
	//第二个参数由于数组无法判断是否结束,用Length
	uint16_t i;
	for(i=0;i<Length;i++){
    
    
		Serial_SendByte(Array[i]);
	}
}

void Serial_SendString(char* String){
    
    //uint8_t也可以,由于字符串自带结束标志位0,不用Length了
	uint8_t i;
    for(i=0;String[i] != '\0';i++){
    
    //可以把字符串当作一个数组
		Serial_SendByte(String[i]);
	}
	
}

uint32_t Serial_Pow(uint32_t X,uint32_t Y){
    
    //次方函数X**Y
	uint32_t Result = 1;
	while(Y--){
    
    
		Result *= X;
	}
	return Result;
}
void Serial_SendNumer(uint32_t Number,uint8_t Length){
    
    
	//首先要把需要发送的Number的个位、十位、百位、千位等每一位以十进制拆分开
	//然后转换为字符数字对应的数据,依次发送出去
	//以十进制拆分:比如一个数字为1234,取千位1:1234/10**3=1.234;1.234%10=1
	uint8_t i;
	for(i=0;i<Length;i++){
    
    
		Serial_SendByte(Number/Serial_Pow(10,Length-i-1)%10+0x30);
		//之所以是Length-i-1是因为从高位开始取的(如1234依次取千位、百位、十位、个位依次发送)
		//之所以+0x30是因为要用字符(文本)显示,ASCII码表里字符0对应0x30。其实也可写成+'0'
	}
	
}

//main.c
#include "stm32f10x.h"   // Device header
#include "Delay.h"   
#include "OLED.h"
#include "Serial.h"

int main(void){
    
    
	OLED_Init();
	Serial_Init();
	Serial_SendByte(0x22);
	//程序的逻辑是上电后,初始化串口,再利用STM32串口发送一个0x22。
	//调用Serial_SendByte(0x22)后TX引脚会产生一个0x22对应的波形,这个波形可以发送给其他支持串口的模块
	//这里使用USB转串口模块发送给电脑端,需要一个串口助手软件查看
	
	uint8_t MyArray[]={
    
    0x42,0x43,0x44,0x45};
	Serial_SendArray(MyArray,4);
	
	Serial_SendString("Hello world!\n");
	
	Serial_SendNumer(1234 , 4);
	
	while(1){
    
    
		
	}
}
//拓:可深入学习下指针、字符数组、可变参数等内容
//sprintf是少有的含有可变参数的函数,有兴趣可搜索C语言可变参数

In the serial port assistant software, if the receiving mode is selected as HEX mode, it will be displayed in the form of raw data, such as sending 0x41, it will be displayed as 41; if you want to display a character string, you can select text mode, and it will be displayed in character form, such as sending 0x41, it will be displayed as A.
HEX mode is also called hexadecimal mode or binary mode, which is displayed in raw data and can only display one hexadecimal number;
text mode is also called character mode, where the character set is encoded into a character through raw data, such as ASCII code The table is the simplest character set. If you want to display and store Chinese characters, you need a Chinese character set , such as GB2312, GBK, GB18030, etc. In order to standardize the character sets of different countries, the Unicode character set has emerged , and the most commonly used transmission form of Unicode is UTF8 .
0x41 to A is called decoding, and A to 0x41 is called encoding.


2. Serial port send + receive

The hardware circuit wiring diagram is the same as the previous one, the receiving part is emphasized in the code, and the points with comments are the differences (this code currently only supports sending one byte):

//Serial.c
#include "stm32f10x.h"   

uint8_t Serial_RxData;//多
uint8_t Serial_RxFlag;//多

void Serial_Init(void){
    
    
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP ;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ;//上拉输入
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//多
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//多
	GPIO_Init(GPIOA,&GPIO_InitStructure);//多
	
	USART_InitTypeDef USART_InitStructure;
	USART_InitStructure.USART_BaudRate= 9600;
	USART_InitStructure.USART_HardwareFlowControl= USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode= USART_Mode_Tx |USART_Mode_Rx;//不同
	USART_InitStructure.USART_Parity= USART_Parity_No;
	USART_InitStructure.USART_StopBits= USART_StopBits_1;
	USART_InitStructure.USART_WordLength= USART_WordLength_8b;
	USART_Init(USART1,&USART_InitStructure);
	
	//对于串口接收可使用查询和中断两种方法,如果使用查询到此初始化就结束
	//查询流程:在主函数里不断判断RXNE标志位,置1说明收到数据了,
	          //再调用USART_ReceiveData读取DR(与上面的Serial_SendByte类似)
	//下面我们程序中实现下中断的方法:
	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//开启RXNE标志位到NVIC的输出
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//NVIC分组
	
	NVIC_InitTypeDef NVIC_InitStructure;//多
	NVIC_InitStructure.NVIC_IRQChannel= USART1_IRQn;//多
	NVIC_InitStructure.NVIC_IRQChannelCmd= ENABLE;//多
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= 1;//多
	NVIC_InitStructure.NVIC_IRQChannelSubPriority= 1;//多
	NVIC_Init(&NVIC_InitStructure);//初始化NVIC的USART通道
	
	USART_Cmd(USART1,ENABLE);
}

void Serial_SendByte(uint8_t Byte){
    
    
	USART_SendData(USART1,Byte);
	while (USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
	
}

void Serial_SendArray(uint8_t* Array,uint16_t Length){
    
    
	uint16_t i;
	for(i=0;i<Length;i++){
    
    
		Serial_SendByte(Array[i]);
	}
}

void Serial_SendString(char* String){
    
    
	uint8_t i;
    for(i=0;String[i] != '\0';i++){
    
    
		Serial_SendByte(String[i]);
	}
	
}

uint32_t Serial_Pow(uint32_t X,uint32_t Y){
    
    
	uint32_t Result = 1;
	while(Y--){
    
    
		Result *= X;
	}
	return Result;
}
void Serial_SendNumer(uint32_t Number,uint8_t Length){
    
    
	uint8_t i;
	for(i=0;i<Length;i++){
    
    
		Serial_SendByte(Number/Serial_Pow(10,Length-i-1)%10+0x30);
	}
	
}


//RXNE标志位一但置1,就会向NVIC申请中断,之后就会在中断函数里接收数据
//其实就是在中断里面对数据进行了一次转存,最终还要扫描查询RxFlag来接收数据
//放在这里转运一个字节意义看着不大,但是为下节多字节数据包接收作铺垫
void USART1_IRQHandler(void){
    
    //中断函数名是固定的
	if (USART_GetFlagStatus(USART1,USART_IT_RXNE)==SET){
    
    
		Serial_RxData= USART_ReceiveData(USART1);
		Serial_RxFlag= 1;
		USART_ClearITPendingBit(USART1,USART_IT_RXNE);
		//标志位,如果读取了DR就会自动清零,如果没读取DR,就需要手动清零。这里清零下也不影响
	}
}

uint8_t Serial_GetRxFlag(void){
    
    //实现读后自动清除功能
	if(Serial_RxFlag == 1){
    
    
		Serial_RxFlag=0;
		return 1;
	}
	return 0;
}
uint8_t Serial_GetRxData(void){
    
    //封装接收数据函数
	return Serial_RxData;
}

//main.c
#include "stm32f10x.h"   
#include "Delay.h"   
#include "OLED.h"
#include "Serial.h"

uint8_t RxData;

int main(void){
    
    
	OLED_Init();
	OLED_ShowString(1,1,"RxData:");
	
	Serial_Init();
	
	while(1){
    
    
		if (Serial_GetRxFlag()==1){
    
    
			RxData =Serial_GetRxData();//接收数据
			Serial_SendByte(RxData);//把接受到的这一数据回传到电脑
			OLED_ShowHexNum(1,8,RxData,2);
		}
		
	}
}


Summarize

When you encounter setbacks, you must have the courage to move forward, act immediately, stick to the end, and never give up. Those who succeed will never give up, and those who give up will never succeed. On the road to success, there will definitely be failures; for failures, we must treat and treat them correctly, those who are not afraid of failures will surely succeed; those who are afraid of failures will be useless and will fail even more.
This is the end of today's learning sharing, see you next time! !
insert image description herePrevious highlights:
STM32 timer input capture (IC)
STM32 timer output comparison (PWM wave)
STM32 timing interrupt
STM32 external interrupt
STM32GPIO intensive talk
...

Guess you like

Origin blog.csdn.net/weixin_51658186/article/details/129770790