初始化版本

This commit is contained in:
冯佳
2025-12-18 21:24:08 +08:00
parent 7e8a6d1ce3
commit 9773cb5a0a
15 changed files with 4355 additions and 0 deletions

302
src/param/menu_param.c Normal file
View File

@ -0,0 +1,302 @@
/**
* @file menu_param.c
* @brief 菜单参数管理模块(可裁剪功能)
*/
#include "menu_core.h"
#include "menu_data.h"
#if MENU_CONFIG_ENABLE_PARAM
/************************** 全局变量定义 **************************/
MenuParam s_menu_params[MENU_CONFIG_MAX_PARAMS];
/**
* @brief 查找参数通过参数ID
* @param param_id 参数ID
* @return 参数指针NULL表示未找到
*/
static MenuParam* menu_param_find(uint16_t param_id)
{
for (uint16_t i = 0; i < MENU_CONFIG_MAX_PARAMS; i++)
{
if (s_menu_params[i].is_registered && s_menu_params[i].id == param_id)
{
return &s_menu_params[i];
}
}
return NULL;
}
/**
* @brief 将浮点值转换为参数内部值(根据类型)
* @param param 参数指针
* @param value 浮点值
* @return 转换后的内部值(通过指针返回)
*/
static void menu_param_float_to_internal(MenuParam* param, float value)
{
MENU_ASSERT(param != NULL);
// 确保值在范围内
if (value < param->min_val)
{
value = param->min_val;
}
else if (value > param->max_val)
{
value = param->max_val;
}
// 应用缩放因子
value /= param->scale;
// 根据参数类型转换
switch (param->type)
{
case MENU_PARAM_TYPE_INT8:
param->value.i8 = (int8_t)value;
break;
case MENU_PARAM_TYPE_UINT8:
param->value.u8 = (uint8_t)value;
break;
case MENU_PARAM_TYPE_INT16:
param->value.i16 = (int16_t)value;
break;
case MENU_PARAM_TYPE_UINT16:
param->value.u16 = (uint16_t)value;
break;
case MENU_PARAM_TYPE_INT32:
param->value.i32 = (int32_t)value;
break;
case MENU_PARAM_TYPE_UINT32:
param->value.u32 = (uint32_t)value;
break;
case MENU_PARAM_TYPE_FLOAT:
param->value.f = value;
break;
default:
break;
}
}
/**
* @brief 将参数内部值转换为浮点值(根据类型)
* @param param 参数指针
* @return 浮点值
*/
static float menu_param_internal_to_float(const MenuParam* param)
{
MENU_ASSERT(param != NULL);
float value = 0.0f;
// 根据参数类型转换
switch (param->type)
{
case MENU_PARAM_TYPE_INT8:
value = (float)param->value.i8;
break;
case MENU_PARAM_TYPE_UINT8:
value = (float)param->value.u8;
break;
case MENU_PARAM_TYPE_INT16:
value = (float)param->value.i16;
break;
case MENU_PARAM_TYPE_UINT16:
value = (float)param->value.u16;
break;
case MENU_PARAM_TYPE_INT32:
value = (float)param->value.i32;
break;
case MENU_PARAM_TYPE_UINT32:
value = (float)param->value.u32;
break;
case MENU_PARAM_TYPE_FLOAT:
value = param->value.f;
break;
default:
break;
}
// 应用缩放因子
return value * param->scale;
}
/**
* @brief 注册参数到菜单节点(参数管理功能)
* @param node_id 菜单节点ID参数与菜单绑定
* @param param_id 参数ID唯一
* @param type 参数类型
* @param min_val 最小值(浮点型,内部自动转换)
* @param max_val 最大值(浮点型,内部自动转换)
* @param default_val 默认值(浮点型,内部自动转换)
* @param scale 缩放因子如0.1表示保留1位小数
* @return 错误码
*/
MenuErrCode menu_param_register(MenuNodeId node_id, uint16_t param_id, MenuParamType type, float min_val, float max_val, float default_val, float scale)
{
if (scale <= 0.0f)
{
return MENU_ERR_INVALID_PARAM;
}
// 查找菜单节点
MenuNode* node = menu_core_find_node(node_id);
if (node == NULL)
{
return MENU_ERR_NODE_NOT_FOUND;
}
// 检查参数ID是否已存在
if (menu_param_find(param_id) != NULL)
{
return MENU_ERR_INVALID_PARAM;
}
// 查找空闲参数位置
MenuParam* param = NULL;
for (uint16_t i = 0; i < MENU_CONFIG_MAX_PARAMS; i++)
{
if (!s_menu_params[i].is_registered)
{
param = &s_menu_params[i];
break;
}
}
if (param == NULL)
{
return MENU_ERR_OUT_OF_MEMORY;
}
// 初始化参数
MENU_MEM_SET_ZERO(param, sizeof(MenuParam));
param->id = param_id;
param->type = type;
param->min_val = min_val;
param->max_val = max_val;
param->scale = scale;
param->is_registered = true;
// 设置默认值
menu_param_float_to_internal(param, default_val);
// 保存默认值
menu_param_float_to_internal((MenuParam*)&param->default_val, default_val);
// 将参数与菜单节点绑定
node->param_id = param_id;
MENU_DEBUG("Param registered: ID=%d, Type=%d, Range=[%0.2f, %0.2f], Default=%0.2f, Scale=%0.2f",
param_id, type, min_val, max_val, default_val, scale);
return MENU_OK;
}
/**
* @brief 设置参数值
* @param param_id 参数ID
* @param value 新值(浮点型,内部自动转换)
* @return 错误码
*/
MenuErrCode menu_param_set_value(uint16_t param_id, float value)
{
// 查找参数
MenuParam* param = menu_param_find(param_id);
if (param == NULL)
{
return MENU_ERR_NODE_NOT_FOUND;
}
// 设置新值
menu_param_float_to_internal(param, value);
MENU_DEBUG("Param set: ID=%d, Value=%0.2f (Internal: %0.2f)",
param_id, value, menu_param_internal_to_float(param));
return MENU_OK;
}
/**
* @brief 获取参数值
* @param param_id 参数ID
* @param value 输出参数,当前值(浮点型)
* @return 错误码
*/
MenuErrCode menu_param_get_value(uint16_t param_id, float* value)
{
if (value == NULL)
{
return MENU_ERR_INVALID_PARAM;
}
// 查找参数
MenuParam* param = menu_param_find(param_id);
if (param == NULL)
{
return MENU_ERR_NODE_NOT_FOUND;
}
// 获取当前值
*value = menu_param_internal_to_float(param);
MENU_DEBUG("Param get: ID=%d, Value=%0.2f", param_id, *value);
return MENU_OK;
}
/**
* @brief 将参数恢复为默认值
* @param param_id 参数ID
* @return 错误码
*/
MenuErrCode menu_param_restore_default(uint16_t param_id)
{
// 查找参数
MenuParam* param = menu_param_find(param_id);
if (param == NULL)
{
return MENU_ERR_NODE_NOT_FOUND;
}
// 恢复默认值
float default_val = menu_param_internal_to_float((const MenuParam*)&param->default_val);
return menu_param_set_value(param_id, default_val);
}
/**
* @brief 增加参数值(用于菜单上下键调整)
* @param param_id 参数ID
* @param step 步长(浮点型)
* @return 错误码
*/
MenuErrCode menu_param_increase(uint16_t param_id, float step)
{
float current_val = 0.0f;
MenuErrCode err = menu_param_get_value(param_id, &current_val);
if (err != MENU_OK)
{
return err;
}
return menu_param_set_value(param_id, current_val + step);
}
/**
* @brief 减少参数值(用于菜单上下键调整)
* @param param_id 参数ID
* @param step 步长(浮点型)
* @return 错误码
*/
MenuErrCode menu_param_decrease(uint16_t param_id, float step)
{
float current_val = 0.0f;
MenuErrCode err = menu_param_get_value(param_id, &current_val);
if (err != MENU_OK)
{
return err;
}
return menu_param_set_value(param_id, current_val - step);
}
#endif // MENU_CONFIG_ENABLE_PARAM