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

📄 stepper.c

📁 CYGNAL单片机
💻 C
📖 第 1 页 / 共 2 页
字号:
//-----------------------------------------------------------------------------
// Stepper.c
//-----------------------------------------------------------------------------
// Copyright 2003 Silicon Laboratories, Inc.
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include <c8051f300.h>                 // include SFR declarations
//-----------------------------------------------------------------------------
// defines and typedefs
//-----------------------------------------------------------------------------
#define SYSCLK       24500000          // SYSCLK frequency in Hz
#define BAUDRATE     57600             // Baud rate of UART in bps

#define READ_BUFFER_SIZE 16            // change UART receive buffer size here
#define WRITE_BUFFER_SIZE 16           // change UART receive buffer size here

#define ON 0                           // LED is active low
#define OFF 1
#define ACCELERATE 3                   // motor states
#define SLEWING 2
#define DECELERATE 1
#define DONE 0
#define INIT_TZERO 80                  // Tzero used at start-up and with
                                       // manual mode, change value here for
                                       // different stepper motors

typedef union                          // union used for writing to TL0 & TH0
    {
        struct
        {
            unsigned char hi;
            unsigned char lo;
        } b;
        unsigned int w;
    }udblbyte;
//-----------------------------------------------------------------------------
// Global CONSTANTS
//-----------------------------------------------------------------------------
//
// half step stepper motor step pattern
// transistors are in order  B-,B+,A-,A+
//
// 0x01 = 0001
// 0x05 = 0101
// 0x04 = 0100
// 0x06 = 0110
// 0x02 = 0010
// 0x0A = 1010
// 0x08 = 1000
// 0x09 = 1001

const unsigned char code StepPattern[8]=
   {0x01,0x05,0x04,0x06,0x02,0x0A,0x08,0x09};
//
// stepper motor linear velocity profile
// 255 * [sqrt(n+1)-sqrt(n)]
// n = 0 to 255
//
const unsigned char code StepTable[256]=
{
   0xFF, 0x69, 0x51, 0x44, 0x3C, 0x36, 0x32, 0x2E,
   0x2B, 0x29, 0x27, 0x25, 0x24, 0x22, 0x21, 0x20,
   0x1F, 0x1E, 0x1D, 0x1C, 0x1C, 0x1B, 0x1A, 0x1A,
   0x19, 0x19, 0x18, 0x18, 0x17, 0x17, 0x17, 0x16,
   0x16, 0x16, 0x15, 0x15, 0x15, 0x14, 0x14, 0x14,
   0x14, 0x13, 0x13, 0x13, 0x13, 0x12, 0x12, 0x12,
   0x12, 0x12, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
   0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
   0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
   0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E,
   0x0E, 0x0E, 0x0E, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
   0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
   0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
   0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
   0x0C, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B,
   0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B,
   0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0A, 0x0A,
   0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
   0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
   0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
   0x0A, 0x0A, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09,
   0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
   0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
   0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
   0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
   0x09, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
   0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
   0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
   0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
   0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
   0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
   0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x07
};
//-----------------------------------------------------------------------------
// Function PROTOTYPES
//-----------------------------------------------------------------------------
//
// main and user interface functions
void SYSCLK_Init (void);               // initialize port pins and crossbar
void PORT_Init (void);                 // initialize system clock and watchdog
void Timer_Init (void);                // initialize timer for Motor and UART
void UART_Init (void);                 // initialize UART
void Motor_Init(void);                 // initialize Motor variables
void doneMsg(void);                    // display done message
void error(void);                      // display error message
void delay (void);                     // delay used for position updating
void INT0_ISR (void);                  // external interrupt used for SW2
//
// stepper motor control functions
void move (unsigned int);
void Timer_ISR (void);
unsigned int MUL8x8(unsigned char, unsigned char);
//
//  BUFFERED UART FUNCTION PROTOTYPES
//--Top Level - User Functions ------------------------------------------------

// put a string into transmit buffer, used to display text messages
void puts (char *);

