Файл: The quintessential PIC microcontroller (S. Katzen, 2000).pdf
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 15.06.2025
Просмотров: 5327
Скачиваний: 0
98 The Quintessential PIC Microcontroller
EEDATA register as addressed by the EEADR register and controlled by the EECON1 and EECON2 control file registers. Data EEPROM has a minimum endurance of 1,000,000 writes and such data is retained for upwards of 40 years. Some typical uses of a non-volatile depository would be to hold the number of pages printed in a laser printer or total miles/kilometers travelled in a car.
Details of the Read and Write protocols are given in Chapter 15, but are briefly reviewed here for completeness.
Read
1.Put address (00 – 3Fh) into EEADR.
2.Set RD (bit 0 of EECON1) to 1 to set to the ReaD mode.
3.Read the addressed contents in EEDATA.
Write
1.Put address into EEADR.
2.Put data into EEDATA.
3.Set WREN (bit 2 of EECON1) to 1 to WRite ENable.
4.Put code 55h into EECON2.
5.Put code AAh into EECON2.
6.Begin the Write cycle by setting WR (bit 1 of EECON1) to 1.
Writing, which is normally an infrequent act, is deliberately made circuitous to protect against accidental changes to the EEPROM. The register EECON2 does not actually exist, but the interlock writing 55h followed directly by AAh to File 89h is a necessary part of unlocking the target byte. Interrupts can disrupt this sequence and should be inhibited if used. Writing takes around 50 ms to complete, and sets the EEIF (EEPROM Interrupt Flag) bit 4 of EECON1 after this time, and this can be used to interrupt the processor. The WRERR (WRite ERRor) bit 3 of EECON1 is set if a Write cycle is prematurely terminated, say, by an External reset.
Registers associated with the Data EEPROM are:
EEDATA, File 08h
This contains the addressed data after a Read action and holds data to be written into the addressed byte during a Write action.
EEADR, File 09h
The 6-bit address of the target byte is placed here before a Read or Write cycle.
EECON1, File 88h
This holds the control and status bits that:
•Trigger an EEPROM Read.
•Enable a Write action.
4. The PIC16F84 Microcontroller 99
•Trigger an EEPROM Write.
•Signals a premature end to a Write cycle.
•Signals a Write cycle has been completed. Details are given in Fig. 15.2 on page 434.
EECON2, File 89h
The EEPROM CONtrol 2 is not a physical register and reads as zero. This address is used as the target for the Write cycle unlocking sequence which is implemented by moving 55h followed directly by AAh into this virtual location.
Examples
Example 4.1
Discuss how the performance of the PIC architecture is improved by incorporating pipelining into the design of the instruction-fetch unit. Do you forsee any problems associated with handling Jump instructions (such as goto) in connection with the pipeline structure?
Solution
The pipeline is a precondition for the parallel operation of the fetch and execution units. That is, in order to allow the execution of instruction n whilst the next instruction n + 1 is being fetched from the Instruction store, internal storage must be provided to present the instruction code to the Instruction decoder. As all instructions are the same size, that is 14 bits, then the pipeline register structure and control is considerably simplified. Most conventional CISC processors have instructions that vary considerably in length. For example the 68HC11 MCU core has instructions that cover the range one through four bytes; that is the fetch phase can take between one and four bus transactions. Some more sophisticated processors have multi-stage pipelines with each stage feeding part of the execution circuitry. Thus several streams of execution activity can occur simultaneously.
The problem with pipelines is that they presuppose that the program instructions will be executed sequentially as they are stored in memory. However, instructions that disrupt this smooth running and move on the Program Counter require that the pipeline be emptied so that the instruction code of the destination travels down to the end of the pipe. For example, if instruction k is goto n, then instruction k + 1 will be in the first stage of the pipeline by the time the processor knows that the next step is actually to be instruction n. Thus a null instruction cycle needs to be executed which simply brings this instruction code into the pipeline but does not execute instruction k+1 whose code is at the end of
100 The Quintessential PIC Microcontroller
the pipeline. This is sometimes known as flushing the pipeline. Instructions such as goto need two clock cycles to execute. Conditional Skip instructions, such as incfsz and btfsc take two cycles when the skip is implemented and one otherwise. All other instructions always take one cycle.
Example 4.2
Can you determine why after a subtraction, or addition of a negative number (eg. addlw -6), the setting of the C flag is the complement of the borrow-out. Hint: Look at 2’s complement arithmetic on page 9.
Solution
The solution lies in the method of subtraction by 2’s complementing the subtrahend. The subtract instructions convert the subtrahend to their 2’s complement form and then configure the ALU to add. After the addition there can be two outcomes, depending on the relative magnitude of the minuend and subtrahend.
1.Where the subtrahend is greater than the minuend then the outcome is negative and there is no carry-out. An example of this situation is: 06 − 0A 00000110 + 11110110 = (0) 11111100 or − 4 (no carry).
2.Where the subtrahend is less than the minuend then the outcome is positive and there is a carry-out. An example of this situation is:
0A − 06 00001010 + 11111010 = (1) 00000100 or + 4 (carry).
In both cases the Carry flag acts as an inverted borrow. This is in keeping with the RISC philosophy of the PIC family, to keep the processor ‘lean and mean’. In any case this non inversion means that subtraction can be implemented by adding negative data, eg. addlw -6. This is translated by the assembler to addlw 0FCh, where FCh is of course the 2’s complement of 6.
Example 4.3
Write a program to increment a packed BCD quantity located in Data memory at File 20h.
Solution
Two Binary-Coded Decimal (BCD) digits may be packed into a single byte
to represent numbers up to 99. For example 0100 1001 File 20h represents BCD 49. Incrementing a number stored in this hybrid decimal-
binary form using the normal binary addition rules may give an incorrect result. For example 01001001 + 1 (49 + 1) gives 01001010 (4Ah) after addition, but should give 01010000 (50h). Similarly, 10011001 + 1 (99 + 1) gives 10011010 (9Ah) instead of 00000000 Carry 1 (1 00h).
4. The PIC16F84 Microcontroller 101
From these examples it can be seen that whenever any of the BCD decades equals ten after incrementation then it should be zeroed and one added to any higher decade. Based on this increment and add algorithm we can formulate the task list.
1.Increment the packed BCD byte using normal binary arithmetic.
2.IF the lower nybble of the outcome is ten then add six to the outcome.
3.IF the upper nybble of the outcome is ten then add six to it.
Program 4.1 Incrementing a packed BCD byte.
;**************************************************************
;* FUNCTION: |
Increments a BCD datum giving a BCD outcome |
* |
|||
;* ENTRY |
: |
BCD in F20h |
* |
||
;* |
EXIT |
: |
BCD+1 in F20h |
* |
|
;* |
EXAMPLE : |
10011000 (98) |
+ 1 = 10011001 (99) |
* |
|
;* ************************************************************
; |
|||
STATUS |
equ |
3 |
; The Status register |
C |
equ |
0 |
; Carry flag is bit 0 |
DC |
equ |
1 |
; Digit Carry flag is bit 1 |
BCD |
equ |
20h |
; The BCD number is in File 20h |
; ---------------------------------------------------------- |
|||
BCD_INC |
incf |
BCD,w |
; Binary inc BCD number and put in W |
addlw |
6 |
; Add six |
|
btfss |
STATUS,DC |
; Needed IF produced a half carry |
|
addlw |
-6 |
; ELSE not needed |
|
; Now check the upper |
digit by adding 6 to |
it |
and |
checking Carry |
||
addlw 60h |
; Add 60h (ie six to upper digit) |
|||||
btfss STATUS,C ; Needed |
IF caused |
a Carry |
||||
addlw -60h |
; ELSE cancel the correction factor |
|||||
; The incremented and |
corrected BCD |
number |
is |
now |
in W |
|
movwf BCD |
; Put it |
out in |
memory |
|||
END |
..... ..... |
|||||
Program 4.1 gives an e cient implementation of this task list. After incrementing using normal binary rules, six is added to the previous outcome and the DC flag checked for activity. This flag will only be set when the original nybble was ten (0Ah + 6 = 1 0h). In this case the add six operation is allowed to stand as the necessary correction otherwise it is cancelled by subtraction. The upper nybble (BCD digit) is checked and corrected in the same manner, but this time it is the full Carry flag that is tested. If this is set, then the addition of 60h is allowed to stand, otherwise it is subtracted. This Carry flag could be used to set a hundreds digit if desired, to show overflow from 99 to 100.
An alternative approach would be to subtract nine before incrementation and if the Z flag is set then leave the digit at zero and increment the higher digit; otherwise add ten. Repeat for the upper digit.
102 The Quintessential PIC Microcontroller
Example 4.4
Write a routine that will add two packed BCD numbers at File 20h and File 21h. The outcome is to be in File 22h for the hundred’s digit and File 23h for the tens and unit digits.
Solution
As in the case of Example 4.3 the binary addition of numbers that are already in BCD form may need correction afterwards. Again, a correction will be needed where the digit outcome is greater than nine. The situation is more complex in this case as the sum of two digits can be anywhere between zero and 19 (9 +9 +1(carry-in) = 19). The illegal range 10 to 19 may be determined by applying the criterion:
• Check for the range Ah to Fh (10 to 15) — for example, 3 + 9 = Ch (3 + 9 = 12).
•Otherwise check if there was a carry out to the next decade — for example, 9 + 9 = 1 2h (9 + 9 = 18).
In both cases the digit may be corrected by adding six to ‘jump over’ the six illegal BCD states.
Based on this course a possible task list is:
1.Add the two packed BCD bytes using normal binary arithmetic.
2.IF the addition results in a full Carry THEN Hundreds = 1
3.IF the addition results in a half Digit Carry OR IF the unit BCD nybble is greater than nine THEN add six to the outcome.
4.IF the last correction (if any) resulted in a full Carry OR IF the tens BCD nybble is greater than nine THEN add six to the upper nybble of the outcome.
Program 4.2 directly implements this strategy. The full Carry flag is tested three times.
1.Directly after the addition – for example, 99h + 99h = 1 32h.
2.After the first correction where six is added to the lower digit – for example, 77h + 88h = FFh; FFh + 06h = 1 05h.
3.After the second correction where six is added to the upper digit – for example, 70h + 80h = F0h; F0h + 60h = 1 40h.
If the flag is set at any point then the hundreds digit will be one; the maximum value in this case is 99 + 99 = 198.
A nybble is tested for over nine by subtracting ten. If a carry (half or full depending on which digit is being tested) is not generated then the original nybble must have been ten or greater. I have actually implemented the subtract ten operation by adding −10; that is addlw -10. This is because the sublw instruction actually takes the value in the Working register away from the literal and not the other way around – see also page 55.
4. The PIC16F84 Microcontroller 103
Program 4.2 Adding two packed BCD numbers.
;*********************************************************************
;* FUNCTION: |
Adds two |
packed |
BCD datums giving a BCD outcome |
* |
||||
;* ENTRY |
: |
BCD_1 |
in F20h, BCD_2 in F21h |
* |
||||
;* EXIT |
: |
SUM_H (hundreds digit) in F22h |
* |
|||||
;* |
EXIT |
: |
SUM_L |
(tens:units digit) |
in F23h |
* |
||
;* |
EXAMPLE : |
10011001 |
(99) + |
10011001 |
(99) = 00000001 10011000 (198) * |
|||
;* *******************************************************************
; |
||||
BCD_1 |
equ |
20h |
; The first tens:units BCD number |
|
BCD_2 |
equ |
21h |
; The second tens:units BCD number |
|
SUM_H |
equ |
22h |
; The hundreds digit of the outcome |
|
SUM_L |
equ |
23h |
; The tens:units digits of the outcome |
|
STATUS |
equ |
03h |
; |
The Status register |
C |
equ |
0 |
; |
holding the Carry flag at bit0 |
DC |
equ |
1 |
; |
and the Digit half Carry at bit1 |
; Task 1: Add the |
two numbers using natural binary rules |
|||
BCD_ADD |
clrf |
SUM_H |
; |
Zero the hundreds digit |
movf |
BCD_1,w |
; |
Get the first packed BCD number |
|
addwf |
BCD_2,w |
; |
Add the second number |
|
movwf |
SUM_L |
; |
and put away as the uncorrected result |
|
; Task 2: Was there a full Carry from this binary addition? |
||||
rlf |
SUM_H,f |
; Rotate Carry into hundreds digit |
||
; Task 3: Was there a Digit half Carry from the binary addition? |
||||
btfsc |
STATUS,DC |
; |
IF DC=0 THEN skip |
|
goto |
ADJUST_1 |
; |
ELSE an adjustment is needed |
|
; or if not, is the unit BCD |
digit greater than nine? |
|||
addlw |
-0Ah |
; |
Take away ten |
|
btfss |
STATUS,DC |
; |
Did this give a Digit carry? |
|
goto |
TENS_CHECK ; |
IF it did THEN not >9 |
||
; ------------------------------------------------------------------- |
||||
ADJUST_1 |
movlw |
6 |
; |
Correct the units digit by adding six |
addwf |
SUM_L,f |
; |
with the adjusted value back in the file |
|
btfsc |
STATUS,C |
; |
IF this gives a full Carry |
|
incf |
SUM_H,f |
; THEN record a hundreds digit |
||
; ------------------------------------------------------------------- |
||||
; Task 4: Was there a full Carry from the previous correction (if any)?
TENS_CHECK btfsc |
SUM_H,0 |
; IF yes THEN hundreds digit will be 01h |
||
goto |
ADJUST_2 |
; and the tens digit will need adjustment |
||
; or IF not, is the tens BCD |
digit >9? |
|||
movf |
SUM_L,w |
; Get the current partly |
corrected sum |
|
addlw |
-0A0h |
; Take away ten from the |
tens digit |
|
btfss |
STATUS,C |
; Did this give a Carry? |
||
goto |
FINISH |
; IF it did THEN not >9 |
||
; ------------------------------------------------------------------- |
||||
ADJUST_2 |
movlw |
60h |
; Correct by adding 6 to |
the tens digit |
addwf |
SUM_L,f |
; with the adjusted value back in the file |
||
btfsc |
STATUS,C |
; IF this generates a Carry |
||
incf |
SUM_H,f |
; THEN record a hundreds |
digit |
|
; ------------------------------------------------------------------- |
||||
FINISH |
.... |
..... |
||
104 The Quintessential PIC Microcontroller
Self-assessment questions
4.1The PIC16F877 mid-range MCU has a 8 kbyte Program store, which can hold up to 8192 14-bit instructions located in the range 0000 – 1FFFh. As part of a certain program, execution has to be transferred from the bottom quarter of this map to 1000h. Given that the goto instruction can only directly access 11-bit addresses (0000 – 07FFh), how could you engineer a jump to this address, i.e. goto 1000h?
4.2Write a routine to decrement a packed BCD quantity, as in Example 4.3. Hint: Devise a simple test to activate the relevant carry flag if the digit is Fh.
4.3Write a routine to add ten onto a packed BCD byte located in File 20h. Hint: This is similar to Example 4.3 but only the tens digit is augmented.
4.4Where microprocessors are used in a general-purpose computing environment, the program is normally loaded into and run from read/write RAM memory. This means that the system can run a wordprocessor one minute and a spreadsheet program the next. Of course this means of operation is not applicable to embedded applications, where the program is stored in some variety of non-volatile read-only memory. Discuss why this is so and the virtues of ROM, EPROM and EEPROM implementations of non-volatile storage.
4.5The following routine is designed to do nothing other than defer execution of the main routine by 1282 µs in a PIC MCU which is being clocked using a 4 MHz crystal. Taking into account pipelining, verify this figure.
DELAY |
clrf |
20h |
; Clear count |
D_LOOP |
incf |
20h |
; Increment |
decf |
20h |
; and cancel by decrementation |
|
decfsz |
20h |
; Decrement until zero |
|
goto |
D_LOOP |
||
.... |
..... |
||
4.6 Can you devise an algorithm and task list to subtract two packed BCD numbers located as in Example 4.4. The outcome packed byte is to be in File 23h and File 22h is to hold the overflow carry – that is the negative indicator. This overflow is to be zero if there was a full borrow out, otherwise one. For example 45h − 29h = (01)16h (that is 45 − 29 = +16) and 29h − 45h = (00)84h (29 − 45 = −84) where 84 is the ten’s complement of 16.