Jump to content
43oh

simple stepper control


Recommended Posts


// * DATE: 1/21/2013

// * DESCRIPTION: Simple program to run 8 lead stepper motor at half-steps

 

#include "msp430g2452.h"

 

volatile unsigned short a = 1;

volatile unsigned short i = 1;

volatile unsigned short j = 2;

volatile unsigned short k = 3;

volatile unsigned short l = 4;

volatile unsigned short m = 5;

volatile unsigned short n = 6;

volatile unsigned short o = 7;

volatile unsigned short p = 8;

 

/* MAIN */

 

void main(void) {

 

   WDTCTL = WDTPW + WDTHOLD;               // Stop watchdog timer

 

   P1DIR &= ~BIT3;

   P1IE |= BIT3;

 

   P1DIR |= BIT0;                        // Set P1.0 to output direction

 

   P1DIR |= BIT1;                        // Set P1.6 to output direction

 

   P1DIR |= BIT2;                        // Set P1.1 to output direction

 

   P1DIR |= BIT4;                        // Set P1.2 to output direction

 

   TA0CCR0 = 15000;               // Count limit (16 bit)

 

   TA0CCTL0 = 0x10;               // Enable counter interrupts, bit 4=1

 

   TA0CTL = TASSEL_1 + MC_1;          // Timer A 0 with ACLK @ 12KHz, count UP

 

   _BIS_SR(LPM0_bits + GIE);                            // LPM0 (low power mode) interrupts enabled

}

 

#pragma vector = TIMER0_A0_VECTOR

   __interrupt void Timer0_A0 (void) {             // Timer0 A0 interrupt service routine

 

    if (i == a)

   {P1OUT ^= BIT0;                  

    P1OUT = BIT0;

   }

 

    if (j == a)

    {P1OUT ^= BIT0 + BIT1;               

     P1OUT = BIT0 + BIT1;

    }

 

    if (k == a)

    {P1OUT ^= BIT1;                  

     P1OUT = BIT1;

    }

 

    if (l == a)

    {P1OUT ^= BIT1 + BIT2;               

     P1OUT = BIT1 + BIT2;

    }

 

    if (m == a)

    {P1OUT ^= BIT2;                  

     P1OUT = BIT2;

    }

 

    if (n == a)

    {P1OUT ^= BIT2 + BIT4;               

     P1OUT = BIT2 + BIT4;

    }

 

    if (o == a)

    {P1OUT ^= BIT4;                  

     P1OUT = BIT4;

    }

 

    if (p == a)

    {P1OUT ^= BIT4 + BIT0;               

     P1OUT = BIT4 + BIT0;

     a = 0;

    }

 

    a = a+1;

 

}

 

#pragma vector = PORT1_VECTOR

   __interrupt void button_push_isr(void)                        // Push Button Interrupt

{

     P1IFG &= ~BIT3;                                                 // Clear P1.0 Button Flag

     TA0CCTL0 = 0;

     _BIS_SR(LPM0_bits + CPUOFF);                         // LPM0 (low power mode) interrupts enabled

 

}

Edited by bluehash
Code Tagged.
Link to post
Share on other sites


#pragma vector = TIMER0_A0_VECTOR

__interrupt void Timer0_A0 (void)              // Timer0 A0 interrupt service routine

{

    static const uint8_t steps[8] = {

#if 0   // Full step

        BIT0 | BIT1,

        BIT0 | BIT1,

               BIT1 | BIT2,

               BIT1 | BIT2,

                      BIT2 | BIT4,

                      BIT2 | BIT4                               

        BIT0 |               BIT4,

        BIT0 |               BIT4

#else   // Half step

        BIT0 | BIT1,

               BIT1,

               BIT1 | BIT2,

                      BIT2,

                      BIT2 | BIT4,

                             BIT4,

        BIT0 |               BIT4,

        BIT0

#endif

    };

    static unsigned step = 0;

    

    P1OUT = (P1OUT & ~(BIT0 | BIT1 | BIT2 | BIT4)) | steps[7 & step++];

}

 

