Stepper motor reference position example from today’s class

//
// Stepper control example for dsPIC30F4011
// Written by Ted Burke
// Last updated 13-10-2016
//

#include <xc.h>
#include <libpic30.h>
#include <stdio.h>

_FOSC(CSW_FSCM_OFF & FRC_PLL16); // Clock speed = 7.5MHz x 16, i.e. 30 MIPS
_FWDT(WDT_OFF);                  // Watchdog timer off
_FBORPOR(MCLR_DIS);              // Disable reset pin

#define STEP_DELAY 150000

// Function prototype for step functions and analog read
void step_forward();
void step_back();
void steps(int count);
unsigned int read_analog_channel(int channel);

int main()
{
    // Configure digital I/O
    TRISD = 0b0000; // One digital output for each winding
    LATD  = 0b0000; // Initially, all windings are off
    
    // Setup UART
    U1BRG = 48;            // 38400 baud @ 30 MIPS
    U1MODEbits.UARTEN = 1; // Enable UART
 
    // Configure AN0-AN8 as analog inputs
    ADCON3bits.ADCS = 15;  // Tad = 266ns, conversion time is 12*Tad
    ADCON1bits.ADON = 1;   // Turn ADC ON
 
    // Move to reference position by stepping until the analog
    // voltage from the colour sensor exceeds a threshold
    while(read_analog_channel(0) < 512) step_forward();
    
    // Stay still for 2 seconds
    __delay32(60000000);
    
    // Then start ticking once every second (approx)
    while(1)
    {
        steps(34);
        __delay32(30000000);
    }
    
    return 0;
}

// This function moves the stepper motor through
// the steps specific in the "count" argument.
// Positive values result in forward steps.
// Negative values result in backwards steps.
void steps(int count)
{
    while (count > 0)
    {
        step_forward();
        count--;
    }
    
    while (count < 0)
    {
        step_back();
        count++;
    }
}

void step_forward()
{
    if      (LATD == 0b0001) LATD = 0b0010;
    else if (LATD == 0b0010) LATD = 0b0100;
    else if (LATD == 0b0100) LATD = 0b1000;
    else                     LATD = 0b0001;
    
    __delay32(STEP_DELAY);
}

void step_back()
{
    if      (LATD == 0b0001) LATD = 0b1000;
    else if (LATD == 0b0010) LATD = 0b0001;
    else if (LATD == 0b0100) LATD = 0b0010;
    else                     LATD = 0b0100;
    
    __delay32(STEP_DELAY);
}

// This function reads a single sample from the specified
// analog input. It should take less than 5us when the
// microcontroller is running at 30 MIPS.
// The dsPIC30F4011 has a 10-bit ADC, so the value
// returned is between 0 and 1023 inclusive.
unsigned int read_analog_channel(int channel)
{
    ADCHS = channel;          // Select the requested channel
    ADCON1bits.SAMP = 1;      // Start sampling
    __delay32(30);            // 1us delay @ 30 MIPS
    ADCON1bits.SAMP = 0;      // Start Converting
    while (!ADCON1bits.DONE); // Should take 12 * Tad = 3.2us
    return ADCBUF0;
}
Advertisements
This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s