天天看點

單片機之步進電機

單片機的應用特别地多,其用途非常廣泛,我們這些案例隻是涉及其基本部分,沒有深究,但是也是要作為一個了解的,今天就學習一下步進電機和可控步進電機

步進電機

實驗現象

發現步進電機按照一定速度逆時針旋轉,同時發現SM接口處左側的led燈以一定頻率閃爍

(PS:在沒有步進電機的情況下,可以通過檢視led的閃爍來判斷步進電機是否處于工作狀态下)

工作原理

步進電機

電脈沖信号轉變為角位移或線位移的開環控制元步進電機件

(在非超載的情況下,電機的轉速、停止的位置隻取決于脈沖信号的頻率和脈沖數,而不受負載變化的影響,)

  • 當步進驅動器接收到一個脈沖信号,它就驅動步進電機按設定的方向轉動一個固定的角度,稱為“步距角”,它的旋轉是以固定的角度一步一步運作的。
  • 可以通過控制脈沖個數來控制角位移量,進而達到準确定位的目的;
  • 同時可以通過控制脈沖頻率來控制電機轉動的速度和加速度,進而達到調速的目的

勵磁方式是一相勵磁,勵磁表在程式中為0111、1011、1101、1110,程式連續不停地在不同口送入脈沖信号,即可使步進電機旋轉,通過設定定時器的定時時間減慢步進電機的旋轉速度

電路原理圖:

單片機之步進電機

擴充:

步進電機的勵磁方式有三種:

  1. 一相勵磁

    在每一瞬間,步進電機隻有一個線圈導通。每送一個勵磁信号,步進電機旋轉5.625°,這是三種勵磁方式中最簡單的一種

    順序表如下:

    單片機之步進電機
  2. 二相勵磁

    在每一瞬間,步進電機有兩個線圈同時導通。每送一個勵磁信号,步進電機旋轉5.625°

    順序表如下:

    單片機之步進電機
  3. 一-二相勵磁

    為一相勵磁與二相勵磁交替導通的方式。每送一個勵磁信号,步進電機旋轉2.8125°

    順序表如下:

    單片機之步進電機
代碼解析

設計流程圖如下:

單片機之步進電機

設定其勵磁的順序表的元素,通過中斷實作

void time0() interrupt 1
{
	 switch(i++)//控制步進電機不同IO脈沖電平
	 {
	 case 1: s1=1;s2=0;s3=0;s4=0;break;
	 case 2: s1=0;s2=1;s3=0;s4=0;break;
	 case 3: s1=0;s2=0;s3=1;s4=0;break;
	 case 4: s1=0;s2=0;s3=0;s4=1;break;
	 }
	 if(i==5)
	 i=1;
}
           

初始化

void init_sys()			  
{	
    P4M0=0Xff;  //P4口推挽輸出
	P4M1=0X00;
//	LED =0;	   //數位管顯示
	P4  =0X00;	 //P4口設定低電平,避免複位時對接口造成影響
	TMOD = 0x00;   //設定定時器0,16位
	TH0  = (65536-10000)/256;	//設定5ms
	TL0  = (65536-10000)%256;
	TCON = 0X10;	//定時器開始計時
	IE   = 0x82;	//開啟CPU中斷,定時器0中斷
}
           

最後主函數中設定永真循環即可

可控步進電機

實驗現象

現象與步進電機相同,隻是增加了控制功能

即:

K2鍵可控制步進電機的旋轉方向

K3鍵控制步進電機的旋轉與停止

工作原理

通過在P4.1、P4.2、P4.3、P4.4口每隔5ms*sudu的時間輸入高電平(sudu值由Key1鍵進行确定,并在數位管最右端顯示,分别為1-12這12個檔位,數值越大,轉速越慢)

并結合Key2鍵确認旋轉方向(按下按鍵則按相反方向進行旋轉)

再結合Key3鍵控制步進電機旋轉還是停止

代碼解析

工程設計流程圖如下:

單片機之步進電機
  • 反轉部分代碼

    (隻需要判斷按鍵是否按下,包含按鍵消抖,就利用條件語句,選擇不同的順序,原來1 2 3 4對應的順序表,現在反過來對應即可)

