532 lines
16 KiB
C
532 lines
16 KiB
C
/*
|
||
* @Author: shenghao.xu
|
||
* @Date: 2023-04-19 19:27:49
|
||
* @LastEditors: shenghao.xu
|
||
* @LastEditTime: 2023-07-04 13:20:46
|
||
* @Description: 提供给main.c调用的函数
|
||
* email:545403892@qq.com
|
||
* Copyright (c) 2023 by shenghao.xu, All Rights Reserved.
|
||
*/
|
||
#include "lib/inc/lib.h"
|
||
#include "sys.h"
|
||
#include "board.h"
|
||
#include "flow.h"
|
||
#include "app.h"
|
||
#include "main.h"
|
||
|
||
#define IP_PS_THRESHOLD 2755U
|
||
static struct flow fl_flowmeter_inspection; // 流量计
|
||
static struct flow fl_adc_inspection; // ADC
|
||
static struct flow fl_dac_inspection; // DAC
|
||
static struct flow fl_task_inspection; // 任务流程
|
||
static struct flow fl_systom_inspection; // 系统
|
||
static struct flow fl_master_inspection; // 主机活跃检测
|
||
static bool dac_init_flag = false;
|
||
static bool laser_zero_flag = true;
|
||
static bool step_motor_flag = false;
|
||
void dac_init_flag_reset(void)
|
||
{
|
||
dac_init_flag = false;
|
||
}
|
||
|
||
// 激光调零标记
|
||
void laser_zero_flag_reset(void)
|
||
{
|
||
laser_zero_flag = false;
|
||
}
|
||
|
||
// 继电器扫描
|
||
void relay_scan(void)
|
||
{
|
||
relay_t relay;
|
||
relay.data = app.relay.data;
|
||
// 继电器扫描
|
||
for (uint8_t i = 0; i < 16; i++)
|
||
{
|
||
uint8_t chan = i + 1;
|
||
if (relay.bits.r1 == 1)
|
||
{
|
||
// 如果为1,打开对应的继电器
|
||
if (!relay_isopen(chan))
|
||
{
|
||
relay_open(chan);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// 如果为0,关闭对应的继电器
|
||
if (relay_isopen(chan))
|
||
{
|
||
relay_close(chan);
|
||
}
|
||
}
|
||
relay.data >>= 1;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @description: 任务流程
|
||
* @param {*}
|
||
* @return {*}
|
||
*/
|
||
static uint8_t task_inspection(struct flow *fl)
|
||
{
|
||
process_t *process;
|
||
plan_t *plan;
|
||
action_t *action;
|
||
action_e tp;
|
||
uint16_t sleep;
|
||
uint8_t i, j;
|
||
FL_HEAD(fl);
|
||
for (;;)
|
||
{
|
||
if (app.task_run_state == RUN_STATE_READY_RUN)
|
||
{
|
||
app.process_state.process_index = 0;
|
||
app.process_state.plan_index = 0;
|
||
app.process_state.action_index = 0;
|
||
app.relay.data = 0;
|
||
app.task_run_state = RUN_STATE_EXECUTING;
|
||
relay_scan();
|
||
if (g_config == NULL)
|
||
{
|
||
app.task_run_state = RUN_STATE_FAILED;
|
||
continue;
|
||
}
|
||
if (g_config->process_count < g_execute_process.process_index)
|
||
{
|
||
app.task_run_state = RUN_STATE_FAILED;
|
||
continue;
|
||
}
|
||
process = &g_config->processes[g_execute_process.process_index];
|
||
if (process->plan_count < g_execute_process.plan_index)
|
||
{
|
||
app.task_run_state = RUN_STATE_FAILED;
|
||
continue;
|
||
}
|
||
|
||
plan = &process->plans[g_execute_process.plan_index];
|
||
|
||
app.process_state.process_index = g_execute_process.process_index;
|
||
app.process_state.plan_index = g_execute_process.plan_index;
|
||
app.process_state.action_index = 0;
|
||
for (i = 0; i < plan->action_count; i++)
|
||
{
|
||
action = &plan->actions[i];
|
||
tp = (action_e)action->type;
|
||
app.process_state.action_index = i;
|
||
if (tp == ACTION_WAIT)
|
||
{
|
||
sleep = B2S_UINT16(action->data.sleep); // 毫秒
|
||
for (j = 0; j < sleep / 100; j++)
|
||
{
|
||
HAL_Delay(100);
|
||
}
|
||
}
|
||
else if (tp == ACTION_VALVE)
|
||
{
|
||
if (action->data.valve.valve_type == UNIT_TWO_WAY_VALVE || action->data.valve.valve_type == UNIT_THREE_WAY_VALVE)
|
||
{
|
||
if (action->data.valve.valve_type == UNIT_TWO_WAY_VALVE)
|
||
{
|
||
set_valve_status((unit_e)action->data.valve.valve_type, action->data.valve.no, (uint8_t)action->data.valve.data.open);
|
||
relay_scan();
|
||
}
|
||
else
|
||
{
|
||
set_valve_status((unit_e)action->data.valve.valve_type, action->data.valve.no, action->data.valve.data.position);
|
||
relay_scan();
|
||
}
|
||
}
|
||
else if (action->data.valve.valve_type == UNIT_PROPORTIONAL_VALVE)
|
||
{
|
||
action->data.valve.data.value.c = B2S_UINT32(action->data.valve.data.value.c);
|
||
proportional_valve_dac_value = (uint16_t)action->data.valve.data.value.f;
|
||
// if (proportional_valve_dac_value == 0) // 自动校准
|
||
// {
|
||
// dac_init_flag_reset();
|
||
// app.adc.proportional_valve_in1.is_open = true;
|
||
// }
|
||
}
|
||
}
|
||
else if (tp == ACTION_IP_CONVERTER)
|
||
{
|
||
action->data.ip_converter.value.c = B2S_UINT32(action->data.ip_converter.value.c);
|
||
ip_dac_value = (uint16_t)action->data.ip_converter.value.f;
|
||
if (ip_dac_value == 0) // 自动校准
|
||
{
|
||
dac_init_flag_reset();
|
||
app.adc.ip_in6.is_open = true;
|
||
}
|
||
}
|
||
else if (tp == ACTION_WORK)
|
||
{
|
||
app.task_run_state = RUN_STATE_PREPARED;
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
app.task_run_state = RUN_STATE_FAILED;
|
||
break;
|
||
}
|
||
}
|
||
if (app.task_run_state != RUN_STATE_PREPARED)
|
||
{
|
||
app.task_run_state = RUN_STATE_FAILED;
|
||
}
|
||
}
|
||
FL_LOCK_DELAY(fl, FL_CLOCK_100MSEC); /* 延时100毫秒 */
|
||
}
|
||
FL_TAIL(fl);
|
||
}
|
||
/**
|
||
* @description: modbus通信,读取流量计数据
|
||
* @param {flow} *fl
|
||
* @return {*}
|
||
*/
|
||
#define FLOWMETER_READ_WAIT_TM FL_CLOCK_100MSEC * 2 // 等待数据接收完毕时间
|
||
static uint8_t flowmeter_inspection(struct flow *fl)
|
||
{
|
||
flowmeter_process_sleep_e tm = FLOWMETER_PROCESS_NO_SLEEP;
|
||
FL_HEAD(fl);
|
||
for (;;)
|
||
{
|
||
tm = flowmeter_process_need_sleep();
|
||
if (tm == FLOWMETER_PROCESS_SLEEP_RECVTM)
|
||
{
|
||
FL_LOCK_DELAY(fl, FLOWMETER_READ_WAIT_TM);
|
||
}
|
||
else if (tm == FLOWMETER_PROCESS_SLEEP_100ms)
|
||
{
|
||
FL_LOCK_DELAY(fl, FL_CLOCK_100MSEC); /* 延时100毫秒 */
|
||
}
|
||
else if (tm == FLOWMETER_PROCESS_SLEEP_1s)
|
||
{
|
||
FL_LOCK_DELAY(fl, FL_CLOCK_SEC); /* 延时1000毫秒 */
|
||
}
|
||
else if (tm == FLOWMETER_PROCESS_SLEEP_3s)
|
||
{
|
||
FL_LOCK_DELAY(fl, FL_CLOCK_SEC * 3); /* 延时1000毫秒 */
|
||
}
|
||
else
|
||
{
|
||
__NOP();
|
||
}
|
||
flowmeter_process();
|
||
}
|
||
FL_TAIL(fl);
|
||
}
|
||
|
||
static uint8_t adc_inspection(struct flow *fl)
|
||
{
|
||
uint8_t count = 0;
|
||
FL_HEAD(fl);
|
||
for (;;)
|
||
{
|
||
if (!dac_init_flag)
|
||
{
|
||
FL_LOCK_DELAY(fl, FL_CLOCK_100MSEC); /* 延时100毫秒 */
|
||
continue;
|
||
}
|
||
adc2dma_start();
|
||
while (!adc2dma_completed())
|
||
{
|
||
FL_LOCK_DELAY(fl, FL_CLOCK_100MSEC); /* 延时100毫秒 */
|
||
if (count++ > 10)
|
||
{
|
||
sys_soft_reset();
|
||
}
|
||
}
|
||
if (!app.adc.proportional_valve_in1.is_open)
|
||
{
|
||
app.adc.proportional_valve_in1.original_value = adc2dma_get_result_average(IN1);
|
||
}
|
||
|
||
if (!app.adc.ip_in6.is_open)
|
||
{
|
||
app.adc.ip_in6.original_value = adc2dma_get_result_average(IN6);
|
||
}
|
||
|
||
if (app.adc.ntc_in12.is_open)
|
||
{
|
||
app.adc.ntc_in12.calibration_value = adc2dma_get_result_average(IN12);
|
||
app.adc.ntc_in12.is_open = false;
|
||
}
|
||
else
|
||
{
|
||
app.adc.ntc_in12.original_value = adc2dma_get_result_average(IN12);
|
||
}
|
||
|
||
if (app.adc.presure_in7.is_open)
|
||
{
|
||
app.adc.presure_in7.calibration_value = adc2dma_get_result_average(IN7);
|
||
app.adc.presure_in7.is_open = false;
|
||
}
|
||
else
|
||
{
|
||
app.adc.presure_in7.original_value = adc2dma_get_result_average(IN7);
|
||
}
|
||
|
||
if (app.adc.presure_in8.is_open)
|
||
{
|
||
app.adc.presure_in8.calibration_value = adc2dma_get_result_average(IN8);
|
||
app.adc.presure_in8.is_open = false;
|
||
}
|
||
else
|
||
{
|
||
app.adc.presure_in8.original_value = adc2dma_get_result_average(IN8);
|
||
}
|
||
|
||
if (app.adc.presure_in9.is_open)
|
||
{
|
||
app.adc.presure_in9.calibration_value = adc2dma_get_result_average(IN9);
|
||
app.adc.presure_in9.is_open = false;
|
||
}
|
||
else
|
||
{
|
||
app.adc.presure_in9.original_value = adc2dma_get_result_average(IN9);
|
||
}
|
||
|
||
if (app.adc.presure_in10.is_open)
|
||
{
|
||
app.adc.presure_in10.calibration_value = adc2dma_get_result_average(IN10);
|
||
app.adc.presure_in10.is_open = false;
|
||
}
|
||
else
|
||
{
|
||
app.adc.presure_in10.original_value = adc2dma_get_result_average(IN10);
|
||
}
|
||
|
||
if (app.adc.presure_in11.is_open)
|
||
{
|
||
app.adc.presure_in11.calibration_value = adc2dma_get_result_average(IN11);
|
||
app.adc.presure_in11.is_open = false;
|
||
}
|
||
else
|
||
{
|
||
app.adc.presure_in11.original_value = adc2dma_get_result_average(IN11);
|
||
}
|
||
|
||
if (app.adc.presure_in12.is_open)
|
||
{
|
||
app.adc.presure_in12.calibration_value = adc2dma_get_result_average(IN12);
|
||
app.adc.presure_in12.is_open = false;
|
||
}
|
||
else
|
||
{
|
||
app.adc.presure_in12.original_value = adc2dma_get_result_average(IN12);
|
||
}
|
||
|
||
if (app.adc.minor_loop_in13.is_open)
|
||
{
|
||
app.adc.minor_loop_in13.calibration_value = adc2dma_get_result_average(IN13);
|
||
app.adc.minor_loop_in13.is_open = false;
|
||
}
|
||
else
|
||
{
|
||
app.adc.minor_loop_in13.original_value = adc2dma_get_result_average(IN13);
|
||
}
|
||
|
||
FL_LOCK_DELAY(fl, FL_CLOCK_100MSEC); /* 延时100毫秒 */
|
||
}
|
||
FL_TAIL(fl);
|
||
}
|
||
|
||
static uint8_t dac_inspection(struct flow *fl)
|
||
{
|
||
uint32_t dac_value = 0;
|
||
uint8_t count = 0;
|
||
FL_HEAD(fl);
|
||
pid_controller_init(XDAC_CHANNEL_1, 0.2, 0.4, 0.02);
|
||
pid_controller_init(XDAC_CHANNEL_2, 0.2, 0.4, 0.02);
|
||
for (;;)
|
||
{
|
||
if (app.ip_out_mode == IP_OUT_PWM)
|
||
{
|
||
ip_set_out(ip_pwm_duty_convert_ccr(ip_pwm_duty));
|
||
}
|
||
else
|
||
{
|
||
dac_value = get_ip_dac_out();
|
||
if (dac_value > IP_PS_THRESHOLD)
|
||
{
|
||
IP1_EN_6v();
|
||
}
|
||
else
|
||
{
|
||
IP1_EN_3v();
|
||
}
|
||
ip_set_out(dac_value);
|
||
}
|
||
|
||
dac_value = get_proportional_valve_dac_out();
|
||
dac_set_value(XDAC_CHANNEL_1, dac_value);
|
||
|
||
if (!dac_init_flag)
|
||
{
|
||
adc2dma_start();
|
||
while (!adc2dma_completed())
|
||
{
|
||
FL_LOCK_DELAY(fl, FL_CLOCK_100MSEC); /* 延时100毫秒 */
|
||
if (count++ > 10)
|
||
{
|
||
sys_soft_reset();
|
||
}
|
||
}
|
||
dac_init_flag = true;
|
||
|
||
if (app.adc.ip_in6.is_open)
|
||
{
|
||
app.adc.ip_in6.calibration_value = adc2dma_get_result_average(IN6);
|
||
app.adc.ip_in6.is_open = false;
|
||
}
|
||
|
||
if (app.adc.proportional_valve_in1.is_open)
|
||
{
|
||
app.adc.proportional_valve_in1.calibration_value = adc2dma_get_result_average(IN1);
|
||
app.adc.proportional_valve_in1.is_open = false;
|
||
}
|
||
}
|
||
|
||
FL_LOCK_DELAY(fl, FL_CLOCK_100MSEC * 2); /* 延时100毫秒 */
|
||
}
|
||
FL_TAIL(fl);
|
||
}
|
||
|
||
static uint8_t master_inspection(struct flow *fl)
|
||
{
|
||
FL_HEAD(fl);
|
||
for (;;)
|
||
{
|
||
if (app.master_active)
|
||
{
|
||
app.master_active = false;
|
||
}
|
||
else
|
||
{
|
||
if (proportional_valve_dac_value != 0)
|
||
{
|
||
// 主机不活跃,关闭所有阀门
|
||
// 关闭比例阀,设置比例阀值为0,IP电流设置0
|
||
proportional_valve_dac_value = 0;
|
||
ip_dac_value = 0;
|
||
FL_LOCK_DELAY(fl, FL_CLOCK_SEC * 2);
|
||
// 关闭所有阀门,
|
||
app.relay.data = 0;
|
||
FL_LOCK_DELAY(fl, FL_CLOCK_SEC);
|
||
// 激光初始化
|
||
dac_init_flag_reset();
|
||
app.adc.ip_in6.is_open = true;
|
||
app.task_run_state = RUN_STATE_UNEXECUTED;
|
||
}
|
||
}
|
||
|
||
FL_LOCK_DELAY(fl, FL_CLOCK_SEC * 10);
|
||
}
|
||
FL_TAIL(fl);
|
||
}
|
||
|
||
#define DEVICE_CONNECT_MAX_TIME 1000U
|
||
#define RESET_MAX_TIME 200U
|
||
static void step_motor_stop_cb(step_motor_number_e num)
|
||
{
|
||
step_motor_t *step_motor = get_step_motor(STEP_MOTOR_1);
|
||
step_motor->attribute.add_pulse_count = 0;
|
||
step_motor->interface.stop_cb = NULL;
|
||
}
|
||
static uint8_t systom_inspection(struct flow *fl)
|
||
{
|
||
int16_t dms = 100;
|
||
|
||
static int16_t reset_ms = RESET_MAX_TIME; // 复位时间
|
||
FL_HEAD(fl);
|
||
for (;;)
|
||
{
|
||
FL_LOCK_DELAY(fl, FL_CLOCK_100MSEC); /* 延时100毫秒 */
|
||
if (!step_motor_flag)
|
||
{
|
||
// 步进电机上电后正向转动,寻找限位器
|
||
if (GPIO_PIN_SET == HAL_GPIO_ReadPin(STOPPER_GPIO_Port, STOPPER_Pin))
|
||
{
|
||
step_motor_flag = true;
|
||
}
|
||
else
|
||
{
|
||
step_motor_flag = true;
|
||
step_motor_t *step_motor = get_step_motor(STEP_MOTOR_1);
|
||
step_motor->interface.stop_cb = step_motor_stop_cb;
|
||
step_motor->interface.set_angle(STEP_MOTOR_1, (540 * ANGLE), DIR_CW);
|
||
}
|
||
}
|
||
|
||
// 激光器状态机
|
||
if (dac_init_flag && !laser_zero_flag)
|
||
{
|
||
laser_handle.state = LASER_OPEN_STATUS;
|
||
laser_zero_flag = true;
|
||
}
|
||
|
||
if (laser_handle.state != LASER_READY)
|
||
{
|
||
for (uint8_t i = 0; i < LASER_READY; i++)
|
||
{
|
||
laser_event_t ev = laser_event[i];
|
||
if (ev.sig == laser_handle.state)
|
||
{
|
||
ev.event();
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
laser_handle.command_distance_read_req();
|
||
}
|
||
|
||
relay_scan();
|
||
|
||
if (need_reset())
|
||
{
|
||
reset_ms = reset_ms - dms;
|
||
if (reset_ms <= 0)
|
||
{
|
||
sys_soft_reset();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
reset_ms = 0;
|
||
}
|
||
}
|
||
FL_TAIL(fl);
|
||
}
|
||
|
||
/**
|
||
* @description: 流程启动
|
||
* @return {*}
|
||
*/
|
||
void flow_start(void)
|
||
{
|
||
|
||
adc_inspection(&fl_adc_inspection); // adc检测
|
||
dac_inspection(&fl_dac_inspection); // dac检测
|
||
flowmeter_inspection(&fl_flowmeter_inspection); // 流量计检测
|
||
task_inspection(&fl_task_inspection); // 任务检测
|
||
master_inspection(&fl_master_inspection); // 主机检测
|
||
systom_inspection(&fl_systom_inspection); // 系统检测
|
||
}
|
||
|
||
/**
|
||
* @description: 初始化流程
|
||
* @return {*}
|
||
*/
|
||
void flow_init(void)
|
||
{
|
||
FL_INIT(&fl_adc_inspection);
|
||
FL_INIT(&fl_dac_inspection);
|
||
FL_INIT(&fl_flowmeter_inspection);
|
||
FL_INIT(&fl_task_inspection);
|
||
FL_INIT(&fl_master_inspection);
|
||
FL_INIT(&fl_systom_inspection);
|
||
}
|