当前位置: 首页 > 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"

相关文章:

  • 数据要素配置如何驱动城市经济韧性的多元模式
  • 第四十五篇-Tesla P40+Qwen3-30B-A3B部署与测试
  • 电路图识图基础知识-主电路和辅助电路(七)
  • 网站资源加载出现401错误
  • 开源项目asp本地编译安装教程(ubuntu操作系统)
  • 数字孪生技术前沿探索:与5G/6G、区块链的深度融合及伦理治理框架构建
  • C# ToString格式说明符
  • Pic手机拼图软件:创意拼图,轻松上手
  • 【Elasticsearch】doc_as_upsert
  • Docker部署Spark大数据组件
  • HOW - 从0到1搭建自己的博客站点(三)
  • 学习黑客 Metasploit 主要组件之 Exploit
  • 开疆智能Profinet转Profibus网关连接Modicon TM5扩展模块案例
  • 2025-05-27 Python深度学习7——损失函数和反向传播
  • 【Elasticsearch】_update api的增量更新
  • Protocol Buffers 复杂嵌套编译指南:生成 C++ 代码
  • 【Elasticsearch】ingest对于update操作起作用吗?
  • spring4第2课-ioc控制反转
  • 医疗HMI设计规范解读:如何平衡合规性与用户体验?
  • 每日Prompt:古花卷
  • 深圳外贸英语培训/郑州seo优化培训
  • 谷歌网站推广销售/互联网营销是什么意思
  • h5免费制作平台企业秀/电脑优化软件推荐
  • 网站建设推广哪里实惠/seo搜索引擎优化到底是什么
  • 广告设计软件哪个好用/处理事件seo软件
  • 潍坊外贸网站优化/微商引流一般用什么软件