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 support@ccsinfo.com

Driver for AD7710

 
Post new topic   Reply to topic    CCS Forum Index -> Code Library
View previous topic :: View next topic  
Author Message
iqdamn



Joined: 16 Oct 2006
Posts: 2
Location: Mexico city

View user's profile Send private message Send e-mail

Driver for AD7710
PostPosted: Mon Oct 16, 2006 9:16 pm     Reply with quote

Hi everybody, this is my first post and my first driver Embarassed , feel free to post any comments, errors, etc.

The AD7710 is a 24-bit ADC Signal Conditioning from Analog Devices and it uses a single wire serial interface, so, this driver is basically a bit banging of SPI.

I hope this helps somebody, it worked for me. Wink

Code:

//Assuming a 10 MHz crystal ocsillator is used between MCLK IN and MCLK OUT (AD7710)

//Connection pins to the PIC
#define DRDY    PIN_A3
#define RFS    PIN_A2
#define TFS    PIN_A1
#define A0       PIN_A0
#define SCLK    PIN_C1
#define SDATA    PIN_C2

//TRIS direction and bit, asociated with the pins needed
#bit    TRIS_SDATA = 0x87.2
#bit   TRIS_SCLK  = 0x87.1
#bit   TRIS_A0      = 0x85.0
#bit   TRIS_TFS   = 0x85.1
#bit   TRIS_RFS   = 0x85.2
#bit   TRIS_DRDY  = 0x85.3

//Operating modes
#define NORMAL_MODE          0x00000000
#define SELF_CALIBRATION      0x00200000
#define SYSTEM_CALIBRATION_1   0x00400000
#define SYSTEM_CALIBRATION_2   0x00600000
#define OFFSET_CALIBRATION      0x00800000
#define BACKGROUND_CALIBRATION   0x00A00000
#define RW_ZERO_SCALE_COEF      0x00C00000
#define RW_FULL_SCALE_COEF      0x00E00000

//Gain
#define GAIN_1               0x00000000
#define GAIN_2               0x00040000
#define GAIN_4               0x00080000
#define GAIN_8               0x000C0000
#define GAIN_16               0x00100000
#define GAIN_32               0x00140000
#define GAIN_64               0x00180000
#define GAIN_128            0x001C0000

//Channel selection
#define CHANNEL_1            0x00000000
#define CHANNEL_2            0x00020000

//Power down
#define PWR_NORMAL            0x00000000
#define PWR_DOWN            0x00010000

//Word length
#define WORD_16               0x00000000
#define WORD_24               0x00008000

//Output Compensation Current
#define CURRENT_OFF            0x00000000
#define CURRENT_ON            0x00004000

//Burn-Out Current
#define BURN_OUT_OFF         0x00000000
#define BURN_OUT_ON            0x00002000

//Bipolar/Unipolar Selection
#define BIPOLAR               0x00000000
#define UNIPOLAR            0x00001000

//Filter selection, default = 9.76Hz
#define   FS_CODE               0x000007D0

void write_ad7710(int32 data)
{
   BYTE i;
   BOOLEAN calibration_needed = FALSE;
   
   if(data&SELF_CALIBRATION || data&SYSTEM_CALIBRATION_1 || data&SYSTEM_CALIBRATION_2 || data&OFFSET_CALIBRATION)
         calibration_needed = TRUE;
   
   //Make SDATA an output
   TRIS_SDATA = 0;
   
   //Ignore the 1st byte (MSB)
   for(i=0;i<8;i++)
   {
      shift_left(&data,4,0);
   }
     
   output_low(A0);
   output_low(TFS);

   //25 bits instead of 24 because of timing, check datasheet
   for(i=0;i<25;++i)
   {
      output_low(SCLK);
      output_bit(SDATA, shift_left(&data,4,0));
      output_high(SCLK);
   }
     
   output_high(TFS);
   
   //Wait until the calibration is finished
   if(calibration_needed)
         while(input(DRDY));
   
   //Make clock idle low
   output_low(SCLK);
}

int32 read_ad7710(BOOLEAN output_register)
{
   int32 data = 0x00;
   BYTE i;
     
   //Make SDATA an input
   TRIS_SDATA = 1;
     
   output_bit(A0,output_register);
   
   if(output_register)   
         while(input(DRDY));
     
   output_low(RFS);
         
   for(i=0;i<24;++i)
   {
      output_low(SCLK);
      output_high(SCLK);
      shift_left(&data,4,input(SDATA));
   }
   
   output_high(RFS);
   
   //Make clock idle low
   output_low(SCLK);
   
   return data;
}

