#include "write_analog.h"
#include "hv_voltage_ctrl.h"
#include <math.h>
#include "ls_spi.h"
#include "ls_io_ctrl.h"
#include "delay.h"
#include "hal_spi.h"
#include "hal_gpio.h"
// 全局系统状态
static hv_system_status_t g_hv_sys_status = {0};
// -------------------------- 静态函数声明 --------------------------
static WriteAnalog_t* get_write_analog_instance(uint8_t module_id); // 获取对应模块的DAC实例
static bool check_module_version(uint8_t module_id); // 检查模块版本号
static void reset_all_modules(void);
// 复位所有模块
// -------------------------- 公共函数实现 1. 高压系统初始化 hv_voltage_init--------------------------
hv_error_t hv_voltage_init(void) {
// 1. 初始化驱动层SPI
spi_dac_global_init();
// 2. 初始化5个模块的DAC上层控制
for (uint8_t i = 0; i < HV_MODULE_COUNT; i++) {
WriteAnalog_t* analog = get_write_analog_instance(i + 1);
if (analog == NULL) return HV_ERR_MODULE_INVALID;
//analog->init(analog, analog->dac_dev); // 初始化DAC
hv_set_s1_ex(i + 1, 0); // 禁用模块
hv_set_s2_ex(i + 1, 0); // 关闭高压输出
}
// 3. 复位系统状态
reset_all_modules();
return HV_ERR_SUCCESS;
}
/************2. 设置总目标电压 hv_set_voltage************/
hv_error_t hv_set_voltage(float vol) {
// 1. 参数合法性校验
if (vol < HV_MODULE_MIN_VOLTAGE) {
return HV_ERR_VOLTAGE_LOW;
}
if (vol > HV_TOTAL_MAX_VOLTAGE) {
return HV_ERR_VOLTAGE_HIGH;
}
// 2. 计算需要的模块数量(向上取整)
uint8_t modules_needed = (uint8_t)ceilf(vol / HV_MODULE_MAX_VOLTAGE);
float voltage_per_module = vol / modules_needed;
// 3. 确保每个模块电压不低于最小值(不足则增加模块数)
if (voltage_per_module < HV_MODULE_MIN_VOLTAGE) {
modules_needed = (uint8_t)ceilf(vol / HV_MODULE_MIN_VOLTAGE);
voltage_per_module = vol / modules_needed;
// 再次校验(避免极端情况)
if (modules_needed > HV_MODULE_COUNT || voltage_per_module < HV_MODULE_MIN_VOLTAGE) {
return HV_ERR_MODULE_INVALID;
}
}
// 4. 先关闭所有高压输出和模块使能(安全优先)
for (uint8_t i = 0; i < HV_MODULE_COUNT; i++) {
hv_set_s2_ex(i + 1, 0);
hv_set_s1_ex(i + 1, 0);
g_hv_sys_status.modules[i].is_enabled = false;
g_hv_sys_status.modules[i].is_faulty = false;
}
DELAY_Ms(100); // 等待电压泄放
// 5. 配置每个启用的模块
float total_calc_vol = 0.0f;
for (uint8_t i = 0; i < modules_needed; i++) {
hv_module_status_t* module = &g_hv_sys_status.modules[i];
WriteAnalog_t* analog = get_write_analog_instance(i + 1);
if (analog == NULL) {
hv_voltage_shutdown();
return HV_ERR_MODULE_INVALID;
}
// 计算当前模块电压
float module_vol = (i == modules_needed - 1) ?
(vol - voltage_per_module * (modules_needed - 1)) :
voltage_per_module;
// 计算DAC值
uint16_t dac_val = (uint16_t)(module_vol * DAC_VOLTAGE_TO_VALUE);
dac_val = (dac_val > 4095) ? 4095 : dac_val; // 限制12位范围
// 发送DAC指令
analog->vSetA(analog, dac_val);
// 更新模块状态
module->target_voltage = module_vol;
module->dac_value = dac_val;
module->is_enabled = true;
total_calc_vol += module_vol;
}
// 6. 启用模块并等待稳定
for (uint8_t i = 0; i < modules_needed; i++) {
hv_set_s1_ex(i + 1, 1); // 使能模块
}
DELAY_Ms(500); // 延时≥500ms(模块电压稳定时间)
// 7. 打开高压输出
hv_set_s2_ex(1, 1); // 优先打开第一个模块的输出
// 8. 更新系统状态
g_hv_sys_status.active_module_cnt = modules_needed;
g_hv_sys_status.total_target_voltage = vol;
// 9. 回读电压验证
float actual_vol = 0.0f;
if (hv_read_total_voltage(&actual_vol) != HV_ERR_SUCCESS) {
hv_voltage_shutdown();
return HV_ERR_ADC_READ_FAILED;
}
// 电压误差允许±5%
if (fabsf(actual_vol - vol) > vol * 0.05f) {
hv_voltage_shutdown();
return HV_ERR_MODULE_FAULT;
}
return HV_ERR_SUCCESS;
}
/****************3. 读取总实际电压 hv_read_total_voltage******************* */
hv_error_t hv_read_total_voltage(float* actual_vol) {
if (actual_vol == NULL) return HV_ERR_ADC_READ_FAILED; // 传入指针为空,返回错误
float total_vol = 0.0f; // 总实际电压
bool read_ok = true;
// 读取每个启用模块的输出电压(ADC通道1)
for (uint8_t i = 0; i < HV_MODULE_COUNT; i++) {
hv_module_status_t* module = &g_hv_sys_status.modules[i];
if (!module->is_enabled) continue;
// 读取ADC通道1(模块输出电压)
uint16_t adc_val = hv_spi_adc_read(i + 1, 1);
float module_vol = adc_val * ADC_MODULE_VOLTAGE_COEF;
// 读取ADC通道2(高压线电压,交叉验证)
uint16_t adc_line_val = hv_spi_adc_read(i + 1, 2);
float line_vol = adc_line_val * ADC_MODULE_VOLTAGE_COEF;
// 读取ADC通道6(DAC反馈电压,验证DAC设置)
uint16_t adc_dac_val = hv_spi_adc_read(i + 1, 6);
float dac_vol = adc_dac_val * ADC_DAC_VOLTAGE_COEF;
float expected_dac_vol = module->target_voltage / (DAC_VOLTAGE_TO_VALUE * (5.0f / 4095.0f));
// 故障判断
if (fabsf(module_vol - module->target_voltage) > module->target_voltage * 0.1f) {
module->is_faulty = true;
read_ok = false;
}
if (fabsf(line_vol - module_vol) > module_vol * 0.1f) {
module->is_faulty = true;
read_ok = false;
}
if (fabsf(dac_vol - expected_dac_vol) > 0.5f) { // DAC反馈误差允许±0.5V
module->is_faulty = true;
read_ok = false;
}
module->actual_voltage = module_vol;
total_vol += module_vol;
}
*actual_vol = total_vol;
g_hv_sys_status.total_actual_voltage = total_vol;
return read_ok ? HV_ERR_SUCCESS : HV_ERR_ADC_READ_FAILED;
}
/*************************4. 读取系统状态 hv_get_system_status**************************** */
hv_error_t hv_get_system_status(hv_system_status_t* status) {
if (status == NULL) return HV_ERR_ADC_READ_FAILED;
*status = g_hv_sys_status;
return HV_ERR_SUCCESS;
}
/**************************5. 高压系统自检 hv_voltage_self_test**************************************************************** */
hv_error_t hv_voltage_self_test(void) {
// 1. 复位所有模块
reset_all_modules();
DELAY_Ms(200);
// 2. 检查所有模块版本号
for (uint8_t i = 0; i < HV_MODULE_COUNT; i++) {
if (!check_module_version(i + 1)) {
g_hv_sys_status.modules[i].is_faulty = true;
hv_voltage_shutdown();
return HV_ERR_MODULE_FAULT;
}
}
// 3. 逐个模块测试(输出50V,验证电压)
for (uint8_t i = 0; i < HV_MODULE_COUNT; i++) {
uint8_t module_id = i + 1;
hv_module_status_t* module = &g_hv_sys_status.modules[i];
WriteAnalog_t* analog = get_write_analog_instance(module_id);
if (analog == NULL) {
hv_voltage_shutdown();
return HV_ERR_MODULE_INVALID;
}
// 关闭所有输出
for (uint8_t j = 0; j < HV_MODULE_COUNT; j++) {
hv_set_s2_ex(j + 1, 0);
hv_set_s1_ex(j + 1, 0);
}
DELAY_Ms(100);
// 配置测试电压(50V)
float test_vol = 50.0f;
uint16_t dac_val = (uint16_t)(test_vol * DAC_VOLTAGE_TO_VALUE);
dac_val = (dac_val > 4095) ? 4095 : dac_val;
// 启用模块并发送DAC指令
hv_set_s1_ex(module_id, 1);
analog->vSetA(analog, dac_val);
DELAY_Ms(500);
// 打开该模块的高压输出
hv_set_s2_ex(module_id, 1);
DELAY_Ms(200);
// 读取测试数据
uint16_t adc_module = hv_spi_adc_read(module_id, 1); // 模块输出电压
uint16_t adc_line = hv_spi_adc_read(module_id, 2); // 高压线电压
uint16_t adc_dac = hv_spi_adc_read(module_id, 6); // DAC反馈电压
float module_vol = adc_module * ADC_MODULE_VOLTAGE_COEF;
float line_vol = adc_line * ADC_MODULE_VOLTAGE_COEF;
float dac_vol = adc_dac * ADC_DAC_VOLTAGE_COEF;
// 故障判断(按模块说明文档逻辑)
bool module_fault = false;
if (fabsf(module_vol - test_vol) > test_vol * 0.1f &&
fabsf(line_vol - test_vol) > test_vol * 0.1f) {
if (line_vol < 100.0f) {
// 上报"高压模块-高压输入错误"
module_fault = true;
} else if (fabsf(dac_vol - (test_vol / DAC_VOLTAGE_TO_VALUE * 4095.0f / 5.0f)) > 1.0f) {
// 上报"高压模块-ADC/DAC错误"
module_fault = true;
} else if (line_vol > 100.0f && fabsf(dac_vol - (test_vol / DAC_VOLTAGE_TO_VALUE * 4095.0f / 5.0f)) <= 1.0f) {
// 上报"高压模块-调压错误"
module_fault = true;
}
}
// 读取版本号再次验证
if (!check_module_version(module_id)) {
module_fault = true;
}
if (module_fault) {
module->is_faulty = true;
hv_set_s2_ex(module_id, 0);
hv_set_s1_ex(module_id, 0);
hv_voltage_shutdown();
return HV_ERR_MODULE_FAULT;
}
// 关闭当前模块测试
hv_set_s2_ex(module_id, 0);
hv_set_s1_ex(module_id, 0);
DELAY_Ms(100);
}
// 4. 测试通过,复位状态
reset_all_modules();
return HV_ERR_SUCCESS;
}
/***********************6. 紧急停机 hv_voltage_shutdown******************************************* */
void hv_voltage_shutdown(void) {
// 关闭所有高压输出和模块使能
for (uint8_t i = 0; i < HV_MODULE_COUNT; i++) {
hv_set_s2_ex(i + 1, 0);
hv_set_s1_ex(i + 1, 0);
g_hv_sys_status.modules[i].is_enabled = false;
g_hv_sys_status.modules[i].is_faulty = false;
}
// 复位系统状态
g_hv_sys_status.active_module_cnt = 0;
g_hv_sys_status.total_target_voltage = 0.0f;
g_hv_sys_status.total_actual_voltage = 0.0f;
}
// -------------------------- 静态函数实现1. 获取 DAC 实例 get_write_analog_instance --------------------------
static WriteAnalog_t* get_write_analog_instance(uint8_t module_id) {
switch (module_id) {
case 1: return &xWriteAnalog1;
case 2: return &xWriteAnalog2;
case 3: return &xWriteAnalog3;
case 4: return &xWriteAnalog4;
case 5: return &xWriteAnalog5;
default: return NULL;
}
}
/***********************2. 检查模块版本 check_module_version******************************** */
static bool check_module_version(uint8_t module_id) {
// 读取ADC通道7
uint16_t adc_val = hv_spi_adc_read(module_id, 7);
float version_vol = adc_val * ADC_VERSION_COEF;
// 版本号有效范围:0.5V~2.5V
if (version_vol >= 0.5f && version_vol <= 2.5f) {
g_hv_sys_status.modules[module_id - 1].version_voltage = version_vol;
return true;
}
return false;
}
/***********************3. 复位所有模块 reset_all_modules******************************* */
static void reset_all_modules(void) {
for (uint8_t i = 0; i < HV_MODULE_COUNT; i++) {
hv_module_status_t* module = &g_hv_sys_status.modules[i];
module->is_enabled = false;
module->target_voltage = 0.0f;
module->actual_voltage = 0.0f;
module->dac_value = 0;
module->is_faulty = false;
module->version_voltage = 0.0f;
}
g_hv_sys_status.active_module_cnt = 0;
g_hv_sys_status.total_target_voltage = 0.0f;
g_hv_sys_status.total_actual_voltage = 0.0f;
}
/************底层硬件接口实现1. 控制模块使能引脚 S1_EX hv_set_s1_ex*************** */
void hv_set_s1_ex(uint8_t module_id, uint8_t enable) {
// 校验模块ID(1~5)
if (module_id < 1 || module_id > HV_MODULE_COUNT) return;
// io_ctrl_id_et io_id = IO_CTRL_HV_S1_1 + (module_id - 1);
static bool s1_inited[HV_MODULE_COUNT] = {false};
if (!s1_inited[module_id - 1]) {
// io_ctrl.init(io_id, IO_MODE_OUTPUT_PP); // 推挽输出
s1_inited[module_id - 1] = true;
}
//io_ctrl.set(io_id, enable ? IO_SET : IO_RESET);
}
/************2. 读取 ADC 值********************** */
uint16_t hv_spi_adc_read(uint8_t module_id, uint8_t channel) {
// 1. 参数合法性校验(保持不变)
if (module_id < 1 || module_id > HV_MODULE_COUNT ||
channel < 1 || channel > 7) {
return 0;
}
// 2. 初始化ADC片选引脚(保持不变)
io_ctrl_id_et cs_pin;
switch(module_id) {
case 1: cs_pin = IO_CTRL_HV_ADC_DECODE0; break;
case 2: cs_pin = IO_CTRL_HV_ADC_DECODE1; break;
case 3: cs_pin = IO_CTRL_HV_ADC_DECODE2; break;
case 4: cs_pin = IO_CTRL_HV_ADC_DECODE0; break;
case 5: cs_pin = IO_CTRL_HV_ADC_DECODE1; break;
default: return 0;
}
io_ctrl.init(cs_pin, IO_MODE_OUTPUT_PP);
io_ctrl.set(cs_pin, IO_SET);
// 3. 拉低片选,选中ADC
io_ctrl.set(cs_pin, IO_RESET);
// 4. 构建SPI命令(TLA2518为例)
uint8_t cmd = ( (channel - 1) << 4 ) | 0x0C; // 通道选择+配置
uint8_t rx_buf[2] = {0};
// 6. 拉高片选,结束通信
io_ctrl.set(cs_pin, IO_SET);
// 7. 转换为12位ADC值
return ( (rx_buf[0] << 8) | rx_buf[1] ) >> 4;
}
/*********3. 控制高压输出引脚************** */
void hv_set_s2_ex(uint8_t module_id, uint8_t enable) {
// 校验模块ID(1~5)
if (module_id < 1 || module_id > HV_MODULE_COUNT) return;
static bool s2_inited = false;
if (!s2_inited) {
// 初始化S2解码引脚为推挽输出
io_ctrl.init(IO_CTRL_HV_S2_DECODE0, IO_MODE_OUTPUT_PP);
io_ctrl.init(IO_CTRL_HV_S2_DECODE1, IO_MODE_OUTPUT_PP);
io_ctrl.init(IO_CTRL_HV_S2_DECODE2, IO_MODE_OUTPUT_PP);
s2_inited = true;
}
// 仅允许一个模块使能:先关闭所有,再打开目标(如果需要使能)
if (enable) {
// 解码逻辑:将module_id转换为3位二进制(1~5对应001~101)
io_ctrl.set(IO_CTRL_HV_S2_DECODE0, (module_id & 0x01) ? IO_SET : IO_RESET);
io_ctrl.set(IO_CTRL_HV_S2_DECODE1, (module_id & 0x02) ? IO_SET : IO_RESET);
io_ctrl.set(IO_CTRL_HV_S2_DECODE2, (module_id & 0x04) ? IO_SET : IO_RESET);
} else {
// 禁用时关闭所有
io_ctrl.set(IO_CTRL_HV_S2_DECODE0, IO_RESET);
io_ctrl.set(IO_CTRL_HV_S2_DECODE1, IO_RESET);
io_ctrl.set(IO_CTRL_HV_S2_DECODE2, IO_RESET);
}
}
// 4.延时函数实现 - 直接调用 delay.h 中的 ls_delay_ms
void DELAY_Ms(uint32_t ms) {
DELAY_Ms(ms);
}
//5. SPI DAC全局初始化 - 复用 write_analog.c 中的初始化逻辑
void spi_dac_global_init(void) {
GPIO_InitTypeDef GPIO_InitStruct;
SPI_InitTypeDef SPI_InitStruct;
// 1. 初始化GPIO (复制自 write_analog.c 中的 vGpioConfig)
//RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOB, ENABLE);
//RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOC, ENABLE);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource3, GPIO_AF_0);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource4, GPIO_AF_0);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource5, GPIO_AF_0);
// CS引脚 (PC6)
GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOC, &GPIO_InitStruct);
// SPI引脚 (PB3=SCK, PB5=MOSI)
GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_5;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOB, &GPIO_InitStruct);
// MISO引脚 (PB4)
GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_FLOATING;
GPIO_Init(GPIOB, &GPIO_InitStruct);
// 初始状态:CS高电平(不选中)
GPIO_SetBits(GPIOC, GPIO_Pin_6);
// 2. 初始化SPI (复制自 write_analog.c 中的 vSpiConfig)
//RCC_APB2PeriphClockCmd(RCC_APB2ENR_SPI1, ENABLE);
SPI_DeInit(SPI1);
SPI_StructInit(&SPI_InitStruct);
SPI_InitStruct.SPI_Mode = SPI_Mode_Master;
SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStruct.SPI_DataWidth = 8;
SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStruct.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStruct.SPI_NSS = SPI_NSS_Soft;
SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;
SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_Init(SPI1, &SPI_InitStruct);
SPI_BiDirectionalLineConfig(SPI1, SPI_Direction_Rx);
SPI_BiDirectionalLineConfig(SPI1, SPI_Direction_Tx);
SPI_Cmd(SPI1, ENABLE);
}
评价一下这个高压控制代码#ifndef HV_VOLTAGE_CTRL_H
#define HV_VOLTAGE_CTRL_H
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include "write_analog.h"
// -------------------------- 硬件参数宏定义--------------------------
#define HV_MODULE_COUNT 5 // 总高压模块数
#define HV_MODULE_MIN_VOLTAGE 10.0f // 单个模块最低输出电压(V)
#define HV_MODULE_MAX_VOLTAGE 100.0f // 单个模块最高输出电压(V)
#define HV_TOTAL_MAX_VOLTAGE (HV_MODULE_COUNT * HV_MODULE_MAX_VOLTAGE) // 总最高电压(500V)
// DAC/ADC系数(来自高压电源模块说明)
#define DAC_VOLTAGE_TO_VALUE 33.42857142857f // DAC值 = 模块输出电压 × 该系数
#define ADC_MODULE_VOLTAGE_COEF 0.12332112332f // ADC通道1/2:电压 = ADC值 × 该系数
#define ADC_DAC_VOLTAGE_COEF (5.0f / 4095.0f) // ADC通道6:DAC反馈电压系数(5V参考/12位)
#define ADC_VERSION_COEF (5.0f / 4095.0f) // ADC通道7:版本号电压系数
void hv_set_s1_ex(uint8_t module_id, uint8_t enable);
void hv_set_s2_ex(uint8_t module_id, uint8_t enable);
// 错误码定义
typedef enum {
HV_ERR_SUCCESS = 0, // 成功
HV_ERR_VOLTAGE_LOW, // 电压低于最小值
HV_ERR_VOLTAGE_HIGH, // 电压高于最大值
HV_ERR_MODULE_INVALID, // 模块配置无效
HV_ERR_SPI_FAILED, // SPI通信失败
HV_ERR_ADC_READ_FAILED, // ADC读取失败
HV_ERR_MODULE_FAULT // 模块故障
} hv_error_t;
// 单个模块状态结构体
typedef struct {
bool is_enabled; // 是否启用
float target_voltage; // 目标电压(V)
float actual_voltage; // 实际电压(V)
uint16_t dac_value; // DAC设置值
bool is_faulty; // 是否故障
float version_voltage; // 版本号电压(V)
} hv_module_status_t;
// 系统整体状态结构体
typedef struct {
hv_module_status_t modules[HV_MODULE_COUNT]; // 各模块状态
uint8_t active_module_cnt; // 活跃模块数
float total_target_voltage; // 总目标电压
float total_actual_voltage; // 总实际电压
} hv_system_status_t;
// -------------------------- 外部硬件接口声明(需底层实现)--------------------------
// S1_EX:模块使能(1=使能,0=禁用)
extern void hv_set_s1_ex(uint8_t module_id, uint8_t level);
// S2_EX:高压输出使能(1=有效,0=无效;仅允许一个模块有效!)
extern void hv_set_s2_ex(uint8_t module_id, uint8_t level);
// ADC读取(module_id:1~5;channel:1~7;返回ADC原始值)
extern uint16_t hv_spi_adc_read(uint8_t module_id, uint8_t channel);
// 延时函数(ms)
extern void hv_delay_ms(uint32_t ms);
// -------------------------- 高压控制接口声明 --------------------------
/**
* @brief 高压系统初始化
* @param 无
* @return hv_error_t:错误码
*/
hv_error_t hv_voltage_init(void);
/**
* @brief 设置总目标电压
* @param vol:总目标电压(V),范围:10V ~ 500V
* @return hv_error_t:错误码
*/
hv_error_t hv_set_voltage(float vol);
/**
* @brief 读取总实际电压
* @param actual_vol:输出参数,总实际电压(V)
* @return hv_error_t:错误码
*/
hv_error_t hv_read_total_voltage(float* actual_vol);
/**
* @brief 读取系统状态
* @param status:输出参数,系统状态
* @return hv_error_t:错误码
*/
hv_error_t hv_get_system_status(hv_system_status_t* status);
/**
* @brief 高压系统自检
* @param 无
* @return hv_error_t:错误码(HV_ERR_SUCCESS=自检通过)
*/
hv_error_t hv_voltage_self_test(void);
/**
* @brief 关闭高压系统(紧急停机)
* @param 无
* @return 无
*/
void hv_voltage_shutdown(void);
#endif // HV_VOLTAGE_CTRL_H
最新发布