// converts a 16 bit number to a string of ASCII characters
// and stores the characters into the transmit buffer
void putuint(unsigned int);

// converts an 8 bit number to a string of ASCII characters
// and stores the characters into the transmit buffer
void putuchar(unsigned char);

// retrieves ASCII characters from the receiver buffer
// and converts a string of digits into an 8-bit number
unsigned char getuchar(void);

// retrieves ASCII characters from the receiver buffer
// and converts a string of digits into an 16bit number
unsigned int getuint(void);

void newline(void);                    // outputs carriage return & line feed


//----------Middle Level - Primitive User Functions ---------------------------

// retrieves one character from the receive buffer using readc and echoes
// the character to the transmit buffer
char getc (void);

// stores one character into the transmit buffer using writec
void putc (char);

void readClear(void);                  // clears read buffer

void writeClear(void);                 // clears write buffer

//----------------Lowest level - Hardware access functions --------------------
char readc (void);                     // pulls one character directly
                                       // from the receive buffer

void writec (char);                    // writes one character directly
                                       // to the transmit buffer

//-----------------------------------------------------------------------------
// Global VARIABLES
//-----------------------------------------------------------------------------
//
// user interface variables
sbit LED     = P0 ^ 6;                 // bit set high to turn LED on
//
// Stepper Motor Variables
unsigned int Position;                 // current motor position
unsigned char TableIndex;              // index for stepper motor table
unsigned char MaxTableIndex;           // maximum index for desired profile
unsigned int SlewCount;                // down counter for slewing phase
unsigned char Tzero;                   // initial period, sqrt(2/alpha)
unsigned char PatternIndex;            // index for step pattern, modulus 8 counter
bit Forward;                           // 1 for forward, 0 for reverse
bit doneFlag;                          // done flag used for Timer ISR handshake
unsigned char motorState;              // motor state variable
//
// UART Global Variables

// UART receiver buffer
char idata readBuffer[READ_BUFFER_SIZE];
// UART transmitter buffer
char idata writeBuffer[WRITE_BUFFER_SIZE];
unsigned char writeIndex;              // points to next free write byte
unsigned char readIndex;               // points to next free read byte
unsigned char writeCount;              // number of bytes in write buffer
unsigned char readCount;               // number of bytes in read buffer
bit TX_Idle;                           // flag set when TX buffer is empty
//-----------------------------------------------------------------------------
// MAIN Routine
//-----------------------------------------------------------------------------
//
// The main function initializes everything and then services the user
// interface. The user interface parses characters from the UART and
// executes basic commands. There are three interrupt service routines
// which function in the background - The Timer_ISR which controls the
// stepper motor; The UART_ISR which moves characters to/from the buffers;
// and the INT0_ISR that handles the pushbutton switch commands.
//
void main (void)
{
   char theChar;                       // the character to be parsed
   unsigned int newP;                  // new position to move to

   SYSCLK_Init ();                     // Init system clock to 24.5MHz
   PORT_Init ();                       // Init crossbar and GPIO
   Timer_Init();                       // Init T0 for stepper motor and
                                       // T1 for Baud rate
   UART_Init();                        // Init UART
   Motor_Init();                       // Init motor global variables
   EA = 1;                             // enable global interrupts

   putc('>');                          // display prompt

    while(1)                           // main loop
    {
      if(LED==ON)                      // display position while moving
      {
         putuint(Position);            // display position
         puts("    ");                 // blank out trailing characters
         putc('\r');                   // overwrite line by not using linefeed
         delay();                      // delay sets display update rate
      }
      else
      {
         if(doneFlag)
         {
            doneMsg();                 // if done display message
         }
         theChar = getc();             // get character to be parsed
         switch(theChar)               // parse character
         {
            case '\r':                 // if return character
               putc('\n');             // linefeed with no carriage return
               putc('>');              // display prompt
               break;
            case 'p':                  // p for new position
               newP = getuint();       // get number as unsigned integer
               newline();
               puts("Moving...");      // display moving status indicator
               newline();
               puts("Position:");      // display position tag
               newline();
               move(newP);             // initiate move to new position
               break;
            case 'a':                  // a for change acceleration
               Tzero = getuchar();     // get number as unsigned character
               newline();
               puts("Acceleration:");  // confirm acceleration changed
               newline();
               putuint(Tzero);         // display new acceleration
               newline();
               putc('>');
               break;
            case 's':                  // s for display status
               newline();
               puts("Position:");      // display position tag
               newline();
               putuint(Position);      // display position value
               newline();
               puts("Acceleration:");  // display acceleration tag
               newline();
               putuint(Tzero);         // display acceleration value
               newline();
               putc('>');              // display prompt
               break;
            default:
               error();                // display error message
         }
      }
    }
}
//-----------------------------------------------------------------------------
// SYSCLK_Init
//-----------------------------------------------------------------------------
//
// This routine initializes the system clock to use the internal 24.5MHz
// oscillator as its clock source.  Also enables missing clock detector reset.
//
void SYSCLK_Init (void)
{
   OSCICN = 0x07;                      // set SYSCLK to OSC frequency
   RSTSRC = 0x04;                      // enable missing clock detector
   PCA0MD &= ~0x40;                    // disable watchdog timer
}

