UKHAS Wiki

UK High Altitude Society

User Tools

Site Tools


code:capdac

This is an old revision of the document!


#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.1242776190.txt.gz · Last modified: 2009/05/19 23:36 by laurenceb

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki