amoBBS ladbrokes立博论坛

 找回密码
 注册
搜索
bottom↓
查看: 5594|回复: 48
打印 上一主题 下一主题

PWM模拟DAC电压输出-PID仿真贴

  [复制链接]
跳转到指定楼层
1
发表于 2013-10-26 10:58:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
为了学习PID是怎么回事,特别做了此仿真,呵呵, 也可以说是<如何让PID的值转换成PWM的占空比>!

本人之前对PID一点都不懂,此贴主要是和大家分享学习经验!呵呵, 菜鸟贴, 不对的地方请大家拍砖!

此仿真采用的是PIC单片机, 由P1A引脚输出PWM,经过RC滤波后输出电压,AN0  ADC采样


先贴图吧!
PID算法是用的AVR: AVR221: Discrete PID controller 中的源码
//VFER = 2.048v, 10位分辨率(1024),设定稳压电压是1.024v


在此做几点说明:
1、设置P 、 I 、D

/*! \brief P, I and D parameter values
*
* The K_P, K_I and K_D values (P, I and D gains)
* need to be modified to adapt to the application at hand
*/
//! \xrefitem todo "Todo" "Todo list"
#define K_P     9.00
//! \xrefitem todo "Todo" "Todo list"
#define K_I     0.1
//! \xrefitem todo "Todo" "Todo list"
#define K_D     0.02



2、PID 方法调用

            //512-设定值
            GL(pid_Controller(512, adc_vlue, &pidData)); //VFER = 2.048v, 10位分辨率(1024),设定稳压电压是1.024v

3、ADC采样周期及PID控制周期

ADC 每100us采样一样,采用中位值滤波法
PID每1ms转换一次



最后........
上源码:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
2
 楼主| 发表于 2013-10-26 11:30:58 | 只看该作者
下面是两种常见算法的PID仿真图表:
#ifndef __PID_1_H
#define __PID_1_H

typedef struct PID
{   
        double  SetPoint;           //  设定目标 Desired Value   
       
        double  Proportion;         //  比例常数 Proportional Const   
        double  Integral;           //  积分常数 Integral Const   
        double  Derivative;         //  微分常数 Derivative Const   
       
        double  LastError;          //  Error[-1]   
        double  PrevError;          //  Error[-2]   
        double  SumError;           //  Sums of Errors   

}PID;   

extern void PIDInit(PID *pp);
extern double PIDCalc(PID *pp, double NextPoint);
#endif


#include "pid_1.h"
#include <string.h>

void PIDInit(PID *pp)
{   
    memset(pp, 0, sizeof(PID));   
}   

double PIDCalc(PID *pp, double NextPoint)//这里是位置式算法   
{   
    double  dError, Error;   
   
    Error = pp->SetPoint -  NextPoint;          // 偏差,   偏差=设定值-返回值
    pp->SumError += Error;                      // 积分项, 偏差和   
    dError = pp->LastError - pp->PrevError;     // 微分项  上一次误差-上上一次误差   
    pp->PrevError = pp->LastError;   
    pp->LastError = Error;   
    return (pp->Proportion * Error              // 比例项   
        +   pp->Integral * pp->SumError         // 积分项   
        +   pp->Derivative * dError             // 微分项   
    );   
}   




///

#include "pid_1.h"
#include <string.h>

void PIDInit(PID *pp)
{   
    memset(pp, 0, sizeof(PID));   
}   

double PIDCalc(PID *pp, double NextPoint)//这里增量式的算法   
{   
    double dError, Error;

    Error = pp->SetPoint - NextPoint;                       //偏差
    pp->SumError += Error;                                  //积分
    dError =pp->SumError-2*pp->LastError + pp->PrevError;   //当前微分
   
    pp->PrevError = pp->LastError;
    pp->LastError = Error;
   
    return (pp->Proportion * Error                          //比例项
            +pp->Integral * pp->SumError                    //积分项
            +pp->Derivative * dError                        //微分项
    );   
}   




本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
3
发表于 2013-10-27 11:29:24 | 只看该作者
mark,学习看看,thanks
4
发表于 2013-11-13 21:18:44 | 只看该作者
看了你的PID模拟DAC,现在自己也想做个。是这样的,我想通过单片机PWM去控制输出电压,恒定在一个值,比如输入14-19V,控制输出恒定在13V,通过单片机去读取输出电压。用你的方法可以实现吗。硬件的话就是采用简单的MOS管控制
5
发表于 2013-11-13 21:46:56 | 只看该作者
usm4glx 发表于 2013-11-13 21:18
看了你的PID模拟DAC,现在自己也想做个。是这样的,我想通过单片机PWM去控制输出电压,恒定在一个值,比如 ...

