PDA

View Full Version : Using EEPROM to store variables...



Tom Gonser
- 3rd April 2005, 08:39
I would like to store some values in EEPROM, and then read these out later when I need them.. The problem is what I I2CWRITE is not what I see when I I2Cread... Where I THINK I store a '1', I see it read back as '127' or '80'...???

Consider this - I want to store a baud rate for SERIN2 - a value of "16572".

So, I create a varable:

WBD var Word ' variable to be stored
LOC_WBD = 20 ' memory location to store it

Then I write the value to EEPROM

Assume: WBD = 16572, then ->

I2CWrite DPIN, CPIN, CHIP1, LOC_WBD, WBD.byte0
pause 10
I2CWrite DPIN, CPIN, CHIP1, LOC_WBD+1, WBD.byte1
pause 10

-> I'd EXPECT I just stored the variable 16572 into memory location 20 and 21 (Word)

THEN to get it back, I'd :

I2Cread DPIN, CPIN, CHIP1, LOC_WBD, WBD.byte0
I2Cread DPIN, CPIN, CHIP1, LOC_WBD+1, WBD.byte1


WBD should be 16572... but it is not. What did I miss?

Same goes for BYTE sized storage of varables..

B0 = 1
LOC_B0 = 22

I2CWrite DPIN, CPIN, CHIP1, LOC_BO, B0
pause 10

( I think I stored '1' in memory location 22)

BUT:

I2Cread DPIN, CPIN, CHIP1, LOC_BO, B0
LCDout "BO is: ",#BO

Displays 127 or 80 - not '1'...


I am missing something FUNDAMENTAL here..

Tom

mister_e
- 3rd April 2005, 09:59
will be interesting to know your EEPROM model before. Did you read/ compare your code+schematic to the PBP manual before? Have a search in this forum, you'll find a load of answer!!

Melanie
- 3rd April 2005, 10:22
http://www.picbasic.co.uk/forum/showthread.php?t=587

You WILL need pull-up's on the Clock and Data lines (weak pull-up's just don't work reliably here)... 4K7 is recommended.

Tom Gonser
- 3rd April 2005, 18:46
Deeper question - sorry - let me explain..

The external EEPROM is working.. I am storing and retrieving data. So yes, I know the lines are working, etc. I have pull-ups, etc.

However, I am trying to KEEP data alive even after power down, and this does not seem to be working 100%. Some survives, some does not!!

24LC512s - I am using two of them. The software can tell them apart, and know them as 'Chip1', and 'Chip2'. When I write data to the Chips, then retrieve it, I get valid data, even if I fill up both chips. It works fine at a gross level.

The issue is deeper than if the EEPROM is recording or not - it has to do with saving specific BYTES in EEPROM between power cycles..

My program writes logging data to the EEPROM in Page Mode. My data is 36 bytes long, so I actually read 3 times into an array of a size of 108 (which works on the 18F2525). That way each page has 108 of the 128 bytes used.

1. I ALSO want to store some variables that I need BETWEEN power cycles in EEPROM.
A. the last used memory location, so when I start up again I know where I ws.
B. the user selected 'baud rate' for download
C. the 'passthru flag' - tells the code if it should just record to memory only, or also send that data to the serial port.

SO - I write my LOGGING data in memory positions

128-64000 - in chip 1 -> saving address 0-127
0-64000 in chip 2

I WANT to use the first 'page' on chip one as a place to keep persistent variables. SO I write to the address range 0-127 for these variables.

The memory locations are defined as:

Symbol ADR_loc = 10 ' next usable address
Symbol CHP_loc = 12 ' the chip we are on
Symbol D_baud_loc = 14 ' the download baud value
Symbol pass_loc = 20 ' the flag for passthru
Symbol wpt_loc = 30 ' the flag for waypoints
Symbol W_baud_loc = 40 ' waypoint baud rate


Then, I collect data from the user or from the program, and I2CWRITE the data into the memory locations as per above. The PROBLEM seems to be that when I write for example a '1' into "pass_loc", when I I2CREAD that same memory location later DURING the same power cycle, it is fine - it reads back what I'd expect. The PROBLEM is that if I power cycle, the data gets smashed...

HOWEVER, the data I write in PAGE MODE appears to survive a power cycle....