Link to post
Share on other sites
#pragma vector = TIMER0_A0_VECTOR
__interrupt void Timer0_A0 (void)              // Timer0 A0 interrupt service routine
{
    static const uint8_t steps[8] = {
#if 0   // Full step
        BIT0 | BIT1,
        BIT0 | BIT1,
               BIT1 | BIT2,
               BIT1 | BIT2,
                      BIT2 | BIT4,
                      BIT2 | BIT4                               
        BIT0 |               BIT4,
        BIT0 |               BIT4
#else   // Half step
        BIT0 | BIT1,
               BIT1,
               BIT1 | BIT2,
                      BIT2,
                      BIT2 | BIT4,
                             BIT4,
        BIT0 |               BIT4,
        BIT0
#endif
    };
    static unsigned step = 0;
    
    P1OUT = (P1OUT & ~(BIT0 | BIT1 | BIT2 | BIT4)) | steps[7 & step++];
}

I am still just a noob here oPossum, so any help in streamlining code is appreciated. Regarding your revised version, just to be clear for my understanding, you have omitted the push button interrupt, correct? Again, thanks for showing us the light, best regards. 

Link to post
Share on other sites
  • 3 weeks later...

Why do you first toggle the output pins and then write the output register? I think you probably want to toggle, but only by one output at the same time.

// required sequence   assume start condition is BIT4 + BIT0 high
BIT0 high              toggle BIT4 (BIT4 + BIT0 with BIT4 toggled is BIT0)
BIT0 + BIT1 high       toggle BIT1
BIT1 high              toggle BIT0
BIT1 + BIT2 high       toggle BIT2
BIT2 high              toggle BIT1
BIT2 + BIT4 high       toggle BIT4
BIT4 high              toggle BIT2
BIT4 + BIT0 high       toggle BIT0

You could use a switch statement instead of your series of ifs (which could use constant values instead of the letters i to p)

#pragma vector = TIMER0_A0_VECTOR
   __interrupt void Timer0_A0 (void) {             // Timer0 A0 interrupt service routine

   switch(a)
   {
      case i:
         P1OUT ^= BIT4;                  
         break;
      case j:
         P1OUT ^= BIT1;               
         break;
      case k:
         P1OUT ^= BIT0;                  
         break;
      case l:
         P1OUT ^= BIT2;               
         break;
      case i:
         P1OUT ^= BIT1;                  
         break;
      case j:
         P1OUT ^= BIT4;               
         break;
      case i:
         P1OUT ^= BIT2;                  
         break;
      case j:
         P1OUT ^= BIT0;               
         break;
   }
   a = a+1;
}

Or you could use a look-up table, but you can only do so if your counted values are sequential (which they are in your case)

void main(void) {

   WDTCTL = WDTPW + WDTHOLD;               // Stop watchdog timer

   P1DIR &= ~BIT3;
   P1IE |= BIT3;

   P1DIR |= BIT0 | BIT1 | BIT2 | BIT4;   // Set P1.0, P1.1, P1.2 and P1.4 to output direction

   P1OUT |= BIT0 | BIT4;

   TA0CCR0 = 15000;               // Count limit (16 bit)

   TA0CCTL0 = 0x10;               // Enable counter interrupts, bit 4=1

   TA0CTL = TASSEL_1 | MC_1;          // Timer A 0 with ACLK @ 12KHz, count UP

   _BIS_SR(LPM0_bits | GIE);                            // LPM0 (low power mode) interrupts enabled
}

#pragma vector = TIMER0_A0_VECTOR
   __interrupt void Timer0_A0 (void) {             // Timer0 A0 interrupt service routine

   const unsigned char toggles[8] = {BIT4, BIT1, BIT0, BIT2, BIT1, BIT4, BIT2, BIT0};
   static unsigned short a; // a does not need to be volatile, since it is not used/depended upon outside the ISR

   P1OUT ^= toggles[a];
   a += 1;
   if (a == 8) a = 0;
}

#pragma vector = PORT1_VECTOR
   __interrupt void button_push_isr(void)                        // Push Button Interrupt
{
     P1IFG &= ~BIT3;                                                 // Clear P1.0 Button Flag
     TA0CCTL0 = 0;
     // After the ISR is left, the MSP430 will return to LPM automatically; don't go to LPM inside the ISR!
}
Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...