PDA

View Full Version : Help! - Very strange results with ShiftIn/ShiftOut



khufumen
- 22nd February 2005, 02:51
Hi,
I am running a 16F876 at 20MHz. I am reading a channel on an AD converter (Texas Instruments TLC2543) using the shiftin/shiftout commands and then sending the results to a serial port at 38400. The simple code is shown below. The code works fine as long as the Pause 4 is being used. If I remove the Pause 4 or make it lower than 4 ms, the variable 'result' is zero instead of 2544 or what have you. When I check the voltages at my voltage pin (PORTC.3) which is powering the sensor and ad converter, the pin reads 0 volts when the "PAUSE 4" is not used and when the "PAUSE 4" is used it goes to 5 volts. Now that's weird. The reason I'm getting a zero in the result is because the power pin mysteriously goes to zero as if there is a short or something.

I thought it was perhaps the AD converter being slow but I cancelled this theory when I found I can loop through the converter 20 times and take an average and there is no problem as long as I use the "PAUSE 4" before entering the ReadAD subroutine, looping within the subroutine 20 times and then exiting. If I put the "PAUSE 4" after the ReadAD Subroutine I get zeros. The "PAUSE 4" has to be done before the ReadAD Subroutine. It's really bizzare.
If anyone has some insight into this I would sure appreciate it.

Kind Regards,
Eric

clear ' clear the variables
High SensorPower
MainLoop:
Pause 4
ADch = TiltX
gosub ReadAD
serout2 TX, 6, [Dec result, 13, 10]
goto MainLoop
end

'************************************************* *
' read the AD converter
ReadAD:
High SensorPower
LOW ADcs ' select chip
SHIFTOUT sdo,sclk,MSBFIRST,[ADch<<8\12] ' mode, left justify ADch
SHIFTIN sdi,sclk,MSBPRE,[result\12] ' get result, 12 bits
HIGH ADcs ' deselect chip
RETURN

mister_e
- 22nd February 2005, 03:09
what about if you disable your a/d at the begining of your program HIGH ADcs ... don't forget all pins are supposed to be low at the begining so your adc consider that he is enable.

BUT chances are that you don't set the TRIS for your adc, in this case, the ADcs pin is set as an input and floating. It this case, it can give enough highlevel signal to disable your ADC... this why your PAUSE 4 is handy in your case.

I'm really not sure if it's a good practice to use bit shift in a SHIFTOUT statement.

AND some a/d may need few mSec pause between SHIFTOUT and SHIFTIN... let the time to convert properly. Pause 10 can be good... see your a/d datasheet for that issue.

Darrel Taylor
- 23rd February 2005, 08:15
Hi khufumen,

I think the problem here is that the TLC2543 sends the previous result OUT at the same time the next address is clocked IN to start a conversion.

The SHIFTIN and SHIFTOUT statements can't do both at the same time. Add in the Conversion Time that overlaps into the next SHIFTIN, and the 2 chips get out of Sync when the 12-bits don't match up.

If you don't mind getting only every other sample, you can do it but there are a couple of timing issues.

--------

Do the SHIFTIN first, this will get the results of the last conversion. At the same time it will start a conversion of Channel 0.

Wait at least 10us for the conversion to complete. (double that for safety)

Now, do the SHIFTOUT to start the next Conversion with the desired channel, and exit the subroutine.

Essentialy, you're starting a dummy conversion when Reading, and discarding the results when Writing to the device.


clear ' clear the variables
High SensorPower

ADch = TiltX ' First AD reading will be garbage
gosub ReadAD ' but it also starts the next conversion


MainLoop:
ADch = TiltX
gosub ReadAD
serout2 TX, 6, [Dec result, 13, 10]
goto MainLoop
end

'************************************************* *
' read the AD converter
ReadAD:
High SensorPower
LOW ADcs ' select chip
LOW sdo ' send all 0's during read
SHIFTIN sdi,sclk,MSBPRE,[result\12] ' get result, 12 bits
HIGH ADcs ' deselect chip
PauseUS 20 ' wait for conversion to finish
LOW ADcs ' select chip
SHIFTOUT sdo,sclk,MSBFIRST,[ADch<<8\12] ' Start next conversion
HIGH ADcs ' deselect chip
PauseUS 20 ' wait for conversion to finish
RETURN
If you wanted to write you're own SHIFTIN/OUT routine, you could catch every sample by sending data in both directions at the same time. It would also be much faster. Since PBP's SHIFTOUT operates at somewhere around 50khz, it takes 240uS just to send the instruction to start a conversion, and another 240uS to read the result. If done manually, you should be able to get up to 400khz or more. That would SHIFTOUT 12 bits in 30uS.

HTH,
&nbsp;&nbsp;&nbsp;Darrel

khufumen
- 23rd February 2005, 22:21
Thanks for all your help and input. What was causing the problem was that there was no delay between when I powered up the AD converter and when I started reading from the AD converter. The AD converter when powered up needs about 4 ms to stabilize before it can be read from. Once it stabilizes, it has no problem reading the the data.

The fixed code reads:

clear ' clear the variables
High SensorPower ' power up the sensors and the AD converter
Pause 4 ' wait for power to stabilize

MainLoop: ' enter main loop
ADch = TiltX
gosub ReadAD
serout2 TX, 6, [Dec result, 13, 10]
goto MainLoop
end

'************************************************* *
' read the AD converter
ReadAD:
LOW ADcs ' select chip
SHIFTOUT sdo,sclk,MSBFIRST,[ADch<<8\12] ' mode, left justify ADch
SHIFTIN sdi,sclk,MSBPRE,[result\12] ' get result, 12 bits
HIGH ADcs ' deselect chip
RETURN