UKHAS Wiki

UK High Altitude Society

User Tools

Site Tools


code:capdac

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;
	}
}
code/capdac.txt ยท Last modified: 2009/05/19 23:42 by laurenceb