copyright, Peter H. Anderson, Baltimore, MD, Feb, '00
Introduction.
This discussion focuses on interfacing an SPI EEPROM with a BX24. I used a Microchip
25LC640 which provides 8K X 8 of memory storage. However, I believe the same code may be
used with larger SPI EEPROMs by Atmel, notably the AT25256 (32K by 8) used by NetMedia in
both the BasicX-01 and the BX-24.
My interest was sparked by a question related to data logging posted to the BasicX Mail list
which required the storing of 16 integers per second for 10 minutes. Thus, the required memory
is 2 bytes * 16 integers * 600 seconds or 19,200 bytes. Thus, the Atmel 25256 will provide
adequate storage. But, this data logging application also requires that the time to store the 32
bytes of data be but a fraction of a second to allow time the collect the data. I found that I was
able to store the 16 integers to EEPROM in about 27 ms total.
In developing this discussion, I began with the simplest exercise of writing and reading a single
byte using four of the BX24's 16 general purpose I/O pins (SPI_EEPROM_1.Bas). In
SPI_EEPROM_2.Bas, the outputting and inputting of each byte was performed using the
ShiftOut() and ShiftIn() commands.
Program SPI_EEPROM_3.Bas expands on this to write and read an array of 16 integers.
Program SPI_EEPROM_1.Bas was then reworked to use the BX24's SPI interface
(SPI_EEPROM_4.Bas). SPI_EEPROM_5.Bas is similarly a rework of SPI_EEPROM_3.Bas
using the SPI interface.
Interfacing using "Bit Bang".
Programs SPI_EEPROM_1.Bas through _3.Bas use four of the general purpose IO pins;
BX24 SPI EEPROM
16 <----- MISO --------------------- SO (term 2)
15 ------ MOSI --------------------> SI (term 5)
14 ------ SPI_CLK -----------------> SCK (term 6)
13 ------ SPI_CS ------------------> /CS (term 1)
Program SPIEEPROM_1.Bas.
In the following program, 256 bytes of data are written, byte by byte, to the first 256 locations in
the external EEPROM.
Note that all sessions begin by bringing CS low and are terminated by bringing it high.
The manufacturer has gone to great lengths to assure no "accidental" writes, particularly on
power up. Thus, in writing data, an 8-bit command, WREN is first sent to enable the write latch.
This latch is then cleared after writing to the EEPROM and thus the sending of the WREN
command must always be performed prior to the writing of data.
In writing data, the CS is brought low and the WRITE command is sent, followed by the 16-bit
address followed by the data. CS is then brought high followed by a 5 ms delay to permit the
EEPROM to burn the data.
Note that the 16-bit address permits addressing of 65,536 locations. Valid addresses for the
25LC640 (8K Bytes) are &H0000 - &H2000.
' SPI_EEPROM_1.Bas
'
' Illustrates an interface with the Microchip 25LC640.
'
' Writes 256 bytes to EEPROM and then reads them byte by byte as
' opposed to the page mode. 8-bit serial output on MOSI and 8-bit
' serial input on MISO uses "bit-bang". In Program SPI_EEPROM_2.Bas,
' ShiftOut() and ShiftIn() were used.
'
' copyright, Peter H. Anderson, Baltimore, MD, Feb, '00
Const SPI_WREN as Byte = bx00000110 ' define EEPROM commands
Const SPI_WRDI as Byte = bx00000100
Const SPI_WRITE as Byte = bx00000010
Const SPI_READ as Byte = bx00000011
Const SPI_CS as Byte = 13 ' define the BX24 pins
Const SPI_CLK as Byte = 14
Const MOSI as Byte = 15
Const MISO as Byte = 16
Sub Main()
Dim Address as Integer, Dat as Byte
Call OpenSerialPort(1, 19200)
For Address = 0 to 255 ' write data, byte by byte to EEPROM
Dat = CByte((Address MOD 10) + 1)
Call SPIEEPROMWrite(Address, Dat)
Next
For Address = 0 to 255 ' read it back and display it
Dat = SPIEEPROMRead(Address)
Call PutB(Dat)
If (((Address+1) MOD 8) <>0) Then ' 8 values to a line
Call PutByte(Asc(" "))
Else
Call NewLine()
End If
Next
End Sub
Sub SPIEEPROMWrite(ByVal Address as Integer, ByVal Dat as Byte)
Dim N as Integer, DataByte as Byte, H as Byte, L as Byte
Call PutPin(SPI_CS, 1)
Call PutPin(SPI_CLK, 0) ' be sure CLK is low
Call PutPin(MOSI, 0)
' set the enable latch
Call PutPin(SPI_CS, 0) ' bring CS low to initiate
Call SPIOut8(SPI_WREN) ' enable write latch
Call PutPin(SPI_CS, 1) ' end of session
' split the address into high and low bytes
H = CByte(Address\256)
L = CByte(Address - (CInt(H)*256))
Call PutPin(SPI_CS, 0) ' initiate session
Call SPIOut8(SPI_WRITE) ' send EEPROM command
Call SPIOut8(H) ' followed by Hi and Lo bytes
Call SPIOut8(L) ' of address
Call SPIOut8(Dat) ' send the data
Call PutPin(SPI_CS, 1) ' end of session
Call Sleep(0.005) ' allow time for the EEPROM to burn
End Sub
Function SPIEEPROMRead(ByVal Address as Integer) as Byte
Dim Val as Byte, H as Byte, L as Byte
Call PutPin(SPI_CS, 0) ' intitiate the session
Call SPIOut8(SPI_READ) ' send the EEPROM command
' split the address into high and low bytes
H = CByte(Address\256)
L = CByte(Address - (CInt(H)*256))
Call SPIOut8(H) ' send the address
Call SPIOut8(L)
Val = SPIIn8() ' read the data
Call PutPin(SPI_CS, 1) ' end of session
SPIEEPROMRead = Val
End Function
Sub SPIOut8(ByVal X as Byte) ' "bit-bang" ser out technique
Dim N as Integer
For N = 1 to 8 ' output the data byte most sign byte first
If((X AND bx10000000) <> 0) Then ' set up MOSI
Call Putpin(MOSI, 1)
Else
Call Putpin(MOSI, 0)
End if
Call PutPin(SPI_CLK, 1) ' and then provide a clock pulse
Call PutPin(SPI_CLK, 0)
X = X * 2 ' next bit in most sign bit position
Next
End Sub
Function SPIIn8() as Byte ' "bit-bang" ser in
Dim Val as Byte, N as Byte
For N = 1 to 8
Call PutPin(SPI_CLK, 1)
Val = (Val * 2) + GetPin(MISO) ' read after bringing clk high
Call PutPin(SPI_CLK, 0)
Next
SPIIn8 = Val
End Function
Program SPI_EEPROM_2.Bas.
This program is exactly the same, except that the sending and receipt of a byte is implemented
using the ShiftOut() and ShiftIn() commands which were introduced in software version 1.45.
The data which was written to the EEPROM was modified slightly so that I could verify I wasn't
reading data which was written using the previous program.
Note that use of the ShiftOut() and ShiftIn() commands provides a substantial speed improvement
as it avoids fetching token after token in the SPIOut8() and SPIIn8() routines presented above.
' SPI_EEPROM_2.Bas
'
' Same as SPI_EEPROM_1.Bas except uses ShiftOut() and ShiftIn()
' commands.
'
' copyright, Peter H. Anderson, Baltimore, MD, Feb, '00
Const SPI_WREN as Byte = bx00000110 ' define the EEPROM commands
Const SPI_WRDI as Byte = bx00000100
Const SPI_WRITE as Byte = bx00000010
Const SPI_READ as Byte = bx00000011
Const SPI_CS as Byte = 13 ' define the pins
Const SPI_CLK as Byte = 14
Const MOSI as Byte = 15
Const MISO as Byte = 16
Sub Main()
Dim Address as Integer, Dat as Byte
Call OpenSerialPort(1, 19200)
For Address = 0 to 255 ' write 256 bytes of data
Dat = CByte((Address MOD 10) + 3) ' byte by byte
Call SPIEEPROMWrite(Address, Dat)
Next
For Address = 0 to 255 ' read back, byte by byte
Dat = SPIEEPROMRead(Address)
Call PutB(Dat) ' 8 bytes to a line
If (((Address+1) MOD 8) <>0) Then
Call PutByte(Asc(" "))
Else
Call NewLine()
End If
Next
End Sub
Sub SPIEEPROMWrite(ByVal Address as Integer, ByVal Dat as Byte)
Dim N as Integer, DataByte as Byte, H as Byte, L as Byte
Call PutPin(SPI_CS, 1)
Call PutPin(SPI_CLK, 0)
Call PutPin(MOSI, 0)
' set the enable latch
Call PutPin(SPI_CS, 0) ' initiate session
Call SPIOut8(SPI_WREN) ' enable write latch
Call PutPin(SPI_CS, 1) ' terminate session
' split the address into high and low bytes
H = CByte(Address\256)
L = CByte(Address - (CInt(H)*256))
Call PutPin(SPI_CS, 0) ' initiate session
Call SPIOut8(SPI_WRITE) ' write command
Call SPIOut8(H) ' address
Call SPIOut8(L)
Call SPIOut8(Dat) ' data
Call PutPin(SPI_CS, 1) ' end of session
Call Sleep(0.005) ' allow data to be burned
End Sub
Function SPIEEPROMRead(ByVal Address as Integer) as Byte
Dim Val as Byte, H as Byte, L as Byte
Call PutPin(SPI_CS, 0) ' initiate the session
Call SPIOut8(SPI_READ) ' read command
' split the address into high and low bytes
H = CByte(Address\256)
L = CByte(Address - (CInt(H)*256))
Call SPIOut8(H) ' send address
Call SPIOut8(L)
Val = SPIIn8() ' read the byte
Call PutPin(SPI_CS, 1) ' end of session
SPIEEPROMRead = Val
End Function
Sub SPIOut8(ByVal X as Byte) ' ser out shift performed
' usingShiftOut()
Call ShiftOut(MOSI, SPI_CLK, 8, X)
End Sub
Function SPIIn8() as Byte ' ser in shift performed using ShiftIn()
Dim Val as Byte
Val = ShiftIn(MISO, SPI_CLK, 8)
SPIIn8 = Val
End Function
Program SPI_EEPROM_3.Bas.
This program illustrates writing and reading multiple bytes to the external SPI EEPROM,
commonly termed the "page mode".
In writing, the write enable latch is first enabled followed by a command consisting of the "write"
command, followed by the two byte address, followed by up to 32 bytes of data. In this mode the
address auto increments for each byte.
Limitations on the page write (and read) are that it is limited to 32 bytes and the address auto
increment is limited to the lower eight bits. Thus, the user must assure the data being written will
not cross a 256 byte page boundary. A sure fire way to avoid this is to write 2, 4, 8. 16 or 32
bytes at a time.
Thus, my original interest was in the storing of 12 integers (24 bytes). To avoid crossing a page
boundary I opted to extend this to 16 integers.
In SPIEEPROMWriteIntArray(), the specified array of integers on size NumInts is saved to
addresses beginning at the specified address. To avoid crossing a page boundary, NumInts must
be 1, 2, 4, 8 or 16.
In SPIEEPROMReadIntArray(), an array of integers of size NumInts is read from addresses
beginning at the specified address.
In this routine, the onboard clock is read before and after writing the 16 integers to determine the
amount of time required to save 16 integers to EEPROM. I found it was about 27 ms.
Program SPI_EEPROM_3.Bas.
' SPI_EEPROM_3.Bas
'
' Illustrates "page" write and read.
'
' Dummies up 16 integers, saves to EEPROM beginning at address 0000.
' Dummies up 16 integers again and saves to EEPROM beginning at
' address 0020. Reads data back into integers and displays to the
' terminal.
'
' copyright, Peter H. Anderson, Baltimore, MD, Feb, '00
Const SPI_WREN as Byte = bx00000110 ' define EEPROM commands
Const SPI_WRDI as Byte = bx00000100
Const SPI_WRITE as Byte = bx00000010
Const SPI_READ as Byte = bx00000011
Const SPI_CS as Byte = 13 ' define pins
Const SPI_CLK as Byte = 14
Const MOSI as Byte = 15
Const MISO as Byte = 16
Sub Main()
Dim Address as Integer, N as Integer
Dim IntArray(1 to 16) as Integer
Dim Tm1 as Single, Tm2 as Single
Call OpenSerialPort(1, 19200)
Call PutTime(0, 0, 0.0) ' initialize on-board clock
For N = 1 to 16
IntArray(N) = N+100
' Make up some data values to store at address &H0000
Next
Tm1 = Timer() ' to determine the time to store 16 integers
Address = &H0000
Call SPIEEPROMWriteIntArray(Address, IntArray, 16)
' write the array
Tm2 = Timer()
Call PutS(Tm2 - Tm1) ' display time to execute. 27 ms
Call NewLine()
For N = 1 to 16
IntArray(N) = N+200
' Make up some data values some data values to store
' at &H0020
Next
Address = &H0000 + 32
Call SPIEEPROMWriteIntArray(Address, IntArray, 16)
' write the array
' Now read the data back and display it
Address = &H0000
Call SPIEEPROMReadIntArray(Address, IntArray, 16)
Call DisplayIntArray(IntArray, 16)
Address = &H0000 + 32
Call SPIEEPROMReadIntArray(Address, IntArray, 16)
Call DisplayIntArray(IntArray, 16)
End Sub
Sub SPIEEPROMWriteIntArray(ByVal Address as Integer, _
ByRef IntArray() as Integer, _
ByVal NumInts as Integer)
' saves array of integers of size NumInts beginning at Address
Dim N as Integer, DataByte as Byte, H as Byte, L as Byte
Call PutPin(SPI_CS, 1)
Call PutPin(SPI_CLK, 0)
Call PutPin(MOSI, 0)
' set the enable latch
Call PutPin(SPI_CS, 0)
Call SPIOut8(SPI_WREN) ' enable write latch
Call PutPin(SPI_CS, 1)
' split the address into high and low bytes
H = CByte(Address\256)
L = CByte(Address - (CInt(H)*256))
Call PutPin(SPI_CS, 0)
Call SPIOut8(SPI_WRITE) ' write command
Call SPIOut8(H) ' followed by address
Call SPIOut8(L)
For N = 1 to NumInts ' Max of 16 Ints
H = CByte(IntArray(N)\256) ' splits integers into bytes
L = CByte(IntArray(N) - (CInt(H)*256))
Call SPIOut8(H) ' write the high byte of the integer
Call SPIOut8(L) ' the low byte
Next
Call PutPin(SPI_CS, 1) ' end of session
Call Sleep(0.005) ' allow some time for EEPROM
End Sub
Sub SPIEEPROMReadIntArray(ByVal Address as Integer, _
ByRef IntArray()as Integer, _
ByVal NumIntegers as Integer)
' reads an array of integers from EEPROM beginning at Address
Dim N as Integer, H as Byte, L as Byte
Call PutPin(SPI_CS, 0) ' initiate the session
Call SPIOut8(SPI_READ) ' read command
' split the address into high and low bytes
H = CByte(Address\256)
L = CByte(Address - (CInt(H)*256))
Call SPIOut8(H) ' address
Call SPIOut8(L)
For N = 1 to NumIntegers ' then fetch bytes, two at a time
H = SPIIn8()
L = SPIIn8()
IntArray(N) = CInt(H) * 256 + CInt(L) ' combine the two bytes
Next
Call PutPin(SPI_CS, 1) ' end of session
End Sub
Sub DisplayIntArray(ByRef IntArray() as Integer, ByVal NumInts as
Integer)
' displays 16 integers, separated by a space
Dim N as Integer
For N = 1 to 16
Call PutI(IntArray(N))
Call PutByte(Asc(" "))
Next
Call NewLine()
End Sub
Sub SPIOut8(ByVal X as Byte) Call ShiftOut(MOSI, SPI_CLK, 8, X) End Sub Function SPIIn8() as Byte Dim Val as Byte Val = ShiftIn(MISO, SPI_CLK, 8) SPIIn8 = Val End Function
Using the BX24 SPI Interface.
Programs SPI_EEPROM_4.Bas and _5.Bas use BX24's SPI capability.
The following wiring arrangement was used;
BX24 SPI EEPROM
Hole 4 <-- MISO ------------------ SO (term 2)
Hole 5 --- MOSI -----------------> SI (term 5)
Hole 3 --- SCK ------------------> SCK (term 6)
Pin 13 ---SPI_EEPROM_CS ---------> /CS (term 1)
The 'holes" refer to the array of seven holes at the top of the BX24. Note that hole 1 is closest to
Pin 24. I found it was an easy matter to solder leads to these points.
In using this SPI bus, all SPI devices including the on-board BX24 EEPROM share MISO, MOSI
and SCK. A specific device is selected by bringing the /CS on that device low.
Note that a pull-up resistor to +5 VDC is required on the general purpose IO pin used for the CS
as the BX24 boots with all general purpose IOs as inputs (high impedance) leaving the /CS on the
external device floating. If the external device becomes active as a result, the MISO of the
external device will conflict with the MISO lead on the internal EEPROM and the BX24 will be
unable to read tokens from the internal EEPROM.
Program SPI_EEPROM_4.Bas.
This program is simply a rework of Programs SPI_EEPROM_1.Bas (and _2.Bas) which uses the
BX24's SPI interface.
Note that an SPI channel is first opened which defines the format of the clocking and the CS pin
to be used in selecting this device;
SPISetupByte = 0 ' most sig bit first, sck normally low, etc Call OpenSPI(1, SPISetupByte, 13)
Prior to writing, the write latch is enabled and this single byte is output.
PutData(1) = SPI_WREN Call SPICmd(1, 1, PutData(1), 0, GetData) ' enable the write latch
The SPI command brings the CS lead low, sends one byte beginning at the address of PutData(1)
and then brings CS high.
The data is then sent by filling an array of contiguous bytes consisting of the write command, the
high and low bytes of the address and finally, the data and executing the SPICmd();
PutData(1) = SPI_WRITE ' split the address into high and low bytes H = CByte(Address\256) ' high byte L = CByte(Address - (CInt(H)*256)) PutData(2) = H PutData(3) = L PutData(4) = Dat Call SPICmd(1, 4, PutData(1), 0, GetData)
In reading data, an array consisting of the read command, the high and low bytes of the address is
filled.
PutData(1) = SPI_READ
' split the address into high and low bytes
H = CByte(Address\256)
L = CByte(Address - (CInt(H)*256))
PutData(2) = H
PutData(3) = L
Call SPICmd(1, 3, PutData(1), 1, GetData)
' send command plus address and then fetch the data
' SPI_EEPROM_4.Bas
'
' Illustrates an interface with the Microchip 25LC640.
'
' This is a rework of SPI_EEPROM_1.Bas which uses the BX24's SPI
' Interface.
'
' Writes 256 bytes to EEPROM and then reads them byte by byte as
' opposed to the page mode.
'
' copyright, Peter H. Anderson, Baltimore, MD, Feb, '00
Const SPI_WREN as Byte = bx00000110 ' define EEPROM commands
Const SPI_WRDI as Byte = bx00000100
Const SPI_WRITE as Byte = bx00000010
Const SPI_READ as Byte = bx00000011
' define SPI Setup Bits
Const SPI_LSB as Byte = &H20 'lsb transmitted first
Const SPI_CPOL as Byte = &H08 'sck is mostly high
Const SPI_CPHA as Byte = &H04 'clock phase, see Atmel docs for timing
Const SPI_SCK4 as Byte = &H00 'clock speed f/4
Const SPI_SCK16 as Byte = &H01 'clock speed f/16
Const SPI_SCK64 as Byte = &H02 'clock speed f/64
Const SPI_SCK128 as Byte = &H03 'clock speed f/128
Const SPI_CS as Byte = 13 ' define the BX24 pins
' Note. Pull up this lead to +5 VDC to assure the external EEPROM is
' not active at the same time as the BX24 on-board SPI EEPROM
Sub Main()
Dim Address as Integer, Dat as Byte, SPISetupByte as Byte
Call OpenSerialPort(1, 19200)
SPISetupByte = 0 ' most sig bit first, sck normally low, etc
Call OpenSPI(1, SPISetupByte, 13)
For Address = 0 to 255 ' write data, byte by byte to EEPROM
Dat = CByte((Address MOD 10) + 1)
Call SPIEEPROMWrite(Address, Dat)
Next
For Address = 0 to 255 ' read it back and display it
Dat = SPIEEPROMRead(Address)
Call PutB(Dat)
If (((Address+1) MOD 8) <>0) Then ' 8 values to a line
Call PutByte(Asc(" "))
Else
Call NewLine()
End If
Next
End Sub
Sub SPIEEPROMWrite(ByVal Address as Integer, ByVal Dat as Byte)
Dim PutData(1 to 3) as Byte, GetData as Byte, H as Byte, L as Byte
PutData(1) = SPI_WREN
Call SPICmd(1, 1, PutData(1), 0, GetData) ' enable the write latch
PutData(1) = SPI_WRITE
' split the address into high and low bytes
H = CByte(Address\256) ' high byte
L = CByte(Address - (CInt(H)*256))
PutData(2) = H
PutData(3) = L
PutData(4) = Dat
Call SPICmd(1, 4, PutData(1), 0, GetData)
Call Sleep(0.005) ' allow time for the EEPROM to burn
End Sub
Function SPIEEPROMRead(ByVal Address as Integer) as Byte
Dim PutData(1 to 3) as Byte, GetData as Byte, H as Byte, L as Byte
PutData(1) = SPI_READ
' split the address into high and low bytes
H = CByte(Address\256)
L = CByte(Address - (CInt(H)*256))
PutData(2) = H
PutData(3) = L
Call SPICmd(1, 3, PutData(1), 1, GetData)
' send command plus address
' and then fetch the data
SPIEEPROMRead = GetData
End Function
Program SPI_EEPROM_5.Bas.
This is a rework of program SPI_EEPROM_3.Bas which writes 16 integers to EEPROM and
later, reads them.
In writing data, an array if filled with the "write" command, the two byte address and the high and
low bytes of each of the 16 integers, a total of 35 bytes. This is output;
Call SPICmd(1, 3+2*CByte(NumInts), PutData(1), 0, GetData)
Note that in this case, NumInts is 16.
In reading data, a three byte array is filled with the "read" command and the high and low bytes of
the address. In executing the SPICmd(), after writing these three bytes, 32 bytes are then read
into array GetData. Each two bytes of this data is then concatenated into and integer.
Call SPICmd(1, 3, PutData(1), 2*CByte(NumIntegers), GetData(1)) ' read 32 bytes
Note that in this case, NumInts is 16.
' SPI_EEPROM_5.Bas
'
' Illustrates "page" write and read using the BX24 SPI Interface.
'
' Dummies up 16 integers, saves to EEPROM beginning at address 0000.
' Dummies up 16 integers again and saves to EEPROM beginning at
' address 0020. Reads data back into integers and displays to the
' terminal.
'
' copyright, Peter H. Anderson, Baltimore, MD, Feb, '00
Const SPI_WREN as Byte = bx00000110 ' define EEPROM commands
Const SPI_WRDI as Byte = bx00000100
Const SPI_WRITE as Byte = bx00000010
Const SPI_READ as Byte = bx00000011
' define SPI Setup Bits
Const SPI_LSB as Byte = &H20 'lsb transmitted first
Const SPI_CPOL as Byte = &H08 'sck is mostly high
Const SPI_CPHA as Byte = &H04 'clock phase, see atmel docs for timing
Const SPI_SCK4 as Byte = &H00 'clock speed f/4
Const SPI_SCK16 as Byte = &H01 'clock speed f/16
Const SPI_SCK64 as Byte = &H02 'clock speed f/64
Const SPI_SCK128 as Byte = &H03 'clock speed f/128
Const SPI_EEPROM_CS as Byte = 13 ' define pin to control EEPROM
Sub Main()
Dim Address as Integer, N as Integer
Dim IntArray(1 to 16) as Integer
Dim Tm1 as Single, Tm2 as Single
Dim SPISetupByte as Byte
SPISetupByte = 0
Call OpenSPI(1, SPISetupByte, SPI_EEPROM_CS) ' open an SPI channel
Call OpenSerialPort(1, 19200)
Call PutTime(0, 0, 0.0)
For N = 1 to 16
IntArray(N) = N+100
' Make up some data values to store at address &H0000
Next
Tm1 = Timer() ' to determine the time to store 16 integers
Address = &H0000
Call SPIEEPROMWriteIntArray(Address, IntArray, 16)
' write the array
Tm2 = Timer()
Call PutS(Tm2 - Tm1) ' display time. 27 ms
Call NewLine()
For N = 1 to 16
IntArray(N) = N+200
' Make up some data values some data values to store
' at &H0020
Next
Address = &H0000 + 32
Call SPIEEPROMWriteIntArray(Address, IntArray, 16)
' write the array
' Now read the data back and display it
Address = &H0000
Call SPIEEPROMReadIntArray(Address, IntArray, 16)
Call DisplayIntArray(IntArray, 16)
Address = &H0000 + 32
Call SPIEEPROMReadIntArray(Address, IntArray, 16)
Call DisplayIntArray(IntArray, 16)
End Sub
Sub SPIEEPROMWriteIntArray(ByVal Address as Integer, _
ByRef IntArray() as Integer, _
ByVal NumInts as Integer)
' saves array of integers of size NumInts beginning at Address
' limited to 16 integers
Dim M as Integer, N as Integer, H as Byte, L as Byte
Dim PutData(1 to 35) as Byte, GetData as Byte
PutData(1) = SPI_WREN
Call SPICmd(1, 1, PutData(1), 0, GetData) ' enable write latch
' split the address into high and low bytes
H = CByte(Address\256)
L = CByte(Address - (CInt(H)*256))
PutData(1) = SPI_WRITE
PutData(2) = H
PutData(3) = L
M = 4 ' array index
For N = 1 to NumInts ' for each integer, separate into bytes
H = CByte(IntArray(N)\256)
L = CByte(IntArray(N) - (CInt(H)*256))
PutData(M) = H
M = M + 1
PutData(M) = L
M = M + 1
Next
Call SPICmd(1, 3+2*CByte(NumInts), PutData(1), 0, GetData)
Call Sleep(0.005) ' allow some time for EEPROM
End Sub
Sub SPIEEPROMReadIntArray(ByVal Address as Integer, _
ByRef IntArray()as Integer, _
ByVal NumIntegers as Integer)
' reads an array of integers from EEPROM beginning at Address
' limited to 16 integers by array GetData
Dim N as Integer, H as Byte, L as Byte
Dim PutData(1 to 3) as Byte, GetData(1 to 32) as Byte
' split the address into high and low bytes
H = CByte(Address\256)
L = CByte(Address - (CInt(H)*256))
PutData(1) = SPI_READ
PutData(2) = H ' high and low bytes of address
PutData(3) = L
Call SPICmd(1, 3, PutData(1), 2*CByte(NumIntegers), GetData(1))
' read 32 bytes
For N = 1 to NumIntegers
H = GetData(2*N - 1)
L = GetData(2*N)
IntArray(N) = CInt(H) * 256 + CInt(L)
Next
End Sub
Sub DisplayIntArray(ByRef IntArray() as Integer, ByVal NumInts as
Integer)
' displays 16 integers, separated by a space
Dim N as Integer
For N = 1 to 16
Call PutI(IntArray(N))
Call PutByte(Asc(" "))
Next
Call NewLine()
End Sub