📄 ctl.c
字号:
/*
****************************************************
****************************************************
*/
#include <reg52.H>
#include <rtx51tny.h>
#include "Typedef.H"
#include "UserDef.H"
#include "disp.h"
#include "LTC1860.h"
#include <math.h>
/* */
#define T_SELECT 100 // 采样周期
#define T_DRV 100 // 控制驱动输出周期
#define ADSET 1500
/* 私有全局变量 */
static INT8U sig_targ; // 显示任务的任务号
static xdata float Kp=1; // PID 系数
static xdata float Ki=0.1; // PID 系数 Kp*Ts/Ti
static xdata float Kd=1; // PID 系数 Kp*Td/Ts
static xdata float Yn=0; // PID Yn
static xdata float SumE=0;
/* 端口 */
sbit P_Drv = P3^0; // 输出端口
void PID(INT32U ADCur,INT32U ADSet);
/***************************************************
****************************************************/
static void TaskCTL(void) _task_ TASK_CTL
{
INT32S ni;
INT16U ADn;
/* 显示界面固定文字显示 */
DISP_REQ;
dm.x = 0;
dm.y = 0;
dm.font = 1;
dm.DData = "Set="; //
dm.type = DTYPE_STR;
os_send_signal(sig_targ);
DISP_REQ;
dm.x = 2;
dm.y = 0;
dm.font = 1;
dm.DData = "Cur="; //
dm.type = DTYPE_STR;
os_send_signal(sig_targ);
while (1)
{
os_wait(K_TMO,T_SELECT,0); //采样周期
/* 采样 */
ADn = LTC1860();
DISP_REQ;
dm.x = 0;
dm.y = 50;
dm.font = 1;
ni = ADSET;
dm.DData = ∋
dm.len = 4;
dm.type = DTYPE_INT32S;
os_send_signal(sig_targ);
DISP_REQ;
dm.x = 2;
dm.y = 50;
dm.font = 1;
ni = ADn;
dm.DData = ∋
dm.len = 4;
dm.type = DTYPE_INT32S;
os_send_signal(sig_targ);
PID(ADn,ADSET);
DISP_REQ;
dm.x = 4;
dm.y = 50;
dm.font = 1;
dm.DData = &Yn;
dm.len = 4;
dm.type = DTYPE_FLOAT;
os_send_signal(sig_targ);
}
}
/***************************************************
****************************************************/
static void TaskDRV(void) _task_ TASK_DRV
{
INT8U tOut;
P_Drv = 1;
while (1)
{
P_Drv = 0;
tOut = (INT8U)(Yn * T_DRV);
os_wait(K_TMO,tOut,0); //
P_Drv = 1;
os_wait(K_TMO,T_DRV - tOut,0); //
}
}
/***************************************************
任务创建函数
signal_target_task 接收键盘信号的任务编号
****************************************************/
void TaskCreate_CTL(INT8U signal_target_task)
{
sig_targ = signal_target_task;
os_create_task(TASK_CTL);
os_create_task(TASK_DRV);
}
/***************************************************
****************************************************/
void PID(INT32U ADCur,INT32U ADSet)
{
xdata float Uk;
xdata float Ek;
xdata INT32S dlt;
static xdata float Ek_1;
dlt = (INT32S)ADSet - (INT32S)ADCur;
Ek = (float)dlt;
//PID运算
SumE += Ek;
// 抗积分饱和(积分分离)
if (abs(dlt) > 200)
{
SumE = 0; //积分遗忘
}
Uk = Kp*Ek + Ki*SumE + Kd*(Ek-Ek_1);
//饱和限幅
if (Uk > 100)
Uk = 100;
else if (Uk < 0)
Uk = 0;
Ek_1 = Ek;
Yn = Uk/100.0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -