Forum: Mikrocontroller und Digitale Elektronik Erneutes ausführen von Code-Abschnitten nach Interrupt


von Hanna (Gast)


Lesenswert?

Hi zusammen,

ich habe eine Frage zum Thema Interrupts:

Ich benutze einen SAMD21J18A und ATMEL START/ATMEL Studio (AFS4) 
Umgebung, um ihn zu programmieren.
Jetzt habe ich folgendes Problem:
Ich habe einen SPI Bus, an dem verschiedene Sensoren dran hängen und 
einen Eingangs-Pin, der bei fallender Flanke eine Interruptfunktion 
auslösen soll, die mir einen bestimmten Sensor, über die SPI-Verbindung, 
auslesen soll.

Wenn jetzt aber der Fall auftritt, dass gerade ein Sensor, der an 
besagtem SPI Bus hängt, ausgelesen wird und dabei gleichzeitig die 
Interruptfunktion aufgerufen wird, um einen anderen Sensor in diesem 
Bussystem auszulesen, führt das zu Kuddelmuddel.

Die Interruptfunktion soll eine höhere Priorität haben, als das auslesen 
des anderen Sensors. Sprich: Wenn gerade ein Sensor ausgelesen wird und 
die Interruptfunktion ausgelöst wird, soll das auslesen des anderen 
Sensors abgebrochen werden, die Interruptfunktion ausgeführt und dann 
der Sensor erneut ausgelesen werden. Im Programmablauf müssten also nach 
dem Interrupt ein paar (bereits ausgeführte) Schritte erneut ausgeführt 
werden.

Daraus ergibt sich meine Frage: Gibt es in AFS4 einen Ansatz zu sagen: 
"Wenn zwischen diesem (Startpunkt) und diesem Punk (Endpunkt) im Code 
ein Interrupt getriggert wird, dann springe nach ausführen des 
Interrupts zum Startpunkt(!) zurück."

Danke schonmal für konstruktive Vorschläge!
Hanna

von Stefan F. (Gast)


Lesenswert?

Ich glaube das musst du "zu Fuß" programmieren. Macht die externe 
Hardware das denn einfach so mit?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Hanna schrieb:
> Die Interruptfunktion soll eine höhere Priorität haben, als das auslesen
> des anderen Sensors.

Das halte ich für eine verfehlte Architektur.

Mach die einzelnen Auslesefunktionen schnell / kurz, aber nicht 
unterbrechbar. Sensoren, die eine lange Zeit brauchen, haben oft eine 
Funktion, mit der sie zwischenzeitlich (während ihrer eigentlichen 
Messphase) den Bus freigeben können. Sowas sollte man nutzen.

Ansonsten müsstest du Nägel mit Köpfen machen und uns sagen, welche Art 
Sensor das ist. Dann kann man dich besser beraten.

von Hanna (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Macht die externe
> Hardware das denn einfach so mit?

Da bin ich mir noch nicht sicher :D

Jörg W. schrieb:
> Sensoren, die eine lange Zeit brauchen, haben oft eine
> Funktion, mit der sie zwischenzeitlich (während ihrer eigentlichen
> Messphase) den Bus freigeben können.

Das könnte eine Alternative sein. Da muss ich dann wohl nochmal 
Datenblätter durchstöbern.

von Stefan F. (Gast)


Lesenswert?

Hanna schrieb:
>> Macht die externe
>> Hardware das denn einfach so mit?

> Da bin ich mir noch nicht sicher :D

Dann prüfe das erst mal, denn was du da vor hast ist schon seltsam.

von Route_66 H. (route_66)


Lesenswert?

Hallo!
Wären zwei SPI-Busse die Lösung?
Einer per Interrupt für diesen einen Sensor und der andere Bus für die 
restlichen Sensoren per Bit-Banging?

von Falk B. (falk)


Lesenswert?

Hanna schrieb:
> Wenn jetzt aber der Fall auftritt, dass gerade ein Sensor, der an
> besagtem SPI Bus hängt, ausgelesen wird und dabei gleichzeitig die
> Interruptfunktion aufgerufen wird, um einen anderen Sensor in diesem
> Bussystem auszulesen, führt das zu Kuddelmuddel.

In der Tat.

> Die Interruptfunktion soll eine höhere Priorität haben, als das auslesen
> des anderen Sensors. Sprich: Wenn gerade ein Sensor ausgelesen wird und
> die Interruptfunktion ausgelöst wird, soll das auslesen des anderen
> Sensors abgebrochen werden, die Interruptfunktion ausgeführt und dann
> der Sensor erneut ausgelesen werden. Im Programmablauf müssten also nach
> dem Interrupt ein paar (bereits ausgeführte) Schritte erneut ausgeführt
> werden.

Das geht schief.

> Daraus ergibt sich meine Frage: Gibt es in AFS4 einen Ansatz zu sagen:
> "Wenn zwischen diesem (Startpunkt) und diesem Punk (Endpunkt) im Code
> ein Interrupt getriggert wird, dann springe nach ausführen des
> Interrupts zum Startpunkt(!) zurück."

Kuddelmuddel! Du brauchst ein anderes Konzept! Egal auf welchem 
Prozessor.

Siehe die Antwort von Jörg. Die Frage ist, wie dringend muss der Sensor 
WIRKLICH ausgelesen werden?

a) Nicht super dringend, die aktuelle Sensorabfrage kann noch beendet 
werden. Dann reicht es, im Interrupt ein Flag zu setzen und das Auslesen 
des Sensor in der passenden State machine im Hauptprogramm zu 
machen, gleich nach der Beendigung des aktuellen Sensorzugriffs.

b) SUPER DRINGEND! Wenn das WIRKLICH der Fall ist (über wie viele 
Millisekunden reden wir her?) muss man den Sensor ggf. an einen extra 
SPI-Bus hängen und im Interrupt auslesen. Dann kommt sich auch nix in 
die Quere.