Any ideas why?? Can you not save persistent data to EEPROM?

NavMicroSystems
- 3rd April 2005, 20:04
. . .Can you not save persistent data to EEPROM?of course you can, this is why we use EEPROMs!

I see several reasons for EEPROM data not being what you expect it to be:

It has not been written to EEPROM (is your timing ok?)
or
it is being overwritten during the power up.

In both cases there must be something wrong in your code.

I assume you have already tried a different chip to ensure the EEPROM itself is ok.

Tom Gonser
- 3rd April 2005, 20:45
Have not checked memory - I will. Funny tho how perfectly well it works AS LONG AS I DON'T POWER DOWN.. So the culprit MUST be something in the intitialzation somehow?? hmm.

Maybe the fact I am declaring the memory locations as SYMBOLS is a problem? When I start up, for example, I declare the memory location to store baud rate as

wptbd Symbol = 10

Does this need to be a VARIABLE? I will never write the value for Waypoint Baud to anywhere EXCEPT position 10.. that is so I know where to get it when I need it.

I saw mention of not using SYMBOLS in I2C..

??

mister_e
- 3rd April 2005, 20:54
O.k this is why,

with your EEPROM, your address must be a word sized variable, so use


wptbd VAR WORD
wptbd = 10


And with wptbd Symbol = 10 written as is you didn't get any compilation error??

Tom Gonser
- 4th April 2005, 15:38
Argg!! I just cannot get those values to stay in EEPROM through a power cycle!!

Here is what I've done:

18F2525
2 x 24LC512 connected as CHIP1, CHIP2
Chip1 con %10100000 ' address of chip1
Chip2 con %10100010 ' address of chip2
resistors in pace.

My program stores data to these chips, and this works. I can store data, then read it back and what I get is valid data (because it contains a checksum, if anything were wrong, the recieving software program would choke)

THEN, I decided I wanted to store the BAUD setting for download and waypoint transmssion, and a flag called PASSTHRU, and Waypoint on/off -- RIGHT IN THE EXTERNAL EEPROM so that I did not have to keep setting it every time I power up the system.

SO,

My program uses the chips memory as follows:

Chip1 address usage:
0-127 = special setting storage
128 - 63872 - logging data

Chip2 address usage:
0 - 63872 - logging data


In the initialization, I have set the following parameters:

' ------------ memory eeprom storage locations --------------------------------------
ADR_loc var word ' location to store the address
CHP_loc var byte ' will only be 1, 2, 3, 4
D_baud_loc var word ' download baud rate
pass_loc var byte ' the flag for passthru - 1 or 0
wpt_loc var byte ' the flag for waypoints - 1 or 0
W_baud_loc var word ' waypoint baud rate

ADR_loc = 100 ' next usable address
CHP_loc = 102 ' the chip we are on
D_baud_loc = 104 ' the download baud value
pass_loc = 108 ' the flag for passthru
wpt_loc = 110 ' the flag for waypoints
w_baud_loc = 112 ' waypoint baud rate

The values actually STORED in these locations are:

address var word ' current memory address
chipselect var byte ' current chip we are on 1 or 2
passthru var byte ' flag - allows data to pass thru to PC
Set_Wpt var byte ' flag allows waypoint data to be sent
wptBD var word ' baudrate of waypoint- ie 16572, etc.
D_baud var word ' baudrate of download speed for PC

SO, my program should ALWAYS know where to look for the various settings. In fact, I have proven that this works - when the program powers up, it confirms that each of these values is correct.

THEN,

I2Cread DPIN, CPIN, Chip1, wpt_loc, set_wpt ' waypoint flag storage
I2Cread DPIN, CPIN, Chip1, Pass_loc, passthru ' passthru flag storage
I2Cread DPIN, CPIN, Chip1, D_baud_loc, D_baud.byte0 ' baud2
I2Cread DPIN, CPIN, Chip1, D_baud_loc+1, D_baud.byte1 'baud2
I2Cread DPIN, CPIN, Chip1, W_baud_loc, wptbd.byte0 ' store waddress 1
I2Cread DPIN, CPIN, Chip1, W_baud_loc+1, wptbd.byte1 ' store waddress 2
I2Cread DPIN, CPIN, Chip1, ADR_loc, address.byte0' get the address 1
I2Cread DPIN, CPIN, Chip1, ADR_loc+1, address.byte1' get the address 2
I2Cread DPIN, CPIN, Chip1, CHP_loc, Chipselect ' get the chipselect

