/************************************************************************* Author: Josiah Snarr Date: April 9, 2015 DACSend forms a header for data sent to the DAC, and sends the data with the specified instruction (0 - LDAB, 1 - LDA, 2 - LDB) *************************************************************************/ void DACSend(unsigned char dVal, unsigned char inst) { char lss; //Least significant set to send char mss; //Most significant set to send switch(inst) //Find command and form MSB side of header { case COM_LDA: mss = (DAC_COM_LDA | (HI_NYBBLE(dVal))); break; case COM_LDB: mss = (DAC_COM_LDB | (HI_NYBBLE(dVal))); break; case COM_LDAB: mss = (DAC_COM_LDAB | (HI_NYBBLE(dVal))); break; default: break; } lss = (NYB_CAT(dVal, LSB_FRAME)); //Form LSB side of header //Push output to DAC CLR_BITS(SPI_PORT, SPI_SS); putSPI(mss); putSPI(lss); SET_BITS(SPI_PORT, SPI_SS); }
/************************************************************************* Author: Josiah Snarr Date: April 9, 2015 DACShutdown shuts down the DAC *************************************************************************/ void DACShutdown(void) { CLR_BITS(SPI_PORT, SPI_SS); putSPI(DAC_COM_SHUT); putSPI(LSB_FRAME); SET_BITS(SPI_PORT, SPI_SS); }
/************************************************************************* Author: Josiah Snarr Date: April 9, 2015 DACStandby puts the DAC on standby *************************************************************************/ void DACStandby(void) { CLR_BITS(SPI_PORT, SPI_SS); putSPI(DAC_COM_STAN); putSPI(LSB_FRAME); SET_BITS(SPI_PORT, SPI_SS); }
/************************************************************************* Author: Josiah Snarr Date: April 9, 2015 DACWake wakes the DAC *************************************************************************/ void DACWake(void) { CLR_BITS(SPI_PORT, SPI_SS); putSPI(DAC_COM_WAKE); putSPI(LSB_FRAME); SET_BITS(SPI_PORT, SPI_SS); }
/** * For talking to the MCP4822 DAC */ void DAC_updateVoltage(uint16_t channel, uint16_t value) { // Validate channel selection if(channel <= 1) { // Cap value to 12 bits only if(value > 0x0FFF) { value = 0x0FFF; } char txBuf[2]; uint16_t cmd = 0x3000 | (value & 0x0FFF); if(channel) cmd |= 0x8000; txBuf[1] = cmd & 0x00FF; txBuf[0] = __swap_bytes(cmd) & 0x00FF; CLR_BITS(SPI_PORT(OUT),SSEL | nLDAC); // CS~ falling edge, hold nLDAC low SPI_send(txBuf, 2); SET_BITS(SPI_PORT(OUT),SSEL); // CS~ Rising edge. Because nLDAC is low, DAC output changes on rising CS~ edge. } }
void timer_init(void) { TIMER_SET_PRESCALER(TIMER_PRESCALER_64); TIMER_DISABLE_ON_FREEZE(); TIMER_FANCY_FAST_CLEAR(); TIMER_ENABLE(); CLR_BITS(TIE, (TIE_C3I_MASK)); }
/* Initialize SCI module */ void SCIinit(void) { SET_SCI_BAUD(BAUD38400); // Set baud rate CLR_BITS(SCICR1,SCICR1_INIT); // Set port configuration SCIflush(); SCI_RX_INT_ENABLE; // Enable SCI receive interrupt SET_BITS(SCICR2,( SCICR2_RE_MASK | SCICR2_TE_MASK )); // Enable transmitter and receiver SCIcount = 0; // Clear SCI received bytes counter }
/* 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 stepperInit initializes the ports which the stepper motor uses, PORTT and PORTAD *************************************************************************/ void stepperInit(void) { SET_BITS(STEP_DDR, STEP_OUT); SET_BITS(SMEN_DDR, SMEN_MASK); SET_BITS(STEP_SWI_DIS, STEP_SWI_IN); CLR_BITS(STEP_SWI_DDR, STEP_SWI_IN); MAKE_CHNL_OC(TIOS_IOS4_MASK); TIE &= (~((unsigned char)TIOS_IOS4_MASK)); //Disable interrupts SET_BITS(SMEN_PORT, SMEN_MASK); //Initial direction left, and start at beginning of table direction = DIR_LEFT; stepIndex = 0; stepperHome(); }
/************************************************************************* Author: Josiah Snarr Date: April 9, 2015 putcSPI pushes a byte-long value through the SPI interface with SS low *************************************************************************/ void putcSPI(unsigned char val) { CLR_BITS(SPI_PORT, SPI_SS); putSPI(val); SET_BITS(SPI_PORT, SPI_SS); }