PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Status vom TWI beim Senor BMA020



Jimmybot
26.01.2014, 19:40
Guten abend,

bin mal wieder am verzweifeln.

Also... Ich versuche einen BMA020 über TWI zu konfigurieren und auszulesen.

Nun bin ich hergegangen und habe folgenden C-code gebastelt:

/*
* BMA020.c
*
* Created: 26.01.2014 14:28:04
* Author: Jimmy
*/


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

int main(void)
{

// Portrichtung
DDRD=0xFF;
DDRC &= ~((1<<PC5) | (1<<PC4));
PORTC|=(1<<PC5) | (1<<PC4);
_delay_ms(1000);
DDRB=0xFF;

// TWI Initialisieren
TWBR=32;
TWSR=0;

TWCR|=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN); // TWI starten
while (!(TWCR & (1<<TWINT)));


TWDR=0x70; // Adresse laden (schreiben)
TWCR|=(1<<TWINT)|(1<<TWEN); // Adresse senden
while(!(TWCR&(1<<TWINT)));
PORTD=TWSR;

TWDR=0x14; // Zielregister laden
TWCR|=(1<<TWINT)|(1<<TWEN); // Zielreigster ansprechen
while(!(TWCR&(1<<TWINT)));


TWDR|=(1<<0); // Inhalt fürs Register 0x14h laden
TWCR|=(1<<TWINT)|(1<<TWEN); // Inhalt senden
while(!(TWCR&(1<<TWINT)));

TWCR|=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN); // TWI beenden
while(!(TWCR&(1<<TWINT)));

while(1)
{
_delay_ms(1000);
PORTB|=(1<<PB7);
_delay_ms(1000);
PORTB&=~(1<<PB7);
}
}

ähm ja...
jetzt zu meinem Problemm. Ich verstehe nicht was der TWI da macht, bzw. warum er was falsches macht.

Laut Datenblatt des BMA020 soll das Protokoll zum Konfigurieren so aussehen:

TWI starten ---> BMA020-Schreib adresse --> welches Register --> Daten fürs Register --- > TWI Ende

Jetzt habe ich mit PORTD=TWSR; mir den Status auf eine LED-Anzeige legen lassen.
Dabei stelle ich folgendes fest:


TWCR|=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN); // TWI starten
while (!(TWCR & (1<<TWINT)));
Status nach dem Starten des TWI: 08h


TWDR=0x70; // Adresse laden (schreiben)
TWCR|=(1<<TWINT)|(1<<TWEN); // Adresse senden
while(!(TWCR&(1<<TWINT)));
PORTD=TWSR;
Status nach Senden der Adresse: 18h


TWDR=0x14; // Zielregister laden
TWCR|=(1<<TWINT)|(1<<TWEN); // Zielreigster ansprechen
while(!(TWCR&(1<<TWINT)));
Status nach Senden des Zielregister: 10h (hier müsste aber 28h stehen)

Laut Datenblatt vom ATmega8 sind die 08h und 18h dort wo sie sind richtig.

Warum sendet der Controller nicht den Inhalt von TWDR wie gefordert, sondern wiederholt den Start des TWI?

oberallgeier
27.01.2014, 08:45
... bin ... am verzweifeln ... BMA020 über TWI zu konfigurieren und auszulesen ...Der Sterntaler hatte dazu so ein hübsches Codeschnippsel geschrieben (https://www.roboternetz.de/community/threads/47783-3-Achs-Beschleunigungssensor-sensationell-günstig-!?p=470340&viewfull=1#post470340) das ich später auch bei meinem Übungen (https://www.roboternetz.de/community/threads/47783-3-Achs-Beschleunigungssensor-sensationell-günstig-!?p=485247&viewfull=1#post485247) genau angesehen hatte. - das erklärt zwar nicht Deine Probleme, aber es läuft und läuft und ... ich habe damit den BMA ausgelesen, umgemodelt (https://www.roboternetz.de/community/threads/47783-3-Achs-Beschleunigungssensor-sensationell-günstig-!?p=485256&viewfull=1#post485256) - d.h. Register gesetzt - alles problemlos.

Wo Dein Problem steckt habe ich jetzt (sorry, tut mir leid) garnicht geprüft, vielleicht helfen Dir die Links trotzdem.

Viel Erfolg

Jimmybot
27.01.2014, 17:20
Eigentlich wollte ich ohne eine fremde Bibliothek auskommen. Da zu einem mir eigentlich die Sache klar und logisch schein, sowohl als in eueren Wikis, als auch in meine Büchern.

Werde mir aber dennoch mal die Bib. zu gemüte führen, vielleicht werde ich dort schlauer.

EDIT (20:54):

Ich habe nun den Code von Fleury und mir vergliechen:

hier der Code zum Schreiben von Fleury:
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 */


und hier mein Code:
TWDR=0x14; // Zielregister laden
TWCR|=(1<<TWINT)|(1<<TWEN); // Zielreigster ansprechen
while(!(TWCR&(1<<TWINT)));

Der einzigste unterschied, dass Fleury den Status noch als Rückgabewert benutz, um zu signaliesieren, dass eine Übertragung erfolgreich war, oder nicht.

sast
28.01.2014, 06:39
Der einzigste unterschied, dass Fleury den Status noch als Rückgabewert benutz, um zu signaliesieren, dass eine Übertragung erfolgreich war, oder nicht.

Das sehe ich nicht so.

Während Peter Fleury dem TWCR einen entsprechenden Wert zuweist, änderst du mit

TWCR|=(1<<TWINT)|(1<<TWEN);

nur die beiden Bits TWINT und TWEN. Der Rest steht dann ja noch im TWCR. Oder sollte ich übersehen haben, dass das irgendwo automatisch zurückgesetzt wird. ;)

sast

Jimmybot
28.01.2014, 10:22
Das wäre natürlich eine Fehlerquelle. Ich bin mir nicht ganz sicher welchen Zustand TWRC nach dem Ausführen hat. Werde das mal nach der Arbeit mal Zuhause testen.

Jimmybot
28.01.2014, 17:29
Tatsächlich das war der Fehler.
Vielen dank für euere Hilfe.