PDA

View Full Version : Using external EEprom - need a little guidance



Scampy
- 6th July 2015, 12:16
Guys, having a blonde moment here....

I want to save data to an external chip, a 24c256 EEPROM, but I can't seem to make it work the way I currently save data to the flash in the PIC.

Using a DS1307 RTC as an example I2CWrite SDApin,SCLpin,$D0,$00,[RTCSec,RTCMin,RTCHour,RTCWDay,RTCDay,RTCMonth,RTCY ear,RTCCtrl] works fine as each time the update is made it writes the complete string of variables so they remain in the correct order when read back. However I have used designated memory locations eg



WRITE $50,lightsetHR[0],lightsetMN[0],lightoffHR[0],lightoffMN[1],word droptemp[0] ,word normtemp[0],StartMin[0],StopHour[0],StopMin[0],word alarmhigh[0],StartHour[0],word alarmlow[0]
write $60,lightsetHR[1],lightsetMN[1],lightoffHR[1],lightoffMN[1],word droptemp[1] ,word normtemp[1],StartMin[1],StopHour[1],StopMin[1],word alarmhigh[1],StartHour[1],word alarmlow[1]


How would I impliment this so it uses the 24c256, do I use the second hex address in the I2CWrite SDApin,SCLpin,$D0,$00, statement thus:



I2CWrite SDApin,SCLpin,$A0,$50 [lightsetHR[0],lightsetMN[0],lightoffHR[0],lightoffMN[1],word droptemp[0] etc etc...]
I2CWrite SDApin,SCLpin,$A0,$60 [lightsetHR[1],lightsetMN[1], etc etc...... ]

Scampy
- 6th July 2015, 12:42
When I use


I2CWrite SDApin,SCLpin,$A0,$00,[lightsetHR[0],lightsetMN[0],lightoffHR[0],lightoffMN[1],word droptemp[0] ,word normtemp[0],StartMin[0],StopHour[0],StopMin[0],word alarmhigh[0],StartHour[0],word alarmlow[0]]


It haults with a "bad expression" error when i attempt to compile, with lots of expected [ and ] !! - but all I've added are the [ and ] at the end of the variable string

Tabsoft
- 6th July 2015, 14:35
Scampy,

A couple of things for I2CWrite for sEEPROMs.

1. For the Address, per the manual do not use Constants. Use a variable of the size required by the EEPROM. A 24c256 requires a Word address.
2. When using arrays in I2C you need to use var(0) versus var[0]. This is what is causing all of your compile errors.
3. You are writing all of these values in a string to the sEEPROM, known as Page Write mode. Make sure that the total BYTES sent to the sEEPROM at one time
does not exceed its page write buffer. For the 24c256 it is 64 bytes.
4. Remember the sEEPROMS deal with data on a Byte basis. So for your example if I remember correctly your variables you are writing are WORD variables.
So make sure you x2 when counting the number of BYTES sent to the sEEPROM in Page Write mode.

This should get you going.


i2Addr var word

i2Addr = $00
i2cwrite SDA, SCL, $A0, i2Addr, [lightsetHR(0),lightsetMN(0),lightoffHR(0),lightoff MN(0),droptemp(0),normtemp(0), _
StartMin(0),StopHour(0),StopMin(0),alarmhigh(0),St artHour(0),alarmlow(0)]



This will be 24 bytes. Remember the 24c256 is arranged/addressed in rows of 16 bytes. So this data will start at addr $00 and end at addr $17. (0-23).
The start addr of your next record would be $18.

Scampy
- 6th July 2015, 22:23
Thanks for the guidance.

In replacing the square brackets with round ones, would I also need to change the numeric value too to reflect the array format


normtemp VAR WORD[4] ' used to store the desired temperature setting
normtemp1 VAR normtemp[0]
normtemp2 VAR normtemp[1]
normtemp3 VAR normtemp[2]
normtemp4 VAR normtemp[3]


So that normtemp[0] becomes normtemp(1)

Scampy
- 6th July 2015, 22:56
I still get the bad expression errors with the following


