📄 an155.c
字号:
}
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 + -