Файл: The quintessential PIC microcontroller (S. Katzen, 2000).pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 15.06.2025

Просмотров: 5300

Скачиваний: 0

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

15. To Have and to Hold 441

EECON1 register

7

6

5

4

3

2

1

0

EEPGD

WRERR WREN

WR

RD

EECON1

(R/W X)

(R/W X) (R/W 0)

(R/W 0)

(R/W 0)

File 18Ch

ReaD control

WRite control

WRite ENable

WRite ERRor

EEProGram/Data memory

PIE2

R = Read

4

W = Write

EEIE

File 8D h

( ) = Reset condition

Interrupt

to CPU

PIR2

4

EEIF

File 0D h

Fig. 15.5 The PIC16F87X EEPROM Control register 1.

Reading and writing to the EEPROM Data module is identical to that used for the more basic PIC16F8X device. The only change necessary to subroutines EE_GET and EE_PUT relates to the Bank 2 location of EEDATA and EEADR and Bank 3 for EECON1 and EECON2.

The process of reading from the flash Program store is similar to that of the EEPROM Data module but using double Data and Address registers. However, we are interacting with the same Program store from which code is being fetched into the execution unit. In consideration of this dualism, two dummy nop instructions should follow the instruction setting the RD bit in EECON1[0]. This gives our Read task list for the flash Program store.

1.Copy the target cell’s address to EEADRH:EEADR on entry.

2.Set RD to 1 to initiate the Read cycle.

3.Execute two dummy nop instructions.

4.RD is immediately cleared automatically and the 14-bit target datum can be read from EEDATH:EEDATA as convenient.

The subroutine FLASH_GET of Program 15.4 implements this process assuming that the cell address has been placed in EEADRH:EEADR on entry.


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


15. To Have and to Hold 445

Fig. 15.6 View of the flash Program module showing the look-up table and subroutine SQUARE.

erase it. Thus protection should be disabled during prototyping! However, reading is only inhibited in protected areas.

Code protection also a ects internal Writes into the Program store using code such as in Program 15.5. Internal Writes can be made into unprotected areas of Program memory provided that the WRT fuse is 1; its default setting. Setting this fuse to 0 (_WRT_ENABLE_OFF) will disable internal Writes irrespective of the main code protection setting. Internal Reads are not a ected by code protection. Program 15.6 shows the __config directive used to disable all code protection in Program memory; which is actually superfluous as this is the default situation.

Unlike the PIC16F8X, the PIC16F87X devices can also protect the EEPROM Data module from internal Writes. The CPD fuse (Code Protection Data module) if set to 0 will inhibit any changes in this data.

2007h

13

12

11

10

9

8

7

6

5

4

3

2

1

0

CP1

CP0

DEBUG

WRT

CPD

LVP

BODEN

CP1

CP0

PWRTE

WDTE

FOSC1

FOSC0

Code protect

00

=

All Code Protected

00

=

LP

EEPROM Data

01

= Top half protected

01

= XT

module

10

= Top 256 bytes protected

10

= HS

11

= No Code Protection

11

= RC

Fig. 15.7 Configuration word for the PIC16F87X devices.