基于AVR ATMega16 的PID 控制算法程序

发布者:EternalWhisper最新更新时间:2016-09-18 来源: eefocus关键字:AVR  ATMega16  PID  控制算法 手机看文章 扫描二维码
随时随地手机看文章
最近由于有些时间,于是想起了做一个PID设计,在网上收集了不少关于PID控制的理论,于是计划用mega16L做一个PID测试程序,发现一些意想不到的误差,不知各位同仁是否有遇到与我的类似的现象:我定义了一个PID结构体,在初始化的时候无法把每个元素的初始化值设置为0(见下面的仿真图),而且,PID结构体中的部分参数是应该不变的,在整个PID运算中,但是不应该变化的参数却在PID运算发生了变化,不知道是什么原因,到现在也无法查出原因。有兴趣的朋友可以一起参与讨论或有经验的朋友 给与相关帮助,谢谢!
详细的代码和仿真情况如下:(我的硬件系统是本站的min Mega16/32 + JTAG ICE)
  1. #include "config.h"
  2.  
  3. struct _PID
  4. {
  5. float PVn; //反馈信号变量
  6. float SPn; //设定值
  7. float Mn; //PID运算结果
  8. float Kc;     //比例系数
  9. float Ts;     //采样时间(ms)
  10. float Ti;     //积分时间(ms)
  11. float Td;     //微分时间(ms)
  12. float Mx; //积分项调整参数
  13. float PVn_1;//前一次反馈变量
  14. float MPn; //比例项的结果值
  15. float MIn; //积分项的结果值
  16. float MDn; //微分项的结果值
  17. };
  18.  
  19. struct _PID *myPID;
  20. void init_myPID(void);
  21. void init_ports(void);
  22. void init_device(void);
  23. float MPn_value(struct _PID *PID);
  24. float MIn_value(struct _PID *PID);
  25. float MDn_value(struct _PID *PID);
  26. float Mx_value(struct _PID *PID);
  27. float Mn_value(struct _PID *PID);
  28.  
  29.  
  30. void main (void)
  31. {
  32. init_device();
  33. init_myPID();
  34.  
  35. myPID->SPn = 155.5;
  36. myPID->Kc = 13.2;
  37. myPID->Ts = 0.2;
  38. myPID->Ti = 600.0;
  39. myPID->Td = 0.0;
  40. myPID->PVn = 108.2;
  41.  
  42.  
  43. while(1)
  44. {
  45. myPID->MPn = MPn_value(myPID);
  46. myPID->MDn = MDn_value(myPID);
  47. myPID->Mx = Mx_value(myPID);
  48. myPID->MIn = MIn_value(myPID);
  49. myPID->Mn = Mn_value(myPID);
  50. myPID->PVn_1 = myPID->PVn;
  51. }
  52.  
  53. }
  54.  
  55. /******************************************************************************/
  56. void init_myPID(void)
  57. {
  58. myPID->PVn = 0.0;
  59. myPID->SPn = 0.0;
  60. myPID->Mn = 0.0;
  61. myPID->Kc = 0.0;
  62. myPID->Ts = 0.0;
  63. myPID->Ti = 0.0;
  64. myPID->Td = 0.0;
  65. myPID->Mx = 0.0;
  66. myPID->PVn_1 = 0.0;
  67. myPID->MPn = 0.0;
  68. myPID->MIn = 0.0;
  69. myPID->MDn = 0.0;
  70. }
  71.  
  72. //------------------------------------------------------------------------------
  73. void init_ports(void)
  74. {
  75. PORTA = 0x00; //If ADC Function was be used,the PORTA could`t set bit 1
  76. DDRA = 0x00; //the port set input mode.
  77. PORTB = 0x00;
  78. DDRB = 0x00;
  79. PORTC = 0x00; //m103 output only
  80. DDRC = 0x00;
  81. PORTD = 0x00;
  82. DDRD = 0x00;
  83. }
  84.  
  85. //------------------------------------------------------------------------------
  86. void init_device(void)
  87. {
  88. CLI();
  89. init_ports();
  90. MCUCR = 0x00; //Set Power control(State:Close)
  91. GICR = 0x00; //Set boot guide(State:Close).
  92. SEI(); //re-enable interrupts
  93. //all peripherals are now initialized
  94. }
  95.  
  96.  
  97. // 计算 比例项的值
  98. //------------------------------------------------------------------------------
  99. float MPn_value(struct _PID *PID)
  100. {
  101. float myMPn = 0.0;
  102. myMPn = PID->Kc *( PID->SPn - PID->PVn);
  103. return myMPn;
  104. }
  105.  
  106. //计算积分项的值
  107. //------------------------------------------------------------------------------
  108. float MIn_value(struct _PID *PID)
  109. {
  110. float myMIn = 0.0;
  111. myMIn = PID->Kc*(PID->Ts/PID->Ti)*(PID->SPn - PID->PVn) + PID->Mx;
  112. return myMIn;
  113. }
  114.  
  115.  
  116. //计算微分项的值
  117. //------------------------------------------------------------------------------
  118. float MDn_value(struct _PID *PID)
  119. {
  120. float myMDn = 0.0;
  121. myMDn = PID->Kc * (PID->Td/PID->Ts) * (PID->PVn_1 - PID->PVn);
  122. return myMDn;
  123. }
  124.  
  125. //计算PID的结果
  126. //------------------------------------------------------------------------------
  127. float Mn_value(struct _PID *PID)
  128. {
  129. float myMn = 0.0;
  130. myMn = PID->MPn + PID->MIn + PID->MDn;
  131. return myMn;
  132. }
  133.  
  134. //计算积分项的调整值
  135. //------------------------------------------------------------------------------
  136. float Mx_value(struct _PID *PID)
  137. {
  138. float myMx = 0.0;
  139. if(PID->Mn > 1.0)
  140.    {
  141.    myMx = 1.0 - (PID->MPn + PID->MDn);
  142.    }
  143. else if(PID->Mn < 0.0)
  144.    {
  145.    myMx = -(PID->MPn + PID->MDn);
  146.    }
  147. return myMx;
  148. }

 

 

