View previous topic :: View next topic |
Author |
Message |
jmartinstro
Joined: 07 Nov 2006 Posts: 3
|
PIC16F785 EEPROM read and write not working |
Posted: Tue Nov 07, 2006 10:31 am |
|
|
My code for PIC16F785 EEPROM read and write not working.
Compiler 3.225
A code fragment is as follows:
union Calibration
{
int16 Cal_Voltage;
BYTE Ical[4];
}Calib;
void Write_Voltage()
{
BYTE i, Tmp;
Cal_Voltage = 555;
for(i=0;i<4;i++)
{
Tmp = Calib.Ical[i];
WRITE_EEPROM(i,Tmp);
}
for(i=0;i<4;i++)
{
Tmp = READ_EEPROM(i);
Calib.Ical[i] = Tmp;
}
}
This doesn't remember the values on reboot.
I have looked at the assembler output and I am
suspicious the read is failing....
.................... for(i=0;i<4;i++)
0092: CLRF 3D
0093: MOVF 3D,W
0094: SUBLW 03
0095: BTFSS 03.0
0096: GOTO 0A8
.................... {
.................... Tmp = READ_EEPROM(i);
0097: MOVF 3D,W
0098: BSF 03.6
0099: MOVWF 0D
009A: BSF 03.5
009B: BCF 0C.7
009C: BSF 0C.0
009D: BCF 03.5
009E: MOVF 0C,W
009F: BCF 03.6
00A0: MOVWF 3E
.................... Calib.Ical[i] = Tmp;
00A1: MOVLW 48
00A2: ADDWF 3D,W
00A3: MOVWF 04
00A4: MOVF 3E,W
00A5: MOVWF 00
.................... }
If I translate the numbers into registers,
address 009E should read MOVF EEDAT,W
but it seems to be MOVF EECON1,W
But I'm no expert on this chip (right now) and any help is appreciated.
Thanks
Joe |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Nov 07, 2006 1:31 pm |
|
|
I don't see anything wrong with the read_eeprom() ASM code.
Your union is a little strange. You have a union between a 16-bit
bit value (2 bytes) and an array which is 4 bytes.
You don't really even need the union. You could use the Make8()
and Make16() functions to do this. |
|
|
jmartinstro
Joined: 07 Nov 2006 Posts: 3
|
|
Posted: Wed Nov 08, 2006 2:26 am |
|
|
PCM programmer wrote: | I don't see anything wrong with the read_eeprom() ASM code.
Your union is a little strange. You have a union between a 16-bit
bit value (2 bytes) and an array which is 4 bytes.
You don't really even need the union. You could use the Make8()
and Make16() functions to do this. |
Thanks for comment.
Just like to point out the line which reads
Cal_Voltage = 555;
contained typo when copying - should read
Calib.Cal_Voltage = 555;
The message about union is noted,
the code posted is just a fragment that
doesn't show how else the union is used.
Thanks
Joe |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Nov 08, 2006 2:13 pm |
|
|
I take back what I said about the read_eeprom(). It's using incorrect
register addresses for the 16F785. I installed your version of the
compiler and looked at the .LST file. Also, the write_eeprom() code
is using the wrong register addresses.
Here is a test program with eeprom functions that should work with
your version of the compiler. Use these functions instead of the
built-in functions.
Code: |
#include <16F785.h>
#fuses XT, NOWDT, NOPROTECT, PUT, BROWNOUT
#use delay(clock=4000000)
// Registers and bits used for Data eeprom R/W
// with the 16F785.
#byte INTCON = 0x0B
#byte EEDAT = 0x9A
#byte EEADR = 0x9B
#byte EECON1 = 0x9C
#byte EECON2 = 0x9D
#bit GIE = INTCON.7
#bit RD = EECON1.0
#bit WR = EECON1.1
#bit WREN = EECON1.2
#bit WRERR = EECON1.3
//------------------------------------------
void my_write_eeprom(int8 addr, int8 data)
{
int8 save_intcon;
EEADR = addr;
EEDAT = data;
WREN = 1;
save_intcon = INTCON;
GIE = 0;
EECON2 = 0x55;
EECON2 = 0xAA;
WR = 1;
while(WR);
WREN = 0;
INTCON |= save_intcon;
}
//--------------------------------------
int8 my_read_eeprom(int8 addr)
{
int8 retval;
EEADR = addr;
RD = 1;
retval = EEDAT;
return(retval);
}
//============================
void main()
{
int8 c;
my_write_eeprom(0, 0x55);
c = my_read_eeprom(0);
while(1);
} |
|
|
|
jmartinstro
Joined: 07 Nov 2006 Posts: 3
|
|
Posted: Thu Nov 09, 2006 4:30 am |
|
|
PCM programmer wrote: | I take back what I said about the read_eeprom(). It's using incorrect
register addresses for the 16F785. I installed your version of the
compiler and looked at the .LST file. Also, the write_eeprom() code
is using the wrong register addresses.
Here is a test program with eeprom functions that should work with
your version of the compiler. Use these functions instead of the
built-in functions.
....<snip>
|
Thank you very much.
Your solution worked 100% perfectly.
Once again, thank you.
Joe |
|
|
|