c - 步进电机不会停止旋转

标签 c syntax microcontroller keil stepper

我试图让我的 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_CW()Stepper_CCW() 中都是落后的。以前者为例。假设您尝试达到 198,而 Pos 最初为 1:

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

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

关于c - 步进电机不会停止旋转,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47895681/

相关文章:

c - 在信号量中排队 - 甚至可能吗?

C Printf in while 和 if 循环打印两次

css - 在哪里可以找到 Neo4j GRASS 语言的语法概述?

c - #define 语法解决方案

c++ - 我在微 Controller stm32f373 发现中点亮 LED 时遇到问题

c - 使用正常退出管理可变数量的工作线程

mysql - C - 预处理 mysql 数据,同时有效地维护文件写入的原始副本

c# - 无法访问已实现的属性(从接口(interface))

linux - 使用 SD 卡作为 Beaglebone Black 的外部存储

linux - Mspdebug 收不到数据