i2cread SDA, SCL, $A0, $00,[lightsetHR(1),lightsetMN(1),lightoffHR(1),lightoff MN(1),word droptemp(1) ,word normtemp(1),StartMin(1),StopHour(1),StopMin(1),wor d alarmhigh(1),StartHour(1),word alarmlow(1)]
i2cread SDA, SCL, $A0, $18,[lightsetHR(2),lightsetMN(2),lightoffHR(2),lightoff MN(2),word droptemp(2) ,word normtemp(2),StartMin[2],StopHour(2),StopMin(2),word alarmhigh(2),StartHour(2),word alarmlow(2)]
i2cread SDA, SCL, $A0, $36,[lightsetHR(3),lightsetMN(3),lightoffHR(3),lightoff MN(3),word droptemp(3) ,word normtemp(3),StartMin(3),StopHour(3),StopMin(3),wor d alarmhigh(3),StartHour(3),word alarmlow(3)]
i2cread SDA, SCL, $A0, $54,[lightsetHR(4),lightsetMN(4),lightoffHR(4),lightoff MN(4),word droptemp(4) ,word normtemp(4),StartMin(4),StopHour(4),StopMin(4),wor d alarmhigh(4),StartHour(4),word alarmlow(4)]


Expected "]" but there is one at the end of the statement... :confused:
Edit:
Even when I corrected the StartMin[2] user error ! - still get the same !!

Scampy
- 6th July 2015, 23:27
It seems that as soon as I include the WORD statement it errors.


i2cread SDApin, SCLpin, $A0, $00,[lightsetHR(1),lightsetMN(1),lightoffHR(1),lightoff MN(1)]

compiles fine, but


i2cread SDApin, SCLpin, $A0, $00,[lightsetHR(1),lightsetMN(1),lightoffHR(1),lightoff MN(1),word droptemp(1),word normtemp(1)]

caused the Error:Expected"]" error message

Stumped !!!

Scampy
- 6th July 2015, 23:56
The manual states


If a word- or long-sized array is specified, the bytes that comprise each element are
read lowest byte first. This is the opposite of how simple words and longs are read
and is consistent with the way the compiler normally stores word- and long-sized
variables.


How would I impliment this low.byte / high.byte with an array variable ?

gadelhas
- 6th July 2015, 23:56
Hi Scampy;

Here is a code i do some time go to interface a 93c46 using both MSSP and Shift. Hope ot will be useful to you;



'************************************************* ***************
'* Name : 93C46N EEPROM + MSSP *
'* Author : [GADELHAS] *
'* Notice : Copyright (c) 2012 *
'* : All Rights Reserved *
'* Date : 08-02-2012 *
'* Version : 1.0 *
'* Notes : *
'* : EASYPICV6 + PIC16F887 + 93C46N - FARCHILD *
'************************************************* ***************
' CONFIGS
' ================================================== ==============
@ __CONFIG _CONFIG1, _HS_OSC & _WDT_OFF & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _BOR_OFF & _DEBUG_OFF & _LVP_OFF & _FCMEN_ON & _IESO_OFF
@ __CONFIG _CONFIG2, _WRT_OFF & _BOR40V

' DEFINES & INCLUDES
' ================================================== ==============
DEFINE OSC 8

' REGISTERS AND PINOUT ( 1 = IN; 0 = OUT )
' ================================================== ==============
'76543210 '76543210
TRISA = %00000000: PORTA = %00000000
TRISB = %00000000: PORTB = %00000000
TRISC = %00010000: PORTC = %00000000
TRISD = %00000000: PORTD = %00000000
TRISE = %00000000: PORTE = %00000000
ADCON0 = %00000000
ADCON1 = %00000000
ANSEL = %00000000
ANSELH = %00000000
CM1CON0 = %00000000
CM2CON0 = %00000000

SSPSTAT = %00000000 'Configures the SPI Module ( Read DataSheet )
SSPCON = %00110001 'Configures the SPI Module ( Read DataSheet )

' ALIAS & MODIFIERS
' ================================================== ==============
CS VAR PORTC.1 'Pin 1 of the 93C46N - PDIP CASE ( CS )
CLK VAR PORTC.3 'Pin 2 of the 93C46N - PDIP CASE ( SK )
SDI VAR PORTC.4 'Pin 4 of the 93C46N - PDIP CASE ( DO )
SDO VAR PORTC.5 'Pin 3 of the 93C46N - PDIP CASE ( DI )

' VARIABLES & COSTANTS
' ================================================== ==============
ADDRESS VAR BYTE 'Address position to read or write
BT0 VAR BYTE 'Byte 0 to read or write
BT1 VAR BYTE 'Byte 1 to read or write
I VAR BYTE

