文章目录
- 前言
- 一、查询方式编写串口发送和接收的代码
- 二、中断方式编写串口发送和接收的代码
- 总结
前言
本篇文章来给大家讲解USART的代码详细讲解和使用步骤。
一、查询方式编写串口发送和接收的代码
串口查询发送函数:
HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size, uint32_t Timeout)
参数:
huart(UART_HandleTypeDef 结构体指针): 这是一个指向 UART_HandleTypeDef 结构体的指针,该结构体包含了UART相关的配置信息,例如UART的硬件寄存器基地址、波特率、数据位数等。
pData(uint8_t 指针): 这是一个指向要发送数据缓冲区的指针。
Size(uint16_t 类型): 这是要发送的数据的字节数。
Timeout(uint32_t 类型): 这是发送数据的超时时间,单位是毫秒。如果设置为 HAL_MAX_DELAY,则表示无限等待。
返回值:
函数的返回值是 HAL_StatusTypeDef 类型,表示函数执行的状态。可能的返回值包括:
HAL_OK: 操作成功完成。
HAL_BUSY: 操作正在进行中,不能启动新的操作。
HAL_ERROR: 操作失败。
函数作用:
HAL_UART_Transmit 函数的主要作用是通过UART发送数据。它接收一个指向要发送数据的缓冲区的指针和数据的字节数,然后将这些数据通过配置好的UART通道发送出去。函数会根据配置的超时时间等待发送完成或超时。
HAL_UART_Transmit函数内部机制讲解:
这里只讲解比较重要的代码部分
while (huart->TxXferCount > 0U)
{
if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
{
return HAL_TIMEOUT;
}
if (pdata8bits == NULL)
{
huart->Instance->DR = (uint16_t)(*pdata16bits & 0x01FFU);
pdata16bits++;
}
else
{
huart->Instance->DR = (uint8_t)(*pdata8bits & 0xFFU);
pdata8bits++;
}
huart->TxXferCount--;
}
上面代码的解读:
1.首先先检查要发送的数据是否大于0
2.检查TXE寄存器,判断TDR寄存器中的数据是否被发送出去
3.把数据写入DR数据寄存器中
4.让TxXferCount数据量减1
使用示例:
HAL_UART_Transmit(&huart1, "Hello World", sizeof("Hello World"), 1000);
串口查询接收函数:
HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
参数:
huart:UART 句柄,指定了你要使用的 UART 外设。
pData:指向要存储接收到数据的缓冲区的指针。
Size:要接收的数据的数量,以字节为单位。
Timeout:超时时间,以毫秒为单位。如果在超时时间内没有接收到足够的数据,则函数会返回。可以使用 HAL_MAX_DELAY 作为超时参数来指定无限超时,直到接收到足够的数据。
返回值:
函数的返回值是一个 HAL_StatusTypeDef 类型的枚举值,表示函数执行的结果。可能的返回值包括:
HAL_OK:函数执行成功,接收到了指定数量的数据。
HAL_TIMEOUT:超时,未能在指定的时间内接收到足够的数据。
HAL_ERROR:发生了错误,可能是由于参数错误或者硬件问题引起的。
上面代码的解读:
1.首先先检查要接收的数据是否大于0
2.检查RXNE寄存器,判断RDR寄存器中是否有数据可以接收
3.将DR中的数据读取出来
4.让RxXferCount数据量减1
使用示例:
uint8_t rx_data[10]; // 接收数据缓冲区
while (1)
{
HAL_UART_Receive(&huart1, rx_data, sizeof(rx_data), HAL_MAX_DELAY);
// 处理接收到的数据
// 可以在这里进行数据处理或者将数据发送到其他地方
}
二、中断方式编写串口发送和接收的代码
开启中断:
串口发送函数(中断方式)
HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size)
参数:
huart:UART 句柄,指定了你要使用的 UART 外设。
pData:指向要传输的数据缓冲区的指针。
Size:要传输的数据的数量,以字节为单位。
返回值:
函数的返回值是一个 HAL_StatusTypeDef 类型的枚举值,表示函数执行的结果。可能的返回值包括:
HAL_OK:函数执行成功,数据已经被成功传输。
HAL_ERROR:发生了错误,可能是由于参数错误或者硬件问题引起的。
HAL_BUSY:UART 外设忙,不能执行传输。
HAL_TIMEOUT:超时,传输未能在指定的时间内完成。
HAL_UART_Transmit_IT函数调用的分析:
HAL_UART_Transmit_IT函数并没有直接进行数据的发送而是开启TEX发送数据寄存器空中断。
串口1中断函数:
在HAL_UART_IRQHandler函数中调用了UART_EndTransmit_IT。
发送完最后一个数据后使能TC发送完成中断。
发送最后一个数据完成调用HAL_UART_TxCpltCallback回调函数:
串口中断发送数据方式总结:
1.使能TXE中断,将数据一个个的发送出去。
2.当只有最后一个数据的时候使能TC发送完成中断
3.当最后一个数据发送完成后调用HAL_UART_TxCpltCallback回调函数。
使用示例:
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart == &huart1)
{
// 发送完成回调函数
}
}
HAL_UART_Transmit_IT(&huart1, tx_data, strlen((char *)tx_data)); // 发送数据
串口接收函数(中断方式)
HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
参数:
huart:一个指向 UART_HandleTypeDef 结构体的指针,该结构体包含了 UART 外设的配置和状态信息。
pData:一个指向要存储接收数据的缓冲区的指针。
Size:要接收的数据的字节数。
返回值 (HAL_StatusTypeDef):该函数返回一个 HAL_StatusTypeDef 类型的值,用于表示函数执行的状态。可能的返回值包括:
HAL_OK:函数执行成功。
HAL_BUSY:UART 正在忙于处理其他操作。
HAL_ERROR:发生了错误,导致函数执行失败。
HAL_TIMEOUT:函数执行超时。
HAL_UART_Receive_IT函数会马上返回不会一直等待到有数据才返回。
在UART_Start_Receive_IT中调用__HAL_UART_ENABLE_IT函数开启RXNE中断。
接收数据:
当接收数据完成后会调用HAL_UART_RxCpltCallback回调函数:
uint8_t rx_data = 0;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart == &huart1)
{
// 处理接收到的数据
// 可以在这里进行数据处理或者将数据发送到其他地方
HAL_UART_Receive_IT(&huart1, rx_data, 1); // 继续接收下一个字节
}
}
HAL_UART_Receive_IT(&huart1, rx_data, 1); // 启动接收中断,每次接收一个字节
总结
本篇文章深入的讲解了UART发送和接收查询方式和中断方式的具体函数使用和内部原理。