void setup_ad7710(int32 settings)
{
   write_ad7710(settings);
}

//Returns TRUE if the communication with the AD7710 is successfully established, otherwise FALSE
BOOLEAN check_ad7710()
{
   int32 value = 0x00;
   value = read_ad7710(FALSE);
   
   //The initial value stored in the control register after a power up.
   if(value == 0x00000146)
      return TRUE;
   
   return FALSE;
}

void init_ad7710()
{
   output_high(TFS);
   output_high(RFS);
   output_high(A0);
   
   //Setting the outputs
   TRIS_SCLK = TRIS_RFS = TRIS_RFS = TRIS_A0 = 0;
   
   //Make DRDY an input
   TRIS_DRDY = 1;
   
   //Make clock idle low
   output_low(SCLK);   
}


And this is how it is used...

Code:

#include "16F873.h"

#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#fuses HS,NOWDT,NOPROTECT,NOBROWNOUT,PUT

#include "AD7710.h"

void main()
{   
   int32 data = 0x00;
      
   init_ad7710();
   
   if(check_ad7710())
   {
      printf("AD7710 health check OK!\r\n");
   }
   else
   {
      printf("Error trying to access the AD7710\r\n");
      return;
   }
      
   setup_ad7710(SELF_CALIBRATION|GAIN_1|CHANNEL_1|WORD_24|BIPOLAR|FS_CODE);
   
   data = read_ad7710(FALSE);
   
   printf("Settings = %Lx\r\n",data);
   
   data = read_ad7710(TRUE);
   
   #ignore_warnings 203
   while(TRUE)
   {
      printf("Data = %Lx\r\n",data);
      delay_ms(3500);
      data = read_ad7710(TRUE);
   }   
   #ignore_warnings NONE
}


Greetings from Mexico !! Very Happy
abm.ben



Joined: 02 Sep 2008
Posts: 4

View user's profile Send private message

PostPosted: Tue Sep 09, 2008 8:07 am     Reply with quote

Hello "iqdamn",

I'm in internship and I have to develop a Temperature acquisition system using a pt100 probe.

To do this I chose the AD7711 chip connected to a PIC 18258.

I used your driver on a AD7711 architecture, and the result, we receive an interpretable and a wrong data for example of returned value:

-for 10°c.. SDATA=0x810DF3
-for 40°c.. SDATA=0x812BB9
-for 120°c..SDATA=0x817AE0
-for 140°c..SDATA=0x82651E

Have you developed a similar driver for AD7711, or can you tel me how
I can adapt this one, or who can I solve this problem ?

Please reply me quickly, because I haven't lot time.

Thanks for all.

Bye!
Very Happy
iqdamn



Joined: 16 Oct 2006
Posts: 2
Location: Mexico city

View user's profile Send private message Send e-mail

AD7711
PostPosted: Wed Sep 10, 2008 12:01 pm     Reply with quote

Hi Ben, I'm afraid I did this long time ago and I may not recall all the details, anyway, I wrote a driver but it is for other compiler, I guess is not too hard to translate it.

Header:

Code:

#ifndef _AD7711_H_
#define _AD7711_H_

#include "defines.h"
#include <pic18.h>

//Connection pins to the PIC
#define DRDY1    puerto_b.pin.pin7
#define DRDY2   puerto_b.pin.pin6
#define RFS1    puerto_b.pin.pin1
#define RFS2   puerto_b.pin.pin0
#define TFS1    puerto_b.pin.pin3
#define TFS2   puerto_b.pin.pin2
#define A0       puerto_a.pin.pin0
#define SCLK    puerto_a.pin.pin1
#define SDATA1    puerto_b.pin.pin5
#define SDATA2  puerto_b.pin.pin4

#define TRIS_SDATA1 TRISB5
#define TRIS_SDATA2 TRISB4

//Operating modes
#define NORMAL_MODE          0x00000000
#define SELF_CALIBRATION      0x00200000
#define SYSTEM_CALIBRATION_1   0x00400000
#define SYSTEM_CALIBRATION_2   0x00600000
#define OFFSET_CALIBRATION      0x00800000
#define BACKGROUND_CALIBRATION   0x00A00000
#define RW_ZERO_SCALE_COEF      0x00C00000
#define RW_FULL_SCALE_COEF      0x00E00000

//Gain
#define GAIN_1               0x00000000
#define GAIN_2               0x00040000
#define GAIN_4               0x00080000
#define GAIN_8               0x000C0000
#define GAIN_16               0x00100000
#define GAIN_32               0x00140000
#define GAIN_64               0x00180000
#define GAIN_128            0x001C0000

