void Seria2_Printf(char *format, ...)
{
char String[200];
va_list arg;
va_start(arg, format);
vsprintf(String, format, arg);
va_end(arg);
HAL_UART_Transmit(&huart2,(uint8_t*)&String, strlen(String), HAL_MAX_DELAY);
}
在FreeRTOS中使用HAL_UART_Transmit
函数时,程序可能会卡住的原因通常与以下几个方面有关:
-
阻塞式调用:
HAL_UART_Transmit
是一个阻塞式函数,它会一直等待直到所有数据都发送完毕。在FreeRTOS中,如果任务长时间阻塞,可能会导致其他任务无法及时执行,从而影响系统的实时性。 -
优先级问题: 如果当前任务的优先级较低,而其他高优先级任务占用了CPU资源,当前任务可能会长时间得不到执行,看起来像是卡住了。
-
UART硬件问题: 如果UART硬件出现问题(如波特率设置错误、硬件故障等),
HAL_UART_Transmit
可能会一直等待数据发送完成,导致程序卡住。 -
缓冲区溢出: 如果
vsprintf
生成的字符串长度超过了String
数组的大小(200字节),可能会导致缓冲区溢出,进而引发不可预知的行为,包括程序卡住。 -
中断处理: 如果UART的中断处理不当,可能会导致
HAL_UART_Transmit
无法正常完成。
解决方案
-
使用非阻塞式发送: 可以使用
HAL_UART_Transmit_IT
或HAL_UART_Transmit_DMA
等非阻塞式函数,这样可以在数据发送的同时让任务继续执行其他操作。 -
任务优先级调整: 确保当前任务的优先级合理,避免被其他高优先级任务长时间阻塞。
-
检查硬件配置: 确保UART的波特率、数据位、停止位等配置正确,并且硬件工作正常。
-
增加缓冲区大小: 确保
String
数组足够大,以避免缓冲区溢出。 -
优化中断处理: 确保UART的中断处理函数正确配置,避免影响数据传输。
示例代码(使用非阻塞式发送)
void Seria2_Printf(char *format, ...)
{
char String[200];
va_list arg;
va_start(arg, format);
vsnprintf(String, sizeof(String), format, arg); // 使用vsnprintf防止缓冲区溢出
va_end(arg);
HAL_UART_Transmit_IT(&huart2, (uint8_t*)String, strlen(String)); // 使用非阻塞式发送
}
void Seria2_Printf(char *format, ...)
{
va_list arg;
va_start(arg, format);
// 计算格式化字符串的长度
int len = vsnprintf(NULL, 0, format, arg);
if (len < 0) {
va_end(arg);
return; // 格式化失败
}
// 动态分配缓冲区
char *String = (char *)malloc(len + 1); // +1 用于字符串结束符
if (String == NULL) {
va_end(arg);
return; // 内存分配失败
}
// 格式化字符串
vsnprintf(String, len + 1, format, arg);
va_end(arg);
// 使用非阻塞式发送
HAL_UART_Transmit_DMA(&huart2, (uint8_t*)String, len);
// 释放动态分配的内存
free(String);
}
遇到了一个奇葩问题啊嗯,至今不知道是什么原因,然后。通过开了一个软件定时发送串口程序就可以解决不能发送浮点数的一个问题。(首先声明软件上能找到的设置的我都设置了,并且耽搁了我两天时间我都差一点就整数拼接小数了)
最上面这个不发送浮点数就不会卡
void MAIN_WUStartTask05(void *argument)
{
osTimerStart(WUTimer01Handle, 1000);
while(1)
{
//DHT11_Read_Data(&Temperature,&Humidity);//读取温湿度。
//Data_Upload();
Usart_Control();
osDelay(100);
}
}
void Callback01(void *argument)
{
LED_GREEN_TogglePin;
Data_Upload();
// Seria2_Printf("WUA&1:%s&2:%s&3:%s&4:%s&5:%s&6:%d&7:%d&8:%d&9:%d&10:%.2f&11:600.1&12:500.1&13:100.1&14:-10.5&15:70.1&16:-1700.1&17:0.0&18:-70.12&19:130.1&20:2700.15&21:70.1&22:80.1&23:nil&24:ok\r\n",\
// Relay1,Relay2,Relay3,Relay4,Relay5,Temperature,Humidity,Temperature_max,T_alarm,Voltage);//继电器状态基本数据上传
}