Crash-Course in Interrupts

Document Sample
Crash-Course in Interrupts Powered By Docstoc
					Introduction to HC11 Interrupts                                                     Pg 1 of 7

                  Crash-Course in Interrupts for the Motorola HC11
                            Paul Kissel,


The idea behind the interrupt for a CPU is this: it would be neat if the CPU could do two
things almost at the same time. The analogy is this: suppose your washer breaks and the
repair guy will show up sometime today. You could wait by the door for five hours until
he comes. However that would be very inefficient. You could be cleaning the house,
doing homework, etc. while waiting for him to come by.

In real life, human beings do this all the time. Somebody‟s cleaning house, the doorbell
rings, that person temporarily stops what he or she is doing, responds to the doorbell, and
then once that is done, goes back to work. As with the repair guy, you would go back to
doing homework once you let him in and showed him where the washer was.

The doorbell is an example of an interrupt. It makes you stop what you are currently
doing, respond to it, and then allow you to go back to what you were doing. The same
thing applies to the CPU. The Motorola HC11 supports interrupts. These interrupts,
when enabled, cause the CPU to stop what is doing, process the interrupt, and then allow
the CPU to continue executing the normal program it was running.

Now that we have a feel for what an interrupt is, it‟s time to discuss the different types of
interrupts. The HC11 supports many kinds of interrupts, just like people respond to many
different interrupts. The doorbell interrupt is an example of an event-driven interrupt.
You don‟t know when the doorbell is going to ring, only the repair guy does. When that
happens, you get the door. However, another kind of interrupt is the hourly chime of a
grandfather clock. That is a periodic interrupt, or time-driven interrupt. It sounds every
hour, without exception.

The HC11 has interrupts that are event-driven, and interrupts that are periodic. It even
has a special software interrupt called SWI (the end program instruction is really a call to
an interrupt that ends your program). However, since this is an introduction to interrupts,
we will examine only one at this time: the RTI.

The RTI Interrupt:

The RTI (real-time-interrupt) is a time driven interrupt. What is an RTI? It‟s an interrupt
that occurs when the HC11‟s internal counter resets itself. What is the counter and why
does it reset itself? Well, remember that the HC11 has to have a clock in order to work.
All CPUs depend on clocks to execute instructions. Clocking simply allows the
processor to do one instruction at a time. Remember, computer programs are sequential
programs, you do one instruction, move to the next instruction, do that, etc. until you
finish the program. The CPU can only do one thing at a time. It turns out that the HC11
has a counter built in that will increment periodically. It‟s a 13-bit counter, so it has 2^13
or 8192 values. What is does is take the system E-CLOCK speed (the heart and soul of
the CPU) and divides it by 8192.
Introduction to HC11 Interrupts                                                       Pg 2 of 7

Remember the HC11‟s E-Clock clock is usually set to 2 Mhz. Dividing that by 8192
means 244.1. In other words, the counter resets itself 244.1 times a second. The counter
can‟t go on forever. If it has 8192 values, and it gets to the end, it has to reset itself.

So how is it tied in to an interrupt? The counter, when it resets itself, sets a flag internal
to the CPU. You can make the HC11 run a routine everytime that counter resets itself.
You pick a piece of code (an ISR), setup everything properly, and every 4.096 ms (the
inverse of 244.1), the HC11 runs that routine. All the time, every time, as long as you
don‟t mess anything up:)

There‟s one little note about the RTI. Look in the Frederick Cady book on page 206
(ECE 372 textbook). See the table at the bottom describing the “Nominal RTI rate”?
Notice the 4.096 ms in the center column. Look down further and notice the other three
numbers. You‟ll see different RTI rates.

The RTI interrupt not only divides the E-Clock by 8192, it also gives the programmer
(you) the option of slowing it down. There are two bits RTR1 and RTR0 in the PACTL
($1026) register. If you set those bits both to a one, then the E-CLOCK is first divided by
8192, then it is further divided by 8 (see Table 10-7, third column). 2 Mhz divided by
8192 was 244.1. Well 244.1 divided by 8 is 30.5 Guess what the inverse of 30.5 is?
32.768 ms! See that number in the table? Those two bits allow you to slow that interrupt
down. Where are those two bits? In PACTL ($1026)

Ok, now on to coding and setting the interrupt up. There are several steps here, so read
slowly. I‟ll try to explain with human analogies. The first step in setting an interrupt up
is to let the CPU know it is supposed to respond to it. Suppose a mom has a kid who
spends too much time on the computer, so much so, that he won‟t answer the phone when
it rings. The mom is expecting an important phone call, but she has to do stuff in the
backyard. She knows that unless she explicitly tells her son to pick up the phone and get
her, he won‟t.

So what does she do? She goes to her son, tells him she‟s expecting an important phone
call, and to go get her when that call occurs. Now she can go out into the yard and do
whatever, confident that her son will obey. Otherwise, the phone would ring, and her son
would ignore it.

