Hi there,

I'm having trouble writing 8 bytes to a 24LC16B memory chip.

In fact, I can write 8 consecutive bytes but it seems only the last byte I want to program is written to all 8 positions.

Even after reading the DS many times knowing there is something particular when writing less than 16 bytes (...don't still understand everything for sure ), I can't see what am I missing.

Name:  2020-12-29 21_37_13-Clipboard.png
Views: 534
Size:  70.8 KB

Any clue?

Code:
'======= FUSES ====================================================================================
' PIC 16F690 Fuses (MPASM)

' Internal oscillator
@ __config _FCMEN_OFF &_IESO_OFF &_CPD_OFF &_WDT_OFF &_INTRC_OSC_NOCLKOUT &_BOR_OFF &_CP_OFF &_PWRTE_OFF &_MCLRE_OFF

@ ERRORLEVEL -306

'======= REGISTERS =================================================================================
' Registers   76543210
OPTION_REG = %10000000 ' Pull-Ups disabled
OSCCON     = %01110000 ' Internal oscillator
ANSEL      = %00000000 ' analog inputs Channels 0 to 7
ANSELH     = %00000000 ' analog inputs Channels 8 to 11
WPUA       = %00000000 ' weak pull-ups
WPUB       = %00000000 ' weak pull-ups
ADCON0     = %00000000 ' Select the VP6 channel as ADC input bits5:2 (xx1101xx)
ADCON1     = %00000000 ' Set FRC
VRCON      = %00000000 ' VP6 reference
CM1CON0    = %00000000 ' Comparator1 Module
CM2CON0    = %00000000 ' Comparator2 Module

TRISA      = %00000000 ' Input/Output (0 to 5)
PORTA      = %00000100 ' High/Low (0 to 5)
TRISB      = %00000000 ' Input/Output (4 to 7)
PORTB      = %00000000 ' High/Low (4 to 7)
TRISC      = %00000000 ' Input/Output (0 to 7)
PORTC      = %01000000 ' High/Low (0 to 7)

'======= DEFINES ==================================================================================
DEFINE OSC 8
DEFINE HSER_CLROERR 1 ' Clear overflow automatically
DEFINE NO_CLRWDT 1    ' Don't waste cycles clearing WDT

'======= VARIABLES ================================================================================
Ser_Out     VAR PORTA.2 ' Serial Out
EeWP        VAR PORTC.3 ' memory Write Protect
SCL         VAR PORTC.6 ' i2c Clock pin [6]
SDA         VAR PORTC.7 ' i2c Data pin  [5]
Cntr        VAR BYTE    ' just a counter
Ser_Mode    VAR word    ' serial com baudrate
Mem_Loc     var BYTE    ' holds the user's code memory place (000..255)
Temp        VAR WORD    ' for WORD sized calculation
EeVal       VAR BYTE(8) ' array that holds the numbers in the Eeprom
EeCtrl      var BYTE    ' 4 control bits + 3 memory block selector bits
EeAddress   var BYTE    ' 24LC16B address (0..255)
EeBlock     var BYTE    ' holds memory block number (0..7)

'======= INITIALIZE ===============================================================================
Cntr      = 0
Ser_Mode  = 84 ' 9600bps
Mem_loc   = 0
Temp      = 0
EeCtrl    = 0
EeAddress = 0
EeBlock   = 0
For Cntr = 0 to 7
    EeVal(Cntr) = Cntr ' initialize EeVal
NEXT
HIGH Ser_Out        ' avoid serial data garbage @ startup

'======= TEST =====================================================================================
Mem_loc = 45 ' put here an address between 0..255 to write the data to

'======= PROGRAM ==================================================================================
MAIN:
    ' Calculate control byte
    Temp     = Mem_loc * 8     ' 24LC16B's starting memory position
    EeBlock   = Temp /  256    ' 24LC16B's 0..7 memory block number
    EeAddress = Temp // 256    ' 24LC16B's 0..255 memory position

    ' Get the control byte according to block     [ 0..2047]  [0..255]
    IF Eeblock = 0 THEN EeCtrl = $A0 '                0..255     0..31
    IF Eeblock = 1 THEN EeCtrl = $A2 '              256..511    32..63
    IF Eeblock = 2 THEN EeCtrl = $A4 '              512..767    64..95
    IF Eeblock = 3 THEN EeCtrl = $A6 '             768..1023   96..127
    IF Eeblock = 4 THEN EeCtrl = $A8 '            1024..1279  128..159
    IF Eeblock = 5 THEN EeCtrl = $AA '            1280..1535  160..191
    IF Eeblock = 6 THEN EeCtrl = $AC '            1536..1791  192..223
    IF Eeblock = 7 THEN EeCtrl = $AE '            1792..2047  224..255

    ' Show the input I'm using for this test
    SEROUT2 Ser_Out, Ser_Mode,["Mem_Loc  : ",DEC Mem_Loc,10,"EeBlock  : ",_
        DEC3 EeBlock,10,"EeAddress: ",DEC3 EeAddress,10,"CTRL     : ",BIN EeCtrl,13,10]

' VARIANT 1 - WRITE 8 same bytes to memory = works but...
EeWP = 0
PAUSE 10
For Cntr = 0 to 7
    i2cwrite SDA,SCL,EeCtrl,EeAddress,[33]
    PAUSE 10
NEXT Cntr
EeWP = 1

'' VARIANT 2 - WRITE 8 different bytes to memory = not working
'EeWP = 0   ' Unprotect memory
'PAUSE 10
'For Cntr = 0 to 7
'    i2cwrite SDA,SCL,EeCtrl,EeAddress,[Cntr]
'    PAUSE 10
'NEXT Cntr
'EeWP = 1

'' VARIANT 3 - WRITE 8 different bytes to memory = not working
'EeWP = 0
'PAUSE 10
'i2cwrite SDA,SCL,EeCtrl,EeAddress,[EeVal(0),EeVal(1),EeVal(2),EeVal(3),_
'    EeVal(4),EeVal(5),EeVal(6),EeVal(7)]
'EeWP = 1

'' VARIANT 4 - WRITE 8 different bytes to memory = not working
'EeWP = 0   ' Unprotect memory
'PAUSE 10
'For Cntr = 0 to 7
'    i2cwrite SDA,SCL,EeCtrl,EeAddress,[EeVal(Cntr)]
'    PAUSE 10
'NEXT Cntr
'EeWP = 1

'' VARIANT 5 - WRITE 8 different bytes to memory = not working
'EeWP = 0
'PAUSE 10
'i2cwrite SDA,SCL,EeCtrl,EeAddress,[1]
'PAUSE 10
'i2cwrite SDA,SCL,EeCtrl,EeAddress,[2]
'PAUSE 10
'i2cwrite SDA,SCL,EeCtrl,EeAddress,[3]
'PAUSE 10
'i2cwrite SDA,SCL,EeCtrl,EeAddress,[4]
'PAUSE 10
'i2cwrite SDA,SCL,EeCtrl,EeAddress,[5]
'PAUSE 10
'i2cwrite SDA,SCL,EeCtrl,EeAddress,[6]
'PAUSE 10
'i2cwrite SDA,SCL,EeCtrl,EeAddress,[7]
'PAUSE 10
'i2cwrite SDA,SCL,EeCtrl,EeAddress,[8]
'PAUSE 10
'EeWP = 1

    ' READ 8 bytes from memory
    For Cntr = 0 to 7
        i2cread SDA,SCL,EeCtrl,EeAddress,[EeVal(Cntr)]
    NEXT Cntr
    
    ' display what's in the memory chip    
    SEROUT2 Ser_Out, Ser_Mode,[DEC3 EeVal(0)," ",DEC3 EeVal(1)," ",DEC3 EeVal(2)," ",_
        DEC3 EeVal(3)," ",DEC3 EeVal(4)," ",DEC3 EeVal(5)," ",DEC3 EeVal(6)," ",DEC3 EeVal(7),13,10,10]

end