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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1488|回復: 1
打印 上一主題 下一主題
收起左側

單片機PID溫控源碼,變量值為什么總是不對?

[復制鏈接]
跳轉到指定樓層
樓主
ID:489498 發表于 2019-3-27 16:35 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
求助論壇大神,為什么我學習改寫別人的PID溫控源碼代碼,其中PWM 和temp_PID.SetPoint 總是不對,用串口調試的結果總是不對。
輸出結果:  PWM:100  PWM:12288  PWM_P:  設置溫度:30  實?飾露?2619  temp_s:3000  temp_PID.SetPoint:

按理說我用了這樣的        PWM應該在0到100之間temp_PID.SetPoint:應該是3000才對可是輸出為什么不是,實在查不出原因,請大神指正。

引腳分配    lcd    lcddata:    P0
            lcd_e:        P2^7
            lcd_rs:        P2^6
            lcd_rw:        P2^5
        
        設置按鍵    limit_choise:        P    //溫度上下限選擇按鍵
                increase_temperature        P    //增加溫度限值按鍵
                reduce_temperature        P    //減少溫度限值按鍵
        
        蜂鳴器報警    warning        P   

        溫度傳感器    temperature_sensor    P

        制熱    heatting    P

        制冷    refrigerating    P

        LED顯示        normal        P    //正常溫度指示燈
                high_temperature    P    //高溫指示燈
                low_temperature        P    //低溫指示燈   

