AD7797
Production
The AD7796/AD7797 are complete, analog front ends for high
precision, bridge sensor applications such as weigh scales. The
AD7796/AD7797 contain a S-?...
Datasheet
AD7797 on Analog.com
Hi everyone,
I am working on AD7797, created a custom PCB with atmega328p chip(arduino uno) and also written firmware for this. I am able to communicate with AD7797 but while reading ADC value it false data. Same data repeats. Please help me i am attaching PCB schematic and arduino code. Kindly share some library or code for AD7797.
Regards
Suman
#include <SPI.h> // include the SPI library:
#define cs 10
void setup()
{
Serial.begin(9600); // initialize serial port
pinMode(SCK, OUTPUT);
pinMode(MOSI, OUTPUT);
pinMode(MISO, INPUT);
pinMode(cs, OUTPUT);
digitalWrite(cs, HIGH);
SPI.begin(); // wake up the SPI
SPI.setDataMode(SPI_MODE3); // datasheet p6-7
SPI.setBitOrder(MSBFIRST);
SPI.setClockDivider(SPI_CLOCK_DIV32); // datasheet p6
Serial.println("AD7797 Test");
initAD7797();
}
void initAD7797()
{
beginAD7797();
resetAD7797(); //reset device
delay(2);
if (!(getID() % 2))
{
Serial.println("ID : AD7796");
}
else
{
Serial.println("ID : AD7797");
}
Serial.print("Configuration : "); Serial.println(readCFG(), BIN);
}
void beginAD7797() //must be mode3
{
//SPCR = (1<<SPE)|(1<<MSTR)|(1<<CPOL)|(1<<CPHA)|(1<<SPR0); //mode3, 1MHz
SPCR = (1 << SPE) | (1 << MSTR) | (1 << CPOL) | (1 << CPHA); //mode3, 4MHz
}
void resetAD7797() //p14
{
digitalWrite(cs, LOW); //reset IC by sending out 32b of 1s
transferAD7797(0xFF);
transferAD7797(0xFF);
transferAD7797(0xFF);
transferAD7797(0xFF);
digitalWrite(cs, HIGH);
}
uint8_t getID() //WORKS!
{
uint8_t output = 0;
digitalWrite(cs, LOW);
transferAD7797(0x60); //01100000 0x60
output = transferAD7797(0x00);
digitalWrite(cs, HIGH);
return output;
}
//read value from ADC,
long readAD7797()
{
long value = 0; //uint16_t byte1, byte2, byte3;
//selectCH(ch);
selectMode();
while (readST() > 127); //wait until !RDY
digitalWrite(cs, LOW);
transferAD7797(0x58); //select DATA register (01011000)(0x58) //one read try (01011100)(0x5C) for CREAD
value = (transferAD7797(0x00) << 16) & 0xFF0000;
value += (transferAD7797(0x00) << 8) & 0xFF00; //grab top byte
value += transferAD7797(0x00) & 0xFF; //grab bottom byte
digitalWrite(cs, HIGH); //pull CS high to disengage
return value; //return( ((byte1<<8) | byte2) & 0xFFFF);
}
uint16_t readCFG() //works!
{
long output = 0;
digitalWrite(cs, LOW);
transferAD7797(0x50); //select CONFIGURATION register (01010000)(0x50)
output = (transferAD7797(0x00) << 8) & 0xFF00; //grab top byte
output += transferAD7797(0x00) & 0xFF; //grab bottom byte
digitalWrite(cs, HIGH);
return output;
}
uint8_t readST() //works!
{
long output = 0;
digitalWrite(cs, LOW);
transferAD7797(0x40); //select STATUS register (01000000)(0x40)
output = transferAD7797(0x00); //grab byte
digitalWrite(cs, HIGH);
return output;
}
//select adc channel
void selectCH(uint8_t ch)
{
if (ch > 2)
ch = 2;
ch |= 0x90;
digitalWrite(cs, LOW); //pull CS low to engage
transferAD7797(0x10); //select configuration register 00010000 (0x10)
transferAD7797(0x10); //Write 16 bits to CONFIGURATION register:
//bias voltage: disabled 0 0
//burnout current: disabled 0
//bipolar operation: 0 or 1?
//boost: disabled 1
//gain: disabled 0 0 0
//top 8b: 00011000 (0x18), disable boost yields 00010000 (0x10)
transferAD7797(ch); //internal reference 1
//0 0
//buffer 1
//0
//000 (CH1) 001(CH2) 010(CH3)
//channel select = AIN1(+) - AIN1(-)
//bottom 8b: 10010000 (0x90) 10010001 (0x91) read CH2 10010010 (0x92) read CH3
digitalWrite(cs, HIGH); //pull CS high to disengage
}
void selectMode()
{
digitalWrite(cs, LOW); //pull CS low to engage
transferAD7797(0x08); //select MODE register (00001000)(0x08)
//Write 16 bits to MODE register on page 16 Table 15
transferAD7797(0x20); //0x00 for continuous
//0x20 for single conversion preferred
//0x40 for idle
//0x60 for power down
//0x80 internal zero scale calibration
//0xA0 internal full scale calibration
//0xC0 system zero scale calibration
//0xE0 system full scale calibration
//update rate on page 16/17
transferAD7797(0x0C); //0x00 X X
//0x01 470Hz 4mS
//0x02 242Hz 8mS
//0x03 123Hz 16mS
//0x04 62Hz 32mS
//0x05 50Hz 40mS
//0x06 39Hz 48mS
//0x07 33.2Hz 60mS
//0x08 19.6Hz 101mS -90dB for 60Hz
//0x09 16.7Hz 120mS -80dB for 50Hz
//0x0A 16.7Hz 120mS -65dB for 50/60Hz
//0x0B 12.5Hz 160mS -66dB for 50/60Hz
//0x0C 10Hz 200mS -69dB for 50/60Hz
//0x0D 8.33Hz 240mS -70dB for 50/60Hz
//0x0E 6.25Hz 320mS -72dB for 50/60Hz
//0x0F 4.17Hz 480mS -74dB for 50/60Hz
digitalWrite(cs, HIGH);
}
uint8_t transferAD7797(uint8_t data)
{
beginAD7797(); //set correct SPI settings for devices
SPDR = data;
while (!(SPSR & (1 << SPIF))); //wait until transfer is done
return SPDR; //return received byte
}
void loop()
{
delay(100);
Serial.println(String("ADC Read : ") + readAD7797());
}