HC11‟s the same way. There is a mask bit for every interrupt that allows for the CPU to
respond to them. This mask bit is essential. It must be SET for that interrupt to be
processed. Otherwise the HC11 doesn‟t care about it. The RTI‟s mask bit is located in
TMSK2 ($1024). It is Bit 6. That bit 6 must be set to a one in order for the CPU to
respond to RTI‟s. Once that is set, the CPU knows that it is supposed to respond.

But I‟m getting a head of myself. Even before you set the mask bit, you have to tell the
CPU where to go when an interrupt occurs. If the mom tells her son simply that he is to
pick up the phone, but doesn‟t tell him where she is, the son won‟t realize that she is in
Introduction to HC11 Interrupts                                                       Pg 3 of 7

the backyard, and so he may end up ignoring the call. So, you have to tell the HC11 the
address of your interrupt-service-routine (ISR).

What‟s an ISR? It is the piece of code dedicated to handling that interrupt. When the
doorbell rings, the ISR for human beings is to walk to the door, and open it. When a
phone call occurs, the ISR for human beings is to pick up the phone, answer, and give it
to someone else if the call is for someone else.

To give the HC11 your ISR, you must specify the address in a certain table called the
Buffalo Interrupt Vector Jump Table. This table is located $00C4-$00FF. See page 87 in
Cady book. Notice that each interrupt has a dedicated memory address for it. The CPU
will go to that memory address and run the 3-byte instruction that is there. Notice that
each table entry is three bytes long, just enough for a jump instruction to be inserted.
Why insert a jump instruction there? So you can point it to your ISR code.

How do you set up that address. Use the ORG command.
      ORG $00EB           * RTI’s address in the vector jump table
      JMP YOUR_RTI_ISR              * point it to your code
      ORG $2000                           * NOTE THIS!!!

NOTE THIS: Why did I put an ORG $2000 here? Because the assembler is simple. If
you start putting you code (like LDAA‟s...etc) immediately after that jump
instruction...guess what... you‟ve just overwritten the rest of the interrupt vector jump
table! The ORG instruction simply says start here. It doesn‟t say...start here... and end
here. So you need to put your data ORG or your code ORG or some other ORG right
after the ISR ORG & JMP or you might mess things up.

Ok, this far, and you are almost done. A few more thing to do though. One thing is to
enable all interrupts (CLI).

It turns out that even with mask bit set, the HC11 will still not do your interrupt. That‟s
because there is a special enable all interrupt bit. This special bit is in the flags register.
This special bit must be CLEARED to enable all interrupts. So you need to CLEAR it to
enable all interrupts. The instruction to do that is CLI. To disable all interrupts (useful
for when you want to set something special up or run a piece of code un-interrupted) is
the SEI instruction. It is usually a good programming habit to disable interrupts at the
start of your program, set those interrupts up, and then enable all interrupts.

Here‟s an overview of what we‟ve talked about:

Figure 1

1.      In your code, insert an
        ORG $INT_ADDR
        JMP ISR_ADDR
Introduction to HC11 Interrupts                                                    Pg 4 of 7

Where INT_ADDR is the BUFFALO address of the interrupt.
Every interrupt has a unique address assigned to it. RTI
has its special address reserved for it at $00EB. Anytime
an RTI occurs, and the interrupt is enabled for it, the CPU
goes to that memory location, looking for code to execute.
Well, that JMP instruction you put in (JMP ISR_ADDR) should
point to the ISR routine that you wrote. That’s how the
CPU knows where to go to your code. Its (the CPU) is
preprogrammed to go to a certain spot in memory when an
interrupt occurs (a certain unique spot reserved for that
particular interrupt), and follow whatever instructions are

2.   Enable the enable bit for the Interrupt you want (the
mask bit as it is commonly called)

3.     Enable all interrupts (the CLI instruction).

That‟s it for getting ready to use interrupts. There is one more step, setting up your ISR.

Suppose we‟ve done the previous stuff. The CPU now knows where to go when the RTI
interrupt happens. It now knows to respond to the interrupt (the mask bit and all
interrupts enable bit are set). Now, it jumps to the code.

The ISR:

What happens next? Depends on how you wrote your ISR. How do we write an ISR?
Here‟s how:

The first step in an ISR is to check the interrupt‟s status flag (which is set when the
interrupt occurs)? Why? Shouldn‟t you only be in the ISR if the actual interrupt occurs?
Well, sometimes (I‟ve never seen it happen), the CPU will go into an ISR by accident. In
order to avoid accidentally executing the interrupt, you have to check the flag. The flag
set means that the interrupt is golden (real).

To check RTI‟s flag (in other words, to see if an RTI interrupt actually happened), at the
start of your ISR, you need to check the RTIF bit in TFLG2 ($1025). One way to do this

     ldaa TFLG2
     anda #RTIF               * RTIF => %01000000
     beq EXIT_RTI
     ...                      * rest of code here