c) SUPER DRINGEND und der Sensor kann NICHT an einen an einen extra 
SPI-Bus gehängt werden. Dann liest man den Sensor im Interrupt direkt 
aus und setzt ein "Hallo-ich hab mal dazwischengefunkt"-Flag. Dieses 
wird von den normalen Funktion vor dem normalen Sensorzugriff gelöscht 
und am Ende nochmal geprüft. Ist es dann gesetzt, hat der Interrupt 
dazwischen gefunkt und der Zugriff muss wiederholt werden. Dafür braucht 
es keinerlei exotische Programmfunktionalität.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

SPI per Interrupt macht meist keinen großen Sinn. (Ausnahme: man hat 
seeehr langsame SPI-Clients, die man nur mit vergleichsweise niedrigerer 
Datenrate takten kann.)

Aber da muss uns Hanna erstmal schreiben, welche Sensoren sie da 
überhaupt am Bus hat.

von Stefan F. (Gast)


Lesenswert?

Route_66 H. schrieb:
> Wären zwei SPI-Busse die Lösung?

Auch das kommt auf die externe Hardware an. Du kannst nicht bei jedem 
Chip einfach die Kommunikation mitten im Takt pausieren.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Hanna schrieb:
> einen Eingangs-Pin, der bei fallender Flanke eine Interruptfunktion
> auslösen soll
Woher kommt das Signal das da an diesem "Eingangs-Pin" anliegt?
Interrupts nimmt man, wenn etwas, das nicht lange dauert, schnell 
bearbeitet werden muss.

So, wie wenn du gerade einen Kuchen backst. Dann darf dich vielleicht 
der Postbote ganz kurz unterbrechen. Das Öffnen und Auspacken des 
Pakets bzw. das Bearbeiten der Post sowie das Bezahlen der Rechnungen 
verschiebst du aber auf später.
Und wenn grade die Eier ins Mehl geschlagen hast und du siehst durchs 
Fenster, dass draußen die Hecke geschnitten werden muss, dann merkst 
du dir diese Aufgabe und verschiebst das auf später. Und backst davor 
erst mal den Kuchen fertig.

Hanna schrieb:
> Wenn jetzt aber der Fall auftritt, dass gerade ein Sensor, der an
> besagtem SPI Bus hängt, ausgelesen wird und dabei gleichzeitig die
> Interruptfunktion aufgerufen wird, um einen anderen Sensor in diesem
> Bussystem auszulesen, führt das zu Kuddelmuddel.
Du gehst also einfach her und merkst dir im jeweiligen Interrupt, dass 
du den entsprechenden Sensor auslesen musst. Und dann bearbeitest du 
diese Aufgaben später hübsch nacheinander.

: Bearbeitet durch Moderator
von Falk B. (falk)


Lesenswert?

Stefan ⛄ F. schrieb:
> Route_66 H. schrieb:
>> Wären zwei SPI-Busse die Lösung?
>
> Auch das kommt auf die externe Hardware an. Du kannst nicht bei jedem
> Chip einfach die Kommunikation mitten im Takt pausieren.

Dann ist es kein Jim Beam, ähhh, SPI. Aber OK, es gibt einige ICs, z.B. 
AD-Wandler, welche mit dem SPI-Takt die Wandlung durchführen oder 
zumindest starten.

Aber alles in allem ist es keine sonderlich gute Idee, das SPI im 
Interrupt einfach so brachial zu übernehmen.

von Stefan F. (Gast)


Lesenswert?

Falk B. schrieb:
> Aber OK, es gibt einige ICs, z.B.
> AD-Wandler, welche mit dem SPI-Takt die Wandlung durchführen oder
> zumindest starten.

Genau das hatte ich dabei im Sinn.

von Hanna (Gast)


Lesenswert?

Hi Zusammen,

um nochmal etwas Klarheit zu schaffen:
Die beiden Sensoren um die es geht sind
1. Ein Accelerometer, das hin und wieder ausgelesen werden soll (ca alle 
200ms- 1 mal pro Sekunde). Ich benötige momentan 1.6ms für die gesamte 
Kommunikation mit dem Accelerometer. (Hier ist vermutlich noch 
Verbesserungspotenzial)
und
2. ein ADC, der (siehe Falk Bs Antwort) SUPER DRINGEND ausgelesen werden 
muss. (ca. einmal pro ms und dann muss der Interrupt innerhalb weniger 
us (genauere Werte habe ich hier noch nicht) aufgerufen werden).

Falk B. schrieb:
> c) SUPER DRINGEND und der Sensor kann NICHT an einen an einen extra
> SPI-Bus gehängt werden. Dann liest man den Sensor im Interrupt direkt
> aus und setzt ein "Hallo-ich hab mal dazwischengefunkt"-Flag. Dieses
> wird von den normalen Funktion vor dem normalen Sensorzugriff gelöscht
> und am Ende nochmal geprüft. Ist es dann gesetzt, hat der Interrupt
> dazwischen gefunkt und der Zugriff muss wiederholt werden. Dafür braucht
> es keinerlei exotische Programmfunktionalität.

Bei dem Vorschlag mit der "Hallo-ich hab mal dazwischengefunkt"-Flag 
wäre dann vorher vermutlich wieder die Frage ob die Hardware das so 
einfach mitmacht...

Route_66 H. schrieb:
> Wären zwei SPI-Busse die Lösung?
Zwei SPI-Busse sind keine Alternative

von Hanna (Gast)


Lesenswert?

Hanna schrieb:
> Bei dem Vorschlag mit der "Hallo-ich hab mal dazwischengefunkt"-Flag
> wäre dann vorher vermutlich wieder die Frage ob die Hardware das so
> einfach mitmacht...

klingt aber erstmal einfacher als meine erste Idee :D

von Falk B. (falk)


Lesenswert?

Hanna schrieb:
> Hi Zusammen,
>
> um nochmal etwas Klarheit zu schaffen:
> Die beiden Sensoren um die es geht sind
> 1. Ein Accelerometer, das hin und wieder ausgelesen werden soll (ca alle
> 200ms- 1 mal pro Sekunde).

Also absolut unkritisch.

> Ich benötige momentan 1.6ms für die gesamte
> Kommunikation mit dem Accelerometer. (Hier ist vermutlich noch
> Verbesserungspotenzial)

Klingt so, denn in 1,6ms kann man selbst bei nur 1MHz SPI-Takt satte 
1600 Bit bzw. 200 Bytes übertragen. Und ich glaube nicht, daß dein SPI 
nur mit 1MHz läuft.

> und
> 2. ein ADC, der (siehe Falk Bs Antwort) SUPER DRINGEND ausgelesen werden
> muss. (ca. einmal pro ms und dann muss der Interrupt innerhalb weniger
> us (genauere Werte habe ich hier noch nicht) aufgerufen werden).

AHA! Also ein periodischer Interrupt mit schon recht hoher Frequenz. 
Aber daran erkennt man, daß es mit 1,6ms Auslesezeit für das 
Accelerometer so oder so nicht geht, denn diese Zugriffe müssen in die 
Lücken des ADCs passen. Und damit ist auch das Konzept klar. Der 
Interrupt macht einen sofortigen, direkten ADC-Zugriff. Direkt danach, 
noch im Interrupt wird geprüft, ob das Zeitfenster für das Accelerometer 
erreicht ist. Wenn ja, wird es im Anschluß ausgelesen. Damit gibt es 
keinerlei Überschneidungen beim SPI-Zugriff, alle Zugriffe finden an 
einer Stelle nur im Interrupt statt.

von Hanna (Gast)


Lesenswert?

Falk B. schrieb:
> Also ein periodischer Interrupt mit schon recht hoher Frequenz.

Leider nicht ganz (Hätte ich vielleicht anders formulieren sollen).
Es gibt auch Phasen hin und wieder, da wird der Interrupt nur sehr 
selten bis gar nicht ausgelöst. Trotzdem soll dann das Accelerometer 
ausgelesen werden.

von Falk B. (falk)


Lesenswert?

Hanna schrieb:
> Leider nicht ganz (Hätte ich vielleicht anders formulieren sollen).
> Es gibt auch Phasen hin und wieder, da wird der Interrupt nur sehr
> selten bis gar nicht ausgelöst. Trotzdem soll dann das Accelerometer
> ausgelesen werden.

Hmm, schon wieder ein sehr fragwürdiges Konzept.
Wenn das denn WIRKLICH so ist und so sein soll, hast du das Problem, daß 
du auch in den Pausen das Accelerometer nicht in der Hauptschleife 
auslesen kannst, denn der Interrupt kann ja jeden Moment zuschlagen. 
Oder gibt es wenigstens eine Art Vorhersagemöglichkeit, daß man weiß, 
OK, wir haben JETZT ca. ???ms Ruhe vom ADC, jetzt können wir das 
Accelerometer auslesen. Wenn du das nicht hast, wird es ZIEMLICH 
schwierig, das sauber zu lösen.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Hanna schrieb:
> und 2. ein ADC, der (siehe Falk Bs Antwort) SUPER DRINGEND ausgelesen
> werden muss. (ca. einmal pro ms und dann muss der Interrupt innerhalb
> weniger us (genauere Werte habe ich hier noch nicht) aufgerufen werden).

Kann man den ADC nicht sauber per Timer die Wandlung triggern lassen und 
dann ggf. sogar noch per DMA die Ergebnisse transferieren? (Ich weiß, 
DMA und SPI vertragen sich nicht immer, je nachdem, wie das Select 
erfolgt.)

Ansonsten sollte man vielleicht das aus einem Timer-Interrupt anwerfen, 
der regelmäßig zuerst den ADC abfragt und dann ggf. noch das 
Accelerometer.

von Hanna (Gast)


Lesenswert?

Falk B. schrieb:
> Oder gibt es wenigstens eine Art Vorhersagemöglichkeit, daß man weiß,
> OK, wir haben JETZT ca. ???ms Ruhe vom ADC, jetzt können wir das
> Accelerometer auslesen

Da will mir nichts einfallen...

von Ralf G. (ralg)


Lesenswert?

Ich würde eher versuchen, die Kontrolle selbst zu übernehmen:
Lassen sich die Sensorwerte auch abfragen(*), oder ist man darauf 
angewiesen, dass der Sensor sich meldet?

(*) Die Sensoren sollen in einem ausreichend feinen Zeitraster 
abgefragt werden.

von Hanna (Gast)


Lesenswert?

Jörg W. schrieb:
> Kann man den ADC nicht sauber per Timer die Wandlung triggern lassen und
> dann ggf. sogar noch per DMA die Ergebnisse transferieren? (Ich weiß,
> DMA und SPI vertragen sich nicht immer, je nachdem, wie das Select
> erfolgt.)

Wenn ich das richtig verstehe, funktioniert das leider nicht, da ich den 
Wert vom ADC zu exakt (zumindest sehr genau zu) dem Zeitpunkt brauche, 
an dem der Interrupt ausgelöst wird und in der Interruptfunktion 
passieren noch andere Dinge, die unmittelbar mit dem ADC-Auslesen 
zusammenhängen. (sprich: Reset von Integratoren).

Ralf G. schrieb:
> Lassen sich die Sensorwerte auch abfragen(*), oder ist man darauf
> angewiesen, dass der Sensor sich meldet?

Das verstehe ich nicht, im Moment melde ich mich beim Sensor: "Schick 
mir doch bitte die Werte" woraufhin der Sensor mir die Werte schickt ;)

Beitrag #6441682 wurde vom Autor gelöscht.
von Ackerbau (Gast)


Lesenswert?

Hanna schrieb:
> dass der Sensor sich meldet?

Er meint damit den Interrupt Pin, der dich dazu bewegt beim Sensor 
anzufragen.

