Atmega48 - AD5121 I2C ongelma

Atmegan ja AD5121 digipotikan I2C yhteys tuottaa ongelmia C:llä
Visualmicrolla homma toimii, käyttäein arduinon kirjastoa… Eli raudassa ei ole vikaa.
I2C väylässä ei ole vastuksia vaan sisäiset ylösvedot.

Arduinon koodi:

Wire.beginTransmission(0x2F); //  Address #47
Wire.write(0x10);             //  Instruction byte
Wire.write(val);              //  Potentiometer value
Wire.endTransmission(); 

C koodissa olen käyttänyt osoitetta 0x20 koska digipotikan oikealla (0x2F) osoitteella oskiloskoopissa ei näy mitään… Johtuu varmaan siitä että kellojakson viimeinen bitti on aina 1.

Eli kertokaas mikä koodissa mättää…

C koodi:[code]
/* Crystal 20 MHz */
#define F_CPU 20000000L

/* I2C clock in Hz */
#define SCL_CLOCK 222000L

#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
#include <avr/interrupt.h>
#include <compat/twi.h>

/*************************************************************************
Initialization of the I2C bus interface. Need to be called only once
************************************************************************/
void i2c_init(void)
{
/
initialize TWI clock: 100 kHz clock, TWPS = 0 => prescaler = 1 /
TWSR = 0; /
no prescaler /
TWBR = ((F_CPU/SCL_CLOCK)-16)/2; /
must be > 10 for stable operation /
}/
i2c_init */

/*************************************************************************
Issues a start condition and sends address and transfer direction.
return 0 = device accessible, 1= failed to access device
*************************************************************************/
unsigned char i2c_start(unsigned char address)
{
uint8_t twst;

// send START condition
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);

// wait until transmission completed
while(!(TWCR & (1<<TWINT)));

// check value of TWI Status Register. Mask prescaler bits.
twst = TW_STATUS & 0xF8;
if ( (twst != TW_START) && (twst != TW_REP_START)) return 1;

// send device address
TWDR = address;
TWCR = (1<<TWINT) | (1<<TWEN);

// wail until transmission completed and ACK/NACK has been received
while(!(TWCR & (1<<TWINT)));

// check value of TWI Status Register. Mask prescaler bits.
twst = TW_STATUS & 0xF8;
if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return 1;

return 0;
}/* i2c_start */

/*************************************************************************
Terminates the data transfer and releases the I2C bus
************************************************************************/
void i2c_stop(void)
{
/
send stop condition */
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);

// wait until stop condition is executed and bus released
while(TWCR & (1<<TWSTO));

}/* i2c_stop */

/*************************************************************************
Send one byte to I2C device

Input: byte to be transfered
Return: 0 write successful
1 write failed
*************************************************************************/
unsigned char i2c_write( unsigned char data )
{
uint8_t twst;

// send data to the previously addressed device
TWDR = data;
TWCR = (1<<TWINT) | (1<<TWEN);

// wait until transmission completed
while(!(TWCR & (1<<TWINT)));

// check value of TWI Status Register. Mask prescaler bits
twst = TW_STATUS & 0xF8;
if( twst != TW_MT_DATA_ACK) return 1;
return 0;

}/* i2c_write */

int main(void)
{
DDRC = 0xff; // use all pins on port C for output
DDRD = 0xff; // use all pins on port D for output

PORTD |= (1 << PD5);	// led on
PORTC |= (1 << PC4) | (1 << PC5);			// pull-up

_delay_ms(1000);

for(;:wink:
{

i2c_init();                   // init I2C interface
i2c_start(0x20);	      // set device address (oikea 0x2F)
i2c_write(0x10);         // set device control byte
i2c_write(0xFF);         // set pot value	
i2c_stop();

_delay_ms(10);

}
}
[/code]

Oskiloskooppikuva:
Kuvassa ylimääräset piikit merkattu.

onkos tuo, mikä pomppaa TWI (i2C) protokollan paheksuntabitti. En nyt lähtenyt laskemaan pallukoita, mutta luulisin näin. AD:n datalehti kouran ja katsoon, mitä käsket väärin ja milloin tuo piiri heittäää sen ylös. Koodi näytti nopeasti söpöltä ja oikealta, mutta jossain on jotain varmasti pielessä.

“Ylimääräiset piikit” tulee kun osoite on väärä? luulisin?
Potikan 0x2F osoitteella oskilloskooppi ei löydä signaalia. Miksi?

Joskos jollain olisi vielä vinkkejä tähän :wink:

Oskilloskooppi kuva vielä arduinon koodista missä homma pelittää…

Hieman rasittavaa katsoa kuvaa oskilloskoopin kuvasta…
Mutta jos nyt tulkitsin oikein niin arduino puhuu 0x2f osoitteeseen ja mikään laite ei ole nykäisemässä datalinjaa alas OK:n merkiksi. Toinen tavu on mielestäni 0x10 tai 0x08 ja se menee läpi arduinolla. Lopuksi tulee 0xff Ja ensimmäinen tavu on se tärkeä, koskaa se on osoite.

Sain toimimaan myös C koodilla osoite täytyi olla 8 bittinen. eli (0x2F*2)

Hienoa.

(0x2f * 2) == 0x5e == (0x2f << 1)
Eli voisko olla niin, että seitsemän ylintä bittiä on osoite, sitten on joku bitti esim, luku/kirjoitus. En vieläkään katsonut tuon datasheettiä. sieltä sekin varmasti löytyisi…

Joo, se on noin I2C:ssä aina.

Wikipedia:
en.wikipedia.org/wiki/I2C

Arduinon vähän hassu selitys.
arduino.cc/en/reference/wire