The current version is 1.0. Right now it covers the most common interrupt sources, but more can be added if you'll leave a comment mentioning which you think would be handy.
Compilation Constants
In your program, you'll define compilation constants indicating which interrupts you intend to use. Here are the choices so far, with the first larger group considered to be peripheral interrupts, the remaining group of three not.
ADC: analog to digital converter
RXD: serial receive
TXD: serial transmit
SSP: synchronous serial port
CCP1: capture/compare/PWM
T1_OVERFLOW: Timer1 overflow
T2_MATCH: Timer2 match
OSC_FAIL: primary oscillator fail
COMPARATOR: analog comparator
EEPROM_WRITE: Eeeprom write done
T0_OVERFLOW: Timer0 overflow
PIN_B0: external pin B.0 interrupt
PORTB_CHANGE: PortB has changed
You may define up to six interrupts in your programs. For example,
{$DEFINE INTERRUPT1 'TIMER0_OVERFLOW'}
{$DEFINE INTERRUPT2 'COMPARATOR'}
{$DEFINE INTERRUPT3 'ADC'}
Don't forget the single quote marks since these are compiler string constants.
Commands
Once you've done this, you can then use the following commands to enable or disable the various interrupts you've defined.
procedure IntOn(which);
procedure IntOff(which);
Note that the argument is a member of the t_int data type whose values correspond to the string constants mentioned above, i.e.,
type
t_int = (GLOBAL, PERIPHERALS, ADC, RXD, TXD, SSP, CCP1, T1_OVERFLOW, T2_MATCH, OSC_FAIL, COMPARATOR, EEPROM_WRITE, T0_OVERFLOW, PIN_B0, PORTB_CHANGE);
Further note that these two procedures are optimized to recognize only the interrupt types you've defined, and hence are quite compact.
For even greater convenience, observe that calling IntOn() not only sets the individual interrupt enable bit, but also the global enable bit, and the peripheral interrupt enable bit if applicable. On the other hand, IntOff() only clears the individual interrupt bit.
Additionally you can set/clear the peripheral interrupts (use an argument of
PERIPHERALS) or set/clear all interrupts (use an argument of GLOBAL).
Global Variables
Should you wish to work at a more elementary level, you can also access the various interrupt bits directly with the more convenient MASK aliases declared in the global variables section. These are:
MASK_GLOBAL
MASK_PERIPHERALS
MASK_ADC
MASK_RXD
MASK_TXD
MASK_SSP
MASK_CCP1
MASK_T1_OVERFLOW
MASK_T2_MATCH
MASK_OSC_FAIL
MASK_COMPARATOR
MASK_EEPROM_WRITE
MASK_T0_OVERFLOW
MASK_PIN_B0
MASK_PORTB_CHANGE
For example,
MASK_ADC := true;
will enable the analog-to-digital converter interrupt. Likewise, you can access the various interrupt flags with the similar FLAG aliases. For example,
if (FLAG_T0_OVERFLOW) then
LED := 1;
PMP Interrupts: An Overview
Don't forget that PMP already has a compiler directive for setting up interrupt service routines. As an overview,
{$INTERRUPTS ON, UNIQUE}
specifies that you intend to use one interrupt service routine only, and that the entry point should be generated in code. Use OFF, of course, if you don't wish an entry point to be generated.
{$INTERRUPTS ON, MULTIPLE}
on the other hand indicates that you have several interrupt service routines. The service routines will be called sequentially.
In the multiple case, then, you will need a selection structure in each service routine to determine if it applies to the current interrupt. For example, even if you have several interrupt service routines, this one (below) will only be executed if Timer0 has overflowed.
procedure update; interrupt;
begin
if (FLAG_T0_OVERFLOW) then
begin
FLAG_T0_OVERFLOW := 0;
inc(ticks)
end
end;
Of course, you can simply use a unique service routine and have a multi-selection structure within it which determines which interrupt to handle. Indeed, this may be more efficient than employing several routines, since multiple procedure calls from the main program are avoided.
In any case, study the PMP manual carefully.
Add It to Your Library Collection
You can get the Interupts library unit "Interrupts.pas" by clicking the following link:
Be sure to read over the source code for additional details on how to use it.
And, oh, one more thing: earlier version of PIC Micro Pascal sometimes hiccupped on the register bit names, so this unit is really only usable with Version 2.1.4 (the newest version currently).
Try It Out
I've put together a couple simple demos so you can see how the unit helps make things simpler. These use a circuit very similar to that in the four-digit, 7-segment exercise, so check out the schematic there. Note that both of these also use the Timers library unit.
As always, please be sure to leave a comment if you're finding this useful, or if you have a suggestion for improvements.
No comments:
Post a Comment