176 lines
4.5 KiB
C
176 lines
4.5 KiB
C
#include "APPDEF.h"
|
||
#include "i2c.h"
|
||
uint16_t ACCtrl(uint16_t Percent) /*0-1000*/
|
||
{
|
||
uint8_t Out = 0;
|
||
if (Percent < 10) {
|
||
Out = 0;
|
||
} else if (Percent > 990) {
|
||
Out = 1;
|
||
} else {
|
||
Out = 127u - (uint8_t)((float)Percent * 0.128f);
|
||
}
|
||
WS100T10_Ctrl(Out);
|
||
return Percent;
|
||
}
|
||
void ACCMD(bool cmd)
|
||
{
|
||
if (!cmd) {
|
||
GPIO_ResetBits(GPIOA, GPIO_Pin_15);
|
||
|
||
} else {
|
||
GPIO_SetBits(GPIOA, GPIO_Pin_15);
|
||
}
|
||
}
|
||
uint16_t Percent[4];
|
||
uint16_t GetPercent[4];
|
||
uint16_t PercentOld[4];
|
||
void _task_ACCtrl(const void *p_arg)
|
||
{
|
||
WS100T10_Init();
|
||
for (;;) {
|
||
if (Percent[0] != PercentOld[0]) {
|
||
GetPercent[0] = ACCtrl(Percent[0]);
|
||
PercentOld[0] = Percent[0];
|
||
}
|
||
osDelay(300);
|
||
}
|
||
}
|
||
|
||
osThreadDef(_task_ACCtrl, osPriorityNormal, 1u, 0u);
|
||
|
||
void AC_CTRL_Init(void)
|
||
{
|
||
osThreadCreate(osThread(_task_ACCtrl), NULL);
|
||
}
|
||
|
||
//
|
||
//
|
||
//
|
||
extern float Temperature;
|
||
float Kp, Ki, Kd;
|
||
static enum enumHeatOp_State { // 采样泵操作状态
|
||
eShut,
|
||
eRunning,
|
||
eShutReq
|
||
} volatile HeatOp_State;
|
||
float HeatOutValue;
|
||
float OutputMax = 1;
|
||
static void HeatPID_Task(void)
|
||
{
|
||
float SetValue, RunValue, OutValue = 0.0f;
|
||
float Ek_1, Ek = 0.0f;
|
||
float Up = 0.0f, Ui = 0.0f, Ud = 0.0f;
|
||
float Upid = 0.0f;
|
||
float Initout = 0.0f;
|
||
float UpidSetGain = 0.800f;
|
||
uint32_t SaveTick;
|
||
SetValue = Set.TempSet;
|
||
Kp = 0.06;
|
||
Ki = 0.00029;
|
||
Kd = 1.0;
|
||
HeatOutValue = 0.0f;
|
||
Percent[0] = 0;
|
||
osDelay(500u);
|
||
ACCMD(true);
|
||
// 初始化延时
|
||
osDelay(500u);
|
||
SaveTick = osKernelSysTick();
|
||
const uint32_t oneTick = osKernelSysTickMicroSec(1000u);
|
||
uint32_t now, lostTick, delayCount;
|
||
while (eRunning == HeatOp_State) {
|
||
|
||
RunValue = Temperature;
|
||
// PID计算
|
||
Ek_1 = Ek;
|
||
Ek = (SetValue - RunValue);
|
||
if (Ek > 20.0f) {
|
||
HeatOutValue = OutValue = OutputMax;
|
||
Percent[0] = OutValue * 1000;
|
||
} else {
|
||
Up = Kp * Ek;
|
||
Ui += Ki * Ek;
|
||
|
||
if (Ui < -1.0f) { Ui = -1.0f; }
|
||
if (Ui > +1.0f) { Ui = +1.0f; }
|
||
Ud = (Ud * 0.667f) + (Kd * (Ek - Ek_1) * (1.0f - 0.667f));
|
||
Upid = (Upid * UpidSetGain) + (Up + Ui + Ud) * (1.0f - UpidSetGain);
|
||
OutValue = Upid + Initout;
|
||
|
||
// PID输出
|
||
if (OutValue < 0.0f) { OutValue = 0.0f; }
|
||
if (OutValue > OutputMax) { OutValue = OutputMax; }
|
||
HeatOutValue = OutValue;
|
||
Percent[0] = OutValue * 1000;
|
||
}
|
||
// 定间隔延时
|
||
now = osKernelSysTick();
|
||
// 计算已经逝去的tick计时单位
|
||
lostTick = (uint32_t)(now + oneTick - 1u - SaveTick) / oneTick;
|
||
// 计算余下需要的延时周期(设定间隔时间:300ms)
|
||
if (lostTick < 300u) {
|
||
delayCount = 300u - lostTick;
|
||
} else { // 已经逝去的时间超过设定的间隔,重新计算时间起点后少量延时。
|
||
SaveTick = now;
|
||
delayCount = 30u;
|
||
}
|
||
osDelay(delayCount);
|
||
SaveTick += delayCount * oneTick;
|
||
}
|
||
// PID 停止
|
||
HeatOutValue = 0.0f;
|
||
Percent[0] = 0;
|
||
osDelay(500u);
|
||
ACCMD(false);
|
||
HeatOp_State = eShut;
|
||
}
|
||
|
||
/********************************** 功能说明 ***********************************
|
||
* 套接调用电机控制程序
|
||
*******************************************************************************/
|
||
static void HeatTask_Socket(void const *p_arg)
|
||
{ // 调用采样控制程序,然后结束任务
|
||
HeatPID_Task();
|
||
|
||
osThreadTerminate(osThreadGetId());
|
||
}
|
||
|
||
osThreadDef(HeatTask_Socket, osPriorityHigh, 1, 0);
|
||
|
||
static void HeatTask_Init()
|
||
{
|
||
osThreadCreate(osThread(HeatTask_Socket), NULL);
|
||
}
|
||
/********************************** 功能说明 ***********************************
|
||
* 电机任务的启停控制/// 开关指定的采样泵
|
||
*******************************************************************************/
|
||
// #include "BIOS.H"
|
||
|
||
void Pump_OutCmd(bool NewState)
|
||
{
|
||
if (!NewState) { // 发标志,任务会检测标志自行中止。 // osThread_SetReady;
|
||
HeatOp_State = eShutReq;
|
||
} else if (eRunning == HeatOp_State) { // 请求开泵,但泵并没有关?!
|
||
;
|
||
} else { // 请求开泵,且已知泵是关的
|
||
HeatOp_State = eRunning;
|
||
HeatTask_Init();
|
||
}
|
||
// if( HeatOp_State == eRunning)
|
||
// lightopen();
|
||
// else
|
||
// lightclose();
|
||
}
|
||
|
||
/// 读取指定的采样泵的调速输出[0.0 ~ 1.0]
|
||
float Pump_GetOutput(void)
|
||
{
|
||
{
|
||
if (eShutReq == HeatOp_State) {
|
||
return 0.0f;
|
||
} else {
|
||
return HeatOutValue;
|
||
}
|
||
}
|
||
}
|