单片机控制35BYJ46 型步进电机正反转

发布时间 2023-07-14 16:57:40作者: steven_lg

原理
正转方向的环形分配器编码为
A→AB→B→BC→C→CD→D→DA→A,则反转环形分配
器编码为 A→DA→D→CD→C→BC→B→AB→A。
1.不进电机正反转

void motor_step(uint8_t dir)
{
  static step = 0;
  if(dir == 1)      //反转
  {
     if(step == 0)
    {
      step = 8;
    }
    step--;
  }
  if(step == 0)
  {
    MOTOR_A = 1;
    MOTOR_B = 0;
    MOTOR_C = 0;
    MOTOR_D = 0;
  }
  else if(step == 1)
  {
    MOTOR_A = 1;
    MOTOR_B = 1;
    MOTOR_C = 0;
    MOTOR_D = 0;
  }
  else if(step == 2)
  {
    MOTOR_A = 0;
    MOTOR_B = 1;
    MOTOR_C = 0;
    MOTOR_D = 0;
  }
  else if(step == 3)
  {
    MOTOR_A = 0;
    MOTOR_B = 1;
    MOTOR_C = 1;
    MOTOR_D = 0;
  }
  else if(step == 4)
  {
    MOTOR_A = 0;
    MOTOR_B = 0;
    MOTOR_C = 1;
    MOTOR_D = 0;
  }
  else if(step == 5)
  {
    MOTOR_A = 0;
    MOTOR_B = 0;
    MOTOR_C = 1;
    MOTOR_D = 1;
  }
  else if(step == 6)
  {
    MOTOR_A = 0;
    MOTOR_B = 0;
    MOTOR_C = 0;
    MOTOR_D = 1;
  }
  else if(step == 7)
  {
    MOTOR_A = 1;
    MOTOR_B = 0;
    MOTOR_C = 0;
    MOTOR_D = 1;
  }

  if(dir == 0)      //正转
  {
    step ++;
    if(step == 8)
    {
      step = 0;
    }
  }
}

2.角度控制

void motor_run(void)
{

  static uint16_t step1angle;
  static uint16_t step2angle;

  if(motor_runflg)
  {
    if(step_freq > 9)
    {
      step_freq = 0;
      if(stepseg == 0)        //step1
      {
        stepcnt ++;
        motor_step(0);        //正转
        if(stepcnt > 1360)    //正转120 寻找0初始位置
        {
          stepseg = 1;
          stepcnt = 0;
      
          if(ledstate & 0x0010)         //120
          {
            step1angle = 1360;          //(120/360) * 4080 = 1360
            step2angle = 1360;
          }
          else if(ledstate & 0x0020)    //90
          {
            step1angle = 1190;          //105
            step2angle = 1020;          //90
          }
          else if(ledstate & 0x0040)    //60
          {
            step1angle = 1020;          //90
            step2angle = 680;           //60
          }
        }
      }
      else if(stepseg == 1)   //step2 反转120 反转105 反转90
      {
        stepcnt ++;
        motor_step(1);        //反转
        if(stepcnt > step1angle)
        {
          stepseg = 2;
          stepcnt = 0;
        }
      } 
      else if(stepseg == 2)   //step3 反转120
      {
        stepcnt ++;
        motor_step(0);        //正转
        if(stepcnt > step2angle)
        {
          stepseg = 3;
          stepcnt = 0;
        }
      }
      else if(stepseg == 3)     //step4 反转120
      {
        stepcnt ++;
        motor_step(1);          //反转
        if(stepcnt > step2angle)
        {
          stepseg = 2;
          stepcnt = 0;
        }
      }
    }  
  }
  else
  {
    motor_stop();
    stepseg = 0;      //换挡记的清楚该位
    stepcnt = 0;      //换挡记的清楚该位
  }
}