2003_06_supp(1).pdf

(619 KB) Pobierz
T
N
EE ME
FR LE
PP
SU
EPE PIC
TUTORIAL V2
JOHN BECKER
PART THREE
Quite simply the easiest
low-cost way to learn
about using PIC
Microcontrollers!
In this final part we look at some of the
more sophisticated aspects of using PICs,
and highlight some differences between the
’84 and the ’87x and ’62x families.
EPE PIC
TUTORIAL
R
EFERRING
back to Listing 30 and
Program TK3TUT30 of Part 2 last
month, we continue examining the
program for a 24-hour clock displayed on
an alphanumeric l.c.d.
LISTING 30A
SWAPF STORE2,W ; get tens
ANDLW 15
ADDLW 48
CALL LCDOUT
MOVF STORE2,W ; get units
ANDLW 15
ADDLW 48
CALL LCDOUT
MOVLW ‘:’
; insert colon
CALL LCDOUT
holds the result in W, putting the tens into
the LSN position. Command ANDLW 15
isolates that nibble, zeroing the MSN.
Now ADDLW 48 converts the value to the
ASCII character, and LCDOUT is called,
which sends the data to the l.c.d. (Have
you noticed the similarity to the nibble
extraction used for 7-segment displays?)
Next, MOVF STORE2,W brings the
entire byte into W, ANDLW 15 isolates the
nibble which is in the correct LSN posi-
tion. Again ADDLW 48 and CALL LCD-
OUT are performed. Following that, the
ASCII value for a colon (58) is sent to the
l.c.d., using the single quotes method pre-
viously seen in tables.
Hours, minutes and seconds values are
dealt with similarly, although minutes are
followed by the decimal point (ASCII 46).
Seconds are not followed by any character,
although they could have a space character
(ASCII 32) sent after the units. The
sequence of events, from individually
incrementing time to outputting the data to
the l.c.d. is shown in Listing 30 (Part Two).
Now compare this listing with that for
outputting the time data to the 7-segment
displays (TK3TUT28). Look especially at
the clock count section (from CLKADD to
end of ADDCL2). The second version, of
TIME OUT TO L.C.D.
As with 7-segment l.e.d. clock counting
routines, with the l.c.d. program the
numerical values are held as BCD counts
and each digit is, of course, between 0 and
9 decimal. To the l.c.d., though, values 0 to
9 represent the characters which it holds at
its character register addresses 0 to 9,
which is not the same thing. The l.c.d.’s
characters which “look like” our 0 to 9, are
held at its addresses 48 to 57, in other
words, they are ASCII characters.
With the 7-segment display, we had to
use a table to convert from decimal to a
code that it would show meaningfully.
With the l.c.d., the conversion is much eas-
ier, we simply add the difference between
the decimal value and its ASCII value, i.e.
we increase the value by 48.
Conveniently, 48 decimal has a binary
value of 00110000. The BCD values for
decimal 0 to 9 lie between binary
00000000 and 00001001. All we need to
do, therefore, is to set bits 4 and 5 of the
time digit value in order to increase it by
48, i.e. decimal 9 becomes binary
00111001, which equals 57, the ASCII
code for numeral 9.
The easiest way to set bits 4 and 5 is to
either add 48 to the digit’s value, or to OR
48 with it. In other words, to use either
ADDLW 48 or IORLW 48 as the com-
mand. In this situation they both have the
same effect. To use BSF would require two
commands instead of just one. In the fol-
lowing conversion example, the additive
technique is used (IOR is used in the
program), as shown in Listing 30A.
The SWAPF STORE2,W swaps the nib-
bles of the value held in STORE2 and
CLOCKING ON
which the main part is shown in Listing 30,
is considerably more compact.
After initialisation and general set-up,
the program enters the MAIN routine. At
each
1
/
25
th second time-out, CLKADD is
called and the CLKCNT counter decre-
mented, as we saw earlier. Only if the
value of CLKCNT is zero is the next rou-
tine entered. After resetting CLKCNT, the
address of CLKSEC is set in the indirect
address register FSR, a loop (LOOP) is set
for three operations and STORE1 is
cleared for use as an up-counter. In the
three steps round the loop, CLKSEC is
dealt with first, then CLKMIN and then
CLKHRS.
First time round the loop, at ADDCLK
the first byte to be incremented is, of
course, CLKSEC. This is then checked for
a units value greater than nine and action
taken accordingly. Next, the value within
STORE1 is copied into W and a table
(CHKVAL – see full listing) is called,
returning with the maximum permitted
value for the byte being processed, storing
it in STORE2.
The value of the time byte (CLKSEC at
this moment) is then copied into W, which
is then subtracted from STORE2. If the
Carry flag is set, then STORE2 is greater
than CLKSEC (there is no borrow) and an
exit is made from the loop, no further
action being needed, and a jump is made to
the display routine (CLKSHW).
If CLKSEC is greater than STORE2 a
borrow occurs, thus CLKSEC is cleared,
counter STORE1 is incremented for the
sake of the table jump address, and the
FSR address is incremented (to point now
to CLKMIN). The loop counter (LOOP) is
decremented and, if it is not zero, the loop
is repeated, this time incrementing and
checking CLKMIN in the same way as
CLKSEC was dealt with. If CLKMIN is
reset, the loop is repeated for the third
occasion, this time for CLKHRS.
Everyday Practical Electronics, June 2003
PIC Tutorial V2 Supplement
33
Two sub-routines are used with
CLKSHW, to save repetition of too many
commands. The routines are LCDLIN and
LCDFRM. The former is responsible for
setting the starting display cell position on
the l.c.d. Since in a larger program this
position could change frequently, it is
worthwhile having a generalised routine
for this purpose. In this case, we want the
time to be shown at the start of the second
l.c.d. line, so the value B’11000000’ (the
address of line 2 cell 0) is moved into W
and LCDLIN called. All LCDLIN does is
set the RSLINE flag for command mode
(BCF RSLINE,4), call LCDOUT, and reset
the RSLINE flag to character mode (BSF
RSLINE,4).
Next, the value of CLKHRS is moved
into W and LCDFRM called. This routine
does the swapping, ANDing and ORing
necessary for numerical conversion to the
ASCII value. After this, the colon is sent
directly to LCDOUT. Similar commands
are then given with regard to CLKMIN and
CLKSEC. The program then returns to the
MAIN routine to begin again.
It is worth commenting at this point that
the starting l.c.d. cell position can be set to
any value via the LCDLIN routine. Line 1
needs bits 7 and 6 set to 1 and 0 respec-
tively. Line 2 needs bits 7 and 6 set to 1 and
1 respectively. The cell position on the
lines is controlled by the final four binary
digits, bit 3, 2, 1, 0. For example, to set for
line 1 cell 8 (regarding the first cell as zero)
the value of B’10001000’ should be sent to
LCDLIN, for line 2 cell 15 the value is
B’11001111’.
LISTING 31
PROGRAM TK3TUT31
MAIN
BTFSS INTCON,2
GOTO MAIN
BCF INTCON,2
CALL CLKADD
GOTO MAIN
DECFSZ CLKCNT,F
RETURN
MOVLW 25
MOVWF CLKCNT
CALL GETKEY
INCF HLFSEC,F
BTFSC HLFSEC,0
CALL CLKIT
RETURN
CLKADD
Counter CLKCNT is still set for 25 but
we use an additional counter HLFSEC for
half seconds, so that although the switches
are sampled every half second, the seconds
themselves are still incremented correctly.
Referring to Listing 31, you will see the
command CALL GETKEY, which is then
followed by INCF HLFSEC,F. Only if bit 0
of HLFSEC is 1 will the CLKADD routine
be entered. Imagine now that the switches
on PORTA are designated as follows:
SW4 = seconds reset
SW3 = hours
SW2 = minutes
SW1 = plus (+)
SW0 = minus (–)
(SW4 is the optional switch referred to a
moment ago)
At GETKEY, if switch SW3 is pressed
(hours), EVENT bit 0 is set to 1. This file
value will be used when accessing the
CHKVAL table for the maximum roll-over
value for hours or minutes. Now the
address of CLKHRS is moved into W and
a jump to TIMSET is made.
At this routine, the plus (+) and minus
(–) keys are read for their status, and the
addition (ADDTIM) or subtraction (SUB-
TIM) routine is jumped to and processed.
In these routines, not only have the units to
be checked for values greater than nine, but
the overall BCD value has to be checked
for greater than 23 (hours) and greater than
59 (minutes).
In the addition routine, the excess value
is checked for, and the value is reset to zero
if it is exceeded. In the subtraction routine,
zero is checked for, in which case the max-
imum allowed value is moved into the byte
as the reset value. In both instances, the
value within EVENT is moved into W and
table CHKVAL is called for the maximum
value.
All the commands involved in these rou-
tines should by now be familiar to you
without further explanation. Load
TK3TUT31.HEX and experiment with set-
ting the time.
(Section from CLKIT to end of
LCDLIN omitted)
GETKEY
BTFSS PORTA,3
GOTO CHKSW2
BSF EVENT,0
MOVLW CLKHRS
GOTO TIMSET
BTFSS PORTA,2
RETURN
CLRF EVENT
MOVLW CLKMIN
MOVWF FSR
BTFSC PORTA,0
GOTO SUBTIM
BTFSS PORTA,1
RETURN
INCF INDF,F
MOVLW 6
ADDWF INDF,W
BTFSC STATUS,DC
MOVWF INDF
INCF EVENT,W
CALL CHKVAL
MOVWF STORE2
MOVF INDF,W
SUBWF STORE2,F
BTFSS STATUS,C
CLRF INDF
GOTO CLKSHW
MOVLW 1
SUBWF INDF,F
BTFSS STATUS,C
GOTO SUBSET
BTFSC STATUS,DC
GOTO ENDSUB
MOVF INDF,W
ANDLW B’11110000’
IORLW 9
MOVWF INDF
GOTO ENDSUB
INCF EVENT,W
CALL CHKVAL
MOVWF INDF
GOTO CLKSHW
CHKSW2
TIMSET
ADDTIM
EXERCISE 23
TUTORIAL 24
23.1. Extend the program so that the
clock also keeps track of months and years.
CONCEPTS EXAMINED
Adding time-setting switches
CONNECTIONS NEEDED
L.C.D. as in Fig.7 (Part Two)
CP20 to +5V OUT
CP21 to 0V OUT
Crystal oscillator
The clock program of TK3TUT30 that is
now being run is perfectly usable as a real-
time clock, as is the 7-segment version (but
see later). They both have a major problem
though, the programs have to be started
(reset) at exactly midnight for the time
shown to be accurate. What we need is the
ability to set the current time via switches,
as with most other time-keepers. Here we
show how switched time-setting can be
programmed into the l.c.d. version.
We have already looked quite heavily at
the use of switches in earlier sections. It is
not hard to implement switched time-set-
ting routines, but it takes quite a few com-
mands (as Listing 31 shows), especially as
we are allowing you a luxury: the ability to
count upwards or downwards on both min-
utes and hours. Many clocks do not allow
this, and it can be a right pain if you over-
shoot the time you want! We also allow
you the option of a fifth switch to reset the
seconds, although you will need to add that
switch externally to
TK3’s
p.c.b.
First, though, attention must be paid to
the rate at which the digits are changed by
SUBTIM
TIMING ACCURACY
SUBSET
ENDSUB
the switches. We could easily insert a
switch checking routine either on each
1
/
25
th count, or on each second. However,
the first is too fast for convenience, and the
other too slow. A better rate is on every
half-second. This can be arranged by halv-
ing the prescaler rate, setting it for a ratio
of 1:64 instead of 1:128. Thus, in the
initialisation, instead of commands
MOVLW B’10000110’ and MOVWF
OPTION_REG, we use:
MOVLW B’10000101’
MOVWF OPTION_REG
It is important to be aware that the accu-
racy of a crystal controlled clock using
coding such as this is not perfect. Crystals
are subject to manufacturing tolerance in
respect of the exact frequency at which
they oscillate. Unless the crystal on the
p.c.b.
is
oscillating
at
exactly
3276800·00Hz, the timing will drift over
extended periods.
In other hardware designs it is possible
to include a trimmer capacitor in the oscil-
lating circuit to adjust for timing drift. It is
also possible to include sophisticated
adjustment routines in the program to
compensate. Such an example is included
with the
PICronos L.E.D. Wall Clock
pub-
lished in
EPE
June ’03. Such techniques,
though, are beyond the scope of these
Tutorials.
EXERCISE 24
24.1. Change the role of switch SW4
and create a routine that will also show
how many hours, minutes and seconds
there are until midnight (00:00.00 hours or
24:00.00 if you find it easier) when you
press a switch, clearing the answer when
the switch is released.
34
– PIC Tutorial V2 Supplement
Everyday Practical Electronics, June 2003
LISTING 32A PROGRAM TK3TUT32.ASM
SETPRM
MOVWF EEADR
BANK1
BSF EECON1,WREN
BANK0
MOVF STORE1,W
MOVWF EEDATA
BANK1
MOVLW H’55’
MOVWF EECON2
MOVLW H’AA’
MOVWF EECON2
BSF EECON1,WR
BTFSS EECON1,4
GOTO CHKWRT
BCF EECON1,WREN
BCF EECON1,4
BANK0
BCF INTCON,6
RETURN
; Copy W into EEADR to set EEPROM address
; enable write flag
; get data value from STORE1 and hold in W
; copy W into EEPROM data byte register
; these next 12 lines are according to
; Microchip manual dictated factors
; they cause the action required by
; by the EEPROM to store the data in EEDATA
; at the address held by EEADR.
; set the ”perform write’’ flag
; wait until bit 4 of EECON1 is set
; disable write
; clear bit 4 of EECON1
; clear bit 6 of INTCON
; and RETURN
MANUAL
CHKWRT
LISTING 32B
GETPRM
MOVWF EEADR
BANK1
BSF EECON1,RD
BANK0
MOVF EEDATA,W
RETURN
; copy W into EEADR to set EEPROM address
; enable read flag
; read EEPROM data now in EEDATA into W
; and RETURN
run as it stands and is for use as a sub-
routine within a main program. Also note
that the program is specific to the
PIC16F84 and that other PIC families may
require slightly different coding. Examples
for the PIC16F87x and PIC16F62x fami-
lies are discussed later.
In some respects, use of the EEPROM
read/write facility is similar to that used in
indirect addressing, a special register
(EEADR) is loaded with the address with-
in the EEPROM at which the data is to be
stored or retrieved. This register can be
likened to FSR.
The data which has to be written to the
EEADR register is loaded into register
EEDATA (equivalent to INDF).
On retrieving data from the EEPROM,
register EEADR is loaded with the address
from which the data is to come, and then
the PIC copies the data from that position
into EEDATA.
Prior to writing data to the EEPROM, a
write-enable flag has to be set in register
EECON1. Another flag is set in EECON1
when data is to be read from the EEPROM.
To transfer data from EEDATA to the
EEPROM file pointed to by EEADR, an
obligatory routine as specified in the PIC’s
datasheet has to be performed. This routine
initialises operations built into the PIC and
which last for a predetermined time.
A flag (EECON1,4) is set by the PIC
when these operations have occurred and
its setting has to be waited for before fur-
ther program commands can be performed.
Failure to wait for the flag setting can dis-
rupt the correct storage of the data.
An example of how the writing routine
is used is shown in Listing 32A. Prior to
entry into the routine at SETPRM, the data
to be written is temporarily placed in file
STORE1 (or any name you like). Then the
EEPROM address at which the data is to be
stored is moved into W and the call to SET-
PRM is issued.
On entry to SETPRM, the contents of W
are copied into EEADR, and then, via
BANK1,
the
command
BSF
EECON1,WREN is given, setting the
EEPROM into write-enable mode, after
which follows a reset to BANK0. Data is
then copied from STORE1 into W and then
into EEDATA.
Now the routine specified in the PIC’s
datasheet is started at label MANUAL. The
12 lines of this routine, from BANK1 down
to BCF INTCON,6 should be followed
parrot-fashion in any other EEPROM-writ-
ing program. The final return command
could be replaced by a GOTO, or by the
program immediately following on into
another routine.
Reading data from the EEPROM is very
simple, as Listing 32B shows. The routine
is entered at GETPRM with the EEPROM
file address held in W. This is copied into
EEADR then, via BANK1, the enable read
flag is set (BSF EECON1,RD) and
BANK0 reset. The data required is imme-
diately available to be copied into W by the
command MOVF EEDATA,W.
EXERCISE 25
TUTORIAL 26
There is no exercise for this Tutorial.
CONCEPTS EXAMINED
Illustrating use of EEPROM data
read/write
Converting binary value to hexadecimal
CONNECTIONS NEEDED
L.C.D. as in Fig.7
CP20 to +5V OUT
CP21 to 0V OUT
Crystal oscillator
Program TK3TUT33.ASM illustrates an
example of writing to and reading from the
PIC’s Data EEPROM. It uses the l.c.d. to
display three values, and switches SW0 to
SW2 to increment them. Switch SW3 caus-
es the new values to be stored into the Data
EEPROM at consecutive addresses from 0
to 2.
After the program’s initialisation
sequence, data currently stored in the EEP-
ROM is recalled as shown in routine GET-
VALUES in Listing 33. To retrieve a value
the address at which it is stored in the EEP-
ROM is first loaded into W (0 in the first
instance). The routine at GETPRM (dis-
cussed in Tutorial 25) is then called, and a
return is made to the calling routine with
the retrieved EEPROM value held in W.
This is then stored into the register required
(in the first instance VALUE0).
The procedure is repeated three times
and then a call is made to the display rou-
tine SHOWVALS in which the values are
shown in hexadecimal.
The MAIN routine is then entered in
which the four switches are read at 1/5th of
a second intervals (set by routine PAUSIT).
If any of switches SW0 to SW2 are found
to be pressed, the associated VALUE is
incremented in binary and the display rou-
tine called again, followed by a return to
label MAIN.
If switch SW3 is found to be pressed, the
data storage routine is called, at STOREIT.
The value to be stored (VALUE0 in the
first instance) is called into W and moved
into a temporary store, STORE1. The EEP-
ROM address at which the data is to be
stored (0 in the first instance) is then called
into W and the SETPRM routine called,
24.2. This one is more complicated! By
doing exercise 24.1 you have lost the abili-
ty to reset the seconds count when you
want to – unless you amend the program,
seconds will be reset whenever SW4 is
pressed. It is possible to amend the pro-
gram so that switch SW1 and SW0 still
serve as plus and minus controls, but SW2
could be used to select whether it is the
minutes or the hours that are amended,
with a suitable symbol indicating which
value is under control. SW3 could then be
used to reset the seconds, with SW4 simply
controlling the midnight countdown dis-
play. Have a go at this challenge!
TUTORIAL 25
CONCEPTS EXAMINED
Writing and reading EEPROM file data
Register EECON1
Register EECON2
Register EEDATA
Register EEADR
We have already shown how convenient
it is to be able to repeatedly change the pro-
gram data within a PIC. The demos and
your experiments would simply not have
been practical had we been using a micro-
controller which required erasing by ultra-
violet light each time a new program had to
be loaded into it.
Now we come to another great advan-
tage of most PICs, including the
PIC16F84, the presence of an EEPROM
data memory which can be written to and
read from whenever we want, and which
will not lose the data when the power is
switched off.
We shall now show the commands need-
ed for EEPROM data memory read/write
operation and then in Tutorial 26 demon-
strate a simple program that makes use of
the facility.
The full program for this initial discus-
sion is on your disk as TK3TUT32, its
main contents are shown in Listings 32A
and 32B. Note that this program cannot be
Everyday Practical Electronics, June 2003
PIC Tutorial V2 Supplement
35
LISTING 33 PROGRAM TK3TUT33.ASM
GETVALUES
MOVLW 0
CALL GETPRM
MOVWF VALUE0
MOVLW 1
CALL GETPRM
MOVWF VALUE1
MOVLW 2
CALL GETPRM
MOVWF VALUE2
CALL SHOWVALS
MAIN
CALL PAUSIT
BTFSC PORTA,0
GOTO INCVAL0
BTFSC PORTA,1
GOTO INCVAL1
BTFSC PORTA,2
GOTO INCVAL2
BTFSC PORTA,3
GOTO STOREIT
GOTO MAIN
INCVAL0
INCF VALUE0,F
CALL SHOWVALS
GOTO MAIN
INCVAL1
INCF VALUE1,F
CALL SHOWVALS
GOTO MAIN
INCVAL2
INCF VALUE2,F
CALL SHOWVALS
GOTO MAIN
STOREIT
MOVF VALUE0,W
MOVWF STORE1
MOVLW 0
CALL SETPRM
MOVF VALUE1,W
MOVWF STORE1
MOVLW 1
CALL SETPRM
MOVF VALUE2,W
MOVWF STORE1
MOVLW 2
CALL SETPRM
(routine to display STORED)
WAITSW
BTFSC PORTA,3
GOTO WAITSW
(routine to clear STORED)
GOTO MAIN
where the data is stored at the required
address (as discussed in Tutorial 25).
Following storage of all values, the word
STORED is displayed on screen for as long
as switch SW3 is held pressed. When the
switch is released, the word is cleared and
a jump back to label MAIN is made, to
await the next switch press.
For convenience in this Tutorial, in the
data display routine the binary values are
converted to hexadecimal and then dis-
played. In Tutorial 33 later, conversion of
binary numbers to decimal values suitable
for l.c.d. display use is illustrated.
In the binary to hex routine, an extract of
which is shown in Listing 33A, the byte
value is first swapped into W to put the
MSN (most significant nibble) into the
righthand position, and a call made to a
conversion table, HEXTABLE (see full
listing). Here the value in W is ANDed
with B’00001111’ to extract just the lower
nibble, and ADDed to PCL. The table jump
then returns with the hex value for that nib-
ble, which is then sent to the l.c.d. The pro-
cedure is repeated for the LSN of the value
byte.
To prove that the data has been stored,
note the three values, switch off the power
for a few seconds and then switch back on.
; get values from EEPROM address 0 to 2
; store into VALUE
; show values
; 1/5th sec pause
; is SW0 pressed?
; yes
; no, is SW1 pressed?
; yes
; no, is SW2 pressed?
; yes
; no, is SW3 pressed?
; yes
; no
; inc VALUEs as called and then show
such as in response to clocked timing
values.
It is vital to appreciate that a PIC’s Data
EEPROM has a finite number of times that
it can be written to – around one million
times according to the PIC16F84’s
datasheet. This may seem a large number,
but it can soon be consumed by incautious
programming causing the EEPROM to be
repeatedly written to.
During program development when
automatic EEPROM writing is included, it
is worthwhile putting in a temporary inter-
cept counter and l.e.d. or l.c.d. display rou-
tine to monitor the number of times that
calls are made to the EEPROM write
routine.
EXERCISE 26
; store all VALUEs into EEPROM
; wait until switch SW3 released
The data displayed on screen when the pro-
gram restarts will be the same as that
noted. You can also examine all the Data
EEPROM values via
TK3’s
EEPROM
Message Read facility.
LISTING 33A
SWAPF VALUE2,W
CALL HEXTABLE
CALL LCDOUT
MOVF VALUE2,W
CALL HEXTABLE
CALL LCDOUT
EEPROM data storage and retrieval
has many applications in practical situa-
tions. For example, the option is valuable
when setting up a program during the
testing or tuning stages, allowing the
values to be recalled next time the pro-
gram is run.
The values to be stored need not have
originated from switches, they could be
provided by other functions within a pro-
gram. Storage of the values can be
in response to a switch press, as
illustrated, or could again be triggered by
some aspect within the running program,
The following two exercises are compli-
cated and should only be attempted by
those who have successfully followed the
Tutorials so far!
33.1 To illustrate EEPROM writing
and reading, the author considered modi-
fying the 4-note playing program of
TK3TUT19 so that it became eight notes,
which were played in the order specified
by data in the EEPROM. The data would
have been entered via the switches, using
the l.c.d. to display which note numbers
were being stored at which EEPROM
addresses.
A separate switch would have been
used to start and stop the note sequence
being played. Each note would have had a
duration of one second, although it would
be possible to set their durations by
switches. It would seem preferable to
have separate up/down switches, a MODE
switch to select the functions of the other
switches on a cyclic basis, and a
Start/Stop switch. It should be possible to
do it with the four switches on
TK3’s
p.c.b. Can you do it?
33.2. You will have discovered that pre-
cise musical tuning of the four notes in
program TK3TUT19 is not possible using
the length of a loop to determine the fre-
quency. It
is
possible though, if within the
loop you use a 24-bit counter (three bytes,
MSB, NSB, LSB) and add a 16-bit number
(two bytes) to it. The toggling of PORTA
RA4 would then depend on one of the bit
values of the counter’s MSB. The additive
value depends on the note to be generated
and so eight notes need one each.
It is suggested that you try this technique
with the program modified in 33.1. The
principle was illustrated in the author’s
StyloPIC
of July ’02 (on the PIC Resources
CD-ROM)..
(A similar additive technique can also be
used to adjust the precise timing of a crys-
tal controlled clock, as used in the
PICronos
clock referred to earlier).
TUTORIAL 27
Interrupts
Command RETFIE
CONCEPT EXAMINED
CONNECTIONS NEEDED
SW0 to RB0
LD0 to RA0
LD1-LD7 to RB1-RB7
CP20 to +5V OUT
CP21 to 0V OUT
Crystal oscillator
36
– PIC Tutorial V2 Supplement
Everyday Practical Electronics, June 2003
LISTING 34
PROGRAM TK3TUT34
ORG 0
GOTO 5
ORG 4
GOTO INTRPT
ORG 5
CLRF PORTA
CLRF PORTB
BANK1
CLRF TRISA
CLRF TRISB
MOVLW B’10000111’
MOVWF OPTION_REG
BANK0
MOVLW B’10100000’
MOVWF INTCON
START
TEST
INTRPT
NOP
GOTO START
BSF PORTA,0
MOVLW 2
ADDWF PORTB,F
BCF INTCON,2
GOTO INTRPT; go to interrupt routine
ORG 5
; Start of Program
Memory
Since the program, once triggered by an
interrupt, automatically jumps to the pro-
gram address stated, we can simply set up
a holding routine which waits until the
interrupt occurs, and then the routine spec-
ified at the interrupt address is performed.
We could actually allow the entire pro-
gram to be performed without using a
holding routine, jumping to the specified
routine when the interrupt does occur. This
is tricky, though, and can be dangerous to
the correct operation of the main program.
Allowance has to made for a particular
operation to be completed before the inter-
rupt routine is performed. It is this type of
information and how to handle it that
Malcolm discusses in his article.
For our purposes now the use of a holding
routine illustrates the essential point about
an interrupt action. It can be as simple as:
START: NOP
GOTO START
The program would normally be con-
stantly looping through the two commands
NOP and GOTO START, waiting for an
interrupt to occur. On its occurrence, the
loop would be exited, and a jump made to
the routine at INTRPT. Obviously, at the
end of the routine caused by the interrupt,
a return to the program point from where
the interrupt jump was made must be spec-
ified. There is a command which is used
for this purpose, RETFIE.
MOVLW B’10100000’
MOVWF INTCON
Setting bit 7 of INTCON enables the
program to respond to any interrupts gen-
erated. Setting INTCON bit 5 enables the
timer as the source of the interrupt. The
stage is now set and the START loop
entered. Each time a timer interrupt
occurs, a jump is made to INTRPT, where
PORTB has a value of 2 added to it (to
bypass LD0) and a return made to START
by the command RETFIE, to await another
interrupt.
To prove that the program is not just
“dropping out” of the START loop, a com-
mand to set PORTA RA0 high has been
included immediately following the GOTO
START command. As you will see via
l.e.d. LD7, this action is never performed.
Load and run TK3TUT34.HEX which
illustrates this interrupt.
EXTERNAL INTERRUPT
From here on, none of the commands
examined directly relate to extending or
modifying any of the foregoing programs.
Connect l.e.d. LD7 to PORTA pin RA0 and
switch SW0 to PORTB RB0.
If, instead of using the timer to generate
interrupts, we want an external source to
generate them, one pin that can be used for
this purpose is PORTB RB0, designated in
the pinout diagram as RB0/INT. (Logic
level changes on PORTB RB4 to RB7 are
other possible interrupt sources.) To use
RB0 as the interrupt source, INTCON bit 4
must be set, as follows:
MOVLW B’10010000’
MOVWF INTCON
INTCON bit 7 must, as shown, also be
set to enable the interrupt.
(Note that if the l.c.d. is connected, the
PIC’s Light Pull-ups option, discussed
later, must be off by setting OPTION_REG
bit 7 high, as shown in Listing 35, other-
wise the influence of the l.c.d. may prevent
the interrupt from being generated.)
Suppose now that we want an external
interrupt on RB0 to cause the rest of
PORTB to be incremented. Each time this
interrupt occurs, the jump from the holding
loop is performed as before. However, it is
now INTCON bit 1 which is set on the
interrupt and has to be cleared before
returning to the holding loop, i.e. BCF
INTCON,1.
Load TK3TUT35 which illustrates this
external interrupt. The interrupt is generat-
ed using switch SW0.
Since the switches used on the p.c.b. are
probably only low-cost types, it is possible
that switch-bounce will cause slightly
erratic behaviour of the l.e.d.s. It should
become clear, however, that the count is
basically incremented when the switch is
pressed, not when it is released.
If a signal generator that outputs a
square wave is connected to RB0 and
monitored on a scope, the triggering
edge should be obvious when the gener-
ator’s rate is set very slow. The signal
generator must produce clean 0V to +5V
pulses.
INTERRUPTS
Early on in this series, mention was
made of Interrupts, saying they would be
examined later. That “later” has arrived!
An Interrupt, as the term implies, literal-
ly is an “interrupt” to the program, causing
it to stop what it is currently doing, and
perform another action or set of actions,
returning to where it left off when the inter-
rupt occurred.
Interrupts can be set to occur from sev-
eral sources, of which two seem the most
likely ones to be required: externally from
another piece of equipment, such as a
switch or from a trigger pulse generated by
another electronic circuit; internally, at the
end of a time-out period generated by the
PIC’s own timer.
There are other interrupt possibilities,
but which are probably of more benefit to
experienced programmers and which will
not be detailed here. Readers wanting more
information on interrupts are referred to
Malcolm Wiles’
Programming PIC
Interrupts
of
EPE
Mar/Apr ’02 (on the PIC
Resources CD-ROM).
There are countless situations where
interrupts can be put to good use. Let’s
examine two of them.
First, the address to which the program
must jump when interrupted has to be
specified. This is where the ORG 4 state-
ment now comes into its own. Following
that statement, and prior to the ORG 5
statement, the jump address is inserted.
Let’s call the jump address INTRPT. So, at
the beginning of the program listing we
make the following statements:
ORG 0
GOTO 5
ORG 4
; Reset Vector address
; go to PIC address
location 5
; Interrupt Vector
address
TIMER INTERRUPT
A simple program which makes use of
an internally timer-generated interrupt to
increment a count on PORTB is shown in
Listing 34. Here, the timer is set in the
same way as we have been doing previous-
ly. Then the INTCON register is told that
an interrupt is to be generated when the
timer rolls over to zero:
LISTING 35
PROGRAM TK3TUT35
ORG 0
GOTO 5
ORG 4
GOTO INTRPT
ORG 5
CLRF PORTA
CLRF PORTB
BANK1
CLRF TRISA
MOVLW B’00000001’
MOVWF TRISB
MOVLW B’11000111’
MOVWF OPTION_REG
BANK0
MOVLW B’10010000’
MOVWF INTCON
START
INTRPT
NOP
GOTO START
MOVLW 2
ADDWF PORTB,F
BCF INTCON,1
RETFIE
INTERRUPT EDGE
It is possible to change the interrupt
response to occur on either edge of the
external pulse. As illustrated in
TK3TUT35, it is in response to the rising
edge. To use the falling edge,
OPTION_REG bit 6 must be cleared dur-
ing the BANK1 setup routine, e.g.:
Everyday Practical Electronics, June 2003
PIC Tutorial V2 Supplement
37
Zgłoś jeśli naruszono regulamin