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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

基于51單片機PID算法控制直流電機轉速且LCD1602液晶顯示器顯示實際轉速與設定速度...

  [復制鏈接]
跳轉到指定樓層
樓主
  1. /*PID的參數設置可以參照以下來進行:  
  2.   參數整定找最佳,從小到大順序查;  
  3.   先是比例后積分,最后再把微分加;  
  4.   曲線振蕩很頻繁,比例度盤要放大;  
  5.   曲線漂浮繞大灣,比例度盤往小扳;  
  6.   曲線偏離回復慢,積分時間往下降;  
  7.   曲線波動周期長,積分時間再加長;  
  8.   曲線振蕩頻率快,先把微分降下來;  
  9.   動差大來波動慢。微分時間應加長;  
  10.   理想曲線兩個波,前高后低4比1 ; 
  11.   一看二調多分析,調節質量不會低;
  12. */
  13. #include <reg51.h>
  14. #include<stdio.h>
  15. #define uchar unsigned char
  16. #define uint unsigned int
  17. sbit qidong=P1^3;//啟動鍵
  18. sbit tingzhi=P1^4;//停止鍵
  19. sbit fangxiang=P1^5;//轉向鍵
  20. sbit AddSpeed=P1^6;//加速鍵
  21. sbit SubSpeed=P1^7;//減速鍵
  22. sbit RS = P2^5;//LCD1602數據命令選擇端口
  23. sbit RW = P2^6;//LCD1602讀寫選擇端口
  24. sbit EN = P2^7;//LCD1602使能端口
  25. sbit IN2=P3^3;//L298輸入端2
  26. sbit IN1=P3^4;//L298輸入端1
  27. sbit PWM_FC=P3^5;//L298使能端口
  28. uchar aa[]={'T','a','r','g','e','t',' ',' ',' ',' ',' ','r','/','s','e','c'};//目標轉速:Target  r/sec
  29. uchar cc[]={'A','c','t','u','a','l',' ',' ',' ',' ',' ','r','/','s','e','c'};//實測轉速: Actual  r/sec
  30. uchar displayflag;//顯示標志位變量
  31. uint SetSpeed=3000;//聲明設定速度變量
  32. uint ActualSpeed=0;//聲明實際速度變量
  33. int e ,e1 ,e2 ;//聲明當前偏差值變量、之后偏差值變量、再后偏差值變量
  34. int out=0;//PID調節后輸出偏差值變量
  35. uint cnt=0;//定時器1中斷次數變量
  36. uint Inpluse=0;//聲明脈沖計數變量、
  37. uint PWMTime=100;//聲明脈沖寬度時間變量
  38. float uk ,uk1 ,duk ;//聲明目前總偏差值變量、之后偏差值總變量、偏差值總變量
  39. float Kp=0.36,Ki=0.05,Kd=0.016;//pid控制系數p=0.1,i=0.05,d=0.016。
  40.   void delay(uchar x)
  41. {
  42.    uint i,j;
  43.    for(i=x;i>0;i--)
  44.     for(j=50;j>0;j--);
  45.    }
  46.   void DelayUs2x(unsigned char t)
  47. {   
  48.    while(--t);
  49.   }
  50.   void DelayMs(unsigned char t)
  51. {
  52.    while(t--)
  53. {
  54.     DelayUs2x(245);
  55.     DelayUs2x(245);
  56.    }
  57. }
  58.   void write_com(uchar com)//寫命令
  59. {
  60.    RS=0;
  61.    RW=0;
  62.    P0=com;
  63.    DelayMs(5);
  64.    EN=1;
  65.    DelayMs(5);
  66.    EN=0;
  67.   }
  68.   void write_data(uchar date)//寫一個字符
  69. {
  70.    RS=1;
  71.    RW=0;
  72.    P0=date;
  73.    DelayMs(5);
  74.    EN=1;
  75.    DelayMs(5);
  76.    EN=0;
  77.   }
  78.   void init()//初始化
  79. {
  80.    write_com(0x38);
  81.    write_com(0x0c);
  82.    write_com(0x06);
  83.    write_com(0x01);
  84.   }
  85.   void LCD_Write_String(uchar x,uchar y,uchar *s)//寫字符串
  86. {     
  87.    if (y == 0)
  88. {     
  89.     write_com(0x80 + x);     
  90.    }
  91.    else
  92. {     
  93.     write_com(0xC0 + x);     
  94.    }        
  95.    while (*s)
  96. {     
  97.      write_data( *s);     
  98.      s++;     
  99.    }
  100. }
  101.   void PIDControl()//pid偏差計算
  102. {
  103.    e=SetSpeed-ActualSpeed;//計算當前偏差值變量
  104.    duk=(Kp*(e-e1)+Ki*e+Kd*(e-2*e1+e2));//PID連續系統離散化增量型PID算法,算出總偏差值變量。
  105.    uk=duk+uk1;//計算偏差值總變量加上之后偏差值總變量之和賦給目前總偏差值變量
  106.    out=(int)uk;//強制類型轉化為整數型的目前總偏差值變量賦給PID調節后輸出偏差值變量
  107.    if(out>1000)//判斷PID調節后輸出偏差值變量是否大于100
  108. {
  109.     out=1000;//PID調節后輸出偏差值變量為100
  110.    }
  111.    else if(out<0)//判斷PID調節后輸出偏差值變量是否小于0
  112. {
  113.     out=0;//PID調節后輸出偏差值變量為0
  114.   }
  115.    uk1=uk;//目前總偏差值變量賦給之后偏差值總變量
  116.    e2=e1;//之前偏差值變量賦給之后偏差值變量
  117.    e1=e;//當前偏差值變量賦給之前偏差值變量
  118.    PWMTime=out;//PID調節后輸出偏差值變量賦給脈沖寬度時間變量
  119. }
  120.   void PWMOUT()
  121. {
  122.    if(cnt<PWMTime)//判斷定時器1中斷次數變量是否小于脈沖寬度時間變量
  123. {
  124.     PWM_FC=1;//脈沖寬度輸入端口輸出高電平
  125.    }
  126.    else
  127. {
  128.     PWM_FC=0;//脈沖寬度輸入端口輸出低電平
  129.    }
  130.    if(cnt>1000)//判斷定時器1中斷次數變量是否大于100
  131.    cnt=0;//定時器1中斷次數變量歸0
  132. }
  133.   void SystemInit()//定時器0定時器1外部中斷0初始化函數
  134. {
  135.    TMOD=0X21;//定時器0方式1,定時器1方式2。  
  136.    TH0=0xf8;//初裝定時器0高八位寄存器定時數值
  137.    TL0=0x50 ;//初裝定時器0低八位寄存器定時數值,即2毫秒。
  138.    TH1=0xC0;//初裝定時器1高八位寄存器定時數值
  139.    TL1=0XC0;//初裝定時器1低八位寄存器定時數值,即16毫秒。
  140.    EA=1;//開總中斷
  141.    EX0=1;//開外部中斷0
  142.    IT0=1;//外部中斷0下降沿觸發
  143.    ET0=1;//開定時器0中斷允許
  144.    ET1=1;//開定時器1中斷允許
  145.    TR0=1;//開定時器0中斷
  146.    TR1=1;//開定時器1中斷
  147.    e =0;//偏差值變量為0
  148.    e1=0;//之后偏差值變量為0
  149.    e2=0;//再后偏差值變量為0
  150.    IN1=1;
  151.    IN2=1;
  152.   }
  153.   void SpeedSet()//設定速度函數
  154. {
  155.    if(qidong==0)
  156. {
  157.     delay(5);
  158.     if(qidong==0)
  159.   {
  160.      IN1=0;
  161.      IN2=1;
  162.      while(qidong==1);
  163.     }
  164.    }
  165.    if(tingzhi==0)
  166. {
  167.     delay(5);
  168.     if(tingzhi==0)
  169.   {
  170.      IN1=1;
  171.      IN2=1;
  172.      EN=1;
  173.      while(tingzhi==1);
  174.     }
  175.    }
  176.    if(fangxiang==0)
  177. {
  178.     delay(5);
  179.     if(fangxiang==0)
  180.   {
  181.      IN1=~IN1;
  182.      IN2=~IN2;
  183.      while(fangxiang==1);
  184.     }   
  185.    }
  186.    if(AddSpeed==0)//判斷加速鍵是否按下
  187. {
  188.     delay(5);//延時
  189.     if(AddSpeed==0)//再次判斷加速鍵是否按下
  190.   {
  191.      SetSpeed+=100;//設定速度變量每次加100
  192.      if(SetSpeed>3500)//判斷設定速度變量是否大于3500
  193.    {
  194.       SetSpeed=3500;//設定速度變量歸為3500
  195.      }
  196.     }
  197.    }
  198.    if(SubSpeed==0)//判斷減速鍵是否按下
  199. {
  200.     delay(5);//延時
  201.     if(SubSpeed==0)//再次判斷減速鍵是否按下
  202.   {
  203.      SetSpeed-=100;//設定速度變量每次減100
  204.      if(SetSpeed<0)//判斷設定速度變量是否小于0
  205.      SetSpeed=0;//設定速度變量歸0
  206.     }
  207.    }   
  208.     aa[7]=SetSpeed/1000+'0';
  209.     aa[8]=SetSpeed/100%10+'0';
  210.     aa[9]=SetSpeed/10%10+'0';
  211.     aa[10]=SetSpeed%10+'0';
  212.     LCD_Write_String(0,0,aa);
  213.   }
  214.   /**************主函數************/
  215.   void main()
  216. {
  217.    SystemInit();
  218.    init();
  219.    LCD_Write_String(0,0,aa);
  220.    displayflag=1;
  221.    while(1)
  222. {
  223.     SpeedSet();
  224.     if(displayflag==1)
  225.   {
  226.      displayflag=0;
  227.      cc[7]=ActualSpeed/1000+'0';
  228.      cc[8]=ActualSpeed/100%10+'0';
  229.      cc[9]=ActualSpeed/10%10+'0';
  230.      cc[10]=ActualSpeed%10+'0';
  231.      LCD_Write_String(0,1,cc);
  232.     }
  233.    }
  234.   }
  235.   void int0() interrupt 0//外部中斷0函數
  236. {
  237.    Inpluse++;//脈沖計數變量加加
  238.   }
  239.   void Timer0() interrupt 1//定時器0中斷服務函數
  240. {
  241.    static uint time=0;//轉速測量周期變量
  242.    TH0=0xf8;//重裝定時器0高八位寄存器計數值
  243.    TL0=0x50 ;//重裝定時器0低八位寄存器計數值,即2毫秒。
  244.    time++;//轉速測量周期變量加加
  245.    if(time>500)//判斷轉速測量周期變量是否大于500,等于500就是500x2毫秒=1000毫秒,也就是1s。
  246. {
  247.     time=0;//轉速測量周期變量歸0
  248.     displayflag=1;//顯示標志位變量置1
  249.     ActualSpeed=Inpluse;//脈沖計數變量表示實際速度變量
  250.     Inpluse=0;//脈沖計數變量歸0
  251.     PIDControl();//PID控制函數
  252.    }
  253.    PWMOUT();
  254. }
  255.   void Timer1() interrupt 3//定時器1中斷服務函數
  256. {
  257.    cnt++;//定時器1中斷次數變量
  258.   }