//-----------------------------------------------------------------------------
// PORT_Init
//-----------------------------------------------------------------------------
//
// Configure the Crossbar and GPIO ports.
// P0.0 - A+
// P0.1 - A-
// P0.2 - B+
// P0.3 - B-
// P0.4 - Txd
// P0.5 - Rxd
// P0.6 - LED
// P0.7 - C2D/Switch
//
void PORT_Init (void)
{
   XBR0 = 0x4F;                        // Crossbar Register 1
   XBR1 = 0x03;                        // Crossbar Register 2
   XBR2 = 0x40;                        // Crossbar Register 3
   P0 = 0xC0;                          // Turn off MOSFETs, Set P0.6 & P0.7
   P0MDOUT = 0x5F;                     // Output configuration for P0
   P0MDIN = 0xFF;                      // Input configuration for P0
   IP = 0x02;                          // T0 high priority, others low
   IT01CF = 0x70;                      // use P0.7 for INT1
   IT1 = 1;                            // edge sensitive interrupt
   IE1 = 0;                            // clear external interrupt
   EX1 = 1;                            // enable external interrupt 1
}
//-----------------------------------------------------------------------------
void Timer_Init (void)
{
   CKCON = 0x12;                       // T1 uses sysclk, T0 uses /48,
   TMOD = 0x21;                        // T1 mode 2, T0 mode 1
}
//-----------------------------------------------------------------------------
void UART_Init(void)
{
   SCON0   = 0x10;                     // mode 1, 8-bit UART, disable receiver
   TH1    = 0x2C;                      // set Timer1 reload value for 57600
   TR1    = 1;                         // start Timer1
   TX_Idle = 1;                        // set idle flag
   readClear();                        // zero out read buffer
   writeClear();                       // zero out write buffer
   ES0 = 1;                            // enable UART interrupt
}
//-----------------------------------------------------------------------------
void Motor_Init()
{
   Tzero = INIT_TZERO;                       // initialize acceleration
   Position = 0x0000;                  // zero position
   LED = OFF;                          // turn off LED
   doneFlag = 0;                       // clear done flag
}
//-----------------------------------------------------------------------------
void error (void)                      // used by main
{
   newline();
   puts("invalid character");          // display error message
   newline();
   putc('>');
}
//-----------------------------------------------------------------------------
void delay (void)                      // used by main
{
   unsigned char i,j;

   for(i=255;i>0;i--)                  // simple delay for display update
   {
      for(j=255;j>0;j--);
   }
}
//-----------------------------------------------------------------------------
void doneMsg(void)                     // called from Timer_ISR
{
   putc('\r');                         // overwrite final position
   putuint(Position);                  // display int as string
   newline();
   puts("done!");                      // indicate move complete
   newline();
   putc('>');                          // display prompt
   doneFlag=0;

}

⌨️ 快捷键说明

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