增量式PID算法

以这个为关键词搜索就行了
6
发表于 2013-11-13 21:59:20 | 只看该作者
rclong 发表于 2013-11-13 21:46
增量式PID算法

以这个为关键词搜索就行了

o,只要理论上可以实现,方法我自己可以搞定的。反馈值就是采样输出电压,这样设定值与采样值比较,应该就可以实现了吧
7
发表于 2013-11-14 08:01:58 来自手机 | 只看该作者
好帖,很容易就看懂了
8
 楼主| 发表于 2013-11-14 08:46:02 | 只看该作者
usm4glx 发表于 2013-11-13 21:18
看了你的PID模拟DAC,现在自己也想做个。是这样的,我想通过单片机PWM去控制输出电压,恒定在一个值,比如 ...

可以!
9
发表于 2013-11-14 09:15:02 | 只看该作者
增量式PID算法
10
发表于 2013-11-14 09:47:47 | 只看该作者
好久没碰着这个了
11
发表于 2013-11-14 09:48:23 | 只看该作者
谢谢楼主,正需要pid呢
12
发表于 2013-11-14 17:20:47 | 只看该作者
请教
仿真有较大过冲是因为采集速度与PID速度快的原因么?
13
 楼主| 发表于 2013-11-15 11:07:37 | 只看该作者
一是反馈速度,二是P的值

上图就是减小了P的值,过冲明显小了!

当然,采用何种算法也是一个因素, 以上所得的结果都是软件仿真的结果,目前我还没有实际操作过!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
14
发表于 2013-11-15 12:04:10 | 只看该作者
此帖很好。
提醒楼主,告知大家,仿真文件是在 Proteus 的哪个版本下建立的,是非常必要的。

15
 楼主| 发表于 2013-11-15 14:42:29 | 只看该作者
7.8sp2                       
16
发表于 2013-11-15 15:51:24 | 只看该作者
skype 发表于 2013-11-15 11:07
一是反馈速度,二是P的值

上图就是减小了P的值,过冲明显小了!

这个过冲更小吧。



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
17
 楼主| 发表于 2013-11-15 16:28:02 | 只看该作者
是呀,你用的是上面的算法吗?
那一个?
18
 楼主| 发表于 2013-11-15 16:31:48 | 只看该作者
JQ_Lin 发表于 2013-11-15 15:51
这个过冲更小吧。

呵呵!很不错,请把调节的过程共享一下!
19
发表于 2013-11-17 23:53:32 | 只看该作者
skype 发表于 2013-11-15 16:31
呵呵!很不错,请把调节的过程共享一下!

哈哈,我不懂C,没动代码,随便改了一下电路参数而已。

20
发表于 2013-11-18 00:10:49 | 只看该作者
楼主的仿真文件版本是 Proteus ISIS 7.8sp2。
没有安装 7.8sp2 及其以上版本的网友,只要把下面的 Pic16ex.dll 模型文件复制到你的低版本(例如7.5sp3)的 MODELS 文件夹中,即可运行楼主提供的仿真文件 Demo.dsn 了。

下载 Pic16ex.dll.rar 压缩文件后,不要解压!!
去除 .rar 扩展名,即是 Pic16ex.dll 模型文件。



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
21
发表于 2013-11-18 08:11:26 | 只看该作者
O(∩_∩)O谢谢分享
22
发表于 2013-11-18 08:16:25 | 只看该作者
留个记号
23
 楼主| 发表于 2013-11-18 10:22:48 | 只看该作者
JQ_Lin 发表于 2013-11-17 23:53
哈哈,我不懂C,没动代码,随便改了一下电路参数而已。

高,实在是高!
24
发表于 2013-11-18 14:15:05 | 只看该作者
mark         
25
发表于 2013-11-19 08:54:28 | 只看该作者
skype 发表于 2013-11-15 14:42
7.8sp2

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
26
发表于 2013-11-20 20:12:59 | 只看该作者
rclong 发表于 2013-11-13 21:46
增量式PID算法