von Hanna (Gast)


Lesenswert?

Ackerbau schrieb:
>> dass der Sensor sich meldet?
>
> Er meint damit den Interrupt Pin, der dich dazu bewegt beim Sensor
> anzufragen.

Achso... also man könnte auch den ADC auslesen und wenn der einen 
bestimmten Wert ausgibt, dann könnte ich quasi die Interrupt Funktion 
manuell ausführen, aber dann müsste ich ja wirklich fast durchgehend die 
Werte vom ADC abfragen und ich weiß nicht, was mir das bringen würde...

von Ralf G. (ralg)


Lesenswert?

Ahh, ich glaube, jetzt hab' ich's (nach mehrmaligem Durchlesen)...
Der Interrupt ist die Anforderung, dass jetzt bestimmte|alle Sensoren 
abgefragt werden sollen.

Wie groß darf der Fehler sein?
- (Extrem '1') 'gegen null': dann sollte der Abruf möglichst aller 
Sensoren innerhalb des kürzestmöglichen Interruptintervalles erfolgen 
können
- (Extrem '2') 'naja, geht so': Sensoren reihum auslesen und speichern, 
bei Interrupt Daten aus 'Datenbank' übermitteln (auch wenn die dann 
vielleicht nicht millisekundenaktuell sind)

Lese gerade:
Hanna schrieb:
> aber dann müsste ich ja wirklich fast durchgehend die
> Werte vom ADC abfragen und ich weiß nicht, was mir das bringen würde...

Du legst fest, was passiert! Sonst quatschen alle durcheinander...

Nochmal zu:
'Ahh, ich glaube, jetzt hab' ich's'...
... wahrscheinlich doch nicht? Der Sensor löst einen Interrupt aus, wenn 
er was zu melden hat?

: Bearbeitet durch User
von Falk B. (falk)


Lesenswert?

Hanna schrieb:
> Falk B. schrieb:
>> Oder gibt es wenigstens eine Art Vorhersagemöglichkeit, daß man weiß,
>> OK, wir haben JETZT ca. ???ms Ruhe vom ADC, jetzt können wir das
>> Accelerometer auslesen
>
> Da will mir nichts einfallen...

D.h. die Interrupts kommen sporadisch und trotzdem mit hoher Frequenz?

von Hanna (Gast)


Lesenswert?

Falk B. schrieb:
> D.h. die Interrupts kommen sporadisch und trotzdem mit hoher Frequenz?

Könnte man so sagen...
Also es kommt aufs Eingangssignal drauf an, das ich messen möchte. 
Wesentlich ist:
Bei großem Eingangssignal kommt der Interrupt häufiger (bis zu 1x pro 
1ms)
Bei kleinem Eingangssignal seltener (nur 1x pro Minute o.ä.)
Das Eingangssignal ist nicht vorhersehbar, sprich folgt keinem 
bestimmten Muster (Sinusfrequenz o.ä.)

von Falk B. (falk)


Lesenswert?

Hanna schrieb:
> Könnte man so sagen...
> Also es kommt aufs Eingangssignal drauf an, das ich messen möchte.
> Wesentlich ist:
> Bei großem Eingangssignal kommt der Interrupt häufiger (bis zu 1x pro
> 1ms)
> Bei kleinem Eingangssignal seltener (nur 1x pro Minute o.ä.)
> Das Eingangssignal ist nicht vorhersehbar, sprich folgt keinem
> bestimmten Muster (Sinusfrequenz o.ä.)

Was ist das denn für ein komischer ADC? Klingt nach einem 
selbstgestrickten ADC mit Zählverfahren. Was muss denn im Interrupt aus 
dem ADC ausgelesen werden?

von Hanna (Gast)


Lesenswert?

Ralf G. schrieb:
> Ahh, ich glaube, jetzt hab' ich's (nach mehrmaligem Durchlesen)...
> Der Interrupt ist die Anforderung, dass jetzt bestimmte|alle Sensoren
> abgefragt werden sollen.
>
> Wie groß darf der Fehler sein?
> - (Extrem '1') 'gegen null': dann sollte der Abruf möglichst aller
> Sensoren innerhalb des kürzestmöglichen Interruptintervalles erfolgen
> können
> - (Extrem '2') 'naja, geht so': Sensoren reihum auslesen und speichern,
> bei Interrupt Daten aus 'Datenbank' übermitteln (auch wenn die dann
> vielleicht nicht millisekundenaktuell sind)
>
> Lese gerade:
> Hanna schrieb:
>> aber dann müsste ich ja wirklich fast durchgehend die
>> Werte vom ADC abfragen und ich weiß nicht, was mir das bringen würde...
>
> Du legst fest, was passiert! Sonst quatschen alle durcheinander...
>
> Nochmal zu:
> 'Ahh, ich glaube, jetzt hab' ich's'...
> ... wahrscheinlich doch nicht? Der Sensor löst einen Interrupt aus, wenn
> er was zu melden hat?


Nicht ganz... Der eine Sensor (ADC) soll ausgelesen werden, wenn ein 
bestimmter I/O Pin seinen Zustand von high auf low wechselt (das 
passiert bis zu 1000x pro Sekunde, muss aber nicht).
Ein anderer Sensor (der Accelerator) soll in regelmäßigen Zeitabständen 
(z.B. alle 200ms)  ausgelesen werden.
Beide Sensoren hängen im gleichen SPI-Bussystem.
Beim ADC ist das Timing sehr(!) wichtig. Beim Accelerator eher weniger.

von Hanna (Gast)


Lesenswert?

Falk B. schrieb:
> Hanna schrieb:
>> Könnte man so sagen...
>> Also es kommt aufs Eingangssignal drauf an, das ich messen möchte.
>> Wesentlich ist:
>> Bei großem Eingangssignal kommt der Interrupt häufiger (bis zu 1x pro
>> 1ms)
>> Bei kleinem Eingangssignal seltener (nur 1x pro Minute o.ä.)
>> Das Eingangssignal ist nicht vorhersehbar, sprich folgt keinem
>> bestimmten Muster (Sinusfrequenz o.ä.)
>
> Was ist das denn für ein komischer ADC? Klingt nach einem
> selbstgestrickten ADC mit Zählverfahren. Was muss denn im Interrupt aus
> dem ADC ausgelesen werden?

