zoukankan      html  css  js  c++  java
  • 51单片机 | 实现四相步进电机控制实例

    ————————————————————————————————————————————

    工作原理见书《51单片机应用及原理——基于KeilC和Proteus,陈海宴》P178-180

    ————————————————————————————————————————————

    步进电机控制应用实例

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

    设计要求:

    • 采用定时中断方式控制步进机的转速,定时单位时长为10ms
    • 速度设置在1/2/3/4四个档位,1档最快,依次递减,能够控制步进电机的停、转和方向,同时显示步进机的当前档位。

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

    设计思路:

    • 通过P1控制步进电机的转动,P1.0->aP1.1->bP1.2->cP1.3->d,ULN2003A作为步进电机驱动
    • P2.0-P2.3对应数码管显示(使用7447芯片对应将BCD码转换成7LED数码管),通过7447简单驱动数码管(P2只需要发送1/2/3/4即可)
    • 通过定时器计数,到达设定值时步进电机转动1/4圈,计数清零

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

    元件清单:

    • AT89C51
    • BUTTON
    • MOTOR-STEPPER
    • RESPACK-8
    • 7SEG-COM-ANODE
    • ULN2003A
    • 7447

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

    实现代码:

      1 #include <reg52.h>
      2 typedef unsigned char uchar;
      3 uchar direction = 0;  //0为正转,1为反转
      4 uchar onoff = 0; //关为0,开为1
      5 uchar n = 0; //每次定时器中断触发时n++,当n==max时电机转动1/4
      6 uchar max = 10;
      7 uchar index = 0; //通过index指示电机转动,AB,BC,CD,DA
      8 sbit LED = P3 ^ 7; //当n==max时LED闪烁提示
      9 int main()
     10 {
     11     /* LED */
     12     P2 = 0xff;
     13     /* 初始化中断 */
     14     EA = 1;
     15     EX0 = 1; //要用到的中断是两个外部中断和定时器中断0
     16     IT0 = 1;
     17     EX1 = 1;
     18     IT1 = 1;
     19     ET0 = 1;
     20     /* 定时器0 */
     21     TMOD = 0x01; //使用定时器0,方式1
     22     TH0 = (65536 - 10000) / 256; //12MHz晶振下,定时器为10ms触发中断,更方便观察转动情况
     23     TL0 = (65536 - 10000) % 256;
     24     TR0 = 1;
     25     while(1)
     26     {
     27         switch(P0)
     28         {
     29         case 0xfe: //11111110
     30             max = 1;
     31             P2 = 1;
     32             break;
     33         case 0xfd: //11111101
     34             max = 10;
     35             P2 = 2;
     36             break;
     37         case 0xfb: //11111011
     38             max = 50;
     39             P2 = 3;
     40             break;
     41         case 0xf7: //11110111
     42             max = 100;
     43             P2 = 4;
     44             break;
     45         }
     46     }
     47 }
     48 void Stop()interrupt 0
     49 {
     50     onoff++;
     51     if (onoff > 1)
     52         onoff = 0;
     53 }
     54 void int1()interrupt 2
     55 {
     56     direction++;
     57     if (direction > 1)
     58         direction = 0;
     59 }
     60 void delay50ms(void)
     61 {
     62     unsigned char a, b;
     63     for(b = 173; b > 0; b--)
     64         for(a = 143; a > 0; a--);
     65 }
     66 void time()interrupt 1
     67 {
     68     TH0 = (65536 - 10000) / 256;
     69     TL0 = (65536 - 10000) % 256;
     70     if (onoff == 1) //在开状态下
     71     {
     72         if (n == max) //设定档位速度,经过了max次中断后,步进电机转1/4圈
     73         {
     74             LED = 0; //每次n==max时LED闪烁
     75             delay50ms();
     76             LED = 1;
     77             if (direction == 0)
     78             {
     79                 switch(index) //正转时以AB,BC,CD,DA顺序
     80                 {
     81                 case 0:P1 = 0x03;break; //00000011 AB高电平
     82                 case 1:P1 = 0x06;break; //00000110 BC高电平
     83                 case 2:P1 = 0x0c;break; //00001100 CD高电平
     84                 case 3:P1 = 0x09;break; //00001001 DA高电平
     85                 }
     86                 index ++; 
     87                 if (index == 4) //步进电机转完一圈时index清零
     88                     index = 0;
     89                 n = 0; //到达max,n重置为0
     90             }
     91             if (direction == 1)
     92             {
     93                 switch(index) //反转时以DA,CD,BC,AB顺序
     94                 {
     95                 case 0:P1 = 0x09;break;
     96                 case 1:P1 = 0x0c;break;
     97                 case 2:P1 = 0x06;break;
     98                 case 3:P1 = 0x03;break;
     99                 }
    100                 index ++;
    101                 if (index == 4)
    102                     index = 0;
    103                 n = 0;
    104             }
    105             else n = 0;
    106         }
    107         n++; //n!=max时,n++
    108     }
    109     else n = 0; //在关状态下,n始终为0,无法触发电机转动
    110 }

     

  • 相关阅读:
    BZOJ2219数论之神——BSGS+中国剩余定理+原根与指标+欧拉定理+exgcd
    Luogu 3690 Link Cut Tree
    CF1009F Dominant Indices
    CF600E Lomsat gelral
    bzoj 4303 数列
    CF1114F Please, another Queries on Array?
    CF1114B Yet Another Array Partitioning Task
    bzoj 1858 序列操作
    bzoj 4852 炸弹攻击
    bzoj 3564 信号增幅仪
  • 原文地址:https://www.cnblogs.com/hughdong/p/6899512.html
Copyright © 2011-2022 走看看