Sunday 4 February 2018

microcontroller - ADC registers setup using spi communication


I'm new to microcontrollers - I'm trying to read external ADC values from an AD7798 ADC using SPI communication.


Initially I have to setup some ADC registers - some registers are not configured. To configure the registers, I have to use the communication register to select which register I want to configure.


For example, I want to set the AD7798 configuration register (16bit). I have code like this: #include #define ADC_CS PORTB.3 #define WG_CS PORTB.4 #define MOSI PORTB.5 #define MISO_PU PORTB.6 #define MISO_PIN PINB.6 #define SCK PORTB.7


//global functions.
unsigned int adcConfig;
unsigned int adcMode;
unsigned int adcId;


void init_io(void)
{
DDRB = 0xBF; // make SCK, MOSI, CS1, CS2 outputs
ADC_CS = 1; //disable ADC
WG_CS = 1; //disable WaveGenerator
MISO_PU = 1; //enable pull-up on MISO so we can test !RDY
}

unsigned char spi(unsigned char data)
{

//Start transmision
SPDR = data;
//Wait for transmision complete
while (!(SPSR & (1<return SPDR;
}

//Sets the waveform generator output to given phase
void SetWGPhase(unsigned int phase)
{

SPCR = 0x5A; // mode #2 F_CPU/64
WG_CS = 0; // enable
spi(0x20);
spi(0x00);
spi((phase >> 8) | 0xC0); //Load into phase register 0
spi(phase & 0x00FF);
WG_CS = 1;
}

void setupAd(){

SPCR = 0x5D;
ADC_CS = 0;
// while(spi(0x10) != 0x10);
spi(0x10); //set up communication register for configuration reg.
spi(0x07);
spi(0x10);

spi(0x08); //set up communication register for mode reg.
spi(0x00);
spi(0x0A);

ADC_CS = 1;
}


unsigned int ReadAd(void)
{
unsigned int data;
SPCR = 0x5D; // mode #3 F_CPU/16
CheckStatus();
ADC_CS = 0; // enable

while (MISO_PIN != 0) ; // wait for DOUT/!RDY line to go low
//Read data
spi(0x58); //Place readinstruction in communication register
data = spi(0xFF); // read hi-byte
data = (data << 8) | spi(0xFF); // and lo-byte.
ADC_CS = 1; // disable
return data;
}

unsigned char CheckStatus(void)

{
char adcStatus;
SPCR = 0x5D;
ADC_CS = 0; // enable
while(ADC_CS_PIN);
adcStatus = 0xFF;
while(!(adcStatus & 0x80)){

spi(0x40);
adcStatus = spi(0xFF);

}
ADC_CS = 1;

return adcStatus;
}

unsigned int ReadAdConfReg(void)
{
unsigned int retvalconfig;
SPCR = 0x5D;

ADC_CS = 0;
while (MISO_PIN != 0) ;
spi(0x50);
adcConfig = spi(0xFF);
adcConfig = (adcConfig << 8) | spi(0xFF);
retvalconfig= adcConfig;
ADC_CS = 1;
return retvalconfig;
}


unsigned int ReadAdModeReg(void)
{
unsigned retvalmode;
SPCR = 0x5D;
ADC_CS = 0;
while (MISO_PIN != 0) ;
spi(0x48);
adcMode = spi(0xFF);
adcMode = (adcMode << 8) | spi(0xFF);
retvalmode =adcMode;

ADC_CS = 1;
return retvalmode;
}
unsigned int ReadAdIdReg(void)
{

SPCR = 0x5D;
ADC_CS = 0;
while (MISO_PIN != 0) ;
spi(0x60);

adcId = spi(0xFF);
ADC_CS = 1;
return adcId;
}

when I print configuration register it is giving value"16383". but when I power off/on the target i am getting "1808(which is equivalent to 0x0710)" after that it is giving same value as"16383". I have tested with different configurations also but it is not changing, always printing "16383" except power off/on.I think default value.


Even with mode register it is always printing"10(which is equivalent to 0x000A)" but that is the value i am getting always, even if I change the configuration to "0x0022".


Even I have tried to read Id register, but it is giving "0x48". but in data sheet it mentioned "0xX8" for AD7798. Thanks in advance.


Someone help me please, I am not getting any idea about what mistake I am doing here.




No comments:

Post a Comment

arduino - Can I use TI&#39;s cc2541 BLE as micro controller to perform operations/ processing instead of ATmega328P AU to save cost?

I am using arduino pro mini (which contains Atmega328p AU ) along with cc2541(HM-10) to process and transfer data over BLE to smartphone. I...