当前位置: 首页 > news >正文

嵌入式使用snprintf(str, sizeof(str), “ULV: %.3fV“,values);后出现小数部分丢失的错误以及解决方案

问题背景

跳转到storage页面后回来小数正常,但是我跳转到system页面回来后就变成整数,当在Menu_Interface3/4/5时候按上/下/退出键,再回去Protect_Interface1/2/3就发现三个显示的数据全变成整数了

#include "oled_show.h"
#include "OLED_Data.h"
#include "main.h"
#include "input_system.h"
#include "key.h"ProtectValues_t protect_values = {.ovp_value = 88.0f,.ulv_value = 0.0f,.ocp_value = 66.0f
};uint8_t taskIndex = 0;	//初始任务
//任务调度表
Menu_table_t taskTable[] =
{//{当前页码,ok,右,左,上,下,退出,当前操作}//一级菜单界面{0, 5, 1, 0, 0, 0, 0, Menu_Interface1}, {1, 11, 2, 0, 1, 1, 1, Menu_Interface2}, {2, 12, 3, 1, 2, 2, 2, Menu_Interface3}, {3, 3, 4, 2, 0, 3, 3, Menu_Interface4}, {4, 4, 4, 3, 0, 4, 4, Menu_Interface5}, //二级保护菜单界面	{5, 8, 6, 5, 5, 7, 0, Protect_Interface1},//Protect-OVP{6, 9, 7, 5, 6, 7, 0, Protect_Interface2},//Protect-ULV	{7, 10, 7, 6, 5, 7, 0, Protect_Interface3},//Protect-OCP		// 三级输入界面{8, 8, 6, 5, 5, 7, 5, Protect_Input1},//Protect-OVP	{9, 9, 6, 5, 5, 7, 6, Protect_Input1}, // ULV 输入{10, 10, 6, 5, 5, 7, 7, Protect_Input1}, // OCP 输入		//二级保存界面	{11, 11, 11, 11, 11,11,0, Storage_Interface},//Storage//二级系统界面{12, 12, 12, 12, 12,12,0, System_Interface},//System//    {7, 1, 3, 2, 0, System_Interface3},//System//	//功能设置界面函数 -- 三级界面
//	{4, 4, 4, 1, 3, BaudRate_Interface4},//BaudRate 
//	{5, 5, 5, 2, 3, Function_Interface5},// Config
//	{6, 6, 6, 3, 3, Function_Interface6},//Option
};/*** @number 0* @brief 0  菜单界面函数-》Project 编号0* @param  无* @retval 无*/
void Menu_Interface1(void)
{Buffer_ClearBackBuffer();
Buffer_DrawBitmap1Bit(7, 3, 38, 38,epd_bitmap_protect3838, 0x0f,0);
Buffer_DrawBitmap1Bit(58, 3, 38, 38,epd_bitmap_storage3838, 0x0f,0);	
Buffer_DrawBitmap1Bit(109, 3, 38, 38,epd_bitmap_system3838, 0x0f,0);	
Buffer_DrawBitmap1Bit(160, 3, 38, 38,epd_bitmap_power3838, 0x0f,0);	
Buffer_DrawBitmap1Bit(211, 3, 38, 38,epd_bitmap_esc3838, 0x0f,0);	Buffer_DrawBitmap1Bit(0, 49, 51, 16,border5116, 0x0f,0);
Buffer_DrawBitmap1Bit(1, 50, 50, 15,borderfull5015, 0x0f,0);	//填充
Buffer_DrawBitmap1Bit(51, 49, 51, 16,border5116, 0x0f,0);	
Buffer_DrawBitmap1Bit(102, 49, 51, 16,border5116, 0x0f,0);	
Buffer_DrawBitmap1Bit(153, 49, 51, 16,border5116, 0x0f,0);	
Buffer_DrawBitmap1Bit(204, 49, 52, 16,border5216, 0x0f,0);		Buffer_DrawString(8, 53, "Protect",0x0f, 10,1);
Buffer_DrawString(59, 53, "Storage",0x0f, 10,0);
Buffer_DrawString(113, 53, "System",0x0f, 10,0);
Buffer_DrawString(166, 53, "Power",0x0f, 10,0);
Buffer_DrawString(222, 53, "ESC",0x0f, 10,0);Buffer_Swap(); // 显示
}/*** @number 1* @brief 菜单界面函数-》Storage * @param  无* @retval 无*/
void Menu_Interface2(void)
{Buffer_ClearBackBuffer();
Buffer_DrawBitmap1Bit(7, 3, 38, 38,epd_bitmap_protect3838, 0x0f,0);
Buffer_DrawBitmap1Bit(58, 3, 38, 38,epd_bitmap_storage3838, 0x0f,0);	
Buffer_DrawBitmap1Bit(109, 3, 38, 38,epd_bitmap_system3838, 0x0f,0);	
Buffer_DrawBitmap1Bit(160, 3, 38, 38,epd_bitmap_power3838, 0x0f,0);	
Buffer_DrawBitmap1Bit(211, 3, 38, 38,epd_bitmap_esc3838, 0x0f,0);	Buffer_DrawBitmap1Bit(0, 49, 51, 16,border5116, 0x0f,0);
Buffer_DrawBitmap1Bit(51, 49, 51, 16,border5116, 0x0f,0);	
Buffer_DrawBitmap1Bit(102, 49, 51, 16,border5116, 0x0f,0);	
Buffer_DrawBitmap1Bit(153, 49, 51, 16,border5116, 0x0f,0);	
Buffer_DrawBitmap1Bit(204, 49, 52, 16,border5216, 0x0f,0);		Buffer_DrawBitmap1Bit(52, 50, 50, 15,borderfull5015, 0x0f,0);	//填充Buffer_DrawString(8, 53, "Protect",0x0f, 10,0);
Buffer_DrawString(59, 53, "Storage",0x0f, 10,1);
Buffer_DrawString(113, 53, "System",0x0f, 10,0);
Buffer_DrawString(166, 53, "Power",0x0f, 10,0);
Buffer_DrawString(222, 53, "ESC",0x0f, 10,0);Buffer_Swap(); // 显示
}/*** @number 2* @brief 菜单界面函数-》Storage * @param  无* @retval 无*/
void Menu_Interface3(void)
{Buffer_ClearBackBuffer();
Buffer_DrawBitmap1Bit(7, 3, 38, 38,epd_bitmap_protect3838, 0x0f,0);
Buffer_DrawBitmap1Bit(58, 3, 38, 38,epd_bitmap_storage3838, 0x0f,0);	
Buffer_DrawBitmap1Bit(109, 3, 38, 38,epd_bitmap_system3838, 0x0f,0);	
Buffer_DrawBitmap1Bit(160, 3, 38, 38,epd_bitmap_power3838, 0x0f,0);	
Buffer_DrawBitmap1Bit(211, 3, 38, 38,epd_bitmap_esc3838, 0x0f,0);	Buffer_DrawBitmap1Bit(0, 49, 51, 16,border5116, 0x0f,0);
Buffer_DrawBitmap1Bit(51, 49, 51, 16,border5116, 0x0f,0);	
Buffer_DrawBitmap1Bit(102, 49, 51, 16,border5116, 0x0f,0);	
Buffer_DrawBitmap1Bit(153, 49, 51, 16,border5116, 0x0f,0);	
Buffer_DrawBitmap1Bit(204, 49, 52, 16,border5216, 0x0f,0);		Buffer_DrawBitmap1Bit(103, 50, 50, 15,borderfull5015, 0x0f,0);	//填充Buffer_DrawString(8, 53, "Protect",0x0f, 10,0);
Buffer_DrawString(59, 53, "Storage",0x0f, 10,0);
Buffer_DrawString(113, 53, "System",0x0f, 10,1);
Buffer_DrawString(166, 53, "Power",0x0f, 10,0);
Buffer_DrawString(222, 53, "ESC",0x0f, 10,0);Buffer_Swap(); // 显示
}/*** @number 3* @brief 菜单界面函数-》Storage * @param  无* @retval 无*/
void Menu_Interface4(void)
{Buffer_ClearBackBuffer();
Buffer_DrawBitmap1Bit(7, 3, 38, 38,epd_bitmap_protect3838, 0x0f,0);
Buffer_DrawBitmap1Bit(58, 3, 38, 38,epd_bitmap_storage3838, 0x0f,0);	
Buffer_DrawBitmap1Bit(109, 3, 38, 38,epd_bitmap_system3838, 0x0f,0);	
Buffer_DrawBitmap1Bit(160, 3, 38, 38,epd_bitmap_power3838, 0x0f,0);	
Buffer_DrawBitmap1Bit(211, 3, 38, 38,epd_bitmap_esc3838, 0x0f,0);	Buffer_DrawBitmap1Bit(0, 49, 51, 16,border5116, 0x0f,0);
Buffer_DrawBitmap1Bit(51, 49, 51, 16,border5116, 0x0f,0);	
Buffer_DrawBitmap1Bit(102, 49, 51, 16,border5116, 0x0f,0);	
Buffer_DrawBitmap1Bit(153, 49, 51, 16,border5116, 0x0f,0);	
Buffer_DrawBitmap1Bit(204, 49, 52, 16,border5216, 0x0f,0);		Buffer_DrawBitmap1Bit(154, 50, 50, 15,borderfull5015, 0x0f,0);	//填充Buffer_DrawString(8, 53, "Protect",0x0f, 10,0);
Buffer_DrawString(59, 53, "Storage",0x0f, 10,0);
Buffer_DrawString(113, 53, "System",0x0f, 10,0);
Buffer_DrawString(166, 53, "Power",0x0f, 10,1);
Buffer_DrawString(222, 53, "ESC",0x0f, 10,0);Buffer_Swap(); // 显示
}/*** @number 4* @brief 菜单界面函数-》Storage * @param  无* @retval 无*/
void Menu_Interface5(void)
{Buffer_ClearBackBuffer();
Buffer_DrawBitmap1Bit(7, 3, 38, 38,epd_bitmap_protect3838, 0x0f,0);
Buffer_DrawBitmap1Bit(58, 3, 38, 38,epd_bitmap_storage3838, 0x0f,0);	
Buffer_DrawBitmap1Bit(109, 3, 38, 38,epd_bitmap_system3838, 0x0f,0);	
Buffer_DrawBitmap1Bit(160, 3, 38, 38,epd_bitmap_power3838, 0x0f,0);	
Buffer_DrawBitmap1Bit(211, 3, 38, 38,epd_bitmap_esc3838, 0x0f,0);	Buffer_DrawBitmap1Bit(0, 49, 51, 16,border5116, 0x0f,0);
Buffer_DrawBitmap1Bit(51, 49, 51, 16,border5116, 0x0f,0);	
Buffer_DrawBitmap1Bit(102, 49, 51, 16,border5116, 0x0f,0);	
Buffer_DrawBitmap1Bit(153, 49, 51, 16,border5116, 0x0f,0);	
Buffer_DrawBitmap1Bit(204, 49, 52, 16,border5216, 0x0f,0);		Buffer_DrawBitmap1Bit(205, 50, 50, 15,borderfull5015, 0x0f,0);	//填充Buffer_DrawString(8, 53, "Protect",0x0f, 10,0);
Buffer_DrawString(59, 53, "Storage",0x0f, 10,0);
Buffer_DrawString(113, 53, "System",0x0f, 10,0);
Buffer_DrawString(166, 53, "Power",0x0f, 10,0);
Buffer_DrawString(222, 53, "ESC",0x0f, 10,1);Buffer_Swap(); // 显示
}/*** @number 5* @brief 保护菜单界面函数-》OPV* @param  无* @retval 无*/
void Protect_Interface1(void)
{
Buffer_ClearBackBuffer();
Buffer_DrawSquare(0, 0, 105, 16, 0x0f,0);
Buffer_DrawString(6, 0, "Menu:Protect",0x0f, 16,1);char value_str[20];	
Buffer_DrawBitmap1Bit(8, 18, 12, 12,epd_bitmap_select1212, 0x0f,0);
snprintf(value_str, sizeof(value_str), "OVP: %.3fV", protect_values.ovp_value);
Buffer_DrawString(24, 16, value_str, 0x0f, 16, 0);Buffer_DrawBitmap1Bit(128, 18, 12, 12,epd_bitmap_unselect1212, 0x0f,0);
snprintf(value_str, sizeof(value_str), "ULV: %.3fV", protect_values.ulv_value);
Buffer_DrawString(144, 16, value_str, 0x0f, 16, 0);Buffer_DrawBitmap1Bit(8, 34, 12, 12,epd_bitmap_unselect1212, 0x0f,0);
snprintf(value_str, sizeof(value_str), "OCP: %.3fA", protect_values.ocp_value);
Buffer_DrawString(24, 32, value_str, 0x0f, 16, 0);
Buffer_Swap(); // 显示KeyCode key = CH452_Read();  // 获取按键值}/*** @number 6* @brief 保护菜单界面函数-》ULV* @param  无* @retval 无*/
void Protect_Interface2(void)
{char value_str[20];
Buffer_ClearBackBuffer();
Buffer_DrawSquare(0, 0, 105, 16, 0x0f,0);
Buffer_DrawString(6, 0, "Menu:Protect",0x0f, 16,1);
Buffer_DrawBitmap1Bit(8, 18, 12, 12,epd_bitmap_unselect1212, 0x0f,0);
snprintf(value_str, sizeof(value_str), "OVP: %.3fV", protect_values.ovp_value);
Buffer_DrawString(24, 16, value_str, 0x0f, 16, 0);
Buffer_DrawBitmap1Bit(128, 18, 12, 12,epd_bitmap_select1212, 0x0f,0);
snprintf(value_str, sizeof(value_str), "ULV: %.3fV", protect_values.ulv_value);
Buffer_DrawString(144, 16, value_str, 0x0f, 16, 0);
Buffer_DrawBitmap1Bit(8, 34, 12, 12,epd_bitmap_unselect1212, 0x0f,0);
snprintf(value_str, sizeof(value_str), "OCP: %.3fA", protect_values.ocp_value);
Buffer_DrawString(24, 32, value_str, 0x0f, 16, 0);
Buffer_Swap(); // 显示
}/*** @number 7* @brief 保护菜单界面函数-》OCP* @param  无* @retval 无*/
void Protect_Interface3(void)
{char value_str[20];
Buffer_ClearBackBuffer();
Buffer_DrawSquare(0, 0, 105, 16, 0x0f,0);
Buffer_DrawString(6, 0, "Menu:Protect",0x0f, 16,1);
Buffer_DrawBitmap1Bit(8, 18, 12, 12,epd_bitmap_unselect1212, 0x0f,0);
snprintf(value_str, sizeof(value_str), "OVP: %.3fV", protect_values.ovp_value);
Buffer_DrawString(24, 16, value_str, 0x0f, 16, 0);
Buffer_DrawBitmap1Bit(128, 18, 12, 12,epd_bitmap_unselect1212, 0x0f,0);
snprintf(value_str, sizeof(value_str), "ULV: %.3fV", protect_values.ulv_value);
Buffer_DrawString(144, 16, value_str, 0x0f, 16, 0);
Buffer_DrawBitmap1Bit(8, 34, 12, 12,epd_bitmap_select1212, 0x0f,0);
snprintf(value_str, sizeof(value_str), "OCP: %.3fA", protect_values.ocp_value);
Buffer_DrawString(24, 32, value_str, 0x0f, 16, 0);
Buffer_Swap(); // 显示
}/*** @number 8* @brief 保护菜单界面函数-》OCP* @param  无* @retval 无*/
void Protect_Input1(void)
{//  HAL_Delay(500);
//    KeyCode key = CH452_Read();  // 获取按键值
//    if (key != KEY_NONE) {
//			 __NOP();
//				if (key != KEY_NONE) {
//        Input_HandleKey(key);    // 处理按键
//    }
//	}//  Input_RefreshDisplay();static uint8_t is_first_entry = 1;  // 标记是否首次进入KeyCode key = CH452_Read();if (key != KEY_NONE) {if (is_first_entry && key == KEY_ENTER) {// 首次进入时忽略 ENTER,仅初始化输入状态Input_Init();is_first_entry = 0;} else {// 正常处理按键(包括后续的 ENTER 确认)Input_HandleKey(key);}}Input_RefreshDisplay();is_first_entry = 0;  // 确保后续操作正常}void Storage_Interface(void)
{fill(0x00, 0x00);OLED_ShowChar(0, 0, 'S', 24,0);	OLED_ShowChar(8, 0, 'T', 24,0);OLED_ShowChar(16, 0, 'R', 24,0);}void System_Interface(void)
{fill(0x00, 0x00); OLED_ShowChar(0, 0, 'S', 24,0);	OLED_ShowChar(8, 0, 'Y', 24,0);OLED_ShowChar(16, 0, 'S', 24,0);}

错误排查:

1.不是因为小数处理状态没有正确重置

2.把fill()删了后问题还没解决,不是fill的问题

3.其他问题(原因未知)

我把

void Protect_Interface2(void)
{
char value_str[20];
Buffer_ClearBackBuffer();
Buffer_DrawSquare(0, 0, 105, 16, 0x0f,0);
Buffer_DrawString(6, 0, "Menu:Protect",0x0f, 16,1);
Buffer_DrawBitmap1Bit(8, 18, 12, 12,epd_bitmap_unselect1212, 0x0f,0);
snprintf(value_str, sizeof(value_str), "OVP: %.3fV", protect_values.ovp_value);
Buffer_DrawString(24, 16, value_str, 0x0f, 16, 0);
Buffer_DrawBitmap1Bit(128, 18, 12, 12,epd_bitmap_select1212, 0x0f,0);
snprintf(value_str, sizeof(value_str), "ULV: %.3fV", protect_values.ulv_value);
Buffer_DrawString(144, 16, value_str, 0x0f, 16, 0);
Buffer_DrawBitmap1Bit(8, 34, 12, 12,epd_bitmap_unselect1212, 0x0f,0);
snprintf(value_str, sizeof(value_str), "OCP: %.3fA", protect_values.ocp_value);
Buffer_DrawString(24, 32, value_str, 0x0f, 16, 0);
Buffer_Swap(); // 显示
}

中的

char value_str[20];改成static	char value_str[20];
显示的所有小数点就乱码了

4.添加测试值,也出现同样问题

  • 硬编码测试值**43.14159**也无法显示小数
  • 说明不是数据存储问题,而是浮点数格式化功能失效

可能原因:(具体原因未知)

  • 工具链未正确配置浮点支持
  • **snprintf**的浮点格式化被裁剪
  • 内存对齐问题导致浮点参数传递错误
void Protect_Interface1(void)
{
Buffer_ClearBackBuffer();
Buffer_DrawSquare(0, 0, 105, 16, 0x0f,0);
Buffer_DrawString(6, 0, "Menu:Protect",0x0f, 16,1);char value_str[20];	
Buffer_DrawBitmap1Bit(8, 18, 12, 12,epd_bitmap_select1212, 0x0f,0);
snprintf(value_str, sizeof(value_str), "OVP: %06.3fV", protect_values.ovp_value);
Buffer_DrawString(24, 16, value_str, 0x0f, 16, 0);Buffer_DrawBitmap1Bit(128, 18, 12, 12,epd_bitmap_unselect1212, 0x0f,0);
snprintf(value_str, sizeof(value_str), "ULV: %.3fV", protect_values.ulv_value);
Buffer_DrawString(144, 16, value_str, 0x0f, 16, 0);Buffer_DrawBitmap1Bit(8, 34, 12, 12,epd_bitmap_unselect1212, 0x0f,0);
snprintf(value_str, sizeof(value_str), "OCP: %.3fA", protect_values.ocp_value);
Buffer_DrawString(24, 32, value_str, 0x0f, 16, 0);Buffer_DrawBitmap1Bit(128, 34, 12, 12,epd_bitmap_unselect1212, 0x0f,0);
snprintf(value_str, sizeof(value_str), "TEST:%.3f", 43.14159); // 输出 "43.142"
Buffer_DrawString(144, 32, value_str, 0x0f, 16, 0);
Buffer_Swap(); // 显示
}

我在这里加了个测试的数据,按照之前的操作之后,结果也是显示43

问题解决:替换安全的格式化函数

// 安全浮点转字符串实现
void float_to_str(float val, char* buf, int precision) {int integer = (int)val;float fraction = fabsf(val - integer);// 处理整数部分char int_str[10];sprintf(int_str, "%d", integer);strcpy(buf, int_str);// 处理小数部分if(precision > 0) {strcat(buf, ".");while(precision--) {fraction *= 10;char c = '0' + (int)fraction;strncat(buf, &c, 1);fraction -= (int)fraction;}}
}// 使用示例:
char buf[20];
float_to_str(43.14159f, buf, 3); // 输出"43.142"
http://www.xdnf.cn/news/680005.html

相关文章:

  • thinkadmin中使用layui日期选择器,数据库存储时间戳
  • 记录一ubuntu22.04做开机启动mysql、nginx、redis
  • java 数据输出占5列,右对齐
  • 柠檬(lemon)是什么东西?
  • 全视通智慧病房在护士站、病房及卫生间场景中的创新应用
  • brep2seq 源码笔记2
  • ISP图像处理算法之Demosaic
  • ns-3仿真_wifi发送链路简单解析
  • IEEE出版|2025年智能制造、机器人与自动化国际学术会议 (IMRA2025)
  • 精准调控:基于 SWMM 动态控制规则的合流制排水系统溢流污染防治技术
  • 开源模型应用落地-模型上下文协议(MCP)-安全认证的创新与实践探索(十)
  • 商城前端监控体系搭建:基于 Sentry + Lighthouse + ELK 的全链路监控实践
  • Unity Sherpa-onnx 笔记
  • Python冲刺10天-如何实现基本的矩阵运算
  • 多线程(1)
  • async和await如何捕获异常
  • 两个线程交替打印1-100
  • UWB:litepoint获取txquality里面的NRMSE
  • CSV数据处理全指南:从基础到实战
  • 第六十八篇 从“超市收银系统崩溃”看JVM性能监控与故障定位实战
  • 递归函数,数学表达式转化成递归函数
  • Spring Boot 深度集成 Ollama 指南:从聊天模型配置到生产级应用开发
  • 【STM32】HAL库 之 CAN 开发指南
  • 常用的数据分布
  • [小白]Docker部署kingbase(人大金仓)数据库[超详细]
  • win11如何重启
  • 算法打卡第八天
  • 工业控制系统的神经网络:TSN交换机是如何改变自动化通信的?
  • Python训练营打卡Day38
  • 【DSP笔记】解锁频率之秘:Z 变换与离散傅里叶变换的深度探索