An introduction to schedulers:A better solution

A better solution

A better solution to the problems outlined is to use timer-based interrupts as a means of invoking functions at particular times.

Timer-based interrupts and interrupt service routines

As we saw in Chapter 1, an interrupt is a hardware mechanism used to notify a proces- sor that an ‘event’ has taken place: such events may be internal events or external events. Altogether the core 8051 / 8052 architecture supports seven interrupt sources:

● Three timer/counter interrupts (related to Timer 0, Timer 1 and – where available – Timer 2)

● Two UART-related interrupts (note: these share the same interrupt vector, and can be viewed as a single interrupt source)

● Two external interrupts

In addition, there is one addition interrupt source over which the programmer has minimal control:

● The ‘power-on reset’ (POR) interrupt

When an interrupt is generated, the processor ‘jumps’ to an address at the bottom of the CODE memory area. These locations must contain suitable code with which the microcontroller can respond to the interrupt or, more commonly, the locations will include another ‘jump’ instruction, giving the address of suitable ‘interrupt serv- ice routine’ located elsewhere in (CODE) memory.

While the process of handling interrupts may seem rather complicated, creating interrupt service routines (ISRs) in a high-level language is a straightforward process, as illustrated in Listing 13.3.

An introduction to schedulers-0224

The result of running the program shown in Listing 13.3 in the Keil hardware simula- tor is shown in Figure 13.3.

An introduction to schedulers-0225

Much of Listing 13.3 should be familiar. The code to set up Timer 2 in the function Timer_2_Init() is the same as the delay code discussed in Chapter 11, the two main differences being that, in this case:

1 The timer will generate an interrupt when it overflows

2 The timer will be automatically reloaded, and will immediately begin counting again We discuss both of these differences in the following subsections.

The interrupt service routine (ISR)

The interrupt generated by the overflow of Timer 2, invokes the ISR called, here, X().

An introduction to schedulers-0226

The link between this function and the timer overflow is made using the Keil key- word interrupt (included after the function header in the function definition):

void X(void) interrupt INTERRUPT_Timer_2_Overflow

plus the following #define directive:

#define INTERRUPT_Timer_2_Overflow 5

To understand where the ‘5’ comes from, note that the interrupt numbers used in ISRs directly correspond to the enable bit index of the interrupt source in the 8051 IE SFR. That is, bit 0 of the IE register will be linked to a function using ‘interrupt 0’. Table 13.1 shows the link between the interrupt sources and the required interrupt numbers for the original 8051/8052.

Overall, the use of interrupts linked to timer overflows is a safe and powerful tech- nique which will be applied throughout this book.

Automatic timer reloads

As noted earlier, when Timer 2 overflows, it is automatically reloaded and immedi- ately begins counting again. In this case, the timer is reloaded using the contents of the ‘capture’ registers (note that the names of these registers vary slightly between chip manufacturers):

An introduction to schedulers-0227An introduction to schedulers-0228

This automatic reload facility ensures that the timer keeps generating the required ticks, at precisely 1 ms intervals, without any software load, and without any inter- vention from the user’s program.

The ability to ‘automatically reload’ Timer 2 simplifies the use of this timer as a source of regular ticks. Note that Timer 0 and Timer 1 also have an auto-reload capability, but only when operating as an 8-bit timer. In most applications, an 8- bit timer can only be used to generate interrupts at intervals of around 0.25 ms (or less); this is not generally useful.

Leave a comment

Your email address will not be published. Required fields are marked *