ATtiny45 Using Fleury's I2c issues

Go To Last Post
4 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hey guys, this is my first post so take it east on me. I am trying to use Fleury's I2c library with Atmel Studio 6.2. I am having issues reading an ADC value from a PCF8591 and figured I would see what you guys thought. I am new to I2c communication so any information would help. My code is very basic and all I am doing is setting a DAC value, taking an A/D read then comparing that A/D value with a limit to turn an LED on or Off. Here is my code:

#include 
#include "i2cmaster.h"
#include 

#define PCF8591_0 0x90      // Device address = 000
#define DAC 0x40			// DAC ID = 0x40
#define ADC0 0x40			// ADC0 ID = 0x40
#define ADC1 0x41			// ADC1 ID = 0x41
#define ADC2 0x42			// ADC2 ID = 0x42
#define ADC3 0x43			// ADC3 ID = 0x43

int main(void)
{
	DDRB |= (1<<DDB1);  //Pin 6 as Output
	uint8_t AtoD_Read;
	uint8_t Dac_Value;
	i2c_init();
	Dac_Value=0xff;
	while(1)
	{
		_delay_ms(5);
		SetDac(PCF8591_0,DAC,Dac_Value);
		AtoD_Read = AdcRead(PCF8591_0,ADC0);
		if(AtoD_Read > 0x7F)
		{
			PORTB &= ~(1<<PORTB1);
		}
		else
		{
			PORTB |= (1<<PORTB1);
		}
		Dac_Value--;
		if(Dac_Value < 0)
		{
			Dac_Value = 0xff;
		}
	}
}

And here are my functions:

void SetDac(uint16_t DevID, uint16_t DacID,uint16_t DacValue)
{
	i2c_start_wait(DevID+I2C_WRITE);					//Device ID
	i2c_write(DacID);					//Enable DAC
	i2c_write(DacValue);				//Set DAC to ~1.0v
	i2c_stop();							//Stop I2C Transmission
}

uint8_t AdcRead(uint16_t ADC_DevID, uint16_t Channel)
{
	uint8_t	ret;
	i2c_start_wait(ADC_DevID+I2C_WRITE);     // set device address and write mode
	i2c_write(Channel);
	i2c_rep_start(ADC_DevID+I2C_READ);       // set device address and read mode
	i2c_readAck();
	ret = i2c_readNak();
	i2c_stop();
	return(ret);	
}

So with this code what I am seeing is the SetDac(); function works perfectly however when I take an A/D read I get bogus data. My LED on PB1 just blinks randomly and not around my limit or ~.7v. I am using 1.5v for my reference voltage on the PCF8591 and it is addressed to zero (A0 = 0, A1 = 0, and A2 = 0).

Any idea what I might be doing wrong?[/code]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have not looked at your data sheet. However, if it wants 16-bit data, I should use 16-bit e.g.

void SetDac(uint16_t DevID, uint16_t DacID,uint16_t DacValue)
{
   i2c_start_wait(DevID+I2C_WRITE);               //Device ID
   i2c_write(DacID);               //Enable DAC
   i2c_write(DacValue>>8);         //hi
   i2c_write(DacValue);            //lo
   i2c_stop();                     //Stop I2C Transmission
}

uint16_t AdcRead(uint16_t ADC_DevID, uint16_t Channel)
{
   uint16_t   ret;
   i2c_start_wait(ADC_DevID+I2C_WRITE);     // set device address and write mode
   i2c_write(Channel);
   i2c_rep_start(ADC_DevID+I2C_READ);       // set device address and read mode
   ret = i2c_readAck() << 8;        // hi
   ret |= i2c_readNak();            // lo
   i2c_stop();
   return(ret);   
} 

You may only want 8-bits. However, re-usable functions are always useful. Simply throw away any unwanted bits.

I cant believe that your chip has a 16-bit channel numbers. If it does, you would write two 8-bit bytes for Channel.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Atmel Studio 6.2.
Do you mean AS6.1 SP2 or do you have some new secret version?

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
I have not looked at your data sheet. However, if it wants 16-bit data, I should use 16-bit e.g.

Good eye, I forgot to change that back to "uint8_t".

Quote:
Do you mean AS6.1 SP2 or do you have some new secret version?

SP2