OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3597|回复: 7

有偿请教PID设计方案。。。(微信红包)

[复制链接]

23

主题

79

帖子

0

精华

高级会员

Rank: 4

积分
607
金钱
607
注册时间
2017-8-8
在线时间
145 小时
发表于 2018-1-10 13:46:15 | 显示全部楼层 |阅读模式
10金钱
设计原理图.jpg
void main(void)
{
   //各类初始化;               
   while(1)
   {
     adc = Get_ADC10bitResult(1); //读取霍尔传感器值
     adc = adc/2; //10位ADC,因4V的ADC值为800,转换成实际电流值
     if(set_current > adc) //如果设定值大于反馈值?
        {
          fb++;if(fb>1000)fb=1023;WriteTLC5615(fb);//增加占空比,最高加到5V
        }
     if(set_current < adc) //如果设定值小于反馈值?
        {
          fb--;if(fb<200)fb=200;WriteTLC5615(fb);//增小占空比,最低减到1V
        }     
   }
}
/*整流控制过程如上可实现,但有以下不足,
当设置值与反馈值相差较大时,占空比是逐个增加或减小,
反映时间太慢(>100ms),,,现需要加入PID控制,
当设置值与反馈值相差较大时,大幅度增加或增小占空比,
当设置值与反馈逐渐接近时,再小幅度整占空比,
那样速度会快很多,请问如何实现(<1ms)?
如有方案可私聊我,如果问题解决,必定红包重谢*/

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

3

主题

1155

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
7464
金钱
7464
注册时间
2015-1-15
在线时间
1368 小时
发表于 2018-1-10 15:09:12 | 显示全部楼层
网上PID算法很多的,直接拿个过来用用好了
一分耕耘一分收获。
回复

使用道具 举报

23

主题

79

帖子

0

精华

高级会员

Rank: 4

积分
607
金钱
607
注册时间
2017-8-8
在线时间
145 小时
 楼主| 发表于 2018-1-10 15:24:48 | 显示全部楼层
yklstudent 发表于 2018-1-10 15:09
网上PID算法很多的,直接拿个过来用用好了

#include<stdio.h>
#include<stdlib.h>

struct _pid{
    float SetSpeed;            //定义设定值
    float ActualSpeed;        //定义实际值
    float err;                //定义偏差值
    float err_next;            //定义上一个偏差值
    float err_last;            //定义最上前的偏差值
    float Kp,Ki,Kd;            //定义比例、积分、微分系数
}pid;

void PID_init(){
    pid.SetSpeed=0.0;
    pid.ActualSpeed=0.0;
    pid.err=0.0;
    pid.err_last=0.0;
    pid.err_next=0.0;
    pid.Kp=0.2;
    pid.Ki=0.015;
    pid.Kd=0.2;
}

float PID_realize(float speed){
    pid.SetSpeed=speed;
    pid.err=pid.SetSpeed-pid.ActualSpeed;
    float incrementSpeed=pid.Kp*(pid.err-pid.err_next)+pid.Ki*pid.err+pid.Kd*(pid.err-2*pid.err_next+pid.err_last);
    pid.ActualSpeed+=incrementSpeed;
    pid.err_last=pid.err_next;
    pid.err_next=pid.err;
    return pid.ActualSpeed;
}

int main(){
    PID_init();
    int count=0;
    while(count<1000)
    {
        float speed=PID_realize(200.0);
        printf("%f\n",speed);
        count++;
    }
    return 0;
}
这是我网上找到的增量式PID,怎么代入?
回复

使用道具 举报

31

主题

265

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
413
金钱
413
注册时间
2018-1-9
在线时间
65 小时
发表于 2018-1-10 16:46:01 | 显示全部楼层

你找的这个PID感觉,不是工程用的没有输入啊?
缺少对ActualSpeed的赋值。还有工程用的一定会有饱和输出判断的,就是你原有程序中的200和1000的判断。
你这么大的功率在调程序的时候一定要有,输出限制,不然会炸的。
贴一个DSP的宏定义的PI调节器,其实大部分PID的D都等于0,。也就是PI调节器 了。
你先看看,有什么问题可以使交流。
#ifndef __PI_H__
#define __PI_H__

typedef struct {  _iq  Ref;                           // Input: reference set-point
                                  _iq  Fbk;                           // Input: feedback
                                  _iq  Out;                           // Output: controller output
                                  _iq  Kp;                                // Parameter: proportional loop gain
                                  _iq  Ki;                            // Parameter: integral gain
                                  _iq  Umax;                        // Parameter: upper saturation limit
                                  _iq  Umin;                        // Parameter: lower saturation limit
                                  _iq  up;                                // Data: proportional term
                                  _iq  ui;                                // Data: integral term
                                  _iq  v1;                                // Data: pre-saturated controller output
                                  _iq  i1;                                // Data: integrator storage: ui(k-1)
                                  _iq  w1;                                // Data: saturation record: [u(k-1) - v(k-1)]
                                } PI_CONTROLLER;


/*-----------------------------------------------------------------------------
Default initalisation values for the PI_GRANDO objects
-----------------------------------------------------------------------------*/                     

#define PI_CONTROLLER_DEFAULTS {                \
                                                   0,                         \
                           0,                         \
                                                   0,                         \
                           _IQ(1.0),        \
                           _IQ(0.0),        \
                           _IQ(1.0),        \
                           _IQ(-1.0),         \
                           _IQ(0.0),        \
                           _IQ(0.0),         \
                           _IQ(0.0),        \
                           _IQ(0.0),        \
                           _IQ(1.0)         \
                                        }

