/* * @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 #include #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; }