Add M1 single-shot temp query command; NTC trimmed-mean filter

This commit is contained in:
2026-10-09 22:47:18 +08:00
parent 318d4c60f4
commit bae56ad6cb
4 changed files with 50 additions and 9 deletions
+3 -2
View File
@@ -27,7 +27,7 @@
/* >>>>>>>>>>>>>>>>>>>>[COMMAND DEBUG]<<<<<<<<<<<<<<<<<<<< */
#define COM_DEBUG CFG_ENABLE // CFG_DISABLE: Command debug off; CFG_ENABLE: Command debug on(调试期开启)
#define COM_DEBUG CFG_DISABLE // CFG_DISABLE: Command debug off; CFG_ENABLE: Command debug on
/* 命令协议框架已移植(Src/command.c,数据口 RS485),业务命令待定义 */
/* >>>>>>>>>>>>>>>>>>>>[DEBUG ASSERTIONS DEFINE]<<<<<<<<<<<<<<<<<<<< */
@@ -82,7 +82,8 @@
#define NTC_ADC ADC0
#define NTC_ADC_CHANNEL ADC_CHANNEL_15
#define NTC_SAMPLETIME ADC_SAMPLETIME_480 /* 长采样时间(高阻 NTC 分压源) */
#define NTC_SAMPLE_COUNT 16U /* 单次测温的采样次数(均值降噪) */
#define NTC_SAMPLE_COUNT 16U /* 单次测温的采样次数 */
#define NTC_TRIM_COUNT 2U /* 修剪均值:每端去掉的最大/最小样本数(抗毛刺) */
#define NTC_VREF 3.3f /* ADC 参考电压 V */
#define NTC_ADC_MAX 4095.0f /* 12bit ADC 满量程 */
#define NTC_R_PULL 10000.0f /* 上拉电阻(硬件) */
+24 -1
View File
@@ -15,6 +15,7 @@
#include "rs485.h"
#include "uart.h"
#include "systick.h"
#include "ntc.h"
#include "board_config.h"
#include <stdint.h>
#include <stdbool.h>
@@ -326,7 +327,8 @@ static bool __attribute__((unused)) find_parameter_value(const uint8_t *cmd, uin
* - 无参数命令:M<数字>(如 M999、M888)
* - 带参数命令:M<数字>S<参数>(如 M100S123,参数为十进制)
*
* 支持的命令(FilmForge 通用骨架):
* 支持的命令(FilmForge):
* - M1: 单次查询温度值(payload 为 ASCII 摄氏度,如 "23.8";OPEN/SHRT=故障)
* - M888: 软件复位
* - M999: 输出固件版本号(v<板卡码>.<主>.<次>.<修订>)
* - M9999: 进入 OTA 模式(复位进 Bootloader)
@@ -368,6 +370,27 @@ void handle_command(const uint8_t *frame, uint8_t len) {
cmd_index = (uint8_t)(cmd_index + used_base_cmd); // 更新索引到命令后
switch (base_cmd) {
/* ==========================================
* M1 单次查询温度值
* ========================================== */
case 1u: // M1: 查询当前 NTC 温度,响应 payload 为 ASCII 摄氏度(如 "23.8")
{
float temp = ntc_read_temperature();
char temp_str[8];
uint8_t n;
if (temp <= -274.0f) {
n = (uint8_t)sprintf(temp_str, "SHRT"); // PC5 被拉到 GND(短路)
} else if (temp <= -273.0f) {
n = (uint8_t)sprintf(temp_str, "OPEN"); // PC5 被拉到 VREF(NTC 未连通)
} else {
n = (uint8_t)sprintf(temp_str, "%.1f", temp);
}
send_response(RESP_TYPE_OK, (const uint8_t *)temp_str, n);
COMMAND_DEBUG("M1 temp query: %s", temp_str);
}
return;
/* ==========================================
* M888 软件重启命令
* ========================================== */
+20 -3
View File
@@ -46,13 +46,30 @@ static uint16_t ntc_read_raw_once(void) {
}
float ntc_read_temperature(void) {
uint16_t samples[NTC_SAMPLE_COUNT];
uint32_t sum = 0U;
/* 多次采样均值降噪 */
/* 采集 NTC_SAMPLE_COUNT 个样本 */
for (uint8_t i = 0; i < NTC_SAMPLE_COUNT; i++) {
sum += ntc_read_raw_once();
samples[i] = ntc_read_raw_once();
}
float adc_val = (float)sum / (float)NTC_SAMPLE_COUNT;
/* 插入排序(16 元素,开销可忽略),为修剪均值做准备 */
for (uint8_t i = 1; i < NTC_SAMPLE_COUNT; i++) {
uint16_t key = samples[i];
int8_t j = (int8_t)(i - 1);
while (j >= 0 && samples[j] > key) {
samples[j + 1] = samples[j];
j--;
}
samples[j + 1] = key;
}
/* 修剪均值:去掉每端 NTC_TRIM_COUNT 个极值(野值/毛刺)后取平均 */
for (uint8_t i = NTC_TRIM_COUNT; i < (NTC_SAMPLE_COUNT - NTC_TRIM_COUNT); i++) {
sum += samples[i];
}
float adc_val = (float)sum / (float)(NTC_SAMPLE_COUNT - 2U * NTC_TRIM_COUNT);
/* 分压点电压:上拉 R_PULL 在 VREF 侧,NTC 接 GND 侧 */
float voltage = adc_val * NTC_VREF / NTC_ADC_MAX;
+3 -3
View File
@@ -81,10 +81,10 @@ void rs485_send(const uint8_t *data, uint16_t len) {
/* 回到接收态 */
gpio_bit_reset(RS485_DE_PORT, RS485_DE_PIN);
/* 丢弃发送期间挤入/回环进接收通道的残留字节(读 DATA 清 RBNE/ORE),
并清空接收环形缓冲,避免垃圾字节污染后续协议帧 */
/* 读一次 DATA 丢弃发送窗口内挤入接收通道的残留字节(清 RBNE/ORE)。
注意:不能清接收环形缓冲——缓冲里可能有"已收到待处理"的用户帧字节。
发送期间的回环/杂散字节由协议状态机按非包头丢弃。 */
(void)usart_data_receive(RS485_PHY);
rs485_rx_clear();
/* 恢复接收 */
usart_interrupt_enable(RS485_PHY, USART_INT_RBNE);