SO - at this point, you'd expect that my program now knows:

1. WHERE to look for the data, and
2. It has read the values from those locations into variables.

The PROBLEM is this.. This works great AS LONG AS I DON'T RESTART. Once I store data using "I2CWRITE" into these locations, I can reliably get them back whenver I want. If I restart, the values are all messed up.

As an example, I wrote a small program to allow me to query these values on a PC screen anytime to troubleshoot. Here is what I see:

Upon first startup:

PARAMETER MEMLOC
Download baud rate unknown: 0 104
Waypoint baud rate unknown: 5837 112
Unknown Streaming setting: 197 108
Unknown Waypoint Setting: 215 110

Last Memory Address: 0 100
Current Chip: 7 102

SO, it is properly looking in the right place, but seeinig garbage values. Once I tell it to store a set of 'Default' values that the program will recognize, I get this response:

PARAMETER MEMLOC
Download baud rate 9600 104
Waypoint baud rate 4800 112
Data WILL NOT stream to GPS-TEAM 108
Waypoint Output ON 110

Last Memory Address: 128 100
Current Chip: 1 102

This response is CORRECT. The program recognizes values and is reporting what the settings are.

If I power cycle, the old garbage values come back - the exact same ones!!

PARAMETER MEMLOC
Download baud rate unknown: 0 104
Waypoint baud rate unknown: 5837 112
Unknown Streaming setting: 197 108
Unknown Waypoint Setting: 215 110

Last Memory Address: 0 100
Current Chip: 7 102

-- so SOMETHING is writing garbage to my memory when I am not looking. Might it be my setup variables for the 18F2525

ADCON0 = %00110000' turn off - select port AN12 (nothing)
ADCON1 = %00001111' turn portA to digital I/O (same as dec 15)

CMCON = $07 ' turn off
HLVDCON = %00000000 ' turn off
CVRCON = $00000000 ' turn off

SSPCON1 = %11011100 ' supposed to be turning on I2C
SSPCON2 = %01111000 ' supposed to be turning on I2C

INTCON = %11110000 ' TG guess at 2525 interrups for all INT pins
INTCON2= %01110100 ' rising edge of INT0,1,2 RB0,1,2
RCON = %10000000 ' no priority interrups

T1CON = %11000000 'Timer1 1:1 prescale.
T0CON = 1

SOMETHING is writing to Chip1 memory locations when I am not looking, I just can't figure out WHAT.. ALL of my loops start at 128, even if I do NO OTHER MEMORY WRITES during a session, the variables STILL get messed up.

HELP!

Tom

NavMicroSystems
- 4th April 2005, 22:45
Tom,

on my DataLoggers I have 16F876 or 18F252 and 2x 24LC512.

The following code is tested.

could you give it a try and let us know what the result was?



SCL var PortC.5 ' I2C Clock
SDA var PortC.4 ' I2C Data
ROM0 CON $A0 ' EEPROM 0 Address
ADDR VAR word ' ROM Location
MonPort var PortB.7 ' Monitor Port
Mode con 16572 ' 4800 Baud 8N1 for Monitor Port

Test var byte[21] ' Test Array
I2Cdelay con 10 ' Delay after I2Cwrite

Temp var byte

CLEAR

SEROUT2 MonPort,Mode,[13,10,"** MCU started",13,10,13,10]

ADDR=100

I2CREAD SDA,SCL,ROM0,ADDR,[Temp]

IF Temp="*" THEN GOTO SkipWrite

I2CWRITE SDA,SCL,ROM0,ADDR,_
[$2A,$20,$54,$65,$73,$74,$20,$45,$45,$50,$52,$4F,_
$4D,$20,$2D,$2D,$3E,$20,$4F,$4B,$21]

PAUSE I2Cdelay

SEROUT2 MonPort,Mode,["** EEPROM written",13,10,13,10]

GOTO Loop

SkipWrite:

SEROUT2 MonPort,Mode,["** EEPROM write skipped",13,10,13,10]

I2CREAD SDA,SCL,ROM0,addr,[str test\21]

