livingston 发表于 2012-4-3 12:33:07

Proteus仿真温控,AVR输出PWM控制,1602显示。PID学习绝佳范例。

本帖最后由 livingston 于 2012-4-3 12:40 编辑

新人发帖混脸熟。【原创属性】

平台和硬件够简单了吧。压缩包内包含全部代码。

代码极其简单,只求让新人工程师们能够看得懂。

双击锅炉,可以设置锅炉参数。

PID三个参数在程序里设置。

在图表上按空格可以绘制温控曲线。修改不同的参数,观察曲线的形状吧。{:lol:}







论坛里的关于PID的理论贴足够多了。此贴只是作为一个具体实现的范例,就不多作赘述了。

锅炉的几个参数简单介绍一下。(热力学的东西其实我不懂,随便说说自己的理解吧)

AT:环境温度(就是室温嘛,好理解)
TRA:环境热阻(热量在热流路径上遇到的阻力,反映介质或介质间的传热能力的大小)
OTC:锅炉热力学时间常数。(不懂,猜想类似于RLC振荡电路中的时间常数,由器件特性唯一决定。大概就是由锅炉的大小,水的多少,这类参量综合决定的一个衡量锅炉热力学特性的常量。求专业解释)
HTC:加热器热力学时间常数。(同上)
TC:温度系数。(输出电压与温度的系数比值。)
HP:加热功率。(加热器的额定功率)

实际上,在现实生活中,上面的大多数参数都是不可知的(测量起来太复杂或者根本就不可测)。

但这正是PID的威力所在,我不需要鸟你这些参数是多少。只需要通过合适的调试方法找到合适的PID三个参数,我就可以做到保持这个系统温度恒定。

求讨论,求高人指点,求新人提问。

xue_pic 发表于 2012-4-3 13:20:45

学习的实例,要收藏。

xjx_bldc_2011 发表于 2012-4-3 16:10:48

收下了哦,{:tongue:}

mtxmxt 发表于 2012-4-3 16:35:28

下载了,谢谢!{:smile:}

fenxiang1103 发表于 2012-4-3 17:04:45

留个名,过后向伟大的楼主讨教

cqv 发表于 2012-4-3 18:31:38

这个以前学PID,也是这样模拟过。
Proteus的模拟去PID调节很容易。
实际调节比这个模拟的难点。
你的pid波形,第一个波好高啊

livingston 发表于 2012-4-3 18:37:02

cqv 发表于 2012-4-3 18:31 static/image/common/back.gif
这个以前学PID,也是这样模拟过。
Proteus的模拟去PID调节很容易。
实际调节比这个模拟的难点。


这只是个模拟系统。参数我没有认真去设置。

设置的步骤和实际中一样。有空可以自己调调。{:biggrin:}

cloudmr01 发表于 2012-4-4 19:12:49

DDDDDDDDDDDDDDDDDDDDDDD{:victory:}{:victory:}{:victory:}

wsm80828 发表于 2012-4-4 19:50:28

不错,学习!

zhifeng 发表于 2012-4-5 08:31:26

顶一个{:smile:}

xukai871105 发表于 2012-4-5 08:57:16

这个好像很有意思啊!proteus还可以仿真heater呢,开眼见了!

xukai871105 发表于 2012-4-5 09:00:35

再请问一个问题,heater有一个温度的输出,应该是一个模拟量!请问这个模拟量如何和温度对应起来呢????

livingston 发表于 2012-4-5 09:17:11

xukai871105 发表于 2012-4-5 09:00 static/image/common/back.gif
再请问一个问题,heater有一个温度的输出,应该是一个模拟量!请问这个模拟量如何和温度对应起来呢???? ...

Heater上右侧有个T,就是输出的温度啦。乘以温度系数TC(双击heater设置),就是电压咯。所以接到ATmega16的ADC进行采样转换。

livingston 发表于 2012-4-5 09:20:55

zhifeng 发表于 2012-4-5 08:31 static/image/common/back.gif
顶一个

感动,智峰前辈来顶贴。我是用你的软件长大的。{:biggrin:}

shotstar 发表于 2012-4-5 09:40:02

解压出错。

heart080811126 发表于 2012-4-6 19:40:56

收藏一下啦,谢谢楼主啦!!

okyinglong 发表于 2012-4-12 21:07:52

