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

AD7705 - reading problem

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



Joined: 15 Sep 2003
Posts: 75

View user's profile Send private message

AD7705 - reading problem
PostPosted: Wed Feb 07, 2007 9:50 am     Reply with quote

I have the AD7705 connected to PIC18F2620, so that the MCU reads the 16-bit ADC values. The following are configured:

AD7705:
- 4MHz resonator used but divided by 2 to give 2MHz internally. However, in AD7705 datasheet example uses 2.4576MHz.
- Precision 2.5V across Ref+ (pin 9) and Ref- (pin 10) inputs.
- Both AIN1+ (pin 7) and AIN1- (pin 8) connected to precision 2.5V. Therefore, no differential voltage across these 2 input pins.
- Vdd=5V, Vss=0V.
- Master clock enable on, clock div on, 50Hz update rate, self cal mode,
gain=1, bipolar inputs, buffer on, fync=start.


PIC18F2620:
- 4MHz resonator (separate resonator from AD7705).

Pin connections:
AD7705 PIC18F2620
===============
DRDY A0
DOUT A1
DIN A2
SCLK A3
RESET A4
CS A5

CCS PCWH Compiler V3.249

I have checked the following:

- Serial clock, data in, and CS pulses on a scope, and they appear to be correct.

- All the connections and voltages and they appear to be correct.

- Already tried 2 new samples of AD7705 and the same results obtained.

I have configured the AD7705 to accept bipolar inputs. Therefore, for the above AD7705 conditions, I would expect a data (ADC value) output of 0 because its differential input is 0V (i.e. 2.5V – 2.5V). However, I received –32768!

I would appreciate any comments.

After reading some threads on this Forum, I made some changes to the CCS AD7705.c driver. Please find attached code below:

Code:

// AD7705.c
//// Driver routines for the AD7705 chip
//Assuming a 2.4576 crystal ocsillator is used between MCLK IN and MCLK OUT

//connection pins to the PIC
#ifndef ADC_DRDY
#define ADC_DRDY  PIN_A0
#define ADC_DO    PIN_A1
#define ADC_DI    PIN_A2
#define ADC_CLK   PIN_A3
#define ADC_RESET PIN_A4
#define ADC_CS    PIN_A5
#endif

//Operation modes (MD1, MD0 bits in Setup Register)
#define ADC_NORMAL 0x00
#define ADC_SELF 0x40
#define ADC_ZERO_SCALE 0x80
#define ADC_FULL_SCALE 0xC0

//Gain settings (G2, G1, G0 bits in Setup Register)
#define ADC_GAIN_1      0x00
#define ADC_GAIN_2      0x08
#define ADC_GAIN_4      0x10
#define ADC_GAIN_8      0x18
#define ADC_GAIN_16     0x20
#define ADC_GAIN_32     0x28
#define ADC_GAIN_64     0x30
#define ADC_GAIN_128    0x38

//Polar operations (B/U bit in Setup Register)
#define ADC_BIPOLAR     0x00   
#define ADC_UNIPOLAR    0x04   

//Buffer control (BUF bit in Setup Register)
#define ADC_BUFFER_ON   0x02   
#define ADC_BUFFER_OFF  0x00   

//Fsync (FSYNC bit in Setup Register)
#define ADC_FSYNC_RESET 0x01
#define ADC_FSYNC_START 0x00


//Master clock (CLKDIS bit in Clock Register)
#define ADC_MASTERCLK_ENABLE  0x00
#define ADC_MASTERCLK_DISABLE 0x10

//Clock divider (CLKDIV bit in Clock Register)
#define ADC_CLKDIV_ON  0x08
#define ADC_CLKDIV_OFF 0x00

//Update rates (CLK, FS1, FS0 bits in Clock Register)
#define ADC_20          0x00
#define ADC_25          0x01
#define ADC_100         0x02
#define ADC_200         0x03
#define ADC_50          0x04
#define ADC_60          0x05
#define ADC_250         0x06
#define ADC_500         0x07

// Function prototypes
void adc_init();
void setup_adc_device(int masterclk, int clkdiv, int rate,
int mode, int gain, int polar, int buffer, int fsync);
void write_adc_byte(BYTE data);
long read_adc_word();
long read_adc_value(int1 ch);


//initialization routine
void adc_init()
{
   output_low(ADC_RESET);    // Reset all ADC registers to their default state.
   delay_ms(10);
   output_high(ADC_RESET);

   // See Fig. 17 of AD7705 datsheet
   output_high(ADC_CLK);     // CLK line at high state
   output_high(ADC_CS);      // CS line at high state

   setup_adc_device(ADC_MASTERCLK_ENABLE,ADC_CLKDIV_ON,ADC_50,
                    ADC_SELF,ADC_GAIN_1,ADC_BIPOLAR,ADC_BUFFER_ON,ADC_FSYNC_START);
   delay_ms(10);
}


