关于STM32的USART整理的全局函数 HAL_USART.C介绍 (2)

本文详细介绍串口通信的各种功能函数,包括结构体初始化、缓存清除、数据发送接收处理等,并提供具体的函数使用说明。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

函数及功能介绍:

/**
	* @brief	结构体公共部分初始化
	* @param[in]	
	* @retval  
	* 公共部分初始化为 0 或固定值的参数初始化,其余参数另行初始化
	*/
void USARTx_PublicInit(USARTx_BufferType *USARTx_Buffer)

/**
	* @brief	清除 结构体的接收/发送缓存及接收/发送标志
	* @param[in]	USART_Buffer 接收发送数据结构体
	* @param[in]	mode: 初始化模式 |0x01 初始化接收缓存区
	*                               |0x02 初始化发送缓存区
	*				|0x04 初始化接收长度
	*				|0x08 初始化发送长度
	* @retval  
	*/
void USARTx_BufferType_ResMark(USARTx_BufferType *USARTx_Buffer,u8 mode)
/**
	* @brief 中断发送串口字符
	* @param[i] USARTx: USART1..3 
	* @param[i] USARTx_Buffer  串口结构体
	* @retval
	* 函数使用说明:
	* 1、该函数调用在使用串口发送的函数中,把要发送的数据赋值给 USARTx_Buffer->sendbuff[] 数组,
	*	   把发送长度赋值给 USARTx_Buffer->send_size
	* 2、串口发送的方式采用发送完成产生中断,此函数中发送一次数据,产生一个串口发送完成中断,后续数据在串口中断函数中完成
	* 3、采用485传输时使 485CLK = 1(发送模式)
	* 4、UART4 采用DMA发送/或者普通发送 无法使用中断
	*/
bool USARTx_Protocol_Send(USART_TypeDef *USARTx,USARTx_BufferType *USARTx_Buffer)
/**
	* @brief 串口数据处理函数
	* @param USARTx_Buffer  串口结构体
	* response :TRUE 需要应答,FALSE 不需要应答	即回应数据
	* @retval 
	* 函数使用说明:
	* 1、先在 USARTx_StructInit() 函数中根据硬件及需求初始化对应的处理函数 USARTx_Buffer->Data_Processing = &(UOCS_Data_Processing);
	* 2、按照需求对 UOCS_Data_Processing() 函数进行修改
	* 3、在定时器中按照需求调用本函数 最长刷新时间 可根据波特率进行计算
	* T = 1s * 10bit / bps = 1000 * 10 /9600 (ms) = 1.0417 ms.
	* 4、采用DMA方式时 从DMA接收数组中循环检验数据。
	*/	
void USARTx_Data_Processing(USART_TypeDef *USARTx,USARTx_BufferType *USARTx_Buffer,bool response)

/**
	* @brief 串口中断接收处理函数 
	* @param 	USARTx x =1.2.3
	*		USARTx_Buffer 
	* @retval
	* 函数说明:应用在串口中断服务函数中,用于数据接收及数据处理 
	*/	
void USARTx_IRQ_Receive(USART_TypeDef *USARTx,USARTx_BufferType *USARTx_Buffer)
/**
	* @brief 串口中断发送处理函数
	* @param 	USARTx x =1.2.3
	*		USARTx_Buffer 
	* @retval
	* 函数说明:应用在串口中断服务函数中,用于数据发送,
	* 1、采用485传输时,在传输完成后设置485CLK = 0
	* 2、发送数据采用发送完成中断,
	*/	
void USARTx_IRQ_Send(USART_TypeDef *USARTx,USARTx_BufferType *USARTx_Buffer)
/**
	* @brief 串口 printf 打印函数
	* @param 	USARTx: USART1..3
	*		Send_Buff	要发送的字符串地址指针
	* @retval 
	* 函数说明:
	* 1、采用DMA方式发送 需要细分各个串口对应的DMA通道
	* 2、采用普通方式发送
	*/
