epm/User/app.c

919 lines
28 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.

/*
* @Author: shenghao.xu
* @Date: 2023-04-04 08:17:16
* @LastEditors: shenghao.xu
* @LastEditTime: 2023-07-04 13:15:43
* @Description:
* email:545403892@qq.com
* Copyright (c) 2023 by shenghao.xu, All Rights Reserved.
*/
#include "app.h"
#ifdef STM32
#include "sys.h"
#include "uart.h"
#include "flash.h"
#include "board.h"
#include "easyflash.h"
#include <stdio.h>
#include <stdlib.h>
#endif
static bool reset_flag = false; // 设备复位软标记
uint16_t ip_dac_value = 0; // IP转换器电流值uA
float32 ip_pwm_duty = 0; // IP转换器PWM值
uint16_t proportional_valve_dac_value = 0; // 比例阀压力值
bool pid_pressure_flag = false; // 压力传感器PID标记,当该标志位true时需要根据压力传感器的值进行PID控制
sensor_bits_e pid_pressure_no; // PID压力传感器设备编号
static data_interupt_cb_t uart_data_analysis_cb = NULL; // 数据解析回调
volatile app_t app; // APP全局变量
agreement_req_cb_t agreement_req_cb;
static void get_sensor_pressure_data(const sensor_bits_e sensor_bits, float32_t *ptr);
// 初始化传感器
static void sensor_init(void)
{
ip_dac_value = 0;
proportional_valve_dac_value = 0;
app.adc.ip_in6.is_open = true;
app.adc.proportional_valve_in1.is_open = true;
app.relay.data = 0;
app.process_state.process_index = 0;
app.process_state.plan_index = 0;
app.process_state.action_index = 0;
pid_pressure_no.data = 0;
}
static void flash_write_address(void)
{
#ifdef STM32
hal_int_state_t s;
HAL_ENTER_CRITICAL(s);
flash_write_no_buffer(FLASH_DEVICE_ADDRESS, (uint32_t *)&app.device_address, sizeof(app.device_address));
HAL_EXIT_CRITICAL(s);
#endif
}
static void flash_write_ip_mode(void)
{
#ifdef STM32
hal_int_state_t s;
HAL_ENTER_CRITICAL(s);
flash_write_no_buffer(FLASH_IP_OUT_MODE_ADDRESS, (uint32_t *)&app.ip_out_mode, sizeof(app.ip_out_mode));
HAL_EXIT_CRITICAL(s);
#endif
}
static void flash_write_ip_pwm_frequency(void)
{
#ifdef STM32
hal_int_state_t s;
HAL_ENTER_CRITICAL(s);
flash_write_no_buffer(FLASH_IP_OUT_PWM_FREQUENCY_ADDRESS, (uint32_t *)&app.ip_out_pwm_frequency, sizeof(app.ip_out_pwm_frequency));
HAL_EXIT_CRITICAL(s);
#endif
}
static void flash_write_process_config(config_t config)
{
#ifdef STM32
pbuf_t *pbuf = pbuf_allocz(LARGE_PBUF_BUFFER_SIZE __PLINE1);
DBG_ASSERT(pbuf != NULL __DBG_LINE);
pbuf->data_len += 2; // 偏移2个字节用来在flash中存储长度
config_convert_pbuf(config, &pbuf);
if (pbuf->data_len > 0)
{
osel_memcpy(&pbuf->data_p[0], (uint8_t *)&pbuf->data_len, 2);
hal_int_state_t s;
HAL_ENTER_CRITICAL(s);
flash_write_no_buffer(FLASH_PROCESS_CONFIG, (uint32_t *)&pbuf->data_p[0], pbuf->data_len);
HAL_EXIT_CRITICAL(s);
}
pbuf_freez(&pbuf __PLINE2);
#endif
}
void flash_load(void)
{
#ifdef STM32
flash_read_byte(FLASH_IP_OUT_MODE_ADDRESS, (uint8_t *)&app.ip_out_mode, sizeof(uint8_t));
if (app.ip_out_mode != IP_OUT_PWM && app.ip_out_mode != IP_OUT_DAC)
{
app.ip_out_mode = IP_OUT_DAC;
}
flash_read_byte(FLASH_IP_OUT_PWM_FREQUENCY_ADDRESS, (uint8_t *)&app.ip_out_pwm_frequency, sizeof(uint8_t));
if (app.ip_out_pwm_frequency == 0)
{
app.ip_out_pwm_frequency = 20;
}
flash_read_byte(FLASH_DEVICE_ADDRESS, (uint8_t *)&app.device_address, sizeof(app.device_address));
if (app.device_address == 0)
{
app.device_address = 1;
}
pbuf_t *pbuf = pbuf_allocz(LARGE_PBUF_BUFFER_SIZE __PLINE1);
DBG_ASSERT(pbuf != NULL __DBG_LINE);
uint16_t size = 0, offset = 2;
if (flash_read_byte(FLASH_PROCESS_CONFIG, (uint8_t *)&size, offset))
{
if (size > 0 && size < LARGE_PBUF_BUFFER_SIZE)
{
if (flash_read_byte(FLASH_PROCESS_CONFIG + offset, pbuf->data_p, size))
{
pbuf->data_len = size;
data_convert_config(pbuf->data_p, size);
}
}
}
pbuf_freez(&pbuf __PLINE2);
#endif
}
// 需要复位
bool need_reset(void)
{
return reset_flag;
}
// 获取IP转换器需要设置的电流值
uint32_t get_ip_dac_out(void)
{
// DAC = val / 1000*37*20.3/1000/3*4096 Imax=4.00mA
// DAC = (val *37*20.3*4096)/3000000
float64 ip_tmp = 0;
#if PID_IP == 0
ip_tmp = ip_dac_value; // μA
#else
#ifdef STM32
ip_tmp = pid_position_control(XDAC_CHANNEL_2, ip_dac_value, get_ip_adc_in(app.adc.ip_in6.original_value).f);
#endif
#endif
if (ip_tmp > (4000))
{
ip_tmp = 4000;
}
else if (ip_tmp < 0)
{
ip_tmp = 0;
}
ip_tmp = (ip_tmp * 3076505.6) / 3000000;
return ip_tmp;
}
float32_t get_ip_adc_in(uint32_t adc_val)
{
// current =(adc/4096)*300/48
float32_t f;
if (adc_val == 0)
{
f.f = 0;
}
else
{
float64 tmp = adc_val;
tmp = (tmp * 300000) / 196608;
f.f = (int32_t)tmp;
}
return f;
}
uint32_t get_proportional_valve_dac_out(void)
{
/**
* 电流 0-20mA电阻15k最大电压3V
* 压力和电流关系 电流值 = (压力值 - 最小压力值) * (最大电流值 - 最小电流值) / (最大压力值 - 最小压力值) + 最小电流值 => mA = (p - 0) * (20 - 4) / (900 - 0) + 4
* mA和DAC关系 mA = (DAC/4096)*3*1000*10/1500
* 推导关系转化 (p - PROPORTIONAL_VALVE_MIN) * (20 - 4) / (PROPORTIONAL_VALVE_MAX -PROPORTIONAL_VALVE_MIN) + 4 = (DAC/4096)*3*1000*10/1500
* DAC = (((p - PROPORTIONAL_VALVE_MIN) * (20 - 4) / (PROPORTIONAL_VALVE_MAX -PROPORTIONAL_VALVE_MIN) + 4)*1500)*4096/(3*1000*10)
* 简化后的关系 DAC = ((p - PROPORTIONAL_VALVE_MIN) / (PROPORTIONAL_VALVE_MAX - PROPORTIONAL_VALVE_MIN) * 16 + 4) * 204.8
*/
if (proportional_valve_dac_value == 0)
{
return 0;
}
float32 tmp;
// float32 tmp = proportional_valve_dac_value;
#ifdef STM32
if (pid_pressure_flag)
{
float32_t f;
get_sensor_pressure_data(pid_pressure_no, &f);
tmp = pid_position_control(XDAC_CHANNEL_1, proportional_valve_dac_value, f.f);
}
else
{
tmp = pid_position_control(XDAC_CHANNEL_1, proportional_valve_dac_value, get_proportional_valve_adc_in(app.adc.proportional_valve_in1.original_value).f);
}
#endif
if (tmp > PROPORTIONAL_VALVE_MAX)
{
tmp = PROPORTIONAL_VALVE_MAX;
}
else if (tmp < PROPORTIONAL_VALVE_MIN)
{
tmp = PROPORTIONAL_VALVE_MIN;
}
return ((tmp - PROPORTIONAL_VALVE_MIN) / (PROPORTIONAL_VALVE_MAX - PROPORTIONAL_VALVE_MIN) * 16 + 4) * 204.8;
}
// 获取比例阀压力值
float32_t get_proportional_valve_adc_in(uint32_t adc_val)
{
/**
* ITV-2050-012N 模拟输出电压1-5V单片机分压后到ADC的电压1-2.5V
* 压力和电压关系 v = (p - PROPORTIONAL_VALVE_MIN) * (5 - 1) / (PROPORTIONAL_VALVE_MAX - PROPORTIONAL_VALVE_MIN) + 1
* 电压和ADC关系 v = ADC*3*2/4096
* 推导关系转化 (p - PROPORTIONAL_VALVE_MIN) * 4 / (PROPORTIONAL_VALVE_MAX - PROPORTIONAL_VALVE_MIN) + 1 = ADC*3*2/4096
* 简化后的关系 p = (ADC*6/4096 -1)* (PROPORTIONAL_VALVE_MAX - PROPORTIONAL_VALVE_MIN)/4 + PROPORTIONAL_VALVE_MIN
*/
float32_t f;
float32 tmp = adc_val;
if ((tmp * 6 / 4096) < 0.9)
{
f.f = 0;
}
else
{
f.f = (int32_t)((tmp * 6 / 4096 - 1) * (PROPORTIONAL_VALVE_MAX - PROPORTIONAL_VALVE_MIN) / 4 + PROPORTIONAL_VALVE_MIN);
}
return f;
}
// 获取压力传感器的值
float32_t get_pressure_sensor_adc_in(int32_t adc_val)
{
/**
* DP-100压力范围-100-1000kPa输出电流2.4-20mA
* 电流和压力关系 电流值 = (压力值 - 最小压力值) * (最大电流值 - 最小电流值) / (最大压力值 - 最小压力值) + 最小电流值 => mA = (p - -100) * (20 - 2.4) / (1000 - -100) + 2.4
* mA和DAC关系 mA = adc*3000/4096*10*15
* 推导关系转化 (p - PRESURE_SENSOR_MIN) * (20 - 2.4) / (PRESURE_SENSOR_MAX - PRESURE_SENSOR_MIN) + 2.4 = adc*3000/4096*10*15
* => p = (adc*3000/4096*10*15 - 2.4) * (PRESURE_SENSOR_MAX - PRESURE_SENSOR_MIN) / (20 - 2.4) + PRESURE_SENSOR_MIN
* 简化后的关系 p = (adc*30/6144 - 2.4) * (PRESURE_SENSOR_MAX - PRESURE_SENSOR_MIN) / 17.6 + PRESURE_SENSOR_MIN
*/
float32_t f;
float32 tmp = adc_val;
if (((tmp * 30) / 6144) < 2.3)
{
f.f = 0;
}
else
{
f.f = (int32_t)((tmp * 30 / 6144 - 2.4) * (PRESURE_SENSOR_MAX - PRESURE_SENSOR_MIN) / 17.6 + PRESURE_SENSOR_MIN);
}
if (f.f < 0)
{
f.f = 0;
}
return f;
}
// 获取小回路值
float32_t get_minor_loop_adc_in(int32_t adc_val)
{
float32_t f;
float32 tmp = adc_val;
f.f = tmp * 3 / 4096;
return f;
}
// 获取阀门种类对应的继电器状态
static uint8_t get_value_unit_state(unit_e unit)
{
uint8_t state = 0;
if (unit == UNIT_TWO_WAY_VALVE)
{
for (uint8_t i = 1; i < 9; i++)
{
switch (i)
{
case 1:
state = (app.relay.bits.r1 == 1) ? (state | 0x01) : (state & ~0x01);
break;
case 2:
state = (app.relay.bits.r2 == 1) ? (state | 0x02) : (state & ~0x02);
break;
case 3:
state = (app.relay.bits.r3 == 1) ? (state | 0x04) : (state & ~0x04);
break;
case 4:
state = (app.relay.bits.r6 == 1) ? (state | 0x08) : (state & ~0x08);
break;
case 5:
state = (app.relay.bits.r7 == 1) ? (state | 0x10) : (state & ~0x10);
break;
}
}
}
else if (unit == UNIT_THREE_WAY_VALVE)
{
for (uint8_t i = 1; i < 9; i++)
{
switch (i)
{
case 1:
state = (app.relay.bits.r4 == 1) ? (state | 0x01) : (state & ~0x01);
break;
case 2:
state = (app.relay.bits.r5 == 1) ? (state | 0x02) : (state & ~0x02);
break;
case 3:
state = (app.relay.bits.r8 == 1) ? (state | 0x04) : (state & ~0x04);
break;
case 4:
state = (app.relay.bits.r9 == 1) ? (state | 0x08) : (state & ~0x08);
break;
}
}
}
return state;
}
// 设置阀门状态
void set_valve_status(unit_e unit, uint8_t index, uint8_t status)
{
if (unit == UNIT_TWO_WAY_VALVE)
{
switch (index)
{
case 1:
app.relay.bits.r1 = status;
break;
case 2:
app.relay.bits.r2 = status;
break;
case 3:
app.relay.bits.r3 = status;
break;
case 4:
app.relay.bits.r6 = status;
break;
case 5:
app.relay.bits.r7 = status;
break;
}
}
else if (unit == UNIT_THREE_WAY_VALVE)
{
switch (index)
{
case 1:
app.relay.bits.r4 = status == 1 ? LEFT_VALVE : RIGHT_VALVE;
break;
case 2:
app.relay.bits.r5 = status == 1 ? LEFT_VALVE : RIGHT_VALVE;
break;
case 3:
app.relay.bits.r8 = status == 1 ? LEFT_VALVE : RIGHT_VALVE;
break;
case 4:
app.relay.bits.r9 = status == 1 ? LEFT_VALVE : RIGHT_VALVE;
break;
}
}
}
// 标定压力传感器
static void calibration_sensor_pressure(uint8_t bits)
{
for (uint8_t i = 0; i < 8; i++)
{
uint8_t bit = bits & (1 << i);
switch (bit)
{
case 1:
app.adc.presure_in7.is_open = true;
break;
case 2:
app.adc.presure_in8.is_open = true;
break;
case 3:
app.adc.presure_in9.is_open = true;
break;
case 4:
app.adc.presure_in10.is_open = true;
break;
case 5:
app.adc.presure_in11.is_open = true;
break;
case 6:
app.adc.presure_in12.is_open = true;
break;
default:
break;
}
}
}
static void calibration_sensor(query_data_t data)
{
uint8_t count = data.count;
for (uint8_t i = 0; i < count; i++)
{
uint8_t sensor_class = data.sensors[i].sensor_class;
uint8_t sensor_bits = data.sensors[i].sensor.data;
switch (sensor_class)
{
case SENSOR_PRESSURE:
calibration_sensor_pressure(sensor_bits);
break;
case SENSOR_FLOW:
#ifdef STM32
flowmeter_set_calibration_flag(sensor_bits);
#endif
break;
case SENSOR_LASER:
#ifdef STM32
// 激光传感器默认只有一个
laser_handle.state = LASER_IDEL;
#endif
break;
default:
break;
}
}
}
static void get_sensor_pressure_data(const sensor_bits_e sensor_bits, float32_t *ptr)
{
uint8_t offset = 0;
if (sensor_bits.bits.sensor_1)
{
(ptr + offset)->f = get_pressure_sensor_adc_in(app.adc.presure_in7.original_value - app.adc.presure_in7.calibration_value).f;
offset++;
}
if (sensor_bits.bits.sensor_2)
{
(ptr + offset)->f = get_pressure_sensor_adc_in(app.adc.presure_in8.original_value - app.adc.presure_in8.calibration_value).f;
offset++;
}
if (sensor_bits.bits.sensor_3)
{
(ptr + offset)->f = get_pressure_sensor_adc_in(app.adc.presure_in9.original_value - app.adc.presure_in9.calibration_value).f;
offset++;
}
if (sensor_bits.bits.sensor_4)
{
(ptr + offset)->f = get_pressure_sensor_adc_in(app.adc.presure_in10.original_value - app.adc.presure_in10.calibration_value).f;
offset++;
}
if (sensor_bits.bits.sensor_5)
{
(ptr + offset)->f = get_pressure_sensor_adc_in(app.adc.presure_in11.original_value - app.adc.presure_in11.calibration_value).f;
offset++;
}
if (sensor_bits.bits.sensor_6)
{
(ptr + offset)->f = get_pressure_sensor_adc_in(app.adc.presure_in12.original_value - app.adc.presure_in12.calibration_value).f;
offset++;
}
}
static void get_sensor_flowmeter_data(sensor_bits_e sensor_bits, float32_t *ptr)
{
uint8_t offset = 0;
if (sensor_bits.bits.sensor_1)
{
#ifdef STM32
(ptr + offset)->f = flowmeter_get_flow(0);
#endif
offset++;
}
if (sensor_bits.bits.sensor_2)
{
#ifdef STM32
(ptr + offset)->f = flowmeter_get_flow(1);
#endif
offset++;
}
}
static float32_t *get_sensor_data(sensor_e sensor_class, sensor_bits_e sensor_bits)
{
static float32_t data[8];
float32_t *ptr = NULL;
#ifdef STM32
step_motor_t *step_motor;
#endif
// initialize data array to 0
osel_memset((uint8_t *)data, 0, sizeof(data));
ptr = data;
switch (sensor_class)
{
case SENSOR_PRESSURE:
// get pressure data
get_sensor_pressure_data(sensor_bits, ptr);
break;
case SENSOR_FLOW:
// get flowmeter data
get_sensor_flowmeter_data(sensor_bits, ptr);
break;
case SENSOR_TEMPERATURE:
#ifdef STM32
data[0] = ntc_get_temp(app.adc.ntc_in12.original_value);
#endif
break;
case SENSOR_LASER:
#ifdef STM32
// get laser distance
data[0].f = laser_handle.distance;
#endif
break;
case SENSOR_MINOR_LOOP:
#ifdef STM32
data[0] = get_minor_loop_adc_in(app.adc.minor_loop_in13.original_value);
#endif
break;
case SENSOR_STEP_MOTOR:
#ifdef STM32
step_motor = get_step_motor(STEP_MOTOR_1);
data[0].f = (int)(step_motor->attribute.add_pulse_count * MAX_STEP_ANGLE);
data[0].f = ABS(data[0].f); // 在当前项目中步进电机反转角度为正值
#endif
break;
default:
break;
}
return data;
}
// 串口发送数据
static void uart_send_data(uint8_t *data, uint16_t len)
{
#ifndef STM32
LOG_HEX(data, len);
#else
UartSend(UART_1, data, len);
#endif
}
static slave_request_done_t request_done(command_e command, void *data)
{
slave_request_done_t rsp;
osel_memset((uint8_t *)&rsp, 0, sizeof(slave_request_done_t));
switch (command)
{
case COMMAND_QUERY_IP_INPUT_CURRENT: // 读取电流
rsp.data.current.f = (uint32_t)get_ip_adc_in(app.adc.ip_in6.original_value).f;
rsp.default_value.f = ip_dac_value;
break;
case COMMAND_ADJUST_IP_INPUT_CURRENT: // 调节电流
rsp.data.current.f = *(float32 *)data;
ip_dac_value = (uint16_t)rsp.data.current.f;
if (ip_dac_value == 0) // 自动校准
{
#ifdef STM32
dac_init_flag_reset();
laser_zero_flag_reset();
#endif
}
break;
case COMMAND_QUERY_STATE: // 读取状态
{
uint8_t hi = 0, lo = 0;
osel_memcpy(rsp.data.query_state.code, (uint8_t *)PROJECT_NAME, 3);
version_split((uint8_t *)VERSION, &hi, &lo);
rsp.data.query_state.version.bits.hi = hi;
rsp.data.query_state.version.bits.lo = lo;
rsp.data.query_state.status = app.task_run_state;
rsp.data.query_state.process_index = app.process_state.process_index;
rsp.data.query_state.plan_index = app.process_state.plan_index;
rsp.data.query_state.action_index = app.process_state.action_index;
rsp.data.query_state.two_way_valve = get_value_unit_state(UNIT_TWO_WAY_VALVE);
rsp.data.query_state.three_way_valve = get_value_unit_state(UNIT_THREE_WAY_VALVE);
}
break;
case COMMAND_QUERY_PROCESS: // 读取流程
if (g_config != NULL)
{
osel_memcpy((uint8_t *)&rsp.data.config, (uint8_t *)g_config, sizeof(config_t));
}
break;
case COMMAND_CONFIG_PROCESS: // 配置流程
if (data != NULL)
{
osel_memcpy((uint8_t *)&rsp.data.config, (uint8_t *)data, sizeof(config_t));
flash_write_process_config(rsp.data.config);
}
break;
case COMMAND_EXECUTE_PROCESS: // 执行流程
if (data != NULL)
{
osel_memcpy((uint8_t *)&rsp.data.execute_process, (uint8_t *)data, sizeof(config_t));
if (app.task_run_state != RUN_STATE_EXECUTING)
{
app.task_run_state = RUN_STATE_READY_RUN;
}
}
break;
case COMMAND_STOP_PROCESS: // 停止流程
app.task_run_state = RUN_STATE_UNEXECUTED;
app.relay.data = 0;
break;
case COMMAND_QUERY_DATA: // 读取数据
{
if (data != NULL)
{
float32_t *f;
query_data_rsp_t *query_data_rsp = NULL;
osel_memcpy((uint8_t *)&rsp.data.query_data, (uint8_t *)data, sizeof(query_data_t));
query_data_rsp = (query_data_rsp_t *)osel_mem_alloc(rsp.data.query_data.count * sizeof(query_data_rsp_t)); // 申请内存在query_data_convert_pbuf中释放
DBG_ASSERT(query_data_rsp != NULL __DBG_LINE);
for (uint8_t i = 0; i < rsp.data.query_data.count; i++)
{
query_data_rsp[i].sensor_class = rsp.data.query_data.sensors[i].sensor_class;
query_data_rsp[i].sensor.data = rsp.data.query_data.sensors[i].sensor.data;
query_data_rsp[i].count = get_bit_num(query_data_rsp[i].sensor.data);
f = get_sensor_data((sensor_e)query_data_rsp[i].sensor_class, query_data_rsp[i].sensor);
if (f != NULL)
{
osel_memcpy((uint8_t *)query_data_rsp[i].data, (uint8_t *)f, query_data_rsp[i].count * sizeof(float32_t));
}
}
rsp.data.query_data_rsp = query_data_rsp; // 需要手动释放
}
}
break;
case COMMAND_CONFIG_ADDRESS: // 配置地址
if (data != NULL)
{
osel_memcpy((uint8_t *)&rsp.data.config_address, (uint8_t *)data, sizeof(config_address_t));
app.device_address = B2S_UINT16(rsp.data.config_address.address);
// 写到flash中
flash_write_address();
}
break;
case COMMAND_QUERY_ADDRESS: // 读取地址
// TODO 从flash中读取地址
rsp.data.query_address.address = S2B_UINT16(app.device_address);
break;
case COMMAND_CALIBRATE_SENSOR:
if (data != NULL)
{
osel_memcpy((uint8_t *)&rsp.data.calibration_sensor, (uint8_t *)data, sizeof(calibration_sensor_t));
if (rsp.data.calibration_sensor.state == 0) // 0值
{
calibration_sensor(rsp.data.calibration_sensor.sensor_data);
}
else
{
// TODO ?
}
}
break;
case COMMAND_SET_VALVE: // 设置阀门
if (data != NULL)
{
osel_memcpy((uint8_t *)&rsp.data.set_valve, (uint8_t *)data, sizeof(set_valve_t));
set_valve_status((unit_e)rsp.data.set_valve.unit, rsp.data.set_valve.index, rsp.data.set_valve.status);
}
break;
case COMMAND_QUERY_VALVE: // 比例阀查询
rsp.data.valve_ratio.value.f = (uint32_t)get_proportional_valve_adc_in(app.adc.proportional_valve_in1.original_value).f;
rsp.default_value.f = proportional_valve_dac_value;
if (pid_pressure_flag)
{
rsp.data.valve_ratio.pid_sensor_class = SENSOR_PRESSURE;
rsp.data.valve_ratio.pid_sensor_no = pid_pressure_no.data;
}
else
{
rsp.data.valve_ratio.pid_sensor_class = SENSOR_PROPORTIONAL_VALVE;
rsp.data.valve_ratio.pid_sensor_no = 1;
}
break;
case COMMAND_SET_VALVE_RATIO: // 设置比例阀
if (data != NULL)
{
osel_memcpy((uint8_t *)&rsp.data.valve_ratio, (uint8_t *)data, sizeof(set_valve_ratio_t));
proportional_valve_dac_value = (uint16_t)rsp.data.valve_ratio.value.f;
if (rsp.data.valve_ratio.pid_sensor_class == SENSOR_PRESSURE)
{
pid_pressure_flag = true;
pid_pressure_no.data = rsp.data.valve_ratio.pid_sensor_no;
}
else
{
pid_pressure_flag = false;
pid_pressure_no.data = 0;
}
if (proportional_valve_dac_value == 0) // 自动校准
{
#ifdef STM32
dac_init_flag_reset();
#endif
app.adc.proportional_valve_in1.is_open = true;
}
}
break;
case COMMAND_SET_STEPPER_MOTOR: // 设置步进电机
if (data != NULL)
{
osel_memcpy((uint8_t *)&rsp.data.stepper_motor, (uint8_t *)data, sizeof(stepper_motor_t));
#ifdef STM32
step_motor_t *step_motor = get_step_motor(STEP_MOTOR_1);
step_motor->interface.stop(STEP_MOTOR_1);
// 因为步进电机带动转盘电机360度转一圈转盘只转2度所以需要乘以180
step_motor->interface.set_angle(STEP_MOTOR_1, (uint16_t)(rsp.data.stepper_motor.angle * ANGLE), (dir_e)rsp.data.stepper_motor.dir);
#endif
}
break;
case COMMAND_QUERY_IP_INPUT_PWM_DUTY:
{
float32_t f;
f.f = ip_pwm_duty;
f.c = S2B_UINT32(f.c);
rsp.data.query_ip_pwm_duty.frequency = app.ip_out_pwm_frequency;
rsp.data.query_ip_pwm_duty.percent = f.f;
LOG_PRINT("ip pwm duty:%f", rsp.data.query_ip_pwm_duty.percent);
break;
}
case COMMAND_ADJUST_IP_INPUT_PWM_DUTY:
if (data != NULL)
{
osel_memcpy((uint8_t *)&rsp.data.adjust_ip_pwm_duty, (uint8_t *)data, sizeof(adjust_ip_pwm_duty_t));
ip_pwm_duty = rsp.data.adjust_ip_pwm_duty.percent;
LOG_PRINT("ip pwm duty:%f", ip_pwm_duty);
}
break;
case COMMAND_SET_IP_MODE: // 设置IP模式
if (data != NULL)
{
osel_memcpy((uint8_t *)&rsp.data.set_ip_mode, (uint8_t *)data, sizeof(set_ip_mode_t));
app.ip_out_mode = rsp.data.set_ip_mode.mode;
app.ip_out_pwm_frequency = rsp.data.set_ip_mode.data.frequency;
flash_write_ip_mode();
flash_write_ip_pwm_frequency();
LOG_PRINT("ip mode:%d, ip frequency:%d", app.ip_out_mode, app.ip_out_pwm_frequency);
#ifdef STM32
ip_set_init((ip_out_mode_e)app.ip_out_mode, app.ip_out_pwm_frequency);
#endif
}
break;
case COMMAND_QUERY_IP_MODE: // 查询IP模式
{
rsp.data.query_ip_mode.mode = app.ip_out_mode;
if (app.ip_out_mode == 2)
{
rsp.data.query_ip_mode.data.frequency = app.ip_out_pwm_frequency;
rsp.data.query_ip_mode.data_length = 1;
}
else
{
rsp.data.query_ip_mode.data_length = 0;
}
break;
}
case COMMAND_RESET_DEVICE:
reset_flag = true;
break;
default:
break;
}
return rsp;
}
static void data_analysis_event(void)
{
uint8_t frame[UART_RXSIZE];
uint8_t data_head[3];
uint8_t crc[2];
uint16_t frame_len, out_frame_len;
data_read(UART_DATA_ANALYSIS_PORT, &data_head[0], 3);
osel_memcpy((uint8_t *)&frame_len, &data_head[1], 2);
frame_len = B2S_UINT16(frame_len) - 2; // 报文长度包含帧长这里需要减2
if (frame_len > UART_RXSIZE)
{
lock_data(UART_DATA_ANALYSIS_PORT);
unlock_data(UART_DATA_ANALYSIS_PORT);
return;
}
out_frame_len = data_read(UART_DATA_ANALYSIS_PORT, frame, (uint16_t)frame_len);
if (out_frame_len != frame_len)
{
return;
}
out_frame_len = out_frame_len - 1; // 报文中包含帧尾这里需要减1
// 校验CRC_16
uint16_t crc_16 = 0;
uint16_t crc16 = crc16_compute(&frame[0], out_frame_len - 2);
osel_memcpy(&crc[0], &frame[out_frame_len - 2], 2);
crc_16 = BUILD_UINT16(crc[1], crc[0]);
if (crc16 != crc_16)
{
return;
}
// CRC校验通过后将数据长度-2
out_frame_len -= 2;
pbuf_t *frm_buf = pbuf_allocz(out_frame_len __PLINE1);
DBG_ASSERT(frm_buf != NULL __DBG_LINE);
frm_buf->data_len = out_frame_len;
osel_memcpy(&frm_buf->data_p[0], frame, out_frame_len);
agreement_req_cb(&frm_buf->data_p[0], out_frame_len);
pbuf_freez(&frm_buf __PLINE2);
app.master_active = true; // 主机活跃
}
bool uart_init(agreement_req_cb_t cb)
{
DBG_ASSERT(cb != NULL __DBG_LINE);
// 注册数据解析
data_reg_t reg;
reg.sd.valid = true;
reg.sd.len = 1;
reg.sd.pos = 0;
reg.sd.data[0] = FRAME_HEAD;
reg.ld.len = 2;
reg.ld.pos = 2; // 报文长度包含帧长这里需要设置偏移2
reg.ld.valid = true;
reg.ld.little_endian = false;
reg.argu.len_max = 1024;
reg.argu.len_min = 2;
reg.ed.valid = true;
reg.ed.len = 1;
reg.ed.data[0] = FRAME_TAIL;
reg.echo_en = false;
reg.func_ptr = data_analysis_event;
uart_data_analysis_cb = data_fsm_init(UART_DATA_ANALYSIS_PORT);
data_reg(UART_DATA_ANALYSIS_PORT, reg);
agreement_req_cb = cb;
return true;
}
/**
* @description: 应用层初始化
* @return {*}
*/
bool app_init(void)
{
app.task_run_state = RUN_STATE_UNEXECUTED;
if (!DBG_ASSERT(false != uart_init(agreement_slave_req) __DBG_LINE))
return false;
agreement_init_t agreement_init_param;
agreement_init_param.slave = 1;
agreement_init_param.response_call = uart_send_data;
agreement_init_param.slave_request_done_call = request_done;
if (!DBG_ASSERT(false != agreement_init(&agreement_init_param) __DBG_LINE))
return false;
sensor_init();
flash_load();
#ifdef STM32
// app.ip_out_mode = IP_OUT_PWM;
// app.ip_out_pwm_frequency = 32;
ip_set_init((ip_out_mode_e)app.ip_out_mode, app.ip_out_pwm_frequency);
ip_set_out(0);
#endif
return true;
}
// 串口接收到数据
void uart_recv_data(uint8_t *data, uint16_t len)
{
if (uart_data_analysis_cb != NULL)
{
for (uint16_t i = 0; i < len; i++)
{
uart_data_analysis_cb(UART_DATA_ANALYSIS_PORT, *(data + i));
}
}
}
void register_request_done(void)
{
handle.slave_request_done_call = request_done;
}