Loop:
SEROUT2 MonPort,Mode,[STR Test\21,13,10]
PAUSE 1000
GOTO Loop

END

Tom Gonser
- 5th April 2005, 02:17
Ralph:

Thanks for the demo code, here is what the result was - pasted from the Hyperterminal window. (I added "writing:" to the string so I could see that it was becuse it was not writing anything that showed up on the screen.)
---------------------------------------------------------------------

** MCU started

** EEPROM written

writing:
writing:
writing:
writing:
writing:
writing:
writing:
writing:
writing:
writing:

--------------------------------------------------------------------------

Here is the code I used:

'--------------------------------------------------------------------------------

'Tom,

'on my DataLoggers I have 16F876 or 18F252 and 2x 24LC512.
'The following code is tested.
'could you give it a try and let us know what the result was?


' -----[ Fuses ]------------------------------------------------
@ __CONFIG _CONFIG1H, _OSC_INTIO67_1H
@ __CONFIG _CONFIG2H, _WDT_ON_2H & _WDTPS_128_2H
@ __CONFIG _CONFIG3H, _PBADEN_OFF_3H & _MCLRE_OFF_3H
@ __CONFIG _CONFIG4L, _LVP_OFF_4L & 0bfh ;_XINST_OFF_4L
'
' -----[ Includes/Defines ]---------------------------------------------------------
include "modedefs.bas" 'include serout defines

OSCCON=%01111000
DEFINE OSC 8
While OSCCON.2=0:Wend


SCL var PortC.5 ' I2C Clock
SDA var PortC.4 ' I2C Data
ROM0 CON $A0 ' EEPROM 0 Address
ADDR VAR word ' ROM Location
MonPort var PortC.6 ' Monitor Port
Mode con 16572 ' 4800 Baud 8N1 for Monitor Port

Test var byte[21] ' Test Array
I2Cdelay con 10 ' Delay after I2Cwrite

Temp var byte

CLEAR

SEROUT2 MonPort,Mode,[13,10,"** MCU started",13,10,13,10]

ADDR=100

I2CREAD SDA,SCL,ROM0,ADDR,[Temp]

IF Temp="*" THEN GOTO SkipWrite

I2CWRITE SDA,SCL,ROM0,ADDR,_
[$2A,$20,$54,$65,$73,$74,$20,$45,$45,$50,$52,$4F,_
$4D,$20,$2D,$2D,$3E,$20,$4F,$4B,$21]

PAUSE I2Cdelay

SEROUT2 MonPort,Mode,["** EEPROM written",13,10,13,10]

GOTO Loop

SkipWrite:

SEROUT2 MonPort,Mode,["** EEPROM write skipped",13,10,13,10]

I2CREAD SDA,SCL,ROM0,addr,[str test\21]

Loop:
SEROUT2 MonPort,Mode,["writing: ", STR Test\21,13,10]
PAUSE 1000
GOTO Loop

END

----------------------------------------------------------------


Is this what you expected?

Tom

Tom Gonser
- 5th April 2005, 02:38
I got to wondering why I was getting nothing in the last build. So I trapped for failures to read and write. I did see that it was just not getting there, so tweaked the port assignments, etc. Here is what I get now:

** MCU started

** EEPROM write skipped

Reading:* Test EEPROM --> OK!
Reading:* Test EEPROM --> OK!
Reading:* Test EEPROM --> OK!
Reading:* Test EEPROM --> OK!
Reading:* Test EEPROM --> OK!

(I added "reading" to it)

The program is as follows:

------------------------------------------------------------------


'--------------------------------------------------------------------------------

'Tom,

'on my DataLoggers I have 16F876 or 18F252 and 2x 24LC512.
'The following code is tested.
'could you give it a try and let us know what the result was?


' -----[ Fuses ]------------------------------------------------
@ __CONFIG _CONFIG1H, _OSC_INTIO67_1H
@ __CONFIG _CONFIG2H, _WDT_ON_2H & _WDTPS_128_2H
@ __CONFIG _CONFIG3H, _PBADEN_OFF_3H & _MCLRE_OFF_3H
@ __CONFIG _CONFIG4L, _LVP_OFF_4L & 0bfh ;_XINST_OFF_4L
'
' -----[ Includes/Defines ]---------------------------------------------------------
include "modedefs.bas" 'include serout defines