單片機源程序如下:
  1. /*******************************************************************************
  2. * 包含頭文件
  3. *******************************************************************************/
  4. #include <main.h>

  5. /*******************************************************************************
  6. * 變量聲明
  7. *******************************************************************************/

  8. uint  PWM=0;
  9. uint  PWM_P;//PWM_P  功率占比顯示

  10. uchar time_value=0;
  11. uchar time_heatting=0;
  12. uint temp_m=0;                        //實際溫度
  13. uint up_limit_temp=30;
  14. uint temp_s; //設置溫度*100
  15. PID temp_PID;

  16. uchar massage[]=0;


  17. /*******************************************************************************
  18. * 函數名                                                : void main()
  19. * 函數功能                                        : 主函數
  20. * 輸入                                                : 無
  21. * 輸出                                                : 無
  22. *******************************************************************************/

  23. void main()//主函數
  24. {
  25.     init();//初始化函數

  26.     temp_PID.Proportion =150;              //  設置 PID 系數
  27.     temp_PID.Integral   =5;
  28.     temp_PID.Derivative =2;


  29.                 while(1)
  30.                 {
  31.                         temp_s = up_limit_temp*100;
  32.                         temp_PID.SetPoint =        temp_s;
  33.                         if(time_value==10)                                                                                        //讀取溫度
  34.                         {
  35.                                 temp_m=get_temp(Ds18b20ReadTemp());

  36.                         }
  37.                         if(time_value==50)
  38.       {
  39.                                 if(temp_s-temp_m>=100)
  40.                                 {
  41.                                         PWM=100;
  42.                                 }
  43.                                 else
  44.                                 {
  45.                                         PWM = pid_calc(&temp_PID,temp_m);
  46.                                         if( PWM>=100 )                PWM=100;
  47.                                         else if(PWM<=1)                PWM=1;
  48.                                 }
  49.                         }
  50.                         if(time_value==60)                                                                                        //顯示溫度
  51.                         {

  52.                                 display_real_temp(temp_m);                                                
  53.                         }
  54.                   if(time_value==70)
  55.                         {               
  56.                                 send_string("  PWM:");
  57.                                 DtoA(PWM,massage);
  58.                                 send_string(massage);               
  59.                                 /*
  60.                                 PWM_P = PWM;
  61.                                 
  62.                                 LcdWriteCom(0x80+0X40+0x0C);
  63.                                 LcdWriteData('0'+PWM_P/100);
  64.                                 LcdWriteCom(0x80+0X40+0x0D);
  65.                                 LcdWriteData('0'+PWM_P%100/10);
  66.                                 LcdWriteCom(0x80+0X40+0x0E);
  67.                                 LcdWriteData('0'+PWM_P%10);        
  68.                                 
  69.                                 */
  70.                                 send_string("  PWM:");
  71.                                 DtoA(PWM,massage);
  72.                                 send_string(massage);
  73.                                        
  74.                                 send_string("  PWM_P:");
  75.                                 DtoA(PWM_P,massage);
  76.                                 send_string(massage);
  77.                                 
  78.                                 send_string("  設置溫度:");
  79.                                 DtoA(up_limit_temp,massage);
  80.                                 send_string(massage);
  81.         
  82.                                 send_string("  實際溫度:");
  83.                                 DtoA(temp_m,massage);
  84.                                 send_string(massage);

  85.                           send_string("  temp_s:");
  86.                                 DtoA(temp_s,massage);
  87.                                 send_string(massage);
  88.                                 
  89.                                 send_string("  temp_PID.SetPoint:");
  90.                                 DtoA(temp_PID.SetPoint,massage);
  91.                                 send_string(massage);
  92.                                 send_string("\n");

  93.                         }

  94.                         if(time_value>=100)                                                                                        //指令執行時間,一個單位時間是10ms
  95.       {      
  96.                                 time_value=0;  
  97.       }
  98.                         if(time_heatting >= 500)  time_heatting = 0;
  99.                         if(time_heatting <= PWM*5)      
  100.                         {
  101.                                 heatting=1;
  102.                         }
  103.                         else
  104.                         {        
  105.                                 heatting=0;
  106.                         }

  107.         }               
  108. }
  109. /*******************************************************************************
  110. * 函數名                                                : void init()
  111. * 函數功能                                        : 初始化函數
  112. * 輸入                                                : 無
  113. * 輸出                                                : 無
  114. *******************************************************************************/
  115. void init()//初始化函數
  116. {
  117.         uint i,j;        
  118.         Ds18b20Init();//Ds18b20初始化
  119.         //heatting=0;//不制熱
  120.         
  121.         IT0Init();
  122.         IT1Init();
  123.         InitUart0();
  124.         InitTimer0();//定時器初始化
  125.         pid_init (&temp_PID);//PID初始化

  126.         
  127.         LcdInit();//LCD初始化函數
  128.         
  129.         LcdWriteCom(0x80);//第一行顯示
  130.         j=strlen(num1);
  131.         for(i=0; i<j; i++)
  132.         {
  133.                 LcdWriteData(num1[i]);        
  134.                 delay_ms(1);
  135.         }
  136.         LcdWriteCom(0x80+0x40);//第二行顯示
  137.         j=strlen(num2);
  138.         for(i=0; i<j; i++)
  139.         {
  140.                 LcdWriteData(num2[i]);        
  141.                 delay_ms(1);
  142.         }
  143.         LcdWriteCom(0x04);  //關閉寫一個指針加1
  144. }

  145. /*******************************************************************************
  146. * 函數名                                                : uint get_temp(uint temp)
  147. * 函數功能                                        : 計算溫度函數
  148. * 輸入                                                : 溫度
  149. * 輸出                                                : 溫度
  150. *******************************************************************************/
  151. uint get_temp(uint temp)//計算溫度函數
  152. {
  153.         float tp;
  154.         
  155.         tp=temp;//因為數據處理有小數點所以將溫度賦給一個浮點型變量
  156.         //如果溫度是正的那么,那么正數的原碼就是補碼它本身
  157.         temp=tp*0.0625*100+0.5;        
  158.         //留兩個小數點就*100,+0.5是四舍五入,因為C語言浮點數轉換為整型的時候把小數點
  159.         //后面的數自動去掉,不管是否大于0.5,而+0.5之后大于0.5的就是進1了,小于0.5的就
  160.         //算加上0.5,還是在小數點后面。
  161.         return temp;
  162. }
  163. /*******************************************************************************
  164. * 函數名                                                : void display_real_temp(uint temp)
  165. * 函數功能                                        : 實時溫度顯示函數
  166. * 輸入                                                : 溫度
  167. * 輸出                                                : 無
  168. *******************************************************************************/
  169. void display_real_temp(uint temp)//實時溫度顯示函數
  170. {
  171.         uchar datas[] = {0, 0, 0, 0}; //定義數組

  172.         datas[0] = temp % 10000 / 1000;
  173.         datas[1] = temp % 1000 / 100;
  174.         datas[2] = temp % 100 / 10;
  175.         datas[3] = temp % 10;

  176.         LcdWriteCom(0x80+0x0a);                 //寫地址 80表示初始地址
  177.         LcdWriteData('0'+datas[0]); //十位

  178.         LcdWriteCom(0x80+0x0b);        //寫地址 80表示初始地址
  179.         LcdWriteData('0'+datas[1]); //個位

  180.         LcdWriteCom(0x80+0x0d);         //寫地址 80表示初始地址
  181.         LcdWriteData('0'+datas[2]); //顯示小數點  

  182.         LcdWriteCom(0x80+0x0e);                 //寫地址 80表示初始地址
  183.         LcdWriteData('0'+datas[3]); //顯示小數點  

  184. }

  185. /*******************************************************************************
  186. * 函數名                                                : void InitTimer0(void)
  187. * 函數功能                                        : 定時器初始化函數
  188. * 輸入                                                : 無
  189. * 輸出                                                : 無
  190. *******************************************************************************/
  191. void InitTimer0(void)
  192. {
  193.     TMOD &= 0xF0;
  194.     TMOD |= 0x01;//設置定時模式1
  195.     TH0 = 0xD8;
  196.     TL0 = 0xF0;
  197.     EA = 1;
  198.     ET0 = 1;
  199.     TR0 = 1;
  200. }
  201. /*******************************************************************************
  202. * 函數名                                                : void Timer0Interrupt(void) interrupt 1
  203. * 函數功能                                        : 定時器中斷函數
  204. * 輸入                                                : 無
  205. * 輸出                                                : 無
  206. *******************************************************************************/
  207. void Timer0Interrupt(void) interrupt 1
  208. {
  209.     TH0 = 0xD8;
  210.     TL0 = 0xF0;

  211.         
  212.                 time_value++;             //功能計數值+1  
  213.                 time_heatting++;         //加熱計數值+1
  214. }
  215. /*******************************************************************************
  216. * 函數名                                                : void INIT0(void) interrupt 0
  217. * 函數功能                                        : 外部中斷0執行函數
  218. * 輸入                                                : 無
  219. * 輸出                                                : 無
  220. *******************************************************************************/
  221. void INIT0(void) interrupt 0
  222. {
  223.         
  224.         delay_ms(5);
  225.         if (increase_temperature == 0)
  226.                 {
  227.                         while(increase_temperature == 0);
  228.                                         if(up_limit_temp<=110)
  229.                                         {
  230.                                         up_limit_temp=up_limit_temp+5;
  231.                                         LcdWriteCom(0x80+0X40+0x03);
  232.                                         LcdWriteData('0'+up_limit_temp%1000/100);
  233.                                         LcdWriteCom(0x80+0X40+0x04);
  234.                                         LcdWriteData('0'+up_limit_temp%100/10);
  235.                                         LcdWriteCom(0x80+0X40+0x05);
  236.                                         LcdWriteData('0'+up_limit_temp%10);
  237.                                         }

  238.                 }        
  239. }
  240. /*******************************************************************************
  241. * 函數名                                                : void INIT1(void) interrupt 2
  242. * 函數功能                                        : 外部中斷1執行函數
  243. * 輸入                                                : 無
  244. * 輸出                                                : 無
  245. *******************************************************************************/
  246. void INIT1(void) interrupt 2
  247. {
  248.         

  249.         delay_ms(5);
  250.         if (reduce_temperature == 0)
  251.                 {
  252.                         while(reduce_temperature == 0);
  253.                                         if(up_limit_temp>=20)
  254.                                         {
  255.                                         up_limit_temp=up_limit_temp-5;
  256.                                         LcdWriteCom(0x80+0X40+0x03);
  257.                                         LcdWriteData('0'+up_limit_temp%1000/100);
  258.                                         LcdWriteCom(0x80+0X40+0x04);
  259.                                         LcdWriteData('0'+up_limit_temp%100/10);
  260.                                         LcdWriteCom(0x80+0X40+0x05);
  261.                                         LcdWriteData('0'+up_limit_temp%10);
  262.                                         }

  263.                 }        
  264.                
  265. }
  266. /*******************************************************************************
  267. * 函數名                                                : void IT0Init(void)
  268. * 函數功能                                        : 外部中斷0初始化
  269. * 輸入                                                : 無
  270. * 輸出                                                : 無
  271. *******************************************************************************/
  272. void IT0Init(void)
  273. {
  274.     IT0 = 0;//0為電平,1為下降沿
  275.     EX0 = 1;//外部中斷1
  276. }
  277. /*******************************************************************************
  278. * 函數名                                                : void IT1Init(void)
  279. * 函數功能                                        : 外部中斷1初始化
  280. * 輸入                                                : 無
  281. * 輸出                                                : 無
  282. *******************************************************************************/
  283. void IT1Init(void)
  284. {
  285.     IT1 = 0;//0為電平,1為下降沿
  286.     EX1 = 1;//外部中斷0
  287. }
  288. /*******************************************************************************
  289. * 函數名                                                : void InitUart0(void)
  290. * 函數功能                                        : 串口中斷初始化
  291. * 輸入                                                : 無
  292. * 輸出                                                : 無
  293. *******************************************************************************/
  294. void InitUart0(void)
  295. {//設計波特率:4800bps;實際波特率:4464bps
  296.     TMOD&=0x0F;
  297.     TMOD|=0x20;
  298.     SCON=0x50;
  299.     PCON|=0x80;
  300.     TH1 = 0xF3;
  301.     TL1 = 0xF3;
  302.     ES = 1;                //使能串口中斷 ,無論是TI/RI出現,只要中斷打開,單片機就進入中斷函數。
  303.     TR1 = 1;
  304.                 //ET1 = 0;//禁止T1中斷
  305. }
  306. /*******************************************************************************
  307. * 函數名                                                : void IT1Init(void)
  308. * 函數功能                                        : 串口中斷函數
  309. * 輸入                                                : 無
  310. * 輸出                                                : 無
  311. *******************************************************************************/
  312. void Usart() interrupt 4
  313. {

  314.         //uchar receiveData;
  315.         //receiveData=SBUF;//出去接收到的數據
  316.         RI = 0;//清除接收中斷標志位
  317.         
  318.         //SBUF=receiveData;//將接收到的數據放入到發送寄存器
  319.         //while(!TI);                         //等待發送數據完成
  320.         //TI=0;                                                 //清除發送完成標志
  321.         //massage[0]=0;
  322.         


  323. }
  324. /*******************************************************************************
  325. * 函數名                                                : void send_byte(uchar by)
  326. * 函數功能                                        : 串口發送字節函數
  327. * 輸入                                                : 無
  328. * 輸出                                                : 無
  329. *******************************************************************************/
  330. void send_byte(uchar by)
  331.         {

  332.     SBUF = by;
  333.     while(!TI);//當寫下這句的時候,就不要在中斷函數里面在寫TI = 0;這句了,不然進入中斷函數將TI清零之后,程序就會一直卡在這里
  334.     TI = 0;       //在這里將TI清零
  335.         }
  336. /*發送一個字符串*/
  337. /*******************************************************************************
  338. * 函數名                                                : void send_string(uchar *p)
  339. * 函數功能                                        : 串口發送字符串函數
  340. * 輸入                                                : 無
  341. * 輸出                                                : 無
  342. *******************************************************************************/
  343. void send_string(uchar *p)
  344.         {

  345.     while(*p!= '\0')
  346.                         {
  347.    
  348.         send_byte(*p);
  349.         p++;

  350.                         }
  351.         }
  352. /*******************************************************************************
  353. * 函數名                                                : void DtoA(unsigned long dat, unsigned char* buffer)
  354. * 函數功能                                        : 串口發送字符串函數
  355. * 輸入                                                : 無
  356. * 輸出                                                : 無
  357. *******************************************************************************/
  358.         
  359. void DtoA(uint dat, unsigned char* buffer)
  360. {
  361. uint tmp = 0;
  362. char length = 0;
  363. tmp = dat;
  364. while(tmp != 0)//求出數字的實際長度
  365. {
  366. tmp = tmp/10;
  367. length++;
  368. }
  369. buffer[length] = '\0';//長度數為字符串截止位
  370. length--;

  371. while(length >= 0)//數字的低位放入數組的高位
  372. {
  373. tmp = dat%10;
  374. buffer[length--] = 0x30|tmp;

  375. dat = dat/10;
  376. }
  377. }
