evg

Работа с АЦП AD7710 и её Российским аналогом 1273ПВ8Р.



#define TRUE 1
#define FALSE 0
 
//определение используемых пинов
 #define DRDY    	7 
 #define RFS    	9 
 #define TFS    	8 
 #define AO       	11 
 #define SCLK    	13 
 #define SDATA    	12
 #define SYNC    	10 

 //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(unsigned long data) 
 { 
    int i; 
    byte calibration_needed = FALSE; 
    unsigned long t; 
	//определим необходимость выполнения калибровки
    if(data & SELF_CALIBRATION || data & SYSTEM_CALIBRATION_1 || data & SYSTEM_CALIBRATION_2 || data & OFFSET_CALIBRATION) 
          calibration_needed = TRUE; 
    pinMode(SDATA,OUTPUT);
    digitalWrite(SCLK,LOW);
    digitalWrite(AO,LOW); 
    digitalWrite(TFS,LOW); 

    //запишем 24 бита данных
    for(i=23;i>=0;i--) 
    { 
      digitalWrite(SCLK,LOW); 
      t=data & (1L<<i);

      digitalWrite(SDATA, (t)?HIGH:LOW); 
      digitalWrite(SCLK,HIGH); 
    } 
    digitalWrite(SCLK,LOW); 
    digitalWrite(TFS,HIGH); 

    //подождем окончания процесса калибровки
    if(calibration_needed) {
          while(digitalRead(DRDY)); 
          digitalWrite(SYNC,LOW);
          digitalWrite(SYNC,HIGH);
    }

 } 

// чтение из регистров
unsigned long read_ad7710(byte output_register) 
 { 
     long data = 0x00; 
    int i;
    pinMode(SDATA, INPUT);
    digitalWrite(RFS, HIGH); 
    digitalWrite(TFS, HIGH);
    digitalWrite(AO, output_register);

    if(output_register)
          while(digitalRead(DRDY)==HIGH); 

    digitalWrite(RFS, LOW);
    for(i=23;i>=0;i--) 
    { 
      if(digitalRead(SDATA))data|=(1L<<i);
      digitalWrite(SCLK,HIGH);
      digitalWrite(SCLK,LOW);
    }
    digitalWrite(RFS, HIGH);
    return data; 
 } 

// запись настроек
 void setup_ad7710(unsigned long settings) 
 { 
     Serial.print("Write settings:");
     Serial.println(settings, HEX);
     write_ad7710(settings); 
 } 

// Проверка работоспособности микросхемы.
// Проверяется начальное значение CONTROL_REGISTER, по умолчанию равно 0x146.
// Но, я для проверки использую предварительно записанное значение в CONTROL_REGISTER.
// Причем необходимо учитывать, что при выполнении процедуры калибровки биты разрешения
// калибровки сбросятся автоматически
 byte check_ad7710(unsigned long v) 
 { 
    unsigned long value = 0x00; 
    value = read_ad7710(FALSE); 
    Serial.print("Check: ");Serial.print (value,HEX);Serial.print ("/"); Serial.println (v,HEX);
	if(value == v)
       return TRUE; 
    return FALSE; 
 } 


// инициализация 
 void init_ad7710() 
 { 
    
   pinMode(TFS,OUTPUT);
   pinMode(RFS,OUTPUT);
   pinMode(AO,OUTPUT);
 //  pinMode(DRDY,INPUT);
   pinMode(SCLK,OUTPUT);
   pinMode(SYNC,OUTPUT);

  digitalWrite(TFS,HIGH);
  digitalWrite(RFS,HIGH);
  digitalWrite(AO,HIGH);
  digitalWrite(SCLK,LOW);
  digitalWrite(SYNC,HIGH);

 }


 #define FCLK 10000000
// Определение значения фильтра
#define FS(f) ((FCLK/512) / f)
// Для 1273ПВ8Р не используется, т.к. не все значения работают.
// Для этой микросхемы выбираем значение фильтра из таблицы:
/*
FS   Fnotch
20 976,56
23 849,18
40 488,28
47 415,56	
80 244,14
88 221,95
95 205,59
160 122,07
176 110,97
191 102,26
320 61,04
352 55,49
383 51
640 30,52
704 27,74
767 25,46
1280 15,26
1408 13,87
1535 12,72
*/
 
// Значение фильтра 
unsigned long fs_code = 320;
// Настройки АЦП
 unsigned long settings = GAIN_8|CHANNEL_2|WORD_24|BIPOLAR|fs_code;
// Коэффициент усиления
 int Ku = 8;
// Опорное напряжение
 int Vref = 2.45097;

void setup() {


  // put your setup code here, to run once:
    Serial.begin(9600);
    init_ad7710(); 

    setup_ad7710(SELF_CALIBRATION|settings);
    if(check_ad7710(settings)) 
    { 
       Serial.println("AD7710 check OK!"); 
    } 
    else 
    { 
       Serial.println("Error trying to access the AD7710\r\n"); 
       while(!check_ad7710(settings))delay(500);
    } 
   //  setup_ad7710(BACKGROUND_CALIBRATION|settings);

}

void loop() {
 // put your main code here, to run repeatedly:
 long data = 0x00; 
 // Чтение данных из DATA_REGISTER и расчет напряжения
 data = read_ad7710(TRUE); 
 while(TRUE) 
 {
    Serial.print("Data = ");Serial.print(data);Serial.print(" (");
    if(settings & UNIPOLAR) 
      Serial.print(data/Ku*Vref/Ku*0xffffff,4); 
    else 
      Serial.print((data - 0x7fffff)/ Ku * ( 2*Vref/0xffffff),4); 
      Serial.println("V)");

      data = (data*3 + read_ad7710(TRUE))/4; 

 }

}

Коментарии