Proteus仿真温控,AVR输出PWM控制,1602显示。PID学习绝佳范例。
本帖最后由 livingston 于 2012-4-3 12:40 编辑新人发帖混脸熟。【原创属性】
平台和硬件够简单了吧。压缩包内包含全部代码。
代码极其简单,只求让新人工程师们能够看得懂。
双击锅炉,可以设置锅炉参数。
PID三个参数在程序里设置。
在图表上按空格可以绘制温控曲线。修改不同的参数,观察曲线的形状吧。{:lol:}
论坛里的关于PID的理论贴足够多了。此贴只是作为一个具体实现的范例,就不多作赘述了。
锅炉的几个参数简单介绍一下。(热力学的东西其实我不懂,随便说说自己的理解吧)
AT:环境温度(就是室温嘛,好理解)
TRA:环境热阻(热量在热流路径上遇到的阻力,反映介质或介质间的传热能力的大小)
OTC:锅炉热力学时间常数。(不懂,猜想类似于RLC振荡电路中的时间常数,由器件特性唯一决定。大概就是由锅炉的大小,水的多少,这类参量综合决定的一个衡量锅炉热力学特性的常量。求专业解释)
HTC:加热器热力学时间常数。(同上)
TC:温度系数。(输出电压与温度的系数比值。)
HP:加热功率。(加热器的额定功率)
实际上,在现实生活中,上面的大多数参数都是不可知的(测量起来太复杂或者根本就不可测)。
但这正是PID的威力所在,我不需要鸟你这些参数是多少。只需要通过合适的调试方法找到合适的PID三个参数,我就可以做到保持这个系统温度恒定。
求讨论,求高人指点,求新人提问。
学习的实例,要收藏。 收下了哦,{:tongue:} 下载了,谢谢!{:smile:} 留个名,过后向伟大的楼主讨教 这个以前学PID,也是这样模拟过。
Proteus的模拟去PID调节很容易。
实际调节比这个模拟的难点。
你的pid波形,第一个波好高啊 cqv 发表于 2012-4-3 18:31 static/image/common/back.gif
这个以前学PID,也是这样模拟过。
Proteus的模拟去PID调节很容易。
实际调节比这个模拟的难点。
这只是个模拟系统。参数我没有认真去设置。
设置的步骤和实际中一样。有空可以自己调调。{:biggrin:} DDDDDDDDDDDDDDDDDDDDDDD{:victory:}{:victory:}{:victory:} 不错,学习! 顶一个{:smile:} 这个好像很有意思啊!proteus还可以仿真heater呢,开眼见了! 再请问一个问题,heater有一个温度的输出,应该是一个模拟量!请问这个模拟量如何和温度对应起来呢???? xukai871105 发表于 2012-4-5 09:00 static/image/common/back.gif
再请问一个问题,heater有一个温度的输出,应该是一个模拟量!请问这个模拟量如何和温度对应起来呢???? ...
Heater上右侧有个T,就是输出的温度啦。乘以温度系数TC(双击heater设置),就是电压咯。所以接到ATmega16的ADC进行采样转换。 zhifeng 发表于 2012-4-5 08:31 static/image/common/back.gif
顶一个
感动,智峰前辈来顶贴。我是用你的软件长大的。{:biggrin:} 解压出错。 收藏一下啦,谢谢楼主啦!! 收藏 谢谢楼主 看波形参数没设置好,学习可以,实际应用慎之 我改了下参数,看这效果,
这效果不错啊,
就改成
intSetPoint = 500; //设定目标 Desired Value
intProportion = 120; //比例常数 Proportional Const
intIntegral = 1; //积分常数 Integral Const
intDerivative = 0; //微分常数 Derivative Const 本人是新手,求教了 超调量竟达60%…… hjl2832 发表于 2012-4-18 11:04 static/image/common/back.gif
我改了下参数,看这效果,
这效果不错啊,
就改成
你这个无超调,调节时间应该很长吧?!
你好,avr可否用51单片机代换呢,还有不需要用驱动电路吗? 这个很好,学习很好 gdutzl 发表于 2012-4-24 20:57 static/image/common/back.gif
你好,avr可否用51单片机代换呢,还有不需要用驱动电路吗?
当然可以用51代替了。这只是个学习原理的仿真例子,应用于实际肯定要根据需求具体设计检测与驱动电路的。 hjl2832 发表于 2012-4-18 11:04 static/image/common/back.gif
我改了下参数,看这效果,
这效果不错啊,
就改成
不错哦。
更好的学习方法是,导入cof文件仿真运行,单步调试,一步步观察PID参数的变化。 不错,不错。 谢谢楼主了
不错不错,受教了。 非常有用 谢谢 謝謝.研究一下.. 有问题,我是菜鸟,请问这个怎么用,直接调试运行吗?好像波形不会变一样 收藏一下啦,谢谢楼主啦!! 这个不太会用喔,楼主能不能大致讲下怎么用,我是一个大二的菜鸟,刚接触pid,能教下吗{:cry:} {:hug:}{:handshake:}楼主这个帖子太及时了。纠结了好长时间的pid终于有眉目了,灰常感谢哇! gdutzl 发表于 2012-5-4 01:54 static/image/common/back.gif
有问题,我是菜鸟,请问这个怎么用,直接调试运行吗?好像波形不会变一样 ...
你可以修改一下那三个参数,然后仿真看下修改后的变化结果,这样就能大致了解了。 本帖最后由 gdutzl 于 2012-5-15 22:59 编辑
hjl2832 发表于 2012-5-15 09:55 static/image/common/back.gif
你可以修改一下那三个参数,然后仿真看下修改后的变化结果,这样就能大致了解了。 ...
请问是修改什么文件的三个参数,应该导入的是hex文件,但这个文件不可以直接改,是不是pid.c的还是其他的。还有我按空格没有反应的,那个图一点变化都没有 哥,你太牛叉了,请教个问题,你的图还可以在上面添加波形吗? 好像我的图形没变化啊。。。。请求教!!谢谢!! hjl2832 发表于 2012-4-18 11:04 static/image/common/back.gif
我改了下参数,看这效果,
这效果不错啊,
就改成
请问在哪里改参数呢??是hex文件??还是其他的? chanjay 发表于 2012-5-16 23:08 static/image/common/back.gif
好像我的图形没变化啊。。。。请求教!!谢谢!!
我也是,不知道怎么用,求指教 我的版本是7.8的。。怎么防真不出来呢?
{:sad:} hjl2832 发表于 2012-4-18 11:04 static/image/common/back.gif
我改了下参数,看这效果,
这效果不错啊,
就改成
怎么我的防真不出图形的??请指教。。。谢谢!!我用的是7.8版本! PID不复杂,理解最重要。有这个仿真确实是方便了很多。 谢谢,下载收藏了!!!! 温度控制用增量式PID应该是最合适的。谢谢楼主分享。
这个得顶! 本帖最后由 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: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
}
} proteus还可以仿真这个,强悍 livingston 发表于 2012-4-5 09:17 static/image/common/back.gif
Heater上右侧有个T,就是输出的温度啦。乘以温度系数TC(双击heater设置),就是电压咯。所以接到ATmega1 ...
那个Heater右边的T接的电压测试点电压是有效值?当温度为512的时候,电压为2.5左右而那个比例设定是0.1每伏特 想问电压和温度关系如何算出来的
不错的东西 学习。。。。。。。 没用过AVR,PID.C文件就算修改了参数,也没编译软件啊,纠结中。。。。{:mad:} 请教下楼主,积分项是根据总误差 SumError起作用的, SumError是int型,这个值一直增大,会发生溢出,这样的溢出不会影响控制效果吗 貌似不太准确 ICR1H = 0x27;
ICR1L = 0x10;
这个有什么作用? 收藏
留名 等要学的时候在来看看 謝謝.学习.. 顶一下了,支持 mark一下,回去研究研究 曲线咋不变的呢???研究过的人指点下~~~ 请问楼主的程序的编译软件是什么呀? 李志柳 发表于 2013-1-19 11:09 static/image/common/back.gif
请问楼主的程序的编译软件是什么呀?
ICC AVR
凑字数凑字数凑字数 我把你的PID算法改一下,放入我刚开发的产品中,居然能恒温,太神奇了,振荡2次就能稳定了,好东西,给力呀,要是能自动整定“KP,K I ,KD”就更好了, 李志柳 发表于 2013-1-19 15:28 static/image/common/back.gif
我把你的PID算法改一下,放入我刚开发的产品中,居然能恒温,太神奇了,振荡2次就能稳定了,好东西,给力呀 ...
也不是我的算法,从别的地方抄来的。
你可以调节参数,不用震荡2次,以最快的速度,最小超调达到稳定。
自调节PID就要多很多代码了。 好莱坞。 学习一下 PID学了好多遍了 都没搞定。。
收藏一下啦,谢谢楼主 谢谢分享 学习了。不错啊 看到里面的讨论,有受教了。 不错谢谢 下载了,谢谢! 留名,感谢楼主分享这么实在的PID学习方法 下来 看看 怎么样 好贴,顶一下。 很好的东西。先标记下。 好东西 学习了!!! 收藏,学习中; 好资料收藏了 AVR PID 温控 正好用到不错 谢谢!! 谢谢楼主分享,MARK! 这个不错,对新手学习PID很有帮助 huangfan 发表于 2012-5-23 21:33
限于篇幅,显示程序就不贴了
/*ADC采集,单次模式*/
师兄能不你的代码贴上让我们学习下再说你怎么有差分方程运算的 师兄有没有自整定的软件想向你学习 不错,适合拿来学习 不错,谢谢楼主 学习了{:lol:}{:lol:}{:lol:} 谢谢,下载收藏了!!!!
学习了。
页:
[1]