復制代碼
全部資料51hei下載地址:
PID恒溫控制器.zip (113.68 KB, 下載次數: 20)



分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:507401 發表于 2019-4-25 12:58 | 只看該作者
沒有看到PID實現的函數呀!
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 日韩免费 | 天天操夜夜看 | 久久国产香蕉 | 无码日韩精品一区二区免费 | 日韩三级在线 | 天天澡天天狠天天天做 | 中国一级特黄真人毛片免费观看 | 粉嫩国产精品一区二区在线观看 | 成人av电影免费在线观看 | 久热精品在线观看视频 | 精品乱码一区二区三四区视频 | 成人精品在线观看 | 国产精品一区久久久 | 欧美日韩视频在线 | 91看片在线观看 | 亚洲欧美一区二区三区1000 | 国产精品免费一区二区 | 欧美 日韩精品 | 久久精品一区二区三区四区 | 台湾佬成人网 | 99久久久久久 | 成年人在线 | 成人黄色电影在线播放 | 色网站在线| 精品产国自在拍 | 一区二区在线免费观看 | 国产精品久久 | 成人妇女免费播放久久久 | 国产高清在线精品一区二区三区 | 成人免费淫片aa视频免费 | m豆传媒在线链接观看 | 精品一区二区观看 | 91精品国产综合久久婷婷香蕉 | 成人一级片在线观看 | 黄色国产在线视频 | 国产无套一区二区三区久久 | 精精国产视频 | 亚洲精品2区 | 免费激情| 日本免费视频在线观看 | 91社区在线观看播放 |