PIC Table Write

I am attempting to test the table read/write of the PIC18f2431. I understand that tables are written 8 bytes at a time meaning that the TABLAT register is written to 8 times. I start by setting the table pointer as follows:

MOVLW 0x00 MOVWF TBLPTRU MOVLW 0x10 MOVWF TBLPTRH MOVLW 0x00 MOVWF TBLPTRL

This should set the pointer to address 0x1000. Next I load the TABLAT register 8 times such as:

MOVLW 0x## MOVWF TABLAT TBLWT*+

* * *

I then set the EECON1 and EECON2 registers as follows:

BCF EECON1,CFGS BSF EECON1,EEPGD BSF EECON1,WREN BCF INTCON,GIEL BCF INTCON,GIEH MOVLW 0x55 MOVWF EECON2 MOVLW 0xAA MOVWF EECON2 BSF EECON1,WR NOP BCF EECON1,WREN

At this point the 8 bytes that I transfered to the TABLAT should be written to program memory at 0x1000 right? When I attempt to read back the data, I set the table pointer to 0x1000 just like I did before the write sequence. I use the TBLRD*+ and then read the contents of the TABLAT register. I get

0xFF. When I download the program memory from the PIC into MPLAB, I can see that the data was written starting at 0x1008. What's strange is that the last byte I loaded into TABLAT before the write appears at 0x1008. The byte at 0x1009 contains the first byte that I wrote to TABLAT and then the sequences continues as expected. Is this correct? I would have expected the first byte that I transferred to TABLAT would appear at 0x1000, the second at 0x1001 and so on.
Reply to
Patrick Johnson
Loading thread data ...

That is correct. The example code in the 18Fxx31 datasheet is wrong. Have a look at the 18Fxxx2 datasheet for the correct code.

The low 3 bits of the TBLPTR registers is used to address the 8 holding registers during a short write. On the actual (long) write, the upper 19 bits hold the block of 8 bytes to write to. You code uses post-increment:

so after 8 writes, TBLPTR ends up pointing at the 9th byte, in other words the first byte of the second block of 8 bytes and that is where the holding registers get written to.

The code is the 18Fxxx2 datasheet has two important differences. Right after the erase is complete, a dummy read with auto-decrement is done to move the pointer back one byte.

TBLRD-*

In the loop writing to the holding registers, pre-increment is used:

TBLWRT+*

So, after all 8 bytes are written, TBLPTR is still pointing into the correct 8 byte block so the holding registers get written into the right place.

You might look to see if there are any errata sheets for the 18Fxx31 datasheet. Microchip might have caught the error already.

Reply to
Gary Kato

Actually, I would think that 0x1008 would have the first byte. Hmm.

Reply to
Gary Kato

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.