修正数码管位序: DIG4=固定F, DIG5=小数位 (APP V1.00.37)
- 布局: DIG1百位/DIG2十位/DIG3个位/DIG4固定F/DIG5小数位; DIG6-A华氏, DIG6-B小数点 - display_decode 重写为温度位序, 钳位 0~999.9, 删除 hex 解码 - disp 去掉 hex 模式; 删除 cli_parse_hex; disptest 序列改为温度值 - 仅 APP 改动, Boot 不动 (仍 V1.00.07) - docs/开发日志.md: 新增 §65
This commit is contained in:
parent
d697885694
commit
39e55e867d
18
docs/开发日志.md
18
docs/开发日志.md
@ -1595,3 +1595,21 @@ APP2 链接的镜像发向 APP1 区。设备端 END 校验(向量表 Reset PC
|
||||
原 auto 状态并回到 0.0。
|
||||
- 版本:APP `V1.00.35` → `V1.00.36`(`APP_FW_VERSION_NUM` 0x00010023 →
|
||||
0x00010024)。Boot 不动(仍 V1.00.07)。
|
||||
|
||||
## 65. 修正数码管位序:DIG4 为固定 F、DIG5 为小数位(2026-09-06,APP V1.00.37,仅 APP)
|
||||
|
||||
- 用户实测反馈修正数码管位序(原代码把 DIG1~5 当 5 个全功能数字位是错的):
|
||||
- **DIG1 = 百位、DIG2 = 十位、DIG3 = 个位、DIG4 = 固定标志 F、
|
||||
DIG5 = 温度小数位(十分位)**;DIG6-A = 华氏标志(°F)、
|
||||
DIG6-B = 小数点。
|
||||
- 修改:
|
||||
- `app_display.c` `display_decode()` 重写为温度位序:value 钳位 0.0~999.9,
|
||||
×10 后按 `[百][十][个][F][小数]` 落位(百/十前导零消隐,DIG4 恒写
|
||||
`0x0F`→seg_of_char 出 "F"),`dp_flag` 恒 1(小数位恒显示);删除
|
||||
hex 解码分支;
|
||||
- `cli_core.c` `CmdDisp` 去掉 `hex` 模式(`disp <value> [f]`,0~999.9
|
||||
一位小数),删除 `cli_parse_hex()`;`CmdDispTest` 自检序列改为
|
||||
`0.0~9.0` → `12.3/456.7/999.9` → `36.5F/36.5C`;
|
||||
- `app_display.h` 头部注释与 `display_set` 说明更新为温度位序。
|
||||
- 版本:APP `V1.00.36` → `V1.00.37`(`APP_FW_VERSION_NUM` 0x00010024 →
|
||||
0x00010025)。Boot 不动(仍 V1.00.07)。
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
@ -2,8 +2,9 @@
|
||||
* @file app_display.h
|
||||
* @brief YF30137 7-segment display driver.
|
||||
*
|
||||
* The YF30137 is a 7-pin Charlieplexed LED module:
|
||||
* - 5 seven-segment digits (DIG1..DIG5, segments A..G)
|
||||
* The YF30137 is a 7-pin Charlieplexed temperature display:
|
||||
* - DIG1 = hundreds, DIG2 = tens, DIG3 = ones, DIG4 = fixed "F",
|
||||
* DIG5 = tenths (one decimal place)
|
||||
* - DIG6 holds two single indicators: A6 = "deg F", B6 = decimal point
|
||||
*
|
||||
* A dedicated FreeRTOS task (display_task) scans the module continuously.
|
||||
@ -30,9 +31,9 @@ extern "C" {
|
||||
|
||||
/**
|
||||
* @brief Update what the display should show (read by the scan task).
|
||||
* @param value floating value to display
|
||||
* @param type DISP_TYPE_CELSIUS / DISP_TYPE_FAHRENHEIT
|
||||
* @param base DISP_BASE_DECIMAL (1 decimal place) / DISP_BASE_HEX
|
||||
* @param value temperature to display, clamped to 0.0..999.9 (1 decimal)
|
||||
* @param type DISP_TYPE_CELSIUS / DISP_TYPE_FAHRENHEIT (DIG6-A indicator)
|
||||
* @param base unused (kept for API compatibility)
|
||||
* @note Non-blocking; may be called from any task context.
|
||||
*/
|
||||
void display_set(float value, uint8_t type, uint8_t base);
|
||||
|
||||
@ -9,12 +9,12 @@
|
||||
#define __APP_VERSION_H__
|
||||
|
||||
#ifndef APP_FW_VERSION
|
||||
#define APP_FW_VERSION "V1.00.36"
|
||||
#define APP_FW_VERSION "V1.00.37"
|
||||
#endif
|
||||
|
||||
/* Numeric form used by the BLE info query / OTA records: 0x00MMmmpp */
|
||||
#ifndef APP_FW_VERSION_NUM
|
||||
#define APP_FW_VERSION_NUM 0x00010024u
|
||||
#define APP_FW_VERSION_NUM 0x00010025u
|
||||
#endif
|
||||
|
||||
#endif /* __APP_VERSION_H__ */
|
||||
|
||||
@ -228,95 +228,67 @@ static uint8_t seg_of_char(uint8_t c)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Decode the display value into 5 digit codes + a decimal-point flag.
|
||||
* @param value value to display
|
||||
* @param base DISP_BASE_DECIMAL (1 decimal place) or DISP_BASE_HEX
|
||||
* @param digits out: 5 codes (0..9, 0xA..0xF for hex, CHAR_MINUS, CHAR_BLANK)
|
||||
* @param dp_flag out: 1 = light the DIG6 decimal point
|
||||
* @brief Decode the temperature value into the display layout.
|
||||
*
|
||||
* Layout (left to right):
|
||||
* DIG1 = hundreds (百位)
|
||||
* DIG2 = tens (十位)
|
||||
* DIG3 = ones (个位)
|
||||
* DIG4 = fixed "F" (华氏/摄氏度的固定标志)
|
||||
* DIG5 = tenths (小数位)
|
||||
* DIG6-A (degF indicator) and DIG6-B (decimal point) are handled by
|
||||
* the scan loop, not here.
|
||||
*
|
||||
* @param value temperature to display, clamped to 0.0..999.9
|
||||
* @param base unused (kept for API compatibility)
|
||||
* @param digits out: 5 codes (0..9, 0xF for the fixed "F", CHAR_BLANK)
|
||||
* @param dp_flag out: 1 = light the DIG6 decimal point (always 1)
|
||||
*/
|
||||
static void display_decode(float value, uint8_t base, uint8_t *digits, uint8_t *dp_flag)
|
||||
{
|
||||
uint8_t i, j;
|
||||
int32_t scaled;
|
||||
uint8_t i;
|
||||
|
||||
(void)base;
|
||||
|
||||
*dp_flag = 0u;
|
||||
for (i = 0; i < DISP_DIGITS; i++)
|
||||
{
|
||||
digits[i] = CHAR_BLANK;
|
||||
}
|
||||
*dp_flag = 1u; /* the tenths digit is always shown, so dot is always on */
|
||||
|
||||
if (base == DISP_BASE_HEX)
|
||||
if (value < 0.0f)
|
||||
{
|
||||
uint32_t iv = (uint32_t)(int32_t)value; /* integer part */
|
||||
uint8_t hx[DISP_DIGITS];
|
||||
uint8_t lead = 1u;
|
||||
|
||||
for (j = 0; j < DISP_DIGITS; j++)
|
||||
{
|
||||
hx[DISP_DIGITS - 1u - j] = (uint8_t)(iv & 0xFu);
|
||||
iv >>= 4u;
|
||||
}
|
||||
for (j = 0; j < DISP_DIGITS; j++)
|
||||
{
|
||||
if (lead && hx[j] == 0u && j < (DISP_DIGITS - 1u))
|
||||
{
|
||||
digits[j] = CHAR_BLANK; /* blank leading zeros */
|
||||
}
|
||||
else
|
||||
{
|
||||
lead = 0u;
|
||||
digits[j] = hx[j];
|
||||
}
|
||||
}
|
||||
value = 0.0f;
|
||||
}
|
||||
else /* DISP_BASE_DECIMAL */
|
||||
if (value > 999.9f)
|
||||
{
|
||||
int neg = (value < 0.0f);
|
||||
float a = neg ? -value : value;
|
||||
int32_t scaled;
|
||||
uint8_t dc[DISP_DIGITS];
|
||||
uint8_t lead = 1u;
|
||||
|
||||
if (a > 9999.9f)
|
||||
{
|
||||
a = 9999.9f;
|
||||
}
|
||||
scaled = (int32_t)(a * 10.0f + 0.5f); /* value * 10, 1 decimal */
|
||||
|
||||
for (j = 0; j < DISP_DIGITS; j++)
|
||||
{
|
||||
dc[DISP_DIGITS - 1u - j] = (uint8_t)(scaled % 10);
|
||||
scaled /= 10;
|
||||
}
|
||||
for (j = 0; j < DISP_DIGITS; j++)
|
||||
{
|
||||
if (lead && dc[j] == 0u && j < (DISP_DIGITS - 1u))
|
||||
{
|
||||
digits[j] = CHAR_BLANK; /* blank leading zeros */
|
||||
}
|
||||
else
|
||||
{
|
||||
lead = 0u;
|
||||
digits[j] = dc[j];
|
||||
}
|
||||
}
|
||||
|
||||
*dp_flag = 1u; /* decimal point always on */
|
||||
|
||||
if (neg)
|
||||
{
|
||||
for (j = 0; j < DISP_DIGITS; j++)
|
||||
{
|
||||
if (digits[j] != CHAR_BLANK)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j > 0u)
|
||||
{
|
||||
digits[j - 1u] = CHAR_MINUS; /* '-' just before the value */
|
||||
}
|
||||
}
|
||||
value = 999.9f;
|
||||
}
|
||||
|
||||
/* value * 10 -> [hundreds][tens][ones][-][tenths] */
|
||||
scaled = (int32_t)(value * 10.0f + 0.5f);
|
||||
|
||||
digits[4] = (uint8_t)(scaled % 10); /* DIG5 = tenths */
|
||||
scaled /= 10;
|
||||
digits[2] = (uint8_t)(scaled % 10); /* DIG3 = ones */
|
||||
scaled /= 10;
|
||||
digits[1] = (uint8_t)(scaled % 10); /* DIG2 = tens */
|
||||
scaled /= 10;
|
||||
digits[0] = (uint8_t)(scaled % 10); /* DIG1 = hundreds */
|
||||
|
||||
/* blank leading zeros (hundreds, then tens) */
|
||||
if (digits[0] == 0u)
|
||||
{
|
||||
digits[0] = CHAR_BLANK;
|
||||
}
|
||||
if (digits[0] == CHAR_BLANK && digits[1] == 0u)
|
||||
{
|
||||
digits[1] = CHAR_BLANK;
|
||||
}
|
||||
|
||||
/* DIG4 = fixed "F" */
|
||||
digits[3] = 0x0Fu; /* seg_of_char(0xF) -> F */
|
||||
}
|
||||
|
||||
/* Public functions -----------------------------------------------------------*/
|
||||
|
||||
@ -519,104 +519,60 @@ static int cli_parse_float(const char* s, float* out)
|
||||
* @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.
|
||||
* @brief "disp <value> [f]": set the temperature display.
|
||||
* value 0.0..999.9 is shown as [hundreds][tens][ones][F][tenths];
|
||||
* "f" turns on the DIG6-A degF indicator.
|
||||
*/
|
||||
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;
|
||||
uint8_t type = DISP_TYPE_CELSIUS;
|
||||
float value;
|
||||
int i;
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
cli_write("usage: disp <value> [f] [hex] (e.g. disp 36.5, disp ff hex)\r\n");
|
||||
cli_write("usage: disp <value> [f] (e.g. disp 36.5, disp 36.5 f)\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]);
|
||||
cli_printf("bad mode: %s (use f)\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))
|
||||
if (!cli_parse_float(argv[1], &value))
|
||||
{
|
||||
cli_printf("bad value: %s\r\n", argv[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
display_set(value, type, base);
|
||||
display_set(value, type, DISP_BASE_DECIMAL);
|
||||
|
||||
if (base == DISP_BASE_HEX)
|
||||
/* echo the (clamped) value actually shown */
|
||||
{
|
||||
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)
|
||||
float shown = value;
|
||||
int scaled, ip, fp;
|
||||
|
||||
if (shown < 0.0f)
|
||||
{
|
||||
fp = -fp;
|
||||
shown = 0.0f;
|
||||
}
|
||||
if (shown > 999.9f)
|
||||
{
|
||||
shown = 999.9f;
|
||||
}
|
||||
scaled = (int)(shown * 10.0f + 0.5f);
|
||||
ip = scaled / 10;
|
||||
fp = scaled - ip * 10;
|
||||
cli_printf("display = %d.%d %c\r\n", ip, fp,
|
||||
(type == DISP_TYPE_FAHRENHEIT) ? 'F' : 'C');
|
||||
}
|
||||
@ -840,9 +796,9 @@ static void CmdDispSet(int argc, char* argv[])
|
||||
|
||||
/**
|
||||
* @brief "disptest": automated display self-test. Cycles the display through
|
||||
* digits 0..9, "88888" (all segments), hex "ABCDE", a degF value and
|
||||
* "-123.4" so every digit/segment can be verified visually. Restores
|
||||
* the previous auto-scan state when finished.
|
||||
* ones digits 0..9, multi-digit values, max 999.9 and a degF value so
|
||||
* every digit position (hundreds/tens/ones/F/tenths) and the DIG6-A
|
||||
* indicator can be verified visually. Restores auto-scan when done.
|
||||
*/
|
||||
static void CmdDispTest(int argc, char* argv[])
|
||||
{
|
||||
@ -857,7 +813,7 @@ static void CmdDispTest(int argc, char* argv[])
|
||||
/* the test drives values through display_set(), so auto must be on */
|
||||
display_auto_set(1u);
|
||||
|
||||
cli_write("display self-test: 0..9 -> 88888 -> ABCDE -> 72.0F -> -123.4\r\n");
|
||||
cli_write("display self-test: 0.0..9.0 -> 12.3/456.7/999.9 -> 36.5F\r\n");
|
||||
|
||||
for (i = 0; i < 10u; i++)
|
||||
{
|
||||
@ -866,20 +822,24 @@ static void CmdDispTest(int argc, char* argv[])
|
||||
vTaskDelay(pdMS_TO_TICKS(500));
|
||||
}
|
||||
|
||||
display_set(8888.8f, DISP_TYPE_CELSIUS, DISP_BASE_DECIMAL);
|
||||
cli_write(" 88888 (all segments)\r\n");
|
||||
display_set(12.3f, DISP_TYPE_CELSIUS, DISP_BASE_DECIMAL);
|
||||
cli_write(" 12.3\r\n");
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
|
||||
display_set(456.7f, DISP_TYPE_CELSIUS, DISP_BASE_DECIMAL);
|
||||
cli_write(" 456.7\r\n");
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
|
||||
display_set(999.9f, DISP_TYPE_CELSIUS, DISP_BASE_DECIMAL);
|
||||
cli_write(" 999.9 (max)\r\n");
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
|
||||
display_set(36.5f, DISP_TYPE_FAHRENHEIT, DISP_BASE_DECIMAL);
|
||||
cli_write(" 36.5 F (degF indicator on)\r\n");
|
||||
vTaskDelay(pdMS_TO_TICKS(1200));
|
||||
|
||||
display_set((float)0xABCDEu, DISP_TYPE_CELSIUS, DISP_BASE_HEX);
|
||||
cli_write(" ABCDE (hex)\r\n");
|
||||
vTaskDelay(pdMS_TO_TICKS(1200));
|
||||
|
||||
display_set(72.0f, DISP_TYPE_FAHRENHEIT, DISP_BASE_DECIMAL);
|
||||
cli_write(" 72.0 F (degF indicator on)\r\n");
|
||||
vTaskDelay(pdMS_TO_TICKS(1200));
|
||||
|
||||
display_set(-123.4f, DISP_TYPE_CELSIUS, DISP_BASE_DECIMAL);
|
||||
cli_write(" -123.4 (minus sign)\r\n");
|
||||
display_set(36.5f, DISP_TYPE_CELSIUS, DISP_BASE_DECIMAL);
|
||||
cli_write(" 36.5 C (degF indicator off)\r\n");
|
||||
vTaskDelay(pdMS_TO_TICKS(1200));
|
||||
|
||||
display_set(0.0f, DISP_TYPE_CELSIUS, DISP_BASE_DECIMAL);
|
||||
@ -903,10 +863,10 @@ static const CliCmd_t s_cmds[] = {
|
||||
{"ota", "ota: UART enters OTA binary frame mode (see help ota)", CmdOta},
|
||||
{"reset", "reset: system reset (reboot)", CmdReset},
|
||||
{"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},
|
||||
{"disp", "disp <value> [f]: set temperature display (0-999.9, 1 dec)", CmdDisp},
|
||||
{"dispauto", "dispauto [on|off]: enable/disable auto display scan", CmdDispAuto},
|
||||
{"dispset", "dispset <pin1-7|all> [0|1|z]: drive display pin(s)", CmdDispSet},
|
||||
{"disptest", "disptest: run display self-test (0-9/all-seg/hex/degF/minus)", CmdDispTest},
|
||||
{"disptest", "disptest: run display self-test (digits/multi/max/degF)", CmdDispTest},
|
||||
{"factory", "factory: restore params to defaults and reboot", CmdFactory},
|
||||
{"uartrst", "uartrst: re-init USART1 (460800 8N1), flush rx queue", CmdUartRst},
|
||||
{"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.
@ -1,7 +1,7 @@
|
||||
{
|
||||
"file": "mothercup_ble_prod_ota.bin",
|
||||
"target_bank": 1,
|
||||
"size": 59988,
|
||||
"crc32": "0x856F26BD",
|
||||
"version": 65572
|
||||
"size": 59660,
|
||||
"crc32": "0xF3E3A0A8",
|
||||
"version": 65573
|
||||
}
|
||||
Binary file not shown.
@ -1,7 +1,7 @@
|
||||
{
|
||||
"file": "mothercup_ble_prod_ota_app2.bin",
|
||||
"target_bank": 2,
|
||||
"size": 60288,
|
||||
"crc32": "0x5500BC3A",
|
||||
"version": 65572
|
||||
"size": 59960,
|
||||
"crc32": "0x14643A48",
|
||||
"version": 65573
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user