Damit meine ich nicht das Eingangssignal vom ADC, sondern ein anderes. 
Ich möchte im Grunde einen Strom messen. Der ADC soll natürlich nur die 
Eingangsspannung messen, bei großen Strömen halt häufiger.

von Falk B. (falk)


Lesenswert?

Hanna schrieb:
>> Was ist das denn für ein komischer ADC? Klingt nach einem
>> selbstgestrickten ADC mit Zählverfahren. Was muss denn im Interrupt aus
>> dem ADC ausgelesen werden?
>
> Damit meine ich nicht das Eingangssignal vom ADC, sondern ein anderes.
> Ich möchte im Grunde einen Strom messen. Der ADC soll natürlich nur die
> Eingangsspannung messen, bei großen Strömen halt häufiger.

Und dafür macht du so ein Theater? Lies den ADC REGELMÄßIG aus, dann 
weißt du, wann Pausen für andere Dinge sind.

von Schlaumaier (Gast)


Lesenswert?

Ich würde eine Globle Variable setzt z.b. stoped = false

Die Interruptroutine wird so gecodet

Sub Interrupt
If stoped = true then exit sub
if stoped = false then
  stoped = true
  call gemuetlich_auslesen
end if

exit sub

sub gemuetlich_auslesen
lese_senor_1_aus
lese_senor_2_aus
lese_senor_3_aus
stoped = false
end sub

Problem gelöst.

Ach ja ich code unter B4a da würde der Code funktioniern

von Falk B. (falk)


Lesenswert?

Ohje, jetzt kommen die BASCOM-Philosophen.

von Schlaumaier (Gast)


Lesenswert?

Falk B. schrieb:
> Ohje, jetzt kommen die BASCOM-Philosophen.

Ich code nicht in Bascom. Das ist B4R um genau zu sein. B4R schreibe 
einen Arudino-IDE fähigen Code. Ruft die IDE auf, compiliert und die 
Arduino-IDE schiebt ihn auf den Chip.

Ich bin einfach nur ein Mensch der Geschweifte Klammern hasst. ;)

von Schlaumaier (Gast)


Lesenswert?

Nachtrag :
https://www.b4x.com/android/forum/

Der fast gleiche Code (Programm-Engine) (besondere Eigenheiten der 
Geräte müssen berücksichtigt werden) funktioniert auf Raspberry, Java, 
Android und für 100 Euro im Jahr auch auf Apple-Zeug.  Ergo : Alles was 
nicht MS + VB ist code ich damit.

Und der Editor ist Visual-Basic like.

Also wieso 100 Syntax für den selben Mist. und Wieso teures Bascom 
bezahlen. ??!

von Hanna (Gast)


Lesenswert?

Falk B. schrieb:
> nd dafür macht du so ein Theater? Lies den ADC REGELMÄßIG aus, dann
> weißt du, wann Pausen für andere Dinge sind.

Ich dachte das könnte ich mir sparen, denn ich tue viele andere Dinge :D

von Falk B. (falk)


Lesenswert?

Hanna schrieb:
>> nd dafür macht du so ein Theater? Lies den ADC REGELMÄßIG aus, dann
>> weißt du, wann Pausen für andere Dinge sind.
>
> Ich dachte das könnte ich mir sparen, denn ich tue viele andere Dinge :D

Was denn? Nebenbei Instagrammen und Influencen? ;-)

Sag doch mal, was das für ein komischer ADC sein soll und was der wie 
mißt und warum du glaubst, das mit derartig sporadischen, dann aber 
mikrosekundengenauen SPI-Zugriffen machen zu müssen. Bei den meisten 
ADCs ist das nicht so, die halten ihre Ergebnisse bis zum Sankt 
Nimmerleinstag in den Registern, die kann man beliebig langsam auslesen, 
wenn gleich die nächste Wandlung dann warten muss.

von foobar (Gast)


Lesenswert?

> 1. Ein Accelerometer, das hin und wieder ausgelesen werden soll (ca alle
> 200ms- 1 mal pro Sekunde). Ich benötige momentan 1.6ms für die gesamte
> Kommunikation mit dem Accelerometer. (Hier ist vermutlich noch
> Verbesserungspotenzial)
>und
> 2. ein ADC, der (siehe Falk Bs Antwort) SUPER DRINGEND ausgelesen werden
> muss. (ca. einmal pro ms und dann muss der Interrupt innerhalb weniger
> us (genauere Werte habe ich hier noch nicht) aufgerufen werden).

Die beiden Forderungen sind mit einem einzelnen SPI-Bus nicht unter 
einen Hut zu bekommen.

a) Wenn der ADC jede Millisekunde eine Abfrage fordert, bleiben keine 
1.6ms mehr für den Beschleunigungssensor übrig.

b) Wenn das Auslesen des Accelerometer gerade läuft und dann eine 
Anforderung des ADC ankommt, kann diese nicht sofort bedient werden. 
Selbst falls die Abfrage des Accelerometers unterbrochen werden könnte, 
dauert das einige SPI-Takte und du hast dann einen Jitter auf dem 
ADC-Abfragezeitpunkt.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Ehe man so ein Zippel Zappel an einem SPI Bus macht, schliesst man das 
Acceldings an ein paar freie Pins an und bitbangt die paar Bytes ein. 
Dann bleibt die ganze ISR/SPI Hardware frei für diesen ADC.

: Bearbeitet durch User
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Matthias S. schrieb:
> Dann bleibt die ganze ISR/SPI Hardware frei für diesen ADC.

Naja, ein SAMD21 hat sechs(!) SERCOMs, daran allein kann es eigentlich 
auch nicht liegen …