' DEFINES
' ================================================== ==================
DEFINE LCD_DREG PORTB ' LCD Data bits on PORTB
DEFINE LCD_DBIT 0 ' PORTB starting address
DEFINE LCD_RSREG PORTB ' LCD RS bit on PORTB
DEFINE LCD_RSBIT 4 ' LCD RS bit address
DEFINE LCD_EREG PORTB ' LCD E bit on PORTB
DEFINE LCD_EBIT 5 ' LCD E bit address
DEFINE LCD_BITS 4 ' LCD in 4-bit mode
DEFINE LCD_LINES 2 ' LCD has 2 rows
DEFINE LCD_COMMANDUS 2000 ' Set command delay time in us
DEFINE LCD_DATAUS 50 ' Set data delay time in us

DEFINE DEBUG_REG PORTC
DEFINE DEBUG_BIT 6
DEFINE DEBUG_BAUD 19200
DEFINE DEBUG_MODE 0

' PROGRAM INIT
' ================================================== ==============
'0123456789012345
LCDOUT $FE, 1, " 93C46 EEPROM "
PAUSE 2000
DEBUG "Start", 13,10,13,10

' MAIN LOOP
' ================================================== ==============
MAIN:
FOR I = 0 TO 63
GOSUB READ2BYTES
LCDOUT $FE, 1, "Iteracao: ", DEC I
LCDOUT $FE,$C0,"BT0:", HEX BT0, " - BT1:", HEX BT1
DEBUG "Iteracao: ", DEC I," - ", HEX BT0,HEX BT1,13,10
NEXT
STOP
GOTO MAIN
' SUB - ROTINES
' ================================================== ==============
WRITE2BYTES:
CS=1 'Enable Device
SSPBUF = $1 'Start Bit
SSPBUF = $30 'Command to Write
CS=0 'Disable Device

CS=1 'Select Device
SSPBUF = $1 'Start Bit
WHILE SSPSTAT.0=0:WEND 'Wait for the BF flag to be Set
SSPBUF = $40 | ADDRESS '01000000 Ored with ADDRESS
WHILE SSPSTAT.0=0:WEND 'Wait for the BF flag to be Set
SSPBUF = BT0 'Data 00
WHILE SSPSTAT.0=0:WEND 'Wait for the BF flag to be Set
SSPBUF = BT1 'Data 01
WHILE SSPSTAT.0=0:WEND 'Wait for the BF flag to be Set
CS=0 'Disable Device
PAUSE 5 'Insure that you don't work you the device for 5ms
RETURN

READ2BYTES:
CS=1 'Enable Device
SSPBUF = $1 'Start Bit
WHILE SSPSTAT.0=0:WEND 'Wait for the BF flag to be Set
SSPBUF = $80 | ADDRESS '10000000 Ored with ADDRESS
WHILE SSPSTAT.0=0:WEND 'Wait for the BF flag to be Set
SSPCON.4=0 'Change Signal Clock "DataSheet of the PIC"
SSPBUF = $0 'Send Something
WHILE SSPSTAT.0=0:WEND 'Wait for the BF flag to be Set
BT0=SSPBUF 'Read the SSPBUF to the BT0 Variable
SSPBUF = $0 'Send Something
WHILE SSPSTAT.0=0:WEND 'Wait for the BF flag to be Set
BT1=SSPBUF 'Read the SSPBUF to the BT1 Variable
CS=0 'Disable Device
SSPCON.4=1 'Change the clock to initial state
PAUSE 5 'Insure that you don't work you the device for 5ms
RETURN

ERASEALL:
CS = 1 'Enable Device
SSPBUF = $1 'Start Bit
WHILE SSPSTAT.0=0:WEND 'Wait for the BF flag to be Set
SSPBUF = $20 'Command to Erase ALL
WHILE SSPSTAT.0=0:WEND 'Wait for the BF flag to be Set
CS = 0 'Disable Device
PAUSE 5 'Insure that you don't work you the device for 5ms
RETURN

WRITEALL:
CS = 1 'Enable Device
SSPBUF = $1 'Start Bit
WHILE SSPSTAT.0=0:WEND 'Wait for the BF flag to be Set
SSPBUF = $10 'Command to Erase ALL
WHILE SSPSTAT.0=0:WEND 'Wait for the BF flag to be Set
SSPBUF = BT0 'Data Pattern 00
WHILE SSPSTAT.0=0:WEND 'Wait for the BF flag to be Set
SSPBUF = BT1 'Data Pattern 01
WHILE SSPSTAT.0=0:WEND 'Wait for the BF flag to be Set
CS = 0 'Disable Device
PAUSE 5 'Insure that you don't work you the device for 5ms
RETURN
END







