Help with ADC0838
GaryT
Posts: 11
Has anybody used the the "ADC0838 to debug" object from the object library? I modified it a bit to work on the Demo board and send output to TV. But I don't understand how to use the SE pin, the Object doesn't seem to use it, but I can't get it to work either.
Any help is greatly appreciated.
Thanks,
Gary
Any help is greatly appreciated.
Thanks,
Gary
Comments
Thanks again,
Gary
Thanks for any ideas,
Gary
'********************************
'* ADC 0838 Channel TVOut *
'********************************
'code compiled and revised by Bryan Kobe June, 2007
'revised for demo Board Gary T. Nov, 2008.
'This code is used for addressing and accessing all 8 channels on the ADC 0838
'It will address and TVOut all 8 channels, returning the value 0-255.
{{
ADC0838
│ Vcc(+5V)
┌───────────────┐ │
───┤1 ch0 VCC 20 ├───┤
─┤2 ch1 V+ 19 ├─ nc
─┤3 ch2 CS 18 ├──── pin3
─┤4 ch3 DI 17 ├──── pin2
─│5 ch4 CLK 16 ├─── pin1
─│6 ch5 SARS15 ├── pin4
─│7 ch6 DO 14 ├── pin0
─│8 ch7 SE 13 ├─ nc
┌─┤9 com VREf12 ├────── +5vdc
├─┤10 dgnd agnd11 ├─┐
│ └───────────────┘ │
└───────────────────┫
gnd
}}
CON
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
{{ AD0 = %11000
AD1 = %11100 ' Note: See Datasheet MUX Addressing for more details
AD2 = %11001 ' Bit 4 = Start Bit, Bit 3 = SGL/DIF, Bit 2 = ODD/SIGN, Bit 1 = SELECT 1, Bit 0 = SELECT 0
AD3 = %11101
AD4 = %11010
AD5 = %11110
AD6 = %11011
AD7 = %11111}}
'AD0 = %11000
AD0 = %00011
AD1 = %00111
AD2 = %10011
AD3 = %10111 ' Note: See Datasheet MUX Addressing for more details
AD4 = %01011 'Bit 5 = 1, Bit 4 = Start Bit, Bit 3 = SGL/DIF, Bit 2 = ODD/SIGN, Bit 1 = SELECT 1, Bit 0 = SELECT 0
AD5 = %01111
AD6 = %11011
AD7 = %11111
' pin configuration
clk = 1
cs = 3
dataout = 0
datain = 2
sars = 4
OBJ
TVOut : "TV_Terminal"
num : "Numbers"
VAR
byte ADC ' Analog to Digital Channel Din Value. Set using CON values.
long datar ' 8 Bit return value from conversion
Word Addr
PUB main
dira[noparse][[/noparse]cs]~~ 'set Chip Select to output
outa[noparse][[/noparse]cs] := 1 'set Chip Select High
waitcnt(50_000_000 + cnt)
dira[noparse][[/noparse]clk]~~ 'set clk pin to output
outa[noparse][[/noparse]clk]:=1 'set clock pin low
waitcnt(50_000_000 + cnt)
dira[noparse][[/noparse]dataout]~ 'set data in pin to an input
dira[noparse][[/noparse]datain]~~ 'set data out pin to an output
'start the tv terminal
TVOut.start(12)
TVOut.out(2)
repeat
'GetADC(0)', Num#dec)
TVOut.str(string("Ch0="))
TVOut.str(num.ToStr(GetADC(0), Num#dec))
tvout.out(13)
'waitcnt(50_000000 + cnt)
TVOut.str(string("Ch1="))
TVOut.str(num.ToStr(GetADC(1), Num#dec))
tvout.out(13)
TVOut.str(string("Ch2="))
TVOut.str(num.ToStr(GetADC(2), Num#dec))
tvout.out(13)
TVOut.str(string("Ch3="))
TVOut.str(num.ToStr(GetADC(3), Num#dec))
tvout.out(13)
TVOut.str(string("Ch4="))
TVOut.str(num.ToStr(GetADC(4), Num#dec))
tvout.out(13)
TVOut.str(string("Ch5="))
TVOut.str(num.ToStr(GetADC(5), Num#dec))
tvout.out(13)
TVOut.str(string("Ch6 ="))
TVOut.str(num.ToStr(GetADC(6), Num#dec))
tvout.out(13)
TVOut.str(string("Ch7="))
TVOut.str(num.ToStr(GetADC(7), Num#dec))
tvout.out(13)
waitcnt(5_000_0000 + cnt)
PRI GetADC( chan ) : value
if (chan == 0)
ADC := AD0
if (chan == 1)
ADC := AD1
if (chan == 2)
ADC := AD2
if (chan == 3)
ADC := AD3
if (chan == 4)
ADC := AD4
if (chan == 5)
ADC := AD5
if (chan == 6)
ADC := AD6
if (chan == 7)
ADC := AD7
datar := write(ADC) 'write MUX Address to start conversion for ADC channel and set result to the datar value
return datar
PRI write( cmd ) : datar_val | i
outa[noparse][[/noparse]cs] := 0 ' set Chip Select Low
writeByte( cmd ) ' Write the command to start conversion for X port
repeat while (ina[noparse][[/noparse]sars] == 1) ' SARS goes LOW when sending LSB First Dout on ADC0838 (See Datasheet)
outa[noparse][[/noparse]clk] := 1 ' toggle sclk pin High (add delay here if clock is too fast) (clue: check duty cycle)
waitcnt(5000 + cnt)
outa[noparse][[/noparse]clk] := 0 ' toggle sclk pin Low
waitcnt(5000 + cnt)
' Ok now get the Conversion for this channel
repeat i from 0 to 7 ' read 8 bits
if ina[noparse][[/noparse]dataout] == 1
datar |= |< i ' set bit i HIGH
else
datar &= !|< i ' set bit i LOW
outa[noparse][[/noparse]clk] := 1 ' toggle sclk pin High
waitcnt(50_00 + cnt)
outa[noparse][[/noparse]clk] := 0 ' toggle sclk pin Low
outa[noparse][[/noparse]cs] := 1 ' set Chip Select High
return datar
PRI writeByte( cmd ) | i
repeat i from 0 to 3 ' ADC0838 has 1 start bit and 4 data bits
outa[noparse][[/noparse]datain] := cmd ' send LSB bit
'tvout.bin(cmd,6)
'tvout.out(13)
cmd >>= 1 ' shift to next bit
outa[noparse][[/noparse]clk] := 1 ' toggle sclk pin High (add delay here if clock is too fast) (clue: check duty cycle)
waitcnt(50_00 + cnt)
outa[noparse][[/noparse]clk] := 0 ' toggle sclk pin Low
waitcnt(50_00 + cnt)
On the other hand, a AD0838 needs 5 bits of command and you are only shifting 4... (repeat from 0 to 3). I imagine indention is ok also (use the code tags).
Now I seem to have a strange problem with the results, they are half of what I expect. A 5v input on a pin returns 127, not 255. I think the pins are wired right, +V and Vref are at +5, Agnd is 0. I've tried 3 different ways to receive the data(shown in attached file) and get the same result either way, not the worst problem in the world to have, but I think I'm close to getting it right, and maybe suitable for the Object Library.
Any help greatly appreciated!
Thanks,
Garyt
Anyway, look very closely at the timing diagram for this chip. The setup word and data bit shift timing are different. The last clock pulse of the setup is the first pulse of the data transmission. It's also wierd in that the symetrical data output shares the LSB in the middle AND THAT CLOCK CYCLE. The diagram shows an extra 3 clocks at the very wend of the cycle, I found that these seem to be necessary before the next sample.
(Look at page 11 of the attachment.)
Jim-
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Signature space for rent, only $1.
Send cash and signature to CannibalRobotics.