#ifndef _PROVALCTRL_H_ #define _PROVALCTRL_H_ #include "modbus.h" #include "dac7311.h" #include "main.h" //#include "flash.h" //擦写出错,写入出错 #include "eeprom.h" #include "math.h" #define ENABLE_PID_CTRL 0 #define ENABLE_SECTION_CAL 0 #define AO_0 0 #define AO_1 1 #define AO_2 2 #define SECTION_NUM 10 #define AO_CAL_START 2 #define AO_CAL_END 22 #define CSTEP_WAIT_MAX 0 //逐步接近,等待时间 #define BIAS_MAX 10 //偏大大于此值时不进行控制 #define GAS_IN 0 //充气 #define GAS_OUT 1 //排气 #define SLDW_PRES_OUT 10 //输出气压的滑动窗口长度 extern float ao_dwq; //AO输出电流值(定位器) extern float ao_blf1; //AO输出电流值(比例阀) extern float ao_blf2; //AO输出电流值(比例阀) //比例阀运行状态枚举 typedef enum { PROV_RUNNING = 0, //运行,PID控制 PROV_ADJUSTING = 1, //整定 PROV_HOLDING = 2 //保持原样,比例阀本身 + 分段校准 }prov_status; //继电反馈步骤枚举 typedef enum { ADJ_START = 0, //整定开始 ADJ_MOVE2MIDDLE = 1, //输出气源气压的一半,移动至中间位置附近 ADJ_OSCILLATE = 2, //继电反馈,强制振荡 ADJ_CALCULATE = 3, //计算结果 ADJ_END = 4, //整定结束,等待一段时间后恢复控制 ADJ_WAIT = 5 //等待,未进入整定程序 }adj_steps; //分段校准步骤枚举 typedef enum { SECTION_START = 0, //整定开始 SECTION_RECORD_AIRSOURCE = 1, //记录气源压力,并计算分段电流值(理论下限——气源对应理论电流) SECTION_MOVE = 2, //按照分段点阶梯式步进 SECTION_END = 3, //整定结束 SECTION_WAIT = 4 //等待,未进入整定 }adj_section_steps; //比例阀参数结构体 typedef struct { prov_status status; //比例阀状态 unsigned char tag; //标签,用于区分 float previous_pressure[SLDW_PRES_OUT]; //前几个时刻的输出气压 float current_pressure; //当前输出气压 float current_percent; //当前输出气压百分比 float target_pressure; //目标气压 float target_percent; //目标气压百分比 float target_current; //目标值的理论电流 float current_input; //当前电流输入 float input_max; //输入电流上限 float input_min; //输入电流下限 float ctrl_max; //控制范围上限(默认4~20mA,预留以备分程控制) float ctrl_min; //控制范围下限 float bias; //偏差百分比 float bias_previous; //前一个偏差 float bias_area; //允许的误差范围 [-a, a]% uint8_t gas_direction; //充气或排气 // float Kp; //比例系数 // float Ti; //积分时间 // float Ing; //积分项 // float Ing_sum; //积分求和 // float Ing_max; //求和上限 // float Ing_min; //求和下限 // float Td; //微分时间 // float Ts; //采样时间(控制周期) // float Div; //微分项 // float pidout; //PID输出 // float pidout_max; //PID输出上限 // float pidout_min; //PID输出下限 // uint8_t slow_down_flg; //减速标志 void (*pvout)(float pout); //dac 输出 }propotion_valve; extern propotion_valve pv_one; extern propotion_valve pv_two; //比例阀整定过程参数 #define OSCILL_TIMES 5 //振荡次数 #define TICK_LIMIT 120 //振荡周期限时 #define SECTION_NUM_ADJ 10 //区间端点数,区间数 = 端点数 - 1 typedef struct //过程参数结构体,继电反馈和分段式校准共用此结构体 { //继电反馈 unsigned char adj_flag; //整定标志,用于判断是否处于整定中 float relay_d; //继电反馈,回环幅值 float relay_a[OSCILL_TIMES]; //继电反馈,输出气压振荡幅值,中间数据 float relay_A; //继电反馈,输出气压振荡幅值,结果 float relay_tc[OSCILL_TIMES]; //继电反馈,输出气压振荡周期,中间数据 float relay_Tc; //继电反馈,输出气压振荡周期,结果 float air_source; //气源压力 float middle_current; //中间位置电流 unsigned char oscil_times; //当前振荡次数 //分段式 float table_current[SECTION_NUM_ADJ]; //用于存放电流 float table_pressure[SECTION_NUM_ADJ]; //用于存放实际气压 float stable_area; //当滑动窗口内的max和min都处于 ±stable_area 内时,判断已经稳定 unsigned char wait_tick; }prov_adjust; void prov_init(void); void prov_adj_init(prov_adjust *adj_pvx); void prov_adj_section_init(prov_adjust *adj_pvx); void prov_set(float target_p, propotion_valve *pvx); void prov_ctrl(propotion_valve *pvx, prov_adjust *adj_pvx); void prov_calibrate_pid(propotion_valve *pvx); void prov_calibrate_step(propotion_valve *pvx); void analog_ctrl(void); float abs_bias(float bias); void prov_adj(propotion_valve *pvx, prov_adjust *adj_pvx); void prov_adj_section(propotion_valve *pvx, prov_adjust *adj_pvx); float prov_section_calculate(float target_pressure, prov_adjust *adj_pvx); float current_output_calibrate(uint8_t tag, float target); void current_output_calibrate_init(void); //网络通讯 void tcpip_run(void); /******************************************************************************************/ #endif