/** * @file board.c * @author xxx * @date 2023-09-12 13:52:37 * @brief * @copyright Copyright (c) 2023 by xxx, All Rights Reserved. */ #include "board.h" #include "entity.h" #include "delay.h" #include "filter.h" void SystemClock_Config(void); static BOOL driver_init_flag = FALSE; static uint16_t board_cache[BOARD_CACHE_MAX]; ///< 调节缓存 static lpf_t lpf_temperature; ///< 温度滤波器 __IO static BOOL system_clock_config_flag = FALSE; ///< 系统时钟配置改变标志 __IO uint8_t app_preload_flag __attribute__((at(APP_PRELOAD_AREA))); // 预加载标志 __IO uint8_t app_preload_language_flag __attribute__((at(APP_PRELOAD_AREA + 1))); // 语言标志 __IO uint8_t app_preload_bootload_flag __attribute__((at(APP_PRELOAD_AREA + 2))); // 触发BOOTLOAD启动标志(在用户代码中接受代码文件) __IO uint8_t app_preload_bootload_jump_flag __attribute__((at(APP_PRELOAD_AREA + 3))); // 触发BOOTLOAD跳转更新标志(在BOOTLOAD代码中更新用户代码) __IO uint32_t app_preload_cupid_encrypt __attribute__((at(APP_PRELOAD_AREA + 4))); // 加密后的CPUID /***************************************** 板卡初始化相关函数 *****************************************/ /** * @brief LCD设计 * @return {*} * @note */ void lcd_design(void) { } /** * @brief LCD初始化 * @return {*} * @note */ void lcd_init(void) { // 设置功能引脚 GPIO_SET_OUTPUT(LCD_PWR_GPIO_Port, LCD_PWR_Pin); GPIO_SET_OUTPUT(LCD_CS_GPIO_Port, LCD_CS_Pin); GPIO_SET_OUTPUT(LCD_DISP_GPIO_Port, LCD_DISP_Pin); if (0 == LCD_IS_POWER_ON()) { } } /** * @brief LCD反初始化 * @return {*} * @note */ void lcd_dinit(void) { } /** * @brief 功耗引脚初始化 * @return {*} * @note */ void driver_init(void) { // 标志位检查:driver_init_flag = TRUE,表示已经初始化 if (driver_init_flag == TRUE) { return; } driver_init_flag = TRUE; pdctrl_run(); // 控制输出使能 PWM_START(TIM3, LL_TIM_CHANNEL_CH3); // PWM OUT使能 } /** * @brief 功耗引脚反初始化 * @return {*} * @note */ void driver_dinit(void) { // 标志位检查:driver_init_flag = FALSE,表示已经反初始化 if (driver_init_flag == FALSE) { return; } driver_init_flag = FALSE; pdctrl_stop(); // 控制输出禁用 PWM_STOP(TIM3, LL_TIM_CHANNEL_CH3); // PWM OUT禁用 } /** * @brief 板卡初始化 * @return {*} * @note */ void board_init(void) { VIP_H_EN_DISABLE(); // IP禁用,满足条件时才使能 adc_init(ADCS_1, ADC1, DMA1, LL_DMA_CHANNEL_1, 30, IN5 | IN6 | IN7 | IN8 | IN9 | IN11 | IN12 | IN13 | IN14 | INTEMP | INVREF); // 初始化ADC1通道,默认采集AD adc_init(ADCS_2, ADC2, DMA1, LL_DMA_CHANNEL_2, 10, IN5 | IN6); // 初始化ADC2通道,慢速采集通道 rtc_init(); // 初始化RTC eeprom_m95_init(M95_1); // 初始化SPI EEPROM1 eeprom_m95_init(M95_2); // 初始化SPI EEPROM2 eeprom_fm24_init(); // 初始化 IIC EEPROM eeprom_lc02b_init(); // 初始化 IIC EEPROM leds_init(); // 初始化LED lpf_init(&lpf_temperature); system_clock_config_low(); // debug_freeze_watchdog(); // 冻结看门狗 } void board_dinit(void) { adc_dinit(ADCS_1); // ADC反初始化 DISABLE_TIM(TIM6); DISABLE_TIM(TIM7); driver_dinit(); rtc_dinit(); // RTC反初始化 eeprom_m95_dinit(M95_1); eeprom_m95_dinit(M95_2); eeprom_fm24_dinit(); eeprom_lc02b_dinit(); leds_dinit(); // LED Deinitialization lcd_dinit(); // LCD screen Deinitialization } /** * @brief 板卡工作暂停 * @return {*} * @note 在用户层处理bootload接收数据时需要暂时关闭一些应用层的处理 */ void board_work_stop_or_run(void) { static BOOL stop_or_run_state = FALSE; if (get_app_preload_bootload_flag() != stop_or_run_state) { // 如果stop_or_run_state是FALSE,那么app_preload_bootload_flag是TRUE,表示当前需要暂停工作 // 目前先暂停TIM7控制模块,TIM6的任务执行不受影响,因为任务模块会执行最简单的任务 if (stop_or_run_state == FALSE) { DISABLE_TIM(TIM7); } else { ENABLE_TIM(TIM7); } stop_or_run_state = get_app_preload_bootload_flag(); } } /** * @brief 缓存数据初始化 * @return {*} * @note */ void board_cache_reset(void) { for (uint8_t i = 0; i < BOARD_CACHE_MAX; i++) { board_cache[i] = 0; } } /** * @brief 缓存数据获取 * @param {board_cache_e} index * @return {*} * @note */ uint16_t board_cache_get(board_cache_e index) { return board_cache[index]; } /** * @brief 系统时钟配置低频 * @return {*} * @note 2M 默认使用系统时钟配置低频 */ // static void system_clock_config_low_2m(void) //{ // LL_FLASH_SetLatency(LL_FLASH_LATENCY_0); // while (LL_FLASH_GetLatency() != LL_FLASH_LATENCY_0) // { // } // LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE1); // while (LL_PWR_IsActiveFlag_VOS() != 0) // { // } // LL_RCC_HSE_Enable(); // /* Wait till HSE is ready */ // while (LL_RCC_HSE_IsReady() != 1) // { // } // LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, LL_RCC_PLLM_DIV_1, 8, LL_RCC_PLLR_DIV_2); // LL_RCC_PLL_EnableDomain_SYS(); // LL_RCC_PLL_Enable(); // /* Wait till PLL is ready */ // while (LL_RCC_PLL_IsReady() != 1) // { // } // LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL); // /* Wait till System clock is ready */ // while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL) // { // } // LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_16); // LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1); // LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1); // LL_Init1msTick(2000000); // LL_SetSystemCoreClock(2000000); //} void system_clock_config_set_flag(BOOL flag) { system_clock_config_flag = flag; } /** * @brief 系统时钟配置低频 * @return {*} * @note 4M 默认使用系统时钟配置低频 */ void system_clock_config_low(void) { if (system_clock_config_flag == FALSE) { return; } system_clock_config_set_flag(FALSE); // if (udevice.dev_algorithm_mode == MODE_VARIABLE_FREQUENCY_CONTROL_ALGORITHM) // { // system_clock_config_low_2m(); // } // else // { // SystemClock_Config(); // } SystemClock_Config(); uint32_t hclk = SystemCoreClock / 1000000; delay_init(hclk); uint16_t pres = (hclk * 100) - 1; if (LL_TIM_GetPrescaler(TIM6) != pres) { LL_TIM_SetPrescaler(TIM6, pres); } if (LL_TIM_GetPrescaler(TIM7) != pres) { LL_TIM_SetPrescaler(TIM7, pres); } uint32_t reload = (hclk * 1000) - 1; pdctrl_pwm_set_arr(reload); if (LL_TIM_GetAutoReload(TIM3) != reload) { LL_TIM_SetAutoReload(TIM3, reload); } } /** * @brief 系统时钟配置高频 * @return {*} * @note 16M */ void system_clock_config_hight(void) { if (system_clock_config_flag == FALSE) { return; } LL_FLASH_SetLatency(LL_FLASH_LATENCY_0); while (LL_FLASH_GetLatency() != LL_FLASH_LATENCY_0) { } LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE1); while (LL_PWR_IsActiveFlag_VOS() != 0) { } LL_RCC_HSE_Enable(); /* Wait till HSE is ready */ while (LL_RCC_HSE_IsReady() != 1) { } LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, LL_RCC_PLLM_DIV_1, 8, LL_RCC_PLLR_DIV_2); LL_RCC_PLL_EnableDomain_SYS(); LL_RCC_PLL_Enable(); /* Wait till PLL is ready */ while (LL_RCC_PLL_IsReady() != 1) { } LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL); /* Wait till System clock is ready */ while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL) { } LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_2); LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1); LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1); LL_Init1msTick(16000000); LL_SetSystemCoreClock(16000000); uint32_t hclk = SystemCoreClock / 1000000; uint16_t pres = (hclk * 100) - 1; if (LL_TIM_GetPrescaler(TIM6) != pres) { LL_TIM_SetPrescaler(TIM6, pres); } if (LL_TIM_GetPrescaler(TIM7) != pres) { LL_TIM_SetPrescaler(TIM7, pres); } uint32_t reload = (hclk * 1000) - 1; pdctrl_pwm_set_arr(reload); if (LL_TIM_GetAutoReload(TIM3) != reload) { LL_TIM_SetAutoReload(TIM3, reload); } } /***************************************** 板卡LCD操作相关函数 *****************************************/ /** * @brief LCD刷新 * @return {*} * @note */ void gui_flush(void) { } /** * @brief LCD刷新并清除缓存 * @return {*} * @note */ void gui_flush_Clear(void) { } /** * @brief LCD全屏清除 * @return {*} * @note */ void gui_clr(void) { } /** * @brief LCD设置清屏标志 * @return {*} * @note */ void gui_set_clear_flag(void) { } /** * @brief LCD获取清屏标志 * @return {*} * @note */ BOOL gui_get_clear_flag(void) { return TRUE; } /** * @brief LCD全屏填充 * @return {*} * @note */ void gui_full(void) { } /** * @brief LCD启动 * @return {*} * @note */ void gui_open() { } /** * @brief LCD关闭 * @return {*} * @note */ void gui_close() { } /** * @brief 设置扫描方向 * @return {*} * @note */ void gui_set_scandir(uint8_t dir) { } /***************************************** 板卡参数相关函数 *****************************************/ /** * @brief 根据目标行程计算DAC输出理论值 * @param {float32} output - 目标行程(百分比) * @return {uint16_t} DAC输出理论值 * @note 计算公式如下: * > (Osh-Osl)/(Ish-Isl)=(Ov-Osl)/(Iv-Isl)

