EEPROM - SX/B Example (I2C) - modified & question
![John Kauffman](https://forums.parallax.com/uploads/userpics/555/nZBNEPT0B6FMD.jpg)
EEPROM - SX/B Example (I2C) - modified & question
I’m starting with 24LC EEPROM and using the SX/B Help I2C example.
·
To demonstrate success, the help example uses a Watch in Debug mode.
I’d like to demonstrate a successful read/write outside of debug.
·
Here is how I want program to behave:
I’ve built hardware as described in Help I2C example, with two additions:
8 LEDS connected to RB
One LED to designate display has been read: RC.0 named LedRead
·
I have modified the help example as attached, mainly:
··········Added PIN, CON for value to save, variables
Added a short sub to test the LEDs
Deleted FOR…NEXT that created, saved and read random values
Substituted saving the one hard-coded byte and read it back
Set retrieved value to the RB register.
I have not change any of the subs that deal with I2C or MEM_IN and MEM_OUT.
·
Results:
Test display of LEDs works
Display of byte value that was hard-coded works
But then nothing happens.
·
As I analyze the help example, I have a question.
The subroutine named MEM_OUT is listed in Sub declarations as expecting three parameters. But when the sub is called (following line) it seems only two parameters are sent.
Why?
·
' Subroutine Declarations
'
MEM_OUT········ SUB···· 3······················ ' write value to memory
…
...···'later in code:
MEM_OUT addr, outVal
·
Thanks.
I’m starting with 24LC EEPROM and using the SX/B Help I2C example.
·
To demonstrate success, the help example uses a Watch in Debug mode.
I’d like to demonstrate a successful read/write outside of debug.
·
Here is how I want program to behave:
- Hardcode a byte value into the program
- Then run code to behave as follows:
- display the byte value in binary form on 8 LEDS for one second
- turn off LEDs for one second
- save that byte to EEPROM
- read the byte back from EEPROM
- Turn on a LED that flags “value read out”
- Display the byte in binary form on the 8 LEDs
I’ve built hardware as described in Help I2C example, with two additions:
8 LEDS connected to RB
One LED to designate display has been read: RC.0 named LedRead
·
I have modified the help example as attached, mainly:
··········Added PIN, CON for value to save, variables
Added a short sub to test the LEDs
Deleted FOR…NEXT that created, saved and read random values
Substituted saving the one hard-coded byte and read it back
Set retrieved value to the RB register.
I have not change any of the subs that deal with I2C or MEM_IN and MEM_OUT.
·
Results:
Test display of LEDs works
Display of byte value that was hard-coded works
But then nothing happens.
·
As I analyze the help example, I have a question.
The subroutine named MEM_OUT is listed in Sub declarations as expecting three parameters. But when the sub is called (following line) it seems only two parameters are sent.
Why?
·
' Subroutine Declarations
'
MEM_OUT········ SUB···· 3······················ ' write value to memory
…
...···'later in code:
MEM_OUT addr, outVal
·
Thanks.
Comments
Put "outVal = ValueToStore" just before "MEM_OUT addr, outVal"
"MEM_OUT SUB 3" means that three BYTES will be send, in this case it is a WORD for the address and a BYTE for the value.
Bean.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Teacher: What is the difference between ignorance and apathy ?
Student: I don't know and I don't care
Teacher: Correct !
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
www.hittconsulting.com
Post Edited (Bean (Hitt Consulting)) : 8/2/2007 12:15:10 PM GMT
original:
MEM_OUT addr, outVal ' send to 24LC16
Alternates:
MEM_OUT addr, ValueToStore ' send to 24LC16
MEM_OUT addr, %00001111 ' send to 24LC16
You seem to be writing to the EEPROM and then attempting to immediately read back. The EEPROM is probably busy while you're attempting to read back so you're not getting the correct value. You can either insert a PAUSE after the MEM_OUT line, or update the MEM_OUT subroutine so that it doesn't return to the program until the write cycle is complete.
Note that you have to define a bit variable, ackBit, for the update.
You could use conditional compilation to disable the write-delay, and if you're going to be using I2C is a large application its a good idea to encapsulate the core I2C commands in custom subroutines and functions; I2C has a timing element to is and, therefore, generates a bit of code.
···· I replaced code as posted (and added bit VAR named ackbit)
···· For good measure, added a Rip van Winkle-sized pause between write & read.
New version (-02) attached.
Still same result: initial display of value works, then nothing.
I tried another address $0A0A in case %0000 was reserved - no change.
What really has me stymied is that the LedReadFlag does not even come on. It seems that the read part of the code is never executed.
I don't have a second 24LC32A to swap for IC check.·Can I try swapping in 24LC256?
Basics:
Independent check of LedReadFlag circuit·is OK.
EEPROM Pins 1-3 (A0-A2) and pin 7 (WP) are grounded, like in SX/B Help Example wiring diagram.
EEPROM pins 5 & 6 have pull-ups (1k instead of 4.7 k of diagram).
I'm using a Murata 400 resonator. I program, then remove the key, then reset to test.
Dave
GoSub Main
to
GoTo Main
No change in behavior.
Post Edited (JonnyMac) : 8/2/2007 4:00:00 PM GMT
It's not clear which device you started with in your initial post. It looks like you may have started with a 24LC32 and then switched to 24LC16. The addressing on these two devices is different. The 24LC16 requires a device address followed by a single memory address byte. The device address includes the 3 most significant memory address bits. Your code suports this format.
The 24LC32 and larger devices requires an extra address byte. You would need to send the device address, followed by the MSB and LSB memory address bits. In this case, the 3 address bits in the device address are actually chip select bits. They need to match the way the pins are wired on the chip. For a single chip this is normally all zeros.
Dave
I studied your version. I expected:
The 8 LEDs show the value one for half second, then LEDReadFLag comes on while 8 LED still displays 1 (because it read one from EEPROM) for another half second.
Then pause 1.5 seconds
Then repeat for two, etc., changing about every 2.5 seconds up to 255
On several tries no luck, it shows one LED continiously. LedReadFlag is not coming on at all.
It is late here, I am going to recheck all hardware in morning and test section by section.
My first instinct to troubleshooting is to break down the parts and test each. I have not come up with a more basic code to test the EEPROM. LEDs can be reduced down to a simple HIGH LOW. For the EEPROM all the parts have to work immediately (addressing, timing, read, write, etc.) If anyone can think of a way to divide out those functions I could break down the troubleshooting.
Also tomorrow I will try Jon's code with just one read and write rather than a loop.
Two question for testing tomorrow:
Will same code work with 24LC256? I want to test by swap out the EEPROM & don't have another '32 .
Can I use internal 4Mhz or must stick with 4 Mhz Murata?
Thanks.
Actually, the 24LC256 is easier to use as there's no messing around with the slave ID byte, and you can use up to eight of them in a project (not the case with the 24LC16B). I've attached my 24LC512 demo which will in fact work with the 24LC256, 24LC128, 24LC64, and 24LC32 (you just have to limit the EE address for the respective device). Note that this program can write a byte or word to a given address; when a word is written it is stored Little-Endian. There are two functions for reading back: GET_EE and GET_EE2; the latter is for reading back a word value. The address must always be a word. If you want to specify a constant address you can do it like this:
Where two bytes are used for the address: low byte, then high byte. The value that follows can be a byte or word. The same addressing structure exists with GET_EE and GET_EE2.
As I2C is a synchronous protocol you can use the internal oscillator.
Post Edited (JonnyMac) : 8/2/2007 5:56:20 PM GMT
I have attached a file which is Jon's work that I·sliced & diced to get a "For Dummies" version.·My goal was the absolute first program a person should try with an EEPROM. Features:
- Keep most of code in SUBs
- Limit to only one byte saved (no words, no arrays, address is hard coded)
- Users hard-codes the value into the code
- Output is by eight LEDs rather then through BREAK / WATCH
- Code displays the byte the user hard-coded, writes it, reads it and displays what was read
- An extra LED is a flag that the byte on the display was read
- Commented to the max
I know this will be of little use to the hotshots on this forum (go straight to Jon's code posted above), but hopefully it will be found & used by someone that wants a first·try with an EEPROM.I'm planning to write & post programs for the next few learning steps:
Saving words:
-- GET_EE2 in my program does this
Saving arrays:
-- GET_EE2 could be used as a starter; I would pass a pointer to the array and the number of bytes to write
Multiple EEPROMs:
-- you'll need to make the slave ID a variable, and include a variable for the device address
Batch saving:
-- that's essentially what GET_EE2 does, just with two bytes