找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 259|回复: 4
打印 上一主题 下一主题
收起左侧

上传一个PID的算法(有注解)

[复制链接]
跳转到指定楼层
楼主
ID:1104531 发表于 2025-8-13 15:57 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

// PID计算
unsigned int PID_Calculate(struct PID *pid, unsigned int feedback)
{
        // 偏差  设定值-ADC反馈值
    unsigned int Error = pid->SetPoint - feedback; // 偏差

    // 积分项更新(使用有符号数)
    pid->SumError += (int)Error;

    // 积分抗饱和
    if(pid->SumError > MAX_INTEGRAL) pid->SumError = MAX_INTEGRAL;
    else if(pid->SumError < -MAX_INTEGRAL) pid->SumError = -MAX_INTEGRAL;

    // 微分计算
    unsigned int dError = pid->LastError - pid->PrevError;
    pid->PrevError = pid->LastError;
    pid->LastError = Error;

    // 计算各项(使用长整型防溢出)
    unsigned long p_term = (unsigned long)pid->Proportion * Error;
    unsigned long i_term = (unsigned long)pid->Integral * (unsigned long)pid->SumError;
    unsigned long d_term = (unsigned long)pid->Derivative * dError;

    // 综合输出  SCALE_FACTOR这是放大倍数 运算之前进行放大,出去前回归
    unsigned long output = (p_term + i_term + d_term) / SCALE_FACTOR;

    return (unsigned int)output;
}

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏3 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:30165 发表于 2025-8-14 17:35 | 只看该作者
没有搞明白 PID算法主要是为了解决什么问题?比如温度控制 。PID算法和传统到设定控制优缺点是什么?
回复

使用道具 举报

板凳
ID:1104531 发表于 2025-8-15 17:11 | 只看该作者
通过设定值与反馈值计算;再通过PWM进行控制
回复

使用道具 举报

地板
ID:230500 发表于 2025-8-17 08:19 | 只看该作者
现在有了AI , 这些算法不用死记硬背了 稍微修改下 就可以用, 主要精力可以放在KP KI KD的整定上,
下面这部分是AI做的, 直接调用, 就行, 在结构体对PID初始化的时候填入整定好的参数即可运行; 但是AI也不是完全准确,他只对共用算法很准确,对STC的单片机就有点问题, PWM部分需要自己重写,

/********************* PID计算函数 *********************/
float PID_Compute(PID_Controller *pid, float setpoint, float input) {
    float error = setpoint - input; //声明误差变量
    float Pout; //声明比例变量
        float Iout; //声明积分变量
        float Dout; //声明微分变量

    // 死区处理(误差小于0.3℃时不调节)
    if(fabs(error) < 0.3) {
        error = 0;
    }
   
    // 比例项
    Pout = pid->Kp * error;
   
    // 积分项(抗积分饱和)
    pid->integral += pid->Ki * error;
    if(pid->integral > pid->out_max) pid->integral = pid->out_max;
    else if(pid->integral < pid->out_min) pid->integral = pid->out_min;
    Iout = pid->integral;
       
    // 微分项
    Dout = pid->Kd * (error - pid->prev_error);
    pid->prev_error = error; // 保存误差用于下次计算
   
    // 计算输出PID
    pid->output = Pout + Iout + Dout;
   
    // 输出限幅
    if(pid->output > pid->out_max) pid->output = pid->out_max;
    else if(pid->output < pid->out_min) pid->output = pid->out_min;
   
    return pid->output;
}
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表