收藏 谢谢楼主

guzhongqi 发表于 2012-4-12 21:22:56

看波形参数没设置好,学习可以,实际应用慎之

hjl2832 发表于 2012-4-18 11:04:32

我改了下参数,看这效果,
这效果不错啊,
就改成
intSetPoint = 500;         //设定目标 Desired Value
intProportion = 120;         //比例常数 Proportional Const
intIntegral = 1;             //积分常数 Integral Const
intDerivative = 0;         //微分常数 Derivative Const

轩仔 发表于 2012-4-19 22:42:05

本人是新手,求教了

xulong20006 发表于 2012-4-21 11:27:00

超调量竟达60%……

xulong20006 发表于 2012-4-21 11:27:59

hjl2832 发表于 2012-4-18 11:04 static/image/common/back.gif
我改了下参数,看这效果,
这效果不错啊,
就改成


你这个无超调,调节时间应该很长吧?!

gdutzl 发表于 2012-4-24 20:57:00


你好,avr可否用51单片机代换呢,还有不需要用驱动电路吗?

DoubleE 发表于 2012-4-25 11:08:28

这个很好,学习很好

livingston 发表于 2012-4-25 20:27:06

gdutzl 发表于 2012-4-24 20:57 static/image/common/back.gif
你好,avr可否用51单片机代换呢,还有不需要用驱动电路吗?

当然可以用51代替了。这只是个学习原理的仿真例子,应用于实际肯定要根据需求具体设计检测与驱动电路的。

livingston 发表于 2012-4-25 20:29:08

hjl2832 发表于 2012-4-18 11:04 static/image/common/back.gif
我改了下参数,看这效果,
这效果不错啊,
就改成


不错哦。
更好的学习方法是,导入cof文件仿真运行,单步调试,一步步观察PID参数的变化。

lsy5110 发表于 2012-4-25 21:43:45

不错,不错。

xdyyy0508 发表于 2012-4-27 11:28:54

谢谢楼主了

heimantou 发表于 2012-4-27 17:23:12

不错不错,受教了。

yinnianlong 发表于 2012-4-27 20:50:15

非常有用 谢谢

et009.tw 发表于 2012-4-28 08:30:31

謝謝.研究一下..

gdutzl 发表于 2012-5-4 01:54:59

有问题,我是菜鸟,请问这个怎么用,直接调试运行吗?好像波形不会变一样

wthzack 发表于 2012-5-4 02:21:04

收藏一下啦,谢谢楼主啦!!

gdutzl 发表于 2012-5-4 13:00:23

这个不太会用喔,楼主能不能大致讲下怎么用,我是一个大二的菜鸟,刚接触pid,能教下吗{:cry:}

371278638 发表于 2012-5-12 18:09:32

{:hug:}{:handshake:}楼主这个帖子太及时了。纠结了好长时间的pid终于有眉目了,灰常感谢哇!

hjl2832 发表于 2012-5-15 09:55:53

gdutzl 发表于 2012-5-4 01:54 static/image/common/back.gif
有问题,我是菜鸟,请问这个怎么用,直接调试运行吗?好像波形不会变一样 ...

你可以修改一下那三个参数,然后仿真看下修改后的变化结果,这样就能大致了解了。

gdutzl 发表于 2012-5-15 22:56:32

本帖最后由 gdutzl 于 2012-5-15 22:59 编辑

hjl2832 发表于 2012-5-15 09:55 static/image/common/back.gif
你可以修改一下那三个参数,然后仿真看下修改后的变化结果,这样就能大致了解了。 ...

请问是修改什么文件的三个参数,应该导入的是hex文件,但这个文件不可以直接改,是不是pid.c的还是其他的。还有我按空格没有反应的,那个图一点变化都没有

huangfan 发表于 2012-5-16 23:05:00

哥,你太牛叉了,请教个问题,你的图还可以在上面添加波形吗?

chanjay 发表于 2012-5-16 23:08:42

好像我的图形没变化啊。。。。请求教!!谢谢!!

gdutzl 发表于 2012-5-17 00:28:28

hjl2832 发表于 2012-4-18 11:04 static/image/common/back.gif
我改了下参数,看这效果,
这效果不错啊,
就改成


请问在哪里改参数呢??是hex文件??还是其他的?