以这个为关键词搜索就行了

呵呵,没有用,看了下,PID参数太难调了,直接放弃了
27
发表于 2013-11-24 22:09:36 | 只看该作者
很好,正想学习
28
发表于 2013-11-29 10:57:36 | 只看该作者
skype 发表于 2013-10-26 11:30
下面是两种常见算法的PID仿真图表:
#ifndef __PID_1_H
#define __PID_1_H


楼主,你这块增量式的算法有问题吧,,,微分项那块应该是此次误差-2*上次误差+上上次误差。。

还有你返回的值应该加上次计算出来的值吧。。。
29
发表于 2013-11-29 11:07:34 | 只看该作者
R88 发表于 2013-11-29 10:57
楼主,你这块增量式的算法有问题吧,,,微分项那块应该是此次误差-2*上次误差+上上次误差。。

还有你返 ...

你的位置和增量都混乱了吧:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
30
发表于 2013-11-29 11:09:05 | 只看该作者
过冲过大,可能是C5-10uf的滞后最用太强了,,把那个C5去掉过冲就应该小了。。
31
 楼主| 发表于 2013-11-29 14:54:38 | 只看该作者
那两个PID算法是在本坛上找的,拿来就用,没有细研究过,也没有做过相关项目,只是想了解一下PID是怎么回事而已!
32
发表于 2014-3-12 12:04:27 | 只看该作者
学习看看!!!!!!正好需要
33
发表于 2014-7-15 11:20:37 | 只看该作者
楼主的pic16f1827是用哪个版本的MAPLAB环境?
34
发表于 2014-8-25 12:29:28 | 只看该作者
待会儿用stm32f103试试看,这会儿主要需要外围滤波电路。
35
发表于 2015-8-10 00:26:53 | 只看该作者
学习看看!吸收一下
36
发表于 2015-8-10 09:27:44 | 只看该作者
37
发表于 2015-8-10 20:34:36 | 只看该作者
学习看看!!!!!!正好需要
38
发表于 2015-8-10 22:11:27 来自手机 | 只看该作者
学习,留个记号
39
发表于 2015-8-13 14:12:54 | 只看该作者
MARK                  
40
发表于 2015-8-27 16:23:36 | 只看该作者
谢谢楼主。好东西,收了。
41
 楼主| 发表于 2017-11-15 16:02:22 | 只看该作者
今天终于用上PID了,调节电机输出功率。
42
发表于 2017-11-15 16:33:17 来自手机 | 只看该作者
skype 发表于 2017-11-15 16:02
今天终于用上PID了,调节电机输出功率。

效果如何,少年
43
 楼主| 发表于 2017-11-15 16:35:49 | 只看该作者
满意,和仿真结果基本一样。只是PID参数有点修改
44
 楼主| 发表于 2017-11-15 16:39:48 | 只看该作者


#define K_P     1.0
//! \xrefitem todo "Todo" "Todo list"
#define K_I     0.01
//! \xrefitem todo "Todo" "Todo list"
#define K_D     1.0

实际运行还行,用于空气净化器电机驱动,来控制电机运行时的功率!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
45
发表于 2017-11-15 16:53:28 | 只看该作者
skype 发表于 2017-11-15 16:39
#define K_P     1.0
//! \xrefitem todo "Todo" "Todo list"
#define K_I     0.01

用的楼主的代码和仿真文件?
46
 楼主| 发表于 2017-11-16 08:31:33 | 只看该作者
是的                              
47
发表于 2018-10-9 18:26:34 | 只看该作者
温故而知新
48
发表于 2018-10-9 18:38:56 | 只看该作者
刚好需要研究下PID,很好的资料,收藏先,谢谢楼主
49
发表于 2019-6-21 16:04:53 | 只看该作者
一直响学习下PID,留个记号。
友情提示:标题不合格、重复发帖,将会被封锁ID。详情请参考:论坛通告:封锁ID、获得注册邀请码、恢复被封ID、投诉必读
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|ladbrokes立博论坛(原ourAVR/ourDEV) ( 公安备案:44190002001997(交互式论坛) 工信部备案:粤ICP备09047143号 )

GMT+8, 2019-7-6 06:08

ladbrokes立博论坛, 原"中国电子开发网"

© 2004-2018 www.4op7mp.com, 原www.ourdev.cn, 原www.ouravr.com

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