Forum: Mikrocontroller und Digitale Elektronik Beschleunigungssensor BMA020 : New Data Interrupt


von André (Gast)


Lesenswert?

Hallo Forum,

ich betreibe erfolgreich einen BMA020 an einem ATMega8 über 4-Draht-SPI. 
Ich kann die Beschleunigungswerte korrekt auslesen und die 
Grundfunktionen, wie z.B. Bandbreite, konfigurieren. Also scheine ich 
das Datenblatt bisher richtig interpretiert zu haben. So weit, so gut.
Für meine Anwendung möchte ich nun gern den Interrupt-Pin nutzen, um die 
Verfügbarkeit der erneuerten Messwerte mit dem AVR per Interrupt zu 
bedienen. Laut Datenblatt ist dafür "nur" das entsprechende Bit im 
Register 0x15 zu setzen. Nur leider regt sich am INT-Ausgang rein gar 
nichts. Ich bin dem ganzen selbst mit Oszilloskop nachgegangen und 
konnte definitiv kein Interrupt-Signal nachweisen. Das war konstant low. 
Dabei wurden die Messwerte jede 1 ms ausgelesen, so dass ein 
undetektierter Interrupt wieder zurückgesetzt worden wäre.
In den bisherigen Forums-Beiträgen und bei anderen Suchmaschinen bin ich 
nicht fündig geworden. Scheinbar benutzen die meisten Anwender dieses 
Feature nicht ? Hat jemand eine Idee oder gar eine schlüssige Erklärung, 
was ich falsch mache ?

Ciao
André

von Ralph (Gast)


Lesenswert?

André schrieb:
> Dabei wurden die Messwerte jede 1 ms ausgelesen, so dass ein
> undetektierter Interrupt wieder zurückgesetzt worden wäre.

Daran liegt es.
This interrupt is also
reset by any acceleration byte read procedure (read access to address 
02h to 07h).

von André (Gast)


Lesenswert?

Hallo Ralph,

danke für die schnelle Antwort.

Den von Dir angeführten Abschnitt habe ich auch im Datenblatt gelesen. 
Dort steht aber auch, dass die Update-Rate für alle drei Achsen 3 kHz 
beträgt. An anderer Stelle wird konkret von 330 usec gesprochen. Somit 
müsste innerhalb von der von mir verwendeten 1 msec schon mindestens 3 
mal ein vollständiger Refresh des BMA020 passiert sein. Folgendes gibt 
die Seite 47 des Datenblattes her :

Figure 28: Explanation of data ready interrupt: For a bandwidth of e.g. 
1.5kHz the data refresh cycle takes 330µs to update all data registers. 
After the final conversion of z-axis the INT pad will be set high. New 
data can be read out via interface. The interrupt resets automatically 
after read out.

Mein Programm macht nun folgendes :

1. Lese die drei Werte vom BMA020 aus (wenige usec)
2. Warte 1 msec
3. Gehe zu 1.

Initialisiert habe ich beim BMA020 nur folgendes :

1. 4 Wire SPI (vielleicht unnötig, da ja default-Einstellung)
2. 1.5 kHz Bandbreite
3. New Data Interrupt

Wie schon im ersten Beitrag geschrieben, funktioniert alles wunderbar, 
bis auf den Interrupt-Ausgang des BMA020. Der bleibt konstant auf Low.

Meine Erwartungshaltung wäre gewesen :

1. Lese die drei Werte vom BMA020 aus (wenige usec)
2. Nach 330 usec (spätestens aber 660 usec, falls gerade ungünstiges 
Timing) hat der BMA020 seine Register erneuert
3. Nach dem Erneuern der BMA-Werte setzt der BMA sein INT-Pin auf High
4. Da gelatched, bleibt das Pin auf High bis entweder ein Read-Access 
auf die Werte durchgeführt wurde oder aber der Interrupt per Kommando 
zurückgesetzt wurde.
5. Mein Programm wartet 1 msec
6. Auslesen der Werte.
7. Weil ja nun ein Read-Access stattfand setzt der BMA seinen INT-Pin 
auf Low
8. zurück zu 2.

Wo ist nun der Denkfehler ? Oder grundsätzlich, hat schon mal jemand im 
Forum diese Interrupt-Funktion des BMA020 erfolgreich verwendet - ich 
konnte keine Hinweise darauf finden ?

von Ralph (Gast)


Lesenswert?

Hätte jetzt da nur eine Idee. Setz mal Chipselect auf aktiv.
Kann sein das der chip seine Register nur aktualisiert wenn Chipselect 
aktiv ist.

von André (Gast)


Lesenswert?

Hallo,

bin erst am Wochenende zum Testen gekommen. Inzwischen hat sich das 
Problem erledigt, hier die Auflösung :

Die Initialisierung des BMA020 hatte ich, so wie man das nun einmal so 
macht, durchgeführt bevor die Interrupt-Abarbeitung im AVR durch "sei" 
freigeben wurde. Soweit, so gut. Der Interrupt-Ausgang des BMA020 wurde 
auf den INT0-Pin des AVR gelegt und auf die steigende Flanke getriggert. 
Triggern auf Pegel geht nicht, da der BMA020 Interrupt-Ausgang 
High-aktiv ist und er AVR nur Level-Triggern auf Low-Pegel erlaubt. Um 
das zu umgehen, müsst man halt durch eine externe Beschaltung 
invertieren, aber das wollte ich freilich nicht. Nun zum eigentlichen 
Problem.
Das Datenblatt des BMA020 gibt den wichtigen Hinweis, dass der "New 
Data"-Interrupt ein "latched" Interrupt ist. D.h. er ist immer 
gelatched - auch ohne das entsprechende Control-Bit ! Nun triggert der 
BMA020 also gleich nach seiner Initialisierung und dem ersten Füllen 
seiner Daten-Register und sein Interrupt-Pin bleibt solange High, bis 
der Interrupt entweder durch Auslesen oder Interrupt-Reset zurückgesetzt 
wird. Da aber der AVR erst nach Freigabe mit "sei" Interrupts erkennt 
und eine Low-High-Flanke brauchte, die ja nun nicht mehr kommen konnte, 
wurde hier eine wunderschöne, sich selbst blockierende Situation 
geschaffen.
Lösung : Nach dem "sei" den Interrupt des BMA erst einmal zurücksetzen, 
danach läuft alles wie im Datenblatt beschrieben.

Alles ? Fast alles : Nachdem ich mit dem Oszi noch mal nachgemessen 
hatte, stellte ich fest, dass der Interrupt des BMA020 ca. alle 105 usec 
ausgelöst wird. Das Datenblatt besagt aber, es dürfte nur alle 330 usec 
(3 kHz Update-Rate) ausgelöst werden ?!

Hat jemand eine Erklärung für die Diskrepanz ? Wandelt der BMA020 etwa 
wirklich mit fast 10 kHz ? Das kann ich kaum glauben.

von Matthias K. (mklenk)


Lesenswert?

Hallo André,

auch wenn die Chancen gering sind, dass du das noch liest,   kannst du 
mir bitte deinen Code schicken, oder zumindest den Code zum auslesen der 
Sensorwerte. Ich versuche gerade zwei BMA020 mit einem µC auszulesen und 
das geht mit I2C dann nicht mehr (so leicht) wie ich erfahren habe.

Würde mir auf jeden Fall viel Arbeit ersparen.

MfG mklenk

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.