//Channel selection
#define CHANNEL_1            0x00000000
#define CHANNEL_2            0x00020000

//Power down
#define PWR_NORMAL            0x00000000
#define PWR_DOWN            0x00010000

//Word length
#define WORD_16               0x00000000
#define WORD_24               0x00008000

//Output Compensation Current
#define RTD_CURRENT_OFF         0x00000000
#define RTD_CURRENT_ON         0x00004000

//Burn-Out Current
#define BURN_OUT_OFF         0x00000000
#define BURN_OUT_ON            0x00002000

//Bipolar/Unipolar Selection
#define BIPOLAR               0x00000000
#define UNIPOLAR            0x00001000

//Filter selection
extern unsigned long FS_CODE;

void write_ad7711(unsigned long data, unsigned char calibration_register, unsigned char calibration_process, unsigned char ic);
unsigned long read_ad7711(unsigned char output_register, unsigned char ic);
void setup_ad7711(unsigned long settings, unsigned char calibration_process, unsigned char ic);
unsigned char check_ad7711(void);
void init_ad7711(void);
float convert_to_resistance(unsigned long data);
#endif


C file:

Code:

#include "defines.h"
#include "AD7711.h"
#include "delay.h"
#include <stdio.h>

unsigned long FS_CODE   =   0x00000145;

//Iniciamos los puertos que se usarán
void init_ad7711(void)
{   
   //Pedimos que el ADC esté apagado y se configuren sus pines como digitales
   ADCON1 = 0x0F;
   ADON = 0x00;
   
   //Puerto A como salidas
   TRISA = 0x00;
   PORTA = 0x00;
   
   //Puerto B, nible alto como entradas, nible bajo como salidas
   TRISB = 0b11110000;
   
   puerto_a.port = 0x00;
   puerto_b.port = 0x00;

   TFS1 = TFS2 = RFS1 = RFS2 = 1;
   SCLK = 0;
   A0 = 1;
   PORTA = puerto_a.port;
   PORTB = puerto_b.port;
}

void write_ad7711(unsigned long data, unsigned char calibration_register, unsigned char calibration_process, unsigned char ic)
{
      signed char i,j;
      unsigned char array[3],bit_buffer;
   
   array[0] = (unsigned char)(data &0x000000FF);
   array[1] = (unsigned char)((data &0x0000FF00) >> 8);
   array[2] = (unsigned char)((data &0x00FF0000) >> 16);
     
      //Make SDATA an output
      if(ic == 1)
      TRIS_SDATA1 = 0;
      else
     TRIS_SDATA2 = 0;
   
      if(calibration_register == 0x01)
         A0 = 1;
      else
         A0 = 0;
   
      PORTA = puerto_a.port;
     
      if(ic == 1)
      {
         TFS1 = 0;
      }
      else
      {
         TFS2 = 0;
      }
      PORTB = puerto_b.port;

   for(i = 2; i >= 0; i--)
   {
      for(j = 7; j >= 0; j--)
      {
         SCLK = 0;
            PORTA = puerto_a.port;
         
         bit_buffer = 0x00;
         bit_buffer = array[i] >> j;
         bit_buffer &= 0x01;
         
         if(ic == 1)
            SDATA1 = bit_buffer;
         else
            SDATA2 = bit_buffer;
            
         PORTB = puerto_b.port;
         
         DelayUs(100);
            SCLK = 1;
            PORTA = puerto_a.port;
            DelayUs(100);
      }
   }

   SCLK = 0;
   PORTA = puerto_a.port;
         
      if(ic == 1)
         TFS1 = 1;
      else
      TFS2 = 1;
      PORTB = puerto_b.port;
   
      //Wait until the calibration is finished
      if(calibration_process)
      {
      if(ic == 1)
         {
            puerto_b.port = PORTB;
         while(DRDY1)
            puerto_b.port = PORTB;
      }
      else
      {
         puerto_b.port = PORTB;
         while(DRDY2)
            puerto_b.port = PORTB;
      }
      }
      //Make clock idle low
      SCLK = 0;
      PORTA = puerto_a.port; 
}

