/************************************************************* ECE 473 Lab Assignment #2 Students: Philip Lechowicz Olamide Adabonyan Due Date: 10/28/02 **************************************************************/ /************************************************************* *Header Files **************************************************************/ #include #include #include #include /************************************************************* *Global Variables **************************************************************/ unsigned int statusA = 0; unsigned int statusB = 0; unsigned int count = 120; unsigned int dummy = 0; /************************************************************* Function: TOC2_ISR Purpose: This interrupt occurs 10ms after the switch B is pressed to avoid reading signal while switch is bouncing. The interrupt inables IC1 and IC2 for the next time the switch is pressed. Additionally, it reads PA1; if high, the switch is pressed and a global status variable is set to take appropriate action in main. Inputs: None Outputs: None **************************************************************/ #pragma interrupt_handler TOC2_ISR void T0C2_ISR(void) { printf("\nWaited for switch debounce"); TMSK1 = 0x06; /*Enable IC2, IC1 Interrupt1, Disable others*/ TFLG1 = 0x06; /*Clear IC1F and IC2F*/ if ((PORTA & 0x02)==0x02) /*Check to see if signal is high*/ statusB = 1; /*If high, Set "statusB flag" to take action in main*/ asm("rti"); } /************************************************************* Function: TOC1_ISR Purpose: This interrupt occurs 10ms after the switch A is pressed to avoid reading signal while switch is bouncing. The interrupt inables IC1 and IC2 for the next time the switch is pressed. Additionally, it reads PA2; if high, the switch is pressed and a global status variable is set to take appropriate action in main. Inputs: None Outputs: None **************************************************************/ #pragma interrupt_handler TOC1_ISR void TOC1_ISR(void) { printf("\nWaited for switch debounce"); TMSK1 = 0x06; /*Enable IC2, IC1 Interrupts, Disable others*/ TFLG1 = 0x06; /*Clear IC1F and IC2F flags*/ if ((PORTA & 0x04)==0x04) /*Check to see if signal is high*/ statusA = 1; /*If high, Set "statusA flag" to take action in main*/ asm(" rti"); } /************************************************************* Function: TIC2_ISR Purpose: This Interrupt occurs when switch B (PA1)has a rising or falling edge. The tasks of this interrupt are to disable the IC interrupts, and then enable the OC2 interrupt to occur 10ms later. This is to avoid reading the switch while it is bouncing. Inputs: None Outputs: None **************************************************************/ #pragma interrupt_handler TIC2_ISR void TIC2_ISR(void) { printf("\nSwitch on PA1 was pressed"); TMSK1 = 0x40; /*Enable OC2 Interrupt, Disable others*/ TOC2 = TCNT + 20000; TFLG1 = 0x40; /* Clear OC2F */ asm(" rti"); } /************************************************************* Function: TIC1_ISR Purpose: This Interrupt occurs when switch A (PA2)has a rising or falling edge. The tasks of this interrupt are to disable the IC interrupts, and then enable the OC2 interrupt to occur 10ms later. This is to avoid reading the switch while it is bouncing. Inputs: None Outputs: None **************************************************************/ #pragma interrupt_handler TIC1_ISR void TIC1_ISR(void) { printf("\nSwitch on PA2 was pressed"); TMSK1 = 0x80; /*Enable OC1 Interrupt, Disable others*/ TOC1 = TCNT + 20000; TFLG1 = 0x80; /* Clear OC1F */ asm(" rti"); } /************************************************************* Function: RTI_ISR Purpose: This Interrupt occurs at period of 4.096 ms. The purpose of this interrupt is to toggle PA4 every 1 s or every 244 interrupts. Thus, a global variable is used to keep a count of the number of rti interrupts that have occured. The interrupt only toggles the interrupt when the count has been reduced from 244 to 0. Inputs: None Outputs: None **************************************************************/ #pragma interrupt_handler RTI_ISR void RTI_ISR(void) { //printf("\nRTI_ISR entered"); TFLG2 = 0x40; count = count - 1; if (count == 0) { PORTA = (PORTA ^ 0x10); /*Toggle PA4*/ count = 120; } //asm(" pulx"); //asm(" rti"); } /************************************************************* Function: Main Purpose: Main first intialiazes all the IC,and RTI interrupts. It then intializes the SPI communication channel. It then goes into a infinite loop writing to the SPDR if the appropriate status variables are set. Inputs: None Outputs: None **************************************************************/ void main(void) { asm("SEI"); TMSK1 = 0x06; /*enable IC1 and IC2 interrupts*/ TFLG1 = 0x06; /*Clear IC1F and IC2F*/ TCTL2 = 0x3C; /*Set IC1 and IC2 interrupts on any edge*/ TMSK2 = (TMSK2 | 0x40); /*Enable RTI Interrupt*/ TFLG2 = (TFLG2 | 0x40); /*Clear the RTIF */ PACTL = (PACTL & 0x03); /*Set RTI Interrupt rate for T=4.096 ms*/ SPCR = 0x50; /*Intialize the SPI*/ PORTD = (PORTD | 0x20); /*Enable Device as the master*/ DDRD = (DDRD | 0x38); /*Initialize PortD*/ RTIvector = &RTI_ISR; TOC2vector = &T0C2_ISR; TOC1vector = &TOC1_ISR; TIC2vector = &TIC2_ISR; TIC1vector = &TIC1_ISR; asm("CLI"); printf("\nThe start of main"); while(1) { printf("\nstart of while loop"); if (statusA == 1) { SPDR = 0x00; while ((SPSR & 0x80)==0) { dummy = 1; } dummy = SPSR; dummy = SPDR; statusA = 0; } if (statusB == 1) { SPDR = 0x01; while ((SPSR & 0x80)==0) { dummy = 1; } dummy = SPSR; dummy = SPDR; statusB = 0; } } }