gdutzl 发表于 2012-5-17 00:29:07

chanjay 发表于 2012-5-16 23:08 static/image/common/back.gif
好像我的图形没变化啊。。。。请求教!!谢谢!!

我也是,不知道怎么用,求指教

chanjay 发表于 2012-5-17 19:54:57

我的版本是7.8的。。怎么防真不出来呢?
{:sad:}

chanjay 发表于 2012-5-17 19:56:18

hjl2832 发表于 2012-4-18 11:04 static/image/common/back.gif
我改了下参数,看这效果,
这效果不错啊,
就改成


怎么我的防真不出图形的??请指教。。。谢谢!!我用的是7.8版本!

蜂巢 发表于 2012-5-17 20:09:33

PID不复杂,理解最重要。有这个仿真确实是方便了很多。

bacon 发表于 2012-5-21 19:31:02

谢谢,下载收藏了!!!!

LDMega 发表于 2012-5-21 19:41:54

温度控制用增量式PID应该是最合适的。谢谢楼主分享。

szxszx 发表于 2012-5-21 19:52:34

这个得顶!

huangfan 发表于 2012-5-23 21:27:15

本帖最后由 huangfan 于 2012-5-23 21:44 编辑

首先感谢楼主的设计实例,使我受益良多,就是根据楼主提供的Proteus模型,我自己重新用GCC写了一个程序。因为已经5年没写程序了,每天下班后的全部时间都用来研究这个东东,每天都要凌晨1点多才能睡觉,还好,只用了一周的时间就小有成果,很开心。我是个做开关电源的,最近半年做一个3KW的全数字开关电源,芯片用的是TI的TMS32C2XXX系列。因为和软件同事配合一起研究了几个月的数字PID。自认为已经掌握了“核心科技”。现在利用楼主的电路小试牛刀,感觉很满意。愿意和大家一起讨论,欢迎拍砖。我没有修改加热器的任何参数,效果如下
算法参数1:Un=Un_1+1800.002*en-1799.998*en_1;

算法参数2:Un=Un_1+1800.005*en-1799.995*en_1;


楼主的波形:


要是有更好的控制方式请赐教。

huangfan 发表于 2012-5-23 21:33:37

本帖最后由 huangfan 于 2012-5-23 21:36 编辑

限于篇幅,显示程序就不贴了

/*ADC采集,单次模式*/
uint Adconvert()
{
    uint ret;
       
        SREG=0x80;                                    // 全局中断使能
        ADMUX=0xC0;                                 //内部2.56V,0通道
        //ADCSRA=_BV(ADEN)|_BV(ADSC)|_BV(ADFR)|_BV(ADIE)|_BV(ADPS2)|_BV(ADPS1);   
             //ADC使能,开始转换,连续转换,中断使能,,CK/64 8M/64=125KHz ,125KHz-8us,8us*13=104us 采样频率9.615KHz
    ADCSRA=_BV(ADEN)|_BV(ADSC)|_BV(ADPS2)|_BV(ADPS1);
             //ADC使能,开始转换,CK/64 8M/64=125KHz ,125KHz-8us,8us*25=200us
               
                //连续转换1次
                        PORTD|=_BV(PD0);                      //PD0 置0                                                            测试AD转换时间
                DDRD|=_BV(PD0);                     //PD0 设输出
                        //_delay_loop_1(60);
                        while(ADCSRA&_BV(ADSC))
                        //_delay_loop_1(60);
                        _delay_us(1);                         //采样保持时间〉1.5个ADC周期
                        ret=ADCL;
                        ret|=(uint)(ADCH<<8);
                       
                        PORTD&=~_BV(PD0);                     //PD0 置0
               
                SREG=0x80;                                       //开总中断
                ADCSRA=0;                                  //关闭ADC

        return(ret);
}

