acdt/users/Inc/provalctrl.h

155 lines
5.3 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.

#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