OSCCON=%01111000
DEFINE OSC 8
While OSCCON.2=0:Wend

SCL var PortC.3 ' I2C Clock
SDA var PortC.4 ' I2C Data
ROM0 con %10100000 ' address of chip1
ADDR VAR word ' ROM Location
MonPort var PortC.6 ' Monitor Port
Mode con 16572 ' 4800 Baud 8N1 for Monitor Port
Test var byte[21] ' Test Array
I2Cdelay con 10 ' Delay after I2Cwrite

Temp var byte

CLEAR

SEROUT2 MonPort,Mode,[13,10,"** MCU started",13,10,13,10]

ADDR=100

I2CREAD SDA,SCL,ROM0,ADDR,[Temp]

IF Temp="*" THEN GOTO SkipWrite

I2CWRITE SDA,SCL,ROM0,ADDR,_
[$2A,$20,$54,$65,$73,$74,$20,$45,$45,$50,$52,$4F,_
$4D,$20,$2D,$2D,$3E,$20,$4F,$4B,$21],failw

PAUSE I2Cdelay

SEROUT2 MonPort,Mode,["** EEPROM written",13,10,13,10]

GOTO Loop

SkipWrite:

SEROUT2 MonPort,Mode,["** EEPROM write skipped",13,10,13,10]

Loop:
I2CREAD SDA,SCL,ROM0,addr,[str test\21],failr
SEROUT2 MonPort,Mode,["Reading:", STR Test\21,13,10]
PAUSE 1000
GOTO Loop

failr:
serout2 monport, mode,["failure to read",10,13]
return

failw:
serout2 monport, mode,["failure to write",10,13]
return


END

NavMicroSystems
- 5th April 2005, 02:47
So your Hardware is OK.

There must be something wrong with your code.

Tom Gonser
- 5th April 2005, 04:44
Hmm.. I am keeping trying to unravel this -- I have a version of your program, but it won't compile.. Can you tell my why I have a 'bad expression'??? It says the I2Cwrite, I2Cread commands are wrong.. I cannot for the life of me make them compile - defining X as a word, byte, whatever..

TG

'on my DataLoggers I have 16F876 or 18F252 and 2x 24LC512.
'The following code is tested.
'could you give it a try and let us know what the result was?
' -----[ Fuses ]------------------------------------------------
@ __CONFIG _CONFIG1H, _OSC_INTIO67_1H
@ __CONFIG _CONFIG2H, _WDT_ON_2H & _WDTPS_128_2H
@ __CONFIG _CONFIG3H, _PBADEN_OFF_3H & _MCLRE_OFF_3H
@ __CONFIG _CONFIG4L, _LVP_OFF_4L & 0bfh ;_XINST_OFF_4L
'
' -----[ Includes/Defines ]---------------------------------------------------------
include "modedefs.bas" 'include serout defines

OSCCON=%01111000
DEFINE OSC 8
While OSCCON.2=0:Wend

SCL var PortC.3 ' I2C Clock
SDA var PortC.4 ' I2C Data
ROM0 con %10100000 ' address of chip1
ADDR VAR word ' ROM Location
portout var PortC.6
portin var PortC.7
Mode con 16572 ' 4800 Baud 8N1 for Monitor Port
Test var byte[21] ' Test Array
I2Cdelay con 10 ' Delay after I2Cwrite

Temp var byte
X var byte
dta var byte

CLEAR

loop:
SEROUT2 portout,Mode,[13,10,"** MCU started",13,10,13,10]
serout2 portout, mode, ["enter 1 to write data, 2 to read it"]
serin2 portin, mode, [DEC temp]