復制代碼


圖片113.png (88.83 KB, 下載次數: 168)

圖片113.png

圖片114.png (185.69 KB, 下載次數: 133)

圖片114.png

圖片115.png (186.7 KB, 下載次數: 145)

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

使用道具 舉報

沙發
ID:739327 發表于 2020-5-5 14:45 來自手機 | 只看該作者
樓主有protues仿真圖嗎
回復

使用道具 舉報

板凳
ID:171036 發表于 2020-5-5 21:06 | 只看該作者
劍客阿酷 發表于 2020-5-5 14:45
樓主有protues仿真圖嗎

把程序弄清楚了就容易啦
回復

使用道具 舉報

地板
ID:746195 發表于 2020-5-12 18:58 | 只看該作者
樓主我是剛入門的小白,有一些問題能問你一下嘛
回復

使用道具 舉報

5#
ID:641762 發表于 2020-5-13 18:09 | 只看該作者
正是我想需要的,樓主厲害
回復

使用道具 舉報

6#
ID:171036 發表于 2020-5-15 20:45 | 只看該作者
LOVE008 發表于 2020-5-12 18:58
樓主我是剛入門的小白,有一些問題能問你一下嘛

互相學習
回復

使用道具 舉報

7#
ID:171036 發表于 2020-5-15 20:46 | 只看該作者
haoziya 發表于 2020-5-13 18:09
正是我想需要的,樓主厲害

