/************************************************************************* Author: Josiah Snarr Date: April 11, 2015 stepperStep controls the stepper motor to step a position based on the direction it is going *************************************************************************/ void stepperStep(void) { //Step to next position in table FORCE_BITS(STEP_PORT, STEP_OUT, motorPos[stepIndex]); //Set index to next position stepIndex = (stepIndex + direction) & INDEX_MASK; //Increase/decrease current step currStep += direction; }
/* * Reads a CAN frame from the PC monitor via serial * Returns RX_COMPLETE if a complete frame has been received, RX_PARTIAL if a partial frame has been received, or RX_IDLE if waiting for a frame to arrive * Non-blocking: partial frames are buffered so the user's frame is unmodified until a full frame is ready, * and persistent between calls so data will not be lost. */ byte readSerialCANframe(CANframe *frame) { byte b; byte retCode = ( state == RX_STATE_IDH ? RX_IDLE : RX_PARTIAL ); // What to return if no bytes are available while ( sci_bytesAvailable() ) { retCode = RX_PARTIAL; sci_readByte(&b); // Read in one byte at a time per state loop switch ( state ) { case RX_STATE_IDH: FORCE_BITS(framebuf.id, 0xFF00, ((word)b)<<8); state = RX_STATE_IDL; break; case RX_STATE_IDL: FORCE_BITS(framebuf.id, 0x00FF, b); state = RX_STATE_PRIORITY; break; case RX_STATE_PRIORITY: framebuf.priority = b; state = RX_STATE_LENGTH; break; case RX_STATE_LENGTH: length = b; framebuf.length = 0; // Note: stores the number of received bytes, not the expected total state = RX_STATE_PAYLOAD; break; case RX_STATE_PAYLOAD: framebuf.payload[framebuf.length++] = b; // Got a full frame? if ( framebuf.length == length ) { state = RX_STATE_IDH; *frame = framebuf; // Copy to user return RX_COMPLETE; // Return immediately and ignore any remaining bytes until next time } break; default: break; } } return retCode; }
/* Stepper motor control interrupt handler */ interrupt VECTOR_NUM(TC_VECTOR(TC_STEPPER)) void StepperISR(void) { static byte stepper_count = 0; TC(TC_STEPPER) += TIMER_DELTA(stepper_delay); // Acknowledge interrupt and set delta for next event FORCE_BITS(STEPPER_PORT,STEPPER_COIL_BITS,(STEPPER_PATTERN[stepper_count] << 4)); // Change bit pattern on stepper coils /* ADD CHECKING OF LIMITS IN HERE SO THAT STEPPER DOES NOT TRY TO GO PAST PHYSICAL LIMITS */ if(stepper_position != stepper_setpoint || stepper_calibrated == 0) { /* Stepper not at set point or not calibrated */ stepper_count = (stepper_count + stepper_step_type) & STEPPER_COUNT_MASK; // Set offset to next step pattern and mask off bits to keep value in range stepper_position += stepper_step_type; } else { /* Stepper is at set point */ if(stepper_count % 2) CLR_BITS(STEPPER_PORT,STEPPER_COIL_BITS); // Turn off coils on odd numbers (50% duty cycle) } }
/************************************************************************* Author: Josiah Snarr Date: April 11, 2015 the stepControl interrupt controls the next step on the stepper motor, and resets the busy flag when it is complete *************************************************************************/ interrupt VectorNumber_Vtimch4 void stepControl(void) { if(currStep != moveStep) { //Step to next position in table FORCE_BITS(STEP_PORT, STEP_OUT, motorPos[stepIndex]); //Set index to next position stepIndex = (stepIndex + direction) & INDEX_MASK; //Increase/decrease current step currStep += direction; //Increase timer for next interrupts TC4 += STEP_WAIT; } else { //Clear busy flag, disable TC4 interrupts isBusy = NOT_BUSY; TIE &= (~((unsigned char)TIOS_IOS4_MASK)); } }
void main(void) { /* put your own code here */ SET_TCNT_PRESCALE( TCNT_PRESCALE_8); TSCR1 = TSCR1_INIT; seg_init(); CANinit(THE_FLOOR); SET_BITS(LED_DDR, LED1_MASK|LED2_MASK); node_id = PORTB & 3; //get hardware specified node id while (!(CANCTL0&0x10)); CANRFLG = 0xC3; CANRIER = 0x01; InitializeQueue(&rec); // Create the Recieve Queue clear_seg(); EnableInterrupts; for(;;) { if(IsQueueEmpty(rec) != 0) { DeQueue(&rec); Parse_Floor(); } // button 1 press if((PTJ & (SWITCH1_MASK |SWITCH2_MASK) )== SWITCH1_MASK) { if(THE_FLOOR == F1 || THE_FLOOR == F2) { if (last != SWITCH1_MASK) { // check if button already pressed data[0] = THE_FLOOR; data[1] = CALL_SWITCH1; data[2] = UP; (void)CANSend(CONTROLLER, 0x00, 0x00, DATA_LENGTH, data); last = SWITCH1_MASK; } } else if(THE_FLOOR == F3) { if (last != SWITCH1_MASK) { // check if button already pressed data[0] = THE_FLOOR; data[1] = CALL_SWITCH1; data[2] = DOWN; (void)CANSend(CONTROLLER, 0x00, 0x00, DATA_LENGTH, data); last = SWITCH1_MASK; } } } //button 2 press else if((PTJ & (SWITCH1_MASK |SWITCH2_MASK) )== SWITCH2_MASK) { if(THE_FLOOR == F2) { if (last != SWITCH2_MASK) { // check if button already pressed data[0] = THE_FLOOR; data[1] = CALL_SWITCH2; data[2] = DOWN; CANSend(CONTROLLER, 0x00, 0x00, DATA_LENGTH, data); last = SWITCH2_MASK; } } } else last = 0; // Updates the LED FORCE_BITS(PTS,0b00001100 , led) ; } /* loop forever */ /* please make sure that you never leave main */ }