CLI 新增 disp 数码管显示值命令 (APP V1.00.32)

- disp <value> [f] [hex]: 设置 7 段数码管显示数值
  - 默认十进制 1 位小数 °C; f 点亮 °F 指示段; hex 按十六进制整数显示
- 手写 cli_parse_float/cli_parse_hex (不依赖 MicroLIB atof/strtod)
- 背景: 数码管 display_task 之前无任何任务调用 display_set(), 一直显示静态 0
- 仅 APP 改动, Boot 不动 (仍 V1.00.07)
- docs/开发日志.md: 新增 §60
This commit is contained in:
evan.liu 2026-09-12 10:14:58 +08:00
parent 3d6567819a
commit a93d2919a0
14 changed files with 6841 additions and 6582 deletions

View File

@ -1508,3 +1508,20 @@ APP2 链接的镜像发向 APP1 区。设备端 END 校验(向量表 Reset PC
(调试工具);其余空闲脚(PB2~5/PB10/PB12/PA2/PA3)可稳定读写。 (调试工具);其余空闲脚(PB2~5/PB10/PB12/PA2/PA3)可稳定读写。
- 版本:Boot `V1.00.06` → `V1.00.07`;APP `V1.00.30` → `V1.00.31` - 版本:Boot `V1.00.06` → `V1.00.07`;APP `V1.00.30` → `V1.00.31`
(`APP_FW_VERSION_NUM` 0x0001001E → 0x0001001F)。 (`APP_FW_VERSION_NUM` 0x0001001E → 0x0001001F)。
## 60. CLI 新增 `disp` 数码管显示值设置命令(2026-09-06,APP V1.00.32,仅 APP)
- 背景:§58 的数码管驱动只有 `display_task` 扫描,全局值
`g_disp_value/g_disp_type/g_disp_base` 初值 0.0/°C/十进制,**全程无任何
任务调用 `display_set()`**(链接 map 显示 `i.display_set` 被裁掉),
数码管一直显示静态的"0"(小数点常亮)。本次加 `disp` 命令提供修改入口。
- 实现(`mcm-ddc-ble/src/cli_core.c`,仅 APP):
- `cli_parse_float()`:手写十进制浮点解析(符号/整数/1 位小数,不依赖
MicroLIB 的 atof/strtod);
- `cli_parse_hex()`:手写十六进制整数解析(可带 `0x` 前缀);
- `CmdDisp`:`disp <value> [f] [hex]`——默认十进制 °C;`f` 点亮 °F 指示段
(DIG6 A6);`hex` 按十六进制整数显示;先扫模式标志再按进制解析数值,
调 `display_set(value, type, base)` 后回显;
- 命令表注册:`disp <value> [f] [hex]: set 7-seg display value`。
- 版本:APP `V1.00.31` → `V1.00.32`(`APP_FW_VERSION_NUM` 0x0001001F →
0x00010020)。Boot 不动(仍 V1.00.07)。

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -9,12 +9,12 @@
#define __APP_VERSION_H__ #define __APP_VERSION_H__
#ifndef APP_FW_VERSION #ifndef APP_FW_VERSION
#define APP_FW_VERSION "V1.00.31" #define APP_FW_VERSION "V1.00.32"
#endif #endif
/* Numeric form used by the BLE info query / OTA records: 0x00MMmmpp */ /* Numeric form used by the BLE info query / OTA records: 0x00MMmmpp */
#ifndef APP_FW_VERSION_NUM #ifndef APP_FW_VERSION_NUM
#define APP_FW_VERSION_NUM 0x0001001Fu #define APP_FW_VERSION_NUM 0x00010020u
#endif #endif
#endif /* __APP_VERSION_H__ */ #endif /* __APP_VERSION_H__ */

View File

@ -15,6 +15,7 @@
#include "app_params.h" #include "app_params.h"
#include "app_bootset.h" #include "app_bootset.h"
#include "app_cli.h" #include "app_cli.h"
#include "app_display.h"
#include "n32wb03x.h" /* SystemTrimValueGet (temp debug) */ #include "n32wb03x.h" /* SystemTrimValueGet (temp debug) */
#include <stdio.h> #include <stdio.h>
@ -468,6 +469,159 @@ static void CmdPinSet(int argc, char* argv[])
} }
} }
/**
* @brief Parse a decimal floating-point number ("36.5", "-1.2", "88").
* @return 1 on success, 0 on bad input.
*/
static int cli_parse_float(const char* s, float* out)
{
float v = 0.0f;
float frac = 0.1f;
int neg = 0;
int any = 0;
if (*s == '-')
{
neg = 1;
s++;
}
else if (*s == '+')
{
s++;
}
while (*s >= '0' && *s <= '9')
{
v = v * 10.0f + (float)(*s - '0');
s++;
any = 1;
}
if (*s == '.')
{
s++;
while (*s >= '0' && *s <= '9')
{
v += frac * (float)(*s - '0');
frac *= 0.1f;
s++;
any = 1;
}
}
if (!any || *s != '\0')
{
return 0;
}
*out = neg ? -v : v;
return 1;
}
/**
* @brief Parse a hexadecimal integer ("ff", "0xFF", "10").
* @return 1 on success, 0 on bad input.
*/
static int cli_parse_hex(const char* s, uint32_t* out)
{
uint32_t v = 0u;
int any = 0;
if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X'))
{
s += 2;
}
for (;;)
{
uint32_t d;
char c = *s;
if (c >= '0' && c <= '9') { d = (uint32_t)(c - '0'); }
else if (c >= 'a' && c <= 'f') { d = (uint32_t)(c - 'a' + 10); }
else if (c >= 'A' && c <= 'F') { d = (uint32_t)(c - 'A' + 10); }
else { break; }
v = (v << 4) | d;
any = 1;
s++;
}
if (!any || *s != '\0')
{
return 0;
}
*out = v;
return 1;
}
/**
* @brief "disp <value> [f] [hex]": set what the 7-seg display shows.
* Default: decimal with 1 decimal place, Celsius (degF indicator off).
* "f" turns on the degF indicator; "hex" displays the integer in hex.
*/
static void CmdDisp(int argc, char* argv[])
{
uint8_t type = DISP_TYPE_CELSIUS;
uint8_t base = DISP_BASE_DECIMAL;
float value = 0.0f;
uint32_t hexval = 0u;
int i;
if (argc < 2)
{
cli_write("usage: disp <value> [f] [hex] (e.g. disp 36.5, disp ff hex)\r\n");
return;
}
/* scan mode flags first (so the value is parsed in the right base) */
for (i = 2; i < argc; i++)
{
if (strcmp(argv[i], "f") == 0)
{
type = DISP_TYPE_FAHRENHEIT;
}
else if (strcmp(argv[i], "hex") == 0 || strcmp(argv[i], "16") == 0)
{
base = DISP_BASE_HEX;
}
else
{
cli_printf("bad mode: %s (use f / hex)\r\n", argv[i]);
return;
}
}
if (base == DISP_BASE_HEX)
{
if (!cli_parse_hex(argv[1], &hexval))
{
cli_printf("bad hex value: %s\r\n", argv[1]);
return;
}
value = (float)hexval;
}
else if (!cli_parse_float(argv[1], &value))
{
cli_printf("bad value: %s\r\n", argv[1]);
return;
}
display_set(value, type, base);
if (base == DISP_BASE_HEX)
{
cli_printf("display = 0x%lX %c\r\n", (unsigned long)hexval,
(type == DISP_TYPE_FAHRENHEIT) ? 'F' : 'C');
}
else
{
int scaled = (int)(value * 10.0f + (value < 0.0f ? -0.5f : 0.5f));
int ip = scaled / 10;
int fp = scaled - ip * 10;
if (fp < 0)
{
fp = -fp;
}
cli_printf("display = %d.%d %c\r\n", ip, fp,
(type == DISP_TYPE_FAHRENHEIT) ? 'F' : 'C');
}
}
/* Command table; add new commands here */ /* Command table; add new commands here */
static const CliCmd_t s_cmds[] = { static const CliCmd_t s_cmds[] = {
{"help", "help [cmd]: list commands / show one command's help", CmdHelp}, {"help", "help [cmd]: list commands / show one command's help", CmdHelp},
@ -484,6 +638,7 @@ static const CliCmd_t s_cmds[] = {
{"ota", "ota: UART enters OTA binary frame mode (see help ota)", CmdOta}, {"ota", "ota: UART enters OTA binary frame mode (see help ota)", CmdOta},
{"reset", "reset: system reset (reboot)", CmdReset}, {"reset", "reset: system reset (reboot)", CmdReset},
{"pinset", "pinset <pxN> [0|1]: set/read GPIO level (pa0-6/pb0-13)", CmdPinSet}, {"pinset", "pinset <pxN> [0|1]: set/read GPIO level (pa0-6/pb0-13)", CmdPinSet},
{"disp", "disp <value> [f] [hex]: set 7-seg display value", CmdDisp},
{"factory", "factory: restore params to defaults and reboot", CmdFactory}, {"factory", "factory: restore params to defaults and reboot", CmdFactory},
{"uartrst", "uartrst: re-init USART1 (460800 8N1), flush rx queue", CmdUartRst}, {"uartrst", "uartrst: re-init USART1 (460800 8N1), flush rx queue", CmdUartRst},
{"uartinfo", "uartinfo: show USART1 pins/baud/format", CmdUartInfo}, {"uartinfo", "uartinfo: show USART1 pins/baud/format", CmdUartInfo},

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -1,7 +1,7 @@
{ {
"file": "mothercup_ble_prod_ota.bin", "file": "mothercup_ble_prod_ota.bin",
"target_bank": 1, "target_bank": 1,
"size": 57264, "size": 58060,
"crc32": "0xCA35C291", "crc32": "0x71068ACD",
"version": 65567 "version": 65568
} }

View File

@ -1,7 +1,7 @@
{ {
"file": "mothercup_ble_prod_ota_app2.bin", "file": "mothercup_ble_prod_ota_app2.bin",
"target_bank": 2, "target_bank": 2,
"size": 57572, "size": 58364,
"crc32": "0x5A93FD89", "crc32": "0x6DC77249",
"version": 65567 "version": 65568
} }