概要
介绍STM32串口数据接收和发送函数。
整体架构流程
STM32F1 的发送与接收是通过数据寄存器 USART_DR 来实现的,这是一个双寄存器,包含了 TDR 和 RDR。当向该寄存器写数据的时候,串口就会自动发送,当收到数据的时候,也是存在该寄存器内。
HAL 库操作 USART_DR 寄存器发送数据的函数是:
HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);
通过该函数向串口寄存器 USART_DR 写入一个数据。
HAL 库操作 USART_DR 寄存器读取串口接收到的数据的函数是:
HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);
通过该函数可以读取串口接受到的数据。
技术细节
1、HAL_UART_Transmit 函数
HAL_UART_Transmit 函数是STM32 HAL(硬件抽象层)库中的一个函数,用于通过UART(通用异步收发传输器)发送数据。这个函数允许用户通过指定的UART端口发送一串数据。下面是对该函数参数和返回类型的详细解释:
参数
huart: 指向UART_HandleTypeDef结构体的指针,该结构体包含了UART配置的所有信息,如UART的基地址、波特率、中断使能状态等。这个结构体通常在初始化UART时通过HAL_UART_Init函数进行配置。
pData: 指向要发送数据的指针。这是一个uint8_t类型的指针,意味着它指向的数据是一个字节数组(或单个字节,如果Size为1)。pData指向的数据将会被发送到UART指定的端口。
Size: 指定要发送的数据大小,以字节为单位。这个值告诉函数pData指向的数组中有多少个字节需要被发送。
Timeout: 指定操作的超时时间,以毫秒为单位。如果在这段时间内数据没有完全发送,函数将返回错误状态。设置为HAL_MAX_DELAY表示无限等待,直到所有数据都发送完毕或发生错误。
返回类型
HAL_StatusTypeDef: 这是一个枚举类型,用于表示函数的执行结果。可能的返回值包括:
HAL_OK: 表示函数成功执行,所有数据都已在指定的超时时间内发送完毕。
HAL_ERROR: 表示函数执行过程中发生了错误,可能是硬件故障或配置错误等原因。
HAL_BUSY: 表示UART正在忙,无法立即开始发送数据。这通常发生在非阻塞模式下,当UART还在处理前一个操作时。
HAL_TIMEOUT: 表示操作在指定的超时时间内没有完成。
使用示例:
UART_HandleTypeDef huart1;
// 假设huart1已经在某个地方被正确初始化
uint8_t dataToSend[] = "Hello, UART!";
if (HAL_UART_Transmit(&huart1, dataToSend, sizeof(dataToSend) - 1, HAL_MAX_DELAY) != HAL_OK)
{
// 处理发送失败的情况
Error_Handler();
}
在这个示例中,我们尝试通过huart1(假设它已经被正确初始化)发送字符串"Hello, UART!"。我们使用sizeof(dataToSend) - 1来计算字符串的实际大小(不包括末尾的空字符),并将Timeout参数设置为HAL_MAX_DELAY,表示我们愿意无限等待直到所有数据都发送完毕。如果发送失败,我们调用Error_Handler()函数来处理错误情况。
2、HAL_UART_Receive 函数
HAL_UART_Receive 函数是STM32 HAL库中的一个函数,用于通过UART(通用异步收发传输器)接收数据。这个函数允许用户从指定的UART端口接收一串数据。下面是对该函数参数和返回类型的详细解释:
参数
huart: 指向UART_HandleTypeDef结构体的指针,该结构体包含了UART配置的所有信息,如UART的基地址、波特率、中断使能状态等。这个结构体通常在初始化UART时通过HAL_UART_Init函数进行配置。
pData: 指向用于存储接收到的数据的缓冲区的指针。这是一个uint8_t类型的指针,意味着它指向的数据将用于存储从UART接收到的字节数组。
Size: 指定要接收的数据大小,以字节为单位。这个值告诉函数pData指向的缓冲区可以接收多少个字节的数据。
Timeout: 指定操作的超时时间,以毫秒为单位。如果在这段时间内没有接收到足够的数据,函数将返回错误状态。设置为HAL_MAX_DELAY表示无限等待,直到接收到指定数量的数据或发生错误。
返回类型
HAL_StatusTypeDef: 这是一个枚举类型,用于表示函数的执行结果。可能的返回值包括:
HAL_OK: 表示函数成功执行,指定数量的数据已在指定的超时时间内接收完毕。
HAL_ERROR: 表示函数执行过程中发生了错误,可能是硬件故障或配置错误等原因。
HAL_BUSY: 表示UART正在忙,无法立即开始接收数据。这通常发生在非阻塞模式下,当UART还在处理前一个操作时。
HAL_TIMEOUT: 表示操作在指定的超时时间内没有完成,即没有接收到足够的数据。
使用示例
UART_HandleTypeDef huart1;
// 假设huart1已经在某个地方被正确初始化
uint8_t receivedData[10]; // 假设我们期望接收最多10个字节的数据
if (HAL_UART_Receive(&huart1, receivedData, 10, HAL_MAX_DELAY) != HAL_OK)
{
// 处理接收失败的情况
Error_Handler();
}
else
{
// 处理接收到的数据
// 例如,打印接收到的数据
for(int i = 0; i < 10; i++)
{
if(receivedData[i] != 0) // 假设数据以空字符结束,但这里只是示例,实际中可能需要其他逻辑
{
// 打印字符或进行其他处理
HAL_UART_Transmit(&huart1, &receivedData[i], 1, HAL_MAX_DELAY); // 注意:这里只是示例,通常不会将接收到的数据直接回显
}
else
{
break; // 假设数据以空字符结束
}
}
}
注意:上面的示例中,直接回显接收到的数据(通过HAL_UART_Transmit)只是为了演示如何处理接收到的数据。在实际应用中,你可能需要根据接收到的数据执行更复杂的逻辑,并且通常不会以空字符作为数据结束的标志,因为UART通信是字节流的,不保证数据以特定的字符结束。你可能需要实现某种协议来确定何时一条消息已经完全接收。
此外,如果Size参数指定的字节数大于实际接收到的字节数(例如,由于超时或通信中断),则pData缓冲区中未使用的部分将保持未定义的状态,因此在处理接收到的数据时需要注意这一点。
3、HAL_UART_Transmit 函数如果要发送uint16_t类型的数据,怎么处理
HAL_UART_Transmit 函数是设计用来发送 uint8_t 类型数据的,因为它通过 UART 发送的是字节流。如果你需要发送 uint16_t 类型的数据(即一个 16 位的整数),你需要将其拆分为两个 uint8_t 类型的字节,并依次发送它们。
在发送时,你需要决定这两个字节的发送顺序,这通常取决于你与接收设备之间的协议或约定。最常见的两种顺序是:
大端序(Big-Endian):最高有效字节(MSB)先发送,然后是最低有效字节(LSB)。
小端序(Little-Endian):最低有效字节(LSB)先发送,然后是最高有效字节(MSB)。
以下是一个发送 uint16_t 数据的示例,假设我们使用大端序:
c
#include "stm32f1xx_hal.h"
void SendUint16t(UART_HandleTypeDef *huart, uint16_t data)
{
uint8_t buffer[2];
// 将 uint16_t 数据拆分为两个 uint8_t 字节,这里使用大端序
buffer[0] = (data >> 8) & 0xFF; // 发送最高有效字节
buffer[1] = data & 0xFF; // 发送最低有效字节
// 发送数据
if (HAL_UART_Transmit(huart, buffer, 2, HAL_MAX_DELAY) != HAL_OK)
{
// 处理发送失败的情况
Error_Handler();
}
}
// 示例用法
UART_HandleTypeDef huart1;
// 假设 huart1 已经被正确初始化
uint16_t valueToSend = 0x1234; // 示例数据
SendUint16t(&huart1, valueToSend); // 发送数据
在这个示例中,SendUint16t 函数接受一个指向 UART_HandleTypeDef 的指针和一个 uint16_t 类型的数据作为参数。它首先将 uint16_t 数据拆分为两个 uint8_t 字节,并将它们存储在局部缓冲区 buffer 中。然后,它使用 HAL_UART_Transmit 函数发送这个缓冲区中的数据。
小结
HAL_UART_Transmit 和 HAL_UART_Receive 函数是STM32 HAL库中用于UART通信的关键函数。HAL_UART_Transmit 函数负责将数据通过UART发送出去,它接受指向数据缓冲区的指针、数据大小以及超时时间作为参数,确保数据按照指定的字节顺序和格式发送。与之对应,HAL_UART_Receive 函数则用于从UART接收数据,它同样需要指定数据缓冲区、期望接收的数据大小以及超时时间。
这两个函数简化了UART通信的底层细节,使得开发者能够更专注于数据的处理和协议的实现。它们提供了灵活的超时设置,使得在通信过程中可以方便地处理超时情况,提高了通信的可靠性和稳定性。通过合理使用这两个函数,开发者可以轻松实现UART通信的发送和接收功能,满足各种嵌入式应用的需求。