|
|
View previous topic :: View next topic |
Author |
Message |
rwskinner
Joined: 08 Dec 2006 Posts: 125 Location: Texas
|
Bitbanging SPI |
Posted: Thu Jan 28, 2010 7:55 pm |
|
|
Okay, please remember I'm a amateur and trying to learn....
I'm having to manually bit bang a ADS7953, 16 channel, 12 bit ADC.
http://focus.ti.com/lit/ds/symlink/ads7953.pdf
A long time ago, I've done some of the simple stuff where I lower CS, toggle the CLk to start a conversion then I just shift in 8 bits for my reading. This critter is a little more complicated.
Please see if I have this logic right....
1) While I'm shifting out 16 bit on SDI there is data coming back from the previous conversion at the same time on SDO.
Pseudo code...
Shift out first 16 bits for the Config
Ignore DOut
Shift out 2nd 16 bits for the Operation Registers
Ignore DOUT
For this example, the above put the ADC in Auto1 mode, self incrementing on the channels.
Lower CS
Lower DIN (in auto mode so it can be all zeros)
for (i=0; i < 16; i++)
{
make clock high
short delay
read in bit on DO
Lower clock
}
Now I have data from the conversion with the first 4 bits being the channel # and the remaining 12 bits the ADC Value.
Is this close to being correct? |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Fri Jan 29, 2010 12:34 am |
|
|
It's basically correct. I have two comments, however.
- You can use CCS software SPI built-in functions to achieve the same
- Operating a 1 MSPS high speed ADC with software SPI seems to me like "cast pearls before swine". |
|
|
rwskinner
Joined: 08 Dec 2006 Posts: 125 Location: Texas
|
|
Posted: Fri Jan 29, 2010 5:56 am |
|
|
Thanks, I give it a try today.
18F4550 MSSP shares pins with USART so both can not use hardware at the same time. Already using hardware RS232. MC Buggered this one up a little. I guess they figured if you would be using USB, you would not be using RS232. |
|
|
rwskinner
Joined: 08 Dec 2006 Posts: 125 Location: Texas
|
|
Posted: Fri Jan 29, 2010 8:27 am |
|
|
Here is what I have.
Again, I'm trying to learn the timing maps....
I'm getting changing data back, but I'm only getting 6 bits back, the 10 msb are zero.
I'm using the 16 channel, 12 bit version (ADS7953).
Don't be too hard on me
Code: |
#define ADS7953_CLK PIN_B1 //Clock
#define ADS7953_DOUT PIN_D4 //Data from Chip
#define ADS7953_CS PIN_D5 //Chip Select
#define ADS7953_DIN PIN_A2 //must change Data to Chip
//Base routines
void write_ADS7953(int16 data) //Sends 16 bits of data
{
int i;
output_low(ADS7953_CLK); //Initial State
output_low(ADS7953_CS);
delay_us(1);
output_high(ADS7953_CS); //CS High for two clock cycles
for(i=0;i<=2;i++) //Toggle Clk twice,lo to hi
{
output_high(ADS7953_CLK);
delay_us(1);
output_low(ADS7953_CLK);
delay_us(1);
}
output_low(ADS7953_CS); //clk low, now CS low
//start shifting data in
for(i=1;i<=16;++i)
{
output_high(ADS7953_CLK);
output_bit(ADS7953_DIN, shift_left(&data,2,0));
output_low(ADS7953_CLK);
}
output_high(ADS7953_CS); //End serial
}
//Base routines
long read_ADS7953() //Gets 16 bits of data
{
int i;
long data;
data=0;
output_low(ADS7953_CLK); //Inital States
output_low(ADS7953_CS);
delay_us(1);
output_high(ADS7953_CS); //CS high for 2 clk cycles
for(i=0;i<=2;i++) //toggle clk twice, lo to hi
{
output_high(ADS7953_CLK);
delay_us(1);
output_low(ADS7953_CLK);
delay_us(1);
}
output_low(ADS7953_CS); //make CS low
for(i=0;i<16;++i) { // shift data from ADS
output_high(ADS7953_CLK);
delay_us(1);
shift_left(&data,2,input(ADS7953_DOUT));
output_low(ADS7953_CLK);
delay_us(1);
}
output_high(ADS7953_CS);
return(data);
}
//0 = Manual
//1 = Auto1
//2 = Auto2
void init_ADS7953(byte mode)
{ long ModeCfg, ProgCfg, ChanCfg;
//Only support Auto1 for Testing
/*
PGM1 Mode Control Register Layout (Frame 1)
Bit 0-3 GPIO Data for Outputs (Right)
Bit 4 0= Output 4 bit channel data with ADC Val,
1= Output 4 bit GPIO Values
Bit 5 0= Normal 1=Power Down after conversion
Bit 6 0= 2.5 volt Full Scale 1 = 5.0 volt full scale
Bit 7-9 Do not care
Bit 10 0 = Inc Channel 1= Start at lowest channel
Bit 11 0 = Retains Bits 0-10 every frame 1= Program 0-10
Bit 12-15 0010 = Auto Mode, 0001 = reset state
*/
ModeCfg = 0b001000000100000;
/*
PGM2 Program Register layout (Frame 2)
Bits 0-11 Don't Care
Bits 12-15 1000 - Enter Auto1 Mode
*/
ProgCfg = 0b100000000000000;
/*
PGM3 Channel Selection (Frame 3)
Bits 0-15 Which CHannels are on for us, 1111 1111 1111 1111
*/
ChanCfg = 0b1111111111111111;
//Write Mode Control Configuration Frame 1
Write_ADS7953(ModeCfg);
//Write Program Registers Frame 2
Write_ADS7953(ProgCfg);
//Write Channel Selections
Write_ADS7953(ChanCfg);
}
|
|
|
|
rwskinner
Joined: 08 Dec 2006 Posts: 125 Location: Texas
|
|
Posted: Fri Jan 29, 2010 11:27 am |
|
|
I got it...... |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|