//setup the device paramaters
void setup_adc_device(int masterclk, int clkdiv, int rate,
int mode, int gain, int polar, int buffer, int fsync)
{
   int8 temp1, temp2;

    write_adc_byte( 0x20 ); //Communications Register set to write of Clock Register
   temp1 = masterclk|clkdiv|rate;
   write_adc_byte( temp1 ); //Clock Register info here

     write_adc_byte( 0x10 ); //Communications Register set to write of Setup Register
   temp2 = mode|gain|polar|buffer|fsync;
   write_adc_byte( temp2 ); //Setup Register info here
}


void write_adc_byte(BYTE data)
{
   int8 i;

   output_low(ADC_CS);
   for(i=0; i<8; i++)
   {
      output_low(ADC_CLK);
      delay_us(50);
      output_bit(ADC_DI, shift_left(&data,1,0));
      output_high(ADC_CLK);
      delay_us(50);
   }
   output_high(ADC_CS);
}


long read_adc_word()
{
   int8 i;
   long data;

   output_low(ADC_CS);
   for(i=0; i<16; i++)
   {
      output_low(ADC_CLK);
      delay_us(50);
      shift_left(&data,2,input(ADC_DO));
      output_high(ADC_CLK);
      delay_us(50);
   }
   output_high(ADC_CS);
   return data;
}


// read an adc value from the specified channel
// ch = 0 or 1
long read_adc_value(int1 ch)
{
   long value;

   while ( input(ADC_DRDY) ); // Loop until data is ready
   if(ch)  // ch=1 (AIN2+, AIN2-)
      write_adc_byte(0x39);   //communications register set to read of data
   else    // ch=0 (AIN1+, AIN1-)
      write_adc_byte(0x38);   //communications register set to read of data

   value=read_adc_word();

   return value;
}


// ============================================
#include <18F2620.h>             
#device ADC=10                   
#device ICD=TRUE                                         
#FUSES NOWDT                    // Watchdog disabled
#FUSES XT                       
#FUSES NOLVP                     

// 4MHz clock (internal clock of MCU=1MHz)
#use     delay(clock=4000000)

#define ADC_DRDY  PIN_A0
#define ADC_DO    PIN_A1
#define ADC_DI    PIN_A2
#define ADC_CLK   PIN_A3
#define ADC_RESET PIN_A4
#define ADC_CS    PIN_A5
           
#use fast_io(a)               
#use fast_io(b)               
#use fast_io(c)               

#byte port_a = 0xF80          // Give meaningful names for these ports
#byte port_b = 0xF81
#byte port_c = 0xF82

#include "lcd1.c"
#include "ad7705.c"


void main(void)
{
   long value;

   set_tris_a(0b00000011);    // A0, A1=inputs, A2 to A5 = outputs
   set_tris_b(0b11000000);                                                       
   set_tris_c(0b10010000);         

   setup_adc(ADC_OFF);
   delay_ms(1);

   setup_spi(FALSE);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   setup_low_volt_detect(FALSE);
   setup_oscillator(FALSE);

   lcd_init();                // Initialise LCD
   delay_ms(6);          // Allow LCD to settle

   lcd_putc("\fHello!");
   delay_ms(100);

   adc_init();

   while(TRUE)
   {
      value=read_adc_value(0);  // Read (AIN1+, AIN1-) differential inputs
      printf(lcd_putc,"\fValue = %6ld", value);
      delay_ms(1000);
   }
}

Ttelmah
Guest







PostPosted: Wed Feb 07, 2007 10:30 am     Reply with quote

The value you have, is 'spot on'.....
You are in bipolar mode. Hence the input ranges from -2.5v(0) to +2.5v(0xFFFF), via 0v (0x8000). What is wrong, is that you are treating the 16bit value, as a signed number. If you take the hex value 0x8000, and display it as a signed value, you get -32768 (use the Pconvert program with the compiler, to see how values display).

Best Wishes
TL



Joined: 15 Sep 2003
Posts: 75

View user's profile Send private message

PostPosted: Thu Feb 08, 2007 8:39 am     Reply with quote

Hi Ttelmah,

Many thanks for your quick response. You are absolutely correct with your explanation. Yes, I have compared various signed and unsigned long values with the Pconvert program. As there was no formula stated in the AD7705 datasheet for the output code, I made the wrong assumption!

Since then, I have read an FAQ document from the Analog Devices website and the bipolar mode uses “Offset Binary Coding”. The output code for any analogue input differential voltage can be represented as follows:

Output code = [2 to the power of (n-1)] * [(Vdiff * Gain/Vref)+1]

Where n = 16, and Vdiff can be negative or positive.
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