/*差分方程运算*/
SIGNAL(SIG_OUTPUT_COMPARE2)                     //INTERRUPT
{
        //int32_t Vref=2500;                        //Vref=Ref*2.5=400*2.5=2.000V   
        //int32_t Ref=Vref/2.5;
        int32_t Ref=999;
        en=Ref-Adconvert();
               
        PORTD|=_BV(PD1);                              //示波器测试点开                                                      测试计算时间
        DDRD=_BV(PD1)|_BV(PD5)|_BV(PD6);
       
                en=en<<10;                              //en左移10位,相当于乘以1024
                Un=Un_1+1800.005*en-1799.995*en_1;      //差分方程
        if(Un<0)                                    //设置最小占空比
        {Un=2;}
       
        else if(Un>1020*1024)                         //设置最大占空比
        {Un=1020*1024;}
       
        //else
        //{Un=Un;}
       
                Un_1=Un;
                en_1=en;
                y=Un>>10;
                OCR1A=y;                                 // 设置PWM占空比               
               
        PORTD&=~_BV(PD1);                                   //示波器测试点关                      
                y=2.5*y;
       
      NO1=y/1000;
                NO2=(y-=NO1*1000)/100;
                NO3=(y-=NO2*100)/10;
                NO4=(y-=NO3*10);
       
}


void main(void)
{
        uint i,t;
    init_devices();
        LCD_write_command(0x01);                        //清屏
       
        /*配置C/T2为CTR模式*/
        TCNT2=0x00;                        //设初始值为0,
        OCR2=255;         //输出比较寄存器            //产生频率为1/[(OCR2+1)*4uS]
        TCCR2|=_BV(WGM21)|_BV(CS21)|_BV(CS20);                //C/T2中断,CTC模式,clk/64 产生周期 T=(OCR2+1)*(64/(2*8MHz))=(OCR2+1)*4uS
        TIMSK|=_BV(OCIE2);        //T/C2溢出中断使能
       
        /*配置C/T1为快速PWM模式*/
        //TCCR1A=_BV(COM1A1)|_BV(COM1A0)|_BV(WGM10);        //比较匹配时,OCnA输出高电平,8位快速PWM,模式 5
        TCCR1A=_BV(COM1A1)|_BV(WGM11)|_BV(WGM10);                //比较匹配时,OCnA输出高电平,10位快速PWM,模式 5
        TCCR1B=_BV(WGM12)|_BV(CS10);                                        //无预分频,8MHz/1024=7.813KHz
        TCNT1=0;                                        //与OCR1A进行匹配的计数寄存器
    SREG=0x80;                                        //开总中断
   
        DDRB|=_BV(PD5);                                        //设PD5为PWM输出       

   while(1)
   {   
                LCD_write_command(0x0c);                                        //显示开
                LCD_write_string(0,0,"Voltage");                 //第1列,第0行,显示"Voltage"
               
                uchar a[]="0123456789.";                                        //要显示数放在a[]中

                LCD_write_char(0,1,a);                               //第0列,第1行,
                LCD_write_char(1,1,a);                               //第1列,第1行,
                LCD_write_char(2,1,a);                               //第2列,第1行,显示"."
                LCD_write_char(3,1,a);                               //第3列,第1行,
                LCD_write_char(4,1,a);                       //第4列,第1行,
                /* delay time is 20ms*25=500ms */
                for(i=1;i<1;i++)
                        //_delay_us(20);                        //The maximal possible delay is 768 us / F_CPU in MHz .    768us/8   =96us
                        _delay_ms(100);                        //The maximal possible delay is 262.14 ms / F_CPU in MHz.262.14ms/8=32.767ms
    }
   
}

ylei12 发表于 2012-5-23 21:38:30

proteus还可以仿真这个,强悍

QQ373466062 发表于 2012-5-24 22:46:29

livingston 发表于 2012-4-5 09:17 static/image/common/back.gif
Heater上右侧有个T,就是输出的温度啦。乘以温度系数TC(双击heater设置),就是电压咯。所以接到ATmega1 ...

那个Heater右边的T接的电压测试点电压是有效值?当温度为512的时候,电压为2.5左右而那个比例设定是0.1每伏特 想问电压和温度关系如何算出来的

raojialong1988 发表于 2012-5-31 17:12:09

不错的东西

fox8769 发表于 2012-7-4 20:14:06

学习。。。。。。。

Gloome 发表于 2012-7-27 21:00:40

没用过AVR,PID.C文件就算修改了参数,也没编译软件啊,纠结中。。。。{:mad:}

acai039033 发表于 2012-7-30 10:36:03

请教下楼主,积分项是根据总误差 SumError起作用的, SumError是int型,这个值一直增大,会发生溢出,这样的溢出不会影响控制效果吗

johngundam 发表于 2012-8-3 08:54:26

