feat(vd960Loop): 0xC0 主动上报 — 4种杂项类型轮转 + 事件优先级

杂项类型轮转:
- 0b00 时间量: 进场=车间距, 离开=通过时间, 空闲=0
- 0b01 线圈断开次数
- 0b10 车流量累计
- 0b11 继电器动作次数

上报间隔:
- 空闲稳定: 600ms, 轮流上报 0→1→2→3
- 进场/离开事件: 150ms, 强制时间量, 最高优先级

TaskLoop.h: 新增 MISC_TYPE_* / REPORT_*_TICKS 宏
           Loop154_Unit 新增 flow_count/relay_count/passtime_start/misc_value
           Loop154_States 新增 report_misc_round
TaskLoop.c: 进场时记录时间戳+累计; 离开时计算通过时间
main.c:    重写 uart_report_packet_loop_acs
This commit is contained in:
wangfq
2026-07-02 18:18:16 +08:00
parent 9bab650c27
commit 9e125f953c
3 changed files with 114 additions and 28 deletions

View File

@@ -69,6 +69,21 @@
*===========================================================================*/ *===========================================================================*/
#define LOOP_CAPTURE_MAX 4 #define LOOP_CAPTURE_MAX 4
/*===========================================================================
* 主动上报 — 杂项类型 (misc_type 低2bit)
*===========================================================================*/
#define MISC_TYPE_TIME 0 // 时间量 (通过时间/车间距)
#define MISC_TYPE_CUT 1 // 线圈断开次数
#define MISC_TYPE_FLOW 2 // 车流量数
#define MISC_TYPE_RELAY 3 // 继电器输出次数
#define MISC_TYPE_COUNT 4 // 总类型数
/*===========================================================================
* 主动上报 — 间隔 (5ms tick)
*===========================================================================*/
#define REPORT_IDLE_TICKS 120 // 空闲稳定: 120×5ms = 600ms
#define REPORT_EVENT_TICKS 30 // 事件/变化: 30×5ms = 150ms
/*=========================================================================== /*===========================================================================
* 灵敏度表4级: 0=低, 3=高) * 灵敏度表4级: 0=低, 3=高)
* 进入阈值 = Origin × SensTable[SENS] / 65536 * 进入阈值 = Origin × SensTable[SENS] / 65536
@@ -162,13 +177,20 @@ typedef struct {
/*--- 调试 ---*/ /*--- 调试 ---*/
uint32_t xn_counter; uint32_t xn_counter;
/*--- 主动上报杂项计数 ---*/
uint32_t flow_count; // 车流量累计
uint32_t relay_count; // 继电器动作次数
uint32_t passtime_start; // 进场/离开 时间戳(5ms tick)
uint32_t misc_value; // 当前要上报的杂项值
} Loop154_Unit; } Loop154_Unit;
/*=========================================================================== /*===========================================================================
* 全局状态 * 全局状态
*===========================================================================*/ *===========================================================================*/
typedef struct { typedef struct {
uint32_t report_counter; uint32_t report_counter; // 上报间隔计数器 (5ms tick)
uint8_t report_misc_round; // 空闲轮转: 0=MISC_TYPE_TIME, 1=CUT, 2=FLOW, 3=RELAY
Loop154_Unit loop_unit[LOOP_CAPTURE_MAX]; Loop154_Unit loop_unit[LOOP_CAPTURE_MAX];
} Loop154_States; } Loop154_States;

View File

