| Menu | JAQForum Ver 19.10.27 |
Forum Index : Microcontroller and PC projects : Ways to use a 24C32 EEPROM
On the Firmware thread @JanVolk requested information on using the EEPROM on a RTC module. If anyone has code they could share with him perhaps post it here rather than on the Firmware thread. To get it started here are some Subs and Functions I did some time ago. The 24C32 is organized in 32 byte pages. Reading can ignore the page boundaries but writing wont cross a page boundary, instead wrapping back to the start of the page and replacing the original data. These write and read page blocks. Not sure if they will be of any use, but am sure others have better code. Function EEPROM.pageR$(EEPROM.addr As integer, page.no As Integer) ' Read a 32 bit page from a 24Cxx EEPROM to a String (hence R$) 'Usage Variable$ = EEPROM.pageR$(I2C address, page number) I2C OPEN 400, 100, PU I2C Write EEPROM.addr, 0, 2, page.no*32 >> 8, page.no*32 And 255 I2C Read EEPROM.addr, 0, 32, EEPROM.pageR$ End Function Sub EEPROM.pageWS(EEPROM.addr As integer, page.no As Integer, Dat$ As String, Offset As integer, Pad$) ' Write a 32 bit page to a 24Cxx EEPROM from a String (hence WS) ' Usage - EEPROM.pageWS(I2C address, String$to write [, offset from start of page] [,padding character]) ' if specified Pad$ first character fills any remaining space at the end of the page, otherwise leave original data. I2C OPEN 400, 100, PU Local D$ If Offset > 31 Then Offset = 31 D$ = Left$(Dat$,32-Offset) 'prevent wrapping to start of page if too long by truncating data If (Pad$ <> "") And (Len(D$) < (32 - Offset)) Then D$ = D$ + String$(32-Offset-Len(D$), Pad$) 'if data is less than 32 bytes pad remainder with Pad$ - if Pad$ specified, otherwise leave original data. D$ = Chr$((page.no * 32 + Offset) >>8) + Chr$((page.no * 32 + Offset) And 255) + D$ 'prepend 2 pointer bytes to data I2C Write EEPROM.addr, 0, Len(D$), D$ : Pause 5 End Sub Function EEPROM.GetAddr() As integer ' if more than one the last address is returned ' Find the I2C address of a 24Cxx EEPROM I2C OPEN 400, 100, PU Local A For n=80 To 87 'find 24Cxx address I2C read n,0,1,A If Not MM.I2C Then EEPROM.GetAddr = n ' Print "24Cxx I2C address ="; n 'show all the addresses found ' Exit For 'un-REM this if you want the first one EndIf Next End Function Sub EEPROM.pageRA EEPROM.addr, page.no ' Read a 32 bit page from a 24Cxx EEPROM into a global array - DataArray() (hence RA) ' Usage - EEPROM.pageRA I2C address, page number On error skip 'prevent exit if array already exists Dim Integer DataArray(31) 'ensure array exists if not previously created I2C OPEN 400, 100, PU I2C Write EEPROM.addr, 0, 2, page.no*32 >> 8, page.no*32 And 255 I2C Read EEPROM.addr, 0, 32, DataArray() End Sub Sub EEPROM.pageWA EEPROM.addr As integer, page.no As Integer, DataArray%(), Offset As integer, Pad% ' Write a 32 bit page to a 24Cxx EEPROM from an Array (hence WA). ' Usage - EEPROM.pageWA I2C address, Array to write, page.no [, offset = byte no in page.no to start writing] ' [,padding byte] (0 = no padding, use 256 to pad with 0)) - "Array", "page.no" and "offset" are BASE 0 ' if specified Pad% byte fills any remaining space at the end of the page, otherwise leave original data. BASE 0 I2C OPEN 400, 100, PU Local integer DAlength = 0, VE, n, D(33), OutLength If Offset > 31 Then Offset = 31 D(0) = (page.no*32 + Offset) >> 8 : D(1) = (page.no*32 + Offset) And 255 'add pointer bytes For n=0 To 31-offset 'find the length of the data array (- offset to prevent wrap to start of page) On error skip D(n+2) = DataArray%(n) 'and load output array" DAlength = n If Pad% Then If MM.Errno Then D(n+2) = Pad% Else If MM.Errno Then Exit For EndIf Next OutLength = DAlength + 2 If (Pad% > 0) And (DAlength < (32 - Offset)) Then '(0 = no padding, use 256 to pad with 0)) ' if data is less than 32 bytes pad remainder with Pad$ - if Pad% specified, otherwise leave original data. If Pad% > 255 Then Pad% = 0 'ensure only 1 byte OutLength = 34 - offset 'number of bytes to send - 2 pointer bytes + data + padding For n = OutLength To 33 'Add the padding bytes D(n) = Pad% Next EndIf I2C Write EEPROM.addr, 0, OutLength, D() : Pause 5 ' send the data to the EEPROM End Sub Sub Str2Array in$ 'Convert a string to a 32 max. element array - DataArray(max 31) On error skip Erase DataArray() Local n%, L% = Len(in$), addr% If L% > 32 Then L% = 32 Dim integer DataArray(L% - 1) ': Print Len(in$),L% For n% = 1 To L% 'DataArray(n%-1) = Asc(Mid$(in$,n%,1)) ':Print DataArray(n%-1); DataArray(n%-1) = Peek(BYTE Peek(VARADDR in$)+n%) ':Print DataArray(n%-1); Next End Sub Function Array2Str(InArray() As integer) As String 'Convert DataArray() of Bytes to a string, 32 chatacters max. Local n% For n% = 0 To 31 On error skip Array2Str = Array2Str+Chr$(InArray(n%)) If MM.Errno Then n% = 31 Next End Function |
||||||
found my old code, reworked it a little. Can save/restore integer, float and string to/from eeprom. Will check later if I can it make work with structures as well. 24C32-var.zip Gerald |
||||||
Thanks for these programs. As I mentioned before, I need a simple sub to store a number of numbers (22) in an EEPROM and retrieve them later. This is for a backup after a power outage for a climate control system. This process needs to restart with the correct parameters after a reboot, and the program first checks if there is data in the EEPROM. If there is no data in the EEPROM, the program places a standard list in the EEPROM, retrieves this data, and starts processing it. If there is data in the EEPROM, the program processes it. The data is refreshed once a day at a quiet time, such as night. You can also manually perform an update from the program if, for example, you've adjusted control parameters or offsets that you, as the customer, don't need to worry about, but are important for proper configuration. I don't perform a backup for every change due to the limitations of writing to EEPROM or flash memory. This could, of course, also be done with flash memory, but then an update wouldn't erase these values. Alternatively, an SD card can be used as a backup, making it easy for the customer to replace in the event of a defect, with the necessary notifications that the card has been changed. An offset list can be left behind if needed. If you have any other ideas for a solution for this backup, please feel free to post them here. Jan. |
||||||
Jan, if e.g. stat = put_f_eep(test_f, 32) 'store value stat = get_f_eep(test_f, 32) 'retrieve value is simple enough to store/retrieve the FLOAT variable "test_f" in location 32 on eeprom then you should be able to what you want to do with the routines I uploaded. The routines themself are a bit more complicated as the eeproms are a bit complicated as far as writing to them is concerned. The calls for the other dataypes are just the same. Just give it a try And I just saw that the 3rd formal parameter in the call interface (eep_i2c_addr) is not necessary anymore, forgot to remove it when I changed it last time. But you can leave it as it is of course. Gerald |
||||||
| The Back Shed's forum code is written, and hosted, in Australia. |