acdt/users/Inc/provalctrl.h

139 lines
4.6 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 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 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; //减速标志
// float cstep_gasin; //逐步接近,充气步长
// float cstep_gasout; //逐步接近,排气步长
// float cstep_max; //步长上限
// float cstep_min;
// unsigned char cstep_wait; //步长下限
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 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]; //用于存放电流
float table_pressure[SECTION_NUM]; //用于存放实际气压
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);
/******************************************************************************************/
#endif