Introduction to HC11 Interrupts                                                       Pg 5 of 7

This will verify the interrupt‟s validity. If that BEQ doesn‟t branch, you‟ve got a genuine
RTI interrupt.

Now that you‟ve verified the interrupt‟s validity, you can put in your real code: the code
that you want assigned to the RTI interrupt. This can be anything from incrementing a
counter (to keep track of time) to toggling a pin on PORTA. Anything you want...put it
here. When an RTI happens, this code gets executed.

Wrapping up: There‟s a couple of more things to do in your ISR... First, reset the
interrupt‟s flag. This is important. The way an interrupt happens is that when it occurs, it
sets a flag (for the RTI, the RTIF bit). This bit tells the CPU that it should respond to the
interrupt. The CPU will keep calling the interrupt as long as this bit is set. The CPU will
NOT automatically clear it. You‟ve got to clear it! Otherwise, you‟ll execute your ISR
early! Immediately after you‟re done that is!

At the end of your ISR, you must reset the flag. Here‟s one way to do it:

        ldaa #RTIF
        staa TFLG2

This will write a „1‟ to the RTIF flag, resetting it to 0. That‟s right, you write a „1‟ to a
flag to reset it. Sort of reverse logic, but it allows you to only reset the flag you want
easily. Consider what would happen if writing a 0 would reset a flag. If a register has
eight different flags signaling unrelated things, then if you wrote $00 to it, you might
reset 7 other flags that you didn‟t mean to. So that is probably why Motorola designed
the HC11 to reset flags by writing a 1.

Last but not least, you have to have your ISR exit gracefully. To do this use:

     ...                        * code goes here

The RTI here means return from interrupt (NOT real-time interrupt).

When an interrupt happens, it is important for the CPU to remember what is was doing.
When you answer the doorbell, you keep in mind what you were doing, so that when you
are finished answering, you can go back to work. How does the CPU remember? The

When an interrupt happens, the CPU places the PC, data registers, etc. all on the stack.
That way, when an interrupt is done, the RTI instruction pulls all that information back.
The PC is updated to where it originally left off, and the program continues executing.
That‟s why you need an RTI (return from interrupt) instruction.

Now you‟re done!
Introduction to HC11 Interrupts                                                  Pg 6 of 7

You should now understand the interrupt and how it to set it up, how to
enable it, how to process it, check it‟s validity, and exit gracefully. Here‟s a sample
program showing all the steps. It‟s a program that increments a counter every time the
RTI happens. The main loop just displays the string „Hello world.‟ after 100 RTIs.

Remember, there are other interrupts for the HC11 besides the RTI. There are the OCX
interrupts that compare a counter called TCNT with specific registers in memory. There
is a pulse-accumulator interrupt that will trigger when the voltage on PA7 goes high or
low. In the future, this guide may be extended to include discussions on these interrupts.
The ISRs for these interrupts are of a similar form to the ISR for RTI (checking a flag,
running code, clearing the flag), with certain modifications. For now, you should be well
on your way to becoming familiar with interrupts.

Sample Program for RTI:

****     Equates     ****

INPUT                   EQU   $FFAC
OUTSTRG                 EQU   $FFC7
OUTSTRG0       EQU      $FFCA
OUTA           EQU      $FFB8
OUT1BYT                 EQU   $FFBB
OUTCRLF                 EQU   $FFC4
OUT2BSP                 EQU   $FFC1
BACKSPACE      EQU      $8
SPACE          EQU      $20
BIT6           EQU      %01000000
PACTL          EQU      $1026
TMSK2          EQU      $1024
TFLG2          EQU      $1025       * TFLG2 has RTIF bit in it

               ORG      $00EB        * address of RTI handler
               JMP      RTIISR       * our ISR that we want executed

               ORG      $2000        * note: we put our ORG right after ORG!
               SEI                   * Disable all ints. while we’re in setup
               LDAA     #BIT6
               STAA     TMSK2        * Enable RTI interrupt
               LDAA     #$03
               STAA     PACTL        * Select clock frequency
               CLI                   * Enable all interrupts
               LDAA     TOGO
               CMPA     #100
               BNE      LOOP
               CLR      TOGO
               LDX      #HELLO_STR
               JSR      OUTSTRG

               BRA      LOOP

Introduction to HC11 Interrupts                                     Pg 7 of 7

              LDAA   TFLG2
              ANDA   #BIT6
              BEQ    EXITRTI      * Make sure that it is legit
              INC    TOGO         * Service the interrupt

              LDAA   #BIT6        * Re-enable the interrupt (or reset
              STAA   TFLG2        * the flag)

              ORG    $3000        * Data segment

TOGO          FCB    1
HELLO_STR     FCC    ‘Hello World.’
              FCB    $04

Shared By: