155 lines
5.3 KiB
C
155 lines
5.3 KiB
C
#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
|
||
|
||
|