CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

interfacing AD7796 to PIC using SPI

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
zilog
Guest







interfacing AD7796 to PIC using SPI
PostPosted: Thu Jun 07, 2007 2:10 pm     Reply with quote

I am interfacing two AD7796 sigma-delta AD:s to a PIC16F883, the AD:s CLK-lines are tied together using the first to clock the second. PIN_C0 and PIN_C1 are tied to their /CS lines respectively. It seems like I can talk _to_ the AD:s, but I cannot read back stuff that looks sane. On the oscilloscope it looks like I can enable the continous conversion and readout mode (using the code below, I can get 16.7Hz /RDY pace on the scope), and I usually am successful in reading back the device ID:s (but not always as things tend to get a bit random).

I have added
Code:

#define DEBUG_READTEMP

To see if I can read the internal temperature sensor or not, but the output from the SPI bus just keeps flipping randomly between 0x0000 and 0xFFFF just as before. Has anybody done this before, and can guide me a bit?

I use this code to enable the SPI interface:
Code:

 /* input and output data is valid at rising edge of SCLK, SCLK idle high, Fosc/4 */
  SSPSTAT = 0x00;
  set_tris_c(0b10010100);
  SSPCON = 0x30;


This is a function to setup the both AD:s, and make sure they start in sync
Code:

void start_external_adc(void)
{
  /* reset both AD:s */
  output_low(PIN_C0 | PIN_C1);
  spi_write(0xFF); spi_write(0xFF); spi_write(0xFF); spi_write(0xFF);
  delay_us(500);
  output_high(PIN_C0 | PIN_C1);

  /* setup LAST */
  output_low(PIN_C0);
  spi_write(0x08); //next write is MODE REGISTER
  delay_cycles(10);
  spi_write(0x00); spi_write(0x8A); //cont, use external clock, 16.7HZ, 50+60Hz suppression
#ifdef DEBUG_READTEMP
  delay_cycles(10);
  spi_write(0b00010000); //config register
  delay_cycles(10);
  spi_write(0b00010111); spi_write(0b00010110);
#endif
  delay_cycles(10);
  spi_write(0x5C); //cont data output mode
  output_high(PIN_C0);

  output_low(PIN_C1);
  /* setup HANDTAG */
  spi_write(0x08); //next write is MODE REGISTER
  spi_write(0x00); spi_write(0x4A); //cont, output internal clock, 16.7HZ, 50+60Hz suppression
  spi_write(0x5C); //cont data output mode
  output_high(PIN_C1);

  return;
}


And this is a function I call repeatedly to check if both AD:s have finished the conversion by examining the state of the /RDY pin (SDI on the PIC). It also takes timestamps to help monitoring if the AD:s drift or not.

Code:

/* returns true if both AD:s were ready to sample out */
int1 read_external_adc(unsigned int16 *last, unsigned int16 *ht, unsigned int8 *tAD1, unsigned int8 *tAD2, int1 wasteSample)
{
  int1 DTR1 = 0, DTR2 = 0;

  if (wasteSample) {
    /* let both AD:s start, waste the first conversion result */
    output_low(PIN_C0);
    while (input(PIN_C4));
    spi_read(0); spi_read(0);
    output_high(PIN_C0);
   
    output_low(PIN_C1);
    while (input(PIN_C4));
    spi_read(0); spi_read(0);
    output_high(PIN_C1);
   
    reset_timExtAD();
  } else {
    output_low(PIN_C0);
    DTR1 = !input(PIN_C4);
    if (DTR1) {
      *tAD1 = read_timExtAD();
    }
    output_high(PIN_C0);
   
    output_low(PIN_C1);
    DTR2 = !input(PIN_C4);
    if (DTR2)
      *tAD2 = read_timExtAD();
    output_high(PIN_C1);

    if (DTR1 && DTR2) {
      output_low(PIN_C0);
      *last = (unsigned int16)spi_read(0) << 8;
      *last |= (unsigned int16)spi_read(0);
      output_high(PIN_C0);
   
      output_low(PIN_C1);
      *ht = (unsigned int16)spi_read(0) << 8;
      *ht |= (unsigned int16)spi_read(0);
      output_high(PIN_C1);

      reset_timExtAD();
    }

  }

  return (DTR1 && DTR2);
}
[/code]
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jun 07, 2007 2:51 pm     Reply with quote

Quote:
output_low(PIN_C0 | PIN_C1);

This syntax is totally incorrect. You need to look at other CCS
programs before you write your own code.
Guest








PostPosted: Thu Jun 07, 2007 3:36 pm     Reply with quote

Thanks for pointing that out - had totally missed it.

Now that I get some kind of reading from the internal temperature sensor - does anyone know how temperature translates into output value? There is 0.81mV/C specified, but since an offset is missing I cant use it..
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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