久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 11271|回復(fù): 1
收起左側(cè)

936焊臺(tái)用AVR模糊PID恒溫控制

  [復(fù)制鏈接]
ID:75926 發(fā)表于 2015-4-2 22:40 | 顯示全部樓層 |閱讀模式
本帖最后由 xiaos 于 2015-4-2 22:41 編輯

用放大用LM324比較差··不過(guò)溫度還是可以穩(wěn)定,用M8 AD10位 pwm10位溫度范圍為200-500

精確度1度··

因?yàn)槌绦虻脑蚣由弦ㄋ悦看紊郎氐皆O(shè)定值前15度就開(kāi)始整定··

有個(gè)缺點(diǎn)就是PID控制恒溫時(shí)的那幾度溫度升的很慢··

設(shè)置部分還沒(méi)寫(xiě)好

自己的思路是直接用那個(gè)可變電阻做設(shè)置

AD轉(zhuǎn)換采樣可變電阻來(lái)設(shè)定溫度

設(shè)置一按鍵為溫度設(shè)定

當(dāng)按了那按鍵后可變電阻設(shè)定溫度有效

沒(méi)按的話(huà)不管你怎么轉(zhuǎn)都不能調(diào)節(jié)溫度

那部分寫(xiě)完后整個(gè)代碼,發(fā)出來(lái)大家一起參考

發(fā)覺(jué)問(wèn)題還很多的。。希望大家多提下意見(jiàn),小弟初學(xué)的

