This repository has been archived on 2025-02-28. You can view files and clone it, but cannot push or open issues or pull requests.
controller-hd/User/board/src/board.c

1062 lines
25 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @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) <p>
* > Ov=[(Osh-Osl)*(Iv-Isl)/(Ish-Isl)]+Osl <p>
*/
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 <p>
*> 10% - 5.6mA <p>
*> 20% - 7.2mA <p>
*> 30% - 8.8mA <p>
*> 40% - 10.4mA <p>
*> 50% - 12.0mA <p>
*> 55% - 12.8mA <p>
*> 60% - 13.6mA <p>
*> 70% - 15.2mA <p>
*> 80% - 16.8mA <p>
*> 90% - 18.4mA <p>
*> 100% - 20.0mA <p>
*/
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) <p>
* > m = y2 - k * x2 <p>
*/
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 <p>
* > 简化后adc*VREF_VALUE/409600 = ma <p>
*/
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占空比 <p>
* > k = (TDuty20 - TDuty4) / (mA20 - mA4) <p>
* > m = TDuty20 - k * mA20 <p>
*/
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;
}