| 
	
	|  |  |  
	
		| View previous topic :: View next topic |  
		| Author | Message |  
		| iqdamn 
 
 
 Joined: 16 Oct 2006
 Posts: 2
 Location: Mexico city
 
 
			      
 
 | 
			
				| Driver for AD7710 |  
				|  Posted: Mon Oct 16, 2006 9:16 pm |   |  
				| 
 |  
				| Hi everybody, this is my first post and my first driver  , 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.
   
 
  	  | 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 !!
  |  |  
		|  |  
		| abm.ben 
 
 
 Joined: 02 Sep 2008
 Posts: 4
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Tue Sep 09, 2008 8:07 am |   |  
				| 
 |  
				| 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!
 
  |  |  
		|  |  
		| iqdamn 
 
 
 Joined: 16 Oct 2006
 Posts: 2
 Location: Mexico city
 
 
			      
 
 | 
			
				| AD7711 |  
				|  Posted: Wed Sep 10, 2008 12:01 pm |   |  
				| 
 |  
				| 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
   Regards.
 |  |  
		|  |  
		| abm.ben 
 
 
 Joined: 02 Sep 2008
 Posts: 4
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Thu Sep 11, 2008 4:39 am |   |  
				| 
 |  
				| hi "iqdamn"! 
 Thank you for your quick answer.
 
 No problem to adapt this code to ccs.
   
 But in your code it miss the "defines.h" file. please can you give me it.
   
 and also what "puerto_a.port" refers to?
 
 bye.
  |  |  
		|  |  
		| BATMAN 
 
 
 Joined: 10 Dec 2008
 Posts: 1
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Wed Dec 10, 2008 3:14 pm |   |  
				| 
 |  
				| 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
   
 I have checked the write function in your driver it is the same as mine but it doesn't work.
  |  |  
		|  |  
		| johnpoo 
 
 
 Joined: 23 Mar 2010
 Posts: 9
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Fri Apr 02, 2010 12:23 am |   |  
				| 
 |  
				| 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
 
 
 
			    
 
 | 
			
				| ad7710 |  
				|  Posted: Sun Apr 12, 2015 6:59 am |   |  
				| 
 |  
				| 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"
  . 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.
 |  |  
		|  |  
		|  |  
  
	| 
 
 | 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
 
 |