還有如果要改的話(huà)可以不改那電路的引一條采樣跟控制線(xiàn)出來(lái)直接連上M8也可以的













  1. /*******************************
  2. project        :A/D轉(zhuǎn)換數(shù)碼管顯示
  3. chip type      : atmega8               
  4. clock frequency:內(nèi)部RC(INT) 8MHz
  5. Author         :周遠(yuǎn)峰               
  6. ********************************/
  7. #include "iom8v.h"
  8. #include "macros.h"
  9. #define osccal 0x7d                        
  10. unsigned long adc_rel;              //處理后世界轉(zhuǎn)換結(jié)果
  11. unsigned long adc_rl;               //A/D轉(zhuǎn)換結(jié)
  12. unsigned int tmp;                   //設(shè)置的溫度參數(shù)                          
  13. unsigned char adc_mux;              //A/D通道
  14. unsigned char led_buff[3]={0,0,0};  //顯示緩存
  15. signed int error0;                  //當(dāng)前偏差
  16. signed int error1;                  //上次偏差
  17. signed int error2;                  //上上次偏差
  18. signed char Kp;                     //比例常數(shù)
  19. signed char Ki;                     //積分常數(shù)
  20. signed char Kd;                     //微分常數(shù)
  21. signed int kk1;                     //當(dāng)前控制輸出
  22. signed int kk2;                     //上次控制輸出
  23. #define NB -3
  24. #define NM -2
  25. #define NS -1
  26. #define ZO 0
  27. #define PS 1
  28. #define PM 2
  29. #define PB 3
  30. #pragma data:code     
  31. //設(shè)置數(shù)據(jù)區(qū)位程序儲(chǔ)存器
  32. const unsigned char seg_table[16]={0x40,0x79,0x24,0x30,0x19,0x90,0x80,0x78,0x00,0x10,0x08,0x81,0x44,0x21,0x04,0x8c};
  33. const unsigned char KP_table[49]={PB,PB,PM,PM,PS,ZO,ZO,PB,PB,PM,PS,PS,ZO,NS,PM,PM,PM,PS,ZO,NS,NS,PM,PM,PS,ZO,NS,NM,NM,PS,PS,ZO,NS,NS,NM,NM,PS,ZO,NS,NM,NM,NM,NB,ZO,ZO,NM,NM,NM,NB,NB};
  34. const unsigned char KI_table[49]={NB,NB,NM,NM,NS,ZO,ZO,NB,NB,NM,NS,NS,ZO,ZO,NB,NM,NS,NS,ZO,PS,PS,NM,NM,NS,ZO,PS,PM,PM,NM,NS,ZO,PS,PS,PM,PB,ZO,ZO,PS,PS,PM,PB,PB,ZO,ZO,PS,PM,PM,PB,PB};
  35. const unsigned char KD_table[49]={PS,NS,NB,NB,NB,NM,NS,PS,NS,NB,NM,NM,NS,ZO,ZO,NS,NM,NM,NS,NS,ZO,ZO,NS,NS,NS,NS,NS,ZO,ZO,ZO,ZO,ZO,ZO,ZO,ZO,PB,NS,PS,PS,PS,PS,PB,PB,PM,PM,PM,PS,PS,PB};
  36. #pragma data:data   
  37. //設(shè)置數(shù)據(jù)區(qū)回到數(shù)據(jù)儲(chǔ)存器
  38. /*********************************************************

  39. 延時(shí)函數(shù)

  40. *********************************************************/
  41. void delay_us(int time) //微秒級(jí)延時(shí)
  42. {
  43. do
  44. time--;
  45. while (time>1);
  46. }
  47. void delay_ms(unsigned int time)  //毫秒級(jí)延時(shí)
  48. {
  49. while (time!=0)
  50.    {
  51.    delay_us(1000);
  52.    time--;
  53.    }
  54. }
  55. /************************************************************
  56. 中斷顯示初始化
  57. TIMER2 initialize - prescale:1024
  58. WGM: Normal
  59. desired value: 10mSec
  60. actual value:  9.984mSec (0.2%)
  61. *************************************************************/
  62. void timer2_init(void)
  63. {
  64. TCCR2 = 0x00; //stop
  65. ASSR  = 0x00; //set async mode
  66. TCNT2 = 0xB2; //setup
  67. OCR2  = 0x4E;
  68. TCCR2 = 0x07; //start
  69. DDRB=0xff;  //PC口為推挽1輸出
  70. PORTB=0xff; //PC口內(nèi)部上拉
  71. DDRD|=0xf1;
  72. PORTD&=0x1f;  //關(guān)閉LED
  73. }
  74. /***********************************************

  75. 中斷顯示

  76. *************************************************/
  77. #pragma interrupt_handler timer2_ovf_isr:5
  78. void timer2_ovf_isr(void)
  79. {
  80. unsigned char i;
  81. static unsigned k;
  82. SEI();
  83. TCNT2 = 0xB2; //reload counter value
  84. for(i=0;i<3;i++)
  85.    {
  86.    PORTB=led_buff[i];
  87.    PORTD|=(1<<(i+5));//待顯示的位置1
  88.    delay_ms(1);
  89.    PORTD&=0x1f;     //關(guān)閉LED
  90.    }
  91. }
  92. /************************************************************

  93. PWM初始化,OC1A口輸出

  94. *************************************************************/
  95. void timer1_init(void)
  96. {
  97. TCCR1B = 0x00; //stop
  98. TCNT1H = 0x00; //setup
  99. OCR1A  = 200;
  100. TCCR1A = (1<<WGM11)|(1<<WGM10)|(1<<COM1A1);//輸出低電平
  101. TCCR1B = (1<<CS11)|(1<<CS10); //
  102. }
  103. /*****************************************************

  104. PID初始化

  105. ******************************************************/
  106. void pidcalc_init(void)  
  107. {
  108. Kp=3;
  109. Ki=3;
  110. Kd=3;
  111. kk1=0; //當(dāng)前
  112. kk2=100;
  113. error0=0;
  114. error1=0;
  115. error2=0;
  116. tmp=300;
  117. }
  118. void pidcalc_zizheng(void)
  119. {
  120. if (tmp>adc_rel)
  121.    {
  122.         if (kk2<500) kk2+=3;
  123.         else kk2=500;
  124.    }
  125. if ((tmp-1)>adc_rel)
  126.    {
  127.         if (kk2<500) kk2+=3;
  128.         else kk2=500;
  129.    }
  130. /*if ((tmp-2)>adc_rel)
  131.    {
  132.         if (kk2<600) kk2+=3;
  133.         else kk2=600;
  134.    }*/
  135. if (tmp<adc_rel)
  136.    {
  137.    if (kk2>10) kk2-=3;
  138.    else kk2=10;
  139.    }
  140. if ((tmp+1)<adc_rel)
  141.    {
  142.    if (kk2>10) kk2-=3;
  143.    else kk2=10;
  144.    }
  145. /*if ((tmp+2)<adc_rel)
  146.    {
  147.    if (kk2>10) kk2-=3;
  148.    else kk2=10;
  149.    }
  150. /*if (tmp>adc_rel)
  151.    {
  152.    if (Ki<200) Ki+=4;
  153.    else Ki=400;
  154.    }
  155. if (tmp<adc_rel)
  156.    {
  157.    if (Ki>0) Ki-=4;
  158.    else Ki=0;
  159.    }  */
  160. }
  161. /*******************************************************

  162. PID函數(shù)

  163. ********************************************************/
  164. void pidcalc(void)
  165. {
  166. signed long KPP;
  167. signed long KII;
  168. signed long KDD;
  169. signed int i;
  170. signed char j;
  171. error0=tmp-adc_rel;
  172. j=error0-error1;
  173. i=7*(3+error0)+(3+j);
  174. if(i<49)
  175.     {
  176.      if (i>0)
  177.             {
  178.                 Kp=KP_table[i];
  179.                 Ki=KI_table[i];
  180.                 Kd=KD_table[i];
  181.                 }
  182.      }                        //輸出                     
  183. if ((tmp-15)<adc_rel)                         //比設(shè)定低一定值時(shí)開(kāi)始PID
  184.   {
  185.    if((tmp+5)>adc_rel)                        //比設(shè)定高時(shí)關(guān)PID
  186.        {
  187.        KPP=Kp*(error0-error1);                //比例
  188.        KII=error0*Ki;                         //積分
  189.        KDD=Kd*(error0-(2*error1)+error2);     //微分
  190.        kk1=(KPP+KII+KDD)*4+kk2;  
  191.        if(kk1<0x3ef)
  192.                    {
  193.                            if (kk1>=10) OCR1A=kk1;   
  194.                            else OCR1A=0;               
  195.                }
  196.            else
  197.                    {   
  198.                     OCR1A=0x3ff;
  199.                }      
  200.                            /*if((tmp-2)>adc_rel)
  201.                                 {
  202.                                 if(OCR1A<500) OCR1A+=20;
  203.                                 else OCR1A=500;
  204.                                         }*/
  205.            }
  206.     else
  207.            {
  208.            //if (tmp<adc_rel)
  209.                  // {
  210.                   ///  if (OCR1A>50) OCR1A-=20;
  211.                   //  else OCR1A=50;
  212.            OCR1A=0;  
  213.                  // }
  214.        }
  215.    }
  216. else
  217.    {
  218.     OCR1A=0x3ff;
  219.    }
  220. error2=error1;
  221. error1=error0;  
  222. }
  223. /***********************************************

  224. ADC初始化

  225. ************************************************/
  226. void adc_init(void)  
  227. {
  228. DDRC=0x00;
  229. PORTC=0X00;
  230. ADCSRA=0X00;
  231. ADMUX=(1<<REFS1)|(1<<REFS0)|(adc_mux&0x0f); //選擇內(nèi)部2.56V為基準(zhǔn)AREF外加濾波電容
  232. ACSR=(1<<ACD);                  //關(guān)閉模擬比較器
  233. ADCSRA=(1<<ADEN)|(1<<ADSC)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);//128分頻
  234. }
  235. /*********************************************

  236. ADC中斷處理函數(shù)

  237. **********************************************/
  238. #pragma interrupt_handler adc_isr:15
  239. void adc_isr(void)
  240. {
  241. static unsigned i;
  242. adc_rl+=ADC&0x3ff;
  243. ADMUX=(1<<REFS1)|(1<<REFS0)|(adc_mux&0x0f); //選擇內(nèi)部2.56V位基準(zhǔn)
  244. ADCSRA|=(1<<ADSC); //啟動(dòng)AD轉(zhuǎn)換   
  245. if (i<2048)
  246.     i++;
  247. else  
  248.      {
  249.          adc_rel=adc_rl/2048;
  250.          adc_rel=adc_rel*3/5;
  251.          i=0;
  252.          adc_rl=0;
  253.          }
  254. }
  255. /******************************************************

  256. ADC數(shù)據(jù)轉(zhuǎn)壓縮BCD

  257. ******************************************************/
  258. void ADCtoBCD(unsigned int temp)
  259. {
  260. unsigned char i;
  261. for (i=0;i<3;i++)
  262.    {
  263.    led_buff[i]=seg_table[temp%10];/*temp%10求余數(shù)‘假設(shè)一個(gè)數(shù)是234那么234/10=23余4也就是查找4的段碼*/
  264.    
  265.    temp=temp/10;// 234/10=23因?yàn)椴惶幚硇?shù)實(shí)際就等于右移了
  266.    }
  267.    
  268. }
  269. /***************************************************************

  270. 主程序

  271. ***************************************************************/
  272. void main(void)
  273. {
  274. unsigned char i;
  275. unsigned int  k;
  276. unsigned int adc_old;
  277. unsigned long adc_ol;
  278. unsigned int adc_o;
  279. DDRD=0xff;
  280. PORTD=0xf0;
  281. OSCCAL=osccal;
  282. TIMSK = 0x40; //timer interrupt sources
  283. adc_mux=0;
  284. adc_init();
  285. timer1_init();
  286. pidcalc_init();
  287. SEI();
  288. for(i=0;i<3;i++)
  289.    led_buff[i]=seg_table[8];
  290. for(i=0;i<200;i++)
  291.    timer2_init();
  292.    adc_old=0;
  293.    adc_rel=0;
  294.   while(1)
  295.      {
  296.                 if(adc_old!=adc_rel)//ADC更新完畢就執(zhí)行數(shù)據(jù)處理
  297.                  {
  298.                       adc_old=adc_rel;
  299.                           pidcalc();
  300.                           pidcalc_zizheng();
  301.                             if(k<5)
  302.                                     {
  303.                                         k++;
  304.                                         adc_ol+=adc_old;
  305.                                         }
  306.                                 else
  307.                                     {
  308.                                         adc_o=adc_ol/5;
  309.                                         adc_ol=0;
  310.                                         k=0;
  311.                                         }        
  312.                           }  
  313.             ADCtoBCD(adc_o);  
  314.          }
  315. }
