#include <stdio.h>
#include "ls_io_ctrl.h"
#include "ls_system.h"
#include "ls_uart0.h"
#include <math.h>
#include "ls_spi.h"
#include "sys_config.h"
#include "io_comm.h"
#include "led.h"
#include "task.h"
//#include "ad5322.h"
#include "tla2518_A.h"
#include "write_analog.h"
#include "delay.h"
#include "hv_voltage_ctrl.h"
#include "mm32_device.h"
#define LOG_TAG "main.c"
#define LOG_LEVEL LOG_LEVEL_VERBOSE
#include "logger.h"
// 端口初始化函数
static void drv_port_init(void)
{
/***************PA端口*********/
io_ctrl.init(IO_CTRL_CURRENT_DECODE_0, IO_MODE_OUTPUT_PP);
io_ctrl.init(IO_CTRL_CURRENT_DECODE_1, IO_MODE_OUTPUT_PP);
io_ctrl.init(IO_CTRL_CURRENT_DECODE_2, IO_MODE_OUTPUT_PP);
io_ctrl.init(IO_CTRL_SELF_CHECK_CURRENT,IO_MODE_OUTPUT_PP);
io_ctrl.init(IO_CTRL_STATE_LED4,IO_MODE_OUTPUT_PP);
io_ctrl.init(IO_CTRL_LED,IO_MODE_OUTPUT_PP);
io_ctrl.set(IO_CTRL_SELF_CHECK_CURRENT, IO_SET);
io_ctrl.set(IO_CTRL_CURRENT_DECODE_0, IO_SET);
io_ctrl.set(IO_CTRL_CURRENT_DECODE_1,IO_SET);
io_ctrl.set(IO_CTRL_CURRENT_DECODE_2, IO_SET);
io_ctrl.set(IO_CTRL_STATE_LED4,IO_SET);
io_ctrl.set(IO_CTRL_LED,IO_SET);
/***********PB端口***********/
io_ctrl.init(IO_CTRL_STATE_LED3,IO_MODE_OUTPUT_PP);
io_ctrl.init(IO_CTRL_STATE_LED2,IO_MODE_OUTPUT_PP);
io_ctrl.init(IO_CTRL_STATE_LED1,IO_MODE_OUTPUT_PP);
io_ctrl.init(IO_CTRL_HV_DAC_DECODE0,IO_MODE_OUTPUT_PP);
io_ctrl.init(IO_CTRL_HV_DAC_DECODE1,IO_MODE_OUTPUT_PP);
io_ctrl.set(IO_CTRL_STATE_LED3, IO_SET);
io_ctrl.set(IO_CTRL_STATE_LED2, IO_SET);
io_ctrl.set(IO_CTRL_STATE_LED1,IO_SET);
io_ctrl.set(IO_CTRL_HV_DAC_DECODE0,IO_SET);
io_ctrl.set(IO_CTRL_HV_DAC_DECODE1,IO_SET);
io_ctrl.init(IO_CTRL_HV_DAC_DECODE2,IO_MODE_OUTPUT_PP);
io_ctrl.init(IO_CTRL_HV_ADC_DECODE0,IO_MODE_OUTPUT_PP);
io_ctrl.init(IO_CTRL_HV_ADC_DECODE1,IO_MODE_OUTPUT_PP);
io_ctrl.init(IO_CTRL_HV_ADC_DECODE2,IO_MODE_OUTPUT_PP);
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);
io_ctrl.set(IO_CTRL_HV_DAC_DECODE2, IO_SET);
io_ctrl.set(IO_CTRL_HV_ADC_DECODE0, IO_SET);
io_ctrl.set(IO_CTRL_HV_ADC_DECODE1,IO_SET);
io_ctrl.set(IO_CTRL_HV_ADC_DECODE2,IO_SET);
io_ctrl.set(IO_CTRL_HV_S2_DECODE0,IO_SET);
io_ctrl.set(IO_CTRL_HV_S2_DECODE1,IO_SET);
io_ctrl.set(IO_CTRL_HV_S2_DECODE2, IO_SET);
/****PC端口****/
io_ctrl.init(IO_CTRL_HV_LEVEL,IO_MODE_OUTPUT_PP);
io_ctrl.init(IO_CTRL_LV_LEVEL1,IO_MODE_OUTPUT_PP); //10V电平控制
io_ctrl.init(IO_CTRL_LV_LEVEL2,IO_MODE_OUTPUT_PP); //24V电平控制
io_ctrl.init(IO_CTRL_LV_LEVEL3,IO_MODE_OUTPUT_PP); //48V电平控制
io_ctrl.init(IO_CTRL_HV_S1_1,IO_MODE_OUTPUT_PP);
io_ctrl.init(IO_CTRL_HV_S1_2,IO_MODE_OUTPUT_PP);
io_ctrl.init(IO_CTRL_HV_S1_3,IO_MODE_OUTPUT_PP);
io_ctrl.init(IO_CTRL_HV_S1_4,IO_MODE_OUTPUT_PP);
io_ctrl.init(IO_CTRL_HV_S1_5,IO_MODE_OUTPUT_PP);
io_ctrl.set(IO_CTRL_HV_LEVEL,IO_RESET);
io_ctrl.set(IO_CTRL_LV_LEVEL1,IO_SET);
io_ctrl.set(IO_CTRL_LV_LEVEL2,IO_SET);
io_ctrl.set(IO_CTRL_LV_LEVEL3,IO_SET);
io_ctrl.set(IO_CTRL_HV_S1_1,IO_SET);
io_ctrl.set(IO_CTRL_HV_S1_2,IO_SET);
io_ctrl.set(IO_CTRL_HV_S1_3,IO_SET);
io_ctrl.set(IO_CTRL_HV_S1_4,IO_SET);
io_ctrl.set(IO_CTRL_HV_S1_5,IO_SET);
}
// 底层硬件初始化函数
static void bsp_init(void)
{
ls_sys.sys_rcu_init(); // 系统时钟初始化
ls_sys.systick_init(); // 滴答定时器初始化
uart0.init(); // 串口0初始化
drv_port_init(); // 驱动端口初始化
io_comm.init(); // IO通信初始化
led_init(); // LED初始化
hv_voltage_init(); // 高压系统初始化
tla2518_A.init(); // TLA2518 ADC初始化
// ad5322.init();
// 初始化5个高压模块的DAC实例
xWriteAnalog1.vInit(&xWriteAnalog1, &xDacIcDev1);
xWriteAnalog2.vInit(&xWriteAnalog2, &xDacIcDev2);
xWriteAnalog3.vInit(&xWriteAnalog3, &xDacIcDev3);
xWriteAnalog4.vInit(&xWriteAnalog4, &xDacIcDev4);
xWriteAnalog5.vInit(&xWriteAnalog5, &xDacIcDev5);
// 打印版本信息
uart0.send_bytes((mfU8_t *)VERSION_NAME, VERSION_SIZE);
LOG_I("Building at %s %s",__DATE__,__TIME__);
LOG_I("SystemCoreClock : %d",ls_sys.system_clock);
}
int main(void)
{
bsp_init(); // 初始化所有底层硬件
LOG_I("System device init ok!");
// ========== 高压模块1输出50V测试逻辑 ==========
hv_error_t ret = hv_test_module1_output_50v();
if (ret != HV_ERR_SUCCESS)
{
// 测试失败:打印错误码 + 紧急停机 + 死循环保护
printf("Output 50V failed, error code: %d\n", ret);
hv_voltage_shutdown(); // 强制关闭高压系统
while(1)
{
io_ctrl.set(IO_CTRL_LED, IO_RESET);
DELAY_Ms(500);
io_ctrl.set(IO_CTRL_LED, IO_SET);
DELAY_Ms(500);
}
}
printf("Output 50V success!\n");
// ========== 实时读取并校验输出电压 ==========
float actual_vol = 0.0f;
while(1) // 循环监测电压
{
// 读取当前输出电压
if (hv_read_total_voltage(&actual_vol) != HV_ERR_SUCCESS)
{
printf("ADC read failed! Shutdown HV system.\n");
hv_voltage_shutdown(); // ADC读取失败,紧急停机
while(1); // 死循环保护
}
// 打印当前电压
printf("Current output voltage: %.2fV\n", actual_vol);
// 电压超限判断(50V±5%)
if (fabsf(actual_vol - 50.0f) > 50.0f * 0.05f)
{
printf("Voltage out of range! Shutdown HV system.\n");
hv_voltage_shutdown(); // 电压超限,紧急停机
while(1); // 死循环保护
}
DELAY_Ms(500); // 500ms刷新一次电压
}
// 原任务启动逻辑(如需恢复,可注释上面的测试代码,启用下面一行)
// task_start();
}
/*
int main(void)
{
bsp_init();
LOG_I("System device init ok!");
task_start();
return 0;
}
while(1) {
// ========== 修正后的LED一秒一亮逻辑 ==========
led_state = (led_state == IO_SET) ? IO_RESET : IO_SET;
io_ctrl.set(IO_CTRL_LED, led_state);
printf("LED state: %d (IO_SET=1, IO_RESET=0)\n", led_state);
DELAY_Ms(500);
*/
/*
int main(void)
{
bsp_init();
LOG_I("系统设备初始化完成!");
// 注释原任务启动函数,改为死循环实现电压切换
while(1)
{
// 输出48V:设置48V对应控制引脚
io_ctrl.set(IO_CTRL_LV_LEVEL3, IO_SET);
ls_sys.delay_ms(50); // 延时50ms
// 输出0V:拉低48V对应控制引脚(关闭48V输出)
io_ctrl.set(IO_CTRL_LV_LEVEL3, IO_RESET);
ls_sys.delay_ms(50); // 延时50ms
}
}
*/
#include "ls_system.h"
#include <stdio.h>
#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"
#include "hal_rcc.h"
#include "mm32_device.h"
#include "tla2518_A.h" // 引入ADC驱动头文件,解决函数隐式声明警告
// 全局系统状态
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输出50V ***********************/
hv_error_t hv_test_module1_output_50v(void) {
// 1. 初始化高压系统
hv_error_t ret = hv_voltage_init();
if (ret != HV_ERR_SUCCESS) {
return ret;
}
// 2. 安全优先:关闭所有模块的输出和使能
hv_voltage_shutdown();
DELAY_Ms(100); // 等待电压泄放
// 3. 配置模块1输出50V
uint8_t target_module = 1; // 仅用模块1
float target_vol = 50.0f; // 目标电压50V
hv_module_status_t* module = &g_hv_sys_status.modules[target_module - 1];
WriteAnalog_t* analog = get_write_analog_instance(target_module);
DacIcDev_t* dac_dev = &xDacIcDev1 + (target_module - 1);
// 校验模块/DAC实例有效性
if (analog == NULL || dac_dev == NULL) {
hv_voltage_shutdown();
return HV_ERR_MODULE_INVALID;
}
// 4. 计算50V对应的DAC值(AD5623:2.5V→4095,高压模块增益20倍→2.5V×20=50V)
uint16_t dac_val = (uint16_t)(target_vol / HV_MODULE_GAIN * 4095.0f / DAC_REF_VOLTAGE);
dac_val = (dac_val > 4095) ? 4095 : dac_val; // 限制最大值
// 5. 发送DAC指令配置模块1电压
analog->vInit(analog, dac_dev); // 初始化模块1的DAC
analog->vSetA(analog, dac_val); // 设置DAC值
// 6. 使能模块1并等待电压稳定
hv_set_s1_ex(target_module, 1); // 使能模块1
DELAY_Ms(500); // 模块电压稳定延时
// 7. 打开模块1的高压输出
hv_set_s2_ex(target_module, 1);
DELAY_Ms(200); // 输出稳定延时
// 8. 更新系统状态
module->target_voltage = target_vol;
module->dac_value = dac_val;
module->is_enabled = true;
g_hv_sys_status.active_module_cnt = 1;
g_hv_sys_status.total_target_voltage = target_vol;
// 9. 验证实际输出电压(误差±5%以内)
float actual_vol = 0.0f;
ret = hv_read_total_voltage(&actual_vol);
if (ret != HV_ERR_SUCCESS) {
hv_voltage_shutdown();
return HV_ERR_ADC_READ_FAILED;
}
// 校验电压误差(50V±5% → 47.5V ~ 52.5V)
if (fabsf(actual_vol - target_vol) > target_vol * 0.05f) {
hv_voltage_shutdown();
return HV_ERR_MODULE_FAULT;
}
// 10. 输出成功日志
printf("Module 1 output 50V success! Actual voltage: %.2fV\n", actual_vol);
return HV_ERR_SUCCESS;
}
// -------------------------- 公共函数实现 -------------------------
/****************** 一、高压系统初始化 hv_voltage_init ************************ */
hv_error_t hv_voltage_init(void) {
// 1. 初始化驱动层SPI(调用write_analog.c中的实现)
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;
// 初始化DAC
analog->vInit(analog, &xDacIcDev1 + i);
hv_set_s1_ex(i + 1, 0); // 禁用模块
hv_set_s2_ex(i + 1, 0); // 关闭高压输出
}
// 3. 复位系统状态
reset_all_modules();
return HV_ERR_SUCCESS;
}
/********************** 二、设置总目标电压 *****************************/
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);
DacIcDev_t* dac_dev = &xDacIcDev1 + i;
if (analog == NULL || dac_dev == 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值(AD5623:12位,2.5V参考,20倍增益)
uint16_t dac_val = (uint16_t)(module_vol / HV_MODULE_GAIN * 4095.0f / DAC_REF_VOLTAGE);
dac_val = (dac_val > 4095) ? 4095 : dac_val;
// 发送DAC指令(确保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); // 模块电压稳定延时
// 7. 打开高压输出(按模块顺序,避免浪涌)
for (uint8_t i = 0; i < modules_needed; i++) {
hv_set_s2_ex(i + 1, 1);
DELAY_Ms(10); // 模块间延时
}
// 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;
}
/**************** 三、读取总实际电压 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;
// 读取每个启用模块的输出电压
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(模块输出电压)- 调用TLA2518驱动
uint16_t adc_val = tla2518_A_get_sam_value(10, i*2); // 采样10次,模块i对应通道2i
float module_vol = adc_val * ADC_MODULE_VOLTAGE_COEF;
// 读取ADC通道2(高压线电压,交叉验证)
uint16_t adc_line_val = tla2518_A_get_sam_value(10, i*2+1);
float line_vol = adc_line_val * ADC_MODULE_VOLTAGE_COEF;
// 读取ADC通道6(DAC反馈电压,验证DAC设置)
uint16_t adc_dac_val = tla2518_A_get_sam_value(10, 6);
float dac_vol = adc_dac_val * ADC_DAC_VOLTAGE_COEF;
// 正确的DAC反馈电压期望值:DAC输出电压 = (模块目标电压 / 增益)
float expected_dac_vol = module->target_voltage / HV_MODULE_GAIN;
// 故障判断(误差超限标记故障)
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.05f) { // DAC反馈误差±0.05V(更精准)
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;
}
/************************* 四、读取系统状态 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;
}
/************************** 五、高压系统自检 hv_voltage_self_test *************** */
hv_error_t hv_voltage_self_test(void) {
// 1. 复位所有模块
reset_all_modules();
DELAY_Ms(500);
// 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);
DacIcDev_t* dac_dev = &xDacIcDev1 + i;
if (analog == NULL || dac_dev == 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(500);
// 配置测试电压(50V)
float test_vol = 50.0f;
uint16_t dac_val = (uint16_t)(test_vol / HV_MODULE_GAIN * 4095.0f / DAC_REF_VOLTAGE);
dac_val = (dac_val > 4095) ? 4095 : dac_val;
// 启用模块并发送DAC指令
hv_set_s1_ex(module_id, 1);
analog->vInit(analog, dac_dev);
analog->vSetA(analog, dac_val);
DELAY_Ms(500);
// 打开该模块的高压输出
hv_set_s2_ex(module_id, 1);
DELAY_Ms(200);
// 读取测试数据(调用TLA2518驱动)
uint16_t adc_module = tla2518_A_get_sam_value(10, i*2); // 模块输出电压
uint16_t adc_line = tla2518_A_get_sam_value(10, i*2+1); // 高压线电压
uint16_t adc_dac = tla2518_A_get_sam_value(10, 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;
float expected_dac_vol = test_vol / HV_MODULE_GAIN;
// 故障判断(按模块说明文档逻辑)
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 < 10.0f) { // 修正阈值:50V模块输出低于10V判定输入错误
module_fault = true; // 高压模块-高压输入错误
} else if (fabsf(dac_vol - expected_dac_vol) > 0.1f) {
module_fault = true; // 高压模块-ADC/DAC错误
} else if (line_vol > 60.0f && fabsf(dac_vol - expected_dac_vol) <= 0.1f) {
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;
}
/*********************** 六、紧急停机 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;
}
// -------------------------- 静态函数实现 --------------------------
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;
}
}
static bool check_module_version(uint8_t module_id) {
// 读取ADC通道7(版本号通道)- 调用TLA2518驱动
uint16_t adc_val = tla2518_A_get_sam_value(5, 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;
}
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;
// 模块ID到S1引脚的映射(需确保ls_io_ctrl.h中定义这些宏)
static const io_ctrl_id_et s1_pins[HV_MODULE_COUNT] = {
IO_CTRL_HV_S1_1, // 模块1
IO_CTRL_HV_S1_2, // 模块2
IO_CTRL_HV_S1_3, // 模块3
IO_CTRL_HV_S1_4, // 模块4
IO_CTRL_HV_S1_5 // 模块5
};
io_ctrl_id_et io_id = s1_pins[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_RESET(低电平),禁用:IO_SET(高电平)
io_ctrl.set(io_id, enable ? IO_RESET : IO_SET);
}
/************ 2. 读取 ADC 值 hv_spi_adc_read(兼容底层SPI,备用接口) ********************** */
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 CS引脚的映射(3位解码:decode0=bit0, decode1=bit1, decode2=bit2)
io_ctrl_id_et cs_pins[3] = {IO_CTRL_HV_ADC_DECODE0, IO_CTRL_HV_ADC_DECODE1, IO_CTRL_HV_ADC_DECODE2};
uint8_t decode_val = module_id; // 模块1=1(001), 2=2(010), 3=3(011),4=4(100),5=5(101)
// 初始化所有CS解码引脚(移除is_init判断:ls_io_ctrl无该字段,重复初始化安全)
for (uint8_t i=0; i<3; i++) {
io_ctrl.init(cs_pins[i], IO_MODE_OUTPUT_PP); // 直接初始化
io_ctrl.set(cs_pins[i], IO_SET); // 初始高电平
}
// 3. 设置解码引脚,选中目标模块
io_ctrl.set(cs_pins[0], (decode_val & 0x01) ? IO_RESET : IO_SET);
io_ctrl.set(cs_pins[1], (decode_val & 0x02) ? IO_RESET : IO_SET);
io_ctrl.set(cs_pins[2], (decode_val & 0x04) ? IO_RESET : IO_SET);
ls_sys.delay_us(2); // 稳定延时
// 4. 替换未定义的tla2518_A_read_adv为工程已实现的tla2518_A_get_sam_value
// 参数:采样次数(10次) + 通道号(channel-1,适配TLA2518通道0-6对应1-7)
uint16_t adc_val = tla2518_A_get_sam_value(10, channel-1);
// 5. 复位解码引脚
for (uint8_t i=0; i<3; i++) {
io_ctrl.set(cs_pins[i], IO_SET);
}
// 6. 转换为12位ADC值
return adc_val;
}
/********* 3. 控制高压输出引脚 hv_set_s2_ex ************** */
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;
// S2解码引脚(3位:decode0=bit0, decode1=bit1, decode2=bit2)
static const io_ctrl_id_et s2_pins[3] = {
IO_CTRL_HV_S2_DECODE0,
IO_CTRL_HV_S2_DECODE1,
IO_CTRL_HV_S2_DECODE2
};
// 初始化解码引脚(仅第一次)
static bool s2_inited = false;
if (!s2_inited) {
for (uint8_t i=0; i<3; i++) {
io_ctrl.init(s2_pins[i], IO_MODE_OUTPUT_PP);
io_ctrl.set(s2_pins[i], IO_SET); // 初始高电平
}
s2_inited = true;
}
if (enable) {
// 3位二进制解码模块1-5:1=001,2=010,3=011,4=100,5=101
uint8_t decode_val = module_id;
for (uint8_t i=0; i<3; i++) {
io_ctrl.set(s2_pins[i], (decode_val & (1<<i)) ? IO_RESET : IO_SET);
}
} else {
// 禁用时所有解码引脚置高
for (uint8_t i=0; i<3; i++) {
io_ctrl.set(s2_pins[i], IO_SET);
}
}
}
/************ 4. 延时函数实现 *************** */
void DELAY_Ms(uint32_t ms) {
ls_sys.delay_ms(ms);
}
#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)
// AD5623 核心参数(12位DAC,内部2.5V参考)
#define DAC_REF_VOLTAGE 2.5f // DAC参考电压(V)
#define HV_MODULE_GAIN 20.0f // 高压模块增益(DAC输出×20=模块输出)
#define DAC_VOLTAGE_TO_VALUE (4095.0f / (HV_MODULE_MAX_VOLTAGE / HV_MODULE_GAIN)) // 81.9f
// ADC系数(校准后)
#define ADC_MODULE_VOLTAGE_COEF (HV_MODULE_MAX_VOLTAGE / 4095.0f) // 100V/4095≈0.02442f
#define ADC_DAC_VOLTAGE_COEF (DAC_REF_VOLTAGE / 4095.0f) // DAC反馈电压系数(2.5V/4095)
#define ADC_VERSION_COEF (5.0f / 4095.0f) // 版本号电压系数(5V参考)
// 错误码定义
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设置值(12位:0-4095)
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; // 总目标电压(V)
float total_actual_voltage; // 总实际电压(V)
} hv_system_status_t;
// -------------------------- 底层硬件接口声明 --------------------------
/**
* @brief 控制模块使能引脚 S1_EX
* @param module_id:模块ID(1-5)
* @param enable:1=使能(低电平),0=禁用(高电平)
* @return 无
*/
void hv_set_s1_ex(uint8_t module_id, uint8_t enable);
/**
* @brief 控制高压输出引脚 S2_EX(3位解码)
* @param module_id:模块ID(1-5)
* @param enable:1=打开输出,0=关闭输出
* @return 无
*/
void hv_set_s2_ex(uint8_t module_id, uint8_t enable);
/**
* @brief 读取ADC值(适配TLA2518)
* @param module_id:模块ID(1-5)
* @param channel:ADC通道(1-7)
* @return 12位ADC原始值(0-4095)
*/
uint16_t hv_spi_adc_read(uint8_t module_id, uint8_t channel);
/**
* @brief 毫秒级延时
* @param ms:延时时间(ms)
* @return 无
*/
void DELAY_Ms(uint32_t ms);
/**
* @brief SPI DAC全局初始化(实现位于write_analog.c)
* @param 无
* @return 无
*/
void spi_dac_global_init(void);
// -------------------------- 高压控制核心接口 --------------------------
/**
* @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 高压系统自检(逐个模块测试50V输出)
* @param 无
* @return hv_error_t:错误码(HV_ERR_SUCCESS=自检通过)
*/
hv_error_t hv_voltage_self_test(void);
/**
* @brief 关闭高压系统(紧急停机)
* @param 无
* @return 无
*/
void hv_voltage_shutdown(void);
/**
* @brief 测试函数:模块1输出50V
* @param 无
* @return hv_error_t:错误码
*/
hv_error_t hv_test_module1_output_50v(void);
#endif // HV_VOLTAGE_CTRL_H
#include <stdint.h>
#include "write_analog.h"
#include "ls_spi.h"
#include "ls_io_ctrl.h"
#include "ls_system.h"
#include "hal_conf.h"
#include "delay.h"
// --------------------------声明所有static函数 --------------------------
static void vGpioConfig(void);
static void vSpiConfig(void);
static void vSpiTransmit(DacIcDev_t* pxDev);
static void vInitDacIcDev(DacIcDev_t* pxDev);
static void vWriteDacIcDev(DacIcDev_t* pxDev, uint16_t usDacValue, WRITE_ANALOG_CHANNEL_E eChannel);
static void vTestDacIcDev(DacIcDev_t* pxDev);
static void vInitWriteAnalog(WriteAnalog_t* pxWriteAnalog, DacIcDev_t* pxDev);
static void vSetA(WriteAnalog_t* pxWriteAnalog, uint16_t usDacValue);
static void vSetB(WriteAnalog_t* pxWriteAnalog, uint16_t usDacValue);
// -------------------------- 核心引脚定义 --------------------------
#define AD5623_CS_PORT GPIOC
#define AD5623_CS_PIN GPIO_Pin_6
#define AD5623_LDAC_PORT GPIOB
#define AD5623_LDAC_PIN GPIO_Pin_0
#define AD5623_CLR_PORT GPIOB
#define AD5623_CLR_PIN GPIO_Pin_1
#define AD5623_CS_SET() GPIO_SetBits(AD5623_CS_PORT, AD5623_CS_PIN)
#define AD5623_CS_RESET() GPIO_ResetBits(AD5623_CS_PORT, AD5623_CS_PIN)
// -------------------------- 全局对象声明 --------------------------
DacIcDev_t xDacIcDev1 = {.vInit = vInitDacIcDev};
WriteAnalog_t xWriteAnalog1 = {.vInit = vInitWriteAnalog};
DacIcDev_t xDacIcDev2 = {.vInit = vInitDacIcDev};
WriteAnalog_t xWriteAnalog2 = {.vInit = vInitWriteAnalog};
DacIcDev_t xDacIcDev3 = {.vInit = vInitDacIcDev};
WriteAnalog_t xWriteAnalog3 = {.vInit = vInitWriteAnalog};
DacIcDev_t xDacIcDev4 = {.vInit = vInitDacIcDev};
WriteAnalog_t xWriteAnalog4 = {.vInit = vInitWriteAnalog};
DacIcDev_t xDacIcDev5 = {.vInit = vInitDacIcDev};
WriteAnalog_t xWriteAnalog5 = {.vInit = vInitWriteAnalog};
// -------------------------- GPIO初始化 --------------------------
static void vGpioConfig(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOA | RCC_AHBENR_GPIOB | RCC_AHBENR_GPIOC, ENABLE);
// SPI1引脚(GPIOB13=SCK, GPIOB15=MOSI)- 复用推挽
GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_0);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_0);
GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_15;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOB, &GPIO_InitStruct);
// MISO(GPIOB14)- 浮空输入
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_14;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_FLOATING;
GPIO_Init(GPIOB, &GPIO_InitStruct);
// CS(GPIOC6)- 推挽输出,默认拉高
GPIO_InitStruct.GPIO_Pin = AD5623_CS_PIN;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(AD5623_CS_PORT, &GPIO_InitStruct);
AD5623_CS_SET();
// LDAC(GPIOB0)- 拉低永久使能更新
GPIO_InitStruct.GPIO_Pin = AD5623_LDAC_PIN;
GPIO_Init(AD5623_LDAC_PORT, &GPIO_InitStruct);
GPIO_ResetBits(AD5623_LDAC_PORT, AD5623_LDAC_PIN);
// CLR(GPIOB1)- 拉高禁用清零
GPIO_InitStruct.GPIO_Pin = AD5623_CLR_PIN;
GPIO_Init(AD5623_CLR_PORT, &GPIO_InitStruct);
GPIO_SetBits(AD5623_CLR_PORT, AD5623_CLR_PIN);
}
// -------------------------- SPI初始化 --------------------------
static void vSpiConfig(void)
{
SPI_InitTypeDef SPI_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2ENR_SPI1, ENABLE);
SPI_DeInit(SPI1);
// AD5623模式0:CPOL=Low,CPHA=1Edge
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_1Edge;
SPI_InitStruct.SPI_NSS = SPI_NSS_Soft;
SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
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);
}
// -------------------------- SPI传输 --------------------------
static void vSpiTransmit(DacIcDev_t* pxDev)
{
// 16位指令:[3位操作码][3位地址][12位数据]
uint16_t tx_data = ((pxDev->xDacIcReg.xBits.ucC0_2 & 0x07) << 13) |
((pxDev->xDacIcReg.xBits.ucA0_2 & 0x07) << 10) |
(pxDev->xDacIcReg.xBits.usD0_11 & 0x0FFF);
__NOP();__NOP();
AD5623_CS_RESET();
__NOP();__NOP();
// 发送高8位
SPI_SendData(SPI1, (uint8_t)(tx_data >> 8));
while (RESET == SPI_GetFlagStatus(SPI1, SPI_FLAG_TXEPT));
while (RESET == SPI_GetFlagStatus(SPI1, SPI_FLAG_RXAVL));
SPI_ReceiveData(SPI1);
__NOP();__NOP();
// 发送低8位
SPI_SendData(SPI1, (uint8_t)(tx_data & 0xFF));
while (RESET == SPI_GetFlagStatus(SPI1, SPI_FLAG_TXEPT));
while (RESET == SPI_GetFlagStatus(SPI1, SPI_FLAG_RXAVL));
SPI_ReceiveData(SPI1);
__NOP();__NOP();
AD5623_CS_SET();
__NOP();__NOP();
}
// -------------------------- DAC设备初始化 --------------------------
static void vInitDacIcDev(DacIcDev_t* pxDev)
{
if(NULL == pxDev) return;
vGpioConfig();
vSpiConfig();
// 绑定函数指针
pxDev->vTest = vTestDacIcDev;
pxDev->vWrite = vWriteDacIcDev;
// 1. 软件复位所有通道
pxDev->xDacIcReg.ulData = 0;
pxDev->xDacIcReg.xBits.ucC0_2 = DAC_RST;
pxDev->xDacIcReg.xBits.ucA0_2 = DAC_ALL;
pxDev->xDacIcReg.xBits.usD0_11 = 0;
vSpiTransmit(pxDev);
// 2. 配置LDAC:禁用A/B通道锁存
pxDev->xDacIcReg.ulData = 0;
pxDev->xDacIcReg.xBits.ucC0_2 = LDAC_REG_SET;
pxDev->xDacIcReg.xBits.usD0_11 = 0x0003;
vSpiTransmit(pxDev);
// 3. 启用内部2.5V参考(A/B通道)
pxDev->xDacIcReg.ulData = 0;
pxDev->xDacIcReg.xBits.ucC0_2 = REF_REG_SET;
pxDev->xDacIcReg.xBits.ucA0_2 = DAC_A;
pxDev->xDacIcReg.xBits.usD0_11 = 0x0001;
vSpiTransmit(pxDev);
pxDev->xDacIcReg.ulData = 0;
pxDev->xDacIcReg.xBits.ucC0_2 = REF_REG_SET;
pxDev->xDacIcReg.xBits.ucA0_2 = DAC_B;
pxDev->xDacIcReg.xBits.usD0_11 = 0x0001;
vSpiTransmit(pxDev);
// 初始输出0V
pxDev->vWrite(pxDev, 0, WRITE_ANALOG_CHANNEL_A);
pxDev->vWrite(pxDev, 0, WRITE_ANALOG_CHANNEL_B);
}
// -------------------------- DAC写入 --------------------------
static void vWriteDacIcDev(DacIcDev_t* pxDev, uint16_t usDacValue, WRITE_ANALOG_CHANNEL_E eChannel)
{
if(NULL == pxDev || usDacValue > 0x0FFF) return;
pxDev->xDacIcReg.ulData = 0;
pxDev->xDacIcReg.xBits.ucA0_2 = (eChannel == WRITE_ANALOG_CHANNEL_A) ? DAC_A : DAC_B;
pxDev->xDacIcReg.xBits.ucC0_2 = WR_UPD_DAC;
pxDev->xDacIcReg.xBits.usD0_11 = usDacValue;
vSpiTransmit(pxDev);
}
// -------------------------- DAC测试 --------------------------
static void vTestDacIcDev(DacIcDev_t* pxDev)
{
if(NULL == pxDev) return;
while(1)
{
pxDev->vWrite(pxDev, 0, WRITE_ANALOG_CHANNEL_A);
pxDev->vWrite(pxDev, 0, WRITE_ANALOG_CHANNEL_B);
DELAY_Ms(500);
pxDev->vWrite(pxDev, 819, WRITE_ANALOG_CHANNEL_A);
pxDev->vWrite(pxDev, 819, WRITE_ANALOG_CHANNEL_B);
DELAY_Ms(500);
pxDev->vWrite(pxDev, 1638, WRITE_ANALOG_CHANNEL_A);
pxDev->vWrite(pxDev, 1638, WRITE_ANALOG_CHANNEL_B);
DELAY_Ms(500);
pxDev->vWrite(pxDev, 2458, WRITE_ANALOG_CHANNEL_A);
pxDev->vWrite(pxDev, 2458, WRITE_ANALOG_CHANNEL_B);
DELAY_Ms(500);
pxDev->vWrite(pxDev, 3277, WRITE_ANALOG_CHANNEL_A);
pxDev->vWrite(pxDev, 3277, WRITE_ANALOG_CHANNEL_B);
DELAY_Ms(500);
pxDev->vWrite(pxDev, 4095, WRITE_ANALOG_CHANNEL_A);
pxDev->vWrite(pxDev, 4095, WRITE_ANALOG_CHANNEL_B);
DELAY_Ms(500);
}
}
// -------------------------- WriteAnalog初始化 --------------------------
static void vInitWriteAnalog(WriteAnalog_t* pxWriteAnalog, DacIcDev_t* pxDev)
{
if(NULL == pxWriteAnalog || NULL == pxDev) return;
pxDev->vInit(pxDev);
pxWriteAnalog->pxDev = pxDev;
pxWriteAnalog->vSetA = vSetA;
pxWriteAnalog->vSetB = vSetB;
pxWriteAnalog->vSetA(pxWriteAnalog, 0);
pxWriteAnalog->vSetB(pxWriteAnalog, 0);
}
// -------------------------- 通道A/B设置 --------------------------
static void vSetA(WriteAnalog_t* pxWriteAnalog, uint16_t usDacValue)
{
if(NULL == pxWriteAnalog) return;
pxWriteAnalog->pxDev->vWrite(pxWriteAnalog->pxDev, usDacValue, WRITE_ANALOG_CHANNEL_A);
}
static void vSetB(WriteAnalog_t* pxWriteAnalog, uint16_t usDacValue)
{
if(NULL == pxWriteAnalog) return;
pxWriteAnalog->pxDev->vWrite(pxWriteAnalog->pxDev, usDacValue, WRITE_ANALOG_CHANNEL_B);
}
// -------------------------- 全局SPI初始化 --------------------------
void spi_dac_global_init(void)
{
vSpiConfig();
}
#ifndef WRITE_ANALOG_H
#define WRITE_ANALOG_H
#include "stdint.h"
// 配置开关
#define WRITE_ANALOG_USING_LOCK 0
#define AD5623R5 0
#define DAC_IC_TYPE AD5623R5
// DAC参数
#define DAC_IC_BIT 12 // 12位DAC
#define DAC_IC_REF 2.5f // 内部参考电压2.5V
// 通道枚举
typedef enum
{
WRITE_ANALOG_CHANNEL_A, // DAC A通道
WRITE_ANALOG_CHANNEL_B // DAC B通道
}WRITE_ANALOG_CHANNEL_E;
// AD5623操作码(3位)
#define WR_REGR 0x00 // 写寄存器
#define UPD_DAC_REG 0x01 // 更新DAC
#define WR_REG_UPD_ALL_DAC_LDAC 0x02 // 写寄存器并更新所有DAC
#define WR_UPD_DAC 0x03 // 写并更新指定DAC
#define DAC_OFF 0x04 // DAC掉电
#define DAC_RST 0x05 // 软件复位
#define LDAC_REG_SET 0x06 // 配置LDAC寄存器
#define REF_REG_SET 0x07 // 配置参考电压寄存器
// AD5623地址码(3位)
#define DAC_A 0x00 // 通道A
#define DAC_B 0x01 // 通道B
#define DAC_ALL 0x07 // 所有通道
typedef union
{
struct
{
uint16_t usD0_11: 12; // bit9~0: 12位DAC数据
uint8_t ucA0_2: 3; // bit12~10: 地址码
uint8_t ucC0_2: 3; // bit15~13: 操作码
}xBits;
uint16_t usData; // 16位指令整体
uint32_t ulData;
}DacIcReg_t;
// DAC设备结构体
typedef struct DacIcDev_t
{
DacIcReg_t xDacIcReg;
void (*vInit)(struct DacIcDev_t* pxDev);
void (*vWrite)(struct DacIcDev_t* pxDev, uint16_t usDacValue, WRITE_ANALOG_CHANNEL_E eChannel);
void (*vTest)(struct DacIcDev_t* pxDev);
}DacIcDev_t;
// WriteAnalog控制结构体
typedef struct WriteAnalog_t
{
DacIcDev_t* pxDev;
void (*vInit)(struct WriteAnalog_t* pxWriteAnalog, DacIcDev_t* pxDev);
void (*vSetA)(struct WriteAnalog_t* pxWriteAnalog, uint16_t usDacValue);
void (*vSetB)(struct WriteAnalog_t* pxWriteAnalog, uint16_t usDacValue);
}WriteAnalog_t;
// 全局对象声明
extern DacIcDev_t xDacIcDev1;
extern DacIcDev_t xDacIcDev2;
extern DacIcDev_t xDacIcDev3;
extern DacIcDev_t xDacIcDev4;
extern DacIcDev_t xDacIcDev5;
extern WriteAnalog_t xWriteAnalog1;
extern WriteAnalog_t xWriteAnalog2;
extern WriteAnalog_t xWriteAnalog3;
extern WriteAnalog_t xWriteAnalog4;
extern WriteAnalog_t xWriteAnalog5;
// 全局函数声明
void spi_dac_global_init(void);
#endif
第一步:修改 AD5632 驱动文件 (放在驱动层)
修改ad5632的write analog.c与write analog.h两个驱动文件放在驱动层里面
第二步:创建高压控制文件 (放在 Application 层)
目标:根据目标电压,计算出需要动用哪些模块、每个模块需要输出多少电压,然后调用驱动层的接口去执行,并完成电压读取。
创建 2 个新文件,hv_voltage_ctrl.c和hv_voltage_ctrl.h放在 Application/ 文件夹下。
(结合高压电源模块说明进行编写)
hv_voltage_ctrl.h头文件:声明 set_vol 函数和电压读取函数的接口,定义必要的宏等。
hv_voltage_ctrl.c:
完成以下任务
1、set_vol(unit vol)
(1)根据设定电压确认需要用到多少个模块,总共5个
高压模块输出电压 = DAC 输出电压 × 放大系数
(2)计算每个模块需要输出多少电压
(3)往每个模块发送DAC指令
(4)先关闭低压输出通道,再打开高压输出通道。
2、完成电压读取 帮我检查一下这些文件有没有问题,为什么输出不了高压50V,还需要别的文件参考请告诉我.
最新发布