AD7746 demo code
#include <stdio.h>
#include <stdlib.h>
#include <avr/io.h>
#include <util/twi.h> //I2C registers
#include <util/delay_basic.h> //wait delay loop for page write
#define SCL 50000 //100KHz clock
#define _AK_ (1<<TWINT)|(1<<TWEN)|(1<<TWEA) //for setting up I2C read with AK and NAK from master
#define _NAK_ (1<<TWINT)|(1<<TWEN)
#define F_CPU 20000000UL
typedef unsigned char u08;
typedef unsigned short u16;
#define BAUDRATE (unsigned long)9600
#define BAUDDIV (u16)( ((float)F_CPU/(BAUDRATE*16UL)) -1 )//baud divider
void init_i2c(void);
void i2cstart(void);
void i2cstop(void);
u08 i2cread(u08 ak);
void i2cwrite(u08 c);
//----------General I2C functions-------------------------------------------------------------------------
volatile u08 I2Cerr;
void init_i2c()
{
TWBR=(u08)(((float)F_CPU/(2.0*(float)SCL))-8.0);//sets the correct clock rate defined as SCL
} //we dont need to enable the hardware - its done in write
void i2cstart()
{
u16 timeout=1;
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); //send start
while (!(TWCR & (1<<TWINT)) && timeout)
timeout++; //wait for a start to be transmitted
if(!timeout)
I2Cerr|=16; //timeout out waiting for start error
TWCR = (1<<TWEN ); //clear the start condition
if (((TWSR & 0xF8) != TW_START)&&((TWSR & 0xF8) != TW_REP_START))
I2Cerr|=1; //error
}
void i2cstop()
{
u16 timeout=1;
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
while (!(TWCR & (1<<TWSTO)) && timeout)//wait for stop to be sent
timeout++;
if(!timeout)
I2Cerr|=64; //timeout waiting for stop error
}
void i2cwrite(u08 c)
{
u16 timeout=1;
TWDR = c; //load the data
TWCR = (1<<TWINT)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)) && timeout)//wait for it to be sent
timeout++;
if(!timeout)
I2Cerr|=32; //timeout out waiting for write complete error
if ( ((TWSR&0xF8)!=TW_MT_SLA_ACK)&&((TWSR&0xF8)!=TW_MR_SLA_ACK)&&((TWSR&0xF8)!=TW_MT_DATA_ACK) )
I2Cerr|=2; //error
}
u08 i2cread(u08 ak)
{
u16 timeout=1;
TWCR=ak;
while ((!(TWCR & (1<<TWINT))) && timeout)
timeout++; //wait for it to be recieved
if(!timeout)
I2Cerr|=8; //timeout out waiting for data response error
if(((TWSR & 0xF8) !=TW_MR_DATA_ACK) && ((TWSR & 0xF8) !=TW_MR_DATA_NACK))
I2Cerr|=4;
return TWDR;
}
//comms
int put_char(char c, FILE * stream)
{
while(!(UCSR0A & (1<<UDRE0))); //unbuffered tx comms
UDR0 = c;
return 0;
}
int get_char(FILE * stream)
{
while( !(UCSR0A & (1<<RXC0)) );
return(UDR0);
}
//the main code
int main()
{
//setup code
UCSR0B = (1<<RXEN0)|(1<<TXEN0); //mega xx8 registers - enable tx and rx, with no interrupts
UCSR0C = (1<<UPM01)|(1<<UPM00)|(1<<UCSZ01)|(1<<UCSZ00);//setup 8O1
UBRR0L = BAUDDIV;
UBRR0H = BAUDDIV>>8; //end of UART setup
FILE mystdio = FDEV_SETUP_STREAM(put_char, get_char, _FDEV_SETUP_RW);
stdout=&mystdio;
unsigned char command_humidity[]={0x90,0x07,0x81,0x81,0x23,0x01,0xFF};//the humi channel and the temp sensor
unsigned char command_level[]={0x90,0x07,0xC1,0x81,0x0B,0x01,0xFF};//the level sensor channel
init_i2c(); //initialise the I2C
unsigned char n,m,l;
unsigned long int b;
float humidity,temperature,level;
printf("Hello world\n\r");
while(1)
{
for(m=0;m<100;m++)
{
i2cstart();
i2cwrite(0xBF); //reset the AD7746
i2cstop();
I2Cerr=0;
i2cstart();
for(n=0;command_humidity[n]!=0xFF;n++)
{
i2cwrite(command_humidity[n]);
}
i2cwrite(255); //the capdac setting for humidity
do{ //wait for the conversion
i2cstop();
i2cstart();
i2cwrite(0x90);
i2cwrite(0x00);
i2cstart();
i2cwrite(0x91);
}while(i2cread(_NAK_)&0x04);
i2cstop();
i2cstart();
i2cwrite(0x90);
i2cwrite(0x01); //set to first register
i2cstart(); //restart
i2cwrite(0x91); //read from slave
b=0;
for(n=3;n;n--)
{
b|=((unsigned long int)i2cread(_AK_))<<(8*(n-1));
}
humidity+=((float)b)/1.67e8;
b=0;
for(n=2;n;n--)
b|=((unsigned long int)i2cread(_AK_))<<(8*n);
b|=(unsigned long int)i2cread(_NAK_);
temperature+=((((float)b)/2048.0)-4096.0)/100.0;
i2cstop();
i2cstart();
i2cwrite(0xBF); //reset the AD7746
i2cstop();
i2cstart();
for(n=0;command_level[n]!=0xFF;n++)
i2cwrite(command_level[n]);
i2cwrite(190); //the capdac setting
do{ //wait for the conversion
i2cstop();
i2cstart();
i2cwrite(0x90);
i2cwrite(0x00);
i2cstart();
i2cwrite(0x91);
l=i2cread(_NAK_);
}while(l&0x04);
i2cstop();
i2cstart();
i2cwrite(0x90);
i2cwrite(0x01); //set to first register
i2cstart(); //restart
i2cwrite(0x91); //read from slave
b=0;
for(n=2;n;n--)
b|=((unsigned long int)i2cread(_AK_))<<(8*n);
b|=(unsigned long int)i2cread(_NAK_);
level+=((float)b)/1.67e8;
i2cstop();
}
putchar(12);
printf("Temperature=%f\n\r Humidity=%f\n\r Level=%f\r\n",(double)temperature,(double)humidity,(double)level);
printf("Status:%2X\n\r",l);
temperature=0;
humidity=0;
level=0;
}
}