void Xstep_Process()
{
    static uchar i = 1;                      
    if( btRotationFlag == 0 )                
    {
        switch( i++ )                      
        {
            case 1:
                sbtS1 = 1;  sbtS2 = 0;  sbtS3 = 0;  sbtS4 = 0;  break;
            case 2:
                sbtS1 = 0;  sbtS2 = 1;  sbtS3 = 0;  sbtS4 = 0;  break;
            case 3:
                sbtS1 = 0;  sbtS2 = 0;  sbtS3 = 1;  sbtS4 = 0;  break;
            case 4:
                sbtS1 = 0;  sbtS2 = 0;  sbtS3 = 0;  sbtS4 = 1;  break;
            default:
                sbtS1 = 0;  sbtS2 = 0;  sbtS3 = 0;  sbtS4 = 0;  break;
        }
        if( i == 5 )
            i = 1;
    }                                     
    else
    {
        switch( i++ )
        {
            case 1:
                sbtS1 = 0;  sbtS2 = 0;  sbtS3 = 0;  sbtS4 = 1;  break;
            case 2:
                sbtS1 = 0;  sbtS2 = 0;  sbtS3 = 1;  sbtS4 = 0;  break;
            case 3:
                sbtS1 = 0;  sbtS2 = 1;  sbtS3 = 0;  sbtS4 = 0;  break;
            case 4:
                sbtS1 = 1;  sbtS2 = 0;  sbtS3 = 0;  sbtS4 = 0;  break;
            default:
                sbtS1 = 0;  sbtS2 = 0;  sbtS3 = 0;  sbtS4 = 0;  break;
        }
        if( i == 5 )
            i = 1;
    }
}
           
  • 數位管顯示部分

    設定其初始值為一定的檔數,改變一個數字改變一下頻率,得到不同的部分,再利用數位管部分的知識成功顯示即可

void Seg7LedDisplay( uchar s, uchar  e )
{
    unsigned char arrSegSelect[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x40, 0x00}; 
    static  int  i;
    P2 = ( P2 & 0xf0 ) | i;
    switch( i )
    {
        case 0:
            P0 = arrSegSelect[cstDig0];   break;
        case 1:
            P0 = arrSegSelect[cstDig1];   break;
        case 2:
            P0 = arrSegSelect[cstDig2];   break;
        case 3:
            P0 = arrSegSelect[cstDig3];   break;
        case 4:
            P0 = arrSegSelect[cstDig4];   break;
        case 5:
            P0 = arrSegSelect[cstDig5];   break;
        case 6:
            P0 = arrSegSelect[cstDig6];   break;
        case 7:
            P0 = arrSegSelect[cstDig7];   break;
        case 8:
            P0 = cstDig8;           break;
        default:
            P0 = 0x00;            break;
    }
    if( ++i > e ) i = s;
}

           
  • 主函數部分

    包含其判斷使能是否有效,即步進電機能否工作

    以及是什麼擋位的使能有效,進而得到多長時間的間隔改變轉動頻率

void main()
{
    Init();
    ucLedTmp = 0x00;            
    while( 1 )
    {
        if( btT10usFlag )
        {
            btT10usFlag = 0;  T10us_Process();
        }
        if( btT100usFlag )
        {
            btT100usFlag = 0;  T100us_Process();
        }
        if( btT1msFlag )
        {
            btT1msFlag = 0;  T1ms_Process();
        }
        if( btT10msFlag )
        {
            btT10msFlag = 0;  T10ms_Process();
        }
        if( btT100msFlag )
        {
            btT100msFlag = 0; T100ms_Process();
        }
        if( ( btTXmsFlag && btTXmsFlag_en ) ) 
        {
            btTXmsFlag = 0;  TXms_Process();
        }
    }
}
           
  • 中斷服務處理部分

    中斷為10次,即計數10次,就會開啟一種新狀态

  • 初始化部分

    與步進電機類似,增加部分統計變量的初值

  • 各節拍的處理函數

    不同地方的顯示,選擇不同的頻率

void T10us_Process()
{

}
void T100us_Process()          
{
    ucClockXms++;
    if ( ucClockXms == ( cstClockXmsMaxNum ) )
    {
        ucClockXms = 0;   btTXmsFlag = 1;
    }
}
void T1ms_Process()
{
    Seg7LedDisplay( cstDigBegin, cstDigEnd );
}
void T10ms_Process() 
{
    Key_Scan();
}
void TXms_Process()  
{
    Xstep_Process();
}
void T100ms_Process()   
{
    ucSpeed_Seg = ucSpeed;
}
           
  • 按鍵掃描即消抖部分

    參照按鍵消抖代碼即可

繼續閱讀