* > Ov=[(Osh-Osl)*(Iv-Isl)/(Ish-Isl)]+Osl

*/ uint16_t get_dac(float32 output) { return ((udevice.output_max - udevice.output_min) * (output - 0) / (100 - 0)) + udevice.output_min; } /** * @brief PWM输出阀位百分比 * @param {float32} position_per-阀位百分比 * @return {*} * @note 阀位反馈输出, 0%输出4.00mA, 100.0%输出20.00mA *> 0% - 4.0mA

*> 10% - 5.6mA

*> 20% - 7.2mA

*> 30% - 8.8mA

*> 40% - 10.4mA

*> 50% - 12.0mA

*> 55% - 12.8mA

*> 60% - 13.6mA

*> 70% - 15.2mA

*> 80% - 16.8mA

*> 90% - 18.4mA

*> 100% - 20.0mA

*/ void pwm_output_position(float32 position_per) { float32 ftemp = 0; // 根据阀位百分比计算对应的电流 ftemp = position_per; ftemp *= 16; ftemp += 400; // 根据校准参数计算占空比 ftemp *= calib_param[CALIBPARA_VIP].value[0]; ftemp += calib_param[CALIBPARA_VIP].value[1]; // PWM输出 PWM_SET_DUTY(TIM2, 4, ftemp); } /** * @brief 校准4-20mA输出电流 * @return {*} * @note */ void calib_loop(void) { #define MA4 (LOOP_CURRENT_MIN * 1000) #define MA20 (LOOP_CURRENT_MAX * 1000) uint16_t ma = 0, adc = 0; float32 f; // 计算校准参数 ma = MA20 - MA4; adc = board_cache[BOARD_CACHE_2] - board_cache[BOARD_CACHE_1]; f = ma; f = f / adc; calib_param[CALIBPARA_LOOP].value[0] = f / 10; f = f * board_cache[BOARD_CACHE_2]; calib_param[CALIBPARA_LOOP].value[1] = (MA20 - f) / 10; calib_param[CALIBPARA_LOOP].is_calibration = TRUE; } /** * @brief 校准压力表 * @return {*} * @note */ void calib_kpa(void) { #define PRESSURE_200_KPA 200.0f // 200kPa #define PRESSURE_400_KPA 400.0f // 400kPa uint16_t ma = 0, adc = 0; float32 f; // 计算校准参数 ma = PRESSURE_400_KPA - PRESSURE_200_KPA; adc = board_cache[BOARD_CACHE_2] - board_cache[BOARD_CACHE_1]; f = ma; f = f / adc; calib_param[CALIBPARA_PS].value[0] = f; f = f * board_cache[BOARD_CACHE_2]; calib_param[CALIBPARA_PS].value[1] = PRESSURE_400_KPA - f; calib_param[CALIBPARA_PSB].value[0] = calib_param[CALIBPARA_PS].value[0]; calib_param[CALIBPARA_PSB].value[1] = calib_param[CALIBPARA_PS].value[1]; calib_param[CALIBPARA_PB].value[0] = calib_param[CALIBPARA_PS].value[0]; calib_param[CALIBPARA_PB].value[1] = calib_param[CALIBPARA_PS].value[1]; } /** * @brief 校准4-20mA输出电流 * @return {*} * @note */ void calib_pwm_out(void) { // 计算校准参数 float32 mA4 = 400; float32 mA20 = 2000; float32 TDuty4 = board_cache[BOARD_CACHE_1]; float32 TDuty20 = board_cache[BOARD_CACHE_2]; calib_param[CALIBPARA_VIP].value[0] = (TDuty20 - TDuty4) / (mA20 - mA4); calib_param[CALIBPARA_VIP].value[1] = TDuty20 - calib_param[CALIBPARA_VIP].value[0] * mA20; } /** * @brief 校准阀门位置参数,电压转换成%(放大10倍,1位小数) * @return {*} * @note 计算公式如下: * > k = (y2-y1) / (x2-x1)

* > m = y2 - k * x2

*/ void calib_parapos_perent(void) { float32 ftmp = 0.0; // 直行程位置反馈 ftmp = udevice.pos100_travel_vol - udevice.pos0_travel_vol; calib_param[CALIBPARA_PSB].value[0] = 100 / ftmp; ftmp = calib_param[CALIBPARA_PSB].value[0] * udevice.pos100_travel_vol; calib_param[CALIBPARA_PSB].value[1] = 100 - ftmp; calib_param[CALIBPARA_PSB].is_calibration = TRUE; // 小回路 ftmp = udevice.pos100_minor_vol - udevice.pos0_minor_vol; calib_param[CALIBPARA_IPSB].value[0] = 100 / ftmp; ftmp = calib_param[CALIBPARA_IPSB].value[0] * udevice.pos100_minor_vol; calib_param[CALIBPARA_IPSB].value[1] = 100 - ftmp; calib_param[CALIBPARA_IPSB].is_calibration = TRUE; } /** * @brief 获取当前实际行程ADC值 * @return {*} * @note */ uint16_t get_actual_travel_adc(void) { adc_raw[ADC_PSB_CHANNEL] = adc_result_median(ADCS_1, ADC_PSB_CHANNEL); return adc_raw[ADC_PSB_CHANNEL]; } /** * @brief 获取当前实际行程ADC值 * @return {*} * @note */ uint16_t get_actual_travel_adc_average(void) { adc_raw[ADC_PSB_CHANNEL] = adc_result_average(ADCS_1, ADC_PSB_CHANNEL); return adc_raw[ADC_PSB_CHANNEL]; } /** * @brief 获取当前实际行程百分比 * @param {uint16_t} adc * @return {*} * @note */ float32 actual_adc_convert_percent(uint16_t adc) { float32 f = adc * 1.0f; // 计算当前位置 f *= calib_param[CALIBPARA_PSB].value[0]; f += calib_param[CALIBPARA_PSB].value[1]; if (f < 0) { f = 0; } if (f > 100) { f = 100; } return f; } /** * @brief 获取当前实际行程 * @param {uint8_t} filter 1:平均 2:中值 * @return {*} * @note */ float32 get_actual_travel(filter_e filter) { uint16_t raw = 0; // 读取位置反馈ADC值 if (filter == FILTER_AVERAGE) { raw = adc_result_average(ADCS_1, ADC_PSB_CHANNEL); } else if (filter == FILTER_MEDIAN) { raw = adc_result_median(ADCS_1, ADC_PSB_CHANNEL); } else { raw = adc_result_average(ADCS_1, ADC_PSB_CHANNEL); } adc_raw[ADC_PSB_CHANNEL] = raw; return actual_adc_convert_percent(raw); } /** * @brief 获取当前实际行程 * @param {uint8_t} filter 1:平均 2:中值 * @return {*} * @note */ float32 get_actual_travel_2(filter_e filter) { uint16_t raw = 0; // 读取位置反馈ADC值 if (filter == FILTER_AVERAGE) { raw = adc_result_average(ADCS_2, ADC_PSB_CHANNEL); } else if (filter == FILTER_MEDIAN) { raw = adc_result_median(ADCS_2, ADC_PSB_CHANNEL); } else { raw = adc_result_average(ADCS_2, ADC_PSB_CHANNEL); } adc_raw[ADC_PSB_CHANNEL] = raw; return actual_adc_convert_percent(raw); } /** * @brief 获取当前回路电流 * @return {float32} 回路电流值 * @note */ float32 get_current(void) { float32 f = 0.0; // 读取回路电流ADC值 adc_raw[ADC_LOOP_CHANNEL] = adc_result_average(ADCS_1, ADC_LOOP_CHANNEL); f = adc_raw[ADC_LOOP_CHANNEL]; // 计算回路电流 f *= calib_param[CALIBPARA_LOOP].value[0]; f += calib_param[CALIBPARA_LOOP].value[1]; f = f / 100; if (f < 0) { f = 0; } return f; } /** * @brief 获取当前回路电流,保留小数点后1位 * @param {float32} current * @return {*} * @note */ float32 get_current_deal(float32 current) { // 判断current小数点后第二位是否大于5 if ((uint16_t)(current * 100) % 10 >= 5) { return (uint16_t)(current * 10) * 0.1f + 0.1f; } else { return (uint16_t)(current * 10) * 0.1f; } } /** * @brief 获取当前温度值 * @return {float32} 温度值 * @note */ float32 get_temperature(void) { float32 tmp = 0.0f; // 采集ADC原始数据 adc_raw[ADC_NTC_CHANNEL] = adc_result_average(ADCS_1, ADC_NTC_CHANNEL); // 使用NTC算法计算温度值 tmp = ntc_get_temp(adc_raw[ADC_NTC_CHANNEL]).f; tmp = lpf_update(&lpf_temperature, tmp); return tmp; } /** * @brief 获取当前流量 * @return {*} * @note */ float32 get_flow(void) { float32 v = 0.0f; adc_raw[ADC_FLOW] = adc_result_average(ADCS_1, ADC_BPB_CHANNEL); v = ((CPU_VREF * adc_raw[ADC_FLOW] / ADC_MAX) - 0.4) * 600 / 1.6; return v < 0 ? 0 : v; } /** * @brief 获取当前压力 * @return {float32} 压力值 * @note */ float32 get_pressure(pressure_index_e id) { float32 f = 0.0; switch (id) { case ADC_INDEX_PRESSSOURCE: // 读取气源压力ADC adc_raw[ADC_BP_CHANNEL] = adc_result_average(ADCS_1, ADC_BP_CHANNEL); f = adc_raw[ADC_BP_CHANNEL]; // 计算气源压力 f *= calib_param[CALIBPARA_PS].value[0]; f += calib_param[CALIBPARA_PS].value[1]; rt_data.pressure_s = f; break; case ADC_INDEX_PRESSOUTA: // 读取A路压力ADC adc_raw[ADC_BPA_CHANNEL] = adc_result_average(ADCS_1, ADC_BPA_CHANNEL); f = adc_raw[ADC_BPA_CHANNEL]; // 计算A路压力 f *= calib_param[CALIBPARA_PSB].value[0]; f += calib_param[CALIBPARA_PSB].value[1]; rt_data.pressure_a = f; break; case ADC_INDEX_PRESSOUTB: // 读取B路压力ADC adc_raw[ADC_BPB_CHANNEL] = adc_result_average(ADCS_1, ADC_BPB_CHANNEL); f = adc_raw[ADC_BPB_CHANNEL]; // 计算B路压力 f *= calib_param[CALIBPARA_PB].value[0]; f += calib_param[CALIBPARA_PB].value[1]; rt_data.pressure_b = f; break; default: break; } return f; } /***************************** 通过电阻测算,只在测试程序中使用 *****************************/ /** * @brief 回路电流检测转换 * @param {uint16_t} adc * @return {float32} 回路电流值 * @note 计算公式如下: * > 压力和电流关系:(adc/4096)*VREF_VALUE/(5*20) = ma

* > 简化后:adc*VREF_VALUE/409600 = ma

*/ float32 loop_current_convert(uint16_t adc) { float32 f; f = ((float32)(adc * VREF_VALUE)) / 409600; return f; } /** * @brief DAC:IP输出电流值转换 * @param {uint16_t} dac * @return {float32} IP输出电流值 * @note */ float32 ip_dac2current(uint16_t dac) { float32 vol = 0, cur = 0; // 计算电压值 mv vol = (float32)dac / 4096 * VREF_VALUE; // 计算电流值 ma cur = vol / (40 * 40); // 如果电流值大于2.5,则设置为2.5 if (cur > 2.5f) { cur = 2.5; } return cur; } /** * @brief IP输出电流值转换 * @return {*} * @note */ float32 ip2current(void) { float32 cur = 0; adc_raw[ADC_VIP_CHANNEL] = adc_result_average(ADCS_1, ADC_VIP_CHANNEL); // 计算电流值 ma cur = (float32)adc_raw[ADC_VIP_CHANNEL] / (float32)(10 * 101); return cur; } /** * @brief PWM输出电流值转换 * @param {float32} current * @return {*} * @note: 计算公式如下: * > I_OUT=3V*Duty/10K*100(mA) */ void pwm_duty2current(float32 cur_ma) { float32 current; if (cur_ma < 4) current = 4; else if (cur_ma > 20) current = 20; else current = cur_ma; float32 duty = current / 30; uint16_t count = duty * 4095; PWM_CTRL_OUTPUT(count); } /** * @brief 获取RTC时间 * @param {uDateTime_TypeDef} *time * @return {*} * @note */ void get_timestamp(uDateTime_TypeDef *time) { uint8_t tmp[7]; rtc_get_clock_time(tmp); time->Date.Year = tmp[6]; // 将年存储在data结构体的year字段中 time->Date.Month = tmp[5]; // 将月存储在data结构体的month字段中 time->Date.Day = tmp[4]; // 将日存储在data结构体的day字段中 time->Date.Hour = tmp[2]; // 将时存储在data结构体的hour字段中 time->Date.Minute = tmp[1]; // 将分存储在data结构体的minute字段中 time->Date.Second = tmp[0]; // 将秒存储在data结构体的second字段中 } void get_real_time(uint8_t *year, uint8_t *month, uint8_t *day, uint8_t *hour, uint8_t *min, uint8_t *sec) { get_timestamp((uDateTime_TypeDef *)&rt_data.save.real_time); *year = hex_format_dec(rt_data.save.real_time.Date.Year); *month = hex_format_dec(rt_data.save.real_time.Date.Month); *day = hex_format_dec(rt_data.save.real_time.Date.Day); *hour = hex_format_dec(rt_data.save.real_time.Date.Hour); *min = hex_format_dec(rt_data.save.real_time.Date.Minute); *sec = hex_format_dec(rt_data.save.real_time.Date.Second); } void set_real_time(uint8_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t min, uint8_t sec) { rtc_date date = { .year = year, .month = month, .day = day, .hour = hour, .minute = min, .second = sec, .weekday = get_weekday(2000 + hex_format_dec(year), hex_format_dec(month), hex_format_dec(day)), }; rtc_weekday_convert(&date.weekday); rtc_set_clock_time(&date); get_timestamp((uDateTime_TypeDef *)&rt_data.save.real_time); } /** * @brief 设置输出PWM校准电流 * @return {*} * @note 计算公式如下: * > y = k*x + m (x表示电流,y表示PWM占空比)

* > k = (TDuty20 - TDuty4) / (mA20 - mA4)

* > m = TDuty20 - k * mA20

*/ void set_pwm_calib_current() { float32 mA4 = 400; float32 mA20 = 2000; float32 TDuty4 = udevice.output_4ma_duty; float32 TDuty20 = udevice.output_20ma_duty; calib_param[CALIBPARA_VIP].value[0] = (TDuty20 - TDuty4) / (mA20 - mA4); calib_param[CALIBPARA_VIP].value[1] = TDuty20 - calib_param[CALIBPARA_VIP].value[0] * mA20; } /** * @brief 读取4mA输入时的ADC电压 * @return {*} */ void set_loop_4ma(void) { board_cache[BOARD_CACHE_1] = adc_result_average(ADCS_1, ADC_LOOP_CHANNEL); // 获取4mA输入时adc值 } /** * @brief 读取20mA输入时的ADC值 * @return {*} */ void set_loop_20ma(void) { board_cache[BOARD_CACHE_2] = adc_result_average(ADCS_1, ADC_LOOP_CHANNEL); } /** * @brief 读取200kPa输入时的ADC电压 * @return {*} */ void set_200kpa(void) { board_cache[BOARD_CACHE_1] = adc_result_average(ADCS_1, ADC_BP_CHANNEL); // 获取200kPa时adc值 } /** * @brief 读取400kPa输入时的ADC电压 * @return {*} */ void set_400kpa(void) { board_cache[BOARD_CACHE_2] = adc_result_average(ADCS_1, ADC_BP_CHANNEL); } /** * @brief 记录输出4mA时的PWM值 * @return {*} */ void set_output_4ma_pwm(uint16_t value) { board_cache[BOARD_CACHE_1] = value; } /** * @brief 记录输出20mA时的PWM值 * @return {*} */ void set_output_20ma_pwm(uint16_t value) { board_cache[BOARD_CACHE_2] = value; } /** * @brief 设置语言预加载标志 * @param {uint8_t} language * @return {*} * @note */ void set_app_preload_language_flag(uint8_t flag) { if (app_preload_language_flag != flag) { app_preload_language_flag = flag; } } /** * @brief 设置预加载BOOTLOAD标志位 * @param {uint8_t} flag * @return {*} * @note */ void set_app_preload_bootload_flag(uint8_t flag) { if (app_preload_bootload_flag != flag) { app_preload_bootload_flag = flag; } } /** * @brief Get the application preload bootload flag * @return The application preload bootload flag */ BOOL get_app_preload_bootload_flag(void) { return app_preload_bootload_flag; } /** * @brief 设置预加载BOOTLOAD标志位 * @param {app_preload_bootload_jump_e} flag * @return {*} * @note */ void set_app_preload_bootload_jump_flag(app_preload_bootload_jump_e flag) { if (app_preload_bootload_jump_flag != flag) { app_preload_bootload_jump_flag = flag; } } /** * @brief Get the application preload bootload jump flag * @return The application preload bootload jump flag */ app_preload_bootload_jump_e get_app_preload_bootload_jump_flag(void) { return (app_preload_bootload_jump_e)app_preload_bootload_jump_flag; }