Файл: The quintessential PIC microcontroller (S. Katzen, 2000).pdf
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 15.06.2025
Просмотров: 5350
Скачиваний: 0
11. One Byte at a Time 279
• Where the TRIS bit is logic 0 then the complement state of the Data flip flop is gated through to both totem-pole transistors. With D low, TRN conducts and TRP is o giving a low pin voltage. With D high, TRP conducts and TRN is o giving a high pin voltage. In this situation the pin follows the state of the Data flip flop with current being sourced or sunk through the relatively low resistance active conducting transistors.
As an example, consider the situation where an electromagnetic relay is to be activated from pin RA0 and requires a 200 mA activation current at 12 V. For currents and voltages of this magnitude we need external bu ering. In Fig. 11.5(d) a bipolar transistor acts as an external switch. If the minimum gain of this transistor is 100 then a 1.8 kΩ resistor will give a base current of 2 mA assuming a base-emitter conduction voltage of 0.7 V and a PIC VOH of at least 4.3 V.
The output of RA4 shown in Fig. 11.5(c) is somewhat di erent in that only the bottom totem-pole transistor is implemented. As opposed to the 3-state structure of Fig. 11.5(a), this structure has only two states; that is active logic 0 and open-circuit. This type of output is known as open drain (or open-collector), see Fig. 2.3 on page 20.
• When the TRIS flip flop is logic 1, its reset state, then the AND output is low and TRN is o with the output pin high resistance. RA4 is then set to input.
•When TRIS is logic 0 the output transistor conducts when the Data flip flop is logic 0 giving an active-low output. When the Data is logic 1, TRN is o and the output floats.
An open-drain output cannot source current; either the load itself must be connected from the output pin to a positive voltage or an external pull-up resistor used as a load for the on-chip transistor. This is the case in Fig. 11.5(d) where the base current for the external transistor is derived from the 1.8 kΩ pull-up resistor when RA4 is o .
There is one further di erence between RA4 and RA0:3/RA5. The distinction is in the use of a Schmitt trigger bu er to give a better noise immunity when RA4 is used as the input to Timer 0 – see Fig. 13.3 on page 365. As a consequence, logic levels into RA4 are di erent to other Port A (and Port B) inputs. If RA4 is to be used as the Timer 0 input, it is usually configured as an input. If configured as an output, then in this situation PORTA[4] must be set to logic 1, which will disable the opendrain transistor and prevent interaction between it and the external clock input to the Timer.
Many applications involve reading the state of arrays of switches. Rather than use the relatively more expensive single-pole double-throw (SPDT) switch arrangement of Fig. 11.6(a) to give the two logic states, most switches; for example, those in the keypad of Fig. 11.8, are single-throw (SPST) types. In these situations an external pull-up resistor is needed to
11. One Byte at a Time 281
We see from Fig. 11.7 that the internal pull-up resistors (actually a P- channel FET) are switched in only if RBPU (Register B Pull Up, bit 7) of the Option register is low. Although all eight pull-ups are qualified by RBPU only those pins configured as inputs (TRIS[n] = 1) will have the resistor switched in. RBPU resets to 1 and so the pull-up resistors default to o .
As a typical application of weak pull-ups, consider the problem of reading a keypad, such as that illustrated in Fig. 11.8(a). In this particular example there are 12 switches and rather than use up all these scarce I/O pins it is hardware e cient to connect these switches in the form of a 4×3 matrix, as illustrated in Fig. 11.8(b). This 2-dimensional array reduces the I/O pin count to 7. Larger keypads show an even greater e ciency gain, with a 64-contact 8 × 8 keyboard needing only 16 I/O pins.
1 |
2 |
3 |
VDD |
RB7 |
(1) |
1 |
2 |
3 |
|
4 |
5 |
6 |
RB6 |
(0) |
4 |
5 |
6 |
||
7 |
8 |
9 |
RB5 |
(1) |
7 |
8 |
9 |
||
MEM |
0 |
SET |
RB4 |
||||||
(1) |
MEM |
0 |
SET |
||||||
(a) A 4x3 |
keypad |
RBPU = 0 |
|||||||
(1) |
RB3 |
330R |
|||||||
(0) |
RB2 |
330R |
|||||||
(1) |
RB1 |
330R |
|||||||
(b) Showing |
key 5 being |
accessed |
|||||||
Fig. 11.8 Interfacing to a keypad.
Although there are variations on this theme, the topology shown here is typical. The four rows are read in via RB7:4 with internal pull-up resistors enabled. The three columns connected to RB1:3 can be individually selected in turn by driving the appropriate pin low, thus scanning through the matrix. The switch contacts are normally open and, because of the pull-up resistors, read as logic 1. Should a switch connected to a low column line be closed then the appropriate row line is low. This means that
282 The Quintessential PIC Microcontroller
once the closed key row has been detected the column:row intersection is known. The 330 Ω resistors limit the current through the switch should one of the RB7:3 pins accidentally give a low output due to erroneous software.
In order to tie these concepts together, consider a subroutine to interrogate the keypad and return either with the key pressed (or at least the first key found if more than one) or if no key then −1 (i.e. FFh). Before looking at the coding we can assume that somewhere in the main software Port B has been configured appropriately with the correct input and outputs assigned and that bit RBPU in the Option register has been cleared. Something like:
include "p16f84.inc" |
||
MAIN bsf |
STATUS,RP0 |
; Change to Bank1 where |
movlw |
b’11110000’ |
; TRISB & OPTION_REG lie |
movwf |
TRISB |
; RB7:4 inputs, RB3:0 outputs |
bcf |
OPTION_REG,NOT_RBPU ; Activate internal pull-ups |
|
bcf |
STATUS,RP0 |
; Go back to Bank0 |
The listing of Program 11.1 is based on the task list:
1.Set KEY_COUNT to one.
2.For i = 0 to 2.
•Activate column i.
•For j = 0 to 3.
–Check row j.
–IF zero THEN BREAK to step 4.
–ELSE advance KEY_COUNT by 3.
•Reset KEY_COUNT back to j+1.
3.Set KEY_COUNT to −1 if no key found.
4.Return KEY_COUNT.
Basically the sequence of operations is to begin with a count of one; i.e. key[1], and bring column[0] low. As each row is checked for a zero, the count kept in the Working register is advanced by 3 (lines 21, 24, 27) to reflect the three keys in each row. If no closure (that is a 0) is found, the column key tally in memory at KEY_COUNT is advanced by one (i.e. one column) and the next column tried.
There are two ways out of the loop.
•If a 0 is found during the scan, the count in W is the desired value and the subroutine immediately returns (lines 20, 23, 26, 29).
•If the column pattern shift in line 36 results in the sample 0 arriving in bit 0 then the subroutine returns FFh to show no key has been found.
In the real world a subroutine like this would often read in rubbish due to switch bounce and possibly noise induced in the connections between keypad and the electronics.
One way of filtering out this unpredictability is shown in the subroutine of Program 11.2. Here the state of the keypad is interrogated using