MoistureSoftware/Source/WS100T10.c

176 lines
4.5 KiB
C
Raw Permalink 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.

#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;
}
}
}