What am i doing wrong with my code?
I am trying to read the data from an ADS8341 16 bit 4 channel A/D convertor using internal clock mode.
The data sheet states that to read from channel 1 using internal clock mode i need to send out a 8 bits 11010110
here is my code
the data sheet can be found at www.chipcatalog.com/Datasheet/2838D5B2E81B44E3DC343E2C4AAB9B9A.htm
The data sheet states that to read from channel 1 using internal clock mode i need to send out a 8 bits 11010110
here is my code
CON
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
CS = 13 'Propeller Pin
Din = 14 'Propeller Pin
Dout = 15 'Propeller Pin use a resistor on this pin
Clk = 12 'Propeller Pin
OBJ
SER[noparse][[/noparse] 3 ] : "FullDuplexSerial"
pub start
ser[noparse][[/noparse] 0 ].start(31, 30, 0, 9600) 'Sets up Com port (Rxpin,Txpin,mode,baud)
ser[noparse][[/noparse] 1 ].start(15, 14, 0, 9600) 'Set up com from IC
dira[noparse][[/noparse]CS]~~ 'sets pin as output
repeat
outa[noparse][[/noparse]CS]~~ 'sets pin 7 high
outa[noparse][[/noparse]CS]~ 'sets pin 7 low activating the ADS8341
ser[noparse][[/noparse] 1 ].str(string("%11010110"))
waitcnt (1_000_000 * 50 + cnt )
outa[noparse][[/noparse]CS]~~ 'sets pin 7 high
outa[noparse][[/noparse]CS]~ 'sets pin 7 low activating the ADS8341
waitcnt (1_000_000 * 50 + cnt )
ser[noparse][[/noparse] 0 ].str(ser[noparse][[/noparse] 1 ].rx)
ser.tx(13) 'line feed
ser.tx(10)
the data sheet can be found at www.chipcatalog.com/Datasheet/2838D5B2E81B44E3DC343E2C4AAB9B9A.htm

