配置hal库
1配置时钟
2配置uart
3打开中断
程序结构
uart中断函数
中断接收和发送函数
HAL_UART_Receive_IT()
:启动中断驱动的接收过程,当接收到指定数量的字节后会产生中断,并调用HAL_UART_RxCpltCallback()
回调函数。-
HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) { // 内部实现 }
HAL_UART_Transmit_IT()
:启动中断驱动的发送过程,当发送完指定数量的字节后会产生中断,并调用HAL_UART_TxCpltCallback()
回调函数。-
HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) { // 内部实现 }
中断回调函数
HAL_UART_TxCpltCallback()
:当UART传输完成时调用。-
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) { if (huart->Instance == USART1) { // 发送完成,在这里可以执行其他操作 } }
-
HAL_UART_RxCpltCallback()
:当UART接收完成时调用。HAL_UART_TxHalfCpltCallback()
:当UART传输一半的数据完成时调用(如果启用了半传输中断)。HAL_UART_RxHalfCpltCallback()
:当UART接收一半的数据完成时调用(如果启用了半接收中断)。HAL_UART_ErrorCallback()
:当UART发生错误时调用。
代码的实现
实现发送
#include "stm32f1xx_hal.h"
UART_HandleTypeDef huart1;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART1_UART_Init(void);
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART1)
{
// 发送完成,在这里可以执行其他操作
}
}
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
// 要发送的数据
uint8_t data[] = "Hello, World!";
HAL_UART_Transmit_IT(&huart1, data, sizeof(data) - 1); // 启动中断发送
while (1)
{
// 主循环中的其他代码
}
}
static void MX_USART1_UART_Init(void)
{
huart1.Instance = USART1;
huart1.Init.BaudRate = 9600;
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();
}
}
void SystemClock_Config(void)
{
// ...系统时钟配置代码
}
static void MX_GPIO_Init(void)
{
// ...GPIO初始化代码
}
void Error_Handler(void)
{
// ...错误处理代码
}
#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t* file, uint32_t line)
{
// ...断言失败处理代码
}
#endif
实现接收
#include "stm32f1xx_hal.h"
UART_HandleTypeDef huart1;
uint8_t rxData[1]; // 用于存储接收到的单个字节的缓冲区
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART1_UART_Init(void);
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART1)
{
// 处理接收到的数据
// 例如,将其打印到调试控制台
// 注意:这里只是示例,实际应用中可能需要更复杂的处理
// 重新启动接收过程以接收下一个字节
HAL_UART_Receive_IT(&huart1, rxData, 1);
}
}
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
// 启动中断接收
HAL_UART_Receive_IT(&huart1, rxData, 1);
while (1)
{
// 主循环中的其他代码
}
}
static void MX_USART1_UART_Init(void)
{
huart1.Instance = USART1;
huart1.Init.BaudRate = 9600;
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();
}
}
void SystemClock_Config(void)
{
// ...系统时钟配置代码
}
static void MX_GPIO_Init(void)
{
// ...GPIO初始化代码
}
void Error_Handler(void)
{
// ...错误处理代码
}
#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t* file, uint32_t line)
{
// ...断言失败处理代码
}
#endif
总结
注意回调函数中的代码的细节
回调函数尽量精简,写耗时短的代码
注意
启动中断驱动的接收过程,当接收到指定数量的字节后会产生中断,并调用HAL_UART_RxCpltCallback()
回调函数。