关于err_sys未定义错误解决方法

本文介绍了一组用于C语言程序中的错误处理函数,包括err_ret、err_sys、err_exit等。这些函数能够帮助开发者更方便地处理系统调用时产生的错误,并提供了不同的错误处理方式。
    1. err_sys以及err_quit等函数不是C语言自带函数,是作者自己编写的函数。所以,想要运行书中的源代码,就必须自建一个头文件my_err.h把作者的代码拷贝进去,然后在程序中加载,可以和apue.h放在一个路径下,然后在代码中加上#include "error.h"。
    2. 下面是error.h的内容。



    3. #include <errno.h> /* for definition of errno */
    4. #include <stdarg.h> /* ISO C variable aruments */

    5. static void err_doit(int, int, const char *, va_list);

    6. /*
    7.  * Nonfatal error related to a system call.
    8.  * Print a message and return.
    9.  */
    10. void
    11. err_ret(const char *fmt, ...)
    12. {
    13.     va_list ap;

    14.     va_start(ap, fmt);
    15.     err_doit(1, errno, fmt, ap);
    16.     va_end(ap);
    17. }


    18. /*
    19.  * Fatal error related to a system call.
    20.  * Print a message and terminate.
    21.  */
    22. void
    23. err_sys(const char *fmt, ...)
    24. {
    25.     va_list ap;

    26.     va_start(ap, fmt);
    27.     err_doit(1, errno, fmt, ap);
    28.     va_end(ap);
    29.     exit(1);
    30. }


    31. /*
    32.  * Fatal error unrelated to a system call.
    33.  * Error code passed as explict parameter.
    34.  * Print a message and terminate.
    35.  */
    36. void
    37. err_exit(int error, const char *fmt, ...)
    38. {
    39.     va_list ap;

    40.     va_start(ap, fmt);
    41.     err_doit(1, error, fmt, ap);
    42.     va_end(ap);
    43.     exit(1);
    44. }


    45. /*
    46.  * Fatal error related to a system call.
    47.  * Print a message, dump core, and terminate.
    48.  */
    49. void
    50. err_dump(const char *fmt, ...)
    51. {
    52.     va_list ap;

    53.     va_start(ap, fmt);
    54.     err_doit(1, errno, fmt, ap);
    55.     va_end(ap);
    56.     abort(); /* dump core and terminate */
    57.     exit(1); /* shouldn'get here */
    58. }


    59. /*
    60.  * Nonfatal error unrelated to a system call.
    61.  * Print a message and return.
    62.  */
    63. void
    64. err_msg(const char *fmt, ...)
    65. {
    66.     va_list ap;

    67.     va_start(ap, fmt);
    68.     err_doit(0, 0, fmt, ap);
    69.     va_end(ap);
    70. }


    71. /*
    72.  * Fatal error unrelated to a system call.
    73.  * Print a message and terminate.
    74.  */
    75. void
    76. err_quit(const char *fmt, ...)
    77. {
    78.     va_list ap;

    79.     va_start(ap, fmt);
    80.     err_doit(0, 0, fmt, ap);
    81.     va_end(ap);
    82.     exit(1);
    83. }


    84. /*
    85.  * Print a message and return to caller.
    86.  * Caller specifies "errnoflag".
    87.  */
    88. static void
    89. err_doit(int errnoflag, int error, const char *fmt, va_list ap)
    90. {
    91.     char buf[MAXLINE];
    92.    vsnprintf(buf, MAXLINE, fmt, ap);
    93.    if (errnoflag)
    94.        snprintf(buf+strlen(buf), MAXLINE-strlen(buf), ": %s",
    95.          strerror(error));
    96.    strcat(buf, "\n");
    97.    fflush(stdout); /* in case stdout and stderr are the same */
    98.    fputs(buf, stderr);
    99.    fflush(NULL); /* flushes all stdio output streams */
    100. }

.\Objects\ctrlbox.axf: Error: L6218E: Undefined symbol DELAY_Ms (referred from hv_voltage_ctrl.o). .\Objects\ctrlbox.axf: Error: L6218E: Undefined symbol hv_set_s1_ex (referred from hv_voltage_ctrl.o). .\Objects\ctrlbox.axf: Error: L6218E: Undefined symbol hv_set_s2_ex (referred from hv_voltage_ctrl.o). .\Objects\ctrlbox.axf: Error: L6218E: Undefined symbol hv_spi_adc_read (referred from hv_voltage_ctrl.o). .\Objects\ctrlbox.axf: Error: L6218E: Undefined symbol spi_dac_global_init (referred from hv_voltage_ctrl.o). Not enough information to list image symbols.#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 #include "write_analog.h" #include "hv_voltage_ctrl.h" #include <math.h> #include "ls_spi.h" #include "ls_io_ctrl.h" #include "delay.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); // 复位所有模块 // -------------------------- 公共函数实现 -------------------------- 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; } 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->set_voltage(analog, dac_val); 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. 打开高压输出(严格遵守:仅允许一个S2_EX有效!) 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; } 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; } 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_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; } 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 uint16_t adc_val = hv_spi_adc_read(module_id, 7); float version_vol = adc_val * ADC_VERSION_COEF; // 版本号有效范围:0.5V~2.5V(对应版本1~5,每0.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; } 怎么解决这五个报错,不新增文件的情况下
11-26
#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" // 全局系统状态 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); // 复位所有模块 // -------------------------- 公共函数实现 -------------------------- 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; } 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->set_voltage(analog, dac_val); 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. 打开高压输出(严格遵守:仅允许一个S2_EX有效!) 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; } 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; } 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_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; } 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 uint16_t adc_val = hv_spi_adc_read(module_id, 7); float version_vol = adc_val * ADC_VERSION_COEF; // 版本号有效范围:0.5V~2.5V(对应版本1~5,每0.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; } 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); } 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; } 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); } } Rebuild started: Project: ctrl_box_500 *** Using Compiler 'V5.06 update 7 (build 960)', folder: 'C:\Keil_v5\ARM\ARMCC\Bin' Rebuild target 'MM32F0273D' compiling test.c... compiling led.c... compiling task.c... compiling ad5322.c... compiling ringbuf.c... compiling logger.c... compiling hv_voltage_ctrl.c... compiling hal_flash.c... compiling main.c... compiling io_comm.c... compiling ls_uart0.c... compiling hal_gpio.c... compiling write_analog.c... compiling ls_io_ctrl.c... compiling ls_spi.c... compiling hal_rcc.c... compiling hal_uart.c... compiling tla2518_A.c... compiling ls_system.c... assembling startup_mm32f0270_keil.s... compiling hal_spi.c... compiling hal_tim.c... compiling system_mm32f0270.c... linking... .\Objects\ctrlbox.axf: Error: L6218E: Undefined symbol DELAY_Ms (referred from hv_voltage_ctrl.o). .\Objects\ctrlbox.axf: Error: L6218E: Undefined symbol spi_dac_global_init (referred from hv_voltage_ctrl.o). Not enough information to list image symbols. Not enough information to list load addresses in the image map. Finished: 2 information, 0 warning and 2 error messages. ".\Objects\ctrlbox.axf" - 2 Error(s), 0 Warning(s). Target not created. Build Time Elapsed: 00:00:01 #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 解决一下
11-26
#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
最新发布
11-26
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值