把樓主說高了  好好學習  共同進步
回復

使用道具 舉報

8#
ID:720149 發表于 2020-5-16 09:55 | 只看該作者
樓主,有沒有轉速電流雙閉環的pi算法啊
回復

使用道具 舉報

9#
ID:368810 發表于 2020-5-18 10:29 | 只看該作者
那個L298就是PID的硬件嗎?還是說PID算法是寫在程序里面的啊
回復

使用道具 舉報

10#
ID:171036 發表于 2020-5-18 20:20 | 只看該作者
zyy1100 發表于 2020-5-18 10:29
那個L298就是PID的硬件嗎?還是說PID算法是寫在程序里面的啊

pid寫在程序里面
回復

使用道具 舉報

11#
ID:741067 發表于 2020-5-30 16:48 | 只看該作者
那個灰色的圓是什么來的
回復

使用道具 舉報

12#
ID:741067 發表于 2020-5-30 17:49 | 只看該作者
為什么我的實際轉速為0,沒有轉,電路圖是正確的
回復

使用道具 舉報

13#
ID:861377 發表于 2020-12-17 20:39 來自手機 | 只看該作者
為什么實踐轉速和設定轉速不一樣
回復

使用道具 舉報

14#
ID:862666 發表于 2020-12-19 08:42 | 只看該作者
妄妄妄妄網 發表于 2020-5-16 09:55
樓主,有沒有轉速電流雙閉環的pi算法啊