unsigned long read_ad7711(unsigned char output_register, unsigned char ic)
{
   unsigned long data = 0x00000000;
      unsigned char i;
   unsigned char buffer_temp = 0x00;
     
      //Make SDATA an input
      if(ic == 1)
         TRIS_SDATA1 = 1;
      else
      TRIS_SDATA2 = 1;
     
    if(output_register == 0x01)
       A0 = 1;
    else
       A0 = 0;
       
      PORTA = puerto_a.port;
   
      if(output_register == 0x01)   
      {
      if(ic == 1)   
      {
         puerto_b.port = PORTB;
         while(DRDY1)
            puerto_b.port = PORTB;
      }
      else
      {
         puerto_b.port = PORTB;
         while(DRDY2)
            puerto_b.port = PORTB;
      }
   }
   
      if(ic == 1)
      { 
         RFS1 = 0;
      }
      else
      {
      RFS2 = 0;
      }
      PORTB = puerto_b.port;
            
   GIEL = 0;
   GIEH = 0;
      for(i=0;i<24;++i)
      {
        DelayUs(10);
         SCLK = 0;
         PORTA = puerto_a.port;
         DelayUs(10);
         SCLK = 1;
         PORTA = puerto_a.port;
                        
      buffer_temp = PORTB;
        data <<= 1;
        
        if(ic == 1)
      {
         SDATA1 = (buffer_temp & 0b00100000) >> 5;
            data |= SDATA1;
        }
      else
      {
         SDATA2 = (buffer_temp & 0b00010000) >> 4;
         data |= SDATA2;
      }
      }
   
      if(ic == 1)
         RFS1 = 1;
      else
      RFS2 = 1;
   PORTB = puerto_b.port;
 
      //Make clock idle low
      SCLK = 0;
      PORTA = puerto_a.port;

   GIEL = 1;
   GIEH = 1;

      return data;
}

void setup_ad7711(unsigned long settings, unsigned char calibration_process, unsigned char ic)
{
   write_ad7711(settings,0x00,calibration_process, ic);
}

unsigned char check_ad7711(void)
{
   unsigned long value1 = 0x00;
   unsigned long value2 = 0x00;
   value1 = read_ad7711(0x00, 1);
   value2 = read_ad7711(0x00, 2);

   //The initial value stored in the control register after a power up.
   if(value1 == 0x00000146 && value2 == 0x00000146)
      return 1;
   
   return 0;
}

float convert_to_resistance(unsigned long data)
{
   float resultado = 0.0f;

      resultado = data*ADC_RESOLUCION;
      resultado /= 0.000200f;
      return resultado;
}


And if I remember correctly, this is how to use it:


Code:

    init_ad7711();
   
    if(!check_ad7711())
    {
       printf("Error in AD7711\r\n");
         while(1);
   }
   
   setup_ad7711(control1,TRUE,1);
   setup_ad7711(control2,TRUE,2);
   
   InitPID();

   DelayMs(200);   

   lectura_a = read_ad7711(FALSE,1);


I had two AD7711 with a PT100 each, this was for a PID routine. Hope this help you.

Sorry for the spanish comments in code Smile
Regards.
abm.ben



Joined: 02 Sep 2008
Posts: 4

View user's profile Send private message

PostPosted: Thu Sep 11, 2008 4:39 am     Reply with quote

hi "iqdamn"!

Thank you for your quick answer.

No problem to adapt this code to ccs. Smile

But in your code it miss the "defines.h" file. please can you give me it. Crying or Very sad

and also what "puerto_a.port" refers to?

bye. Very Happy
BATMAN



Joined: 10 Dec 2008
Posts: 1

View user's profile Send private message

PostPosted: Wed Dec 10, 2008 3:14 pm     Reply with quote

Hi iqdamn

I have a problem and hope you help me.

I have written the software and I read the control and data register but I can't write to the control register. I have checked the datasheet many times but I couldn't solve it. The control register doesn't change when I write in it Sad

I have checked the write function in your driver it is the same as mine but it doesn't work. Sad
johnpoo



Joined: 23 Mar 2010
Posts: 9

View user's profile Send private message

PostPosted: Fri Apr 02, 2010 12:23 am     Reply with quote

Hi iqdamn

I tried your program, but there is a problem. I cannot calibrate the AD7710.
?
Help needed.
jungemed



Joined: 10 Apr 2015
Posts: 2

View user's profile Send private message

ad7710
PostPosted: Sun Apr 12, 2015 6:59 am     Reply with quote

hi
I tried to work with ad7710 ı used to your driver but is not work. I always get "Error trying to access the AD7710\r\n" Confused . I change your program lıke
Code:

int32 check_ad7710_int()
{
   int32 value = 0x00;
   value = read_ad7710(FALSE);
   
   //The initial value stored in the control register after a power up.
   if(value == 0x00000146)
      return value;
   
   return value;
}

for know to return value. And I get always 0x1C0146. I can not solve this problem. Help me plz.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> Code Library 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