Comments
Nick
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Never use force, just go for a bigger hammer!
The DIY Digital-Readout for mills, lathes etc.:
YADRO
Hum ! ill take another look
So lets make a list of the key points listed in the datasheet:
The above specifications mean that you should be using a SPI object, not FullDuplexSerial. SPI_Engine is a good choice, and so is BS2 Functions. I would highly recommend you use the internal clock for ADC conversion clock since external clocking will likely cause you more problems (like minimum 24kHz clock, etc).
Your posted code also has a few fundamental flaws that would prevent it from working even if you got the ADC communication working perfectly. To send a binary number, you would use ser.tx(%11010110) and not ser.str(...). To echo the received data to another FullDuplexSerial object, you would need a repeat block and ser1.tx(ser2.rx).
So try rewriting your code using SPI Engine and make sure you look at the clocking/data requirements for the chip. The information about when to read the data with regards to the clock rising/falling edge is extremely important.
{{ ADS0831 4 channel 16 bit a/d *********************************************************************** M.J.A 3/11/08 *********************************************************************** ADS8341 ┌───────────────┐ ─┤1 +vcc DCLK 16├─ Pin 12 on propeller ─┤2 Ch0 CS 15├─ Pin 13 on propeller ─┤3 Ch1 DIN 14├─ Pin 14 on propeller ─┤4 Ch2 BUSY 13├─ ─┤5 Ch3 DOUT 12├─ Pin 15 on propeller with a 1KOhm resistor in series ─┤6 Com GND 11├─ ─┤7 Ch2 GND 10├─ ─┤8 Vref +Vcc 9 ├─ └───────────────┘ Notes }} CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 CS = 13 Din = 14 Dout = 15 Dclk = 12 Bits = 8 Mode = 0 Value = %11010110 'Data out to select 1 of 4 channels on the A/D Rbits = 16 '16bits of data receivable OBJ Shift :"SPI engine" SER :"Fullduplexserial" pub start | TEMP_data SER.start(31, 30, 0, 9600) 'Sets up Com port for computer (Rxpin,TXpin,mode,baud) dira[noparse][[/noparse]CS]~~ 'sets pin as output repeat Shift.start outa[noparse][[/noparse]CS]~~ 'sets pin 7 high outa[noparse][[/noparse]CS]~ 'sets pin 7 low activating the ADS0831 Shift.SHIFTOUT(Din, Dclk, Mode, Bits, Value) Shift.Stop outa[noparse][[/noparse]CS]~~ 'sets pin 7 high outa[noparse][[/noparse]CS]~ 'sets pin 7 low activating the ADS0831 shift.SHIFTIN(Dout, Dclk, Mode, RBits) result := TEMP_data Shift.Stop outa[noparse][[/noparse]CS]~~ 'sets pin 7 high ser.tx(10) 'line feed ser.tx(13) 'carriage return waitcnt (1_000_000 * 50 + cnt ) ser.str(string("Results = ")) ser.dec(TEMP_data) 'display decimal value of lm34temp ser.str(string("binary value is ")) ser.bin(TEMP_data,16) 'display binary value of lm34temp ser.tx(13) 'line feed ser.tx(10) 'carriage returnI need to know what the following is for
What does "mode" do? and "Value"?
Can some one explain to me if i am approaching this correctly?
your "SPI Engine" object, wherever that came from.
Looks like you're on the right track though.
Here is the object i am using
{{ Notes: Consecutive SHIFTIN/SHIFTOUT updates through Spin at 80 MHz is about 14kHz (Bit rate about 112k) Consecutive SHIFTIN/SHIFTOUT updates through Assembly at 80 MHz is about 310kHz (Bit rate about 2.5M) }} { ******************************************** SPI Engine V1.1 ******************************************** coded by Beau Schwabe (Parallax) ******************************************** Revision History: V1.0 - original program V1.1 - fixed problem with SHIFTOUT MSBFIRST option - fixed argument allocation in the SPI Engines main loop } CON #1,_SHIFTOUT,_SHIFTIN VAR long cog, command, Flag PUB SHIFTOUT(Dpin, Cpin, Mode, Bits, Value) 'Once called from Spin, SHIFTOUT remains running in its own COG. if Flag == 0 'If SHIFTOUT is called with 'Bits' set to Zero, then the COG will shut start 'down. Another way to shut the COG down is to call 'stop' from Spin. setcommand(_SHIFTOUT, @Dpin) PUB SHIFTIN(Dpin, Cpin, Mode, Bits)|Value 'Once called from Spin, SHIFTIN remains running in its own COG. if Flag == 0 'If SHIFTIN is called with 'Bits' set to Zero, then the COG will shut start 'down. Another way to shut the COG down is to call 'stop' from Spin. setcommand(_SHIFTIN, @Dpin) result := Value '------------------------------------------------------------------------------------------------------------------------------ PUB start : okay '' Start SPI Engine - starts a cog '' returns false if no cog available stop Flag := 1 okay := cog := cognew(@loop, @command) + 1 PUB stop '' Stop SPI Engine - frees a cog Flag := 0 if cog cogstop(cog~ - 1) command~ PRI setcommand(cmd, argptr) command := cmd << 16 + argptr 'write command and pointer repeat while command 'wait for command to be cleared, signifying receipt '################################################################################################################ DAT org ' ' SPI Engine - main loop ' loop rdlong t1,par wz 'wait for command if_z jmp #loop movd :arg,#arg0 'get 5 arguments ; arg0 to arg4 mov t2,t1 ' │ mov t3,#5 '───┘ :arg rdlong arg0,t2 add :arg,d0 add t2,#4 djnz t3,#:arg mov address,t1 'preserve address location for passing 'variables back to Spin language. wrlong zero,par 'zero command to signify command received ror t1,#16+2 'lookup command address add t1,#jumps movs :table,t1 rol t1,#2 shl t1,#3 :table mov t2,0 shr t2,t1 and t2,#$FF jmp t2 'jump to command jumps byte 0 '0 byte SHIFTOUT_ '1 byte SHIFTIN_ '2 byte NotUsed_ '3 NotUsed_ jmp #loop '################################################################################################################ SHIFTOUT_ 'SHIFTOUT Entry mov t4, arg3 wz ' Load number of data bits if_z jmp #Done ' '0' number of Bits = Done mov t1, #1 wz ' Configure DataPin shl t1, arg0 muxz outa, t1 ' PreSet DataPin LOW muxnz dira, t1 ' Set DataPin to an OUTPUT mov t2, #1 wz ' Configure ClockPin shl t2, arg1 muxz outa, t2 ' PreSet ClockPin LOW muxnz dira, t2 ' Set ClockPin to an OUTPUT sub LSBFIRST, arg2 wz,nr ' Detect LSBFIRST mode for SHIFTOUT if_z jmp #LSBFIRST_ sub MSBFIRST, arg2 wz,nr ' Detect MSBFIRST mode for SHIFTOUT if_z jmp #MSBFIRST_ jmp #loop ' Go wait for next command '------------------------------------------------------------------------------------------------------------------------------ SHIFTIN_ 'SHIFTIN Entry mov t4, arg3 wz ' Load number of data bits if_z jmp #Done ' '0' number of Bits = Done mov t1, #1 wz ' Configure DataPin shl t1, arg0 muxz dira, t1 ' Set DataPin to an INPUT mov t2, #1 wz ' Configure ClockPin shl t2, arg1 muxz outa, t2 ' PreSet ClockPin LOW muxnz dira, t2 ' Set ClockPin to an OUTPUT sub MSBPRE, arg2 wz,nr ' Detect MSBPRE mode for SHIFTIN if_z jmp #MSBPRE_ sub LSBPRE, arg2 wz,nr ' Detect LSBPRE mode for SHIFTIN if_z jmp #LSBPRE_ sub MSBPOST, arg2 wz,nr ' Detect MSBPOST mode for SHIFTIN if_z jmp #MSBPOST_ sub LSBPOST, arg2 wz,nr ' Detect LSBPOST mode for SHIFTIN if_z jmp #LSBPOST_ jmp #loop ' Go wait for next command '------------------------------------------------------------------------------------------------------------------------------ MSBPRE_ ' Receive Data MSBPRE MSBPRE_Sin test t1, ina wc ' Read Data Bit into 'C' flag rcl t3, #1 ' rotate "C" flag into return value call #Clock ' Send clock pulse djnz t4, #MSBPRE_Sin ' Decrement t4 ; jump if not Zero jmp #Update_SHIFTIN ' Pass received data to SHIFTIN receive variable '------------------------------------------------------------------------------------------------------------------------------ LSBPRE_ ' Receive Data LSBPRE LSBPRE_Sin test t1, ina wc ' Read Data Bit into 'C' flag rcr t3, #1 ' rotate "C" flag into return value call #Clock ' Send clock pulse djnz t4, #LSBPRE_Sin ' Decrement t4 ; jump if not Zero mov t4, #32 ' For LSB shift data right 32 - #Bits when done sub t4, arg3 shr t3, t4 jmp #Update_SHIFTIN ' Pass received data to SHIFTIN receive variable '------------------------------------------------------------------------------------------------------------------------------ MSBPOST_ ' Receive Data MSBPOST MSBPOST_Sin call #Clock ' Send clock pulse test t1, ina wc ' Read Data Bit into 'C' flag rcl t3, #1 ' rotate "C" flag into return value djnz t4, #MSBPOST_Sin ' Decrement t4 ; jump if not Zero jmp #Update_SHIFTIN ' Pass received data to SHIFTIN receive variable '------------------------------------------------------------------------------------------------------------------------------ LSBPOST_ ' Receive Data LSBPOST LSBPOST_Sin call #Clock ' Send clock pulse test t1, ina wc ' Read Data Bit into 'C' flag rcr t3, #1 ' rotate "C" flag into return value djnz t4, #LSBPOST_Sin ' Decrement t4 ; jump if not Zero mov t4, #32 ' For LSB shift data right 32 - #Bits when done sub t4, arg3 shr t3, t4 jmp #Update_SHIFTIN ' Pass received data to SHIFTIN receive variable '------------------------------------------------------------------------------------------------------------------------------ LSBFIRST_ ' Send Data LSBFIRST mov t3, arg4 ' Load t3 with DataValue LSB_Sout test t3, #1 wc ' Test LSB of DataValue muxc outa, t1 ' Set DataBit HIGH or LOW shr t3, #1 ' Prepare for next DataBit call #Clock ' Send clock pulse djnz t4, #LSB_Sout ' Decrement t4 ; jump if not Zero mov t3, #0 wz ' Force DataBit LOW muxnz outa, t1 jmp #loop ' Go wait for next command '------------------------------------------------------------------------------------------------------------------------------ MSBFIRST_ ' Send Data MSBFIRST mov t3, arg4 ' Load t3 with DataValue mov t5, #%1 ' Create MSB mask ; load t5 with "1" shl t5, arg3 ' Shift "1" N number of bits to the left. shr t5, #1 ' Shifting the number of bits left actually puts ' us one more place to the left than we want. To ' compensate we'll shift one position right. MSB_Sout test t3, t5 wc ' Test MSB of DataValue muxc outa, t1 ' Set DataBit HIGH or LOW shr t5, #1 ' Prepare for next DataBit call #Clock ' Send clock pulse djnz t4, #MSB_Sout ' Decrement t4 ; jump if not Zero mov t3, #0 wz ' Force DataBit LOW muxnz outa, t1 jmp #loop ' Go wait for next command '------------------------------------------------------------------------------------------------------------------------------ Update_SHIFTIN mov t1, address ' Write data back to Arg4 add t1, #16 ' Arg0 = #0 ; Arg1 = #4 ; Arg2 = #8 ; Arg3 = #12 ; Arg4 = #16 wrlong t3, t1 jmp #loop ' Go wait for next command '------------------------------------------------------------------------------------------------------------------------------ Clock mov t2, #0 wz,nr ' Clock Pin muxz outa, t2 ' Set ClockPin HIGH muxnz outa, t2 ' Set ClockPin LOW Clock_ret ret ' return '------------------------------------------------------------------------------------------------------------------------------ Done ' Shut COG down mov t2, #0 ' Preset temp variable to Zero mov t1, par ' Read the address of the first perimeter add t1, #4 ' Add offset for the second perimeter ; The 'Flag' variable wrlong t2, t1 ' Reset the 'Flag' variable to Zero CogID t1 ' Read CogID COGSTOP t1 ' Stop this Cog! '------------------------------------------------------------------------------------------------------------------------------ { ########################### Defined data ########################### } zero long 0 'constants d0 long $200 MSBPRE long $0 ' Applies to SHIFTIN LSBPRE long $1 ' Applies to SHIFTIN MSBPOST long $2 ' Applies to SHIFTIN LSBPOST long $3 ' Applies to SHIFTIN LSBFIRST long $4 ' Applies to SHIFTOUT MSBFIRST long $5 ' Applies to SHIFTOUT { ########################### Undefined data ########################### } 'temp variables t1 res 1 ' Used for DataPin mask and COG shutdown t2 res 1 ' Used for CLockPin mask and COG shutdown t3 res 1 ' Used to hold DataValue SHIFTIN/SHIFTOUT t4 res 1 ' Used to hold # of Bits t5 res 1 ' Used for temporary data mask address res 1 ' Used to hold return address of first Argument passed arg0 res 1 'arguments passed to/from high-level Spin arg1 res 1 arg2 res 1 arg3 res 1 arg4 res 1Let me know what you think it is as i eagerly wait
There may be a reason that this code was not implemented into the object exchange... I only had a chance to do limited testing with a few shiftin/shiftout IC's (74HC165, and 74HC595).
It's probably just too fast for some other IC's and needs to be slowed down a bit, but I don't know that for sure.· Where I would slow it down would be in this section of code...
'------------------------------------------------------------------------------------------------------------------------------ Clock mov t2, #0 wz,nr ' Clock Pin muxz outa, t2 ' Set ClockPin HIGH muxnz outa, t2 ' Set ClockPin LOW Clock_ret ret ' return '------------------------------------------------------------------------------------------------------------------------------... by inserting NOP or delays in-between where the clock goes HIGH or LOW.
Alternatively you could try the BS2_Function library and use the SHIFTIN/SHIFTOUT routines there.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Beau Schwabe
IC Layout Engineer
Parallax, Inc.
I posted the "New" code for any one that needs to use it on a ADS8341E 16bit 4 channel A to D converter
{ ************************************************************************************************************ * Michael A. 3/11/2008 ************************************************************************************************************ } {{ TESTING UNIT Ver 2.50 }} CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 AD_CS = 13 'AD Chip Select AD_Din = 14 'AD Data IN AD_Dout = 15 'AD Data out AD_Dclk = 12 'AD clock esc = $1B 'Escape code cr = $0D 'Carriage Return code lf = $0A 'Line Feed code eos = $FF 'End of string code eog = $FF 'End of graphics code space = $20 'Space character code VAR Long X long T OBJ LCD : "LCDFINAL22" BASIC : "BS2_Functions" PUB MAIN dira[noparse][[/noparse]AD_CS]~~ 'sets pin as output LCD.init 'Initialize the display LCD.Cls 'Clear the Display waitcnt (1_000_000 * 50 + cnt ) AD_DATA 'Call AD_Data Method Pub AD_DATA | R , Channel_One Channel_One := %11010111 'Allows me to read CH1 BASIC.Start(31,30) 'Turn on Basic Object repeat t := 0 'Set to 0 used for avg. X := 0 'Set to 0 used for avg outa[noparse][[/noparse]AD_CS]~~ 'Chip Select high "OFF" repeat R from 0 to 99 'my loop for getting an average AtoD number outa[noparse][[/noparse]AD_CS]~ 'Chip Select low "ON" waitcnt (500_000 + cnt ) 'Pause a bit not sure if i need this Basic.SHIFTOUT(AD_Din,AD_DClk,Channel_One,BASIC#MSBFIRST,8) waitcnt (500_000 + cnt ) 'Again Pause X := BASIC.SHIFTIN(AD_Dout,AD_DCLK,BASIC#MSBPOST,16) outa[noparse][[/noparse]AD_CS]~~ 'Chip Select High "OFF" T := T + X 'ADD up and repeat T := T / 100 'Now take an average lcd.home 'Set up Display 2X20 LCD.str(string("Data = ")) 'Display Data = LCD.dec(T) 'Display a dec number avg.Again thanks people. . .