好像沒有
回復

使用道具 舉報

15#
ID:462629 發表于 2021-12-28 09:56 | 只看該作者
能補全電路原理圖,源碼嗎
回復

使用道具 舉報

16#
ID:1045221 發表于 2022-11-1 16:06 | 只看該作者

實物連接,帶霍爾編碼器的直流電機的最中間的兩根線怎么接呢,一共6根線,兩根電機電源線,兩根編碼器電源線
回復

使用道具 舉報

17#
ID:1085509 發表于 2023-6-22 22:13 | 只看該作者
樓主,請問一下為什么我的仿真過程中,電機的速度就是達不到設定速度
回復

使用道具 舉報

18#
ID:59980 發表于 2023-11-4 13:51 | 只看該作者
基于51單片機PID算法控制直流電機轉速且LCD1602液晶顯示器顯示實際轉速與設定速度
回復

使用道具 舉報

19#
ID:1109793 發表于 2024-9-4 09:36 | 只看該作者
問一下,電流限制要怎么加進去啊?電流用0.1歐姆電阻采樣,要放大嗎?用LM358可以不,精度0.1A就行
回復

使用道具 舉報

20#
ID:1140214 發表于 2024-12-18 15:56 | 只看該作者
請問怎么調能讓實際轉速與設定速度一樣?
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 91国在线观看 | 久久69精品久久久久久久电影好 | 亚洲成色777777在线观看影院 | 黄色成人在线观看 | 一本一道久久a久久精品蜜桃 | 久久不卡 | 给我免费的视频在线观看 | 亚洲欧美在线视频 | 亚洲国产中文字幕 | 国产偷自视频区视频 | 国产欧美性成人精品午夜 | 亚洲图片一区二区三区 | 91.com视频| 国产福利视频 | 欧美日本韩国一区二区 | www.久草.com | 亚洲一区二区精品视频 | 日韩国产精品一区二区三区 | 精品日韩一区二区 | 在线观看中文字幕视频 | 国产精品成人一区二区 | 国产在线对白 | 日韩网| 日本在线一区二区三区 | 欧美成年视频 | 无人区国产成人久久三区 | 亚洲国产中文字幕 | 亚洲精品日韩精品 | 亚洲一区二区三区在线播放 | 在线视频亚洲 | 国产成人精品一区二区三区网站观看 | 国产在线中文字幕 | 99久久精品免费看国产四区 | 91视频在线观看 | 欧美日韩高清在线一区 | 亚洲欧美综合精品另类天天更新 | 国产精品免费观看视频 | 最新av在线网址 | 欧美精品一区二区三区在线 | 久久久久久天堂 | 国产成人精品一区二区三区四区 |