: Bearbeitet durch Moderator
von uwe (Gast)


Lesenswert?

Eventsystem mit DMA Controller ist keine Lösung für dein ADC?
Falls der ACC Sensor länger als 1ms zum Auslesen benötigt muss der dann 
natürlich an einen anderen SPI...

von Thomas (kosmos)


Lesenswert?

/Bei dem Vorschlag mit der "Hallo-ich hab mal dazwischengefunkt"-Flag
wäre dann vorher vermutlich wieder die Frage ob die Hardware das so
einfach mitmacht.../

man nimmt da einfach ein Register und setzt dort ein einzelnes Bit, dies 
ist das das oben genannte "Hallo-ich hab mal dazwischengefunkt"-Flag. 
Mir ist noch kein µC begegnet der das nicht gekonnt hätte.

00000000 Interrupt xyz hat nicht dazwischengefunkt
00000001 Interrupt abc hat dazwischengefunkt
00000010 Interrupt 123 hat dazwischengefunkt

Für mich hört sich das so an als ob du diesen Wert gar nicht alle 1mSek 
benötigst, warscheinlich ist dieser eh veraltet da ihn der Sensor 
vielleicht schon vor 5 mSek gemessen hat und du ihn jetzt erst abrufst.

ansonsten dein µC hat doch passende ADC's onboard, wieso dann nicht 
gleich den passenden Sensor nehmen und auf die SPI Krücke verzichten.
*12-bit, 350ksps Analog-to-Digital Converter (ADC) with up to 20 
channels
Differential and single-ended input
*1/2x to 16x programmable gain stage
*Automatic offset and gain error compensation
*Oversampling and decimation in hardware to support 13-, 14-, 15- or 
16-bit resolution

von foobar (Gast)


Lesenswert?

>> Bei dem Vorschlag mit der "Hallo-ich hab mal dazwischengefunkt"-Flag
>> wäre dann vorher vermutlich wieder die Frage ob die Hardware das so
>> einfach mitmacht...
>
> Mir ist noch kein µC begegnet der das nicht gekonnt hätte.

Mit Hardware ist nicht der Prozessor sondern die SPI-Peripherie gemeint.

von Peter D. (peda)


Lesenswert?

Hanna schrieb:
> Sprich: Wenn gerade ein Sensor ausgelesen wird und
> die Interruptfunktion ausgelöst wird, soll das auslesen des anderen
> Sensors abgebrochen werden, die Interruptfunktion ausgeführt und dann
> der Sensor erneut ausgelesen werden.

Das ist Unfug^³.

SPI ist nicht reentrant. Entweder alles als Interrupt oder als Main.
Die Main-Funktionen können ja einfach in einen Puffer schreiben, den der 
SPI-Interrupt dann abarbeitet.

Wenn es aber unbedingt so sein muß (muß es nie), dann nimmt man einfach 
einen MC mit mehreren SPI. Z.B. der ATmega2560 kann bis 5 SPI-Master 
parallel benutzen, die 4 UARTs können auch SPI.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Peter D. schrieb:
> dann nimmt man einfach einen MC mit mehreren SPI

Hat sie doch, schrieb ich oben: stolze 6 SERCOMs sind zur Verfügung.

Inwiefern natürlich ggf. das Hardware-Layout vergurkt ist und an wie 
viele man davon rankommt, muss sie selbst klären.

von Wolfgang (Gast)


Lesenswert?

Hanna schrieb:
> Wenn jetzt aber der Fall auftritt, dass gerade ein Sensor, der an
> besagtem SPI Bus hängt, ausgelesen wird und dabei gleichzeitig die
> Interruptfunktion aufgerufen wird, um einen anderen Sensor in diesem
> Bussystem auszulesen, führt das zu Kuddelmuddel.

Auf einem Controller mit einem einzigen Kern gibt es kein "gleichzeitig" 
;-)

Der Interrupt kann die erste Lesefunktion nur unterbrechen, wenn du es 
ihm erlaubst. Alles andere ist eine Frage der Softwarearchitektur - und 
ganz richtig - zwei verschachtelte Leseoperationen auf dem selben Bus 
gehen schief.

von MCUA (Gast)


Lesenswert?

>Es gibt auch Phasen hin und wieder, da wird der Interrupt nur sehr
>selten bis gar nicht ausgelöst.
Man kann eine CPU nicht mit mit beliebig kurzen aufeinanderfolgenden 
INT-Anforderungen belasten. Irgentwann packt die es nicht mehr, und jede 
ISR benötigt eine gewisse Anzahl von Takten (je weniger desto besser).
Je öfter/schneller das passieren soll desto höher die INT-Priorität 
desto weniger die Takte in der ISR (sonst fährt das System sich fest).
Betr dem ADC wäre die Frage:
Wie genau, bzw wie einfach könnte das Timing (!) gemacht werden; ob 
nicht vieleicht sogar ein period. Abfrage (1 ms) gehen würde / gemacht 
werden sollte, was einfacheres Timing wäre. (Es schadend nichts, wenn 
CPU manchmal einige Werte 'zuviel' liest, die gar nicht benötigt werden, 
diese Werte später aber wieder da sind wenn sie benötigt werden (im 
worstcase wären es vermutlich sowiso 1ms)).
Und wenn ein Sensor bsp. nur alle 50ms mal abgefragt werden soll heist 
das nicht, dass die Abfrage selbst 50ms dauern muss. Dies Abfrage passt 
doch problemlos in ein 1ms 'Protokoll' hinein.

von Falk B. (falk)


Lesenswert?

MCUA schrieb:
>>Es gibt auch Phasen hin und wieder, da wird der Interrupt nur sehr
>>selten bis gar nicht ausgelöst.
> Man kann eine CPU nicht mit mit beliebig kurzen aufeinanderfolgenden
> INT-Anforderungen belasten. Irgentwann packt die es nicht mehr, und jede
> ISR benötigt eine gewisse Anzahl von Takten (je weniger desto besser).
> Je öfter/schneller das passieren soll desto höher die INT-Priorität
> desto weniger die Takte in der ISR (sonst fährt das System sich fest).

