【问题标题】:Stepper Motor won't stop rotating步进电机不会停止旋转
【发布时间】:2017-12-19 21:48:28
【问题描述】:

我正在尝试让我的 28BYJ-48 步进电机旋转四分之一圈然后停止,但我无法在代码中实现它。我发现无论我在代码中输入的数字有多小,甚至以让我认为它可以正常工作的方式对其进行更改,我都无法让它停止旋转。下面是代码的有用部分。

#define STEPPER  (*((volatile uint32_t *)0x4000703C))

// Move 1.8 degrees clockwise, delay is the time to wait after each step
void Stepper_CW(uint32_t delay) {
  Pt = Pt->Next[clockwise];     // circular
  STEPPER = Pt->Out; // step motor

  if(Pos==199) {      // shaft angle
    Pos = 0;         // reset
  }
  else {
    Pos--; // CW
  }
 SysTick_Wait(delay);
}

// Move 1.8 degrees counterclockwise, delay is wait after each step
void Stepper_CCW(uint32_t delay) {
  Pt = Pt->Next[counterclockwise]; // circular
  STEPPER = Pt->Out; // step motor
  if(Pos==0) {        // shaft angle
    Pos = 199;         // reset
  }
  else {
    Pos++; // CCW
  }
 SysTick_Wait(delay); // blind-cycle wait
}

// Initialize Stepper interface
void Stepper_Init(void) {
  SYSCTL_RCGCGPIO_R |= 0x08; // 1) activate port D
  SysTick_Init();
  Pos = 0;                   
  Pt = &fsm[0]; 
                                // 2) no need to unlock PD3-0
  GPIO_PORTD_AMSEL_R &= ~0x0F;      // 3) disable analog functionality on PD3-0
  GPIO_PORTD_PCTL_R &= ~0x0000FFFF; // 4) GPIO configure PD3-0 as GPIO
  GPIO_PORTD_DIR_R |= 0x0F;             // 5) make PD3-0 out
  GPIO_PORTD_AFSEL_R &= ~0x0F;          // 6) disable alt funct on PD3-0
  GPIO_PORTD_DR8R_R |= 0x0F;            // enable 8 mA drive
  GPIO_PORTD_DEN_R |= 0x0F;         // 7) enable digital I/O on PD3-0 
}

// Turn stepper motor to desired position
// (0 <= desired <= 199)
// time is the number of bus cycles to wait after each step
void Stepper_Seek(uint8_t desired, uint32_t time) {
 short CWsteps;
  if((CWsteps = (desired-Pos))<0) {
   CWsteps+=200;
  } 

// CW steps is > 100
 if(CWsteps > 100) {
   while(desired != Pos) {
     Stepper_CCW(time);
   }
 }
 else {
   while(desired != Pos) {
    Stepper_CW(time);
   } 
 }
}

Stepper_Seek 在这里被调用...

#include <stdint.h>
#include "stepper.h"
#define T1ms 16000    // assumes using 16 MHz PIOSC (default setting for clock source)
int main(void) {
  Stepper_Init();
  Stepper_CW(T1ms);   // Pos=1; GPIO_PORTD_DATA_R=9
  Stepper_CW(T1ms);   // Pos=2; GPIO_PORTD_DATA_R=5
  Stepper_CW(T1ms);   // Pos=3; GPIO_PORTD_DATA_R=6
  Stepper_CW(T1ms);   // Pos=4; GPIO_PORTD_DATA_R=10
  Stepper_CW(T1ms);   // Pos=5; GPIO_PORTD_DATA_R=9
  Stepper_CW(T1ms);   // Pos=6; GPIO_PORTD_DATA_R=5
  Stepper_CW(T1ms);   // Pos=7; GPIO_PORTD_DATA_R=6
  Stepper_CW(T1ms);   // Pos=8; GPIO_PORTD_DATA_R=10
  Stepper_CW(T1ms);   // Pos=9; GPIO_PORTD_DATA_R=9
  Stepper_CCW(T1ms);  // Pos=8; GPIO_PORTD_DATA_R=10
  Stepper_CCW(T1ms);  // Pos=7; GPIO_PORTD_DATA_R=6
  Stepper_CCW(T1ms);  // Pos=6; GPIO_PORTD_DATA_R=5
  Stepper_CCW(T1ms);  // Pos=5; GPIO_PORTD_DATA_R=9
  Stepper_CCW(T1ms);  // Pos=4; GPIO_PORTD_DATA_R=10
  Stepper_Seek(8,T1ms);// Pos=8; GPIO_PORTD_DATA_R=10
  Stepper_Seek(0,T1ms);// Pos=0; GPIO_PORTD_DATA_R=10
  while(1) {
    Stepper_CW(10*T1ms);   // output every 10ms
  }
}

我认为它可能是它一直在重置它的位置并在它重置后重新开始,但即使在注释掉它不会修复的行之后。

提前谢谢大家!

【问题讨论】:

  • 您能否发布代码来说明您如何使用这些步进函数(例如,在哪里调用了 Stepper_Seek 等)?
  • 在您更新 Pos 的位置添加输出/调试语句,并将其与 desired 进行比较。另请注意,您有评论 CW steps is 0 to 199 并且下一行将 CWsteps 与 100 进行比较。只是一个危险信号......
  • 翻转逻辑是向后的。 Pos-- 需要匹配检查是否达到 0,Pos++ 需要检查是否达到 199。

标签: c syntax microcontroller keil stepper


【解决方案1】:

您的环绕逻辑在Stepper_CW()Stepper_CCW() 中都是向后的。以前者为例。假设您试图达到 198,而 Pos 最初是 1:

  1. 第一次调用时,Pos 减为 0。这不等于 198,因此再次调用该函数。
  2. 第二次调用时,Pos 递减为 199。这不等于 198,因此再次调用该函数。
  3. 在第三次调用时,会触发回绕情况,并将 Pos 设置为 0。这不等于 198 ....

第(3)步后的状态与第(1)步后的状态相同——无限循环。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-18
    • 1970-01-01
    相关资源
    最近更新 更多