⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stepper.c

📁 Stepper驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
//-----------------------------------------------------------------------------
void INT0_ISR (void) interrupt 2       // external interrupt 0 used for switch
{
      if(LED==OFF)                     // ignore switch if moving
      {
         if(Position==0)               // if home move to 100
         {
            move(1600);
         }
         else                          // if not home move to home
         {
            move(0);
         }
      }
}
//-----------------------------------------------------------------------------
// move
// This function calculates the profile and initializes the stepper
// motor. Function will abort if the target equals the Position or if
// the motor is still moving. Forward is set to 1 if target>Position.
// the length is calculated as the absolute value of Position minus
// target. For short moves less than 1024, MaxTableIndex is length
// divided by 4. For long moves, MaxTableIndex is set to 255.
//
// slewCount = length - 2 * MaxTableIndex - 1
//
// The slewcount is calculated by subtracting MaxTableIndex twice and
// decrementing. The TableIndex is initialized to zero.
//
void move (unsigned int target)
{
   unsigned int length;                // used to calculate length of move

   if (target != Position)             // abort if already there
   {
      if (target > Position)
      {
         Forward = 1;                  // set forward flag
         length = target - Position;   // subtract smaller (position)
      }
      else
      {
         Forward = 0;                  // clear forward flag
         length = Position - target;   // subtract smaller (target)
      }
      if (length < 1024)               // if short move
         MaxTableIndex = length>>2;    // divide length by 4
      else
         MaxTableIndex = 0xff;         // else max is 255
      SlewCount = length;              // build value in SlewCount
      SlewCount -= MaxTableIndex;      // subtract MaxTableIndex twice
      SlewCount -= MaxTableIndex;
      SlewCount--;                     // Subtract one to account first step
      TableIndex = 0;                  // init table index
      motorState = ACCELERATE;               // init motor state
      TL0 = -100;                      // move starts in 100 ticks
      TH0 = 0xFF;                      // extend sign
      LED = ON;                        // turn on LED
      ET0 = 1;                         // enable Timer0 interrupts
      TR0 = 1;                         // start Timer0
   }
      else
   {
      doneFlag=1;                       // if done display message
   }
}
//-----------------------------------------------------------------------------
// Timer_ISR()
// This is the timer interrupt service routine for the stepper motor.
// First the PatternIndex and Position are incremented or decremented
// depending on the direction of the motor. Then the new pattern is
// output to the stepper motor. Nested if..else statements are used to
// determine the if the motor is in the acceleration, slewing, or
// deceleration phase. The TableIndex and SlewCount are modified
// accordingly. When the move is complete, further output compares and
// interrupts are disabled.
//
void Timer_ISR (void) interrupt 1
{
   unsigned char TableValue;
   unsigned int offset;
   udblbyte time;

   if (Forward)                        // if forward
   {
      PatternIndex++;                  // increment step pattern
      PatternIndex &= 0x07;            // fix modulus 8 counter
      Position++;                      // increment Position
   }
   else
   {
      PatternIndex--;                  // decrement step pattern
      PatternIndex &= 0x07;            // fix modulus 8 counter
      Position--;                      // increment Position
   }
   // output step pattern, set bit 7 because it is an input
   P0 = StepPattern[PatternIndex] | 0x80;

   // determine motor state based on counter values
   if (SlewCount == 0)
      if (TableIndex == 0)
         motorState = DONE;
      else
         motorState = DECELERATE;
   else
      if (TableIndex < MaxTableIndex)
         motorState = ACCELERATE;
      else
         motorState = SLEWING;

   if (motorState == DONE)
   {
      ET0     = 0;                     // disable T0 interrupts
      TR0     = 0;                     // stop T0
      LED = OFF;                       // turn off LED
      doneFlag = 1;                    // display done message
   }
   else
   {
      // get value from table, multiply by T zero
      TableValue = StepTable[TableIndex];
      offset = MUL8x8(Tzero, TableValue);
      TR0 = 0;                         // stop Timer0
      time.b.lo = TL0;                 // read lo byte first
      time.b.hi = TH0;                 // read hi byte second
      time.w = time.w - offset;        // calculate new time
      TL0 = time.b.lo;                 // write lo byte first
      TH0 = time.b.hi;                 // write hi byte second
      TR0 = 1;                         // start Timer0
     if (motorState == DECELERATE)     // if decelerating
         TableIndex--;                 // decrement table index
      else if(motorState == ACCELERATE)// if accelerating
         TableIndex++;                 // increment table index
      else if (motorState == SLEWING)  // if slewing
         SlewCount--;                  // decrement slewCount
      ET0     = 1;                     // enable Timer0 interrupts
   }
}
//-----------------------------------------------------------------------------
unsigned int MUL8x8(unsigned char a, unsigned char b)
{
   unsigned int ab;
   ab = (unsigned int) a * b;          // cast a to int to trick compiler
   return ab;                          // return int
}
//-----------------------------------------------------------------------------
void puts(char *string)                // puts a string into send buffer
{
   while(*string)                      // while not null character
   {
      putc(*string);                   // put character at pointer in buffer
      string++;                        // increment pointer
   }
}
//-----------------------------------------------------------------------------
unsigned int getuint(void)             // get string and convert to int
{
   char theChar;
   unsigned int i;

   i=0;                                // build value in i
   theChar=getc();                     // get next character
   while( theChar<'0' || theChar>'9')  // while not 0-9
      theChar=getc();
   while(theChar>='0' && theChar<='9') // while 0-9
   {
      theChar -= '0';                  // convert from ASCII
      i *= 10;                         // shift decimal point
      i += theChar;                    // add next digit
      theChar=getc();
   }
   return i;                           // return int value
}
//-----------------------------------------------------------------------------
void putuint(unsigned int i)
{
   char string[7];                     // string used to build output
   char *sp;                           // string pointer

   sp=string + 6;                      // build back to front
   *sp=0;                              // insert null character
   do
   {
      sp--;                            // predecrement pointer
      *sp=i%10 + 0x30;                 // take modulus add 30
      i/=10;                           // divide i by 10
   } while (i);                        // while i not zero
                                       // now output front to back
   while (*sp)                         // while not null character
   {
      putc(*sp);                       // put character in buffer
      sp++;                            // increment pointer
   }
}
//-----------------------------------------------------------------------------
unsigned char  getuchar ()             // same as getuint but returns uchar
{
   char theChar;
   unsigned char i;
   i=0;                                // build value in i
   theChar=getc();                     // get next character
   while( theChar<'0' || theChar>'9')  // while not 0-9
      theChar=getc();
   while(theChar>='0' && theChar<='9') // while 0-9
   {
      theChar -= '0';                  // convert from ASCII
      i *= 10;                         // shift decimal point
      i += theChar;                    // add next digit
      theChar=getc();
   }
   return i;                           // return uchar value
}
//-----------------------------------------------------------------------------
void newline(void)                     // normally cr and lf are used together
{
   putc('\r');                         // output carriage return
   putc('\n');                         // output linefeed
}
//-----------------------------------------------------------------------------
// getc
// Gets a character from the read buffer using readc().
// The getc() function also echos the incoming keystrokes to the display;
//
char getc(void)
{
   char theChar;
   theChar=readc();                    // get character using readc
   writec(theChar);                    // echo characters to display
   return theChar;
}
//-----------------------------------------------------------------------------
// putc
// This is a totally unnecessary layer of abstraction. It is only used to be
// consistent with the getc function which requires an additional layer of
// abstraction to handle character echo.
//
void putc(char theChar)
{
   writec(theChar);
}
//-----------------------------------------------------------------------------
void readClear(void)                   // clears read buffer
{
   unsigned char i;
   readCount=0;
   readIndex=0;
   i = READ_BUFFER_SIZE;
   do
   {
      i--;                             // predecrement
      readBuffer[i]=0;                 // zero all data
   } while (i != 0);
}
//-----------------------------------------------------------------------------
void writeClear(void)                  // clears write buffer
{
   unsigned char i;
   writeCount=0;
   writeIndex=0;
   i = WRITE_BUFFER_SIZE;
   do
   {
      i--;                             // predecrement
      writeBuffer[i]=0;                // zero all data
   } while (i != 0);
}
//-----------------------------------------------------------------------------
// readc()
//
// The readc() function is the lowest level function which provides
// direct access to the read buffer. It reads one character from the
// read buffer.
//
// Note that readc will wait if the read buffer is empty. This is usually
// desired if the program is waiting for user input.
//
// readc is a driver function and is closely integrated with the ISR.
// UART interrupts are temporarily disabled while the buffer is updated,
// This prevents the ISR from modifying the buffer and counter values
// during processing. That would be bad.