Mann O Mann, dümmer kann man wohl kaum antworten! Da spricht der OP von 
selten bis gar nicht bzw. maximal 1x pro Millisekunde und ein "Experte" 
faselt was von beliebig kurzen Interruptanforderungen!

Setzen, Sechs! Thema verfehlt!

von Stefan F. (Gast)


Lesenswert?

In Größenordnungen um 1ms sind Interruptroutinen meistens sowieso das 
falsche Mittel. Da geht man mit Hardware ran, die Daten ganz alleine 
erfasst und in Puffer schreibt.

-> Siehe Soundkarten und Grafikkarten (bzw. Chipsätze) im PC

Die CPU kann die gepuffertem Daten wesentlich effizienter blockweise 
abarbeiten.

von Falk B. (falk)


Lesenswert?

Stefan ⛄ F. schrieb:
> In Größenordnungen um 1ms sind Interruptroutinen meistens sowieso das
> falsche Mittel. Da geht man mit Hardware ran, die Daten ganz alleine
> erfasst und in Puffer schreibt.

Unsinn, wir leben nicht mehr im Jahr 1970, wo Mikrocontroller 
bestenfalls dreistellige kHz Taktraten hatten. 1ms ist selbst für kleine 
Mikrocontroller ala AVR, PIC & Co eine kleine Ewigkeit.

> -> Siehe Soundkarten und Grafikkarten (bzw. Chipsätze) im PC
>
> Die CPU kann die gepuffertem Daten wesentlich effizienter blockweise
> abarbeiten.

OMG! Du vergleichst Melonen mit Erdnüssen!

von Stefan F. (Gast)


Lesenswert?

Falk B. schrieb:
> OMG

Nu werde mal nicht religiös. Ich will will nicht dein Gott sein, und der 
andere "da oben" oder so hat andere Sorgen.

von MCUA (Gast)


Lesenswert?

>Setzen, Sechs! Thema verfehlt!
von wegen...
du musst dich setzen!
Auch kannst du nicht lesen!
Der TO hat von us-genauer Anforderung geschrieben.
Im Gegensatz zu deinem Gesülze ist an meinem Beitrag Rein Gar Nichts 
auszusetzen.

von MCUA (Gast)


Lesenswert?

> In Größenordnungen um 1ms sind Interruptroutinen meistens sowieso das
> falsche Mittel.
Nö, grade nicht.
Sind bei 100MHz ganze 100000 Takt-Cyclen (also bestenfalls so viele 
Befehle), mit denen du arbeiten kannst.

von sid (Gast)


Lesenswert?

wenn ich die Frage richtig verstanden habe,
dann seh ich auch den grösseren Nutzen darin den "unkritischen" Sensor
in einer schleife zu lesen,
dessen Wert kann damit ruhig einen Schleifendurchlauf altern (eben 
unkritisch)
solange der ADC (was auch immer dran hängt) das nicht tut, der bleibt in 
einer ISR.

Im Grunde braucht es also zwei globale variablen
einen für den alternden wert,
den anderen für die Abfrage ob die ISR aufgerufen wurde wurde
das kostet Taktzyklen leider.. ich glaub 5?

in pseudo code in etwa
1
//global vars
2
accsensordata; //kA was rein soll, int array würde ich vermuten
3
isrtriggered = false; // 'ne boolean
4
.......
5
isr()
6
{
7
    read_adcvalue();
8
    isrtriggered = true;
9
    report_isrdata();
10
    .......
11
}
12
13
main() //Hauptschleife, im Grunde irgendeine while(1) oder so
14
{
15
........
16
loopstart:
17
    isrtriggered = false; // ab hier ist nichtmehr egal ob der isr ausgelöst wurde
18
    // hier sollte nur was zwischen was auch den Beschleunigungssensor betrifft.
19
    preaparation(&sens);
20
    some_random_stuff(&sens);
21
    if(isrtriggered) goto loopstart; //bis hier ist alles 'geschützt'
22
    accsensordata = read_accsensor(&sens);
23
    report_sensordata();
24
........
25
}
Nachteil:
das Auslesen des Beschleunigungssensors (das war doch der unkritische, 
oder?)
über irgendetwas anderes als mundgemaltes Assembler vermutlich
eine mehrzeilige ungesicherte Lücke lässt in der der Interrupt die ISR 
auslösen kann.
ich glaube nicht, dass der isr zu jedem Taktzyklus ausgelöst werden 
kann,
ich meine immer nur vor oder nach einem assembler Befehl (nie probiert);
Also müsste die Abfrage ob der isr auslöste (isrtriggered) so nah wie 
möglich an das neuschreiben der Speicherzelle (accsensordata)
wenn es mehrere speicherzellen sind (array?) eventuell sogar vor jede 
davon.
Assembler verknotet mir aber zu sehr das Gehirn um das auch nur 
annäherend logisch/inhaltlich korrekt hier hinkritzeln zu können.(da 
brauch ich cheatsheets und Kaffee und jmd der mir die Hand hält für)
Das kann bestimmt jmd anderes besser als ich ;)

Das Prinzip bleibt dasselbe.
nachdem der immens wichtige Senor durch den interrupt ausgelöst wurde, 
setzt man ein flag,
das man in einer permanent laufenden schleife
exakt vor dem neuschreiben der Beschleunigungssensordaten prüft
um ggf zum Anfang der Schleife zurückzuspringen.

'okay' geht das in jeder Hochsprache die Sprungmarken akzeptiert (alle 
mir bekannten)

'richtig gut' geht das mMn nur in Assembler, weil man nur da 
sicherstellen kann, dass die Abfrage auch EXAKT einen Befehl vor dem 
Schreiben des Speichers landet und man im Zweifel auch an bessere 
Position zurückspringen kann.

