730 lines
25 KiB
C
730 lines
25 KiB
C
/**
|
||
* @file app_flow.c
|
||
* @author xxx
|
||
* @date 2023-08-30 08:58:43
|
||
* @brief 此文件用于管理各个任务流程
|
||
* @copyright Copyright (c) 2023 by xxx, All Rights Reserved.
|
||
*/
|
||
|
||
#include <math.h>
|
||
#include "flow.h"
|
||
#include "app.h"
|
||
#include "main.h"
|
||
#include "tim.h"
|
||
#include "filter.h"
|
||
#include "lcds.h"
|
||
#include "menus.h"
|
||
#include "mode.h"
|
||
#include "mode_diagnosis.h"
|
||
#include "at_bluetooth.h"
|
||
#include "bootload.h"
|
||
#include "app_hart.h"
|
||
#include "file_storage.h"
|
||
uint16_t scheduler_use_time = 0;
|
||
|
||
/**
|
||
* @brief 100毫秒定时中断处理函数
|
||
*
|
||
* 当定时器到达100毫秒时,会触发此中断处理函数。
|
||
* 在该函数中,启动或重置定时器计数。
|
||
* @param cycle 定时器周期 毫秒
|
||
*/
|
||
void scheduler_time_irqhandler(uint8_t cycle)
|
||
{
|
||
DBG_ASSERT(cycle > 0 __DBG_LINE);
|
||
static uint32_t cnt = 0;
|
||
uint32_t time_ms = ++cnt * cycle;
|
||
|
||
BOOL flag_1s = (time_ms % 1000 == 0) ? TRUE : FALSE;
|
||
BOOL flag_200ms = (time_ms % 200 == 0) ? TRUE : FALSE;
|
||
|
||
// 考虑是否要控制器工作的时候才计时
|
||
if (rt_save.dev_run_time_h < WORK_HOURS_MAX)
|
||
{
|
||
if (flag_1s)
|
||
{
|
||
rt_save.dev_run_time_s++; // 工作时长
|
||
}
|
||
if (rt_save.dev_run_time_s >= 3600)
|
||
{
|
||
rt_save.dev_run_time_h++;
|
||
rt_save.dev_run_time_s = 0;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
rt_save.dev_run_time_h = WORK_HOURS_MAX;
|
||
rt_save.dev_run_time_s = 0;
|
||
}
|
||
|
||
// 控制过程中快速闪灯
|
||
if (mode_get()->interface_req.mode_control_idle() == FALSE)
|
||
{
|
||
if (flag_200ms)
|
||
{
|
||
diagnosis_fault_indicate((diag_class_e)get_diagnosis_result()->priority);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (flag_1s)
|
||
{
|
||
diagnosis_fault_indicate((diag_class_e)get_diagnosis_result()->priority);
|
||
}
|
||
}
|
||
|
||
if (flag_1s)
|
||
{
|
||
hart_timer_1s();
|
||
}
|
||
|
||
if (cnt >= 10000)
|
||
{
|
||
cnt -= 10000;
|
||
}
|
||
}
|
||
|
||
#if HART_HARDWARE_TEST_ENABLE == TRUE
|
||
static struct flow hart_hardware_test_handle; // HART硬件测试任务句柄
|
||
|
||
static uint8_t hart_hardware_test_task(struct flow *fl)
|
||
{
|
||
FL_HEAD(fl);
|
||
static uint8_t data[64];
|
||
for (;;)
|
||
{
|
||
if (rt_data.flag.bits.hart_rts_on == TRUE)
|
||
{
|
||
if (rt_data.flag.bits.hart_send_test != 0)
|
||
{
|
||
if (rt_data.flag.bits.hart_send_test == 1)
|
||
{
|
||
osel_memset(data, 0x00, ARRAY_LEN(data));
|
||
}
|
||
else
|
||
{
|
||
osel_memset(data, 0xff, ARRAY_LEN(data));
|
||
}
|
||
HART_RTS_OFF();
|
||
hart_get_handle()->interface.response(APP_UART_1, data, ARRAY_LEN(data));
|
||
}
|
||
}
|
||
}
|
||
FL_TAIL(fl);
|
||
}
|
||
|
||
#elif HART_SOFTWARE_TEST_ENABLE == TRUE
|
||
static struct flow hart_soft_test_handle; // HART软件测试任务句柄
|
||
|
||
static uint8_t hart_soft_test_task(struct flow *fl)
|
||
{
|
||
float32 limit = 0.0f;
|
||
float32 coefficient = 0.0f;
|
||
hart_device_variable_t* pv = NULL;
|
||
FL_HEAD(fl);
|
||
for (;;)
|
||
{
|
||
if (hart_device_attribute.simulation_command52 == COMMAND_187_SET_VARIABLE_CLOSE_TO_LOWER_RANGE_VALUE)
|
||
{
|
||
coefficient = 0.02f;
|
||
// 设置传感器输入接近零测量值。该值必须足够接近零测量值,以便设备能够重新归零其校准,但必须大于其当前校准的正常测量范围1%
|
||
pv = get_device_variable(DIN_ANALOG_INPUT); // 输入电流
|
||
limit = (pv->attribute.upper_range_value - pv->attribute.lower_range_value) * coefficient;
|
||
rt_data.loop_current = pv->attribute.lower_range_value + limit;
|
||
|
||
pv = get_device_variable(DIN_INTERNAL_TEMPERATURE); // 温度
|
||
limit = (pv->attribute.upper_range_value - pv->attribute.lower_range_value) * coefficient;
|
||
rt_data.temperature = pv->attribute.lower_range_value + limit;
|
||
|
||
rt_data.actual_travel = i2psb(rt_data.loop_current);
|
||
rt_save.travel_set_pt = i2psb(rt_data.loop_current);
|
||
rt_data.target_travel = i2psb(rt_data.loop_current);
|
||
|
||
pv = get_device_variable(DIN_SUPPLY_PRESSURE); // 供气压力
|
||
limit = (pv->attribute.upper_range_value - pv->attribute.lower_range_value) * coefficient;
|
||
rt_data.pressure_s = pv->attribute.lower_range_value + limit;
|
||
|
||
pv = get_device_variable(DIN_PRESSURE_PORT_A); // A路压力
|
||
limit = (pv->attribute.upper_range_value - pv->attribute.lower_range_value) * coefficient;
|
||
rt_data.pressure_a = pv->attribute.lower_range_value + limit;
|
||
|
||
pv = get_device_variable(DIN_PRESSURE_PORT_B); // B路压力
|
||
limit = (pv->attribute.upper_range_value - pv->attribute.lower_range_value) * coefficient;
|
||
rt_data.pressure_b = pv->attribute.lower_range_value + limit;
|
||
|
||
pv = get_device_variable(DIN_DRIVE_SIGNAL); // 驱动信号(百分比)
|
||
limit = (pv->attribute.upper_range_value - pv->attribute.lower_range_value) * coefficient;
|
||
rt_data.driver_signal = pv->attribute.lower_range_value + limit;
|
||
|
||
pv = get_device_variable(DIN_DIFFERENTIAL_PRESSURE); // 压力A减压力B
|
||
limit = (pv->attribute.upper_range_value - pv->attribute.lower_range_value) * coefficient;
|
||
rt_data.pressure_cross_point = pv->attribute.lower_range_value + limit;
|
||
|
||
pv = get_device_variable(DIN_PRIMARY_FEEDBACK); // 伺服反馈(和实际行程的值一样)
|
||
limit = (pv->attribute.upper_range_value - pv->attribute.lower_range_value) * coefficient;
|
||
rt_data.servo_feedback = pv->attribute.lower_range_value + limit;
|
||
}
|
||
else if (hart_device_attribute.simulation_command52 == COMMAND_187_SET_VARIABLE_BELOW_LOWER_TRANSDUCER_LIMIT)
|
||
{
|
||
coefficient = 0.1f;
|
||
// 设置传感器输入值远低于下限,设备无法将其校准重新定为零
|
||
pv = get_device_variable(DIN_ANALOG_INPUT); // 输入电流
|
||
limit = (pv->transducer.upper_limit.f - pv->transducer.lower_limit.f) * coefficient;
|
||
rt_data.loop_current = pv->transducer.lower_limit.f - limit;
|
||
|
||
pv = get_device_variable(DIN_INTERNAL_TEMPERATURE); // 温度
|
||
limit = (pv->transducer.upper_limit.f - pv->transducer.lower_limit.f) * coefficient;
|
||
rt_data.temperature = pv->transducer.lower_limit.f - limit;
|
||
|
||
rt_data.actual_travel = i2psb(rt_data.loop_current);
|
||
rt_save.travel_set_pt = i2psb(rt_data.loop_current);
|
||
rt_data.target_travel = i2psb(rt_data.loop_current);
|
||
|
||
pv = get_device_variable(DIN_SUPPLY_PRESSURE); // 供气压力
|
||
limit = (pv->transducer.upper_limit.f - pv->transducer.lower_limit.f) * coefficient;
|
||
rt_data.pressure_s = pv->transducer.lower_limit.f - limit;
|
||
|
||
pv = get_device_variable(DIN_PRESSURE_PORT_A); // A路压力
|
||
limit = (pv->transducer.upper_limit.f - pv->transducer.lower_limit.f) * coefficient;
|
||
rt_data.pressure_a = pv->transducer.lower_limit.f - limit;
|
||
|
||
pv = get_device_variable(DIN_PRESSURE_PORT_B); // B路压力
|
||
limit = (pv->transducer.upper_limit.f - pv->transducer.lower_limit.f) * coefficient;
|
||
rt_data.pressure_b = pv->transducer.lower_limit.f - limit;
|
||
|
||
pv = get_device_variable(DIN_DRIVE_SIGNAL); // 驱动信号(百分比)
|
||
limit = (pv->transducer.upper_limit.f - pv->transducer.lower_limit.f) * coefficient;
|
||
rt_data.driver_signal = pv->transducer.lower_limit.f - limit;
|
||
|
||
pv = get_device_variable(DIN_DIFFERENTIAL_PRESSURE); // 压力A减压力B
|
||
limit = (pv->transducer.upper_limit.f - pv->transducer.lower_limit.f) * coefficient;
|
||
rt_data.pressure_cross_point = pv->transducer.lower_limit.f - limit;
|
||
|
||
pv = get_device_variable(DIN_PRIMARY_FEEDBACK); // 伺服反馈(和实际行程的值一样)
|
||
limit = (pv->transducer.upper_limit.f - pv->transducer.lower_limit.f) * coefficient;
|
||
rt_data.servo_feedback = pv->transducer.lower_limit.f - limit;
|
||
}
|
||
else if (hart_device_attribute.simulation_command52 == COMMAND_187_SET_VARIABLE_ABOVE_UPPER_TRANSDUCER_LIMIT)
|
||
{
|
||
coefficient = 0.1f;
|
||
// 设置传感器输入值远高于下限,设备无法将其校准重新定为零
|
||
pv = get_device_variable(DIN_ANALOG_INPUT); // 输入电流
|
||
limit = (pv->transducer.upper_limit.f - pv->transducer.lower_limit.f) * coefficient;
|
||
rt_data.loop_current = pv->transducer.upper_limit.f + limit;
|
||
|
||
pv = get_device_variable(DIN_INTERNAL_TEMPERATURE); // 温度
|
||
limit = (pv->transducer.upper_limit.f - pv->transducer.lower_limit.f) * coefficient;
|
||
rt_data.temperature = pv->transducer.upper_limit.f + limit;
|
||
|
||
rt_data.actual_travel = i2psb(rt_data.loop_current);
|
||
rt_save.travel_set_pt = i2psb(rt_data.loop_current);
|
||
rt_data.target_travel = i2psb(rt_data.loop_current);
|
||
|
||
pv = get_device_variable(DIN_SUPPLY_PRESSURE); // 供气压力
|
||
limit = (pv->transducer.upper_limit.f - pv->transducer.lower_limit.f) * coefficient;
|
||
rt_data.pressure_s = pv->transducer.upper_limit.f + limit;
|
||
|
||
pv = get_device_variable(DIN_PRESSURE_PORT_A); // A路压力
|
||
limit = (pv->transducer.upper_limit.f - pv->transducer.lower_limit.f) * coefficient;
|
||
rt_data.pressure_a = pv->transducer.upper_limit.f + limit;
|
||
|
||
pv = get_device_variable(DIN_PRESSURE_PORT_B); // B路压力
|
||
limit = (pv->transducer.upper_limit.f - pv->transducer.lower_limit.f) * coefficient;
|
||
rt_data.pressure_b = pv->transducer.upper_limit.f + limit;
|
||
|
||
pv = get_device_variable(DIN_DRIVE_SIGNAL); // 驱动信号(百分比)
|
||
limit = (pv->transducer.upper_limit.f - pv->transducer.lower_limit.f) * coefficient;
|
||
rt_data.driver_signal = pv->transducer.upper_limit.f + limit;
|
||
|
||
pv = get_device_variable(DIN_DIFFERENTIAL_PRESSURE); // 压力A减压力B
|
||
limit = (pv->transducer.upper_limit.f - pv->transducer.lower_limit.f) * coefficient;
|
||
rt_data.pressure_cross_point = pv->transducer.upper_limit.f + limit;
|
||
|
||
pv = get_device_variable(DIN_PRIMARY_FEEDBACK); // 伺服反馈(和实际行程的值一样)
|
||
limit = (pv->transducer.upper_limit.f - pv->transducer.lower_limit.f) * coefficient;
|
||
rt_data.servo_feedback = pv->transducer.upper_limit.f + limit;
|
||
}
|
||
else
|
||
{
|
||
// 真实的值
|
||
rt_data.loop_current = get_current(FILTER_AVERAGE);
|
||
rt_data.temperature = get_temperature();
|
||
rt_data.actual_travel = i2psb(rt_data.loop_current);
|
||
rt_save.travel_set_pt = i2psb(rt_data.loop_current);
|
||
rt_data.target_travel = i2psb(rt_data.loop_current);
|
||
rt_data.pressure_s = trim_pressure_point(DIN_SUPPLY_PRESSURE, pressure_kpa2unit(get_pressure(PRESSURE_PARAM_S), udevice.press_unit), udevice.press_unit);
|
||
rt_data.pressure_a = trim_pressure_point(DIN_PRESSURE_PORT_A, pressure_kpa2unit(get_pressure(PRESSURE_PARAM_A), udevice.press_unit), udevice.press_unit);
|
||
rt_data.pressure_b = trim_pressure_point(DIN_PRESSURE_PORT_B, pressure_kpa2unit(get_pressure(PRESSURE_PARAM_B), udevice.press_unit), udevice.press_unit);
|
||
rt_data.driver_signal = 0;
|
||
rt_data.pressure_cross_point = 0;
|
||
rt_data.servo_feedback = 0;
|
||
}
|
||
|
||
leds_toggle(LEDS_GREEN);
|
||
FL_LOCK_DELAY(fl, FL_CLOCK_SEC);
|
||
}
|
||
FL_TAIL(fl);
|
||
}
|
||
#else
|
||
static struct flow sensor_task_handle; // 传感器任务句柄
|
||
static struct flow business_task_handle; // 业务任务句柄
|
||
static struct flow system_task_handle; // 系统任务句柄
|
||
static struct flow menu_task_handle; // 菜单任务句柄
|
||
|
||
// 时间戳更新
|
||
static void timestamp_update(uint8_t cycle)
|
||
{
|
||
BOOL ret = FALSE;
|
||
rtc_date_t date;
|
||
rtc_time_t time;
|
||
uint32_t timestamp = 0;
|
||
static uint8_t count = 0x64;
|
||
if (count++ >= cycle)
|
||
{
|
||
count = 0;
|
||
ret = rtc_get_datetime(&date, &time);
|
||
if (ret == TRUE)
|
||
{
|
||
timestamp = time2stamp(&date, &time);
|
||
if (timestamp > rt_data.timestamp)
|
||
{
|
||
rt_save.real_time.date.year = date.year;
|
||
rt_save.real_time.date.month = date.month;
|
||
rt_save.real_time.date.day = date.day;
|
||
rt_save.real_time.date.hour = time.hour;
|
||
rt_save.real_time.date.minute = time.minute;
|
||
rt_save.real_time.date.second = time.second;
|
||
rt_data.timestamp = timestamp;
|
||
}
|
||
// 如果rtc_get_datetime失败,则不需要额外操作,但可以在调试时记录
|
||
// else
|
||
// {
|
||
// // 记录错误或进行其他处理
|
||
// }
|
||
|
||
rt_data.flag.bits.real_time_idel = TRUE;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 实时数据部分更新
|
||
static void rt_data_update(void)
|
||
{
|
||
rt_data.board_current = get_board_current();
|
||
rt_data.cpu_percent = scheduler_time_occupancy_get(1000);
|
||
rt_data.cpu_temperature = get_cpu_temperature();
|
||
rt_data.cpu_volt = get_cpu_volt();
|
||
rt_data.mem_percent = my_mem_perused(SRAMIN);
|
||
rt_data.dc = CPU_VREF * adc_raw[ADC_DCDC_CHANNEL] * 4 / ADC_MAX;
|
||
rt_data.vdd = CPU_VREF * adc_raw[ADC_VDD_CHANNEL] * 4 / ADC_MAX;
|
||
timestamp_update(3); // 这个周期数量根据外面的任务时间来定
|
||
}
|
||
|
||
static void rt_save_update(void)
|
||
{
|
||
if (is_run_max_time() == TRUE)
|
||
{
|
||
udevice.control_mode = WAIT_MODE; // 设备已经达到通电时间的上限,自动切换到待机模式
|
||
}
|
||
rt_save.diagnosis_log_node_write_count = file_storage_block_get(&nvm1_file_storage, FILE_BLOCK_DIAGNOSIS_LOG)->params.used_node;
|
||
rt_save.diagnosis_log_node_start_offset_index = file_storage_block_get(&nvm1_file_storage, FILE_BLOCK_DIAGNOSIS_LOG)->params.start_node;
|
||
}
|
||
|
||
static void ble_detection(float32 loop_current, float32 temperature)
|
||
{
|
||
float32 ble_close = FALSE;
|
||
uint8_t wireless_id[WIRELESS_ID_LEN];
|
||
// 判断当前电流是否大于等于3.8mA,如果是,则启动UART
|
||
if (loop_current >= INPUT_CURRENT_MIN_UART)
|
||
{
|
||
driver_init(); // 初始化驱动
|
||
if (FALSE == HART_IS_ENABLE()) // 检查HART是否已启用,如果否,则初始化HART UART
|
||
{
|
||
hart_uart_init();
|
||
}
|
||
}
|
||
// 否则,关闭UART
|
||
else
|
||
{
|
||
driver_dinit(); // 关闭驱动
|
||
hart_uart_dinit(); // 关闭HART UART
|
||
}
|
||
|
||
if (temperature < BLE_WORK_TEMP_MIN || temperature > BLE_WORK_TEMP_MAX)
|
||
{
|
||
ble_close = TRUE;
|
||
}
|
||
|
||
// 蓝牙
|
||
// 判断当前电流是否大于等于xx mA且工作模式在离线模式下,如果是,则启动蓝牙
|
||
if (wireless_can_work(loop_current) == TRUE)
|
||
{
|
||
if (FALSE == BLE_IS_ENABLE()) // 检查蓝牙是否已启用,如果否,则初始化蓝牙
|
||
{
|
||
hart_ble_init();
|
||
}
|
||
else
|
||
{
|
||
// 检查蓝牙是否正常工作
|
||
if (BIT_IS_CLR(bluetooth_state, BIT7))
|
||
{
|
||
delay_ms(500);
|
||
if (BIT_IS_CLR(bluetooth_state, BIT0))
|
||
{
|
||
// 读取蓝牙MAC地址
|
||
bluetooth_work(AT_GET_MAC);
|
||
delay_ms(500);
|
||
}
|
||
|
||
if (BIT_IS_SET(bluetooth_state, BIT0))
|
||
{
|
||
osel_memset(wireless_id, 0, WIRELESS_ID_LEN);
|
||
// 设置MAC地址
|
||
at_get_memcmp_cache(wireless_id, WIRELESS_ID_LEN);
|
||
if (wireless_id[0] != 0 && wireless_id[1] != 0)
|
||
{
|
||
if (osel_memcmp(wireless_id, (uint8_t*)&udevice.wireless_id, WIRELESS_ID_LEN) != 0)
|
||
{
|
||
osel_memcpy((uint8_t*)&udevice.wireless_id, wireless_id, WIRELESS_ID_LEN);
|
||
}
|
||
}
|
||
|
||
// 检查蓝牙名称
|
||
bluetooth_work(AT_CMD_NAME_REQ);
|
||
delay_ms(500);
|
||
if (BIT_IS_CLR(bluetooth_state, BIT1))
|
||
{
|
||
// 设置蓝牙名称
|
||
bluetooth_work(AT_CMD_NAME);
|
||
}
|
||
#if BLE_TYPE == BLE_TYPE_MX02
|
||
delay_ms(500);
|
||
bluetooth_work(AT_CMD_TX_POWER);
|
||
#endif
|
||
|
||
BIT_SET(bluetooth_state, BIT7);
|
||
}
|
||
else
|
||
{
|
||
BIT_SET(bluetooth_state, BIT7); // 如果蓝牙被主动连接的话,上面的AT指令不会有响应
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// bluetooth_work(100);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
ble_close = TRUE;
|
||
}
|
||
|
||
if (ble_close == TRUE)
|
||
{
|
||
if (TRUE == BLE_IS_ENABLE())
|
||
{
|
||
hart_ble_dinit(); // 关闭蓝牙
|
||
}
|
||
bluetooth_state = 0;
|
||
rt_data.flag.bits.ble_on = FALSE;
|
||
}
|
||
else
|
||
{
|
||
rt_data.flag.bits.ble_on = TRUE;
|
||
}
|
||
}
|
||
|
||
// LCD 、LED检测
|
||
static void lcd_detection(float32 loop_current, float32 temperature)
|
||
{
|
||
BOOL lcd_close = FALSE, led_close = FALSE;
|
||
// LCD扩展板必须接入
|
||
if (is_lcd_ext_board() == FALSE)
|
||
{
|
||
lcd_close = TRUE;
|
||
rt_data.flag.bits.lcd_detect = FALSE;
|
||
}
|
||
else
|
||
{
|
||
rt_data.flag.bits.lcd_detect = TRUE;
|
||
}
|
||
|
||
if (gui_can_work() == FALSE)
|
||
{
|
||
lcd_close = TRUE;
|
||
}
|
||
|
||
if (*mode_get()->ctrl.mode == STOP_MODE)
|
||
{
|
||
lcd_close = TRUE;
|
||
}
|
||
|
||
/**
|
||
* 检查温度是否在LCD的有效工作范围内。
|
||
* 如果温度低于最小值或高于最大值,则关闭LCD。
|
||
*
|
||
* @param rt_data 包含温度值的实时数据结构。
|
||
*/
|
||
if (temperature < temperature_c2unit(LCD_WORK_TEMP_MIN, udevice.temp_unit) || temperature > temperature_c2unit(LCD_WORK_TEMP_MAX, udevice.temp_unit))
|
||
{
|
||
lcd_close = TRUE;
|
||
}
|
||
|
||
// 如果工作模式为停止模式,则关闭LCD
|
||
if (*mode_get()->ctrl.mode == STOP_MODE)
|
||
{
|
||
lcd_close = TRUE;
|
||
}
|
||
|
||
if (lcd_close == TRUE)
|
||
{
|
||
gui_clr(); // 清除LCD
|
||
lcd_dinit();
|
||
get_menus()->run_enable = FALSE;
|
||
}
|
||
else
|
||
{
|
||
lcd_init(); // 初始化LCD
|
||
if (rt_data.flag.bits.lcd_detect == TRUE) // 检查LCD是否已关闭,如果是,则打开LCD
|
||
{
|
||
if (get_menus()->run_enable == FALSE)
|
||
{
|
||
#if LCD_DESIGN == FALSE
|
||
menus_jump(MENUS_WORK, FALSE); // 跳转到工作界面
|
||
#endif
|
||
}
|
||
get_menus()->run_enable = TRUE;
|
||
}
|
||
else
|
||
{
|
||
get_menus()->run_enable = FALSE;
|
||
}
|
||
|
||
gui_set_scandir(udevice.display_direction); // 更新扫描方向
|
||
menus_set_scandir(udevice.display_direction); // 设置菜单显示方向
|
||
gui_open(); // 打开LCD
|
||
}
|
||
|
||
if (led_close == TRUE)
|
||
{
|
||
leds_dinit();
|
||
}
|
||
else
|
||
{
|
||
leds_init(); // 初始化LED
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @brief 图标检测
|
||
* @return {*}
|
||
* @note
|
||
*/
|
||
static void icon_inspection(void)
|
||
{
|
||
if (rt_data.flag.bits.hart_on == FALSE)
|
||
{
|
||
driver_icon_enable.bits.hart = 0; // 禁用HART
|
||
}
|
||
else
|
||
{
|
||
driver_icon_enable.bits.hart = 1; // 使能HART
|
||
}
|
||
|
||
if (rt_data.flag.bits.ble_on == FALSE) // 检查蓝牙是否已启用
|
||
{
|
||
driver_icon_enable.bits.bluetooth = 0; // 禁用蓝牙
|
||
}
|
||
else
|
||
{
|
||
driver_icon_enable.bits.bluetooth = 1; // 使能蓝牙
|
||
}
|
||
|
||
driver_icon_enable.bits.work_mode = (uint8_t)udevice.control_mode; // 工作模式
|
||
driver_icon_enable.bits.write_protect = get_device_write_protect(); // 是否写保护
|
||
driver_icon_enable.bits.lock = get_device_lock(); // 是否锁定
|
||
}
|
||
|
||
/*********************************************************************************************** */
|
||
|
||
static uint8_t sensor_task(struct flow *fl)
|
||
{
|
||
FL_HEAD(fl);
|
||
static float32 current = 0.0f;
|
||
static float32 temperature = 0.0f, humidity = 0.0f;
|
||
for (;;)
|
||
{
|
||
scheduler_time_start();
|
||
// 计算当前电流,方法为读取ADC通道ADC_LOOP_CHANNEL的平均值并转换为浮点数
|
||
current = get_current_by_resistance();
|
||
rt_data.loop_current = current;
|
||
rt_data.show_loop = current;
|
||
// 获取当前温度
|
||
rt_data.temperature = get_temperature();
|
||
// 更新设备最小、最大温度
|
||
update_device_temp_min_max(rt_data.temperature);
|
||
// 获取当前湿度
|
||
if (sht40_read(&temperature, &humidity) == TRUE)
|
||
{
|
||
rt_data.humidity = (uint16_t)humidity;
|
||
rt_data.temperature2 = temperature;
|
||
}
|
||
if (current < INPUT_CURRENT_RUN) // 待机状态是如果电流小于INPUT_CURRENT_MIN_MCU,则进行系统复位
|
||
{
|
||
sys_soft_reset();
|
||
}
|
||
else
|
||
{
|
||
if (current < SYSTEM_CLOCK_HIGHT_CURRENT_MIN)
|
||
{
|
||
rt_data.flag.bits.current_low = TRUE;
|
||
}
|
||
else
|
||
{
|
||
if (rt_data.flag.bits.current_low == TRUE)
|
||
{
|
||
#if LCD_DESIGN == FALSE
|
||
menus_jump(MENUS_WORK, FALSE); // 跳转到工作界面
|
||
#endif
|
||
}
|
||
rt_data.flag.bits.current_low = FALSE;
|
||
}
|
||
|
||
// 蓝牙
|
||
ble_detection(current, rt_data.temperature);
|
||
|
||
// LCD 、LED
|
||
lcd_detection(current, rt_data.temperature);
|
||
}
|
||
scheduler_use_time = scheduler_time_stop();
|
||
FL_LOCK_DELAY(fl, FL_CLOCK_SEC);
|
||
}
|
||
FL_TAIL(fl);
|
||
}
|
||
|
||
static uint8_t business_task(struct flow *fl)
|
||
{
|
||
FL_HEAD(fl);
|
||
for (;;)
|
||
{
|
||
scheduler_time_start();
|
||
if (in_correct_model())
|
||
{
|
||
rt_data_update(); // 实时数据更新
|
||
rt_save_update(); // 实时数据存储更新
|
||
mode_master_detection(); // 工作模式检测
|
||
app_hart_inspection(); // HART检测
|
||
uart1_set_idel_handle_1_sec(); // 设置UART1空闲处理函数
|
||
params_storage_update(); // 存储数据更新
|
||
|
||
if (mode_get()->interface_req.mode_is_adjusting() == TRUE && is_selftune_menu() == FALSE) // KEIL窗口强制跳转到自整定流程,需要在这里做判断
|
||
{
|
||
menus_jump(MENUS_SELFTUNE, TRUE); // 跳转到自动整定界面
|
||
}
|
||
}
|
||
|
||
scheduler_use_time = scheduler_time_stop();
|
||
FL_LOCK_DELAY(fl, FL_CLOCK_SEC);
|
||
}
|
||
FL_TAIL(fl);
|
||
}
|
||
|
||
static uint8_t system_task(struct flow *fl)
|
||
{
|
||
FL_HEAD(fl);
|
||
static BOOL run_first = TRUE;
|
||
for (;;)
|
||
{
|
||
scheduler_time_start();
|
||
|
||
if (rt_data.flag.bits.dbg_assert_reset == TRUE)
|
||
{
|
||
DBG_ASSERT(FALSE __DBG_LINE);
|
||
}
|
||
|
||
// 图标检测
|
||
icon_inspection();
|
||
|
||
if (run_first == FALSE)
|
||
{
|
||
menus_set_language(udevice.display_language);
|
||
|
||
// 参数复位检测
|
||
params_restart_inspection();
|
||
|
||
set_app_preload_language_flag(udevice.display_language); // 缓存语言实时更新,用于重启是第一时间判断语言
|
||
// 诊断同步
|
||
diagnosis_synchronous();
|
||
|
||
// 在停机模式下,不进行诊断
|
||
if (*mode_get()->ctrl.mode != STOP_MODE)
|
||
{
|
||
// 过程报警 1s一次(时间可以改)
|
||
diagnosis_inspection(); // 第一次不做诊断,防止报错
|
||
// 故障处理
|
||
diagnosis_fault_deal();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
run_first = FALSE;
|
||
}
|
||
current_limit_to_travel(); // 电流限制到行程
|
||
|
||
scheduler_use_time = scheduler_time_stop();
|
||
FL_LOCK_DELAY(fl, FL_CLOCK_SEC);
|
||
}
|
||
FL_TAIL(fl);
|
||
}
|
||
|
||
static uint8_t menu_process_task(struct flow *fl)
|
||
{
|
||
FL_HEAD(fl);
|
||
for (;;)
|
||
{
|
||
scheduler_time_start();
|
||
// 菜单处理
|
||
menus_process();
|
||
scheduler_use_time = scheduler_time_stop();
|
||
FL_LOCK_DELAY(fl, MENU_TICKS / FL_HARD_TICK);
|
||
}
|
||
FL_TAIL(fl);
|
||
}
|
||
#endif
|
||
/**
|
||
* @brief 初始化流程
|
||
* @return {*}
|
||
*/
|
||
void flow_init(void)
|
||
{
|
||
#if HART_HARDWARE_TEST_ENABLE == TRUE
|
||
hart_uart_init();
|
||
udevice.wireless_enable = TRUE;
|
||
FL_INIT(&hart_hardware_test_handle);
|
||
#elif HART_SOFTWARE_TEST_ENABLE == TRUE
|
||
hart_uart_init();
|
||
FL_INIT(&hart_soft_test_handle);
|
||
#else
|
||
rt_data.flag.bits.current_low = TRUE;
|
||
FL_INIT(&system_task_handle);
|
||
FL_INIT(&business_task_handle);
|
||
FL_INIT(&business_task_handle);
|
||
FL_INIT(&menu_task_handle);
|
||
#endif
|
||
}
|
||
|
||
void flow_start(void)
|
||
{
|
||
#if HART_HARDWARE_TEST_ENABLE == TRUE
|
||
hart_hardware_test_task(&hart_hardware_test_handle);
|
||
#elif HART_SOFTWARE_TEST_ENABLE == TRUE
|
||
hart_soft_test_task(&hart_soft_test_handle);
|
||
#else
|
||
sensor_task(&sensor_task_handle);
|
||
business_task(&business_task_handle);
|
||
system_task(&system_task_handle);
|
||
menu_process_task(&menu_task_handle);
|
||
#endif
|
||
}
|