ECE 271 LAB 13 Spring 2012 PURPOSE: INTRODUCTION TO THE TIMER SYSTEM AND INTERRUPTS EXERCISE: For this lab you will rewrite Lab 12 using interrupts. The new code should be entirely interrupt driven. I.e., after initialization code, everything is done in interrupts. To prove this you should cut and paste an earlier lab (e.g., lab 7 code) into your main program and have it run simultaneously with this lab. You will need two interrupt service routines (ISRs); e.g., TOC2 and TOC3: 1) A timer ISR (aka "speaker interrupt"), who's job is to toggle the speaker once, set up the time for the next interrupt, decrement a counter, and then disable itself when the counter reaches zero. Note: if you use TOC3 for this interrupt you can have the speaker automatically toggle on interrupt. 2) Ideally, an SCI interrupt service routine is also used, but since our serial communication is through an external serial communications system, we will "fake it" with another timer interrupt. This interrupt will simply be set up to interrupt every millisecond. It will then check the RDRF flag and if it is not set then return. If it is set, it will read the character from the receive register, write it to transmit register (you can use your old putchar routine), and then call playtone and return from interrupt (note RTI!). Your main code will print the prompt string as in lab 12, then it will perform the initialization for the two timer interrupts (see below), and then it will jump to the lab 7 code. For testing however, it is advised that you simply execute the following infinite loop: HERE WAI BRA HERE Your table of notes from lab 12 will be modified to so the "period" value is equal to the number of clock cycles between toggles, rather than a number to be loaded into the X register to achieve the desired software delay. (I.e., multiply each number from lab 12 by six). Your playtone routine will be modified: After determining which note to play, store the "period" and "number of toggles" in a mailbox location so that the "speaker interrupt" can use them. Then enable the speaker interrupt and return. The playing of the note will now be done in the interrupt. "NOTES": 1. As on previous labs: write good code, have flowcharts, each subroutine must be transparent, etc. 2. In each interrupt service routine, make sure you clear the condition that caused the interrupt (i.e., clear the associated timer flag). If you don't do this, the interrupt will occur occur again instantly on exit - i.e., an infinite loop. Also remember to use RTI to exit the ISR. 3. As a general rule, keep the work done in an interrupt service routine to an absolute minimum. 4. Debugging interrupts requires a little care, as you cannot step into or out of an interrupt. A good techniquie is to set a break point in an interrput to make sure the interrupt is set up and "vectored to" properly. OUTPUT COMPARE INTERRUPT INITIALIZATION. The following assumes TOC3. Page numbers refer to the HC11 manual (in the lab), but most of the information is in your text in section 7.8: 1) Insert interrupt vector in the jump vector table: Memory $FFE4 contains $00D9, so insert a JMP XXXX instruction at $00D9 (where XXXX is the address of your TOC3 service routine. Note: the opcode for JMP is $7E. 2) Read the current Timer Count from TCNT (pg. 374), add your DELAY to it, and store the result in TOC3 (pg. 409). This defines when you want the first interrupt to occur. 3) Set OC3I bit in TMSK1 to enable TOC3 interrupts (pg. 410). 4) Clear the OC3F bit in TFLG1 to clear any previous interrupt condition. (pg. 410). IMPORTANT!!! Note that you must write a 1 to this bit to clear it! Do not use BSET! See the discussion on page 387. 5) Optional: Write to OM3 and OL3 bits in TCTL1 register to define how the OC3 output pin will behave when the interrupt occurs (pg. 412). 6) Enable interrupts globally. (See SEI and CLI instructions.) TOC3 SERVICE ROUTINE: 1) Define when the next interrupt should occur by adding your DELAY to TOC3. 2) Do whatever it is you want done in the service routine 3) Clear the OC3F bit in TFLG1 to clear the interrupt condition (SEE ABOVE). 4) Return from interrupt when done (pg. 181).