貌似不太准确

jin 发表于 2012-8-3 20:47:01

ICR1H = 0x27;         
ICR1L = 0x10;
这个有什么作用?

小默 发表于 2012-8-4 12:04:06

收藏   

wubingqp 发表于 2012-8-4 12:49:23

留名   等要学的时候在来看看

ls81250 发表于 2012-11-21 23:53:50

謝謝.学习..

YOU1 发表于 2012-12-1 16:10:57

顶一下了,支持

52171314 发表于 2012-12-9 17:43:50

mark一下,回去研究研究

zhanyanqiang 发表于 2012-12-9 19:11:00

曲线咋不变的呢???研究过的人指点下~~~

李志柳 发表于 2013-1-19 11:09:29

请问楼主的程序的编译软件是什么呀?

livingston 发表于 2013-1-19 11:37:48

李志柳 发表于 2013-1-19 11:09 static/image/common/back.gif
请问楼主的程序的编译软件是什么呀?

ICC AVR

凑字数凑字数凑字数

李志柳 发表于 2013-1-19 15:28:45

我把你的PID算法改一下,放入我刚开发的产品中,居然能恒温,太神奇了,振荡2次就能稳定了,好东西,给力呀,要是能自动整定“KP,K I ,KD”就更好了,

livingston 发表于 2013-1-19 15:42:32

李志柳 发表于 2013-1-19 15:28 static/image/common/back.gif
我把你的PID算法改一下,放入我刚开发的产品中,居然能恒温,太神奇了,振荡2次就能稳定了,好东西,给力呀 ...

也不是我的算法,从别的地方抄来的。

你可以调节参数,不用震荡2次,以最快的速度,最小超调达到稳定。

自调节PID就要多很多代码了。

liubinghui 发表于 2013-1-23 11:35:35

   好莱坞。

yulijie 发表于 2013-1-25 21:58:47

学习一下 PID学了好多遍了 都没搞定。。

libitao 发表于 2013-1-27 13:10:52


收藏一下啦,谢谢楼主

zhangfuhg 发表于 2013-3-6 22:59:32

谢谢分享

cuikai12345 发表于 2013-3-12 22:19:27

学习了。不错啊

dilongsong 发表于 2013-3-18 15:37:10

看到里面的讨论,有受教了。

hamipeter 发表于 2013-3-18 20:17:49

不错谢谢

pidaneng1 发表于 2013-10-28 00:56:45

下载了,谢谢!

wyshrs 发表于 2013-11-1 20:11:32

    留名,感谢楼主分享这么实在的PID学习方法

yaonen 发表于 2013-11-6 09:37:58

下来 看看 怎么样

helh 发表于 2013-12-17 21:51:24

好贴,顶一下。

stevenniu500 发表于 2013-12-18 17:48:48

很好的东西。先标记下。

ljh407055315 发表于 2013-12-29 15:53:19

好东西 学习了!!!

BruceZeng 发表于 2014-3-6 10:19:42

收藏,学习中;

muyejingfeng 发表于 2014-3-20 16:47:58

好资料收藏了   AVR PID 温控                                                                                                         

kihell 发表于 2014-9-2 21:04:31

正好用到不错 谢谢!!

iirfw 发表于 2014-11-14 13:38:13

谢谢楼主分享,MARK!

Ca_guo 发表于 2014-11-14 13:41:31

这个不错,对新手学习PID很有帮助

chunyu 发表于 2015-4-9 09:15:57

huangfan 发表于 2012-5-23 21:33
限于篇幅,显示程序就不贴了

/*ADC采集,单次模式*/


师兄能不你的代码贴上让我们学习下再说你怎么有差分方程运算的

chunyu 发表于 2015-4-9 09:33:17

师兄有没有自整定的软件想向你学习

shuen729 发表于 2015-8-17 16:41:53

不错,适合拿来学习

yanzhiwei 发表于 2015-11-25 11:21:43

不错,谢谢楼主

茂实科技 发表于 2017-8-1 22:21:58

学习了{:lol:}{:lol:}{:lol:}

stewen 发表于 2017-8-28 19:56:00

谢谢,下载收藏了!!!!

学习了。
页: [1]
查看完整版本: Proteus仿真温控,AVR输出PWM控制,1602显示。PID学习绝佳范例。