Файл: The quintessential PIC microcontroller (S. Katzen, 2000).pdf
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 15.06.2025
Просмотров: 5300
Скачиваний: 0
442 The Quintessential PIC Microcontroller
Program 15.4 Reading a word from the flash Program store.
; ************************************************************
; * |
FUNCTION: |
Gets one byte from the flash Program store |
* |
||
; |
* |
ENTRY |
: |
Address in EEADRH:EEADR |
* |
; |
* |
EXIT |
: |
Datum in EEDATH:EEDATA. System in Bank0 |
* |
; ************************************************************
FLASH_GET |
||
bsf |
STATUS,RP1 |
; Change to Bank3 |
bsf |
STATUS,RP0 |
|
movlw |
b’10000000’ |
; Point to Program memory |
movwf |
EECON1 |
; by setting EEPGD |
bsf |
EECON1,RD |
; Set RD for Read cycle |
nop |
; Dummy nops |
|
nop |
||
bcf |
STATUS,RP1 |
; Return to Bank0 |
bcf |
STATUS,RP0 |
|
return |
||
The Write cycle also is virtually identical to its Data module counterpart but with the addition of a double-nop relaxation phase. This gives us our flash Write cycle task list:
1.Copy the target cell address to EEADRH:EEADR.
2.Set WREN in EECON1[2] to enable the Write process.
3.Disable all interrupts.
4.Send 55hto EECON2.
5.Send AAhto EECON2.
6.Set WR to initiate the Write cycle.
7.Execute two dummy nop instructions.
8.Clear WREN.
9.Enable interrupts.
10.Wait until WR returns to zero, signalling the completion of the Write cycle, and exit.
The subroutine FLASH_PUT in Program 15.5 assumes that the cell address is in EEADRH:EEADR and 14-bit datum is in EEDATH:EEDATA on entry.
For our example we will design a subroutine that will return the square of an integer between 0 and 100 in EEDATH:EEDATA. We could of course calculate this by multiplication, but for the purposes of this exercise we will implement this exercise as a look-up table located in flash Program store. As this is a table of constants we can load the data into flash memory at the same time as the rest of the program code.
In Program 15.6 the table is located at 300h in the Program store. The directive dw (Data Word) is similar to de but each datum in the comma separated list is 14-bits. For convenience the radix directive is used to specify constants by default are treated as decimal.
15. To Have and to Hold 443
Program 15.5 Writing to flash Program memory.
; ************************************************************
; * |
FUNCTION: |
Writes one |
byte into the flash Program store |
* |
|||
; * |
ENTRY |
: |
Datum |
byte |
in EEDATH:EEDATA |
* |
|
; * |
ENTRY |
: |
Datum |
address in EEADRH:EEADR |
* |
||
; |
* |
EXIT |
: |
Interrupts |
disabled for 11 instructions |
* |
|
; |
* |
EXIT |
: |
System in Bank0 |
* |
||
; ************************************************************
FLASH_PUT bsf |
STATUS,RP0 |
; |
Go to Bank 3 |
bsf |
STATUS,RP1 |
||
bsf |
EECON1,EEPGD; |
Target the flash Program store |
|
bsf |
EECON1,WREN |
; |
Enable for Write cycle |
FLASH_LOOP bcf |
INTCON,GIE |
; |
Disable all interrupts |
btfsc |
INTCON,GIE |
; |
Check, did it clear? |
goto |
FLASH_LOOP |
; |
IF not THEN do again |
movlw |
55h |
; |
Now do the interlock |
movwf |
EECON2 |
||
movlw |
0AAh |
||
movwf |
EECON2 |
||
bsf |
EECON1,WR |
; |
Initiate the Write cycle |
nop |
; |
Dummy nops |
|
nop |
|||
bcf |
EECON1,WREN |
; |
Disable any more Writes |
bsf |
STATUS,GIE |
; |
Re-enable interrupts |
FLASH_EXIT |
|||
btfsc EECON1,WR |
; |
Check, has the Write completed? |
|
goto FLASH_EXIT |
; |
IF not THEN retry |
|
bcf |
STATUS,RP1 |
; |
Go back to Bank 0 |
bcf |
STATUS,RP0 |
||
return |
; |
& return when cycle has finished |
|
Directly following the table is the executable code. In this manner Program 15.6 is comparable to a C++ class where a program object comprises both data members and member functions (subroutines).
The subroutine itself builds up the table element nn address by placing the integer passed in W in EEADR and the constant 03h in EEADRH. This gives the double-byte address as 3nnh. Once this is done, the subroutine FLASH_GET retrieves the 14-bit datum from the table. The subroutine then moves both bytes from EEDATH:EEDATA and returns the datum in the two file registers SQRH:SQRL in Bank 0. Unlike the PIC16F8X, general-purpose file registers are not reflected across the various banks, so each byte copied from EEPROM SPRs in Bank 2 needs switching to Bank 0 once the byte has reached the Working register.
When the program has been burnt into flash memory by the external programmer the Program store in the area around 300h will look like Fig. 15.6.
444 The Quintessential PIC Microcontroller
Program 15.6 Squaring an integer.
__config _CPD_OFF & _WRT_ENABLE_OFF org 300h
; ************************************************************
; * |
FUNCTION: |
Generates the square |
of |
an integer |
* |
|||
; * |
RESOURCE: |
Subroutine |
FLASH_GET |
* |
||||
; |
* |
ENTRY |
: |
Integer in |
W range 0 |
-- |
100 |
* |
; |
* |
EXIT |
: |
14-bit square in SQRH:SQRL. In Bank0 |
* |
|||
; ************************************************************
TABLE
dw 0,1,4,9,16,25,36,49,64,81,100,121,144,169,196,225
dw 256,289,324,361,400,441,484,529,576,625,696,729,784,841 dw 900,961,1024,1089,1156,1225,1296,1369,1444,1521,1600,1681 dw 1764,1849,1936,2025,2116,2209,2304,2401,2500,2601,2704
dw 2809,2916,3025,3136,3249,3364,3481,3600,3721,3844,3969 dw 4049,4225,4356,4489,4624,4761,4900,5041,5184,5329,5476 dw 5625,5776,5929,6084,6241,6400,6561,6724,6889,7056,7225 dw 7396,7569,7744,7921,8100,8281,8464,8649,8836,9025,9216 dw 9409,9604,9801,10000
SQUARE bsf |
STATUS,RP1 |
; Move to Bank2 |
bcf |
STATUS,RP0 |
|
movwf |
EEADR |
; Build up the address |
movlw |
3 |
|
movwf |
EEADRH |
|
call |
FLASH_GET |
; Get table entry n in 3nnh |
bsf |
STATUS,RP1 |
; Move back to Bank2 |
bcf |
STATUS,RP0 |
|
movf |
EEDATA,w |
; Get lower byte of square |
bcf |
STATUS,RP1 |
; Bank0 |
movwf |
SQRL |
; Copy to SQRL in Bank0 |
bsf |
STATUS,RP1 |
; Back to Bank2 |
movf |
EEDATH,w |
; Get high byte of square |
bcf |
STATUS,RP1 |
; Bank0 |
movwf |
SQRH |
; and copy to SQRH in Bank0 |
return |
||
Like the PIC16F8X, as discussed on page 260, the PIC16F87X line has code protection fuses in its configuration word – as shown in Fig. 15.7. The primary function of code protection is to prevent the external programmer reading code from the Program store to give a measure of security against unauthorized peeking at the code. In the case of the PIC16F87X devices two code bits (duplicated as bits 13:12 and 5:4) in the configuration word in the special/test configuration area at 2007h give protection for all the Program store (00), the top half of the store (01), the top 256 bytes only (10) or no protection (11); the default situation. If protection is given to any area of memory then the external programmer cannot subsequently write data into anywhere in the Program store nor