找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

帖子
查看: 1437|回復: 4
收起左側(cè)

大佬們能幫忙看看這個電機調(diào)速單片機程序有啥問題嗎?

[復制鏈接]
ID:1009113 發(fā)表于 2022-3-26 22:29 | 顯示全部樓層 |閱讀模式
在另一位大佬貼出來的程序的基礎(chǔ)上改的,各部分程序的作用也都理解了但是燒錄到單片機后電機就是不會調(diào)速自己一直看不出有啥問題,請大佬們幫忙看看

單片機源程序如下:
  1. #include<reg51.h>
  2. #include "intrins.h"
  3. #include <LCD1602.H>
  4. #define uchar unsigned char
  5. #define uint unsigned int
  6. #define GPIO_KEY P2
  7. sbit PWM=P1^3;                  
  8. uchar speed1[4]={"000"};//設(shè)定轉(zhuǎn)速
  9. uchar speed2[3]={"000"};//占空比        
  10. uchar speed[]={"000"};  //當前轉(zhuǎn)速
  11. uchar KeyValue=0;       //鍵值
  12. uint AA,count=0,flag;
  13. float pid_p=0.003,pid_i=0.003,pid_d=0.002;        //PID三個參數(shù)初值
  14. uint SpeedSet=50,CurrentSpeed;              //設(shè)定轉(zhuǎn)速 當前轉(zhuǎn)速
  15. unsigned char pid_val_mid;                  //pid_val_mid脈沖寬度
  16. unsigned int lastError=0;                   //之前誤差初始為0
  17. long int sumError=0;                        //偏差積累初始為0
  18.         
  19. void delay1(unsigned int i)
  20. {
  21.    unsigned int j;
  22.          for(;i>0;i--)
  23.          for(j=0;j<333;j++)
  24.          {;}
  25. }        
  26. /********************* 鍵盤掃描*************/
  27. void KeyDown(void)               
  28. {
  29.         GPIO_KEY=0x0f; //設(shè)置按鍵觸點初始值為0;0000 1111
  30.                 delay1(10);
  31.         if(GPIO_KEY!=0x0f) //判斷按鍵是否按下
  32.         {
  33.                 delay1(10);  //延時消抖
  34.                 if(GPIO_KEY!=0x0f) //再次判斷按鍵是否按下,低電平有效
  35.                 {
  36.                         GPIO_KEY=0X0F;
  37.                         delay1(10);
  38.                         //測試列
  39.                         switch(GPIO_KEY)
  40.                         {
  41.                                 case(0X07):        KeyValue=0;break;//0000 0111
  42.                                 case(0X0b):        KeyValue=1;break;//0000 1011
  43.                                 case(0X0d): KeyValue=2;break;//0000 1101
  44.                                 case(0X0e):        KeyValue=3;break;//0000 1110
  45.                         }
  46.                         //測試行
  47.                         GPIO_KEY=0XF0;//設(shè)置按鍵觸點初始值為1;1111 0000
  48.                         delay1(10);
  49.                         switch(GPIO_KEY)
  50.                         {                                                                                                                  //鍵盤表:
  51.                                 case(0X70):        KeyValue=KeyValue+0;break;//0111 0000      0  1  2  3   
  52.                                 case(0Xb0):        KeyValue=KeyValue+4;break;//1011 0000           4  5  6  7
  53.                                 case(0Xd0): KeyValue=KeyValue+8;break;//1101 0000           8  9  a  b
  54.                                 case(0Xe0):        KeyValue=KeyValue+12;break;//1110 0000           c  d  e  f
  55.                         }
  56.                 }
  57.         }
  58. }

  59. void timer()
  60. {
  61.          TMOD=0x11;//定時器0工作方式1.16位定時,定時器1工作方式1,16位定時;
  62.          TH0=0x4c;//11.0592mhz下的50ms初值  (65535-50000)/256 12mhz是0x3c
  63.          TL0=0x00;//                                (65535-50000)%256        0xb0
  64.          TH1=0xfc;//11.0592mhz下的1msPWM控制
  65.          TL1=0x66;
  66.          TR1=1;           //定時器1啟動位,該位由軟件清零
  67.          ET1=1;           //定時器T1溢出中斷允許
  68.          IT0=1;    //外部中斷下降沿觸發(fā)
  69.          TR0=1;           //定時器0啟動位,該位由軟件清零
  70.          ET0=1;           //定時器T0溢出中斷允許
  71.          EX0=1;           //外部中斷0中斷允許
  72.          EA=1;           //CPU全局中斷開放
  73. }
  74. /***********************lcd顯示*************/
  75. void  display()
  76. {   
  77.             speed[0]=CurrentSpeed/100+0x30; //當前轉(zhuǎn)速
  78.                 speed[1]=CurrentSpeed/10%10+0x30;//0x30對應(yīng)ASCII的數(shù)值0
  79.                 speed[2]=CurrentSpeed%10+0x30;
  80.                 speed1[0]=SpeedSet/100+0x30;//設(shè)定轉(zhuǎn)速
  81.                 speed1[1]=SpeedSet/10%10+0x30;
  82.                 speed1[2]=SpeedSet%10+0x30;  
  83.                 speed2[0]=pid_val_mid/100+0x30;//占空比
  84.                 speed2[1]=pid_val_mid/10%10+0x30;
  85.                 speed2[2]=pid_val_mid%10+0x30;

  86.             LCD_ShowString(1,1,"SET:"); //設(shè)定速度
  87.                 LCD_ShowNum(1,5,speed1,3);
  88.                 LCD_ShowString(1,8,"R/MIN");
  89.                 LCD_ShowString(2,1,"NOW:"); //當前速度
  90.                 LCD_ShowNum(2,5,speed,3);
  91.                 LCD_ShowString(2,8,"R/MIN");        
  92.                
  93. }
  94. /************************電機控制*************/
  95. void keyKZ()
  96. {
  97.                         if(KeyValue==7)//c設(shè)定速度加10
  98.                         SpeedSet+=10;
  99.                         if(KeyValue==15)//d設(shè)定速度減10
  100.                         SpeedSet-=10;
  101.                         if(KeyValue==3)//e設(shè)定速度加1
  102.                         SpeedSet+=1;
  103.                         if(KeyValue==11)//f設(shè)定速度減1
  104.                         SpeedSet-=1;
  105.                         KeyValue=0;                                
  106. }
  107. /************************PID控制算法*************/
  108. unsigned int PID()
  109. {  
  110.   int dError=0,Error=0,B;
  111.     Error=SpeedSet-CurrentSpeed;//當前誤差
  112.     sumError=Error+sumError;//誤差積累
  113.     dError=Error-lastError;//誤差偏差
  114.     lastError=Error;
  115.     B=pid_p*Error+pid_i*sumError+pid_d*dError;//三個參數(shù)計算
  116.         
  117.         if(B>100) pid_val_mid=100;
  118.     if(B<0) pid_val_mid=0;      
  119.         if(B>=0&&B<=100)
  120.     pid_val_mid=B;              
  121.         return(0);
  122. }
  123. void Timer0_isr() interrupt 1  //定時器0中斷
  124. {
  125.          AA++;                     
  126.          TH0=0x4b;                 //重裝50ms
  127.          TL0=0xfe;
  128.          if(AA==20)        //1s      
  129.          {               
  130.            CurrentSpeed=count/96*60;//一分鐘的轉(zhuǎn)速:count/96(96線編碼器)得出1s內(nèi)圈數(shù)也就是r/s,圈數(shù)*60得到r/min
  131.                                 count=0;
  132.                                 AA=0;
  133.                                 PID();
  134.          }
  135. }
  136. void key_int() interrupt 0         //外部中斷0  P3.2口接a相
  137. {
  138.         count++;                 //a相脈沖計數(shù)
  139. }

  140. void Timer1() interrupt 3    //定時器1中斷
  141. {
  142.    static int c=0;                                   //static靜態(tài)變量,只有第一次會賦值
  143.                  TH1=0xfc;                 //重新賦值1mspwm,也就是每間隔1ms中斷一次
  144.                   TL1=0x66;
  145.                  c++;                      //每次定時器溢出加1                  
  146.           if(c<=pid_val_mid) PWM=1;           //當中斷次數(shù)小于設(shè)定的脈寬給高電平,
  147.           if(c>pid_val_mid)  PWM=0;           //等到了設(shè)定脈寬值就變?yōu)榈碗娖?br />
  148.           if(c>=100)         c=0;                    //一個周期分為100段高低電平,大于100就是下一個周期
  149. }
  150. void main()
  151. {
  152.                 timer();   //定時器初始化
  153.                 LCD_Init();//LCD初始化
  154.                 while(1)
  155.                 {
  156.                    KeyDown();  //鍵盤掃描
  157.                    keyKZ();  //鍵盤控制
  158.                    display();//顯示LCD
  159.                 }
  160. }        
復制代碼


回復

使用道具 舉報

ID:394424 發(fā)表于 2022-3-27 09:56 | 顯示全部樓層
調(diào)試是一步步來才能找到問題的  比如先讓電機動起來  然后可快可慢  這樣才能知道問題點
回復

使用道具 舉報

ID:161164 發(fā)表于 2022-3-27 11:43 | 顯示全部樓層
你PID三個參數(shù)的初值設(shè)得太小
    float pid_p=0.003,pid_i=0.003,pid_d=0.002;
    Error=SpeedSet-CurrentSpeed;//當前誤差
    sumError=Error+sumError;//誤差積累
    dError=Error-lastError;//誤差偏差
    lastError=Error;
    B=pid_p*Error+pid_i*sumError+pid_d*dError;//三個參數(shù)計算假設(shè)CurrentSpeed=40;SpeedSet=50;Error=10;
Error小于333, pid_p等于沒用
sumError要34秒后才大于333
dError要Error有改變才有用

研究一下PID三個參數(shù)值的正確設(shè)置吧
回復

使用道具 舉報

ID:1009113 發(fā)表于 2022-3-27 11:53 | 顯示全部樓層
Wprogrammer 發(fā)表于 2022-3-27 09:56
調(diào)試是一步步來才能找到問題的  比如先讓電機動起來  然后可快可慢  這樣才能知道問題點

現(xiàn)在的情況就是LCD會顯示但是顯示的速度值不對,電機通電就能轉(zhuǎn)但是按按鍵啥速度不會改變只能慢慢調(diào)試了
回復

使用道具 舉報

ID:587810 發(fā)表于 2022-3-27 16:56 | 顯示全部樓層
不可以光改設(shè)速度。對應(yīng)的PID參數(shù)也要改的,每一套PID參數(shù)都是對應(yīng)當前設(shè)定速度的。
回復

使用道具 舉報

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

本版積分規(guī)則

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

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

快速回復 返回頂部 返回列表