select case temp
case 1
for X = 0 to 256
I2Cwrite SDA, SCL,ROMO,X,[X],failw
pause 10
next x
case 2
for x = 0 to 256
I2Cread SDA,SCL,ROMO,X,[X],failr
Serout2 portout, mode, ["Address: ",#addr," Data:",#dta]
pause 100
next x
end select

goto loop:

failr:
serout2 portout, mode,["failure to read",10,13]
return

failw:
serout2 portout, mode,["failure to write",10,13]
return


END

Tom Gonser
- 5th April 2005, 04:58
... ahem nevermind.. I was using ROMO instead of ROM0... shortened it to ROM so I could not make that mistake, and it works.

NOW I have a program that tests memory.. and the use of WORD or BYTE.. This will read or write to memory. VERY odd behavour tho, leading me to think I am missing some key understanding:

I write 0-640 to memory 0-640.. When I read it back I get REALLY odd stuff... NOT 0-640:

'on my DataLoggers I have 16F876 or 18F252 and 2x 24LC512.
'The following code is tested.
'could you give it a try and let us know what the result was?
' -----[ Fuses ]------------------------------------------------
@ __CONFIG _CONFIG1H, _OSC_INTIO67_1H
@ __CONFIG _CONFIG2H, _WDT_ON_2H & _WDTPS_128_2H
@ __CONFIG _CONFIG3H, _PBADEN_OFF_3H & _MCLRE_OFF_3H
@ __CONFIG _CONFIG4L, _LVP_OFF_4L & 0bfh ;_XINST_OFF_4L
'
' -----[ Includes/Defines ]---------------------------------------------------------
include "modedefs.bas" 'include serout defines

OSCCON=%01111000
DEFINE OSC 8
While OSCCON.2=0:Wend

SCL var PortC.3 ' I2C Clock
SDA var PortC.4 ' I2C Data
ROM con %10100000 ' address of chip1
ADDR VAR word ' ROM Location
portout var PortC.6
portin var PortC.7
Mode con 16572 ' 4800 Baud 8N1 for Monitor Port
Test var byte[21] ' Test Array
I2Cdelay con 10 ' Delay after I2Cwrite

Temp var byte
X var word
dta var word

CLEAR

Addr=100
loop:
SEROUT2 portout,Mode,[13,10,"** MCU started",13,10,13,10]
serout2 portout, mode, ["enter 1 to write data, 2 to read it"]
serin2 portin, mode, [DEC1 temp]

select case temp
case 1
for X = 0 to 640
I2Cwrite SDA, SCL,ROM,X,[X],failw
Serout2 portout, mode, ["Write Address: ",#x," Data:",#X,10,13]
pause 10
next x
case 2
for x = 0 to 640
I2Cread SDA,SCL,ROM,X,[dta.byte0],failr
I2Cread SDA,SCL,ROM,X+1,[dta.byte1],failr
Serout2 portout, mode, ["Address: ",#x," Data:",#dta,10,13]
pause 10
next x
case else
goto loop
end select

goto loop:

failr:
serout2 portout, mode,["failure to read",10,13]
return

failw:
serout2 portout, mode,["failure to write",10,13]
return


END

Tom Gonser
- 5th April 2005, 05:27
OK, I am drained.. here is the last program. I have been experimenting with BYTE and WORD and notice they make the memory behaviour REALLY different.. In any event, I have noticed:

1. I can WRITE from 0-640 to memory
2. When I READ this back, it is all '0's..
3. When I ERASE it ($FFFF), and read it back it is all 65355..

I THINK somehow I am writing PAGES using the [x] brackets..(???) I want to write to SPECFIC memory locations.. but can't figure out the syntax for that. maybe that is why the data is all messed up? So I tried putting it in increments of 128.. still reading back '0'..

Anyway - here is the sample program that lets you write, read and erase from an external 24LC512... and get back zeros..

TG

------------------------

'on my DataLoggers I have 16F876 or 18F252 and 2x 24LC512.
'The following code is tested.
'could you give it a try and let us know what the result was?
' -----[ Fuses ]------------------------------------------------
@ __CONFIG _CONFIG1H, _OSC_INTIO67_1H
@ __CONFIG _CONFIG2H, _WDT_ON_2H & _WDTPS_128_2H
@ __CONFIG _CONFIG3H, _PBADEN_OFF_3H & _MCLRE_OFF_3H
@ __CONFIG _CONFIG4L, _LVP_OFF_4L & 0bfh ;_XINST_OFF_4L
'
' -----[ Includes/Defines ]---------------------------------------------------------
include "modedefs.bas" 'include serout defines

OSCCON=%01111000
DEFINE OSC 8
While OSCCON.2=0:Wend

SCL var PortC.3 ' I2C Clock
SDA var PortC.4 ' I2C Data
ROM con %10100000 ' address of chip1
ADDR VAR word ' ROM Location
portout var PortC.6
portin var PortC.7
Mode con 16468 ' 4800 Baud 8N1 for Monitor Port
Test var byte[21] ' Test Array
I2Cdelay con 10 ' Delay after I2Cwrite

Temp var byte
X var word
dta var word

CLEAR

Addr=100
loop:
SEROUT2 portout,Mode,[13,10,"** MCU started",13,10,13,10]
serout2 portout, mode, ["enter 1 to write data, 2 to read it, 3 to erase"]
serin2 portin, mode, [DEC1 temp]

select case temp
case 1
for X = 0 to 640 step 128
I2Cwrite SDA, SCL,ROM,X,[X],failw
Serout2 portout, mode, ["Read Address: ",#X," Data:",#X,10,13]
pause 10
next x
case 2
for x = 0 to 640 step 128
I2Cread SDA,SCL,ROM,X,dta,failr
Serout2 portout, mode, ["Read Address: ",#X," Data:",#dta,10,13]
next x
Case 3
for x = 0 to 640 step 128
I2Cwrite SDA,SCL,ROM,X,[$FFFF],failw
Serout2 portout, mode,["Erasing Address: ",#X," Data:",$FFFF,10,13]
pause 10
next x
case else
goto loop
end select

goto loop:

failr:
serout2 portout, mode,["failure to read",10,13]
return

failw:
serout2 portout, mode,["failure to write",10,13]
return

END

NavMicroSystems
- 5th April 2005, 12:36
Tom,

your code works as designed.

In the FOR...NEXT loop to write the eeprom you are counting from 0 to 640.
X is a WORD size variable and being used as EEPROM address as well as value to be written.
This means you are writing a WORD (two BYTES) to the EEPROM.
This requires two BYTE locations in your EEPROM.
By incrementing the address counter by 1 the LowByte of the last WORD written will always be overwritten with the HighByte oft the current WORD.

here is a working example:



for X = 0 to 640
I2Cwrite SDA, SCL,ROM,X*2,[x]
pause 10
Serout2 portout, mode, ["Write Address: ",#x*2," Data:",#x,10,13]
dta=dta+1
next x

for x = 0 to 640
I2Cread SDA,SCL,ROM,X*2,[dta]
Serout2 portout, mode, ["Address: ",#x*2," Data:",#dta,10,13]
pause 100
next x

Tom Gonser
- 5th April 2005, 15:19
Thanks! That makes sense, and the program now pulls it right - partially. I have a routine (below)

1. writes data
2. reads data
3. erases data
4. reads a specific location in memory

problem is this - When I READ, I get for example "1" stored in location "2".. this makes sense.

BUT when I read from a specific location using a lookup, it returns a totally different value.. Example:

Enter 1 to write data, 2 to read it, 3 to erase, 4 to select -> "4"
Enter the memory location you want (000-255) - > "002"
Reading: 2 Data stored there: 21332

I'd expect the "002" memory location to match the one above and return a "1".. instead I get "21332"... Something is wrong with my DEC3 collection?

Thanks for helping me understand how these words/byte, etc equate to memory space.

Tom

- Updated CODE ------------------------------------------------------
'on my DataLoggers I have 16F876 or 18F252 and 2x 24LC512.
'The following code is tested.
'could you give it a try and let us know what the result was?
' -----[ Fuses ]------------------------------------------------
@ __CONFIG _CONFIG1H, _OSC_INTIO67_1H
@ __CONFIG _CONFIG2H, _WDT_ON_2H & _WDTPS_128_2H
@ __CONFIG _CONFIG3H, _PBADEN_OFF_3H & _MCLRE_OFF_3H
@ __CONFIG _CONFIG4L, _LVP_OFF_4L & 0bfh ;_XINST_OFF_4L
'
' -----[ Includes/Defines ]---------------------------------------------------------
include "modedefs.bas" 'include serout defines

OSCCON=%01111000
DEFINE OSC 8
While OSCCON.2=0:Wend

SCL var PortC.3 ' I2C Clock
SDA var PortC.4 ' I2C Data
ROM con %10100000 ' address of chip1
ADDR VAR word ' ROM Location
portout var PortC.6
portin var PortC.7
Mode con 16468 ' 4800 Baud 8N1 for Monitor Port

I2Cdelay con 10 ' Delay after I2Cwrite

Temp var byte
X var word
dta var word
stuff var word ' Test Array

CLEAR

Addr=100
loop:
SEROUT2 portout,Mode,[13,10,"** MCU started",13,10,13,10]
serout2 portout, mode, ["Enter 1 to write data, 2 to read it, 3 to erase, 4 to select",10,13]
serin2 portin, mode, [DEC1 temp]

select case temp
case 1
for X = 0 to 128
I2Cwrite SDA, SCL,ROM,X*2,[X],failw
pause 10
Serout2 portout, mode, ["write Address: ",#X*2," Data:",#X,10,13]
next x
case 2
for x = 0 to 128
I2Cread SDA,SCL,ROM,X*2,[dta],failr
Serout2 portout, mode, ["Read Address: ",#X*2," Data:",#dta,10,13]
next x
Case 3
for x = 0 to 128
I2Cwrite SDA,SCL,ROM,X*2,[x],failw
Serout2 portout, mode,["Erasing Address: ",#X*2," Data:",$FFFF,10,13]
pause 10
next x
Case 4
Serout2 portout, mode,["Enter the memory location you want (000-255)",10,13]
serin2 portin, mode, [DEC3 temp]
I2Cread SDA,SCL,ROM,temp,[stuff],failr
Serout2 portout, mode,["Reading: ",#temp," Data stored there: ",#stuff,10,13]
pause 10
case else
goto loop
end select

goto loop:

failr:
serout2 portout, mode,["failure to read",10,13]
return

failw:
serout2 portout, mode,["failure to write",10,13]
return

END

NavMicroSystems
- 5th April 2005, 17:02
Tom,



Temp var byte
I2Cread SDA,SCL,ROM,temp,[stuff],failr


in this example you are using the BYTE size variable "Temp" as address.

Do you remember that the 25LC512 requires a WORD size variable as address ;-)

Tom Gonser
- 5th April 2005, 17:19
Argghh! Thanks very much.. I am sure that will make a difference.

Had a question also about the notion of Page Write vs Byte Write. I notice in the data sheets that the chip does either one.

For some reason I though the use of [ ] indicated a page write, and ( ) was for a byte write, but that does not seem to hold up. So -

How do you tell the memory to do a Byte write vs a Page write? In my program I am writing a STR FOO\XXX - and am incrementing the counter by 128, assuming this is approximating a page write. It seems to be.

However, when I just want to write values like:

"1" - needing only a 'byte' sized space..

or

"16472" - needing a 'word' sized space no doubt...

to specific memory locations, I'd assume I'd be writing these a byte or a word at a time.. How do we tell the program to write a Byte vs a Page?

Then, to get the data back out - I am OK on how to get a byte out, but for a word, i'd need to read the memory location, and memory location +1, reading the lowbyte and highbyte, correct? In this example, I need to retrieve "16472" which is more than a byte.


Tom

NavMicroSystems
- 5th April 2005, 17:40
Then, to get the data back out - I am OK on how to get a byte out, but for a word, i'd need to read the memory location, and memory location +1, reading the lowbyte and highbyte, correct? In this example, I need to retrieve "16472" which is more than a byte.

Tom,

looks like you are getting lost with bits, bytes and words.

you should take a break, have a cup of coffee or tea, and look at my last code example, it does read and write a word at a time.

Tom Gonser
- 6th April 2005, 15:14
I figured it out. Thanks to all who contributed, it was a 'learning experience'..

The root of my mis-understanding was this:

1. WORDS can be stored with a simple I2Cwrite command, and it is not necessary to write variable.byte0, then variable.byte1 in order to do this. Writing a WORD at a memory location just STARTS there and goes forward to the next location (Byte). I did not get this.

2. If you leave out [ ] around what you are writing or reading, it will pass compiler, but not do anything. This was my biggest issue. I was just writing

I2Cread , Dpin, Cpin, Chip1, location , data, failroutine

This works fine, but does not write anything for 'data'... If you do this:

I2Cread , Dpin, Cpin, Chip1, location , [data], failroutine

It works PERFECTLY... Once I went back and added the brackets, and made sure I was dealing with WORDS, it all came together..


THANKS.

TOM

NavMicroSystems
- 6th April 2005, 15:51
Good to hear you are back on track!