char readc(void)
{
   char theChar;                       // the character to return
   signed char i;                      // signed value to build location
   while (readCount==0);               // wait here if buffer empty [blocking]
   ES0 = 0;                            // disable UART interrupts
   i = readIndex - readCount;          // back up by readcount
   if (i < 0)                          // fix value if out of range
      i+=READ_BUFFER_SIZE;
   theChar = readBuffer[i];            // get character from read buffer
   readCount--;                        // one less character in the buffer
   ES0 = 1;                            // enable UARt interrupt
   return theChar;                     // return the character
}
//-----------------------------------------------------------------------------
//
// writec()
//
// The writec() function is the lowest level function which allows access
// to the write buffer. It writes one character to the write buffer.
//
// Note that writec will wait if the write buffer is full. This is usually
// desired to prevent the write buffer from overflowing.
//
// writec is a driver function and is closely integrated with the ISR.
// UART interrupts are temporarily disabled while the buffer is updated to
// prevent the ISR from modifying the buffer and counter values during
// processing. That would be bad.

void writec(char theChar)
{
   // wait here if full [blocking]
   while (writeCount >= WRITE_BUFFER_SIZE);
   ES0 = 0;                            // disable UART interrupts
   writeBuffer[writeIndex] = theChar;  // put character in buffer at writeIndex
   writeIndex++;                       // increment index
   if (writeIndex >= WRITE_BUFFER_SIZE)// fix if out of range
      writeIndex = 0;
   writeCount++;                       // one more character in buffer
   if(TX_Idle)                         // if transmitter idle flag set
   {
      TI0 = 1;                         // force TX interrupt
      TX_Idle = 0;                     // idle no more
   }
   ES0 = 1;                            // enable UART interrupts
}
//-----------------------------------------------------------------------------
void uartISR(void) interrupt 4         // main UART interrupt service routine
{
   char dummy;
   signed char i;
                                       // Who done it?
   if(RI0 == 1)                        // Was it the receiver?
   {
      RI0 = 0;                         // yep, clear receiver flag
      // if not full
      if (readCount != READ_BUFFER_SIZE)
      {
         readBuffer[readIndex]= SBUF0; // read char from UART
         readIndex++;                  // increment index
         if (readIndex == READ_BUFFER_SIZE)
            readIndex = 0;             // fix if out of range
         readCount++;                  // one more in the buffer
      }
      else
      {
         dummy = SBUF0;                // drop characters dummy!
      }
   }
   if(TI0 == 1)                        // Was it the transmitter?
   {
      TI0 = 0;                         // yep, clear transmitter flag
      if (writeCount>0)                // if not empty
      {
         i = writeIndex - writeCount;  // calculate where to get it
         if (i < 0)                    // fix if out of range
            i+=WRITE_BUFFER_SIZE;
         SBUF0 = writeBuffer[i];       // write character to UART
         writeCount--;                 // one less in the buffer
      }
      else
      {
      TX_Idle = 1;                     // set idle flag when empty
      }
   }
}
//-----------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -