News:

;) This forum is the property of Proton software developers

Main Menu

24LC16B EEPROM send 16 bytes read 15 bytes

Started by JackB, Jan 06, 2025, 10:23 PM

Previous topic - Next topic

JackB

Hello everyone,

I'm working with a 24LC16B, and when I send 16 bytes, I read only 15 bytes back + 1 random.

This eeprom came from Aliexpress, they sold me a 16 bytes for a 15 bytes who know's ?
on the last 12 years,I had experience with Aliexpress IC's when they stamp brand name like National, Fairchild, Texas Intruments and produce low end quality many of theses IC's dont match the original
manifacturer data sheet.

My question is when sending 16 bytes then reading the chip I got back 16 bytes but the last

bytes has nothing to do with the primary send could be a flaw from the production firm.

eg:
 
 Write : 1------Y-------1
 Read  : 1------Y-------a

I tested with 2 10k and 2k resistor from SDA/SCL to VDD same result.
I checked the data sheet ( 2009-2016) and on page 1 :it's printed: 'The 24LC16B also has a page write capability for up to 16 bytes of data'.
I tried at 100Khz and 400Khz with the 'Declare I2C_Slow_Bus OFF/On'

I traced the I2C signals and the write signal look's ok with the ACK at the end, but the read signal
terminate with a 'a+NAK.'

Is anybody had this kind of problem, let me know.

(Also I did test a 24LC64 and it's working fine sending / receiving 32 bytes.)

Thanks to everyone.


Device = 18F14K22 
Declare Xtal = 64
Config_Start
  FOSC = IRC       
  PLLEN = On       
  MCLRE = OFF
  LVP = OFF
Config_End

ANSEL = 0
ANSELH= 0
OSCCON = $70                   ' 16Mhz for PLLEN:64Mhz / p:17

Dim SDA_Pin As PORTB.4 ' Alias the SDA (Data) line
Dim SCL_Pin As PORTB.6 ' Alias the SSL (Clock) line
Declare I2C_Slow_Bus OFF ' 400Khz

Dim aArray[16] As Byte  ="1------Y-------1" 
Dim bArray[16] As Byte
Dim I As Word

TRISA = %00001000
TRISB = %00100000
TRISC = %00111111 
High PORTA.0   

MAIN:                                 
'----- Wait for button press/release
While PORTA.3 = 1: Wend               
DelayMS 100                           
While PORTA.3 = 0: Wend               
DelayMS 100                           

'----- Start of the loop
For I = 0 To 0 Step 16

'----- Writing 16 Bytes to 24LC16B
SerOut PORTA.0,84, [" Record: ",Dec I,13,10]
I2COut SDA_Pin, SCL_Pin, %10100000, I, [Str aArray\16]
DelayMS 10
SerOut PORTA.0,84, [" Write : ",Str aArray,13,10]

'----- Reading 16 bytes from 24LC16B
I2CIn SDA_Pin, SCL_Pin, %10100001, I, [Str bArray\16]
SerOut PORTA.0,84, [" Read  : ",Str bArray,13,10]

Next I
GoTo MAIN














 


trastikata

Hello JackB,

try this code to see if it is writing and reading correctly all 16 bytes, reading from those chips is a bit different:

Symbol ReadMemAddress = %10100001
Symbol WriteMemAddress = %10100000
Declare SDA_Pin = PORTB.4
Declare SCL_Pin = PORTB.6

Dim aArray[16] As Byte  ="1------Y-------1"
Dim bArray[16] As Byte
Dim wAddress As Word
Dim bCounter As Byte

'Write a page
    wAddress = 0
    BStart
        BusOut WriteMemAddress       
        BusOut wAddress.Byte1 
        BusOut wAddress.Byte0  
        For bCounter = 0 To 15
            BusOut aArray[bCounter]
        Next        
    BStop

    DelayMS 10

'Read page
    BStart
        BusOut WriteMemAddress       
        BusOut wAddress.Byte1 
        BusOut wAddress.Byte0
    BStart
        BusOut ReadMemAddress
        For bCounter = 0 To 14
            bArray[bCounter] = BusIn
            BusAck
        Next
        bArray[15] = BusIn
        BusNack  
    BStop
End

JackB

Hello Trastikata

many thanks,

I'll get to it tomorrow and let you know the outcome.


Thanks again

JackB

Hello ,

I had sometime to trace this program, still the same.

see trace.

Thanks again

JackB

#4
Update : 24LC16B

when inside a For-Next loop the problem occur when receiving data

even when including a delay before the Next command.

without the For-Next only sending & receiving 1 record of 16 Bytes the problem disappear.

a For~Next loop seem to create the problem.

I'll have to find a way to automate the process.

any suggestions let me know

Thanks again




'For I = 0 To 0 Step 16
'SerOut PORTA.0,84, [" Record: ",Dec I,13,10]

I2COut SDA_Pin, SCL_Pin, %10100000, 0, [Str aArray\16]
SerOut PORTA.0,84, [" Write : ",Str aArray,13,10]
DelayMS 10

I2CIn SDA_Pin, SCL_Pin, %10100001, 0, [Str bArray\16]
SerOut PORTA.0,84, [" Read  : ",Str bArray,13,10]

'next i





JackB

Update: 24LC16B eeprom

instead of relying on the For~Next, I enter each address as a constant  0,32,48,64, etc.. to write
each record then with a standalone EEPROM programmer I verified each records.

Then use I2Cin function 'stand alone' without any loop in Positron to read one by one each records (enter address 0) compile and read (enter address 16) compile and read, etc..all records received alright.

it's seem whitin a loop the I2Cin / I2Cout is affected while using a variable instead of a constant.

is this can be resolve, let me know

Thanks again.

' use a constant as address
I2CIn SDA_Pin, SCL_Pin, %10100001, 256, [Str bArray\16]









Frizie

I find the programrule  For i = 0 To 0 Step 16  a bit unusual.
Maybe that's the cause?
Ohm sweet Ohm | www.picbasic.nl

JackB

Hello Frizie,

the  For I = 0 To 0 Step 16, is to write the first record only

with For I = 0 To 32 Step 16 to write & read record 0,1,2 of 16 bytes each

As it show on the EEPROM Programmer dump on the left manual entry work ok, on the right

using I2Cout / I2Cin the record # 0 is affected record 1,2 etc.. are not written using within a For-Next.





' Write & Read 3 records of 16 Bytes each

For I = 0 To 32 Step 16
SerOut PORTA.0,84, [" Record: ",Dec I,13,10]

I2COut SDA_Pin, SCL_Pin, %10100000, I, [Str aArray\16]
SerOut PORTA.0,84, [" Write : ",Str aArray,13,10]
DelayMS 10
I2CIn SDA_Pin, SCL_Pin, %10100001, I, [Str bArray\16]
SerOut PORTA.0,84, [" Read  : ",Str bArray,13,10]

Next I

JackB


my guess is the 24LC16B from Aliexpress are a defective batch

Here's a test with a 24LC64 from Digikey, work fine with a For-Next.



'24LC64 TEST

Device = 18F14K22 
Declare Xtal = 64
Config_Start
  FOSC = IRC                       
  PLLEN = On                       
  MCLRE = OFF
  LVP = OFF  'OFF:PORTC.3 I/O
Config_End

TRISA = %00001000              ' 0:Out 1:In
TRISB = %00100000
TRISC = %00111111 
High PORTA.0                         
                         
ANSEL = 0
ANSELH= 0
OSCCON = $70           

Dim I As Word

Declare I2C_Slow_Bus OFF       ' 400Khz
Declare Hserial_Baud = 9600    ' USART 1 Baudrate
Declare HRSOut1_Pin = PORTB.7  ' USART 1 out pin

Dim SDA_Pin As PORTB.4 ' Alias the SDA (Data) line
Dim SCL_Pin As PORTB.6 ' Alias the SSL (Clock) line

Dim aArray[32] As Byte   ="X--------------O---------------X"
Dim bArray[32] As Byte

MAIN:                                  ' Main Routine

While PORTA.3 = 1: Wend               
DelayMS 100                            ' Bounce delay
While PORTA.3 = 0: Wend                ' Button release
DelayMS 100                           

For I = 0  To 8192 Step 32  ' 32 Bytes record

SerOut PORTA.0,84, [" Record  : ",Dec I,13,10]

I2COut SDA_Pin, SCL_Pin, %10100000, I, [Str aArray\32]

SerOut PORTA.0,84, [" Write   : ",Str aArray,13,10]

'DelayMS 10

I2CIn SDA_Pin, SCL_Pin, %10100001, I, [Str bArray\32]

SerOut PORTA.0,84, [" Read    : ",Str bArray,13,10]

Next I

GoTo MAIN




Frizie

The 24LC16 doesn't have to be broken.
My experience with the 24LC16 (years ago) is that they need to be controlled slightly differently than the 24LC512 that I usually use.
Ohm sweet Ohm | www.picbasic.nl

JackB

Here's another test with the suspected defective IC batch both type DIP8 & SOIC8

both came from Aliexpress on the same order and have the same behavior

I wrote manualy 17 records of 16 bytes using a constant instead of a variable without the For-Next

and it's work fine but at the 17th record the chip can't take it.

Then when reading back the data with a For-Next loop, I received 16 records alright but the 17th record

was not as send.

From the Positron side, everything is working alright since

I have no problem writing/reading a 24LC64 from Digikey.



' 17 records with address as constant

For I = 0 To 256 Step 16
'SerOut PORTA.0,84, [" Record: ",Dec I,13,10]


(*

' Manual entry for 17 records

I2COut SDA_Pin, SCL_Pin, %10100000, 0, [Str aArray\16]     
DelayMS 10
I2COut SDA_Pin, SCL_Pin, %10100000, 16, [Str aArray\16]
DelayMS 10
I2COut SDA_Pin, SCL_Pin, %10100000, 32, [Str aArray\16]
DelayMS 10
I2COut SDA_Pin, SCL_Pin, %10100000, 48, [Str aArray\16]
DelayMS 10
I2COut SDA_Pin, SCL_Pin, %10100000, 64, [Str aArray\16]
DelayMS 10
I2COut SDA_Pin, SCL_Pin, %10100000, 80, [Str aArray\16]
DelayMS 10
I2COut SDA_Pin, SCL_Pin, %10100000, 96, [Str aArray\16]
DelayMS 10
I2COut SDA_Pin, SCL_Pin, %10100000, 112, [Str aArray\16]
DelayMS 10
I2COut SDA_Pin, SCL_Pin, %10100000, 128, [Str aArray\16]
DelayMS 10
I2COut SDA_Pin, SCL_Pin, %10100000, 144, [Str aArray\16]
DelayMS 10
I2COut SDA_Pin, SCL_Pin, %10100000, 160, [Str aArray\16]
DelayMS 10
I2COut SDA_Pin, SCL_Pin, %10100000, 176, [Str aArray\16]
DelayMS 10
I2COut SDA_Pin, SCL_Pin, %10100000, 192, [Str aArray\16]
DelayMS 10
I2COut SDA_Pin, SCL_Pin, %10100000, 208, [Str aArray\16]
DelayMS 10
I2COut SDA_Pin, SCL_Pin, %10100000, 224, [Str aArray\16]
DelayMS 10
I2COut SDA_Pin, SCL_Pin, %10100000, 240, [Str aArray\16]
DelayMS 10
I2COut SDA_Pin, SCL_Pin, %10100000, 256, [Str aArray\16]
DelayMS 10

GoTo MAIN
'SerOut PORTA.0,84, [" Write : ",Str aArray,13,10]
*)

' Receiving 17 records
I2CIn SDA_Pin, SCL_Pin, %10100001, I, [Str bArray\16]
SerOut PORTA.0,84, [" Read  : ",Str bArray,13,10]
DelayMS 10

Next I








JackB

Update : 24LC16B

when using Dim I as Byte for record address instead of Word, it's working well but up to 255 only

and my other 24LC64 and 256 work as espected since it's required an address in word format

Also I found out when using eeprom above 128 Kbites with the PIC18F14K22 is best not to use any Serout

after writing or reading this help a better data transfert.

Anyway, I've got new 24LC16B in transit from Digikey and will update.





Dim SDA_Pin As PORTB.4 ' Alias the SDA (Data) line
Dim SCL_Pin As PORTB.6 ' Alias the SSL (Clock) line
Declare I2C_Slow_Bus OFF ' 400Khz

Dim aArray[16] As Byte  ="[OOOOOOOOOOOOOO]" 
Dim bArray[16] As Byte

Dim I As Byte      ' Record address

TRISA = %00001000
TRISB = %00100000
TRISC = %00111111 
High PORTA.0   
MAIN:                                 
While PORTA.3 = 1: Wend               
DelayMS 100                           
While PORTA.3 = 0: Wend               
DelayMS 100                           
Low PORTA.1

For I = 0 To 255 Step 16

SerOut PORTA.0,84, [" Record: ",Dec I,13,10]

I2COut SDA_Pin, SCL_Pin, %10100000,I , [Str aArray\16]
DelayMS 10

'SerOut PORTA.0,84, [" Write : ",Str aArray,13,10]
'I2CIn SDA_Pin, SCL_Pin, %10100001, 0, [Str bArray\16]
'SerOut PORTA.0,84, [" Read  : ",Str bArray,13,10]
'DelayMS 20

Next I
High PORTA.1
GoTo MAIN



JackB

I found this about I2C EEPROM 24LC16b, 24LC65 problem on

STMicroelectronics Website. (‎2019-01-16 03:33 AM)

https://community.st.com/t5/others-hardware-and-software/i2c-eeprom-24lc16b-24lc65-problem/td-p/403124

look's the 24LC16B need only 1 byte to address the memory page and not 2 bytes.

this make sense when earlier I was able to write the first 255 bytes of the eeprom.

if someone do have any sample code for this eeprom to share it will be much appreciate.

Thanks to everyone.




Device = 18F14K22 
Declare Xtal = 64
Config_Start
  FOSC = IRC       
  PLLEN = On       
  MCLRE = OFF
  LVP = OFF
Config_End

ANSEL = 0
ANSELH= 0
OSCCON = $70                   ' 16Mhz for PLLEN:64Mhz / p:17

Dim SDA_Pin As PORTB.4 ' Alias the SDA (Data) line
Dim SCL_Pin As PORTB.6 ' Alias the SSL (Clock) line
Declare I2C_Slow_Bus OFF ' 400Khz

Dim aArray[16] As Byte  ="[--------------]"   
Dim bArray[16] As Byte

Dim I As Byte

TRISA = %00001000
TRISB = %00100000
TRISC = %00111111 

MAIN:                                 

While PORTA.3 = 1: Wend               
DelayMS 100                           
While PORTA.3 = 0: Wend               
DelayMS 100                           


For I = 0 To 255 Step 16

I2COut SDA_Pin, SCL_Pin, %10100000,I , [Str aArray\16]

DelayMS 20

Next I

GoTo MAIN








JackB

Finaly I got it !

(this is an excerpt from Picaxe AXE110 'USING I2C WITH PICAXE' page 5)

The cheapest EEPROMs (e.g. Microchip parts ending in the letter 'B') only use a single byte register address, which by definition can only uniquely identify 256 registers. This means that the various blocks (if they exist) must be identified in a different way. The 24LC16B has 8 blocks, the other EEPROMS have less (see table below). The way these cheap EEPROMs overcome this address problem is by merging the block address into the slave address. This means, in effect, that a single 24LC16B 'appears' on the i2c bus as 8 different 'slaves', each slave having a unique address and containing 256 registers. This system might at first appear quite strange, but the IC is constructed this way to keep the cost of the IC to a minimum. However this system does have the downfall that only one part can be used per bus (the external IC pins A2-A0 are not actually physically connected within these cheaper 'B' parts).


I2C address   %1010bbbx

where   b = block address (internal to EEPROM)
        x = 0 = I2Cout , 1 = I2Cin

each memory blocks 'bbb' use a byte address 0~255 for a total of 8 blocks 000,001,010...111.

eg:


[b]'Writing to 24LC16B[/b]

'block 0                      bbb 
I2COut SDA_Pin, SCL_Pin, %10100000,I , [Str aArray\16]
DelayMS 10

'block 1                      bbb
I2COut SDA_Pin, SCL_Pin, %10100010,I , [Str aArray\16]
DelayMS 10
;
;
'block 7                      bbb
I2COut SDA_Pin, SCL_Pin, %10101110,I , [Str aArray\16]
DelayMS 10


[b]'Reading from 24LC16B[/b]

'block 0                     bbb 
I2Cin SDA_Pin, SCL_Pin, %10100000,I , [Str aArray\16]
DelayMS 10

'block 1                     bbb
I2Cin SDA_Pin, SCL_Pin, %10100010,I , [Str aArray\16]
DelayMS 10
;
;
'block 7                     bbb
I2Cin SDA_Pin, SCL_Pin, %10101110,I , [Str aArray\16]
DelayMS 10