I have a data-logging application where I collect ASCII-formatted data, stuff it into an outboard SPI memory, and then transfer it to a PC on-demand. By formatting the data with a stopbit/startbit preamble when I write it to the memory, I can drive the RS232 RX line of the PC directly from the SPI memory data out and get much higher data rates than I could otherwise achieve with a PICAXE-08M.
Here's a diagram of how the PICAXE interfaces to the SPI memory:
Here's the code associated with writing the memory...
And here's how I read it out (note that a "setfreq m8" is assumed in the pwmout and pause statements)...
How do I get data into the PICAXE-08M to begin with? Well, IN3 and SEROUT/OUT0 are not used in the above circuit diagram, so those are available for interfacing with an external data source. Also, IN1/OUT1 and IN2/OUT2 can also be used when the SPI memory is not being written or read because it will ignore the SCK and SI inputs so long as /CS is held high.
Enjoy!
Here's a diagram of how the PICAXE interfaces to the SPI memory:
Code:
+----------------+ VDD +---------------+
| PICAXE-08M | -+- |RAMTRON FM25640|
| | | 3| |
| | +--+/WP |
| | | 7| |
| | +--+/HOLD |
| |6 5| |2
| IN1/OUT1+--------+SI SO+-+->RS232RX
| |5 6| | |
| IN2/OUT2+--------+SCK | /
| |2 1| | \ 10k
| IN4/OUT4+--------+/CS | /
| | | | |
+----------------+ +---------------+ V
Code:
writetospi:
' Kick off a WRITE operation
low 1 ' Idle SPI SI
low 2 ' Idle SPI CLK
low 4 ' Assert SPI /CS low
b1 = 0x06 ' WREN opcode
gosub spiout
low 1 ' Idle SPI SI
pulsout 4, 1 ' Strobe /CS
b1 = 0x02 ' WRITE opcode
gosub spiout
w0 = w2 ' Next avail address is in w2
gosub spiout
gosub spiout
' Loop over contents of buffer
for b9 = 80 to b10
' Fetch a byte from buffer
peek b9, b0
' Writing an RS232-compatible bitstream here, so:
' 1) Invert the data
' 2) Shift the data LSB-first
' 3) Prepend a stopbit(0)/startbit(1) preamble
b1 = b0 NOR 0 ' b1 = NOT(b0 OR 0) = NOT(b0)
b0 = 0x80 ' Preamble
' Shift out 16bits
for b2 = 0 to 15
pin1 = bit0 ' Set SPI SI TO LSB
pulsout 2, 1 ' Strobe SPI CLK
w0 = w0 / 2 ' Shift data right
next b2
' Increment the SPI addr pointer
' (remember that we're writing 2 bytes to the memory
' for every byte of data in the buffer)
w2 = w2 + 2
next b9
low 1 ' Idle SPI SI
high 4 ' De-assert SPI /CS high
return
' This subroutine simply bangs out the 8 bits stored in b1, MSB first
' To transmit the entire contents of w0, just call it twice in a row
' outpin2 is clk
' outpin1 is data
' Note that this routine will corrupt the contents of b0 and b1
spiout: for b2 = 0 to 7
pin1 = bit15 ' Set the output pin
pulsout 2, 1 ' Strobe clock low then high
w0 = w0 * 2 ' Shift data left
next b2
return
Code:
readfromspi:
' Initialize a READ starting @ address 0
low 1 ' Idle SPI SI
low 2 ' Idle SPI CLK
low 4 ' Assert SPI /CS low
b1 = 0x03 ' READ opcode
gosub spiout
w0 = 0 ' Address = 0
gosub spiout
gosub spiout
' Blast the data to the PC
pwmout 2, 51, 104 ' Fire up the SPICLK @ 38400Hz
pause 3413 ' 2 * 1000 * 8192 * 8 / 38400
pwmout 2, 0, 0 ' Shut down SPICLK
low 1 ' Idle SPI SI
high 4 ' De-assert SPI /CS high
return
Enjoy!