嵌入式使用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"