/* * Program to solve Part 5 of Lab 6 * Use Input Capture 2 Interrupt to measure time between two falling edges * Use Output Compare 2 Interrupt to generate 1 kHz square wave * Use Real Time Interrupt to increment Port B */ #include <hc11.h> #define TRUE 1 #define HALF_PERIOD 62 /* 125 clock cycles in a period for 1 kHz; 62 in half period */ int write_to_serial(unsigned short n); void tic2_isr(void); void toc2_isr(void); void rti_isr(void); unsigned short first_edge; /* Time of first edge */ unsigned short second_edge; /* Time of second edge */ unsigned short which_edge; /* Used to let ISR know which time to set */ main() { TMSK2 = (TMSK2 | 0x03); /* 8 us clock to timer subsystem */ /* * Set up Input Capture 2 */ TCTL2 = (TCTL2 | 0x08) & ~0x04; /* Capture falling edge on TIC2 */ TIC2_JMP = JMP_OP_CODE; /* Set the TIC2 interrupt vector */ TIC2_VEC = tic2_isr; /* to point to the tic2_isr() routine */ TMSK1 = TMSK1 | 0x02; /* Set Bit 1 (IC2I bit) in TMSK1 */ /* to enable the TIC2 interrupt */ TFLG1 = 0x02; /* Clear TIC2 flag before enabling ints */ which_edge = 1; /* 1st time in interrupt, capture first edge */ /* * Done with Input Capture 2 setup */ /* * Set up Output Compare 2 */ TCTL1 = (TCTL1 | 0x40) & ~0x80; /* Toggle on successful compare */ TOC2_JMP = JMP_OP_CODE; /* Set the TOC2 interrupt vector */ TOC2_VEC = toc2_isr; /* to point to the toc2_isr() routine */ TMSK1 = TMSK1 | 0x40; /* Set Bit 6 (OC2I bit) in TMSK1 */ /* to enable the TOC2 interrupt */ TFLG1 = 0x40; /* Clear TOC2 flag before enabling ints */ /* * Done with Output Compare 2 setup */ /* * Set up Real Time Interrupt */ PACTL = (PACTL | 0x01) & ~0x02; /* 8.192 ms RTI rate */ RTI_JMP = JMP_OP_CODE; /* Set the RTI interrupt vector */ RTI_VEC = rti_isr; /* to point to the rti_isr() routine */ TMSK2 = TMSK2 | 0x40; /* Set Bit 6 (RTII bit) in TMSK1 */ /* to enable the TOC2 interrupt */ TFLG2 = 0x40; /* Clear RTIF flag before enabling ints */ /* * Done with Real Time Interrupt setup */ which_edge = 1; /* 1st time in interrupt, capture first edge */ enable(); /* Enable interrupts (clear I bit in CCR) */ while (TRUE) { if (which_edge == 3) /* Got both edges if which_edge == 3 */ { write_to_serial(second_edge - first_edge); /* Print time diff */ which_edge = 1; /* Next time in will be for first edge */ } } } #pragma interrupt_handler tic2_isr void tic2_isr(void) { if (which_edge == 1) /* Get time of first edge if which_edge == 1 */ { first_edge = TIC2; /* get time */ which_edge = 2; /* Next time will grab time of second edge */ } else if (which_edge == 2) /* Get time of second edge if which_edge == 2 */ { second_edge = TIC2; /* get time */ which_edge = 3; /* Tell main program time got both edges */ } TFLG1 = 0x02; /* Clear source of interrupt */ } #pragma interrupt_handler toc2_isr void toc2_isr(void) { TOC2 = TOC2 + HALF_PERIOD; /* Set time for next compare */ TFLG1 = 0x40; /* Clear source of interrupt */ } #pragma interrupt_handler rti_isr void rti_isr(void) { PORTB = PORTB + 1; /* Increment Port B on RTI */ TFLG1 = 0x40; /* Clear source of interrupt */ } /* Routine to write an integer to the serial port */ int write_to_serial(unsigned short n) { char i; unsigned char t,c[6]; for (i=3;i>=0;i--) { t = (n&0x0f); if (t < 10) c[i] = t + 48; else c[i] = t + 55; n = n >> 4; } c[4] = 0x0d; c[5] = 0x0a; for (i=0;i<6;i++) { while (!(SCSR&0x80)) ; SCDR = c[i]; } }