当前位置:网站首页>STM32 Hal serial port (uart/usart) debugging experience (I) -- basic knowledge of serial port communication +hal library code understanding
STM32 Hal serial port (uart/usart) debugging experience (I) -- basic knowledge of serial port communication +hal library code understanding
2022-07-27 04:55:00 【Restar_ xt】
STM32 HAL Library serial port (UART/USART) Commissioning experience ( One )—— Basic knowledge of serial communication +HAL Library code understanding
Written by Restar_xt
at UESTC LIREN_B 303
For reference only to the class.4 in the College of Optoelectronic Science and Engineering of UESTC
Catalog
- STM32 HAL Library serial port (UART/USART) Commissioning experience ( One )—— Basic knowledge of serial communication +HAL Library code understanding
( One )Serial communication protocol( Serial communication protocol ) summary
Communication protocol
Generally speaking, communication refers to the sending and receiving of data , When it comes to sending and receiving data, it inevitably involves how to receive 、 How to send 、 When to start sending 、 When to start collecting , So engineers introduced a regulation —— Communication protocol , This set of regulations is mainly composed of three parts :
1. grammar : The format of data transmission 、 Coding form . Level high and low ( Logic signals ).
2. semantics : Content of communication , Is the information transmitted , for example : Control information (stm32 Commonly used Bluetooth /ESP32 Realize the communication between mobile phone and MCU , for example : Transmit a variable value with Bluetooth ,stm32 After receiving the variable, execute the corresponding task , The common one is switch-case Match variable values , Then execute the corresponding statement ).
3. sequential : It mainly specifies when data will be received 、 When to send and the rate of communication .
serial communication
In modern computer communication , Almost all communication is serial communication , What is serial ?
Serial and parallel It is two data transmission methods in communication , The two are fundamentally different .
Serial Refer to : Only one signal can be transmitted at a time, and one signal line is used , One byte (1 byte) Send data out one byte . Each bit of data can only be sent after the previous bit is sent .
parallel Refer to : Multiple signals can be transmitted at the same time , Each signal occupies a signal line , Each bit of data is transmitted at the same time .
ps: Here we can associate resistors in series and in parallel , In a series resistor network, current flows through each resistor in turn , In the parallel resistor network , Current flows through each resistor at the same time .
Take the following example as the carrier , Compare the two communication modes .
transmission 1 byte (8 position ,1byte=8bit) Data time , Parallel communication requires 8 Data line , Time consuming 1T; Serial communication has only one data line , delivery 8bit Data takes time 8T.
Serial : Communication efficiency is low , But the requirements for signal lines are low , Strong anti-interference ability , At the same time, the cost is relatively low , Generally used with computers and external devices , Or long-distance data transmission .
parallel : Communication efficiency is high , But the requirements for signal lines are also very high , It is generally used for parallel communication between fast devices , for example CPU And storage devices 、 Memory and memory 、 The host and printer adopt parallel communication .
According to the different ways of synchronous data sending and receiving in serial communication , Serial communication mode is divided into Synchronous serial and Asynchronous serial .
Asynchronous serial
use Fixed communication format , The data is transmitted in the same frame format . Each frame consists of Start bit 、 Data bits 、 Parity bit and Stop bit form .(ps: For the introduction of start bits, etc., see the following STM32CubeMX Configuration part )
When the device starts sending data , The device sends a logic first 0 As a sign that data transmission is about to start , When the receiver receives 0 The corresponding channel will be opened for data reception , In the logical 0 After the signal is the data to be transmitted , When the transmission is completed, the sender will send a logic 1 The signal , When the receiving end receives logic 1 Signal will stop receiving data , In this way, the transmission and reception of a frame of data have been completed .(ps: If a frame of data is not sent immediately after sending it , Then the logic on the signal line 1 The signal will remain , Indicates that the line is idle , The understanding of idle here will contribute to the understanding of subsequent idle interrupts )
Synchronous serial ( S P I SPI SPI、 I 2 C I^2C I2C)
In synchronous communication , Both sides of the communication Share a clock , This is the most remarkable feature that distinguishes synchronous communication from asynchronous communication . In asynchronous communication , Each character should use the start and stop bits as the marks of the beginning and end of the character , That takes up time . So when the data block is transmitted , To improve communication speed , Often remove these signs , Synchronous communication is adopted . In synchronous communication , Before data transmission starts, it is indicated by synchronous characters ( It is often agreed that 1~2 individual ), The synchronization between the sending end and the receiving end is realized by the clock , That is, after detecting the specified synchronization character , Next, the data is transmitted in sequence , Until a piece of data is transmitted . During synchronous transmission , There is no gap between characters , Also don't start and stop bits , Use sync characters only at the beginning of the data SYNC To instruct ,, Synchronous communication will not be repeated here , The detailed knowledge of synchronous communication will be in S P I SPI SPI、 I 2 C I^2C I2C Introduced in .
( Two )STM32 Serial communication experiment ——HAL library (Hardware Abstraction Layer) Code understanding
ps:HAL library (Hardware Abstraction Layer) design idea :HAL The basic design purpose of the layer is that the upper software can be accessed through the general interface MCU Some resources of , Instead of caring about “ Which is MCU”/“MCU Which part ” What we're doing , Blur the bottom function implementation .HAL See STM32_HAL_SUMMARY_NOTE
2.1 Serial port handle
stay uart.c You can see the following code in , The two lines of code represent uart1 The handle of 、uart2 The handle of . What is a handle ? For timers (TIMER)、 A serial port (UART) And analog-to-digital converter (ADC) And other peripherals with complex functions ,HAL The library designs a data type called peripheral handle PPP_HandleTypeDef(PPP Represents the name of the peripheral ). The peripheral handle is used as an identifier of the peripheral , It is generally used Structure Type implementation , The member variables of the structure correspond to the working parameters of the peripheral .
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
UART_HandleTypeDef huart1;
UART_HandleTypeDef huart2;
/* USART1 init function */
stay keil Right click UART_HandleTypeDef, Click on Go To Definition, Jump to stm32fxxx_hal_uart_h file , You can see the following code .
typedef struct __UART_HandleTypeDef
{
USART_TypeDef *Instance; /*!< UART registers base address */
UART_InitTypeDef Init; /*!< UART communication parameters */
uint8_t *pTxBuffPtr; /*!< Pointer to UART Tx transfer Buffer */
uint16_t TxXferSize; /*!< UART Tx Transfer size */
__IO uint16_t TxXferCount; /*!< UART Tx Transfer Counter */
uint8_t *pRxBuffPtr; /*!< Pointer to UART Rx transfer Buffer */
uint16_t RxXferSize; /*!< UART Rx Transfer size */
__IO uint16_t RxXferCount; /*!< UART Rx Transfer Counter */
__IO HAL_UART_RxTypeTypeDef ReceptionType; /*!< Type of ongoing reception */
DMA_HandleTypeDef *hdmatx; /*!< UART Tx DMA Handle parameters */
DMA_HandleTypeDef *hdmarx; /*!< UART Rx DMA Handle parameters */
HAL_LockTypeDef Lock; /*!< Locking object */
__IO HAL_UART_StateTypeDef gState; /*!< UART state information related to global Handle management and also related to Tx operations. This parameter can be a value of @ref HAL_UART_StateTypeDef */
__IO HAL_UART_StateTypeDef RxState; /*!< UART state information related to Rx operations. This parameter can be a value of @ref HAL_UART_StateTypeDef */
__IO uint32_t ErrorCode; /*!< UART Error code */
} UART_HandleTypeDef;
It's not hard to find out , This code is of type __UART_HandleTypeDef, An alias for UART_HandleTypeDef Definition of the structure of !
We might as well look at the two lines of code of serial port handle :
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
UART_HandleTypeDef huart1;
UART_HandleTypeDef huart2;
/* USART1 init function */
The first line means : be known as huart1 Of 、 The type is UART_HandleTypeDef A structure of type
The second line says : be known as huart2 Of 、 The type is UART_HandleTypeDef A structure of type
Believe it here , Everyone to HAL The library designs a data type called peripheral handle PPP_HandleTypeDef(PPP Represents the name of the peripheral ). The peripheral handle is used as an identifier of the peripheral , Generally, the structure type is used to realize , The member variables of the structure correspond to the working parameters of the peripheral This sentence has been understood clearly . Next, we analyze the serial port handle code line by line .
2.1.1 Serial port instance :
USART_TypeDef *Instance; /*!< UART registers base address */
Here we rewrite the code as follows for better understanding :
USART_TypeDef* Instance; /*!< UART registers base address */
Simply read the code Instance yes USART_TypeDef Pointer variables of this type of structure , Be sure to pay attention to the nesting relationship of the structure here !
<1> First, the outermost structure —— Handle structure :UART_HandleTypeDef
<2> Secondly, a pointer variable is set separately in the handle structure Instance, Point to another structure :USART_TypeDef
So in other words Each serial port handle corresponds to a USART_TypeDef Structure !
according to HAL Comments on the library , You can know Instance Actually, it points to uart The base address of the register group , It is not difficult to guess that this is called USART_TypeDef The member variables of the structure of are actually register groups . Right click USART_TypeDef, Click on Go To Definition Jump to stm32fxxxxb.h You can see the following code :
typedef struct
{
__IO uint32_t SR; /*!< USART Status register, Address offset: 0x00 */
__IO uint32_t DR; /*!< USART Data register, Address offset: 0x04 */
__IO uint32_t BRR; /*!< USART Baud rate register, Address offset: 0x08 */
__IO uint32_t CR1; /*!< USART Control register 1, Address offset: 0x0C */
__IO uint32_t CR2; /*!< USART Control register 2, Address offset: 0x10 */
__IO uint32_t CR3; /*!< USART Control register 3, Address offset: 0x14 */
__IO uint32_t GTPR; /*!< USART Guard time and prescaler register, Address offset: 0x18 */
} USART_TypeDef;
Reading the above code is not difficult to verify our conjecture , This structure is uart Register group configuration , Such as :SR(Status register Status register ),DR(Date register Data register ),BRR(Baud rate register Baud rate register ) wait , This also provides instructions for us to directly operate registers , For details of these registers, please refer to the corresponding data sheet. So this pointer variable Instance What's the use ? Please think about where we met instance Well ? That's right in uart.c In the document MX_USARTx_UART_Init(void) Yes , To deepen the impression , Paste here MX_USARTx_UART_Init(void) Complete code for :
void MX_USART1_UART_Init(void)
{
/* USER CODE BEGIN USART1_Init 0 */
/* USER CODE END USART1_Init 0 */
/* USER CODE BEGIN USART1_Init 1 */
/* USER CODE END USART1_Init 1 */
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)
{
Error_Handler();
}
Here we only look at huart1.Instance = USART1; This line of code , First and foremost huart1.Instance It represents the structure huart1 Member variables in Instance, Some students may ask this huart1 Where is the structure of defined ? Actually huart1 This structure is serial port 1 Defined by the handle of !->>UART_HandleTypeDef huart1;( The handle is actually called huart1 Of UART_HandleTypeDef Type structure ) So here comes the question , Why? Instance This member variable is equal to USART1 Well ?
To solve this problem , stay keil Right click USART1, Click on Go To Definition You can see the following code :
#define USART1 ((USART_TypeDef *)USART1_BASE)
original USART1 Is a macro ! And this macro will USART1_BASE( Constant ) Cast to USART_TypeDef Type structure pointer , What does it mean to cast a constant to a structure pointer ? The constant is forcibly converted to a structure pointer , This constant is the starting address of the structure . in other words USART1_BASE Be coerced into USART_TypeDef From , Memory space will be in USART_TypeDef Type , The first address is USART1_BASE, There are members in the space , Allocate memory space in order of its inherent types .
So there is huart1.Instance = ((USART_TypeDef *)USART1_BASE)
and Instance again USART_TypeDef Pointer to structure
Then the logic of the whole analysis is like this :
1. We are cubeMX Configure the serial port in 1 after , Automatically generate serial port handle of serial port one UART_HandleTypeDef huart1;, Its essence is to automatically create a named huart1 Of UART_HandleTypeDef Type structure
2. This huart1 The first member variable of a structure Instance It's a USART_TypeDef Type structure type pointer (USART_TypeDef*)Instance; ( Here is structure nesting ,UART_HandleTypeDef The member variable of is USART_TypeDef The pointer to , In this way UART_HandleTypeDef Type structure nested USART_TypeDef Type structure )
3. On the serial port 1 Abstract initialization of MX_USART1_UART_Init(void) Lieutenant general huart1 In the structure Instance This member variable is assigned USART1 This macro huart1.Instance = USART1;, And this macro is USART_TypeDef The first address of type structure #define USART1 ((USART_TypeDef *)USART1_BASE), That is to say huart1.Instance = ((USART_TypeDef *)USART1_BASE) Realized huart1 Nested in a structure USART_TypeDef The first address assignment of the structure !
4. because USART_TypeDef Structure member variables are serial port register groups , that Instance As the base address of the whole register group , You can go through Instance To access the underlying register set ! In other words, it realizes serial port 1 Register group address allocation !
Serial port instance , Mainly the definition of serial port register base address , Used to access hardware registers . The way to do it is : First, package all the registers used by the serial port into one USART_TypeDef Type of structure , Then convert the first address of the serial port peripheral into the pointer of the structure type , Then according to the structure pointer + Member variables ( Base address + Offset ) To access the underlying registers .
example :UART1 -> SR // Access serial port 1 SR register
About peripheral register address allocation ,STM32 The logic is as follows :( Still with UART1 For example )
The following code is stm32f103xb.h file
#define PERIPH_BASE 0x40000000UL /*!< Peripheral base address in the alias region */
// First defined PERIPH_BASE—— On chip peripheral base address
/*!< Peripheral memory map */( Peripheral memory mapping )
#define APB1PERIPH_BASE PERIPH_BASE
#define APB2PERIPH_BASE (PERIPH_BASE + 0x00010000UL)
#define AHBPERIPH_BASE (PERIPH_BASE + 0x00020000UL)
// And then PERIPH_BASE Add the address offset of each bus on , obtain APB1 、APB2 The address of the bus APB1PERIPH_BASE 、APB2PERIPH_BASE—— Bus base address
——————————————————————————————————————————————————————————————————
#define TIM2_BASE (APB1PERIPH_BASE + 0x00000000UL)
#define TIM3_BASE (APB1PERIPH_BASE + 0x00000400UL)
#define TIM4_BASE (APB1PERIPH_BASE + 0x00000800UL)
#define RTC_BASE (APB1PERIPH_BASE + 0x00002800UL)
#define WWDG_BASE (APB1PERIPH_BASE + 0x00002C00UL)
#define IWDG_BASE (APB1PERIPH_BASE + 0x00003000UL)
#define SPI2_BASE (APB1PERIPH_BASE + 0x00003800UL)
#define USART2_BASE (APB1PERIPH_BASE + 0x00004400UL)
#define USART3_BASE (APB1PERIPH_BASE + 0x00004800UL)
// Then add the address offset of each peripheral on each bus —— Specific peripheral base address
——————————————————————————————————————————————————————————————————
#define TIM2 ((TIM_TypeDef *)TIM2_BASE)
#define TIM3 ((TIM_TypeDef *)TIM3_BASE)
#define TIM4 ((TIM_TypeDef *)TIM4_BASE)
#define RTC ((RTC_TypeDef *)RTC_BASE)
#define WWDG ((WWDG_TypeDef *)WWDG_BASE)
#define IWDG ((IWDG_TypeDef *)IWDG_BASE)
#define SPI2 ((SPI_TypeDef *)SPI2_BASE)
#define USART2 ((USART_TypeDef *)USART2_BASE)
#define USART3 ((USART_TypeDef *)USART3_BASE)
#define I2C1 ((I2C_TypeDef *)I2C1_BASE)
#define I2C2 ((I2C_TypeDef *)I2C2_BASE)
#define USB ((USB_TypeDef *)USB_BASE)
#define CAN1 ((CAN_TypeDef *)CAN1_BASE)
#define BKP ((BKP_TypeDef *)BKP_BASE)
#define PWR ((PWR_TypeDef *)PWR_BASE)
#define AFIO ((AFIO_TypeDef *)AFIO_BASE)
#define EXTI ((EXTI_TypeDef *)EXTI_BASE)
#define GPIOA ((GPIO_TypeDef *)GPIOA_BASE)
#define GPIOB ((GPIO_TypeDef *)GPIOB_BASE)
#define GPIOC ((GPIO_TypeDef *)GPIOC_BASE)
#define GPIOD ((GPIO_TypeDef *)GPIOD_BASE)
#define GPIOE ((GPIO_TypeDef *)GPIOE_BASE)
#define ADC1 ((ADC_TypeDef *)ADC1_BASE)
#define ADC2 ((ADC_TypeDef *)ADC2_BASE)
#define ADC12_COMMON ((ADC_Common_TypeDef *)ADC1_BASE)
#define TIM1 ((TIM_TypeDef *)TIM1_BASE)
#define SPI1 ((SPI_TypeDef *)SPI1_BASE)
#define USART1 ((USART_TypeDef *)USART1_BASE)
// Then the macro definition forces a typecast , Complete the cast conversion from constant to struct pointer
——————————————————————————————————————————————————————————————————
typedef struct
{
__IO uint32_t SR; /*!< USART Status register, Address offset: 0x00 */
__IO uint32_t DR; /*!< USART Data register, Address offset: 0x04 */
__IO uint32_t BRR; /*!< USART Baud rate register, Address offset: 0x08 */
__IO uint32_t CR1; /*!< USART Control register 1, Address offset: 0x0C */
__IO uint32_t CR2; /*!< USART Control register 2, Address offset: 0x10 */
__IO uint32_t CR3; /*!< USART Control register 3, Address offset: 0x14 */
__IO uint32_t GTPR; /*!< USART Guard time and prescaler register, Address offset: 0x18 */
} USART_TypeDef;
// Then, the serial port register group is encapsulated in the structure type , end !
——————————————————————————————————————————————————————————————————
Example : utilize C The syntax of language access member variables specifies access to register groups
The pointer + "->" + Member variable name
USART1 -> SR = 0xFFFF;
2.1.2 Serial port initialization parameter configuration :
UART_InitTypeDef Init; /*!< UART communication parameters */
See 2.2 Serial initialization .
2.1.3 The first address of the send data buffer :
uint8_t *pTxBuffPtr; /*!< Pointer to UART Tx transfer Buffer */
2.1.4 Number of data to be sent :
uint16_t TxXferSize; /*!< UART Tx Transfer size */
2.1.5 Send data counter :
__IO uint16_t TxXferCount; /*!< UART Tx Transfer Counter */
2.1.6 The first address of the receive data buffer :
uint8_t *pRxBuffPtr; /*!< Pointer to UART Rx transfer Buffer */
2.1.7 Number of data to be received :
uint16_t RxXferSize; /*!< UART Rx Transfer size */
2.1.8 Receive data counter :
__IO uint16_t RxXferCount; /*!< UART Rx Transfer Counter */
2.1.9 Ongoing data receiving mode :
__IO HAL_UART_RxTypeTypeDef ReceptionType; /*!< Type of ongoing reception */
ps: Here quote HAL Library notes
*@brief HAL UART Reception type definition
* @note HAL UART Reception type value aims to identify which type of Reception is ongoing.
* It is expected to admit following values :
* HAL_UART_RECEPTION_STANDARD = 0x00U,
* HAL_UART_RECEPTION_TOIDLE = 0x01U,
*/
2.1.10 DMA Send mode structure type pointer
DMA_HandleTypeDef *hdmatx; /*!< UART Tx DMA Handle parameters */
2.1.11 DMA Receive mode structure type pointer
DMA_HandleTypeDef *hdmarx; /*!< UART Rx DMA Handle parameters */
2.1.12 Protection lock type definition
HAL_LockTypeDef Lock; /*!< Locking object */
2.1.13 Serial port global + Send working status
__IO HAL_UART_StateTypeDef gState; /*!< UART state information related to global Handle management and also related to Tx operations. This parameter can be a value of @ref HAL_UART_StateTypeDef */
2.1.14 Serial port receiving working state
__IO HAL_UART_StateTypeDef RxState; /*!< UART state information related to Rx operations. This parameter can be a value of @ref HAL_UART_StateTypeDef */
2.1.15 Serial port error code
__IO uint32_t ErrorCode; /*!< UART Error code */parameters */
2.2 Serial initialization
Serial port initialization is mainly divided into two parts
@ Abstract initialization of serial port : Mainly refers to HAL The library abstracts the serial communication protocol , Such as baud rate 、 Parity bit 、 Start bit 、 Stop bit
@ Serial port load initialization : Mainly refers to HAL The library is located outside MCU Level resource allocation , For example, pin allocation and enabling 、 Clock distribution and enabling
The following two parts of initialization are introduced
@ Abstract initialization of serial port
stay STM32CubeMX+Keil Folders generated in the development environment Application/User/Core Open in uart.c File can see the following code :
void MX_USART1_UART_Init(void)
{
/* USER CODE BEGIN USART1_Init 0 */
/* USER CODE END USART1_Init 0 */
/* USER CODE BEGIN USART1_Init 1 */
/* USER CODE END USART1_Init 1 */
huart1.Instance = USART1; // USART1 example
huart1.Init.BaudRate = 115200; // Baud rate
huart1.Init.WordLength = UART_WORDLENGTH_8B; // Data frame word length
huart1.Init.StopBits = UART_STOPBITS_1; // Stop bit
huart1.Init.Parity = UART_PARITY_NONE; // Parity bit
huart1.Init.Mode = UART_MODE_TX_RX; // Receive and receive —— Full duplex mode
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; // Hardware flow control
huart1.Init.OverSampling = UART_OVERSAMPLING_16;// Oversampling
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART1_Init 2 */
/* USER CODE END USART1_Init 2 */
}
The code analysis
This part of the code is HAL Abstract initialization of serial port peripherals by Library , It mainly stipulates the communication protocol for serial communication , This part of communication protocol initialization will be analyzed separately below
huart1.Init.BaudRate = 115200;
Baud rate (BaudRate): In the information transmission channel , The signal unit carrying data information is called symbol , The number of symbols transmitted through the channel in a unit time is called the symbol transmission rate , Baud rate for short .
How to better understand the concept of baud rate ?
First of all, make it clear , Baud rate indicates the speed of information transmission , From the precise definition of baud rate , Baud rate describes the number of symbols transmitted through the channel in unit time , Also known as symbol transmission rate , So here comes the question —— What is a symbol ? Refer to the rigorous definition of symbols —— In digital communication, symbols with the same time interval are often used to represent a binary number , The signal in such a time interval is called ( Binary system ) Code element . So here comes the question , What are symbols ? Refer to the precise definition of symbols , We can see that the symbols here are not common + = - * / These mathematical symbols , The symbol here refers to A sinusoidal carrier wave used to represent a certain phase or amplitude value of a digital code type . Students who have not been exposed to the principle of communication must have learned that it must be in the clouds , So how to understand the concept of baud rate ? We can regard the symbol as a piece of carrying information ( Binary number ) Pulse signal of , That is to say, the symbol is regarded as the carrier of information , Code element ( Pulse signal ) Its amplitude 、 Features such as phase are the reflection of the information carried . for example : Specify the amplitude of a pulse signal as low (00)、 in (01)、 high (10)、 Extremely high (11) Four kinds of , Then when we receive a symbol and find that its amplitude is low , We receive the information it carries -00. So it can be seen that a binary symbol can carry 1byte(2bit) Information about , Since baud rate is the symbol transmission rate ( Symbol rate / Bit rate ), And the bit rate is the information transmission rate ( Signal transmission rate ), Then the baud rate ==1/2 Bit rate . There is a formula here I = S ∗ l o g 2 N I = S*log_2{N} I=S∗log2N I Representative baud rate ,N Represents the number of information bits carried by the symbol . If the baud rate 、 If the understanding of symbols is not complete , It can be understood in this way : A symbol is a wave ! This wave carries information , Baud rate refers to the propagation rate of waves ! That is, the number of waves received per unit time !
PS: This is just for the convenience of readers ! Examples are inappropriate
huart1.Init.WordLength = UART_WORDLENGTH_8B; // Data frame word length
Data frame word length (WordLength): It describes the real length of a frame of data during serial communication , The code shown above means that the length of a frame of data transmitted by the serial port is 8bit(1 byte), The protocol format of serial communication can be seen more intuitively from the following figure , Start bit (1bit)+ Data bits (8bit)+ Check bit (1bit)+ Stop bit (1bit)
huart1.Init.StopBits = UART_STOPBITS_1;
Stop bit (StopBits): It marks the end of serial communication , When the receiving end receives logic 1 Time indicates that the data acceptance of this frame is over
huart1.Init.Parity = UART_PARITY_NONE;
Parity bit (Parity): It is the simplest of many error checking methods
@ What is parity ?
as everyone knows , The most common error in the process of communication between two devices is that one of the data has a problem , For example, it should have been transmitted 01010101, But I received 01010100, So how to check the received information ? you 're right , The simplest is parity . The principle of parity check is after the original data to be transmitted (/ front ) Add a check bit . for example 01010101 For the data to be transmitted , If odd check is used , Then the sender should send 010101011, Why is the check digit 1 Well ( The red position is the added check digit )? Because odd check is odd check , That is to say, ensure the transmission Data bits + Check bit in 1 The number of is odd , Similarly, if even check is used , To ensure data bits + Check bit 1 The number of is even , Still with 01010101 For the data to be transmitted , Then in the case of even check, the actual transmission should be 010101010.
@ After knowing what parity is , So how does parity check detect data errors ?
Odd check 01010101 For example :
··· If there is no error in the data during transmission , Then the receiving end receives 010101011, After inspection, this group of data 1 The number of is odd , Then it proves that there is no error in the transmission of this group of data .
··· If data occurs during transmission 1 Bit error , That is, the data originally sent is 010101011 Turned into 010101111, The receiver received 010101111 Later, it was found that 1 The number of is even , Not an odd number ! It means that this group of data is wrong (ps: In general , The parity bit will not cause data errors , Only data bit errors are considered here )
··· If data occurs during transmission 2 Bit error , That is, the data originally sent is 010101011 Turned into 010111111, The receiver received 010101111 Later, it was found that 1 The number of is odd , According to the principle of parity check, this group of data is correct ??? Obviously, this is the drawback of parity ! Although parity check is simple , But the error rate is low !
huart1.Init.Mode = UART_MODE_TX_RX;
Communication mode (Mode): Receive and send ( full duplex )
@ Serial port load initialization
stay STM32CubeMX+Keil Folders generated in the development environment Application/User/Core Open in uart.c File can see the following code :
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {
0};
if(uartHandle->Instance==USART1)
{
/* USER CODE BEGIN USART1_MspInit 0 */
/* USER CODE END USART1_MspInit 0 */
/* USART1 clock enable */
__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/**USART1 GPIO Configuration PB6 ------> USART1_TX PB7 ------> USART1_RX */
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
__HAL_AFIO_REMAP_USART1_ENABLE();
/* USART1 interrupt Init */
HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);
/* USER CODE BEGIN USART1_MspInit 1 */
/* USER CODE END USART1_MspInit 1 */
}
else if(uartHandle->Instance==USART2)
{
/* USER CODE BEGIN USART2_MspInit 0 */
/* USER CODE END USART2_MspInit 0 */
/* USART2 clock enable */
__HAL_RCC_USART2_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**USART2 GPIO Configuration PA2 ------> USART2_TX PA3 ------> USART2_RX */
GPIO_InitStruct.Pin = GPIO_PIN_2;
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_3;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USART2 interrupt Init */
HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART2_IRQn);
/* USER CODE BEGIN USART2_MspInit 1 */
/* USER CODE END USART2_MspInit 1 */
}
}
It can be seen that this part is ST The company provides serial port peripherals MSP( The specific solution of single chip microcomputer ), Mainly IO Pin assignments 、 Interrupt priority allocation, etc
Any errors , it is respectful to have you criticize and correct sth !
About STM32 For register address allocation, see : Single chip microcomputer STM32 Detailed explanation of register mapping in learning notes
About HAL For the understanding of the library, please refer to :STM32_HAL_SUMMARY_NOTE
边栏推荐
- Understand kingbasees V9 in one picture
- [dynamic planning hundred questions strengthening plan] 11~20 (continuously updating)
- Unity:Resource Merging、Static Batching、Dynamic Batching、GPU Instancing
- RN开发系列<9>--Mobx(1)入门篇
- 【C语言】自定义类型详解(结构体+枚举+联合)
- HCIA static routing comprehensive experiment
- 如何将Photoshop图层复制到其他文档
- What is the difference between using varchar type and using date type for timestamp column?
- 使用Unity做一个艺术字系统
- [construction of independent stations] this website is the first choice for cross-border e-commerce companies to open online stores at sea!
猜你喜欢

Yolov4 network details

【C语言】动态内存管理

【C语言】自定义类型详解(结构体+枚举+联合)
![Shell中的文本处理工具、cut [选项参数] filename 说明:默认分隔符是制表符、awk [选项参数] ‘/pattern1/{action1}filename 、awk 的内置变量](/img/ed/941276a15d1c4ab67d397fb3286022.png)
Shell中的文本处理工具、cut [选项参数] filename 说明:默认分隔符是制表符、awk [选项参数] ‘/pattern1/{action1}filename 、awk 的内置变量

Summary of fire safety training materials
![[C language] detailed explanation of user-defined types (structure + enumeration + Union)](/img/d9/b10371159c63c126b5ff98bac0971a.png)
[C language] detailed explanation of user-defined types (structure + enumeration + Union)

CDH cluster integration external Flink (improved version - keep pace with the times)

Digital integrated circuit: MOS tube device chapter (I)

Explain left value, right value, left value reference and right value reference in detail

利用Power Automate,轻松下载Power BI报告中的数据
随机推荐
Photoshop提示暂存盘已满怎么办?ps暂存盘已满如何解决?
Title: there is an array that has been sorted in ascending order. Now enter a number and ask to insert it into the array according to the original rule.
Pinia入门到精通,Pinia使用全流程,包含state,actions,getters,以及如何解构,进行响应,actions使用的多种方法
The price reduction of iphone13 is just a show. Consumers are waiting for iphone14
Shell的正则表达式入门、常规匹配、特殊字符:^、$、.、*、字符区间(中括号):[ ]、特殊字符:\、匹配手机号
Photoshop裁剪工具隐藏技巧
JS day 2 (variables, variable usage, naming rules, syntax extensions)
安全第四次课后练习
CEPH operation
结构型模式-桥接模式
Shell programming enhancements
题目:有一个已经按升序排好序的数组。现输入一个数,要求按原来的规律将它插入数组中。
缓存读写策略:CacheAside、Read/WriteThrough及WriteBack策略
Unity:Resource Merging、Static Batching、Dynamic Batching、GPU Instancing
结构型模式-装饰者模式
如何做数据平滑迁移:双写方案
数字中国建设峰会闭幕,现场海量图片一览!
Two way republication experiment
Interesting C language
Bo Yun container cloud and Devops platform won the trusted cloud "technology best practice Award"