'************************************************* ***************
'* Name : 93C46N EEPROM *
'* Author : [GADELHAS] *
'* Notice : Copyright (c) 2012 *
'* : All Rights Reserved *
'* Date : 08-02-2012 *
'* Version : 1.0 *
'* Notes : *
'* : EASYPICV6 + PIC16F887 + 93C46N - FARCHILD *
'************************************************* ***************
' CONFIGS
' ================================================== ==============
@ __CONFIG _CONFIG1, _HS_OSC & _WDT_OFF & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _BOR_OFF & _DEBUG_OFF & _LVP_OFF & _FCMEN_ON & _IESO_OFF
@ __CONFIG _CONFIG2, _WRT_OFF & _BOR40V

' DEFINES & INCLUDES
' ================================================== ==============
DEFINE OSC 8

' REGISTERS AND PINOUT ( 1 = IN; 0 = OUT )
' ================================================== ==============
'76543210 '76543210
TRISA = %00000000: PORTA = %00000000
TRISB = %00000000: PORTB = %00000000
TRISC = %10101101: PORTC = %00000000
TRISD = %00000000: PORTD = %00000000
TRISE = %00000000: PORTE = %00000000
ADCON0 = %00000000
ADCON1 = %00000000
ANSEL = %00000000
ANSELH = %00000000
CM1CON0 = %00000000
CM2CON0 = %00000000

' ALIAS & MODIFIERS
' ================================================== ==============
CS VAR PORTC.1 'Pin 1 of the 93C46N - PDIP CASE ( CS )
CLK VAR PORTC.3 'Pin 2 of the 93C46N - PDIP CASE ( SK )
SDI VAR PORTC.4 'Pin 4 of the 93C46N - PDIP CASE ( DO )
SDO VAR PORTC.5 'Pin 3 of the 93C46N - PDIP CASE ( DI )

' VARIABLES & COSTANTS
' ================================================== ==============
ADDRESS VAR BYTE 'Address position to read or write
BT0 VAR BYTE 'Byte 0 to read or write
BT1 VAR BYTE 'Byte 1 to read or write
I VAR BYTE

' DEFINES
' ================================================== ==================
DEFINE LCD_DREG PORTB ' LCD Data bits on PORTB
DEFINE LCD_DBIT 0 ' PORTB starting address
DEFINE LCD_RSREG PORTB ' LCD RS bit on PORTB
DEFINE LCD_RSBIT 4 ' LCD RS bit address
DEFINE LCD_EREG PORTB ' LCD E bit on PORTB
DEFINE LCD_EBIT 5 ' LCD E bit address
DEFINE LCD_BITS 4 ' LCD in 4-bit mode
DEFINE LCD_LINES 2 ' LCD has 2 rows
DEFINE LCD_COMMANDUS 2000 ' Set command delay time in us
DEFINE LCD_DATAUS 50 ' Set data delay time in us

DEFINE DEBUG_REG PORTC
DEFINE DEBUG_BIT 6
DEFINE DEBUG_BAUD 19200
DEFINE DEBUG_MODE 0

' PROGRAM INIT
' ================================================== ==============
'0123456789012345
LCDOUT $FE, 1, " 93C46 EEPROM "
PAUSE 2000
DEBUG "Start",13,10,13,10

' MAIN LOOP
' ================================================== ==============
MAIN:
FOR I = 0 TO 63
GOSUB READ2BYTES
LCDOUT $FE, 1, "Iteracao: ", DEC I
LCDOUT $FE,$C0,"BT0:", HEX BT0, " - BT1:", HEX BT1
DEBUG "Iteracao: ", DEC I," - ", HEX BT0,HEX BT1,13,10
NEXT
STOP
GOTO MAIN
' SUB - ROTINES
' ================================================== ==============
WRITE2BYTES:
CS = 1
SHIFTOUT SDO,CLK,1,[%10011,0\4] 'Enable write
PAUSE 5
CS = 0

CS = 1
SHIFTOUT SDO, CLK, 1, [%101\3,ADDRESS\6,BT0,BT1] 'Two bytes at a time
PAUSE 5
CS = 0
RETURN

READ2BYTES:
CS=1
SHIFTOUT SDO,CLK,1,[%110\3,ADDRESS\6]
SHIFTIN SDI,CLK,2,[BT0,BT1] 'Two bytes at a time
PAUSE 5
CS=0
RETURN

ERASEALL:
CS = 1
SHIFTOUT SDO,CLK,1,[%10010,0\4]
PAUSE 5
CS = 0
RETURN

WRITEALL:
CS = 1
SHIFTOUT SDO,CLK,1,[%10001,0\4,BT0,BT1] 'Two bytes data pattern
PAUSE 5
CS = 0
RETURN
END

