/********************************** Nick Sitarski Vladi Gergov Lab 2 ECE 473 W 2003 Professor Shaout Slave **********************************/ #include #include #include /********************************* EQUATES **********************************/ #define fivePercent 1000 /********************************** PRAGMA DEFINES **********************************/ #pragma interrupt_handler PWMhandler() /********************************** GLOBAL VARIABLES **********************************/ short ontime, offtime; char motorstatus=0; /********************************** FUNCTION PROTOTYPES **********************************/ void initSlave(void); void PWMhandler(void); /************************************************************* Function: initSlave Purpose: This function performs the initilization steps for the target hc11 to be in slave mode. Inputs: None Outputs: None **************************************************************/ void initSlave(void) { char dummy; /* dummy variable */ ontime = 10000; /* setup variable for motor to start at 50% duty cycle */ offtime = 10000; /* setup variable for motor to start at 50% duty cycle */ SPCR = 0x40; /* Enable the SPI system */ DDRD = (DDRD | 0x04); /* Master in slave out (MISO) corresponding pin on Port D set to an output */ PORTD = 0x00; /* Clear Port D */ PACTL = 0x80; /* Set PA7 to an output */ PORTA = 0x00; /* Clear Port A */ dummy = SPSR; /* Clear the Clear the SPIF ( Transfer Compleate flag ) */ dummy = SPDR; /* Clear the Clear the SPIF ( Transfer Compleate flag ) */ TMSK1 = 0x08; /* Enable the OC5 Interrupt */ TFLG1 = 0x08; /* Clear the OC5 Interrupt flag */ /**** ISR ADDRESS INIT FROM VECTOR.H ****/ TOC5vector = &PWMhandler; printf("Initialization Compleate"); } /************************************************************* Function: PWMhandler Purpose: This function controls the Pulse width modulation Inputs: None Outputs: None **************************************************************/ void PWMhandler(void) { TFLG1 = 0x08; if(motorstatus==0) { PORTA |= 0x80; /* Turn Motor on leaving LED's alone */ motorstatus = 1; /* Tells the next ISR that the motor was turned on */ TOC5 = TOC5 + ontime; /* Reschedule OC5 with new values */ } else { PORTA &= 0x7F; /* Turns Motor off leaving LED's alone */ motorstatus=0; /* Tells the next ISR that the motor was turned on */ TOC5 = TOC5 + offtime; /* Reschedule OC1 with new values */ } } /************************************************************* Function: Main Purpose: This function controls the Pulse width modulation. It recives the data from the master via the SPI and then decides how to react according to what the data contains. If its a 1 then the motor gets turned off if its a 2 then the motor gets turned on at 50% duty cycle and if its a 4 then the motor speed is increased by 5%. Inputs: None Outputs: None **************************************************************/ void main(void) { char dummy, spdr_data; initSlave(); /* Calling the initialization function for the slave */ asm("sei"); /* Disable global interupts */ dummy = SPSR; /* Clear the SPIF flag using dummy variable */ dummy = SPDR; /* Clear the SPIF flag using dummy variable */ while(1) { while ((SPSR&0x80)==0); /* Wait untill data has been recived from the master via SPI */ dummy = SPSR; /* clear SPIF bit in SPSR via dummy dump (SPI transfer complete flag) */ spdr_data = SPDR; /* Get the data from the SPDR and store it in spdr_data variable */ /******************************** This if statement is active only when switch one from the master has been pressed It turnes the interrupts and the motor off, and turns the RED LED on. Also schedules the ontime and offtime to 50% duty cycle for initialization purposes and clears the motorstatus global variable because the motor has been shut off ********************************/ if(spdr_data==0x01) { asm("sei"); PORTA=0x00; PORTA=0x10; offtime=10000; ontime=10000; motorstatus=0; printf("\nSwitch 1 Pressed...\nSetting PWM to: "); printf("%d ontime, %d offtime", ontime, offtime); } /******************************** This else if statement is active only when switch two from the master has been pressed It turnes the interrupts and the motor on, and turns the GREEN LED on. Also schedules the ontime and offtime to 50% duty cycle for initialization purposes. ********************************/ else if (spdr_data==0x02) { asm("cli"); PORTA |= 0x20; PORTA &= 0xA0; ontime = 10000; offtime = 10000; printf("\nSwitch 2 Pressed...\nSetting PWM to: "); printf("%d ontime, %d offtime", ontime, offtime); } /******************************** This if statement is active only when switch three from the master has been pressed It turnes the interrupts and the motor on, and turns the YELLOW LED on. Also schedules the ontime and offtime to 5% more each time it runs. The check for an ontime bigger than 20k is because if the ontime has reached 20k then we are at 100% duty cycle and there is no need to increase it by 5% again. ********************************/ else if(spdr_data==0x04) { asm("cli"); PORTA |= 0x40; PORTA &= 0xc0; ontime += fivePercent; offtime -= fivePercent; if(ontime > 20000) { ontime = 20000; offtime = 0; } printf("\nSwitch 3 Pressed...\nSetting PWM to: "); printf("%d ontime, %d offtime", ontime, offtime); } } }