Forum: Mikrocontroller und Digitale Elektronik IMU über TWI an ATMega32


von Benjamin B. (revolutionfx)


Angehängte Dateien:

Lesenswert?

Hallo an alle,

hab mal eine Frage zu einem IMU Combiboard
(http://www.sparkfun.com/datasheets/Sensors/IMU/6DOF-Digital-v10.pdf)

Will den Sensor über TWI/I2C mit einem ATMega32 aus lesen und auf einem 
Breedboard eine kleine Schaltung mit LEDs erstellen die dann zur 
Auswertung dient ( z.B. GrüneLED Pos.-Auslenkung in x/y/z, RoteLED 
Neg.-Auslenkung ...),
um mich dann später einwenig in Regler (P, PD, PDI) einzuarbeiten.

Der IMU hat ein integriertes I2C Interface wenn ich die Datenblätter der 
beiden Sensoren (Gyro/LinAcc) richtig interpretiert habe.
Allerdings haben sich bei mir nach dem Lesen diverser TWI und GCC TWI 
Tutorials einige Fragen aufgetan.

Der IMU hat 6 Anschlüsse GND, 3,3V, SCL, SDA sind für die TWI 
Komunikation, allerdings hat er noch einen INT0 und einen INT1 PORT.
Dienen diese Anschlüssen zur getrennten Ansprechung der Sensoren?
Es müssen ja 6 Werte (je 3) ausgelesen werden.

Habe ja hier noch eine Beispiel Programm für'n ATMega128 gfunden:
--------------------------------------------------------------------

/*
TWI Interface Library for an ATMega168
written by Ryan Owens
9/28/10
*/
#include <util/twi.h>

void twiInit(unsigned long scl_freq)
{
//Set the TWI Prescaler to 1
//(Actually this is default setting...)

//Set up the TWI Bit Rate
TWBR = F_CPU/(2*(long)scl_freq)-8; //(SCL_FREQ = F_CPU/(16+2*TWBR) 
*According to datasheet
}

//Puts the ATmega in Master Transmitter mode and sends a value to a 
register
//pre: sla - i2c address of slave
// reg_addr - the register to address
// value - the value to write in the register location
//returns: 1-Success
// TWSR - Failure (The TWI failure code)
char twiTransmit(char sla, char reg_addr, char value)
{
//Send the start condition
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); //Clear int bit(by writing a 1), 
enable twi and send start
while (!(TWCR & (1<<TWINT))); //Wait for the interrupte bit to get set
if(TW_STATUS != TW_START)return TWSR;

//No matter what we start with a write to the slave
TWDR = sla | TW_WRITE; //Put the slave address in the twi data register
TWCR = (1<<TWINT)|(1<<TWEN); //Send the address to the slave
while (!(TWCR & (1<<TWINT))); //Wait for the operatation to complete
if (TW_STATUS != TW_MT_SLA_ACK)return TWSR; //Make sure we received an 
ack from the slave.

//Load the register into the slave device that we want to alter
TWDR = reg_addr;
TWCR = (1<<TWINT)|(1<<TWEN); //Send the register address through the twi 
interface
while (!(TWCR & (1<<TWINT))); //Wait for operation to complete
if (TW_STATUS != TW_MT_DATA_ACK)return TWSR; //Make sure we received an 
ack from the slave

//Now send the actual register data to the slave
TWDR = value;
TWCR = (1<<TWINT)|(1<<TWEN); //Send the register value through the twi 
interface
while (!(TWCR & (1<<TWINT))); //Wait for operation to complete
if (TW_STATUS != TW_MT_DATA_ACK)return TWSR; //Make sure we received an 
ack from the slave

//We're finished. Send a stop.
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
return 1;
}

//Reads a value from a specified register
//pre: sla - i2c address of slave
// reg_addr - The address of the register to read from
// value - a pointer to a character
//post: value is assigned the value read from the register
//returns: 1 - Success
// TWSR - Failur
char twiReceive(char sla, char reg_addr, char * value)
{
//Send the start condition
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); //Clear int bit(by writing a 1), 
enable twi and send start
while (!(TWCR & (1<<TWINT))); //Wait for the interrupte bit to get set
if (TW_STATUS != TW_START)return TWSR; //Check the TWI status, return if 
bad status.

//Start Condition has been transmitted
//Send SLA+W to TWDR
TWDR = sla|TW_WRITE; //Put the slave address in the twi data register
TWCR = (1<<TWINT)|(1<<TWEN); //Send the address to the slave
while (!(TWCR & (1<<TWINT))); //Wait for the operatation to complete
if(TW_STATUS != TW_MT_SLA_ACK)return TWSR;