'perfekt' geht das mMn garnicht,
da ich glaube der Interrupt kann keinen 'laufenden' assemblerbefehl 
abbrechen,
Also könnte der interrupt im Zweifel trotzdem
exakt ausgelöst werden nachdem gepüft wurde ob der isr aufgerufen worden 
ist, womit der Speicher in dieser Schleife dennoch mit dem 
möglicherweise schon veralteten 'neuen Wert' beschrieben würde.
Glücklicherweise ist das aber ja der unkritische von beiden ;)

Ich mag aber auch die Frage falsch verstanden haben, und der acc-sensor 
muss ebenfalls unbedingt via interrupt Aufruf seine Daten preisgeben.
#schulterzuck
In dem Fall würde man den interrupt des 'unkritischen' während der isr 
des 'dringenden' löschen müssen und erst nach dessen Ausführung wieder 
zulassen.


'sid

von Bernd M. (bernd_m)


Lesenswert?

Wie viele Daten müssen vom Accelerometer geholt werden?
Kann man die in kleineren Häppchen holen?
Lässt der/die/das Accelerometer das zu?

Dann wäre folgendes möglich:
jede 1ms ADC lesen und im Anschluss ein Häppchen vom Accelerometer

von MCUA (Gast)


Lesenswert?

>da ich glaube der Interrupt kann keinen 'laufenden' assemblerbefehl
>abbrechen,
Ein Interrupt unterbricht i.d.R. keinen ASM-Befehl, braucht er auch gar 
nicht, da ein ASM-Befehl, norm. sehr kurz ist.
(Ausnahme vielleicht umfangreiche Befehle, MUL, MAC, RMAC, Stingbefehle 
usw, die umfassendere Hardware erfordern. Bei einigen CPUs sind solche 
Befehle unterbrechbar (ggfs je nach INT-Priorität), bei anderen nicht.
Man sollte also je nach Timing-Anforderung (sofern man 'ms' und 'us' 
unterscheiden kann) drauf achten, zu lang andauernde Befehle ggfs. nicht 
zu benutzen, auch dürfen u.U. wegen Abhängigkeiten zusammenhängende 
Befehlsfolgen gar nicht unterbrochen werden.)

von MCUA (Gast)


Lesenswert?

>Unsinn, wir leben nicht mehr im Jahr 1970, wo Mikrocontroller
>bestenfalls dreistellige kHz Taktraten hatten.
Im Jahr 1970 gab es keine Mikrocontroller.

von Uwe (Gast)


Lesenswert?

Event System mit DMA sollte das ohne CPU Intervention hinbekommen...

von Falk B. (falk)


Lesenswert?

Uwe schrieb:
> Event System mit DMA sollte das ohne CPU Intervention hinbekommen...

Auf EINEM SPI-Bus? Soso . . .

Beitrag #6443507 wurde von einem Moderator gelöscht.
von W.S. (Gast)


Lesenswert?

Hanna schrieb:
> Ich benutze einen SAMD21J18A und ATMEL START/ATMEL Studio (AFS4)
> Umgebung, um ihn zu programmieren.

Das ist hier völlig nebensächlich. Nimm als Toolchain was dir gefällt, 
es spielt für einen sinnvollen Aufbau einer Firmware keine Rolle.

> Jetzt habe ich folgendes Problem:
> Ich habe einen SPI Bus, an dem verschiedene Sensoren dran hängen und
> einen Eingangs-Pin, der bei fallender Flanke eine Interruptfunktion
> auslösen soll, die mir einen bestimmten Sensor, über die SPI-Verbindung,
> auslesen soll.
>
> Wenn jetzt aber der Fall auftritt, dass gerade ein Sensor, der an
> besagtem SPI Bus hängt, ausgelesen wird und dabei gleichzeitig die
> Interruptfunktion aufgerufen wird, um einen anderen Sensor in diesem
> Bussystem auszulesen, führt das zu Kuddelmuddel.

Eben die Idee, so etwas machen zu wollen, ist der Grund für deinen 
Kuddelmuddel. Also mal was Grundsätzliches zu Interrupts:

Ein Interrupt ist etwas, das von der µC-Peripherie aktiviert wird, wenn 
eben genau DIESE ganz dringend einen Service benötigt. Die Betonung 
liegt auf DIESE.

Du hast hingegen irgend einen Eingang, an dem irgend eine Schaltung dran 
herumziehen kann, wenn sie meint, daß ein Sensor auszulesen sei. Ist ja 
nett, aber das hat mit dem SPI und dem Sensor rein garnichts zu tun. Es 
ist eine andere Aktivität als das Auslesen eines Sensors. Also hat so 
etwas auch rein garnichts in einer Interruptroutine zu suchen.

Mach eines: Wenn dein von irgendwo ausgelöster Interrupt kommt, dann 
generiere daraus einen Event, der in eine Event-Warteschlange eingereiht 
wird. Und eben diese Event-Warteschlange wird schön der Reihe nach in 
der Grundschleife in main abgearbeitet. Damit kannst du all die ganze 
Ausleserei gut genug steuern.

Meinetwegen nenne deine Events "LiesSensor1aus", "LiesSensor2aus", 
"LiesSensor4711aus" oder sonstwie und ordne diesen Events irgend eine 
passende Nummer zu. Wenn du nicht mehr als rund 250 verschiedene 
Eventarten brauchst, dann reicht pro Event ein simples Byte in der Queue 
aus.

W.S.

Beitrag #6443630 wurde von einem Moderator gelöscht.
von MCUA (Gast)


Lesenswert?

> Event System mit DMA sollte das ohne CPU Intervention hinbekommen...
Das funktioniert wie oben erläutert über gleiches SPI (mehrere Sensoren 
...) bis zu einer bestimmten Timing-Anforderung (sofern man Lesen kann 
und nicht auf Anfänger-Gesülze hört) über SPI-FIFO.

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.