基于AVR ATMega16 的PID 控制算法程序 - 风雨里 - 风雨里的博客

运行到PID初始化函数:void init_myPID(void)时的仿真结果如下:无法全部初始化为0

 

 

基于AVR ATMega16 的PID 控制算法程序 - 风雨里 - 风雨里的博客

运行到:
myPID->SPn = 155.5;
   myPID->Kc = 13.2;
   myPID->Ts = 0.2;
   myPID->Ti = 600.0;
   myPID->Td = 0.0;
   myPID->PVn = 108.2;

重新赋值后,部分参数Ts并不为0.2

关键字:AVR  ATMega16  PID  控制算法 引用地址:基于AVR ATMega16 的PID 控制算法程序

上一篇:AVR ISP下载线在AVR Studio环境下的下载方法
下一篇:avr中断使用例子

推荐阅读最新更新时间:2024-03-16 15:10

基于AVR微控制器的蓄电池充放电控制器的设计
摘要: 针对539CH-1型Ni-Cd电池,提出一种基于 AVR 微控制器的蓄电池充、放电控制器。该控制器以Mega16L为核心,根据上位机的命令控制蓄电池的充、放电电流值以及放电电阻的接入时机。 关键词: 蓄电池; AVR 微控制器;TLV5638;电源控制 引言   蓄电池是飞行器电源系统中重要的组成部分,蓄电池的性能直接影响飞行器的安全。因此,正确维护、保养蓄电池就成为一项十分重要的工作。539CH-1型Ni-Cd蓄电池是法国SAFT公司生产的碱性蓄电池,该电池包含20个单体电池,额定电压24V,额定容量53Ah。波音737客机即采用该型蓄电池。   充电和放电是该电池维护、保养中的主要工作。由于该电池为Ni-Cd
[单片机]
基于<font color='red'>AVR</font>微控制器的蓄电池充放电控制器的设计
应用AVR单片机制作电子打铃仪的思路
AVR具有512个字节的片内EEPROM,利用它可以记录事先设定的打铃时间(如果每个时间条需要2个字节,则存储的时间条可以200多个),然后将AVR制作成电子钟,在某个时间内,扫描并取出片内存储的时间条,与当前时间进行对比,如果吻合,则打铃。 下面是打铃仪(成熟产品)的具体设计思路: 1、硬件方面:用有备用电池供电的日历芯片DS1302作电子钟的标准时间,AVR外置I2C存储器,LED作状态和时间显示,四至五个轻触开关作控制,输出采用无触点方案。供电:12V直流/220V两用,没有市电自动转换12V蓄电池供电。 控制开关的分配:时分调整2个,功能转换1个,存储或显示记录打铃点1个,备用1个。 2、软件方面:从存储
[单片机]
PID控制的原理及常用口诀总结
PID控制器(比例-积分-微分控制器)是一个在工业控制应用中常见的反馈回路部件,由比例单元比例P(proportion)、积分单元 I(integration)和微分单元D(differentiation)组成。PID控制器作为最早实用化的控制器已有近百年历史,现在仍然是应用最广泛的工业控制器。PID控制器简单易懂,使用中不需精确的系统模型等先决条件,因而成为应用最为广泛的控制器。 1.PID常用口诀: 参数整定找最佳,从小到大顺序查,先是比例后积分,最后再把微分加,曲线振荡很频繁,比例度盘要放大,曲线漂浮绕大湾,比例度盘往小扳,曲线偏离回复慢,积分时间往下降,曲线波动周期长,积分时间再加长,曲线振荡频率快,先把微分降下来,动差
[嵌入式]
基于AVR单片机和EM4094射频卡读写基站的多协议读写器的设计
引言 射频识别(RFID)是利用无线方式对电子数据载体(电子标签)进行识别的一种新兴技术。与接触式IC卡和条形码识别等系统比较,它有着巨大的优势。利用射频识别技术,能有效实现对数量大、分布区域广的信息进行智能化管理,达到高效快捷运作的目的,特别是在第二代身份证、物流、交通航运、自动收费、超市、门禁系统管理、服务领域等方面有着广泛的应用前景。随着我国国民经济的快速发展,国内RFID行业也正经历着深刻的变革。 RFID系统一般是由读写器、射频卡、应用软件来组成。其中读写器的设计是至关重要的,它决定了系统的稳定性和准确性。 除了要求其能支持一系列协议、标准和收发器外,对读写器可能还有其它功能性方面的要求,如高性能、防冲突、远/近感应距离
[单片机]
基于<font color='red'>AVR</font>单片机和EM4094射频卡读写基站的多协议读写器的设计
AVR单片机的RTOS-AVRX应用
简介:AVRX是一个不错的RTOS,最显著的特点就是内核小,速度快,编译后大概只需500~700字节,且基本的调度功能一个也不少。由于其代码公开,结合不同型号AVR单片机的特性,可以在此基础上进行系统的裁减和扩展,使之能达到更好的效果,本文为AVR嵌入式系统的应用提供了借鉴。 引言 随着技术的发展,嵌入式系统的设计及应用对人们的生活产生了很大的影响,并将逐渐改变人们未来的生活方式,在特定的操作系统上开发应用程序,可以使开发人员忽略掉很多底层硬件细节,使得应用程序调试更方便、易于维护、开发周期缩短并且降低开发成本,因而嵌入式操作系统深得开发人员的青睐。 AVR微处理器是Atmel公司开发的8位嵌入式RISC处理器,它具有
[单片机]
LCD1602高手使用详解
前面总算走完了对AVR MEGA16这块单片机的一些基本的应用方式了,这时候大家对AVR的一些内部资源比如定时器,ADC,最主要的IO口的使用方式应该有了一个虽比较粗浅但是却比较形象的认识了。这节我们来看使用单片机的另外一大主题,就是用单片机来实现芯片控制。 在前面的数码管显示一文中,就已经涉及到了用单片机来控制芯片为我们工作,CEPARK AVR开发板,为了达到增强驱动能力和节省IO口的作用,运用了移位寄存器74HC595来驱动两个四位八段数码管,是一个十分有创意的设计。但是前面的内容重心还是集中于对AVR的IO口的控制,所以,我们从这节开始要正式逐渐深入的接触各种芯片了。 先做个引子。单片机是一种微控制器,本身内部集成了数
[单片机]
LCD1602高手使用详解
爱特梅尔成立深圳大学–Atmel AVR微控制器实验室
爱特梅尔公司(Atmel® Corporation) 宣布,基于企业与高校联手培养合格工程师的共同目标,深圳大学–Atmel AVR微控制器实验室于2010年4月29日正式挂牌成立,成为爱特梅尔公司在中国地区的11个AVR微控制器大学实验室之一。该实验室将承担机电与控制工程学院本科生微控制器的实践教学,并作为深圳大学机电与控制工程学院的科研实践基地,成为推动双方长远发展、更好合作的开端。 深圳大学–Atmel AVR微控制器实验室成立暨揭牌仪式于4月29日在深圳大学科技楼3号报告厅举行。深圳大学副校长阮双琛教授、深圳大学教务处处长徐晨教授、深圳大学设备处副处长张红兵教授、机电与控制工程学院院长徐刚教授、机电与控制工程
[单片机]
基于AVR单片机的ISP1362OTG设计
   0 引言   随着PDA、移动电话、数码相机、打印机等消费类产品的普及,用于这些设备与电脑、或设备与设备之间的高速数据传输技术越来越受到人们的关注。以往以计算机为核心的数据传输结构,非常不利于USB,总线在嵌入式行业的应用,也不适用于野外作业,而OTG技术的推出则可实现在没有PC的情况下,设备与设备之间的数据传输,它拓展了USB技术的应用范围。本文采用的设计方案是基于Philips公司的ISP1362 OTG控制芯片,参照最新的USB OTG技术规范,设计了一种遵循USB协议的主/从机系统。    1 ISP1362芯片的内部结构   Philips公司的ISP1362是一款符合USB 2.0总线协议的接口芯片,内部有
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved