SPI 18 bits?
SPI 18 bits?
I would like to use the ADC161S626 (16b 50-250ksps) with the PIC16F1719 8MIPs,hardware SPI clocked at 1MHz. SDO on the ADC is high Z for the first two clock pulses. Is there anyway to prevent the PIC from writing the first 2 bits to SPI buffer? Or is their another way to handle this? The min clk for the ADC is 1MHz, max clk is 5MHz.
-
- Posts: 172
- Joined: 24 Aug 2014 17:55
- Location: Sheffield
Re: SPI 18 bits?
Just pulse the spi clock line yourself for 2 pulses before using the spi to read the data something like this
Regards
dave
Code: Select all
for(i=0;i<2;i++){
ADC_CS=0; //enable
delay_us(1);
SPI_Clk=1;
delay_us(1);
SPI_Clk=0
delay_us(1);
}
the above will enable the ADC Data Output but you wont be reading any data
int16 adc_data=SPI_Read ADC;
ADC_CS=1; //disable
dave
"When the bugs strike it's no good bashing your head against a brick wall, you might damage the wall"
-
- Posts: 1179
- Joined: 24 Nov 2005 20:07
- Location: Colorado, USA
Re: SPI 18 bits?
Another solution would be to place a pull down resistor on the DO line (~10K) so that it has a defined logic low state when the ADC sets it to high-Z. This will allow you to clock those undefined first bits as zeros without any consequence to the data integrity and still use the SPI hardware module for speed and simplicity. However since the ADC outputs an 18-bit result you will still need to clock and read 3-bytes worth of data from it via the SPI module. This then will require you to bit-shift the recovered data to re-align the MSB/LSB data positions in order to make the ADC measurement end result correct.
Manually clocking the ADC using software delay intervals may prove to be lacking in speed depending upon the PIC crystal frequency, code overhead, and read rate of the ADC.
Manually clocking the ADC using software delay intervals may prove to be lacking in speed depending upon the PIC crystal frequency, code overhead, and read rate of the ADC.
Re: SPI 18 bits?
Thank you
is this a practical solution. Wait for the buffer overflow flag to set then read SSPBUF. I don't think that will work, I only have 3 maybe 4 instruction cycles to read the SSPBUF before the next bit comes in.
I'll try as you suggested sparky. It's high z for the first clk pulse then zero, then useful 16b data.
is this a practical solution. Wait for the buffer overflow flag to set then read SSPBUF. I don't think that will work, I only have 3 maybe 4 instruction cycles to read the SSPBUF before the next bit comes in.
I'll try as you suggested sparky. It's high z for the first clk pulse then zero, then useful 16b data.
-
- Posts: 1179
- Joined: 24 Nov 2005 20:07
- Location: Colorado, USA
Re: SPI 18 bits?
What bits? Have I misunderstood your reply? The PIC SPI output/input buffer operates in 8-bit chunks (1-byte), is clock dependent internally since it is the master, and is self timed for the simultaneous send/receive event. There are no "bits" to wait for since the master is always in control to when data is exchanged in either direction.I don't think that will work, I only have 3 maybe 4 instruction cycles to read the SSPBUF before the next bit comes in.
The ADC will only send data when the master provides the clock. So as the first "0" byte is clocked out (to nowhere in this case) the PIC will be receiving the first byte of the ADC data. Once 8-bits have been received, you read the ssp1buf register and store its contents into a variable, then send another "0" byte to obtaint the second byte of ADC data. Repeat for 3rd byte. The ADC chip will wait until the next group of 8 clock pulses are seen to send more data provided that you have not de-selected the ADC chip select at any point during this transference session.
It should go something like this.
Code: Select all
ADC_CS = 0; // enable ADC chip select
ssp1buf = 0x00; // load dummy byte into SPI TX shift out register
while (!pir1.SSP1IF); // wait until done bit is set (byte sent indicator)
ADC_HighByte = ssp1buf; // obtain ADC high byte read in as dummy byte was sent out
ssp1buf = 0x00;
while (!pir1.SSP1IF);
ADC_MidByte = ssp1buf; // obtain ADC middle byte
ssp1buf = 0x00;
while (!pir1.SSP1IF);
ADC_LowByte = ssp1buf; // obtain ADC low byte
ADC_CS = 1; // disable ADC chip select
Once you have all the ADC bytes you combine them into one variable and then bit-shift until you have the data bits aligned into the proper MSB/LSB positions. If you don need the upper 2 bits of the ADC result then mask them off using the bit-wise "&" function as the last step.
Last edited by Sparky1039 on 03 Nov 2018 20:08, edited 2 times in total.
Re: SPI 18 bits?
Hi Sparky
I see, thanks Sparky. While I'm reading sspbuf will the SPI module continue to clk out and shift bits into sspsr? The reason I'm trying to do this as quickly as possble, is the data sheet states, to meet the specifications a minimum clk frequency is 1MHz, due to sampling cap leakage.
I see, thanks Sparky. While I'm reading sspbuf will the SPI module continue to clk out and shift bits into sspsr? The reason I'm trying to do this as quickly as possble, is the data sheet states, to meet the specifications a minimum clk frequency is 1MHz, due to sampling cap leakage.
-
- Posts: 1179
- Joined: 24 Nov 2005 20:07
- Location: Colorado, USA
Re: SPI 18 bits?
No, you failed to grasp what I was saying in the previous post. The SPI module only works with 8-bits at a time per communication instance. You have to initiate the process over for successive bytes. I suggest doing some web searching about SPI bus fundamentals and reading through the PIC data sheet on how the MSSP / SPI module works. The code snippet I provided should also give you some insight to the processes as well.While I'm reading sspbuf will the SPI module continue to clk out and shift bits into sspsr?