//SLA+W has been transmitted, Ack has been received
//Load the register into the slave device that we want to read
TWDR = reg_addr;
TWCR = (1<<TWINT)|(1<<TWEN); //Send the register address through the twi 
interface
while (!(TWCR & (1<<TWINT))); //Wait for operation to complete
if(TW_STATUS != TW_MT_DATA_ACK)return TWSR;

//Data byte has been transmitted, Ack has been received
//Now send a 'repeated start' to switch to master receiver mode
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); //Clear int bit(by writing a 1), 
enable twi and send start
while (!(TWCR & (1<<TWINT))); //Wait for the interrupte bit to get set
if (TW_STATUS != TW_REP_START)return TWSR;

//A Repeated Start condition has been received
//Send the SLA+R
TWDR = sla | TW_READ; //Load the slave address and the read bit into the 
data register
TWCR = (1<<TWINT)|(1<<TWEN); //Send the address+R to the slave
while(!(TWCR & (1<<TWINT))); //Wait for the operation to complete
if (TW_STATUS != TW_MR_SLA_ACK)return TWSR; //Make sure we got the right 
ack.

//SLA+R has been transmitted, Ack has been received
//Get the value from the pre-configured register on the slave
TWCR = (1<<TWINT)|(1<<TWEN); //Tell the slave to send the next value and 
send NACK afterwards
while(!(TWCR & (1<<TWINT))); //Wait for the operation to complete
if (TW_STATUS != TW_MR_DATA_NACK)return 5; //Make sure we got the right 
ack.

//Data byte has been received, Nack has been returned
//Send a stop
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);

*value = TWDR;
return 1; //Return the value we got from the register
}

//Resets the TWI interface
void twiReset(void)
{
TWCR = 0;
}

--------------------------------------------------------------

Werd daraus nur leider nich wirklich schlau.

Vllt kann mir jemand helfen der sich damit auch schon einmal herum 
geärgert hat.

Grüße Ben

von Lehrmann M. (ubimbo)


Lesenswert?

Benjamin Barth schrieb:
> Werd daraus nur leider nich wirklich schlau.

Wieviel Ahnung hast du denn von Mikrocontrollern. Du solltest in jedem 
Fall das AVR Tutorial durchmachen bevor du mit sowas anfängst.
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial

Benjamin Barth schrieb:
> Der IMU hat ein integriertes I2C Interface wenn ich die Datenblätter der
> beiden Sensoren (Gyro/LinAcc) richtig interpretiert habe.
> Allerdings haben sich bei mir nach dem Lesen diverser TWI und GCC TWI
> Tutorials einige Fragen aufgetan.
>
> Der IMU hat 6 Anschlüsse GND, 3,3V, SCL, SDA sind für die TWI
> Komunikation, allerdings hat er noch einen INT0 und einen INT1 PORT.
> Dienen diese Anschlüssen zur getrennten Ansprechung der Sensoren?
> Es müssen ja 6 Werte (je 3) ausgelesen werden.

Dafür gibt es das 2 Datenblätter für die beiden verbauten Sensoren. 
Diesen kann man sowohl die Bedeutung der einzelnen Pins (hier Interrupt, 
etc...), so wie die Kommunikation für I2C entnehmen. Ohne die geht 
garnichts.

Benjamin Barth schrieb:
> Werd daraus nur leider nich wirklich schlau.

Dann solltest du selbst lernen den Code zu programmieren und nicht 
einfach irgendwo Code zu verwenden den du nicht verstehst und auch nciht 
debuggen kannst.

Benjamin Barth schrieb:
> Vllt kann mir jemand helfen der sich damit auch schon einmal herum
> geärgert hat.

Ja um ehrlich zu sein sind das einfach triviale Grundlagen. Die Aufgabe 
besteht darin ein paar Funktionen des I2C (das darf Atmel aber nicht 
sagen darum heißt das bei denen TWI) aufzurufen und ein paar Messerwerte 
abzuholen.

von Benjamin B. (revolutionfx)


Lesenswert?

Ja also wie gesagt, das Tutorial hab ich durchgelesen, am durch arbeiten 
bin ich ja gerade mehr oder weniger.
Im Zuge dessen bin ich jetzt halt bei TWI angelangt.

Problem dabei ist halt nur das sich der Daten-Bus unter AVR-Studio 
schlecht simulieren lässt.

Hab ja schon mit dem Gedanken gespielt eine Schaltung aufzubauen in der 
2 µC mit einander über TWI komunizieren (µC billiger als IMU im 
Schadensfall), allerdings kann ich ohne Schnittstelle zur Visualisierung 
der Daten daraus auch keine großen Erkenntnisse ziehen (daher Sensor und 
LEDs). -> Also Lerning by Doing

Gibts da für den Einstieg vllt einen guten Tipp? ( evtl. über STK500 
oder so?)

Grüße Ben

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.