 Experimenting with a 32KB RAM |
Posted - 8/4/2008 9:38:15 PM | The next component I thought I'd experiment with is the RAM. The project is an analogue recorder - a circuit that samples an analogue input periodically and saves it in RAM, and can be configured to play the recorded signal back afterwards.

Yes, it says plating.
A single RAM chip offers 32K with an eight-bit word size. This requires fifteen lines to address it, A0..A14. The PICAXE-28X1 that is to control the circuit does not have enough output pins to be able drive this address bus and a data bus (to transfer values to and from RAM) and a still have enough pins left over to control the various components. To get around this, two octal (eight-bit) latches are used to drive the address lines, A0..A7 from one chip and A8..A14 from another. The inputs to these latches are connected to the data bus (PortC on the PICAXE), and two pins on the PICAXE are set aside to trigger the latch enable pins on either latch.
What this means in practice is that if you wished to change the current address to $1234 you would put $34 on the data bus and trigger the latch that corresponds to the least significant byte of the address, then put $12 on the data bus and trigger the latch that corresponds to the most significant byte of the address.

Any hobbyist can have wire insulation in any color that he wants so long as it is black.
A 10K potentiometer provides the required analogue input and an LED provides the output. The switch on the left is used to change between recording and playback modes. The large chip at the top is the RAM, the two small ones in the middle are the octal latches and the medium one on the right is the PICAXE-28X1.
As only 15 lines are needed to address 32KB, the most significant bit of the address bus is wired to the /WE pin of the RAM chip. This pin determines whether we're writing to (low) or reading from (high) the chip. This effectively means that addresses $0000..$7FFF are used when writing and addresses $8000..$FFFF are used when reading.
The only remaining connections to the RAM chip required are chip enable (/CE) and output enable (/OE). When chip enable is low, the RAM chip can be accessed; when high, it ignores all input. When not in use we therefore make sure that chip enable is high. When output enable is low, the RAM chip puts the value at the current address onto the data bus, so we need to pull this low when reading but make sure it's left high most of the time so that the RAM chip doesn't interfere with other devices trying to put a value on the data bus.
The code for the test program is as follows:
; Pins:
Symbol RamChipDisable = 4
Symbol RamOutputDisable = 5
Symbol AddressLatch0 = 6
Symbol AddressLatch1 = 7
; Registers:
Symbol RamValue = B0
Symbol RamAddress = W1 ; B3:B2
Symbol RamAddressLow = B2
Symbol RamAddressHigh = B3
Symbol RamPointer = W2 ; B5:B4
Symbol RecordingLength = W3 ; B7:B6
Boot:
Let DirsC = $00
High RamChipDisable
High RamOutputDisable
Low AddressLatch0
Low AddressLatch1
Let RamPointer = 0
SetFreq M8
Main:
StartPlaying:
SerTxd ("Started playing: ", #RecordingLength, " bytes", CR, LF)
Let RamPointer = 0
Pause 100
PlayingLoop:
If PortA Pin1 = 1 Then StartRecording
; Read stored value from RAM.
Let RamAddress = RamPointer
GoSub ReadRam
; Set LED brightness to stored value.
Let W4 = RamValue * 4
HPwm PwmSingle, PwmHHHH, %0100, 255, W4
; Increment playback pointer and loop if hit end.
Let RamPointer = RamPointer + 1
If RamPointer = RecordingLength Then
RamPointer = 0
EndIf
; Loop back.
GoTo PlayingLoop
StartRecording:
SerTxd ("Started recording...", CR, LF)
Let RecordingLength = 0
Pause 100
RecordingLoop:
If PortA Pin1 = 0 Then StartPlaying
; Read value from ADC.
ReadAdc 0, RamValue
; Set LED brightness to read value.
Let W4 = RamValue * 4
HPwm PwmSingle, PwmHHHH, %0100, 255, W4
; Store value read from ADC into RAM.
Let RamAddress = RecordingLength
GoSub WriteRam
; Increment record pointer.
Let RecordingLength = RecordingLength + 1
GoTo RecordingLoop
WriteRam:
; Set up address bus:
Let DirsC = $FF
Let RamAddressHigh = RamAddressHigh & %01111111
Let PinsC = RamAddressHigh
High AddressLatch1 : Low AddressLatch1
Let PinsC = RamAddressLow
High AddressLatch0 : Low AddressLatch0
; Set up data bus and write:
Let PinsC = RamValue
Low RamChipDisable
High RamChipDisable
Let DirsC = $00
Return
ReadRam:
; Set up address bus:
Let DirsC = $FF
Let RamAddressHigh = RamAddressHigh | %10000000
Let PinsC = RamAddressHigh
High AddressLatch1 : Low AddressLatch1
Let PinsC = RamAddressLow
High AddressLatch0 : Low AddressLatch0
; Set up data bus and read:
Let DirsC = $00
Low RamOutputDisable
Low RamChipDisable
Let RamValue = Pins
High RamChipDisable
High RamOutputDisable
Return
As before, there's a simple video of the circuit in action.

798KB WMV
| |
Comments
 |  bL0wF1sH
Member since: 8/26/2003 From: Kirkland, WA |
Posted - 8/27/2008 1:16:01 AM | This is so freaking cool it's not even funny. I've wanted to do this from time to time. The real question though is how in the heck do you get started?
| |
|
| S | M | T | W | T | F | S | | | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | | |
OPTIONS
Track this Journal
ARCHIVES
August, 2010
July, 2010
June, 2010
April, 2010
March, 2010
February, 2010
January, 2010
December, 2009
November, 2009
October, 2009
August, 2009
June, 2009
May, 2009
March, 2009
February, 2009
January, 2009
December, 2008
November, 2008
October, 2008
September, 2008
August, 2008
July, 2008
June, 2008
May, 2008
April, 2008
March, 2008
February, 2008
November, 2007
October, 2007
September, 2007
August, 2007
July, 2007
May, 2007
April, 2007
February, 2007
January, 2007
December, 2006
November, 2006
October, 2006
September, 2006
August, 2006
July, 2006
June, 2006
May, 2006
April, 2006
March, 2006
February, 2006
January, 2006
December, 2005
November, 2005
October, 2005
September, 2005
August, 2005
April, 2005
February, 2005
January, 2005
|