天天看點

基于單片機的四相步進電機控制設計(電路+程式)

部落客福利:100G+電子設計學習資源包!

​​http://mp.weixin.qq.com/mp/homepage?__biz=MzU3OTczMzk5Mg==&hid=7&sn=ad5d5d0f15df84f4a92ebf72f88d4ee8&scene=18#wechat_redirect​​ --------------------------------------------------------------------------------------------------------------------------

步進電機控制應用執行個體

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

設計要求:

  • 采用定時中斷方式控制步進機的轉速,定時機關時長為10ms。
  • 速度設定在1/2/3/4四個檔位,1檔最快,依次遞減,能夠控制步進電機的停、轉和方向,同時顯示步進機的目前檔位。
基于單片機的四相步進電機控制設計(電路+程式)

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

設計思路:

  • 通過P1控制步進電機的轉動,P1.0->a,P1.1->b,P1.2->c,P1.3->d,ULN2003A作為步進電機驅動
  • P2.0-P2.3對應數位管顯示(使用7447晶片對應将BCD碼轉換成7端LED數位管),通過7447簡單驅動數位管(P2隻需要發送1/2/3/4即可)
  • 通過定時器計數,到達設定值時步進電機轉動1/4圈,計數清零

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

元件清單:

  • AT89C51
  • BUTTON
  • MOTOR-STEPPER
  • RESPACK-8
  • 7SEG-COM-ANODE
  • ULN2003A
  • 7447
#include <reg52.h>
typedef unsigned char uchar;
uchar direction = 0;  //0為正轉,1為反轉
uchar onoff = 0; //關為0,開為1
uchar n = 0; //每次定時器中斷觸發時n++,當n==max時電機轉動1/4
uchar max = 10;
uchar index = 0; //通過index訓示電機轉動,AB,BC,CD,DA
sbit LED = P3 ^ 7; //當n==max時LED閃爍提示
int main()
{
    /* LED */
    P2 = 0xff;
    /* 初始化中斷 */
    EA = 1;
    EX0 = 1; //要用到的中斷是兩個外部中斷和定時器中斷0
    IT0 = 1;
    EX1 = 1;
    IT1 = 1;
    ET0 = 1;
    /* 定時器0 */
    TMOD = 0x01; //使用定時器0,方式1
    TH0 = (65536 - 10000) / 256; //12MHz晶振下,定時器為10ms觸發中斷,更友善觀察轉動情況
    TL0 = (65536 - 10000) % 256;
    TR0 = 1;
    while(1)
    {
        switch(P0)
        {
        case 0xfe: //11111110
            max = 1;
            P2 = 1;
            break;
        case 0xfd: //11111101
            max = 10;
            P2 = 2;
            break;
        case 0xfb: //11111011
            max = 50;
            P2 = 3;
            break;
        case 0xf7: //11110111
            max = 100;
            P2 = 4;
            break;
        }
    }
}
void Stop()interrupt 0
{
    onoff++;
    if (onoff > 1)
        onoff = 0;
}
void int1()interrupt 2
{
    direction++;
    if (direction > 1)
        direction = 0;
}
void delay50ms(void)
{
    unsigned char a, b;
    for(b = 173; b > 0; b--)
        for(a = 143; a > 0; a--);
}
void time()interrupt 1
{
    TH0 = (65536 - 10000) / 256;
    TL0 = (65536 - 10000) % 256;
    if (onoff == 1) //在開狀态下
    {
        if (n == max) //設定檔位速度,經過了max次中斷後,步進電機轉1/4圈
        {
            LED = 0; //每次n==max時LED閃爍
            delay50ms();
            LED = 1;
            if (direction == 0)
            {
                switch(index) //正轉時以AB,BC,CD,DA順序
                {
                case 0:P1 = 0x03;break; //00000011 AB高電平
                case 1:P1 = 0x06;break; //00000110 BC高電平
                case 2:P1 = 0x0c;break; //00001100 CD高電平
                case 3:P1 = 0x09;break; //00001001 DA高電平
                }
                index ++; 
                if (index == 4) //步進電機轉完一圈時index清零
                    index = 0;
                n = 0; //到達max,n重置為0
            }
            if (direction == 1)
            {
                switch(index) //反轉時以DA,CD,BC,AB順序
                {
                case 0:P1 = 0x09;break;
                case 1:P1 = 0x0c;break;
                case 2:P1 = 0x06;break;
                case 3:P1 = 0x03;break;
                }
                index ++;
                if (index == 4)
                    index = 0;
                n = 0;
            }
            else n = 0;
        }
        n++; //n!=max時,n++
    }
    else n = 0; //在關狀态下,n始終為0,無法觸發電機轉動
}      

繼續閱讀