ADC TLC2543, channel addressing
Hi I am trying to get my TLC2543 analog to digital convert to work with the javelin. I have written a class that extends the AtoD Class. I think I am messing up in the addressing for the channels. The TLC2543 data sheet says that it is an 8 bit serial address. Does anyone know what this means for the read() method? I would appreciate people looking at my code and pointing me in the right direction.
package stamp.peripheral.io.ADC; import stamp.core.*; public class TLC2543 extends AtoD { private int adCH = 0; private int clockPin; private int dataOut; private int dataIn; private int chipSelectPin; private int readSize; private int resolution; final static int bitHigh = 1; final static int bitLow = 14464; public TLC2543(int clockPin, int dataOut, int dataIn, int chipSelectPin){ // update protected variables this.clockPin = clockPin; this.dataOut = dataOut; this.dataIn = dataIn; this.chipSelectPin = chipSelectPin; readSize = 12; resolution = 4096; super.setBitValue(bitHigh,bitLow,0); // initialize chip -- high to low on chip select CPU.writePin(this.chipSelectPin, true); CPU.writePin(this.dataIn,true); CPU.writePin(this.clockPin,true); CPU.writePin(this.dataOut,true); } public void setOffset(int offset) { super.setBitValue(bitHigh,bitLow,offset); } public int read(int command){ int data; switch(command) { case 0: command = read(0); break; case 1: command = read(1); break; case 2: command = read(2); case 3: command = read(3); case 4: command = read(4); case 5: command = read(5); case 6: command = read(6); case 7: command = read(7); case 8: command = read(8); case 9: command = read(9); default: command = read(0); break; } CPU.writePin(this.chipSelectPin,false); // set port CPU.shiftOut(this.dataOut,this.clockPin,5,CPU.SHIFT_MSB, (command << 8/12)); // read the value data = CPU.shiftIn(dataIn,clockPin,readSize,CPU.PRE_CLOCK_MSB); CPU.writePin(chipSelectPin,true); CPU.delay(100); lastRaw = data; super.calcMV(data); return data; } }
Comments
time the address bits are shifted in. This means you should not use consecutive shiftOut
and shiftIn because then you loose databits.
You should manually clock the device so you read in databits and write commandbits
at the same time.
I attached a class for the PS2 gamecontroller that operates likewise.
Important there is the method PSX_TxRx().
· // Transmit psxOut to, and receive psxIn from the
· // PSX controller
· private void PSX_TxRx() {
··· for (idx=0; idx<8; idx++) {
····· CPU.writePin(cmdPin,((psxOut>>>idx)&1)==1); //setup command bit
····· CPU.writePin(clkPin,clockMode); //clock the bit
····· psxIn &= ~(1<<idx);
····· if (CPU.readPin(datPin)) psxIn |= (1<<idx); //get data bit
····· CPU.writePin(clkPin,!clockMode); //release clock
··· }
· }
You should be able to apply that to the TLC2543 by changing it to 12bits.
regards peter
I believe the help I was given earlier in the above post shifts the commands in and out one bit at a type while triggering the clock. If this manually shifting the bits and the triggering the clock is necessary for my chip, could someone help me understand a few lines. I'm getting tripped up on the bit shifting.
and lastly, why would it be necessary to invert the clock?
[noparse][[/noparse]code]
'{PBASIC 2.5}
' ADread subroutine.
' On command, returns 12 bit digital data from one of 11 analog channels.
' The value of ADch from 0 to 10 selects external analog inputs.
' ADch=14 puts the converter into its sleep mode.
' converter has 5 volt reference, connection to the Vdd power supply, for 1.2207 mV per bit
sclk PIN 15 ' clock out from BS2 to AD2543
sdo PIN 14 ' data out from BS2 to AD2543 sdi
sdi PIN 13 ' data in from AD2543 sdo to BS2
ADcs PIN 12 ' AD2543 chip select, active low
ADch VAR Nib ' selects AD external channel 0-10
result VAR Word ' result, 12 bit A/D conversion
demo: ' to show off the subroutine below.
DIRS=$FFFF ' makes all Stamp pins outputs to start
OUTS=$1000 ' makes all pins except ADC chip select low to start
DO
GOSUB ADwake ' makes a dummy conversion to initialize converter
FOR ADch =0 TO 10 ' specify one of 11 input channels
GOSUB ADread ' get millivolt data from that channel
result = 14464 ** result + result ' convert count to millivolts.
DEBUG DEC ADch,": ",DEC result,REP 32\5,cr ' display, use extra spaces to clear garbage
NEXT
GOSUB ADsleep
NAP 7
DEBUG home ' repeat the demo
LOOP
ADread: ' entry point to give result as count from 0 to 4095
LOW ADcs ' select chip
SHIFTOUT sdo,sclk,msbfirst,[noparse][[/noparse]ADch<<8\12] ' mode, left justify ADch
SHIFTIN sdi,sclk,msbpre,[noparse][[/noparse]result\12] ' get result, 12 bits
HIGH ADcs ' deselect chip
RETURN
ADsleep: ' entry point to put TLC2543 to sleep
LOW ADcs ' select chip
SHIFTOUT sdo,sclk,msbfirst,[noparse][[/noparse]$e\4] ' command=$e
HIGH ADcs ' deselect chip
LOW sdi ' keep this pin from floating in sleep
RETURN
ADwake:
ADch=$b
GOTO ADread
www.emesystems.com/OL2tlc2543.htm
TLC542_Read:
reading = $00
LOW CS
OUTPUT SIGL
SHIFTOUT SigL,Clk, MSBFIRST,[noparse][[/noparse]Addr\4,0\4]: LOW SIGL
INPUT SIGL
PAUSE 1
SHIFTIN SigL, Clk, MSBPOST,[noparse][[/noparse]readings(addr)\8]
HIGH CS
RETURN
Notice that shiftout uses MSBFIRST and shiftin uses MSBPOST.
Here is a video of showing the TLC542 beisng used to read 10 infared sensors.
http://www.bjhamltn.com/videos/ACD_AppModDemo.wmv
Also the code written for the TLC2543 shifts out with MSBFIRST and in with "MSBPRE".