gadelhas
- 7th July 2015, 00:01
Found another one using I2C



'************************************************* ***************
'* Name : Ext. EEprom.BAS *
'* Author : [GADELHAS] *
'* Notice : Copyright (c) 2011 *
'* : All Rights Reserved *
'* Date : 14-08-2010 *
'* Version : 1.0 *
'* Notes : *
'* : EASYPICV6 + PIC16F887 + LCD 16X2 *
'************************************************* ***************
@__CONFIG _CONFIG1, _HS_OSC & _WDT_OFF & _PWRTE_ON & _MCLRE_ON & _CP_OFF & _BOR_ON & _DEBUG_OFF & _LVP_OFF & _FCMEN_ON & _IESO_OFF
@__CONFIG _CONFIG2, _WRT_OFF & _BOR40V

DEFINE OSC 8
DEFINE I2C_HOLD 1

' VARIÁVEIS
' ================================================== ==================
I var byte 'VARIÁVEL DOS I2C READ AND WRITE
buffer var byte[13]
buffer1 var byte[13]
buffer[0] = "H"
buffer[1] = "u"
buffer[2] = "g"
buffer[3] = "o"
buffer[4] = " "
buffer[5] = "O"
buffer[6] = "l"
buffer[7] = "i"
buffer[8] = "v"
buffer[9] = "e"
buffer[10] = "i"
buffer[11] = "r"
buffer[12] = "a"



' REGISTOS PINOUT 1 = IN; 0 = OUT
' ================================================== ==================
'76543210
TRISA = %00000001
TRISB = %00000000
TRISC = %00000000
TRISD = %00000000
TRISE = %00000000
ADCON0 = 0
ANSEL = 0
ANSELH = 0
CM1CON0= 0
CM2CON0= 0

PORTA = 0
PORTB = 0
PORTC = 0
PORTD = 0
PORTE = 0

' NOMES PINOUT
' ================================================== ==================
LED VAR PORTA.0
SDA var PORTC.4
SCL var PORTC.3

' DEFENIÇÕES
' ================================================== ==================
DEFINE LCD_DREG PORTB ' LCD Data bits on PORTB
DEFINE LCD_DBIT 0 ' PORTB starting address
DEFINE LCD_RSREG PORTB ' LCD RS bit on PORTB
DEFINE LCD_RSBIT 4 ' LCD RS bit address
DEFINE LCD_EREG PORTB ' LCD E bit on PORTB
DEFINE LCD_EBIT 5 ' LCD E bit address
DEFINE LCD_BITS 4 ' LCD in 4-bit mode
DEFINE LCD_LINES 2 ' LCD has 2 rows
DEFINE LCD_COMMANDUS 2000 ' Set command delay time in us
DEFINE LCD_DATAUS 50 ' Set data delay time in us

' INICIO PROGRAMA
' ================================================== ==================
MAIN:
HIGH LED
PAUSE 500
LOW LED
PAUSE 500
HIGH LED
PAUSE 500
LOW LED
PAUSE 500
HIGH LED

'0123456789012345
lcdout $FE, 1, "Teste Ext.EEprom"
lcdout $FE,$C0," Hugo Oliveira"

GOSUB WRITEEEPROM
GOSUB READEEPROM:

lcdout $FE, 1, "Teste Ext.EEprom"
lcdout $FE,$C0, STR buffer1\13

end
' SUB ROTINA - LE EEprom
' ================================================== ==================
READEEPROM:
FOR I = 0 to 12
i2cread sda,scl,$A3, I,[buffer1[I]]
NEXT
RETURN
' SUB ROTINA - ESCREVE EEprom
' ================================================== ==================
WRITEEEPROM:
FOR I = 0 to 12
i2cwrite sda,scl,$A2, I,[buffer[I]]
pause 5
next
RETURN
END

Scampy
- 7th July 2015, 00:11
Thanks for the input Gadelhas,

I'm not 100% sure if it applies to my issue of writing and reading word array variables to the external eprom. I assume the [Buffer[i]] will be a normal byte variable ??

gadelhas
- 7th July 2015, 00:23
Thanks for the input Gadelhas,

I'm not 100% sure if it applies to my issue of writing and reading word array variables to the external eprom. I assume the [Buffer[i]] will be a normal byte variable ??

I can't confirm, but i acutally think that 24c256is not capable of writting 2 bytes in sequence. You can only wirte one byte, or one page of 64bytes in sequence.

What is the vendor? Please confirm this information in the datasheet.