/*------------------------------------------------------------------------------
        PI_GRANDO Macro Definition
------------------------------------------------------------------------------*/

#define PI_MACRO(v)                                                                                                \
                                                                                                                                \
        /* proportional term */                                                                         \
        v.up = _IQmpy(v.Kp, (v.Ref - v.Fbk));                                                \
                                                                                                                                \
        /* integral term */                                                                                 \
        v.ui = (v.Out == v.v1)?(_IQmpy(v.Ki, v.up)+ v.i1) : v.i1;        \
        v.i1 = v.ui;                                                                                                \
                                                                                                                                \
        /* control output */                                                                                 \
        v.v1 = v.up + v.ui;                                                                                        \
        v.Out= _IQsat(v.v1, v.Umax, v.Umin);                                                \
        //v.w1 = (v.Out == v.v1) ? _IQ(1.0) : _IQ(0.0);               
回复

使用道具 举报

23

主题

79

帖子

0

精华

高级会员

Rank: 4

积分
607
金钱
607
注册时间
2017-8-8
在线时间
145 小时
 楼主| 发表于 2018-1-10 18:14:48 | 显示全部楼层
jinfeihan57 发表于 2018-1-10 16:46
你找的这个PID感觉,不是工程用的没有输入啊?
缺少对ActualSpeed的赋值。还有工程用的一定会有饱和输出 ...

限幅那些后面加入,先把最重要的PID计算搞定,
怎么代入程序?
最终的结果要写入DAC芯片,
能否帮代入程序?简单的就行,
已知设定值,反馈值,求最后写入DAC值。
回复

使用道具 举报

4

主题

211

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2600
金钱
2600
注册时间
2016-7-6
在线时间
546 小时
发表于 2018-1-10 22:58:21 | 显示全部楼层
我看着这个要求,感觉有点不简单。
把复杂的事,做简单!
回复

使用道具 举报

31

主题

265

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
413
金钱
413
注册时间
2018-1-9
在线时间
65 小时
发表于 2018-1-11 14:33:59 | 显示全部楼层
lovewjl 发表于 2018-1-10 18:14
限幅那些后面加入,先把最重要的PID计算搞定,
怎么代入程序?
最终的结果要写入DAC芯片,

#ifndef __PI_H__
#define __PI_H__

typedef struct {                  u16  Ref;                           // Input: reference set-point
                                  u16  Fbk;                           // Input: feedback
                                  u16  Out;                           // Output: controller output
                                  u16  Kp;                                // Parameter: proportional loop gain
                                  u16  Ki;                            // Parameter: integral gain
                                  u16  Umax;                        // Parameter: upper saturation limit
                                  u16  Umin;                        // Parameter: lower saturation limit
                                  u16  up;                                // Data: proportional term
                                  u16  ui;                                // Data: integral term
                                  u16  v1;                                // Data: pre-saturated controller output
                                  u16  i1;                                // Data: integrator storage: ui(k-1)
                                  u16  w1;                                // Data: saturation record: [u(k-1) - v(k-1)]
                                } PI_CONTROLLER;


/*-----------------------------------------------------------------------------
Default initalisation values for the PI_GRANDO objects
-----------------------------------------------------------------------------*/                     

#define PI_CONTROLLER_DEFAULTS {                \
                                                   0,                         \
                                                   0,                         \
                                                   0,                         \
                                                   1        \
                                                   0,        \
                                                   1,        \
                                                   -1,         \
                                                   0,        \
                                                   0,         \
                                                   0,        \
                                                   0,        \
                                                   0         \
                                        }

/*------------------------------------------------------------------------------
        PI_GRANDO Macro Definition
------------------------------------------------------------------------------*/

#define PI_MACRO(v)                                                                                                \
                                                                                                                                \
        /* proportional term */                                                                         \
        v.up =v.Kp*(v.Ref - v.Fbk));                                                \
                                                                                                                                \
        /* integral term */                                                                                 \
        v.ui = (v.Out == v.v1)?(v.Ki*v.up)+ v.i1) : v.i1;        \
        v.i1 = v.ui;                                                                                                \
                                                                                                                                \
        /* control output */                                                                                 \
        v.v1 = v.up + v.ui;                                                                                        \
        v.Out=v.v1                                               \
        //v.w1 = (v.Out == v.v1) ? _IQ(1.0) : _IQ(0.0);              

//以下为调用:
主函数中先定义PI_CONTROLLER结构体 X
              初始化结构体
              根据结构体中各个成员的含义进行赋值。如设定值,Kp,Ki等。pi参数的设定就要看计算的结果,或者看看网上怎么说。
              主循环中先把采样回来的值赋给Fbk这个成员
              调用PI_MACRO函数 PI_MACRO(X)
              然后取Out的值进行饱和判断
              就可以赋值给真正的输出了。
      这里有一个大坑需要根据你的具体案例做。就是,在定义结构体的时候一定要注意各成员的类型。以防止在运算的时候溢出产生错误。
      我这里定义的结构体中有很多个成员没有使用,你可以删去,不删也没事
回复

使用道具 举报

23

主题

79

帖子

0

精华

高级会员

Rank: 4

积分
607
金钱
607
注册时间
2017-8-8
在线时间
145 小时
 楼主| 发表于 2018-1-12 15:11:51 | 显示全部楼层
jinfeihan57 发表于 2018-1-11 14:33
#ifndef __PI_H__
#define __PI_H__

谢谢,我试试看。。。
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-14 13:51

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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