PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : TWI - kommunikation zw. atmega168 und ad7745



salle
06.12.2006, 18:26
Hallo!

Ich hab ein Problem mein Programm funktioniert
zwar in der Simulation, aber nicht bei der Anwendung.
Wenn ich mit dem Oszi den TWI bus ausmesse, dann werden
keine Signale auf den Bus gesendet.
Anbei habe ich meine files.
Vielleicht könnte mir jemand helfen.

Danke ganz liebe Grüße
Christian

salle
06.12.2006, 20:56
Hier sind die Files noch mal angegeben



// main file

#include <inttypes.h>
#include <avr/io.h>
#include "i2cmaster.h"

#define ad7745 0x90 // Bauteiladresse laut Datenblatt

void ad7745_init(void); // Funktion zur Initialization des AD7745
uint32_t read_data(void); // Funktion zur lesen der Daten vom AD7745
// uint24_t verwendet 24bit
void warten(int); // Warteschleife


void main(void)
{
uint32_t cap = 0;

DDRD = 0xff; // Port D als Ausgänge definiert
PORTD = 0x00;

i2c_init(); // init I2C interface

ad7745_init(); // init AD7745

cap = read_data(); // Kapazitätswert einlesen

}

//================
// Warteschleife
//================

void warten(int t)
{
int h;
for (;t>0;t--)
{
for (h=1000;h>0;h--) {}
}
return;
}


//=========================================
// Funktion zum lesen der Daten vom AD7745
//=========================================

uint32_t read_data(void)
{
uint32_t cap_wert = 0;
uint32_t cap_wert_h = 0;
uint32_t cap_wert_m = 0;
uint32_t cap_wert_l = 0;

i2c_start_wait(ad7745+I2C_WRITE); // AD ansprechen + Schreibmodus
i2c_write(0x01); // Pointer auf Adresse 1 Setzen

i2c_rep_start(ad7745+I2C_READ); // Repeat Start => Lesemodus
// Auto increment Pointer durch Baustein
cap_wert_h = i2c_readAck(); // Cap Channel Data - H byte
cap_wert_m = i2c_readAck(); // Cap Channel Data - M byte
cap_wert_l = i2c_readNak(); // Cap Channel Data - L byte

i2c_stop(); // setzt Stop Bit => Bus verlassen

cap_wert = (cap_wert_h<<16) & (cap_wert_m<<8) & (cap_wert_l); // H-M-L zu 1Wert zusammenfassen


return cap_wert;
}


//============================
// Initialization des AD7745
//============================

void ad7745_init(void)
{
unsigned char ret;

// Einstellungen in Register schreiben
ret = i2c_start(ad7745 + I2C_WRITE); // Bauteiladresse + Schreibmodus


if ( ret ) {
// falls Gerät nicht reagiert
i2c_stop();
// gesetzt => zB LED leuchtet
}
else {
// StartBit ist angekommen
i2c_write(0x07); // Adresspointer greift auf CAP SET-UP Reg zu

i2c_write(0x80); // 0x80 in Cap Set-Up geschrieben (CAP enabled)

i2c_write(0x00); // VT Set-Up (Temp deaktiviert)
i2c_write(0x00); // EXC Set-Up
i2c_write(0x01); // Config , continous Conversion

i2c_write(0x00); // CAP DAC A
i2c_write(0x00); // CAP DAC B

i2c_write(0x80); // CAP Offset H
i2c_write(0x00); // CAP Offset L


// factory calibration
//i2c_write(0x00); // CAP Gain H
//i2c_write(0x00); // CAP Gain L

//i2c_write(0x00); // CAP
//i2c_write(0x00); // CAP DAC A

i2c_stop(); // StopBit setzen und Bus verlassen
}
}




// library
#include <inttypes.h>
#include <compat/twi.h>

#include "i2cmaster.h"


// definieren der CPU-Frequenz
#ifndef F_CPU
#define F_CPU 8000000UL
#endif

// I2C clock in Hz
#define SCL_CLOCK 100000L


//===========================
// Initialisierung des TWI
//===========================
void i2c_init(void)
{
// initialisiert TWI clock: 100 kHz clock, TWPS = 0 => prescaler = 1

TWSR = 0; // kein prescaler
TWBR = ((F_CPU/SCL_CLOCK)-16)/2; // muß > 10 für eine stabile operation

}

//================================================
// START Sequenz mit Geräteadresse
// return 0 = erreichbar, 1= nicht erreichbar
//================================================
unsigned char i2c_start(unsigned char address)
{
uint8_t twst; // verwendet exakt N bits

// sendet START Bit
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);

// warten bis Interrupt bit ausgelöst wird
while(!(TWCR & (1<<TWINT)));

// liest Wert des TWI Status Registers aus und maskiert Prescaler bits
twst = TW_STATUS & 0xF8;
if ( (twst != TW_START) && (twst != TW_REP_START)) return 1;

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

// warten auf interrupt
while(!(TWCR & (1<<TWINT)));

// liest Wert des TWI Status Registers aus und maskiert Prescaler bits
twst = TW_STATUS & 0xF8;
if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return 1;

return 0;

}


/************************************************** ***********************
Issues a start condition and sends address and transfer direction.
If device is busy, use ack polling to wait until device is ready

Input: address and transfer direction of I2C device
************************************************** ***********************/
void i2c_start_wait(unsigned char address)
{
uint8_t twst;


while ( 1 )
{
// sendet START bit
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);

// auf Int warten
while(!(TWCR & (1<<TWINT)));

// liest Wert des TWI Status Registers aus und maskiert Prescaler bits
twst = TW_STATUS & 0xF8;
if ( (twst != TW_START) && (twst != TW_REP_START)) continue;

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

// warten auf int
while(!(TWCR & (1<<TWINT)));

// liest Wert des TWI Status Registers aus und maskiert Prescaler bits
twst = TW_STATUS & 0xF8;
if ( (twst == TW_MT_SLA_NACK )||(twst ==TW_MR_DATA_NACK) )
{
// device busy, send stop condition to terminate write operation
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);

// warten auf Stop-Bit Bestätigung und Busfreigabe
while(TWCR & (1<<TWSTO));

continue;
}
//if( twst != TW_MT_SLA_ACK) return 1;
break;
}

}


/************************************************** ***********************
Issues a repeated start condition and sends address and transfer direction

Input: address and transfer direction of I2C device

Return: 0 device accessible
1 failed to access device
************************************************** ***********************/
unsigned char i2c_rep_start(unsigned char address)
{
return i2c_start( address );

}


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

// wartet auf Bestätigung => Bus-Freigabe
while(TWCR & (1<<TWSTO));

}


/************************************************** ***********************
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;

// sendet daten zum adressierten gerät
TWDR = data;
TWCR = (1<<TWINT) | (1<<TWEN);

// wartet auf fertige Übertragung
while(!(TWCR & (1<<TWINT)));

// liest Wert des TWI Status Registers aus und maskiert Prescaler bits
twst = TW_STATUS & 0xF8;
if( twst != TW_MT_DATA_ACK) return 1;
return 0;

}


/************************************************** ***********************
Read one byte from the I2C device, request more data from device

Return: byte read from I2C device
************************************************** ***********************/
unsigned char i2c_readAck(void)
{
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
while(!(TWCR & (1<<TWINT)));

return TWDR;

}


/************************************************** ***********************
Read one byte from the I2C device, read is followed by a stop condition

Return: byte read from I2C device
************************************************** ***********************/
unsigned char i2c_readNak(void)
{
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT)));

return TWDR;

}