立即注冊(cè) 登錄
返回首頁(yè)

uid:582255的個(gè)人空間

日志

步進(jìn)電機(jī)控制實(shí)驗(yàn)

已有 1016 次閱讀2021-2-3 21:30

電機(jī)轉(zhuǎn)動(dòng)的代碼
uchar phasecw[8] ={0x08,0x0c,0x04,0x06,0x02,0x03,0x01,0x09};//正轉(zhuǎn) 電機(jī)導(dǎo)通相序 D-C-B-A
uchar phaseccw[8]={0x01,0x03,0x02,0x06,0x04,0x0c,0x08,0x09};//反轉(zhuǎn) 電機(jī)導(dǎo)通相序 A-B-C-D

//順時(shí)針轉(zhuǎn)動(dòng)

  1. void MotorCW(void)
  2. {
  3. uchar i;
  4. for(i=0;i<8;i++)
  5.   {
  6.    MotorData=phasecw[i];
  7.    Delay_ms(speed);//轉(zhuǎn)速調(diào)節(jié)
  8.   }
  9.         i=0;
  10. }
  11. //逆時(shí)針轉(zhuǎn)動(dòng)
  12. void MotorCCW(void)
  13. {
  14. uchar i;
  15. for(i=0;i<8;i++)
  16.   {
  17.    MotorData=phaseccw[i];
  18.    Delay_ms(speed);//轉(zhuǎn)速調(diào)節(jié)
  19.   }
  20. }

  21. 根據(jù)步進(jìn)電機(jī)的原理:依次給4相高電平就可以驅(qū)動(dòng)步進(jìn)電機(jī)轉(zhuǎn)動(dòng)而A,B,C,D四相 分別對(duì)應(yīng)P1.0,P1.1,P1.2,P1.3口所以只有讓P1口依次為0x01,0x02,0x04,0x08就行了,如果要反轉(zhuǎn)就把它倒過(guò)來(lái)依次為0x08,0x04,0x02,0x01.一圈4步,所以叫四相四拍。但是我不推薦使用這種,它的一步角度較大電機(jī)會(huì)有較大抖動(dòng)。所以采用了四相八拍0x01,0x03,0x02,0x06,0x04,0x0c,0x08,0x09這樣電機(jī)轉(zhuǎn)動(dòng)也相對(duì)平穩(wěn)不易出事。
    為了實(shí)現(xiàn)電機(jī)的不停頓轉(zhuǎn)動(dòng)我將轉(zhuǎn)動(dòng)函數(shù)放在了死循環(huán)里,但是在死循環(huán)里我們無(wú)法控制電機(jī)了怎么辦了就在死循環(huán)里加入一  步進(jìn)電機(jī)實(shí)驗(yàn).zip (20.67 KB, 下載次數(shù): 213) 個(gè)按鍵函數(shù)這樣死循環(huán)不停掃描按鍵我們就可以在k1 里面通過(guò)sem控制電機(jī)的正反轉(zhuǎn)了。
    死循環(huán):while(sem&&sam)
                    {                        
                    MotorCW();
              Delay_ms(speed);//轉(zhuǎn)速調(diào)節(jié)
              keypros();
                    }   
        while(!sem&&sam)
                    {
                    MotorCCW();
              Delay_ms(speed);//轉(zhuǎn)速調(diào)節(jié)
    按鍵控制:

    if(k1==0)                  //檢測(cè)按鍵K1是否按下
            {        
                    Delay_ms(10);   //消除抖動(dòng) 一般大約10ms
                    if(k1==0)         //再次判斷按鍵是否按下
                    {
                            sam=1;
                            sem=!sem;
              }
                    while(!k1);         //檢測(cè)按鍵是否松開(kāi)
            }        
    為什么要用一個(gè)鍵控制正反轉(zhuǎn)了?不僅僅是因?yàn)榘存I不夠,更重要的是能消除鍵位沖突,鍵位沖突是指同時(shí)按下不同的鍵產(chǎn)生的沖突。消除鍵位沖突也是每次實(shí)驗(yàn)應(yīng)該考慮的事情。但是這樣也產(chǎn)生了新的問(wèn)題就是當(dāng)我們用兩個(gè)鍵控制正反轉(zhuǎn)時(shí),單片機(jī)上電后電機(jī)不會(huì)轉(zhuǎn)動(dòng)。而用上述方法的話上電電機(jī)就進(jìn)入死循環(huán)開(kāi)始轉(zhuǎn)動(dòng),所以引入sam控制電機(jī)的開(kāi)始于停止。當(dāng)sam為0與上sem可以使sem失去控制能力,也就是電機(jī)不轉(zhuǎn)了。這樣也就解決此問(wèn)題還能控制電機(jī)停止        
    if(k2==0)                  //檢測(cè)按鍵K1是否按下
            {        
                    Delay_ms(10);   //消除抖動(dòng) 一般大約10ms
                    if(k2==0)         //再次判斷按鍵是否按下
                    {               
                    sam=0;
                    }        
             while(!k2);         //檢測(cè)按鍵是否松開(kāi)
            }
    我們由步進(jìn)電機(jī)原理可知電機(jī)是一步一步的走的,如果我們控制了它每一步的間隔時(shí)間就可以達(dá)到控制電機(jī)的速度的目的。但是對(duì)于我買的步進(jìn)電機(jī)來(lái)說(shuō)速度變換的一定程度就不明顯了所以我設(shè)置了限位這樣就減少代碼的bug,所以寫(xiě)出按鍵控制速度代碼如下
    if(k3==0)                  //檢測(cè)按鍵K1是否按下
            {        
                    Delay_ms(10);   //消除抖動(dòng) 一般大約10ms
                    if(k3==0)         //再次判斷按鍵是否按下
             {
                            speed++;
                     if(speed>6)
                    {
                            speed=6;
                    }
                   
             }
                    while(!k3);         //檢測(cè)按鍵是否松開(kāi)
            }        
    if(k4==0)                  //檢測(cè)按鍵K1是否按下
            {        
                    Delay_ms(10);   //消除抖動(dòng) 一般大約10ms
                    if(k4==0)         //再次判斷按鍵是否按下
             {
                            speed--;
                            if(speed<1)
                    {
                            speed=1;
                    }
            
             }
                    while(!k3);         //檢測(cè)按鍵是否松開(kāi)
            }        
    }
    理解了這些代碼的原理就可以寫(xiě)出總代碼了
    1. #include<reg52.h>
    2. #define uchar unsigned char
    3. #define uint unsigned int
    4. #define MotorData P1                    //步進(jìn)電機(jī)控制接口定義
    5. uchar phasecw[8] ={0x08,0x0c,0x04,0x06,0x02,0x03,0x01,0x09};//正轉(zhuǎn) 電機(jī)導(dǎo)通相序 D-C-B-A
    6. uchar phaseccw[8]={0x01,0x03,0x02,0x06,0x04,0x0c,0x08,0x09};//反轉(zhuǎn) 電機(jī)導(dǎo)通相序 A-B-C-D
    7. uint  sem=0,sam=0,speed=3;//信號(hào)量,sem控制正反轉(zhuǎn),sam設(shè)置電機(jī)是否轉(zhuǎn)動(dòng),1轉(zhuǎn)動(dòng),0不轉(zhuǎn)動(dòng)
    8. sbit k1=P3^1;
    9. sbit k2=P3^0;
    10. sbit k3=P3^2;
    11. sbit k4=P3^3;
    12. //ms延時(shí)函數(shù)
    13. void Delay_ms(uint x)
    14. {
    15. uint i,j;
    16. for(i=0;i<x;i++)
    17.   for(j=0;j<112;j++);
    18. }
    19. //順時(shí)針轉(zhuǎn)動(dòng)
    20. void MotorCW(void)
    21. {
    22. uchar i;
    23. for(i=0;i<8;i++)
    24.   {
    25.    MotorData=phasecw[i];
    26.    Delay_ms(speed);//轉(zhuǎn)速調(diào)節(jié)
    27.   }
    28.         i=0;
    29. }
    30. //逆時(shí)針轉(zhuǎn)動(dòng)
    31. void MotorCCW(void)
    32. {
    33. uchar i;
    34. for(i=0;i<8;i++)
    35.   {
    36.    MotorData=phaseccw[i];
    37.    Delay_ms(speed);//轉(zhuǎn)速調(diào)節(jié)
    38.   }
    39. }

    40. //按鍵函數(shù)
    41. void keypros()
    42. {

    43.         if(k1==0)                  //檢測(cè)按鍵K1是否按下
    44.         {        
    45.                 Delay_ms(10);   //消除抖動(dòng) 一般大約10ms
    46.                 if(k1==0)         //再次判斷按鍵是否按下
    47.                 {
    48.                         sam=1;
    49.                         sem=!sem;
    50.           }
    51.                 while(!k1);         //檢測(cè)按鍵是否松開(kāi)
    52.         }               
    53.         if(k2==0)                  //檢測(cè)按鍵K1是否按下
    54.         {        
    55.                 Delay_ms(10);   //消除抖動(dòng) 一般大約10ms
    56.                 if(k2==0)         //再次判斷按鍵是否按下
    57.                 {               
    58.                 sam=0;
    59.                 }        
    60.          while(!k2);         //檢測(cè)按鍵是否松開(kāi)
    61.         }
    62.         if(k3==0)                  //檢測(cè)按鍵K1是否按下
    63.         {        
    64.                 Delay_ms(10);   //消除抖動(dòng) 一般大約10ms
    65.                 if(k3==0)         //再次判斷按鍵是否按下
    66.          {
    67.                         speed++;
    68.                  if(speed>6)
    69.                 {
    70.                         speed=6;
    71.                 }
    72.                
    73.          }
    74.                 while(!k3);         //檢測(cè)按鍵是否松開(kāi)
    75.         }        
    76. if(k4==0)                  //檢測(cè)按鍵K1是否按下
    77.         {        
    78.                 Delay_ms(10);   //消除抖動(dòng) 一般大約10ms
    79.                 if(k4==0)         //再次判斷按鍵是否按下
    80.          {
    81.                         speed--;
    82.                         if(speed<1)
    83.                 {
    84.                         speed=1;
    85.                 }
    86.         
    87.          }
    88.                 while(!k3);         //檢測(cè)按鍵是否松開(kāi)
    89.         }        
    90. }
    91. //主函數(shù)
    92. void main(void)
    93. {

    94. while(1)
    95. {
    96.                  MotorData=0x00;  //設(shè)初值
    97.           keypros();
    98.     while(sem&&sam)
    99.                 {                        
    100.                 MotorCW();
    101.           Delay_ms(speed);//轉(zhuǎn)速調(diào)節(jié)
    102.           keypros();
    103.                 }   
    104.     while(!sem&&sam)
    105.                 {
    106.                 MotorCCW();
    107.           Delay_ms(speed);//轉(zhuǎn)速調(diào)節(jié)
    108.           keypros();
    109.                 }               
    110. }

    111. }
    復(fù)制代碼
    本文大體就是這樣

路過(guò)

雞蛋

鮮花

握手

雷人

全部作者的其他最新日志

評(píng)論 (0 個(gè)評(píng)論)

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

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

返回頂部