Initial commit: CCU621_M firmware project with BLE debug link support.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-08 17:28:36 +08:00
commit 9ceb218f80
1597 changed files with 724159 additions and 0 deletions
@@ -0,0 +1,189 @@
# collect_ctrl 模块说明
> 路径:`app/collect_ctrl/`
> 返回主说明:[README](../../README.md)
## 1. 模块职责
- 数据采集任务(DataColl)实现:周期调度、任务锁、喂狗、周期运行日志;
- 维护“遥信/遥测(YXYC)”实时数据镜像,并对外提供统一读取接口;
- 维护“遥控(YK)”命令缓存,提供对外设置接口与任务内统一执行入口;
- 提供温度/枪温采集的循环框架(片选切换 + 周期读取 + 缓存),为后续接入真实 ADC/SPI 采集预留入口。
## 2. 关键文件
- `collect_task.c`
- `collect_task.h`
- `yk_ctrl.c`
- `yk_ctrl.h`
- `led_ctrl.c`
- `led_ctrl.h`
## 3. 功能说明
### 3.1 任务模型(DataColl
- **任务 ID 与调度**:任务 ID 使用 `TASK_ID_DataColl`;睡眠周期通过 `MY_GET_SLEEP_TIME(TASK_ID_DataColl)` 获取(宏 `DATACOLL_SLEEP_TIME_MS()`)。
- **任务锁**:通过 `u8_task_lock_ctrl()` 实现互斥(宏 `DATACOLL_LOCK_INIT/TAKE/GIVE`),保证“写入更新/对外读取”之间的数据一致性。
- **喂狗**:任务循环内调用 `v_wdt_setFlag(TASK_ID_DataColl)`(宏 `DATACOLL_FEED_DOG()`)。
- **运行日志**:按 `TASK_RUN_PRINT_TIME` 周期尝试获取锁并输出运行日志(避免与数据更新互相干扰)。
对应入口:`v_collect_task(void *arg)`、初始化:`v_collect_task_init()``v_init_collect()`
### 3.2 实时数据镜像(遥信/遥测,YXYC)
模块内部维护全局镜像 `sys_yxyc_data`(类型 `YXYC_DATA`),包含:
- **整桩数据**`SYS_RT_DATA s_sys_rt_data`
- **单枪数据**`GUN_RT_DATA s_gun_rt_data[GUN_MAX_CNT]`
- **枪数量/适配项**`u8_gunNo``u8_gunLockNeg[]`(用于“电子锁输入取反”适配)
数据更新入口:
- `v_update_gun_yxyc(GUN_RT_DATA* p_gun, U8_T u8_gunNo)`:更新指定枪的遥信/遥测字段(内部会根据 `u8_gunLockNeg` 处理锁输入取反)。
- 采集来源按“对接外部接口”集中在四个函数内(后续需要改点位时,直接改这些 switch-case 即可):
- `u8_coll_get_yx_sys()`:整桩遥信(目前主要来自**副板 DI13~DI19**,通过 `SubComm` 缓存读取)。
- `u8_coll_get_yx_gun()`:单枪遥信(目前来自**主板 DI1~DI10** 等)。
- `f32_coll_get_yc_gun()`:单枪遥测(目前来自 ADC 缓存读取 `f_get_gun_data(E_ADC_TYPE_xxx)`)。
- `f32_coll_get_yc_sys()`:整桩遥测(目前用进/出风口温度缓存映射为桩温1/2)。
对外读取接口(均带任务锁保护):
- `U8_T u8_get_yxyc_data(SYS_RT_DATA *pile_data, GUN_RT_DATA *gun_data, U8_T u8_gunNo)`:一次性拷贝获取整桩 + 指定枪数据(任一入参为 NULL 则跳过该部分)。
- `U8_T u8_get_gun_yx_data(E_YX_GUN gun_yx_type, U8_T u8_gunNo)`:读取单枪遥信(如枪连接、电子锁、接触器、熔断器、归位等)。
- `F32_T f32_get_gun_yc_data(E_YC_GUN gun_yc_type, U8_T u8_gunNo)`:读取单枪遥测(母线电压、枪温、回路电流等)。
- `U8_T u8_get_sys_yx_data(E_YX_SYS sys_yx_type)`:读取整桩遥信(急停、门禁、水浸、防雷、烟感、交流接触器/断路器等)。
- `F32_T f32_get_sys_yc_data(E_YC_SYS sys_yc_type)`:读取整桩遥测(例如桩温 1/2)。
### 3.3 遥控命令缓存与执行(YK)
为了避免外部模块“直接打 DO”导致状态不可追踪/动作不可控,本模块提供“遥控命令缓存 → 任务内统一执行”的机制:
- **代码位置**YK 逻辑已从 `collect_task.c` 拆分为独立文件 `yk_ctrl.c/.h`,由采集任务周期调用执行。
- **缓存结构**`yk_ctrl.c` 内部维护遥控缓存(`U_YK_CTRL_DATA`),按 `YK_DATA_NUM` 维护多路控制命令(直流接触器1/2、母联、交流接触器、风扇、泄放继电器、枪 A/B 电子锁等)。
- **对外设置接口**`v_yk_ctrl_impl(E_YK_CTRL_TYPE e_type, E_CMD e_cmd)`,仅更新缓存,不直接控制 IO。
- **任务内执行入口**
- `v_yk_ctrl_init()`:清空缓存;
- `v_yk_ctrl_cheak()`:遍历缓存并调用 `v_yk_ctrl()` 执行动作;
- `v_yk_ctrl(E_YK_CTRL_TYPE e_type, E_CMD e_cmd)`:底层执行:
- **主板 DO**:直流接触器/母联/交流接触器/风机/泄放等走 `DOx()`
- **主板 PK1/PK2**:电子锁走 `ELOCK_A()/ELOCK_B()`
- **副板 DO11/DO15/DO16**12/24V 切换与辅源控制通过 `v_sub_comm_yk_set()` 下发到副板。
> 注意:`v_yk_ctrl_cheak()` 需要在 DataColl 任务周期里调用才符合“统一时序执行”的设计初衷;若外部在其他上下文频繁写入缓存,应评估并发一致性(当前 `u_yk_data` 未加锁)。
### 3.4 温度/枪温采集框架(ADC)
模块内提供“片选切换 + 周期读取 + 缓存”的枪温/温度采集框架:
- `S_ADC_GUN_CTRL s_adc_gun_ctrl`:维护通道切换状态(`flag_set/flag_read`)、计时(`u16_timer_cnt`)、缓存数组:
- `f_adc_data[6]`:4 路枪温 + 2 路进/出风口温度;
- `f_adc_dc_vol[4]`:直流母线电压采集缓存(目前示例代码保留)。
- `v_set_adc()`:按状态机切换温度传感器通道(调用 `select_temp_channel()`)。
- `v_gun_temp_loop(U16_T u16_leep_time)`:按固定节拍读取 `adc_readval()` 并推进通道切换。
- `float f_get_gun_data(E_ADC_TYPE e_type)`:统一读取缓存并做简单限幅(如温度超过 `TEMP_MAX_NUM` 则返回 0)。
> 目前枪连接状态 `u8_get_gunLink()` 以及部分 ADC 电压采集为“预留对接点”,系统集成时按硬件方案补齐实现即可。
### 3.5 指示灯状态缓存(LED
为适配“本项目不执行 `v_led_do_ctrl()` 硬件灯控动作”的现状,`led_ctrl.c` 目前主要承担**状态计算与缓存**职责:
- `v_led_state_refresh()`:按现有规则计算 A/B 两把枪 LED 状态,并写入全局缓存;
- `u8_led_state_get(u8_gunNo)`:读取指定枪 LED 状态缓存(`E_LED_STATE_TYPE` 编码);
- `v_led_ctrl(u16_sleepTime)`:不再直接下发硬件动作,内部改为刷新缓存并维护周期计数;
- `v_led_init()`:初始化时清零缓存并执行一次刷新。
`sub_comm_task.c` 在组 0x04 枪信息帧时通过上述接口读取 LED 状态,避免在 `sub_comm` 内重复维护一套灯态判定逻辑。
### 3.6 遥控/遥信/遥测点位与板卡位置表(主板/副板)
说明:
- **主板 DI/DO/PK**:见 `BSP/sys_drv_init.h``DI1~DI12``DO1~DO10``ELOCK_A/B(PK1/PK2)`)。
- **副板 DI/DO**:通过 `app/sub_comm/sub_comm_task.c` 的 USART0 协议接入:
- DI 状态命令 `0x01`:更新 `u8_sub_comm_yx_get(E_SUB_YX_xx)`(当前用 bit-map 解包)。
- DO 控制命令 `0x02`:下发 `v_sub_comm_yk_set(E_SUB_YK_DOxx, CMD_ON/OFF)`(当前 2 字节 bit-map 编码)。
#### 3.6.1 整桩遥信(系统 YX,来源:副板 DI13~DI19
```text
YX_PILE_EMERGENCY 急停开关状态 = 副板 DI13 = u8_sub_comm_yx_get(E_SUB_YX_13)
YX_PILE_DOOR 门禁开关状态 = 副板 DI14 = u8_sub_comm_yx_get(E_SUB_YX_14)
YX_PILE_WARTER 水浸开关状态 = 副板 DI15 = u8_sub_comm_yx_get(E_SUB_YX_15)
YX_PILE_KM 交流接触器状态 = 副板 DI16 = u8_sub_comm_yx_get(E_SUB_YX_16)
YX_PILE_SPD 防雷器状态 = 副板 DI17 = u8_sub_comm_yx_get(E_SUB_YX_17)
YX_PILE_QF 交流进线开关状态 = 副板 DI18 = u8_sub_comm_yx_get(E_SUB_YX_18)
YX_PILE_BUS_KM 母联直流接触器状态 = 副板 DI19 = u8_sub_comm_yx_get(E_SUB_YX_19)
YX_PILE_SMOKE 烟感状态 = 预留/待对接(当前默认 0)
```
对应实现:`collect_task.c``u8_coll_get_yx_sys()`
#### 3.6.2 单枪遥信(枪 YX,来源:主板 DI1~DI10 等)
```text
YX_GUN_LOCK 枪电子锁状态 = 主板 DI1/DI7 (A枪/B枪) (注:实际电子锁输出为 PK1/PK2,锁“状态”输入点位需按硬件对接)
YX_GUN_DC_KM 直流接触器状态 = 主板 DI2/DI6
YX_GUN_RELIF 泄放继电器状态 = 主板 DI4/DI9
YX_GUN_DC_FUSE 直流熔断器状态 = 主板 DI3/DI8
YX_GUN_HOMING 枪归位状态 = 主板 DI5/DI10
YX_GUN_AUXPOWER 低压辅源状态 = 预留/待对接(当前默认 0)
YX_GUN_LINK 枪连接状态 = u8_get_gunLink(u8_gunNo)(对接点)
```
对应实现:`collect_task.c``u8_coll_get_yx_gun()`
#### 3.6.3 单枪遥测(枪 YC,来源:ADC 缓存 `f_get_gun_data()`
```text
ADC_GUN_VOLT_PLUS 直流母线正对地电压 = f_get_gun_data(E_ADC_TYPE_GUN_DC_VOL_A1/B1)
ADC_GUN_VOLT_MINUS 直流母线负对地电压 = f_get_gun_data(E_ADC_TYPE_GUN_DC_VOL_A2/B2)
ADC_GUN_BAT_PLUS 接触器外侧正对地电压 = 复用 DC_VOL_A1/B1(后续按硬件改)
ADC_GUN_BAT_MINUS 接触器外侧负对地电压 = 复用 DC_VOL_A2/B2(后续按硬件改)
ADC_GUN_TEMP_PLUS 枪正极温度 = f_get_gun_data(E_ADC_TYPE_GUN_TEMP_A1/B1)
ADC_GUN_TEMP_MINUS 枪负极温度 = f_get_gun_data(E_ADC_TYPE_GUN_TEMP_A2/B2)
ADC_GUN_MVI 回路电流 = 预留/待对接(当前默认 0)
```
对应实现:`collect_task.c``f32_coll_get_yc_gun()`
#### 3.6.4 整桩遥测(系统 YC,来源:进/出风口温度缓存)
```text
ADC_PILE_TEMP1 桩温1 = f_get_gun_data(E_ADC_TYPE_FAN_IN_TEMP)
ADC_PILE_TEMP2 桩温2 = f_get_gun_data(E_ADC_TYPE_FAN_OUT_TEMP)
```
对应实现:`collect_task.c``f32_coll_get_yc_sys()`
#### 3.6.5 遥控(YK,主板 DO/PK + 副板 DO
```text
E_KY_TYPE_DC_CONT1 直流接触器1 = 主板 DO3
E_KY_TYPE_DC_CONT2 直流接触器2 = 主板 DO6
E_KY_TYPE_DC_CONT_BUS 直流母联接触器 = 主板 DO9
E_KY_TYPE_AC_CONT 交流接触器 = 主板 DO7
E_KY_TYPE_FAN_CONT 散热风机 = 主板 DO10
E_KY_TYPE_RELIEF_A A枪泄放 = 主板 DO2
E_KY_TYPE_RELIEF_B B枪泄放 = 主板 DO5
E_KY_TYPE_GUN_LOCK1 A枪电子锁 = 主板 PK1 (ELOCK_A)
E_KY_TYPE_GUN_LOCK2 B枪电子锁 = 主板 PK2 (ELOCK_B)
E_KY_TYPE_V12_24_SWITCH 12/24V切换 = 副板 DO11SubComm 下发)
E_KY_TYPE_AUX_POWER1 辅源1 = 副板 DO15SubComm 下发)
E_KY_TYPE_AUX_POWER2 辅源2 = 副板 DO16SubComm 下发)
```
对应实现:`yk_ctrl.c``v_yk_ctrl()`
## 4. 维护建议
- **更新与读取要保持一致性**:对外读取接口已加任务锁;如果增加“周期更新整桩/整枪数据”的逻辑,建议也在同一把 `DATACOLL` 锁内完成。
- **按职责分层扩展**:建议按“采集(驱动对接)/数据整形(单位换算、限幅、去抖)/对外发布(接口、共享区)”分层维护,避免在任务循环里堆叠业务。
- **日志节流**:保持 `TASK_RUN_PRINT_TIME` 这类周期日志输出,避免高频打印影响实时性。
- **遥控并发**:若外部可能在中断或多任务环境写 `v_yk_ctrl_impl()`,建议补充锁/临界区,或改为消息队列/事件投递。
## 5. 关联文档
- 主索引:[README](../../README.md)
- 备注:`collect_task.c` 头部注释里提到的 `collectTask_readme.md` 当前目录下未找到;如该设计文档实际存在,建议补充到本目录并在此处建立链接,便于维护对照。
+920
View File
@@ -0,0 +1,920 @@
#include "collect_ctrl/collect_task.h"
#include "collect_ctrl/yk_ctrl.h"
#include "collect_ctrl/led_ctrl.h"
#include "sub_comm/sub_comm_task.h"
#include "app_init/app_init.h"
#include "app_init/task_lock.h"
#include "mylog/mylog.h"
#include "publicdata/publicdata.h"
#include "wdt_task/wdt_task.h"
#include <stdio.h>
#include "usart.h"
#include "adc/adc_temp.h"
#include "adc/adc_spi5_batVoltCurr.h"
#include "adc/adc_spi3_insuVolt.h"
// 数据采集任务ID
#define DATACOLL_TASK_ID (TASK_ID_DataColl)
// 获取数据采集任务睡眠时间(毫秒)
#define DATACOLL_SLEEP_TIME_MS() (MY_GET_SLEEP_TIME(DATACOLL_TASK_ID))
// 初始化数据采集任务锁
#define DATACOLL_LOCK_INIT() (u8_task_lock_ctrl(DATACOLL_TASK_ID, TASK_LOCK_OP_INIT))
// 获取数据采集任务锁
#define DATACOLL_LOCK_TAKE() (u8_task_lock_ctrl(DATACOLL_TASK_ID, TASK_LOCK_OP_TAKE))
// 释放数据采集任务锁
#define DATACOLL_LOCK_GIVE() (u8_task_lock_ctrl(DATACOLL_TASK_ID, TASK_LOCK_OP_GIVE))
// 喂狗(数据采集任务)
#define DATACOLL_FEED_DOG() (v_wdt_setFlag(DATACOLL_TASK_ID))
// 数据采集任务日志记录
#define DATACOLL_LOG(fmt, ...) MYLOG_MSG(DATACOLL_TASK_ID, (fmt), ##__VA_ARGS__)
#define TEMP_MAX_NUM (2000) //温度最大值 超过则为0
#if 1 //结构定义及变量声明
typedef struct
{
U8_T u8_gunNo; //枪数量
U8_T u8_gunLockNeg[GUN_MAX_CNT]; //枪锁取反标志
SYS_RT_DATA s_sys_rt_data; //整桩遥信、遥测
GUN_RT_DATA s_gun_rt_data[GUN_MAX_CNT]; //充电枪相关遥信、遥测
} YXYC_DATA; //系统遥信、遥测结构体
typedef struct
{
U8_T flag_set; //设置标志
U8_T flag_read; //读取标志
U8_T gunLink_exit[2]; //枪连接中断
U16_T u16_timer_cnt; //周期计时
float f_adc_data[6]; //4路枪温数据 + 2路温度监测
float f_adc_dc_vol[4]; //直流母线adc电压采集值
float f_adc_bat_vol[2]; //直流外侧adc电压采集值
float f_adc_dc_cur[2]; //直流外侧adc电压采集值
float f_adc_gunLink[2]; //枪连接 adc
} S_ADC_GUN_CTRL;
S_ADC_GUN_CTRL s_adc_gun_ctrl;
YXYC_DATA sys_yxyc_data; //系统遥信、遥测
#endif
#if 1 //外部参数获取函数
/********************************
* 函数说明: 获取枪数量
* *参数说明:
* 输入参数:void
* 输出参数:U8_T u8_ret 枪数量
* 备注:
**********************************/
static U8_T u8_coll_get_gun_num()
{
U8_T u8_ret = 0;
u8_ret = g_t_share_data.t_sys_fix_cfg.u8_gunCnt; //获取充电枪数量,需调用外部参数
return u8_ret;
}
/****************************************************
*功能说明: 获取充电桩对应遥信状态或数据(功能框架)
*参数说明:
* 输入参数: E_YX_SYS sys_yx_type , 要读取的整桩遥信状态或数据
* 输出参数: U8_T 遥信状态或数据(当前默认返回 0,待系统集成对接真实数据来源)
*备注:
****************************************************/
static U8_T u8_coll_get_yx_sys(E_YX_SYS sys_yx_type)
{
U8_T u8_ret = 0;
/*
* 数据来源在此处对接(先给默认值,后续你可以直接改每个 case 的赋值):
* - 例如对接 DIu8_ret = DIxx;
* - 或对接共享数据:u8_ret = g_t_share_data.xxx;
* - 或对接 CAN 状态:u8_ret = xxx_get();
*/
switch (sys_yx_type)
{
case YX_PILE_EMERGENCY: //急停(副板 DI13
u8_ret = u8_sub_comm_yx_get(E_SUB_YX_13);
break;
case YX_PILE_DOOR: //门禁(副板 DI14
u8_ret = u8_sub_comm_yx_get(E_SUB_YX_14);
break;
case YX_PILE_WARTER: //水浸(副板 DI15
u8_ret = u8_sub_comm_yx_get(E_SUB_YX_15);
break;
case YX_PILE_KM: //交流接触器状态(副板 DI16
u8_ret = u8_sub_comm_yx_get(E_SUB_YX_16);
break;
case YX_PILE_SPD: //防雷器状态(副板 DI17
u8_ret = u8_sub_comm_yx_get(E_SUB_YX_17);
break;
case YX_PILE_QF: //交流进线开关状态(副板 DI18)
u8_ret = u8_sub_comm_yx_get(E_SUB_YX_18);
break;
case YX_PILE_BUS_KM: //母联直流接触器状态(副板 DI19)
u8_ret = u8_sub_comm_yx_get(E_SUB_YX_19);
break;
case YX_PILE_SMOKE: //烟感(
u8_ret = 0;
break;
default:
u8_ret = 0;
break;
}
return u8_ret;
}
/****************************************************
*功能说明: 获取充电枪对应遥信状态或数据
*参数说明:
* 输入参数: E_YX_GUN e_yx_gun , 要读取的充电枪状态或数据
U8_T u8_gunNo 枪号
* 输出参数: -1 失败 u8_ret 充电枪对应遥信遥测状态或数据
*备注:
****************************************************/
static U8_T u8_coll_get_yx_gun(E_YX_GUN gun_yx_type, U8_T u8_gunNo)
{
U8_T u8_ret;
switch(gun_yx_type)
{
case YX_GUN_LINK: //枪连接状态
u8_ret = u8_get_gunLink(u8_gunNo);
break;
case YX_GUN_LOCK: //枪电子锁状态
u8_ret = u8_gunNo ? DI7 : DI1;
break;
case YX_GUN_DC_KM: //直流输出接触器状态
u8_ret = u8_gunNo ? DI6 : DI2;
break;
case YX_GUN_RELIF: //泄放继电器状态
u8_ret = u8_gunNo ? DI9 : DI4;;
break;
case YX_GUN_DC_FUSE: //直流熔断器状态
u8_ret = u8_gunNo ? DI8 : DI3;
break;
case YX_GUN_AUXPOWER: //低压辅源状态
u8_ret = u8_gunNo ? AUX_B : AUX_A;
break;
case YX_GUN_HOMING: //充电枪归位
u8_ret = u8_gunNo ? DI10 : DI5;
break;
}
return u8_ret;
}
/****************************************************
*功能说明: 获取充电枪对应遥测状态或数据
*参数说明:
* 输入参数: E_YC_GUN e_yc_gun , 要读取的充电枪状态或数据
U8_T u8_gunNo 枪号
* 输出参数: F32_T -1 失败 f32_ret 充电枪对应遥信遥测状态或数据
*备注:
****************************************************/
static F32_T f32_coll_get_yc_gun(E_YC_GUN gun_yc_type, U8_T u8_gunNo)
{
F32_T f32_ret;
switch(gun_yc_type)
{
case ADC_GUN_VOLT_PLUS: //直流母线正对地电压
f32_ret = ((u8_gunNo == 0) ? f_get_gun_data(E_ADC_TYPE_GUN_DC_VOL_A1) : f_get_gun_data(E_ADC_TYPE_GUN_DC_VOL_B1));
break;
case ADC_GUN_VOLT_MINUS: //直流母线负对地电压
f32_ret = ((u8_gunNo == 0) ? f_get_gun_data(E_ADC_TYPE_GUN_DC_VOL_A2) : f_get_gun_data(E_ADC_TYPE_GUN_DC_VOL_B2));
break;
case ADC_GUN_MVI: //直流回路测量电流
f32_ret = ((u8_gunNo == 0) ? f_get_gun_data(E_ADC_TYPE_GUN_MVI_A) : f_get_gun_data(E_ADC_TYPE_GUN_MVI_B));
break;
case ADC_GUN_BAT: //接触器外侧电压
f32_ret = ((u8_gunNo == 0) ? f_get_gun_data(E_ADC_TYPE_GUN_BAT_VOL_A1) : f_get_gun_data(E_ADC_TYPE_GUN_BAT_VOL_B1));
break;
case ADC_GUN_TEMP_PLUS: //充电枪正极温度
f32_ret = ((u8_gunNo == 0) ? f_get_gun_data(E_ADC_TYPE_GUN_TEMP_A1) : f_get_gun_data(E_ADC_TYPE_GUN_TEMP_B1));
break;
case ADC_GUN_TEMP_MINUS: //充电枪负极温度
f32_ret = ((u8_gunNo == 0) ? f_get_gun_data(E_ADC_TYPE_GUN_TEMP_A2) : f_get_gun_data(E_ADC_TYPE_GUN_TEMP_B2));
break;
}
return f32_ret;
}
/****************************************************
*功能说明: 获取充电桩对应遥信遥测状态或数据
*参数说明:
* 输入参数: E_YX_SYS sys_yc_type , 要读取的整桩遥测状态或数据
U8_T u8_gunNo 枪号
* 输出参数: F32_T -1 失败 f32_ret 充电枪对应遥测状态或数据
*备注:
****************************************************/
F32_T f32_coll_get_yc_sys(E_YC_SYS sys_yc_type)
{
F32_T f32_ret;
switch(sys_yc_type)
{
case ADC_PILE_TEMP1: //桩温1
f32_ret = f_get_gun_data(E_ADC_TYPE_FAN_IN_TEMP);
break;
case ADC_PILE_TEMP2: //桩温2
f32_ret = f_get_gun_data(E_ADC_TYPE_FAN_OUT_TEMP);
break;
}
return f32_ret;
}
#endif
#if 1 //整桩遥信/遥测更新
/****************************************************
*功能说明: 更新桩体相关遥信、遥测数据
*参数说明:
* 输入参数: SYS_RT_DATA* p_sys 整桩遥测遥信结构体
* 输出参数: void
*备注:
****************************************************/
static void v_updata_sys_yxyc(SYS_RT_DATA* p_sys)
{
if (p_sys == NULL)
return;
if (DATACOLL_LOCK_TAKE() != 1U) // 获取数据采集锁
return;
/* 整桩相关遥信状态更新(数据来源当前默认 0,仅保留功能框架) */
p_sys->yx_sys_data.bit_yx_sys_data.yx_emergency = u8_coll_get_yx_sys(YX_PILE_EMERGENCY);
p_sys->yx_sys_data.bit_yx_sys_data.yx_door = u8_coll_get_yx_sys(YX_PILE_DOOR);
p_sys->yx_sys_data.bit_yx_sys_data.yx_water = u8_coll_get_yx_sys(YX_PILE_WARTER);
p_sys->yx_sys_data.bit_yx_sys_data.yx_smoke = u8_coll_get_yx_sys(YX_PILE_SMOKE);
p_sys->yx_sys_data.bit_yx_sys_data.yx_bus_KM = u8_coll_get_yx_sys(YX_PILE_BUS_KM);
p_sys->yx_sys_data.bit_yx_sys_data.yx_spd = u8_coll_get_yx_sys(YX_PILE_SPD);
p_sys->yx_sys_data.bit_yx_sys_data.yx_KM = u8_coll_get_yx_sys(YX_PILE_KM);
p_sys->yx_sys_data.bit_yx_sys_data.yx_QF = u8_coll_get_yx_sys(YX_PILE_QF);
/* 整桩相关遥测状态更新 */
p_sys->f32_yc_sys_temp1 = f32_coll_get_yc_sys(ADC_PILE_TEMP1);
p_sys->f32_yc_sys_temp2 = f32_coll_get_yc_sys(ADC_PILE_TEMP2);
DATACOLL_LOCK_GIVE(); // 释放数据采集锁
}
#endif
#if 1 //对外接口函数
/****************************************************
*功能说明: 获取遥信遥测数据结构体
*参数说明:
* 输入参数: SYS_RT_DATA *pile_data , 桩数据
GUN_RT_DATA *gun_data , 枪数据
U8_T u8_gunNo 枪号
* 输出参数: U8_T 0 失败 1成功
*最后修改时间: 20230923
****************************************************/
U8_T u8_get_yxyc_data(SYS_RT_DATA *pile_data, GUN_RT_DATA *gun_data, U8_T u8_gunNo)
{
if (DATACOLL_LOCK_TAKE() != 1U) // 获取数据采集锁
return 0;
if(pile_data != NULL)
{
memset(pile_data, 0, sizeof(SYS_RT_DATA));
memcpy(pile_data, &sys_yxyc_data.s_sys_rt_data, sizeof(SYS_RT_DATA));
}
if(gun_data != NULL)
{
memset(gun_data, 0, sizeof(GUN_RT_DATA));
memcpy(gun_data, &sys_yxyc_data.s_gun_rt_data[u8_gunNo], sizeof(GUN_RT_DATA));
}
DATACOLL_LOCK_GIVE(); // 释放数据采集锁
return 1;
}
/****************************************************
*功能说明: 获取充电枪对应遥信状态或数据
*参数说明:
* 输入参数: E_YX_GUN gun_yx_type , 要读取的充电枪状态或数据
U8_T u8_gunNo 枪号
* 输出参数: U8_T -1 失败 u8_ret 充电枪对应遥信状态或数据
*备注:
****************************************************/
U8_T u8_get_gun_yx_data(E_YX_GUN gun_yx_type, U8_T u8_gunNo)
{
if (DATACOLL_LOCK_TAKE() != 1U) // 获取数据采集锁
return 0xFFU;
GUN_RT_DATA *gun_data = &sys_yxyc_data.s_gun_rt_data[u8_gunNo];
U8_T u8_ret;
switch(gun_yx_type)
{
case YX_GUN_LINK: //枪连接状态
u8_ret = gun_data->u8_gunlink_state;
break;
case YX_GUN_LOCK: //枪电子锁状态
u8_ret = gun_data->yx_gun_data.bit_yx_gun_data.yx_gun_lock;
break;
case YX_GUN_DC_KM: //母线直流输出接触器状态
case YX_GUN_DC_KM_NEG:
u8_ret = gun_data->yx_gun_data.bit_yx_gun_data.yx_switch;
break;
case YX_GUN_RELIF: //泄放继电器状态
u8_ret = gun_data->yx_gun_data.bit_yx_gun_data.yx_relief_swich;
break;
case YX_GUN_DC_FUSE: //直流熔断器状态
u8_ret = gun_data->yx_gun_data.bit_yx_gun_data.yx_fuse;
break;
case YX_GUN_AUXPOWER: //低压辅源状态
u8_ret = gun_data->yx_gun_data.bit_yx_gun_data.yx_gun_power;
break;
case YX_GUN_HOMING: //充电枪归位
u8_ret = gun_data->yx_gun_data.bit_yx_gun_data.yx_gun_homing;
break;
}
DATACOLL_LOCK_GIVE(); // 释放数据采集锁
return u8_ret;
}
/****************************************************
*功能说明: 获取充电枪对应遥测状态或数据
*参数说明:
* 输入参数: E_YC_GUN gun_yc_type , 要读取的充电枪状态或数据
U8_T u8_gunNo 枪号
* 输出参数: F32_T -1 失败 f32_ret 充电枪对应遥测状态或数据
*备注:
****************************************************/
F32_T f32_get_gun_yc_data(E_YC_GUN gun_yc_type, U8_T u8_gunNo)
{
if (DATACOLL_LOCK_TAKE() != 1U) // 获取数据采集锁
return -1;
GUN_RT_DATA *gun_data = &sys_yxyc_data.s_gun_rt_data[u8_gunNo];
F32_T f32_ret;
switch(gun_yc_type)
{
case ADC_GUN_VOLT_PLUS: //直流母线正对地电压
f32_ret = gun_data->f32_yc_gun_vol_pos;
break;
case ADC_GUN_VOLT_MINUS: //直流母线负对地电压
f32_ret = gun_data->f32_yc_gun_vol_neg;
break;
case ADC_GUN_MVI: //直流回路测量电流
f32_ret = gun_data->f32_yc_gun_curr;
break;
case ADC_GUN_BAT: //接触器外侧正对地电压
f32_ret = gun_data->f32_yc_bat_vol_pos;
break;
case ADC_GUN_TEMP_PLUS: //充电枪正极温度
f32_ret = gun_data->f32_yc_gun_temp_pos;
break;
case ADC_GUN_TEMP_MINUS: //充电枪负极温度
f32_ret = gun_data->f32_yc_gun_temp_neg;
break;
}
DATACOLL_LOCK_GIVE(); // 释放数据采集锁
return f32_ret;
}
/****************************************************
*功能说明: 外部使用 yk功能接口,使外部不直接进行遥控动作,便于保存遥控状态且确保遥控执行完成
*参数说明:
* 输入参数: E_YK_CTRL_TYPE e_type 控制数据类型
* E_CMD e_cmd 控制数据内容 CMD_OFF = 0, ST_ON = !CMD_OFF
* 输出参数: void
*备注:
****************************************************/
/****************************************************
*功能说明: 获取充电桩对应遥信状态或数据
*参数说明:
* 输入参数: E_YX_SYS sys_yx_type , 要读取的整桩遥信状态或数据
* 输出参数: U8_T -1 失败 u8_ret 充电桩对应遥信状态或数据
*备注:
****************************************************/
U8_T u8_get_sys_yx_data(E_YX_SYS sys_yx_type)
{
if (DATACOLL_LOCK_TAKE() != 1U) // 获取数据采集锁
return 0xFFU;
SYS_RT_DATA *sys_data = &sys_yxyc_data.s_sys_rt_data;
U8_T u8_ret;
switch(sys_yx_type)
{
case YX_PILE_EMERGENCY: //急停
u8_ret = sys_data->yx_sys_data.bit_yx_sys_data.yx_emergency;
break;
case YX_PILE_DOOR: //门禁
u8_ret = sys_data->yx_sys_data.bit_yx_sys_data.yx_door;
break;
case YX_PILE_WARTER: //水浸
u8_ret = sys_data->yx_sys_data.bit_yx_sys_data.yx_water;
break;
case YX_PILE_SPD: //防雷器
u8_ret = sys_data->yx_sys_data.bit_yx_sys_data.yx_spd;
break;
case YX_PILE_SMOKE: //烟感
u8_ret = sys_data->yx_sys_data.bit_yx_sys_data.yx_smoke;
break;
case YX_PILE_BUS_KM: //母联接触器
u8_ret = sys_data->yx_sys_data.bit_yx_sys_data.yx_bus_KM;
break;
case YX_PILE_KM: //交流输入接触器
u8_ret = sys_data->yx_sys_data.bit_yx_sys_data.yx_KM;
break;
case YX_PILE_QF: //交流输入断路器
u8_ret = sys_data->yx_sys_data.bit_yx_sys_data.yx_QF;
break;
}
DATACOLL_LOCK_GIVE(); // 释放数据采集锁
return u8_ret;
}
/****************************************************
*功能说明: 获取充电桩对应遥测状态或数据
*参数说明:
* 输入参数: E_YC_SYS sys_yc_type , 要读取的整桩遥测状态或数据
* 输出参数: F32_T -1 失败 f32_ret 充电桩对应遥测状态或数据
*备注:
****************************************************/
F32_T f32_get_sys_yc_data(E_YC_SYS sys_yc_type)
{
if (DATACOLL_LOCK_TAKE() != 1U) // 获取数据采集锁
return -1;
SYS_RT_DATA *sys_data = &sys_yxyc_data.s_sys_rt_data;
F32_T f32_ret;
switch(sys_yc_type)
{
case ADC_PILE_TEMP1: //桩温1
f32_ret = sys_data->f32_yc_sys_temp1;
break;
case ADC_PILE_TEMP2: //桩温2
f32_ret = sys_data->f32_yc_sys_temp2;
break;
}
DATACOLL_LOCK_GIVE(); // 释放数据采集锁
return f32_ret;
}
#endif
#if 1 //遥信数据更新
/****************************************************
*功能说明: 更新充电枪相关遥信、遥测数据
*参数说明:
* 输入参数: GUN_RT_DATA* p_gun 充电枪遥测遥信结构体
U8_T u8_gunNo 枪号
* 输出参数: void
*备注:
****************************************************/
void v_update_gun_yxyc(GUN_RT_DATA* p_gun, U8_T u8_gunNo)
{
if (DATACOLL_LOCK_TAKE() != 1U) // 获取数据采集锁
return;
U8_T gunlockNeg = sys_yxyc_data.u8_gunLockNeg[u8_gunNo]; //获取充电枪电子锁取反状态
/****充电枪遥信状态更新****/
p_gun->u8_gunlink_state = u8_coll_get_yx_gun(YX_GUN_LINK, u8_gunNo); //充电枪连接状态,需调用外部接口
if(gunlockNeg)
p_gun->yx_gun_data.bit_yx_gun_data.yx_gun_lock = (u8_coll_get_yx_gun(YX_GUN_LOCK, u8_gunNo) ? 0 : 1); //电磁锁状态
else
p_gun->yx_gun_data.bit_yx_gun_data.yx_gun_lock = u8_coll_get_yx_gun(YX_GUN_LOCK, u8_gunNo); //电磁锁状态,需调用外部接口
p_gun->yx_gun_data.bit_yx_gun_data.yx_switch = u8_coll_get_yx_gun(YX_GUN_DC_KM, u8_gunNo); //直流输出接触器状态,需调用外部接口
p_gun->yx_gun_data.bit_yx_gun_data.yx_relief_swich = u8_coll_get_yx_gun(YX_GUN_RELIF, u8_gunNo); //直流回路泄放继电器状态,需调用外部接口
p_gun->yx_gun_data.bit_yx_gun_data.yx_fuse = u8_coll_get_yx_gun(YX_GUN_DC_FUSE, u8_gunNo); //直流回路熔断器状态,需调用外部接口
p_gun->yx_gun_data.bit_yx_gun_data.yx_gun_power = u8_coll_get_yx_gun(YX_GUN_AUXPOWER, u8_gunNo); //充电枪辅助电源状态,需调用外部接口
p_gun->yx_gun_data.bit_yx_gun_data.yx_gun_homing = u8_coll_get_yx_gun(YX_GUN_HOMING, u8_gunNo); //充电枪归位状态,需调用外部接口
/****充电枪遥测状态更新****/
p_gun->f32_yc_gun_vol_pos = f32_coll_get_yc_gun(ADC_GUN_VOLT_PLUS, u8_gunNo); //直流母线正对地电压,需调用外部接口
p_gun->f32_yc_gun_vol_neg = f32_coll_get_yc_gun(ADC_GUN_VOLT_MINUS, u8_gunNo); //直流母线负对地电压,需调用外部接口
p_gun->f32_yc_gun_curr = f32_coll_get_yc_gun(ADC_GUN_MVI, u8_gunNo); //直流回路测量电流,需调用外部接口
p_gun->f32_yc_bat_vol_pos = f32_coll_get_yc_gun(ADC_GUN_BAT, u8_gunNo); //接触器外侧正对地电压,需调用外部接口
p_gun->f32_yc_gun_temp_pos = f32_coll_get_yc_gun(ADC_GUN_TEMP_PLUS, u8_gunNo); //充电枪正极温度,需调用外部接口
p_gun->f32_yc_gun_temp_neg = f32_coll_get_yc_gun(ADC_GUN_TEMP_MINUS, u8_gunNo); //充电枪负极温度,需调用外部接口
DATACOLL_LOCK_GIVE(); // 释放数据采集锁
}
#endif
#if 1 //遥测数据更新
//枪温采集是使用一个采集口,通过片选的方式控制
void v_set_adc()
{
//温度采集选通,
/* 选择温度传感器通道的函数
通道0 TEMP5
通道1 VOL
通道2 VOL
通道3 TEMP6
通道4 TEMP1
通道5 TEMP4
通道6 TEMP2
通道7 TEMP3
*/
switch (s_adc_gun_ctrl.flag_set)
{
case 0: //设置采集A枪正极温度值 2
{
select_temp_channel(2);
s_adc_gun_ctrl.flag_read = s_adc_gun_ctrl.flag_set;
s_adc_gun_ctrl.flag_set ++;
break;
}
case 1: //设置采集A枪负极温度值 1
{
select_temp_channel(1);
s_adc_gun_ctrl.flag_read = s_adc_gun_ctrl.flag_set;
s_adc_gun_ctrl.flag_set ++;
break;
}
case 2: //设置采集B枪正极温度值
{
select_temp_channel(4);
s_adc_gun_ctrl.flag_read = s_adc_gun_ctrl.flag_set;
s_adc_gun_ctrl.flag_set ++;
break;
}
case 3: //设置采集B枪负极温度值
{
select_temp_channel(6);
s_adc_gun_ctrl.flag_read = s_adc_gun_ctrl.flag_set;
s_adc_gun_ctrl.flag_set ++;
break;
}
case 4: //设置出风口温度检测值
{
select_temp_channel(5);
s_adc_gun_ctrl.flag_read = s_adc_gun_ctrl.flag_set;
s_adc_gun_ctrl.flag_set ++;
break;
}
case 5: //设置进风口温度检测值
{
select_temp_channel(7);
s_adc_gun_ctrl.flag_read = s_adc_gun_ctrl.flag_set;
s_adc_gun_ctrl.flag_set = 0;
break;
}
default:
{
s_adc_gun_ctrl.flag_set = 0;
break;
}
}
}
/****************************************************
*功能说明: 枪温循环处理函数,用于控制片选信号并获取对应位置的温度
*参数说明:
* 输入参数: U16_T u16_leep_time 执行周期
* 输出参数: void
*备注:
*作者: jiankalka
*日期: 2025-08-07
****************************************************/
void v_gun_temp_loop(U16_T u16_leep_time)
{
if(s_adc_gun_ctrl.u16_timer_cnt % NUM_500 == 0) //100ms
{
// s_adc_gun_ctrl.f_adc_data[s_adc_gun_ctrl.flag_read] = adc_readval(); //获取枪温
// v_set_adc();
}
/* SPI5:CC1 / 外侧电压 / 回路电流,每次调用实时 SPI 采样 */
s_adc_gun_ctrl.f_adc_gunLink[0] = spi5_read_analog_voltage(0); /* A枪 CC1 */
s_adc_gun_ctrl.f_adc_gunLink[1] = spi5_read_analog_voltage(1); /* B枪 CC1 */
s_adc_gun_ctrl.f_adc_bat_vol[0] = spi5_read_analog_voltage(4); /* A枪外侧电压 */
s_adc_gun_ctrl.f_adc_bat_vol[1] = spi5_read_analog_voltage(2); /* B枪外侧电压 */
s_adc_gun_ctrl.f_adc_dc_cur[0] = spi5_read_analog_voltage(7); /* A枪回路电流 */
s_adc_gun_ctrl.f_adc_dc_cur[1] = spi5_read_analog_voltage(6); /* B枪回路电流 */
if((s_adc_gun_ctrl.u16_timer_cnt / u16_leep_time) % NUM_4 == 0) /* 4个周期采一次,10ms 任务约 40ms */
{
s_adc_gun_ctrl.f_adc_dc_vol[0] = spi3_read_analog_voltage(1, 0); //A枪正极adc电压采集值
s_adc_gun_ctrl.f_adc_dc_vol[2] = spi3_read_analog_voltage(2, 0); //B枪正极adc电压采集值
s_adc_gun_ctrl.f_adc_dc_vol[1] = spi3_read_analog_voltage(1, 1); //A枪负极adc电压采集值
s_adc_gun_ctrl.f_adc_dc_vol[3] = spi3_read_analog_voltage(2, 1); //B枪负极adc电压采集值
}
//周期计数
if(s_adc_gun_ctrl.u16_timer_cnt < 0xFF00)
s_adc_gun_ctrl.u16_timer_cnt += u16_leep_time;
else
s_adc_gun_ctrl.u16_timer_cnt = 0;
}
/****************************************************
*功能说明: 枪温处理函数初始化
*参数说明:
* 输入参数: void
* 输出参数: void
*备注:
*作者: jiankalka
*日期: 2025-08-07
****************************************************/
void v_gun_temp_init()
{
memset(&s_adc_gun_ctrl, 0, sizeof(S_ADC_GUN_CTRL));
init_adc();
}
/****************************************************
*功能说明: 充电中( CC1 在 3.2~4.8V )用比较器开关量获取枪连接状态
* PF10/PD3 高表示>4.8V断开,PF9/PA15 低表示<3.2V断开
*返回值: 0未连接 1已连接
****************************************************/
U8_T u8_get_gunLink_cmp(U8_T u8_gunNo)
{
if(u8_gunNo == 0U)
{
if(GUN1_UBAL_READ_H == SET) //A枪CC1检测(高于4.8V,未连接)
return 0U;
if(GUN1_UBAL_READ_L == RESET) //A枪CC1检测(低于3.2V,未连接)
return 0U;
}
else
{
if(GUN2_UBAL_READ_H == SET) //B枪CC1检测(高于4.8V,未连接)
return 0U;
if(GUN2_UBAL_READ_L == RESET) //B枪CC1检测(低于3.2V,未连接)
return 0U;
}
return 1U;
}
/****************************************************
*功能说明: 获取枪连接状态
*参数说明:
* 输入参数: U8_T u8_gunNo 枪号地址 0-1
* 输出参数: U8_T 插枪状态 0未插枪 1插枪
*备注:
*作者: jiankalka
*日期: 2025-08-11
****************************************************/
U8_T u8_get_gunLink(U8_T u8_gunNo)
{
//获取枪连接ADC电压值
float gunLink = s_adc_gun_ctrl.f_adc_gunLink[u8_gunNo];
//根据电压值判断枪连接状态,若在3.2~4.8V范围内
if(gunLink >= GUNLINK_CC1_VOLT_LO && gunLink <= GUNLINK_CC1_VOLT_HI)
return u8_get_gunLink_cmp(u8_gunNo);
return 0U;
}
/****************************************************
*功能说明: 获取枪adc采样值
*参数说明:
* 输入参数: E_ADC_TYPE e_type ADC类型
E_ADC_TYPE_GUN_TEMP_A1, //2 A枪温+
E_ADC_TYPE_GUN_TEMP_A2, //3 A枪温-
E_ADC_TYPE_GUN_TEMP_B1, //4 B枪温正;
E_ADC_TYPE_GUN_TEMP_B2, //5 B枪温-
E_ADC_TYPE_FAN_IN_TEMP, //6 进风口温度
E_ADC_TYPE_FAN_OUT_TEMP, //7 出风口温度
E_ADC_TYPE_GUN_DC_VOL_A1, //8 A枪DC 正极电压采集值
E_ADC_TYPE_GUN_DC_VOL_A2, //9 A枪DC 负极电压采集值
E_ADC_TYPE_GUN_DC_VOL_B1, //10 B枪DC 正极电压采集值
E_ADC_TYPE_GUN_DC_VOL_B2, //11 B枪DC 负极电压采集值
* 输出参数: float ADC采样值
*备注:
****************************************************/
float f_get_gun_data(E_ADC_TYPE e_type)
{
float f_ret = 0;
switch (e_type)
{
case E_ADC_TYPE_GUN_TEMP_A1: //2 A枪温+
f_ret = s_adc_gun_ctrl.f_adc_data[0];
if(f_ret > TEMP_MAX_NUM)
f_ret = 0;
break;
case E_ADC_TYPE_GUN_TEMP_A2: //3 A枪温-
f_ret = s_adc_gun_ctrl.f_adc_data[1];
if(f_ret > TEMP_MAX_NUM)
f_ret = 0;
break;
case E_ADC_TYPE_GUN_TEMP_B1: //4 B枪温正;
f_ret = s_adc_gun_ctrl.f_adc_data[2];
if(f_ret > TEMP_MAX_NUM)
f_ret = 0;
break;
case E_ADC_TYPE_GUN_TEMP_B2: //5 B枪温-
f_ret = s_adc_gun_ctrl.f_adc_data[3];
if(f_ret > TEMP_MAX_NUM)
f_ret = 0;
break;
case E_ADC_TYPE_FAN_IN_TEMP: //6 进风口温度
f_ret = s_adc_gun_ctrl.f_adc_data[4];
if(f_ret > TEMP_MAX_NUM)
f_ret = 0;
break;
case E_ADC_TYPE_FAN_OUT_TEMP: //7 出风口温度
f_ret = s_adc_gun_ctrl.f_adc_data[5];
if(f_ret > TEMP_MAX_NUM)
f_ret = 0;
break;
case E_ADC_TYPE_GUN_DC_VOL_A1: //8 A枪DC 正极电压采集值
f_ret = s_adc_gun_ctrl.f_adc_dc_vol[0];
if(f_ret < 0)
f_ret = 0;
break;
case E_ADC_TYPE_GUN_DC_VOL_A2: //9 A枪DC 负极电压采集值
f_ret = s_adc_gun_ctrl.f_adc_dc_vol[1];
if(f_ret < 0)
f_ret = 0;
break;
case E_ADC_TYPE_GUN_DC_VOL_B1: //10 B枪DC 正极电压采集值
f_ret = s_adc_gun_ctrl.f_adc_dc_vol[2];
if(f_ret < 0)
f_ret = 0;
break;
case E_ADC_TYPE_GUN_DC_VOL_B2: //11 B枪DC 负极电压采集值
f_ret = s_adc_gun_ctrl.f_adc_dc_vol[3];
if(f_ret < 0)
f_ret = 0;
break;
case E_ADC_TYPE_GUN_MVI_A: //12 A枪直流回路测量电流
f_ret = s_adc_gun_ctrl.f_adc_dc_cur[0];
if(f_ret < 0)
f_ret = 0;
break;
case E_ADC_TYPE_GUN_MVI_B: //13 B枪直流回路测量电流
f_ret = s_adc_gun_ctrl.f_adc_dc_cur[1];
if(f_ret < 0)
f_ret = 0;
break;
case E_ADC_TYPE_GUN_BAT_VOL_A1: //14 A枪接触器外侧电压采集值
f_ret = s_adc_gun_ctrl.f_adc_bat_vol[0];
if (f_ret < 0) {
f_ret = 0;
}
break;
;
case E_ADC_TYPE_GUN_BAT_VOL_B1: //16 B枪接触器外侧电压采集值
f_ret = s_adc_gun_ctrl.f_adc_bat_vol[1];
if (f_ret < 0) {
f_ret = 0;
}
break;
default:
break;
}
return f_ret;
}
#endif
void v_init_collect()
{
v_yk_ctrl_init(); //遥控初始化
v_led_init(); //LED状态缓存初始化
v_gun_temp_init(); //枪温采集初始化
memset(&sys_yxyc_data, 0, sizeof(YXYC_DATA)); //初始化清空数据
// 外部数据初始化,可以减少系统运行时对外部数据的获取
sys_yxyc_data.u8_gunNo = u8_coll_get_gun_num(); //获取系统充电枪数量
}
void v_collect_task(void *arg)
{
uint16_t sleep_time_ms; // 任务睡眠时间(毫秒)
uint32_t last_send_time; // 上次发送时间
uint32_t current_time; // 当前时间
U8_T i;
(void)arg; // 忽略未使用的参数
(void)DATACOLL_LOCK_INIT(); // 初始化数据采集任务锁
sleep_time_ms = DATACOLL_SLEEP_TIME_MS(); // 获取任务睡眠时间
last_send_time = get_current_seconds(); // 获取当前时间作为上次发送时间
v_init_collect(); //初始化
for (;;)
{
DATACOLL_FEED_DOG(); // 任务喂狗
current_time = get_current_seconds(); // 获取当前时间
// 检查是否需要打印任务运行信息
if ((TASK_RUN_PRINT_TIME != 0U) && (u32_safe_seconds_since(last_send_time) >= TASK_RUN_PRINT_TIME))
{
// 尝试获取锁
if (DATACOLL_LOCK_TAKE() == 1U)
{
DATACOLL_LOG("data coll task is runing, sleep time is %ums", sleep_time_ms); // 打印任务运行日志
(void)DATACOLL_LOCK_GIVE(); // 释放锁
}
last_send_time = current_time; // 更新上次发送时间
}
/* 1) 执行遥控缓冲命令(统一在采集任务内下发) */
v_yk_ctrl_cheak();
/* 2) LED状态刷新(供sub_comm读取) */
v_led_ctrl(sleep_time_ms);
/* 3) 采集循环(枪温/环境温度等缓存更新) */
v_gun_temp_loop(sleep_time_ms);
/* 4) 遥信/遥测镜像刷新(按枪循环更新) */
for (i = 0; i < sys_yxyc_data.u8_gunNo; i++)
{
v_update_gun_yxyc(&sys_yxyc_data.s_gun_rt_data[i], i);
}
/* 5) 整桩遥信/遥测刷新 */
v_gun_temp_loop(sleep_time_ms);
v_updata_sys_yxyc(&sys_yxyc_data.s_sys_rt_data);
mSleep(sleep_time_ms); // 睡眠指定时间
}
}
+159
View File
@@ -0,0 +1,159 @@
#ifndef COLLECT_TASK_H
#define COLLECT_TASK_H
#include "publicdata/type.h"
#include "publicdata/publicdata.h"
/* CC1电压阈值*/
#define GUNLINK_CC1_VOLT_LO (3.2f)
#define GUNLINK_CC1_VOLT_HI (4.8f)
/*结构定义及变量声明*/
typedef union{ //整桩相关的遥信联合体,2bit表示一个状态,预留16bit
U32_T u32_yx_sys_data;
struct
{
U32_T yx_emergency:2; //急停状态
U32_T yx_door:2; //门禁状态
U32_T yx_water:2; //水浸状态
U32_T yx_smoke:2; //烟感状态
U32_T yx_bus_KM:2; //母联直流接触器状态
U32_T yx_spd:2; //防雷器状态
U32_T yx_KM:2; //交流输入接触器状态
U32_T yx_QF:2; //交流输入断路器状态
U32_T reserve:16; //预留,16bit
}bit_yx_sys_data;
}SYS_YX_DATA;
typedef union{ //充电枪相关的遥信联合体,2bit表示一个状态,预留18bit
U32_T u32_yx_gun_data;
struct
{
U32_T yx_gun_lock:2; //充电枪电子锁状态
U32_T yx_switch:2; //直流输出接触器状态+
U32_T yx_relief_swich:2; //泄放回路接触器状态
U32_T yx_fuse:2; //直流回路熔断器状态
U32_T yx_gun_power:2; //充电枪辅助电源状态
U32_T yx_gun_homing:2; //充电枪归位状态
U32_T reserve:20; //预留,18bit
}bit_yx_gun_data;
}GUN_YX_DATA;
typedef struct //整桩遥信、遥测结构体
{
/****遥信****/
SYS_YX_DATA yx_sys_data; //整桩相关的遥信数据
/****遥测****/
F32_T f32_yc_sys_temp1; //环境温度1
F32_T f32_yc_sys_temp2; //环境温度2
}SYS_RT_DATA;
typedef struct //充电枪遥信、遥测结构体
{
U8_T u8_gunlink_state; //充电枪连接状态,0 枪未连接,1 枪已连接
/****遥信****/
GUN_YX_DATA yx_gun_data; //充电枪相关的遥信数据
/****遥测****/
F32_T f32_yc_gun_vol_pos; //直流母线正对地电压
F32_T f32_yc_gun_vol_neg; //直流母线负对地电压
F32_T f32_yc_gun_curr; //直流回路测量电流
F32_T f32_yc_bat_vol_pos; //接触器外侧正对地电压
F32_T f32_yc_bat_vol_neg; //接触器外侧负对地电压
F32_T f32_yc_gun_temp_pos; //充电枪正极温度
F32_T f32_yc_gun_temp_neg; //充电枪负极温度
}GUN_RT_DATA;
/*充电枪遥测遥信宏定义*/
typedef enum
{
/*充电枪遥信状态宏定义*/
YX_GUN_LINK, //枪连接状态
YX_GUN_LOCK, //枪电子锁
YX_GUN_DC_KM, //直流输出接触器状态
YX_GUN_DC_KM_POS = YX_GUN_DC_KM, //CCU601E_D 兼容: 正母线
YX_GUN_DC_KM_NEG , //CCU601E_D 兼容: 负母线
YX_GUN_RELIF, //泄放继电器状态
YX_GUN_DC_FUSE, //直流熔断器状态
YX_GUN_AUXPOWER, //低压辅源状态
YX_GUN_HOMING, //充电枪归位
}E_YX_GUN;
typedef enum
{
/*充电枪遥测宏定义*/
ADC_GUN_VOLT_PLUS, //直流母线正对地电压
ADC_GUN_VOLT_MINUS, //直流母线负对地电压
ADC_GUN_MVI, //直流回路测量电流
ADC_GUN_BAT, //接触器外侧正对地电压
ADC_GUN_TEMP_PLUS, //充电枪正极温度
ADC_GUN_TEMP_MINUS, //充电枪负极温度
}E_YC_GUN;
/*整桩遥信宏定义*/
typedef enum
{
/*整桩遥信状态宏定义*/
YX_PILE_EMERGENCY, //急停
YX_PILE_DOOR, //门禁
YX_PILE_WARTER, //水浸
YX_PILE_SPD, //防雷状态
YX_PILE_SMOKE, //烟感
YX_PILE_BUS_KM, //母联接触器
YX_PILE_KM, //交流输入接触器
YX_PILE_QF, //交流输入断路器
}E_YX_SYS;
/*整桩遥测宏定义*/
typedef enum
{
/*整桩遥测宏定义*/
ADC_PILE_TEMP1, //桩温1
ADC_PILE_TEMP2, //桩温2
}E_YC_SYS;
#define LED_DO_NUM (4) //LED DO控制数量
/*------ Exported struct(结构体定义) --------------------*/
typedef enum
{
E_ADC_TYPE_GUN_LINK_1=0, //0 A枪连接;
E_ADC_TYPE_GUN_LINK_2, //1 B枪连接;
E_ADC_TYPE_GUN_TEMP_A1, //2 A枪温+
E_ADC_TYPE_GUN_TEMP_A2, //3 A枪温-
E_ADC_TYPE_GUN_TEMP_B1, //4 B枪温正;
E_ADC_TYPE_GUN_TEMP_B2, //5 B枪温-
E_ADC_TYPE_FAN_IN_TEMP, //6 进风口温度
E_ADC_TYPE_FAN_OUT_TEMP, //7 出风口温度
E_ADC_TYPE_GUN_DC_VOL_A1, //8 A枪DC 正极电压采集值
E_ADC_TYPE_GUN_DC_VOL_A2, //9 A枪DC 负极电压采集值
E_ADC_TYPE_GUN_DC_VOL_B1, //10 B枪DC 正极电压采集值
E_ADC_TYPE_GUN_DC_VOL_B2, //11 B枪DC 负极电压采集值
E_ADC_TYPE_GUN_MVI_A, //12 A枪直流回路测量电流(待对接)
E_ADC_TYPE_GUN_MVI_B, //13 B枪直流回路测量电流(待对接)
E_ADC_TYPE_GUN_BAT_VOL_A1, //14 A枪接触器外侧正对地电压采集值
E_ADC_TYPE_GUN_BAT_VOL_B1, //16 B枪接触器外侧正对地电压采集值
}E_ADC_TYPE;
/*------ Exported function prototypes (函数声明) -------*/
U8_T u8_get_yxyc_data(SYS_RT_DATA *pile_data ,GUN_RT_DATA *gun_data ,U8_T u8_gunNo); //获取数据采集结构体
U8_T u8_get_gun_yx_data(E_YX_GUN gun_yx_type ,U8_T u8_gunNo); //获取枪遥信遥测数据
F32_T f32_get_gun_yc_data(E_YC_GUN gun_yc_type ,U8_T u8_gunNo); //获取枪adc采集数据
U8_T u8_get_sys_yx_data(E_YX_SYS sys_yx_type); //获取桩遥信遥测数据
F32_T f32_get_sys_yc_data(E_YC_SYS sys_yc_type); //获取桩adc采集数据
U8_T u8_get_gunLink(U8_T u8_gunNo); //获取枪连接状态
float f_get_gun_data(E_ADC_TYPE e_type);
void v_collect_task(void *arg);
U8_T u8_coll_get_gun_num(void);
#endif
+244
View File
@@ -0,0 +1,244 @@
#include "collect_ctrl/led_ctrl.h"
#include "collect_ctrl/collect_task.h"
#include "flowctrl/flow_interface.h"
#define LED_TYPE (1)
static U8_T g_u8_led_state_cache[GUN_MAX_CNT]; //两把枪指示灯状态缓存(供sub_comm读取)
#if 1 //接口函数
/**
* ************************************************************************
* @brief - 获取枪状态 返回led状态值
*
* @param[in] u8_gunNo - 抢号 0-N
*
* @return E_LED_STATE_TYPE - LED 显示状态
*
* E_LED_TYPE_GREEN_STEADY = 0, //绿灯常亮
* E_LED_TYPE_GREEN_BLINK , //绿灯闪烁
* E_LED_TYPE_RED_STEADY , //红灯常亮
* E_LED_TYPE_RED_BLINK , //红灯闪烁
* E_LED_TYPE_YELLOW_BLINK , //黄灯闪烁
*
* @author jiankalka
* @date 2025-09-05
* ************************************************************************
*/
static E_LED_STATE_TYPE e_led_get_gun_state(U8_T u8_gunNo)
{
E_LED_STATE_TYPE e_ret = E_LED_TYPE_GREEN_STEADY;
E_PILE_STATE_TYPE e_pile_state;
U8_T u8_gunLink = u8_get_gun_yx_data(YX_GUN_LINK,u8_gunNo); //枪连接状态
E_FLOW_REAL_STATE flow_state = (E_FLOW_REAL_STATE)u16_flow_put_data(u8_gunNo , E_FLOW_PUT_DATA_GUN_REAL_STATE,0); //0空闲 1充电启动 2绝缘启动 3绝缘计算完成 4绝缘检测模块停止 5开始预充 6预充完成 7充电中 8BMS通讯超时 9充电停止 10充电停止完成
U8_T u8_fault_num = u8_get_fault_sum(0,0); //整桩故障信息数量
U8_T u8_alarm_num = u8_get_fault_sum(0,1); //整桩告警信息数量
U8_T u8_gun_fault_num = u8_get_fault_sum(u8_gunNo+1,0); //该枪 故障信息数量
U8_T u8_gun_alarm_num = u8_get_fault_sum(u8_gunNo+1,1); //该枪 故障信息数量
if(u8_fault_num != 0 || u8_alarm_num != 0 || //整桩故障 则整桩报告警
u8_gun_fault_num != 0 || u8_gun_alarm_num != 0)
{
e_pile_state = E_PILE_STATE_TYPE_FAULT;//存在故障
}
else if(u8_gunLink == 0)
{
e_pile_state = E_PILE_STATE_TYPE_IDLE; //空闲未插枪
}
else if(flow_state > E_FLOW_REAL_FREE && flow_state < E_FLOW_REAL_CHARGEING) //
{
e_pile_state = E_PILE_STATE_TYPE_STARTING; //启动中
}
else if(flow_state >= E_FLOW_REAL_CHARGEING && flow_state < E_FLOW_REAL_STOP_OK) //
{
e_pile_state = E_PILE_STATE_TYPE_CHARGING; //充电中
}
else //
{
e_pile_state = E_PILE_STATE_TYPE_PLUGGED_NOT_START; //插枪未启动
}
if(g_t_share_data.t_sys_fix_cfg.u_enable.bit_enable.bit_ledGbEn == 0)
{
/*
"黄灯常亮,表示 枪处于空闲状况
红灯常亮,表示 出现故障
绿灯常亮,表示 插枪、充电完成
绿色呼吸灯,表示 准备充电阶段、绝缘检测阶段、充电阶段
若是流水类型,充电中 绿灯流水显示"
*/
switch (e_pile_state)
{
case E_PILE_STATE_TYPE_FAULT : //存在故障
{
e_ret = E_LED_TYPE_RED_STEADY; //存在故障 红灯常亮
break;
}
case E_PILE_STATE_TYPE_IDLE: //空闲未插枪
{
e_ret = E_LED_TYPE_YELLOW_STEADY; //未插枪 黄灯常亮
break;
}
case E_PILE_STATE_TYPE_STARTING: //启动中
{
e_ret = E_LED_TYPE_GREEN_BLINK; //启动中 绿灯闪烁
break;
}
case E_PILE_STATE_TYPE_CHARGING: //充电中
{
if(g_t_share_data.t_sys_fix_cfg.e_ledType == E_LED_TYPE_3)
{
e_ret = E_LED_TYPE_GREEN_RUNNING; //充电中 绿灯流水显示
}
else
{
e_ret = E_LED_TYPE_GREEN_BLINK; //充电中 绿灯闪烁
}
break;
}
case E_PILE_STATE_TYPE_PLUGGED_NOT_START: //插枪未启动
{
e_ret = E_LED_TYPE_GREEN_STEADY ; //插枪未启动 绿灯常量
break;
}
default:
break;
}
}
else
{
/*
故障 黄灯闪烁
空闲未插枪 绿灯常量
启动中 红灯闪烁
充电中 红灯常量,若是流水类型,充电中红灯流水显示
插枪未启动 绿灯闪烁
*/
switch (e_pile_state)
{
case E_PILE_STATE_TYPE_FAULT : //存在故障
{
e_ret = E_LED_TYPE_YELLOW_BLINK; //存在故障 黄灯闪烁
break;
}
case E_PILE_STATE_TYPE_IDLE: //空闲未插枪
{
e_ret = E_LED_TYPE_GREEN_STEADY; //未插枪 绿灯常亮
break;
}
case E_PILE_STATE_TYPE_STARTING: //启动中
{
e_ret = E_LED_TYPE_RED_BLINK; //启动中 红灯闪烁
break;
}
case E_PILE_STATE_TYPE_CHARGING: //充电中
{
if(g_t_share_data.t_sys_fix_cfg.e_ledType == E_LED_TYPE_3)
{
e_ret = E_LED_TYPE_RED_RUNNING; //充电中 红灯流水显示
}
else
{
e_ret = E_LED_TYPE_RED_STEADY; //充电中 红灯常亮
}
break;
}
case E_PILE_STATE_TYPE_PLUGGED_NOT_START: //插枪未启动
{
e_ret = E_LED_TYPE_GREEN_BLINK ; //插枪未启动 绿灯闪烁
break;
}
default:
break;
}
}
return e_ret;
}
#endif
/**
* ************************************************************************
* @brief - LED 控制函数
*
* @param[in] u16_sleepTime - 函数执行周期
*
*
* @author jiankalka
* @date 2025-08-05
* ************************************************************************
*/
void v_led_ctrl(U16_T u16_sleepTime)
{
/*
E_LED_TYPE_GREEN_STEADY = 0, //绿灯常亮
E_LED_TYPE_GREEN_BLINK , //绿灯闪烁
E_LED_TYPE_RED_STEADY , //红灯常亮
E_LED_TYPE_RED_BLINK , //红灯闪烁
E_LED_TYPE_YELLOW_BLINK , //黄灯闪烁
E_LED_TYPE_YELLOW_STEADY , //黄灯常亮
E_LED_TYPE_GREEN_RUNNING , //绿灯流水显示
E_LED_TYPE_RED_RUNNING , //红灯流水显示
E_LED_TYPE_YELLOW_RUNNING , //黄灯流水显示
*/
/* 本项目当前不执行 v_led_do_ctrl() 硬件动作,仅刷新全局状态缓存 */
v_led_state_refresh();
}
/**
* ************************************************************************
* @brief - LED 灯初始化
*
*
*
* @author jiankalka
* @date 2025-08-05
* ************************************************************************
*/
void v_led_init(void)
{
memset(g_u8_led_state_cache, 0, sizeof(g_u8_led_state_cache));
v_led_state_refresh(); /* 上电默认灯态,后续由 SubComm 发 0x04 前周期刷新 */
}
/**
* ************************************************************************
* @brief - 刷新两把枪 LED 状态缓存
*
* @author jiankalka
* @date 2026-04-29
* ************************************************************************
*/
void v_led_state_refresh(void)
{
g_u8_led_state_cache[GUN_A] = (U8_T)e_led_get_gun_state(GUN_A);
g_u8_led_state_cache[GUN_B] = (U8_T)e_led_get_gun_state(GUN_B);
}
/**
* ************************************************************************
* @brief - 获取指定枪 LED 状态缓存
*
* @param[in] u8_gunNo - 枪号 0-N
*
* @return U8_T - LED 状态(E_LED_STATE_TYPE 编码)
*
* @author jiankalka
* @date 2026-04-29
* ************************************************************************
*/
U8_T u8_led_state_get(U8_T u8_gunNo)
{
if (u8_gunNo >= (U8_T)GUN_MAX_CNT)
{
return 0U;
}
return g_u8_led_state_cache[u8_gunNo];
}
+47
View File
@@ -0,0 +1,47 @@
#ifndef LED_CTRL_H
#define LED_CTRL_H
#ifdef __cplusplus /*C++编译环境下兼容C语言*/
extern "C" {
#endif
/*------ Exported includes(头文件) ----------------------*/
#include "main.h"
#include "publicdata/publicdata.h"
/*------ Exported macro(宏定义) -------------------------*/
/*------ Exported struct(结构体定义) --------------------*/
typedef enum
{
E_PILE_STATE_TYPE_FAULT = 0, //存在故障
E_PILE_STATE_TYPE_IDLE, //空闲未插枪
E_PILE_STATE_TYPE_STARTING, //启动中
E_PILE_STATE_TYPE_CHARGING, //充电中
E_PILE_STATE_TYPE_PLUGGED_NOT_START, //插枪未启动
}E_PILE_STATE_TYPE;
typedef enum
{
E_LED_TYPE_GREEN_STEADY = 0, //绿灯常亮
E_LED_TYPE_GREEN_BLINK , //绿灯闪烁
E_LED_TYPE_RED_STEADY , //红灯常亮
E_LED_TYPE_RED_BLINK , //红灯闪烁
E_LED_TYPE_YELLOW_STEADY , //黄灯常量
E_LED_TYPE_YELLOW_BLINK , //黄灯闪烁
E_LED_TYPE_GREEN_RUNNING, //绿灯流水
E_LED_TYPE_RED_RUNNING, //红灯流水
E_LED_TYPE_YELLOW_RUNNING, //黄灯流水
}E_LED_STATE_TYPE;
/*------ Exported variables(变量定义) -------------------*/
/*------ Exported function prototypes (函数声明) -------*/
void v_led_init(void);
void v_led_ctrl(U16_T u16_sleepTime);
U8_T u8_led_state_get(U8_T u8_gunNo);
void v_led_state_refresh(void);
#ifdef __cplusplus
}
#endif
#endif /* LED_CTRL_H */
+305
View File
@@ -0,0 +1,305 @@
#include "collect_ctrl/yk_ctrl.h"
#include "usart.h"
#include "sys_drv_init.h"
#include "sub_comm/sub_comm_task.h"
#include <string.h>
/* 遥控通道总数自动跟随枚举 E_YK_CTRL_TYPE。 */
#define YK_DATA_NUM ((U8_T)E_KY_TYPE_NUM)
/* 遥控缓存区:
* - u8_data[] 便于按索引批量扫描执行;
* - s_yk_data 便于按“语义字段”点对点写入;
* 两者共用同一块内存,用于“写入命令”和“周期执行命令”的桥接。 */
typedef union
{
/* 按枚举下标访问的原始命令缓存。 */
U8_T u8_data[YK_DATA_NUM];
struct
{
E_CMD e_ctrl_dc_cont1; /* 直流接触器1(一枪主回路)。 */
E_CMD e_ctrl_dc_cont2; /* 直流接触器2(二枪主回路)。 */
E_CMD e_ctrl_dc_bus; /* 直流母联接触器。 */
E_CMD e_ctrl_ac_cont; /* 交流接触器。 */
E_CMD e_ctrl_fan; /* 散热风机。 */
E_CMD e_ctrl_relief_a; /* A枪泄放控制。 */
E_CMD e_ctrl_relief_b; /* B枪泄放控制。 */
E_CMD e_ctrl_lock1; /* 枪A电子锁。 */
E_CMD e_ctrl_lock2; /* 枪B电子锁。 */
E_CMD e_ctrl_aux_power1; /* 辅源1。 */
E_CMD e_ctrl_aux_power2; /* 辅源2。 */
E_CMD e_ctrl_v12_24_sw; /* 12/24V切换控制。 */
E_CMD e_ctrl_ac1; /* 模块交流接触器1。 */
E_CMD e_ctrl_ac2; /* 模块交流接触器2。 */
} s_yk_data;
} U_YK_CTRL_DATA;
/* 遥控命令全局缓存(模块私有):
* - 写入口:v_yk_ctrl_impl()
* - 执行入口:v_yk_ctrl_cheak()
* 当前由采集任务周期调用,默认单任务上下文访问。 */
static U_YK_CTRL_DATA u_yk_data;
/**
* @brief 周期执行遥控缓存中的全部命令。
*
* 执行策略:
* 1) 按 E_YK_CTRL_TYPE 的顺序遍历;
* 2) 将缓存命令传入 v_yk_ctrl() 下发到 DO
* 3) 不在本函数中清命令,保持“电平保持型”行为。
*/
void v_yk_ctrl_cheak(void)
{
U8_T i;
for (i = 0; i < YK_DATA_NUM; i++)
{
v_yk_ctrl((E_YK_CTRL_TYPE)i, (E_CMD)u_yk_data.u8_data[i]); //依次执行遥控命令
}
}
/**
* @brief 将指定遥控类型下发到具体硬件 DO。
*
* @param e_type 遥控类型(决定映射到哪个 DO)。
* @param e_cmd 遥控命令(开/关)。
*
* 说明:
* - 本函数只负责“硬件动作”;
* - 命令缓存维护由 v_yk_ctrl_impl() 负责。
*/
void v_yk_ctrl(E_YK_CTRL_TYPE e_type, E_CMD e_cmd)
{
switch (e_type)
{
case E_KY_TYPE_DC_CONT1: /* 直流接触器1 */
{
DO3(e_cmd);
break;
}
case E_KY_TYPE_DC_CONT2: /* 直流接触器2 */
{
DO6(e_cmd);
break;
}
case E_KY_TYPE_DC_CONT_BUS: /* 母联接触器 */
{
DO9(e_cmd);
break;
}
case E_KY_TYPE_AC_CONT: /* 交流接触器 */
{
DO7(e_cmd);
break;
}
case E_KY_TYPE_FAN_CONT: /* 风扇接触器 */
{
DO10(e_cmd);
break;
}
case E_KY_TYPE_RELIEF_A: /* A枪泄放控制 */
{
DO2(e_cmd);
break;
}
case E_KY_TYPE_RELIEF_B: /* B枪泄放控制 */
{
DO5(e_cmd);
break;
}
case E_KY_TYPE_GUN_LOCK1: /* 枪A电子锁 */
{
ELOCK_A(e_cmd);
break;
}
case E_KY_TYPE_GUN_LOCK2: /* 枪B电子锁 */
{
ELOCK_B(e_cmd);
break;
}
case E_KY_TYPE_AUX_POWER1: /* 辅源1 */
{
/* 辅源1 */
DO1(e_cmd);
break;
}
case E_KY_TYPE_AUX_POWER2: /* 辅源2 */
{
/* 辅源2 */
DO4(e_cmd);
break;
}
case E_KY_TYPE_V12_24_SWITCH: /* 12/24V切换控制 */
{
/* 12/24V切换:下发到副板 DO11 */
v_sub_comm_yk_set(E_SUB_YK_DO11, e_cmd);
break;
}
case E_KY_TYPE_AC1: /* 交流接触器1,主板 DO7 */
{
DO7(e_cmd);
break;
}
case E_KY_TYPE_AC2: /* 交流接触器2,主板 DO8 */
{
DO8(e_cmd);
break;
}
default:
break;
}
}
/**
* @brief 外部遥控写入接口(仅更新缓存,不直接动作)。
*
* @param e_type 遥控类型。
* @param e_cmd 遥控命令。
*
* 使用方式:
* - 上层流程调用本函数写入命令;
* - 采集任务周期调用 v_yk_ctrl_cheak() 统一执行;
* 这样可以把遥控执行节拍收敛到单任务上下文,降低并发风险。
*/
static void v_yk_cache_set(E_YK_CTRL_TYPE e_type, E_CMD e_cmd)
{
switch (e_type)
{
case E_KY_TYPE_DC_CONT1: /* 直流接触器1 */
{
u_yk_data.s_yk_data.e_ctrl_dc_cont1 = e_cmd;
break;
}
case E_KY_TYPE_DC_CONT2: /* 直流接触器2 */
{
u_yk_data.s_yk_data.e_ctrl_dc_cont2 = e_cmd;
break;
}
case E_KY_TYPE_DC_CONT_BUS: /* 母联接触器 */
{
u_yk_data.s_yk_data.e_ctrl_dc_bus = e_cmd;
break;
}
case E_KY_TYPE_AC_CONT: /* 交流接触器 */
{
u_yk_data.s_yk_data.e_ctrl_ac_cont = e_cmd;
break;
}
case E_KY_TYPE_FAN_CONT: /* 风扇接触器 */
{
u_yk_data.s_yk_data.e_ctrl_fan = e_cmd;
break;
}
case E_KY_TYPE_RELIEF_A: /* A枪泄放控制 */
{
u_yk_data.s_yk_data.e_ctrl_relief_a = e_cmd;
break;
}
case E_KY_TYPE_RELIEF_B: /* B枪泄放控制 */
{
u_yk_data.s_yk_data.e_ctrl_relief_b = e_cmd;
break;
}
case E_KY_TYPE_GUN_LOCK1: /* 枪A电子锁 */
{
u_yk_data.s_yk_data.e_ctrl_lock1 = e_cmd;
break;
}
case E_KY_TYPE_GUN_LOCK2: /* 枪B电子锁 */
{
u_yk_data.s_yk_data.e_ctrl_lock2 = e_cmd;
break;
}
case E_KY_TYPE_AUX_POWER1: /* 辅源1 */
{
u_yk_data.s_yk_data.e_ctrl_aux_power1 = e_cmd;
break;
}
case E_KY_TYPE_AUX_POWER2: /* 辅源2 */
{
u_yk_data.s_yk_data.e_ctrl_aux_power2 = e_cmd;
break;
}
case E_KY_TYPE_V12_24_SWITCH: /* 12/24V切换控制 */
{
u_yk_data.s_yk_data.e_ctrl_v12_24_sw = e_cmd;
break;
}
case E_KY_TYPE_AC1: /* 模块交流接触器1 */
{
u_yk_data.s_yk_data.e_ctrl_ac1 = e_cmd;
break;
}
case E_KY_TYPE_AC2: /* 模块交流接触器2 */
{
u_yk_data.s_yk_data.e_ctrl_ac2 = e_cmd;
break;
}
default:
break;
}
}
/**
* @brief 遥控模块初始化。
*
* 初始化互斥锁并清空所有遥控命令缓存,确保上电后不携带历史控制状态。
*/
void v_yk_ctrl_init(void)
{
memset(&u_yk_data, 0, sizeof(U_YK_CTRL_DATA));
}
/**
* @brief 立即执行遥控(更新缓存并下发 DO)。
*
* @param e_type 遥控类型。
* @param e_cmd 遥控命令。
*/
void v_yk_ctrl_impl(E_YK_CTRL_TYPE e_type, E_CMD e_cmd)
{
//更新控制命令状态
v_yk_cache_set(e_type, e_cmd);
//执行控制命令
v_yk_ctrl(e_type, e_cmd);
}
/**
* @brief 获取遥控命令缓存中的对应控制状态。
*
* @param e_type 遥控类型。
* @return E_CMD 遥控命令。
*/
E_CMD e_yk_get_ctrl_cmd(E_YK_CTRL_TYPE e_type)
{
if (e_type < E_KY_TYPE_NUM)
{
return (E_CMD)u_yk_data.u8_data[e_type];
}
return CMD_OFF;
}
+41
View File
@@ -0,0 +1,41 @@
#ifndef YK_CTRL_H
#define YK_CTRL_H
#ifdef __cplusplus
extern "C" {
#endif
#include "collect_ctrl/collect_task.h"
/* 遥控类型定义 */
typedef enum
{
E_KY_TYPE_DC_CONT1 = 0, /* 直流接触器1 - 一枪接触器 */
E_KY_TYPE_DC_CONT2, /* 直流接触器2 - 二枪接触器 */
E_KY_TYPE_DC_CONT_BUS, /* 母联接触器 */
E_KY_TYPE_AC_CONT, /* 交流接触器 */
E_KY_TYPE_FAN_CONT, /* 风扇接触器 */
E_KY_TYPE_RELIEF_A, /* A枪泄放控制 */
E_KY_TYPE_RELIEF_B, /* B枪泄放控制 */
E_KY_TYPE_GUN_LOCK1, /* 枪A电子锁控制 */
E_KY_TYPE_GUN_LOCK2, /* 枪B电子锁控制 */
E_KY_TYPE_AUX_POWER1, /* 辅源1遥控 */
E_KY_TYPE_AUX_POWER2, /* 辅源2遥控 */
E_KY_TYPE_V12_24_SWITCH, /* 12/24V切换控制 */
E_KY_TYPE_AC1, /* 交流接触器1,主板 DO7(80kW脉冲上电) */
E_KY_TYPE_AC2, /* 交流接触器2,主板 DO8(80kW脉冲下电) */
E_KY_TYPE_NUM /* 遥控类型数量 */
} E_YK_CTRL_TYPE;
void v_yk_ctrl_init(void);
void v_yk_ctrl_cheak(void);
void v_yk_ctrl(E_YK_CTRL_TYPE e_type, E_CMD e_cmd);
void v_yk_ctrl_impl(E_YK_CTRL_TYPE e_type, E_CMD e_cmd);
E_CMD e_yk_get_ctrl_cmd(E_YK_CTRL_TYPE e_type);
#ifdef __cplusplus
}
#endif
#endif /* YK_CTRL_H */