新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > 基于AVR ATMega16 的PID 控制算法程序

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

        作者: 時間:2016-11-18 來源:網(wǎng)絡(luò) 收藏
        最近由于有些時間,于是想起了做一個PID設(shè)計,在網(wǎng)上收集了不少關(guān)于PID控制的理論,于是計劃用mega16L做一個PID測試程序,發(fā)現(xiàn)一些意想不到的誤差,不知各位同仁是否有遇到與我的類似的現(xiàn)象:我定義了一個PID結(jié)構(gòu)體,在初始化的時候無法把每個元素的初始化值設(shè)置為0(見下面的仿真圖),而且,PID結(jié)構(gòu)體中的部分參數(shù)是應(yīng)該不變的,在整個PID運(yùn)算中,但是不應(yīng)該變化的參數(shù)卻在PID運(yùn)算發(fā)生了變化,不知道是什么原因,到現(xiàn)在也無法查出原因。有興趣的朋友可以一起參與討論或有經(jīng)驗的朋友 給與相關(guān)幫助,謝謝!
        詳細(xì)的代碼和仿真情況如下:(我的硬件系統(tǒng)是本站的min Mega16/32 + JTAG ICE)
        1. #include "config.h"
        2. struct _PID
        3. {
        4. float PVn; //反饋信號變量
        5. float SPn; //設(shè)定值
        6. float Mn; //PID運(yùn)算結(jié)果
        7. float Kc; //比例系數(shù)
        8. float Ts; //采樣時間(ms)
        9. float Ti; //積分時間(ms)
        10. float Td; //微分時間(ms)
        11. float Mx; //積分項調(diào)整參數(shù)
        12. float PVn_1;//前一次反饋變量
        13. float MPn; //比例項的結(jié)果值
        14. float MIn; //積分項的結(jié)果值
        15. float MDn; //微分項的結(jié)果值
        16. };
        17. struct _PID *myPID;
        18. void init_myPID(void);
        19. void init_ports(void);
        20. void init_device(void);
        21. float MPn_value(struct _PID *PID);
        22. float MIn_value(struct _PID *PID);
        23. float MDn_value(struct _PID *PID);
        24. float Mx_value(struct _PID *PID);
        25. float Mn_value(struct _PID *PID);
        26. void main (void)
        27. {
        28. init_device();
        29. init_myPID();
        30. myPID->SPn = 155.5;
        31. myPID->Kc = 13.2;
        32. myPID->Ts = 0.2;
        33. myPID->Ti = 600.0;
        34. myPID->Td = 0.0;
        35. myPID->PVn = 108.2;
        36. while(1)
        37. {
        38. myPID->MPn = MPn_value(myPID);
        39. myPID->MDn = MDn_value(myPID);
        40. myPID->Mx = Mx_value(myPID);
        41. myPID->MIn = MIn_value(myPID);
        42. myPID->Mn = Mn_value(myPID);
        43. myPID->PVn_1 = myPID->PVn;
        44. }
        45. }
        46. /******************************************************************************/
        47. void init_myPID(void)
        48. {
        49. myPID->PVn = 0.0;
        50. myPID->SPn = 0.0;
        51. myPID->Mn = 0.0;
        52. myPID->Kc = 0.0;
        53. myPID->Ts = 0.0;
        54. myPID->Ti = 0.0;
        55. myPID->Td = 0.0;
        56. myPID->Mx = 0.0;
        57. myPID->PVn_1 = 0.0;
        58. myPID->MPn = 0.0;
        59. myPID->MIn = 0.0;
        60. myPID->MDn = 0.0;
        61. }
        62. //------------------------------------------------------------------------------
        63. void init_ports(void)
        64. {
        65. PORTA = 0x00; //If ADC Function was be used,the PORTA could`t set bit 1
        66. DDRA = 0x00; //the port set input mode.
        67. PORTB = 0x00;
        68. DDRB = 0x00;
        69. PORTC = 0x00; //m103 output only
        70. DDRC = 0x00;
        71. PORTD = 0x00;
        72. DDRD = 0x00;
        73. }
        74. //------------------------------------------------------------------------------
        75. void init_device(void)
        76. {
        77. CLI();
        78. init_ports();
        79. MCUCR = 0x00; //Set Power control(State:Close)
        80. GICR = 0x00; //Set boot guide(State:Close).
        81. SEI(); //re-enable interrupts
        82. //all peripherals are now initialized
        83. }
        84. // 計算 比例項的值
        85. //------------------------------------------------------------------------------
        86. float MPn_value(struct _PID *PID)
        87. {
        88. float myMPn = 0.0;
        89. myMPn = PID->Kc *( PID->SPn - PID->PVn);
        90. return myMPn;
        91. }
        92. //計算積分項的值
        93. //------------------------------------------------------------------------------
        94. float MIn_value(struct _PID *PID)
        95. {
        96. float myMIn = 0.0;
        97. myMIn = PID->Kc*(PID->Ts/PID->Ti)*(PID->SPn - PID->PVn) + PID->Mx;
        98. return myMIn;
        99. }
        100. //計算微分項的值
        101. //------------------------------------------------------------------------------
        102. float MDn_value(struct _PID *PID)
        103. {
        104. float myMDn = 0.0;
        105. myMDn = PID->Kc * (PID->Td/PID->Ts) * (PID->PVn_1 - PID->PVn);
        106. return myMDn;
        107. }
        108. //計算PID的結(jié)果
        109. //------------------------------------------------------------------------------
        110. float Mn_value(struct _PID *PID)
        111. {
        112. float myMn = 0.0;
        113. myMn = PID->MPn + PID->MIn + PID->MDn;
        114. return myMn;
        115. }
        116. //計算積分項的調(diào)整值
        117. //------------------------------------------------------------------------------
        118. float Mx_value(struct _PID *PID)
        119. {
        120. float myMx = 0.0;
        121. if(PID->Mn > 1.0)
        122. {
        123. myMx = 1.0 - (PID->MPn + PID->MDn);
        124. }
        125. else if(PID->Mn < 0.0)
        126. {
        127. myMx = -(PID->MPn + PID->MDn);
        128. }
        129. return myMx;
        130. }

        本文引用地址:http://www.104case.com/article/201611/315722.htm

        運(yùn)行到PID初始化函數(shù):void init_myPID(void)時的仿真結(jié)果如下:無法全部初始化為0

        運(yùn)行到:
        myPID->SPn = 155.5;
        myPID->Kc = 13.2;
        myPID->Ts = 0.2;
        myPID->Ti = 600.0;
        myPID->Td = 0.0;
        myPID->PVn = 108.2;

        重新賦值后,部分參數(shù)Ts并不為0.2



        關(guān)鍵詞: AVRATMega16PID控制算

        評論


        技術(shù)專區(qū)

        關(guān)閉
        主站蜘蛛池模板: 澄江县| 甘泉县| 牡丹江市| 金山区| 如东县| 丰宁| 沈阳市| 宾川县| 德钦县| 精河县| 巨鹿县| 二手房| 于都县| 南昌市| 马鞍山市| 桦川县| 客服| 阿图什市| 苍溪县| 淮滨县| 甘南县| 开鲁县| 拉孜县| 荆州市| 循化| 广南县| 潜江市| 靖宇县| 玉树县| 灯塔市| 仁布县| 彭水| 遂平县| 会泽县| 宜兰市| 兴隆县| 青田县| 兰溪市| 德州市| 潜江市| 清流县|