void USARTx_Printf(USART_TypeDef *USARTx,USARTx_BufferType *USARTx_Buffer,char *fmt,...)
/**
	* @brief 串口 printf 打印函数 参数固定
	* @param 	USARTx: USART1..3
	*		Send_Buff	要发送的字符串地址指针
	* @retval 
	* 函数说明:
	* 1、采用DMA方式发送 需要细分各个串口对应的DMA通道
	* 2、采用普通方式发送
	*/
void USARTx_SendBuff(USART_TypeDef *USARTx,USARTx_BufferType *USARTx_Buffer)






<think>我们被要求结合STM32G0系列的HAL库(HAL_usart.c和HAL_USART.h)来讲解如何使用HAL函数操作USART寄存器。用户之前已经给出了一个USART_TypeDef结构体(可能是STM32G0系列中的定义),现在需要讲解如何用HAL库来配置和使用这些寄存器。 首先,回顾一下HAL库的基本设计思想:HAL库提供了一组抽象的函数接口,用于配置和控制外设,从而避免直接操作寄存器。这些函数内部会操作相应的寄存器,但用户无需关心具体寄存器地址和位操作。 在STM32G0的HAL库中,USART相关的函数主要位于`stm32g0xx_hal_usart.c`和头文件`stm32g0xx_hal_usart.h`中。我们针对用户提供的USART_TypeDef结构体中的寄存器,讲解如何使用HAL函数进行配置。 ### 1. HALUSART初始化流程 使用HAL库进行USART配置的基本步骤如下: 1. **定义USART初始化结构体**:`USART_InitTypeDef`,并设置相关参数(波特率、数据位、停止位、流控等)。 2. **调用初始化函数**:`HAL_USART_Init()`,该函数会根据初始化结构体配置USART寄存器。 3. **使能USART**:初始化函数内部会自动使能USART(设置US_CR寄存器的相应位)。 4. **使用中断或DMA(可选)**:如果需要使用中断或DMA,则需调用相应的函数进行配置。 ### 2. 关键HAL函数详解 #### 2.1 初始化函数:`HAL_USART_Init()` ```c HAL_StatusTypeDef HAL_USART_Init(USART_HandleTypeDef *husart); ``` - **参数**:`husart`是指向`USART_HandleTypeDef`结构体的指针,该结构体包含USART的配置信息。 - **功能**:根据`husart`中的配置初始化USART外设,包括波特率、数据位、停止位、校验位、硬件流控和收发模式等。 - **内部操作**:该函数会配置以下寄存器: - `US_BRGR`:波特率寄存器 - `US_MR`:模式寄存器(设置数据位、停止位、校验等) - `US_CR`:控制寄存器(使能收发器等) - 其他相关寄存器(如`US_RTOR`、`US_TTGR`等,根据配置) 示例代码: ```c USART_HandleTypeDef husart1; void USART1_Init(void) { husart1.Instance = USART1; // 选择USART1外设 husart1.Init.BaudRate = 115200; // 波特率115200 husart1.Init.WordLength = USART_WORDLENGTH_8B; // 8位数据位 husart1.Init.StopBits = USART_STOPBITS_1; // 1位停止位 husart1.Init.Parity = USART_PARITY_NONE; // 无校验 husart1.Init.Mode = USART_MODE_TX_RX; // 使能发送和接收 husart1.Init.CLKLastBit = USART_LASTBIT_DISABLE; // 最后一位时钟脉冲不输出 husart1.Init.CLKPolarity = USART_POLARITY_LOW; // 时钟极性低 husart1.Init.CLKPhase = USART_PHASE_1EDGE; // 时钟相位为第一个边沿 if (HAL_USART_Init(&husart1) != HAL_OK) { // 初始化错误处理 } } ``` #### 2.2 数据发送函数 - **阻塞发送**:`HAL_USART_Transmit()` ```c HAL_StatusTypeDef HAL_USART_Transmit(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size, uint32_t Timeout); ``` 该函数会阻塞直到数据发送完成或超时。内部通过轮询`US_CSR`寄存器的发送完成标志位(如TXE)来实现。 - **中断发送**:`HAL_USART_Transmit_IT()` ```c HAL_StatusTypeDef HAL_USART_Transmit_IT(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size); ``` 启动中断发送,发送完成后会调用发送完成回调函数`HAL_USART_TxCpltCallback()`。 - **DMA发送**:`HAL_USART_Transmit_DMA()` ```c HAL_StatusTypeDef HAL_USART_Transmit_DMA(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size); ``` 使用DMA发送数据,发送完成后会触发DMA中断,并调用相应的回调函数。 #### 2.3 数据接收函数 - **阻塞接收**:`HAL_USART_Receive()` ```c HAL_StatusTypeDef HAL_USART_Receive(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size, uint32_t Timeout); ``` - **中断接收**:`HAL_USART_Receive_IT()` ```c HAL_StatusTypeDef HAL_USART_Receive_IT(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size); ``` 启动中断接收,当接收到指定数量的数据后,会调用接收完成回调函数`HAL_USART_RxCpltCallback()`。 - **DMA接收**:`HAL_USART_Receive_DMA()` ```c HAL_StatusTypeDef HAL_USART_Receive_DMA(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size); ``` ### 3. 中断处理 HAL库为USART提供了统一的中断服务函数`HAL_USART_IRQHandler()`,该函数会处理所有USART中断事件(如发送完成、接收完成、错误中断等),并调用相应的回调函数。用户需要在中断服务函数中调用该函数。 例如,对于USART1中断: ```c void USART1_IRQHandler(void) { HAL_USART_IRQHandler(&husart1); } ``` ### 4. 回调函数 HAL库使用回调机制来通知应用程序事件完成。例如,当发送完成时,会调用`HAL_USART_TxCpltCallback()`。用户可以重写这些回调函数(通常是在主文件中定义)来实现自己的逻辑。 ```c void HAL_USART_TxCpltCallback(USART_HandleTypeDef *husart) { // 发送完成,可以启动下一次发送或其他操作 } ``` ### 5. 直接操作寄存器与HAL库的结合 虽然HAL库提供了抽象,但有时需要直接操作寄存器。例如,在HAL库初始化后,如果需要修改某个寄存器位(如`US_MAN`、`US_LINMR`等),可以直接通过`husart.Instance->REGISTER`来访问。 例如,设置LIN模式: ```c husart1.Instance->US_LINMR |= US_LINMR_LINEN; // 使能LIN模式 ``` > **注意**:直接操作寄存器时,应确保不会破坏HAL库维护的状态。 ### 6. HAL库与寄存器结构体的对应关系 HAL库中的`USART_HandleTypeDef`结构体有一个`Instance`成员,它指向USART外设的基地址(即`USART_TypeDef`类型)。因此,通过`husart1.Instance->US_CR`可以直接访问控制寄存器。 ### 总结 使用STM32G0的HAL库操作USART外设,主要步骤为: 1. 定义并配置`USART_HandleTypeDef`结构体。 2. 调用`HAL_USART_Init()`进行初始化。 3. 根据需求选择发送/接收方式(阻塞、中断、DMA)。 4. 处理中断(如果需要)并实现回调函数。 通过HAL库,开发者无需直接操作复杂的寄存器,降低了开发难度。但理解底层寄存器结构有助于在需要时进行更灵活的配置和调试[^1][^2][^3]。 --- §§相关问题§§ 1.STM32G0系列中,如何配置USART的LIN模式? 2. 如何使用HAL库实现USART的DMA双缓冲接收? 3. USART通信中如何实现硬件流控(RTS/CTS)? 4. 如何通过HAL函数获取USART通信中的错误状态(如帧错误、噪声错误)? [^1]: STM32G0系列参考手册(RM0444) [^2]: STM32CubeG0 HAL库用户手册(UM2319) [^3]: STM32CubeIDE开发环境示例代码</think>### 使用STM32G0 HAL库操作USART寄存器详解 在STM32G0系列中,HAL库提供了对USART寄存器的抽象封装,使开发者无需直接操作底层寄存器即可实现串口通信。以下是针对您提供的`USART_TypeDef`结构体的HAL库使用方法: --- #### 1. **初始化配置(HAL_USART_Init)** ```c USART_HandleTypeDef husart; USART_InitTypeDef init = { .BaudRate = 115200, // 对应US_BRGR寄存器 .WordLength = USART_WORDLENGTH_8B, // US_MR寄存器[US_MR_CHRL] .StopBits = USART_STOPBITS_1, // US_MR寄存器[US_MR_NBSTOP] .Parity = USART_PARITY_NONE, // US_MR寄存器[US_MR_PAR] .Mode = USART_MODE_TX_RX, // 使能US_CR寄存器的TXEN/RXEN位 .CLKPolarity = USART_POLARITY_LOW, .CLKPhase = USART_PHASE_1EDGE, .CLKLastBit = USART_LASTBIT_DISABLE }; husart.Instance = USART1; // 选择USART外设 if (HAL_USART_Init(&husart) != HAL_OK) { Error_Handler(); } ``` > 此函数自动配置`US_BRGR`、`US_MR`等寄存器[^2] --- #### 2. **数据收发函数** ```c // 阻塞发送(操作US_THR寄存器) uint8_t tx_data = 'A'; HAL_USART_Transmit(&husart, &tx_data, 1, HAL_MAX_DELAY); // 中断接收(操作US_RHR寄存器) uint8_t rx_data; HAL_USART_Receive_IT(&husart, &rx_data, 1); // DMA发送(使用US_THR) HAL_USART_Transmit_DMA(&husart, tx_buffer, buffer_size); // DMA接收(使用US_RHR) HAL_USART_Receive_DMA(&husart, rx_buffer, buffer_size); ``` --- #### 3. **中断控制(对应US_IER/US_IDR)** ```c // 在HAL_USART_MspInit中启用中断 void HAL_USART_MspInit(USART_HandleTypeDef* husart) { // 启用USART时钟和GPIO... HAL_NVIC_SetPriority(USART1_IRQn, 0, 0); HAL_NVIC_EnableIRQ(USART1_IRQn); // 对应US_IER使能 } // 中断服务函数 void USART1_IRQHandler(void) { HAL_USART_IRQHandler(&husart); // 自动处理US_CSR状态 } // 回调函数(数据接收完成) void HAL_USART_RxCpltCallback(USART_HandleTypeDef *husart) { // 处理接收数据 } ``` --- #### 4. **高级功能配置** ```c // LIN模式配置(操作US_LINMR寄存器) HAL_LIN_Init(&husart, LIN_BaudRate, LIN_WakeUpMethod); // 超时配置(US_RTOR寄存器) __HAL_USART_SET_RECEIVER_TIMEOUT(&husart, timeout_value); // 写保护(US_WPMR/US_WPSR) HAL_USART_EnableWriteProtection(&husart); if (__HAL_USART_GET_FLAG(&husart, USART_FLAG_WUF)) { // 写保护错误处理 } ``` --- #### 5. **错误处理(对应US_NER)** ```c // 获取错误状态(US_CSR寄存器) uint32_t error = husart.ErrorCode; if (error & HAL_USART_ERROR_PE) { // 校验错误 } if (error & HAL_USART_ERROR_NE) { // 噪声错误 } // 清除错误标志 __HAL_USART_CLEAR_FLAG(&husart, USART_CLEAR_OREF | USART_CLEAR_NEF); ``` > **关键设计**:HAL库通过`USART_HandleTypeDef`结构体封装寄存器操作,内部自动处理: > 1. 波特率计算:$$ \text{US\_BRGR} = \frac{f_{\text{CLK}}}{\text{BaudRate}} $$ > 2. 中断标志管理(US_CSR) > 3. DMA传输协调(使用US_THR/US_RHR)[^1][^2] ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值