I'm trying to get my 28BYJ-48 Stepper Motor to rotate one quarter of a revolution and then stop, but I'm having trouble implementing that in code. What I find is no matter how small I make the numbers in my code or even alter it in ways that make me think it'd work properly, I can't get it to stop rotating. Below is the helpful part of the code.
#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 gets called here...
#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
}
}
I thought it could have been that it kept resetting its position and starting again after it reset but even after commenting out the line it wouldn't fix.
Thank you everyone in advance!
Your wrap-around logic is backward in both Stepper_CW()
and Stepper_CCW()
. Take the former as the example. Suppose you're trying to reach 198, and Pos
is initially 1:
Pos
is decremented to 0. This is unequal to 198, so the function is called again.Pos
is decremented to 199. This is unequal to 198, so the function is called again.Pos
is set to 0. This is unequal to 198 ....The state after step (3) is the same as the state after step (1) -- infinite loop.
User contributions licensed under CC BY-SA 3.0