ECE 2325 UMD Fall 2002 LAB 7: Timer Module, Polling Interrupt Flags Objective: To become more familiar with the Timer Module of the 68HC11 and learn the use of polling to utilize interrupts without having to write interrupt service routines. Discussion: The Timer Module in the 68HC11 is large and very useful. The free-running 16-bit counter, TCNT, is the backbone of the module, playing an integral part in all other timer functions. The Real-Time Interrupt, for example, references TCNT in order to cause its interrupts. Any time TCNT overflows (transitions from FFFF to 0000) it sets the TOF (Timer Overflow Flag). If TOI (Timer Overflow Interrupt Enable) is set (One), an interrupt will occur. The vector location for Timer Overflow events is FFDE, FFDF. That location contains the memory address within the Interrupt Vector Jump Table where jump instructions may be stored in order to write a custom interrupt service routine. However, it is not necessary to enable interrupts in order to make good use of the timer interrupt flags. Currently, on the EVBs in MWAH 355, the free-running counter overflows every 32.8 milliseconds. The first time that occurs, the TOF flag, located in bit 7 of special register 1025, gets set to logic one. The is nothing in the Monitor Program to clear the TOF flag and it will remain set unless a program is written to clear it. Such a program could either be an Interrupt Service Routine or simply a regular program which “polls” bit 7 of Register 1025. When polling, a program needs to periodically check the bit for logic one. When it occurs, the program will clear it by storing logic one to that location (1025 is a protected register, See “Clearing Timer Flags”, p. 422 of your textbook). Since the flag gets set every 32.8 mS, it is possible to use such a polling program to perform timing routines, just as one could with interrupt service routines. A typical instruction for polling a bit would be: brset TOF,x,80, CLEAR . This instruction, when inside a loop, will periodically check the contents of memory address TOF. In particular, it will check if bit 7 is logic one. When bit 7 is a one, the instruction will branch out of the loop to the label CLEAR. If one desired to write code which updated a value displayed on the Monitor every 2 seconds, one could poll the TOF flag, updating a counter every time it occurred. When the counter reached 6110, the program would know two seconds had elapsed and it could reset the counter and update the Monitor screen. (In decimal, 61 X 32.8 mS = 2.00 seconds). It is possible to change the rate at which the free-running counter does its counting. PR1 and PR0, bits 1 and 0 of special register TMSK2 (register 1024) can be used to set four different count rates for TCNT, from 32.77 to 524.3 mS. These bits are TIME PROTECTED. In other words, in single user mode and extended mode, PR1 and PR0 can only be changed ONCE and ONLY during the first 64 clock cycles of operation. But, since the EVBs in MWAH 355 run in special test mode, the time protection is waived and the prescale bits may be changed at any time. Unfortunately, it is very Scott Norr Page 1 2/16/2016 ECE 2325 UMD Fall 2002 important to maintain the 32.77 ms overflow rate, since the timer module is used to create a 60Hz frame-synchronizing signal used by the video interface. Procedure: It is desired to create a Real-Time Clock by exploiting the TOF flag of the timer module. The clock will accept a starting time from the keyboard and then continuously update the time displayed on the Monitor every second. Any key press will stop the clock and be accepted as the first number (H1 ) of a new starting time. Upon receiving the 6th key press of a new starting time, the clock will run again. Details: 1. Keyboard input should be: H1H0M1M0S1S0 These 6 digits represent hours, minutes and seconds, such as 12:59:59. No need to input the colons (:) as they will just make the programming more difficult. 2. The time will be displayed on the monitor using colons, however. Use zeros as necessary to maintain the 6 digits of time: 01:05:39 3. The 6 time digits should be collected using GetC, converted from ASCII to Hex and stored in memory locations C000 – C005. This portion of the program will be very similar to the data entry code written for Lab 3: Calculator. 4. Once the sixth digit has been collected and converted, the TOF flag should be cleared, thus starting the ‘clock’. 5. The program then needs to enter a loop, checking for either of two occurrences: 1. A new key press or 2. A TOF flag. 6. If a new key press occurs, branch out of the loop to the portion of code where key presses are collected for a new start time. TOF flags must be ignored in that portion of the code. 7. If a TOF flag occurs, branch out of the loop to a portion of code where the following things must occur: a. The TOF flag is cleared by writing a one to bit 7 of register 1025. b. A memory location (I suggest c006) is updated as a counter to keep track of TOF flags. c. If the proper number of TOF flags have occurred, (i.e. 1 second has elapsed), update the memory locations to keep proper time. Else, return to the loop in 5. above. d. If memory locations have changed, update the monitor with the new time value and then return to the loop. Assumptions: 1. It will be helpful in debugging and in the final result if a carriage return and line feed are sent to the monitor after keying in a new time. Scott Norr Page 2 2/16/2016 ECE 2325 UMD Fall 2002 2. You may assume that you can print each new time (every second) on a new line, so that your clock will display like this: 125959 (new time keyed in) 12:59:59 01:00:00 01:00:01 Etc. 1 Point Extra Credit will be given if the clock display always updates on the same line in the same 8 character positions. 3. It will be helpful to use indexed instructions for updating memory and collecting new start times. The bset/bclr and brset/brclr instructions may be extremely helpful in updating memory locations efficiently. 4. Be careful on how you update your time. Be especially careful of the transition from 12:59:59 to 01:00:00; from 02:59:59 to 03:00:00; and depending on your code, from 09:59:59 to 10:00:00. 5. You may use a custom subroutine, Rslt2, for the output of time values to the monitor screen. Rslt2 takes a 16-bit address value passed to the stack, loads 2 bytes at that address, converts them from Hex to ASCII and puts them out to screen, followed by a colon. For example: ldx #c002 pshx jsr Rslt2 pulx If C002 and C003 contain 05 and 09, Rslt2 will put 59: out to screen. Memory Map: Address C000 C001 C002 C003 C004 C005 C006 Scott Norr Data H1 H0 M1 M0 S1 S0 TOF Count Page 3 2/16/2016 ECE 2325 UMD Fall 2002 Example Code: ; ; Code for Lab 7 on the EVB ; Must be modified to test on THRSim11 ; Program prints an RT clock to screen, ; accepts updates from keys, and calculates ; time changes by polling the TOF Flag. ; PutC = bfd3 ;assign labels to the custom GetC = bfd0 ; instruction address locations ;;;;;;;;;;;;;;;;;;;;;;;; TOF = 25 TCNT = 100e ;;;;;;;;;;;;;;;;;;;;;;;; org c200 Main: lds #dfff ; initialize the stack at bottom of ; memory cli ldx #0a0d ; Put <CR> and <LF> to Monitor, pshx jsr PutC jsr PutC ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; YOUR CODE GOES HERE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Rslt2: ; Input: 16-bit Address passed to stack; ; Address points to location of two ; 4-bit Hex characters ; Output: Puts 2 ASCII Char to Montr ; followed by a colon (:) ; Data NOT removed from stack ; Does not corrupt registers pshy pshx psha tsy ; Use Y as pointer ldx 7,y ; load base address into X ldaa 0,x psha jsr HtoA jsr PutC ldaa 1,x psha jsr HtoA jsr PutC pula pulx Scott Norr Page 4 2/16/2016 ECE 2325 UMD Fall 2002 puly rts ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; AtoH: ; Convert 8-bit ASCII to 4-bit Hex ; input registers: none - 8-bit ; local variable ; passed to stack ; output registers: none - 8-bit ; local variable ; passed to stack ; 4-bits of leading ; zeros, 4-bits data ; pshx ; store old values of X and A psha tsx ; transfer SP contents to X ldaa 5,x ; load ASCII char from stack suba #30 ; stubtract 30 from ASCII cmpa #a ; check if number was less than A (10) blt ADon ; if so, done, restore registers suba #27 ; if not, convert to "a" thru "f" value ADon: staa 5,x ; put HEX number on stack pula ; restore contents of A and X pulx rts ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; HtoA: ; Convert 8-bit ASCII to 4-bit Hex ; input registers: none - 8-bit ; local variable ; passed to stack ; output registers: none - 8-bit ; local variable ; passed to stack ; 4-bits of leading ; zeros, 4-bits data ; pshx ; store old values of X and A psha tsx ; transfer SP contents to X ldaa 5,x ; load ASCII char from stack adda #30 ; stubtract 30 from ASCII cmpa #3a ; check if number was less than A (10) blt HDon ; if so, done, restore registers adda #27 ; if not, convert to "a" thru "f" value HDon: staa 5,x ; put HEX number on stack pula ; restore contents of A and X pulx rts ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Scott Norr Page 5 2/16/2016