復(fù)制代碼






回復(fù)

使用道具 舉報(bào)

ID:73848 發(fā)表于 2016-2-15 16:03 | 顯示全部樓層
最近在做加熱墊的控溫程序,希望用上PID讓曲線(xiàn)好看一點(diǎn)
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 国产精品亚洲成在人线 | 久久精品天堂 | 国产ts一区 | 不卡一区 | 成年网站在线观看 | 国产欧美在线播放 | 在线观看视频亚洲 | av电影手机版 | 91精品中文字幕一区二区三区 | 日韩精品 电影一区 亚洲 | av黄色国产 | 999久久久久久久久6666 | 精品久久久久久亚洲精品 | 99久久影院 | h片在线免费看 | 欧美精品福利 | 国产一二区免费视频 | 亚洲性人人天天夜夜摸 | 欧美中文一区 | 精品一区二区免费视频 | 久久高清免费视频 | 美女在线视频一区二区三区 | 久久国产三级 | 96av麻豆蜜桃一区二区 | jizz在线免费观看 | 二区中文 | 亚洲欧美国产毛片在线 | 91精品在线播放 | 激情五月综合 | 国产精品成人在线观看 | 中文字幕 国产 | 羞羞网站免费观看 | 精品国产乱码久久久久久久久 | 国产在视频一区二区三区吞精 | 亚洲国产精品人人爽夜夜爽 | 成人久久久久久久久 | 国产精品高清一区二区 | aaa国产大片 | 亚洲成人在线视频播放 | 亚洲每日更新 | 欧美亚洲视频在线观看 |