@@ -518,6 +518,12 @@ void vd1_task_per_channel(Loop154_Unit *unit)
unit->loop_entry_cnt = 0; unit->loop_entry_cnt = 0;
unit->loop_freeze_cnt = 0; unit->loop_freeze_cnt = 0;
unit->loop_freeze_ref = 0; unit->loop_freeze_ref = 0;
/* 主动上报: 车流量+1, 继电器+1, 记录进场时间戳 */
unit->flow_count++;
unit->relay_count++;
unit->passtime_start = g_loop_states.report_counter; // 5ms tick
unit->misc_value = 0; // 车间距将在离开时计算
if (unit->hold_time > 0) { if (unit->hold_time > 0) {
unit->loop_VD_HOLD = 1; unit->loop_VD_HOLD = 1;
} }
@@ -597,6 +603,10 @@ void vd1_task_per_channel(Loop154_Unit *unit)
unit->Hold_CNT = 0; unit->Hold_CNT = 0;
unit->flat_ok_cnt = 0; unit->flat_ok_cnt = 0;
unit->exit_state = 0; unit->exit_state = 0;
/* 主动上报: 计算通过时间 = 当前-进场时间戳 (5ms单位) */
unit->misc_value = g_loop_states.report_counter - unit->passtime_start;
unit->relay_count++; // 离开时继电器翻转
} }
} else { } else {
unit->flat_ok_cnt = 0; unit->flat_ok_cnt = 0;
@@ -624,6 +634,10 @@ void vd1_task_per_channel(Loop154_Unit *unit)
unit->loop_ORG_SUM = 0; unit->loop_ORG_SUM = 0;
unit->Hold_CNT = 0; unit->Hold_CNT = 0;
unit->loop_cnt_release = 0; unit->loop_cnt_release = 0;
/* 主动上报: 通过时间 + 继电器 */
unit->misc_value = g_loop_states.report_counter - unit->passtime_start;
unit->relay_count++;
} }
} else { } else {
if (unit->loop_cnt_release > 0) unit->loop_cnt_release = 0; if (unit->loop_cnt_release > 0) unit->loop_cnt_release = 0;

View File

@@ -414,58 +414,108 @@ void uart_report_packet_loop_acs(uint8_t flag)
{ {
uint8_t i, j, _flag_event = 0, _len = 0, _ckb = 0, _sum = 0; uint8_t i, j, _flag_event = 0, _len = 0, _ckb = 0, _sum = 0;
uint8_t _misc = 0; uint8_t _misc = 0;
uint32_t _misc_val[LOOP_CAPTURE_MAX] = {0};
uint16_t _interval;
for(i = 0; i < LOOP_CAPTURE_MAX; i++) /*--- 1. 检查是否有进场/离开事件 ---*/
{ for (i = 0; i < LOOP_CAPTURE_MAX; i++) {
Loop154_Unit *unit = &g_loop_states.loop_unit[i]; Loop154_Unit *unit = &g_loop_states.loop_unit[i];
if (unit->loop_FLAG_IN || unit->loop_FLAG_OUT) _flag_event = 1; if (unit->loop_FLAG_IN || unit->loop_FLAG_OUT) _flag_event = 1;
} }
if(_flag_event == 0) /*--- 2. 确定上报间隔 ---*/
{ if (_flag_event) {
if(g_loop_states.report_counter < 200) return; _interval = REPORT_EVENT_TICKS; // 150ms
} else {
_interval = REPORT_IDLE_TICKS; // 600ms
} }
else if (g_loop_states.report_counter < _interval) return;
{
if(g_loop_states.report_counter < 30) return; /*--- 3. 确定本轮杂项类型 ---*/
if (_flag_event) {
_misc = MISC_TYPE_TIME; // 事件优先级最高
} else {
_misc = g_loop_states.report_misc_round;
g_loop_states.report_misc_round++;
if (g_loop_states.report_misc_round >= MISC_TYPE_COUNT)
g_loop_states.report_misc_round = 0;
} }
/*--- 4. 准备各通道杂项值 ---*/
for (i = 0; i < LOOP_CAPTURE_MAX; i++) {
Loop154_Unit *unit = &g_loop_states.loop_unit[i];
switch (_misc) {
case MISC_TYPE_TIME:
if (_flag_event) {
_misc_val[i] = unit->misc_value; // 已在上层计算
} else {
_misc_val[i] = 0; // 空闲时为0
}
break;
case MISC_TYPE_CUT:
_misc_val[i] = unit->disconnect_count;
break;
case MISC_TYPE_FLOW:
_misc_val[i] = unit->flow_count;
break;
case MISC_TYPE_RELAY:
_misc_val[i] = unit->relay_count;
break;
}
}
/*--- 5. 组包 ---*/
InitPkgUart(&g_pkg_uart_report); InitPkgUart(&g_pkg_uart_report);
i = 0; i = 0;
g_pkg_uart_report.pkg[i++] = 0x7F; g_pkg_uart_report.pkg[i++] = 0x7F;
g_pkg_uart_report.pkg[i++] = 0; g_pkg_uart_report.pkg[i++] = 0;
g_pkg_uart_report.pkg[i++] = _len; g_pkg_uart_report.pkg[i++] = _len; // placeholder
g_pkg_uart_report.pkg[i++] = CMD_SUB_SENS_REPORT; g_pkg_uart_report.pkg[i++] = CMD_SUB_SENS_REPORT;
g_pkg_uart_report.pkg[i++] = SENS_MULTI_LOOP_DYNAMIC; g_pkg_uart_report.pkg[i++] = SENS_MULTI_LOOP_DYNAMIC;
g_pkg_uart_report.pkg[i++] = 0x00; g_pkg_uart_report.pkg[i++] = 0x00; // SubPkgFlag: 无分包
for(j = 0; j < LOOP_CAPTURE_MAX; j++) for (j = 0; j < LOOP_CAPTURE_MAX; j++) {
{
Loop154_Unit *unit = &g_loop_states.loop_unit[j]; Loop154_Unit *unit = &g_loop_states.loop_unit[j];
g_pkg_uart_report.pkg[i++] = (g_loop_cng_info.loop_cng[j].loopFreq_Level << 6) | (1 << 4) | (unit->loop_SensLevel & 0x03); // 配置1: freq_level(2) | direction(1) | freq_type(1=实时) | sens(4)
g_pkg_uart_report.pkg[i++] = 0 | ((!unit->loop_LOOP_OK) << 3) | (unit->loop_VD_FLAG << 2) | (_misc); g_pkg_uart_report.pkg[i++] =
// 上报频率 = sclk_freq * input_div * LPCNT / CAPVD (先乘后除避免精度损失) (g_loop_cng_info.loop_cng[j].loopFreq_Level << 6)
| (1 << 4) // freq_type=实时
| (unit->loop_SensLevel & 0x03);
// 评估条件: condition(4) | loop_state(1) | car_state(1) | misc_type(2)
g_pkg_uart_report.pkg[i++] =
((!unit->loop_LOOP_OK) << 3) // loop_state
| (unit->loop_VD_FLAG << 2) // car_state
| (_misc & 0x03); // misc_type
// 频率 (3B, LE)
uint32_t _frequent = 0; uint32_t _frequent = 0;
if (unit->loop_LPCNT > 0 && unit->loop_CAPVD > 0) { if (unit->loop_LPCNT > 0 && unit->loop_CAPVD > 0) {
_frequent = (uint32_t)((uint64_t)g_crm_clocks_freq_struct.sclk_freq * g_input_div * unit->loop_LPCNT / unit->loop_CAPVD); _frequent = (uint32_t)((uint64_t)g_crm_clocks_freq_struct.sclk_freq
* g_input_div * unit->loop_LPCNT / unit->loop_CAPVD);
} }
g_pkg_uart_report.pkg[i++] = (uint8_t)(_frequent & 0xFF); g_pkg_uart_report.pkg[i++] = (uint8_t)(_frequent & 0xFF);
g_pkg_uart_report.pkg[i++] = (uint8_t)((_frequent >> 8) & 0xFF); g_pkg_uart_report.pkg[i++] = (uint8_t)((_frequent >> 8) & 0xFF);
g_pkg_uart_report.pkg[i++] = (uint8_t)((_frequent >> 16) & 0xFF); g_pkg_uart_report.pkg[i++] = (uint8_t)((_frequent >> 16) & 0xFF);
uint32_t variation = (unit->loop_Origin > unit->loop_CAPVD) ? // 变化量 (2B, LE)
(unit->loop_Origin - unit->loop_CAPVD) : (unit->loop_CAPVD - unit->loop_Origin); uint32_t variation = (unit->loop_Origin > unit->loop_CAPVD)
? (unit->loop_Origin - unit->loop_CAPVD)
: (unit->loop_CAPVD - unit->loop_Origin);
g_pkg_uart_report.pkg[i++] = (uint8_t)(variation & 0xFF); g_pkg_uart_report.pkg[i++] = (uint8_t)(variation & 0xFF);
g_pkg_uart_report.pkg[i++] = (uint8_t)((variation >> 8) & 0xFF); g_pkg_uart_report.pkg[i++] = (uint8_t)((variation >> 8) & 0xFF);
// time val: pass_time (placeholder, not tracked in DLD154V4B algo) // 杂项值 (4B, LE)
uint32_t _tmp = 0; g_pkg_uart_report.pkg[i++] = (uint8_t)(_misc_val[j] & 0xFF);
g_pkg_uart_report.pkg[i++] = (uint8_t)(_tmp & 0xFF); g_pkg_uart_report.pkg[i++] = (uint8_t)((_misc_val[j] >> 8) & 0xFF);
g_pkg_uart_report.pkg[i++] = (uint8_t)((_tmp >> 8) & 0xFF); g_pkg_uart_report.pkg[i++] = (uint8_t)((_misc_val[j] >> 16) & 0xFF);
g_pkg_uart_report.pkg[i++] = (uint8_t)((_tmp >> 16) & 0xFF); g_pkg_uart_report.pkg[i++] = (uint8_t)((_misc_val[j] >> 24) & 0xFF);
g_pkg_uart_report.pkg[i++] = (uint8_t)((_tmp >> 24) & 0xFF);
} }
/*--- 6. 回填 LEN + 校验 ---*/
g_pkg_uart_report.pkg[2] = i - 3; g_pkg_uart_report.pkg[2] = i - 3;
for (j = 1; j < i; j++) { for (j = 1; j < i; j++) {