printf的重定向
为了方便使用,通过keil中的Help功能的帮助,做一个printf的重定向
搜索fputc,复制这段
将复制的那段放入工程中,并添加串口发送的函数
关键代码
u8 rx_buff[30]; // 定义一个长度为30的接收缓冲区数组rx_buff
u8 rx_data; // 定义一个用于存储接收到的单个字节的变量rx_data
u8 buff_size = 0; // 定义一个变量buff_size,用于记录接收缓冲区中已接收的字节数
u32 rx_tick = 0; // 定义一个变量rx_tick,用于记录最近一次接收数据的时间戳void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) // UART接收完成回调函数
{rx_tick = uwTick; // 更新接收数据的时间戳为当前系统时间HAL_UART_Receive_IT(&huart1, &rx_data, 1); // 使能UART中断接收下一个字节的数据rx_buff[buff_size++] = rx_data; // 将接收到的数据存入接收缓冲区,并更新已接收字节数
}void Rx_proc() // 接收数据处理函数
{if (uwTick - rx_tick < 50) // 如果距离上次接收数据时间不足50毫秒return; // 则退出函数,等待下次处理rx_tick = uwTick; // 更新接收数据的时间戳为当前系统时间if (buff_size == 1 && rx_buff[0] == '#') // 如果接收缓冲区中只有一个字节且为'#'{LED_disp(0x01); // 控制LED显示,示例中将LED设置为特定的模式}else if (buff_size == 1 && rx_buff[0] == '$') // 如果接收缓冲区中只有一个字节且为'$'{LED_disp(0xab); // 控制LED显示,示例中将LED设置为特定的模式}else if (buff_size > 0) // 如果接收缓冲区中有数据{printf("%s\r\n", rx_buff); // 将接收缓冲区中的数据打印输出printf("send data error!\r\n"); // 打印提示信息,表示发送数据出错}buff_size = 0; // 重置接收缓冲区已接收字节数为0memset(rx_buff, '\0', sizeof(rx_buff)); // 清空接收缓冲区,准备接收新的数据
}
1,在HAL_UART_RxCpltCallback函数中,当UART接收完成时,将接收到的数据存入接收缓冲区rx_buff中,并更新已接收字节数buff_size。然后通过使能UART中断接收下一个字节的数据。
2,Rx_proc函数用于处理接收到的数据。首先判断距离上次接收数据的时间是否超过50毫秒,如果不足则退出函数。然后根据接收缓冲区中的数据内容,分别执行不同的操作:
- 如果接收到的数据为#,则控制LED显示特定模式。
- 如果接收到的数据为$,同样控制LED显示特定模式。
- 如果接收到其他数据,则将数据打印输出,并提示发送数据出错。
3,最后,重置接收缓冲区的已接收字节数为0,并清空接收缓冲区,以便下一次接收新的数据。
注意点:
1,串口重定向的时候,ch前需要加上取地址符&,强制将ch类型转化为u8
2,串口接收回调函数时,中断接收到的先赋给rx_data,rx_data再给rx_buff
3,接收设置函数要记得最后清空接收数组rx_buff,和buff_size
4,主函数中记得开启接收回调函数
关键函数:
HAL_UART_Transmit(&huart1, (u8 *)&ch, 1, 50); //printf重定向串口发送函数
HAL_UART_Receive_IT(&huart1, &rx_data, 1); //串口接收中断函数