|
|
View previous topic :: View next topic |
Author |
Message |
Ryan Barton Guest
|
'876 won't receive SPI data (as Master) |
Posted: Wed Nov 21, 2001 1:45 pm |
|
|
I'm attempting to read data from an SPI A/D (MAX189). The PIC is in Master mode, and transmits SPI data fine (I'm sending data to a D/A as well), but when I use data=spi_read() to fetch a byte from the A/D, nothing happens! The clock line doesn't budge. I tried passing trash to spi_read() in an effort to wake it up (p 61 manual), and this did indeed trigger SCLK. Now the A/D faithfully provides the data onto SDI, but the PIC refuses to read it. Help!
Applicable code segments:
/* Initialize Registers */
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_spi( spi_master | spi_h_to_l | spi_clk_div_64 ); // 125kbit clock rate (8Mhz/64)
setup_counters(RTCC_INTERNAL,RTCC_DIV_2);
setup_ccp1(CCP_OFF);
setup_ccp2(CCP_OFF);
/* Initialize both CS lines high for SPI bus */
output_bit( PIN_B1, 1);
output_bit( PIN_B2, 1);
...
int H, L;
output_bit( PIN_B1, 0); // Bring ADC CS low, ADC starts to sample
delay_us(20); // conversion takes 8.5us
H = spi_read(83); // passing random data so that PIC will activate the clock line (but it still doesn't read)
L = spi_read(83);
output_bit( PIN_B1, 1); // Bring ADC CS high
Thanks in advance for any assistance!
- Ryan Barton
___________________________
This message was ported from CCS's old forum
Original Post ID: 1277 |
|
|
Neutone
Joined: 08 Sep 2003 Posts: 839 Location: Houston
|
Re: '876 won't receive SPI data (as Master) |
Posted: Wed Nov 21, 2001 2:09 pm |
|
|
This is for reading 24 bits from a LTC2400 via an SPI interface and could be easily modified for fewer bits. This portion of code only reads the SPI port when the conversion is complete and can thus be placed in a primary services loop.
output_low(PIN_A0);
delay_cycles(5); // give time for pin A1 to toggle
if (input(PIN_A1))
{
output_high(PIN_A0);
goto CheckSerialPort;
}
output_high(PIN_A3);
ADCbuffer[0]=0;
ADCbuffer[1]=0;
ADCbuffer[2]=0;
for (shiftbit = 1; shiftbit <= 26; shiftbit++)
{
output_high(PIN_A2);
shift_left(ADCbuffer,3,input(PIN_A1));
output_low(PIN_A2);
}
output_high(PIN_A0);
CheckSerialPort:
___________________________
This message was ported from CCS's old forum
Original Post ID: 1278 |
|
|
Ryan Barton Guest
|
Re: '876 won't receive SPI data (as Master) |
Posted: Wed Nov 21, 2001 2:19 pm |
|
|
thx. I was just thinking that bit-banging SCI wouldn't be too hard. The only disadvantage is throwing away my working SCI transmit code and having to rebuild it from scratch (all 3 ports would need to be defined as general I/O). I'd like to find a solution using the built-in functions, but if I get peeved enough, brute-force is always an option...
- Ryan
___________________________
This message was ported from CCS's old forum
Original Post ID: 1279 |
|
|
Ryan Barton Guest
|
kludge fix |
Posted: Wed Nov 21, 2001 3:18 pm |
|
|
After researching the '87x manual and looking at the assembly produced, I found the problem: data=spi_read() simply copies the contents of the SSPBUF register to 'data'. In Slave Mode, the compiler expects you to check for data (spi_data_is_in) before grabbing it. BUT... when in Master Mode, there's no point in checking since the PIC controls SCLK, and without running SCLK, no data comes in!
Kludged solution: Drop to assembly, throw something at SSPBUF, come back. This starts the SCLK transitions (and starts to clock in the data!) NOW poll spi_data_is_in until the byte has arrived, and then use spi_read() to get it. Sheesh!
Code sample (that works!):
int H, L;
output_bit( PIN_B1, 0); // Bring ADC CS low, ADC starts to sample
delay_us(20); // conversion takes 8.5us
#ASM
movlw 0
movwf 0x13 // write trash to SSPBUF to activate SPI clocking (PIC datasheet p70)
#ENDASM
while(spi_data_is_in()==0) {} // wait till byte is received
H = spi_read();
#ASM
movlw 0
movwf 0x13 // write trash to SSPBUF to activate SPI clocking (PIC datasheet p70)
#ENDASM
while(spi_data_is_in()==0) {} // wait till byte is received
L = spi_read();
output_bit( PIN_B1, 1); // Bring ADC CS high
One could use spi_write to force something out (to avoid the drop to assembly). Does anyone know of a more elegant solution than this? (just curious)
- Ryan Barton
___________________________
This message was ported from CCS's old forum
Original Post ID: 1280 |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
Re: kludge fix |
Posted: Wed Nov 21, 2001 3:59 pm |
|
|
BUT... when in Master Mode, there's no point in checking since the PIC controls SCLK, and without running SCLK, no data comes in!
:=Kludged solution: Drop to assembly, throw something at SSPBUF, come back. This starts the SCLK transitions (and starts to clock in the data!) NOW poll spi_data_is_in until the byte has arrived, and then use spi_read() to get it.
------------------------------------------
I think you can do this with spi_read(0). Check the Version 3
manual for spi_read().
___________________________
This message was ported from CCS's old forum
Original Post ID: 1281 |
|
|
|
|
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
|