Forum: Mikrocontroller und Digitale Elektronik cortex-m0+ inline assembler anweisung


von Elektolurch (Gast)


Lesenswert?

Hallo,

ich programmiere in GCC-C (Atmel Studio 7) einen Cortex-M0+ Prozessor.
Nun habe ich Probleme, die sich wohl nur durch (inline-) Assembler lösen 
lassen, da ich auf die Flanke von sehr schnellen/kurzen Signalen 
synchronisieren muss. Die CPU läuft auf 48MHz (max.), das Signal hat 
60ns Pulsdauer. Nach der Flankenerkennung darf eine feste Zeit vergehen, 
bis der Pegel eines Portpins oder eines Registerbits geändert wird.
Es braucht auch nicht gleich die erste oder jede Flanke erkannt werden.
Wichtig ist nur eine definierte Reaktionszeit nach einer Flanke.

Da ich von Assembler nur wenig Ahnung habe, bräuchte ich fachmännische 
Hilfe.

- Problem 1:
An Portpin PA18 (Eingang) liegt 16MHz (50:50) Signal an.
Nach fallender Flanke PA18 soll Portpin PA00 den Pegel wechseln.

- Problem 2:
Nach einem 60ns langen Puls an Portpin PA02 muss innerhalb 6µs eine 
Timer-PWM gestartet werden - TC3->COUNT8.CTRLA.bit.ENABLE= 1

Weis jemand dafür Assembler-Lösungen?

von Axel S. (a-za-z0-9)


Lesenswert?

Elektolurch schrieb:

> ich programmiere in GCC-C (Atmel Studio 7) einen Cortex-M0+ Prozessor.
> Nun habe ich Probleme, die sich wohl nur durch (inline-) Assembler lösen
> lassen, da ich auf die Flanke von sehr schnellen/kurzen Signalen
> synchronisieren muss.

Es ist unwahrscheinlich, daß die Lösung dafür in (Inline) Assembler 
liegt. Schreibst du ja selber:

> Weis jemand dafür Assembler-Lösungen?

Ein wesentliches Charakteristikum der µC-Programmierung liegt darin, daß 
man Probleme nicht (nur) mit brachialer CPU-Power rein softwaremäßig 
löst, sondern daß man die vorhandenen spezialisierten Hardware-Einheiten 
benutzt. Für die schnelle Reaktion auf Pegelwechsel würden sich 
Pin-Change Interrupts oder Timer anbieten.

> - Problem 1:
> An Portpin PA18 (Eingang) liegt 16MHz (50:50) Signal an.
> Nach fallender Flanke PA18 soll Portpin PA00 den Pegel wechseln.

Also ein schlichter Frequenzteiler 2:1? Warum belästigst du den µC mit 
derartigen Trivialitäten?

> - Problem 2:
> Nach einem 60ns langen Puls an Portpin PA02 muss innerhalb 6µs eine
> Timer-PWM gestartet werden - TC3->COUNT8.CTRLA.bit.ENABLE= 1

6µs Reaktionszeit sind eine Ewigkeit bei 48MHz Taktfrequenz. Das kann 
man mit einem Interrupt lösen.

von Nop (Gast)


Lesenswert?

Der Punkt ist hier wohl eher die Interrupt-Latenz als die 
Code-Ausführung. 6µs bei 48MHz entspricht immerhin 288 Takten, da 
solltest Du auch mit C keine Probleme haben. Hast Du denn das überhaupt 
schon mit C versucht? Was ist das Ergebnis?

von Johannes S. (Gast)


Lesenswert?

kann der µC das nicht in Hardware? Timmer triggern und bei Ablauf 
Ausgang setzen?

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


Lesenswert?

Da es um Atmel und CM0+ geht: SAMD21 und Konsorten haben das 
Event-System des Xmega geerbt. Das wäre aus meiner Sicht prädestiniert 
für solche Aufgaben.

von Elektolurch (Gast)


Lesenswert?

Nein, es geht NICHT um einen Frequenzteiler 2:1.
Ich muss einen Synchronisationsimpuls für ein IC erzeugen (einmalig zur 
richtigen Zeit)

Problem 2:
>> Hast Du denn das überhaupt schon mit C versucht? Was ist das Ergebnis?
Das habe ich natürlich:
while(!(PORT->Group[PORTA].IN.reg & PORT_PA18)) ;  // bei 0-Pegel warten
while(PORT->Group[PORTA].IN.reg & PORT_PA18)  ;  // bei 1-Pegel warten
PORT->Group[PORTA].OUTCLR.reg= PORT_PA00; // Ausgang ändern

Das Programm bleibt im Run-Modus bei einer While-Schleife hängen.
Die letzte Anweisung wird also nie ausgeführt.
Erstaunlicher weise läuft es im Step-Over Debugmodus durch!

>> 6µs Reaktionszeit sind eine Ewigkeit bei 48MHz Taktfrequenz. Das kann
man mit einem Interrupt lösen.
Ja, das muss ich mir nochmal durchdenken, da ich andere INTs solange 
sperren kann. Nur hoffe ich, dass meine 2 hoch priorisierten DMA-Kanäle 
da nicht auch noch in die Latenzzeit reinpfuschen.

>> SAMD21 und Konsorten haben das Event-System des Xmega geerbt. Das wäre aus 
meiner Sicht prädestiniert für solche Aufgaben.
Danke für den Hinweis. Muss mal schauen, ob ich über das Eventsystem
den PWM-Timer starten oder synchronisieren kann.

Ich dachte halt, dass sich die Probleme mit effektiven 
Assembler-Anweisungen direkt lösen lässt.
Die beschriebenen Probleme sind auch nur ein Teil des ganzen 
Synchronisations-Problems.

von Axel S. (a-za-z0-9)


Lesenswert?

Elektolurch schrieb:
> Nein, es geht NICHT um einen Frequenzteiler 2:1.
> Ich muss einen Synchronisationsimpuls für ein IC erzeugen (einmalig zur
> richtigen Zeit)

Das war deiner Beschreibung nicht zu entnehmen.
Ich kopiere sie nochmal her:

>> An Portpin PA18 (Eingang) liegt 16MHz (50:50) Signal an.
>> Nach fallender Flanke PA18 soll Portpin PA00 den Pegel wechseln.

Ein 16MHz Signal produziert am laufenden Band fallende Flanken. Und von 
"einmalig" steht da nichts.

>>> Hast Du denn das überhaupt schon mit C versucht?
> Das habe ich natürlich:
> while(!(PORT->Group[PORTA].IN.reg & PORT_PA18)) ;  // bei 0-Pegel warten
> while(PORT->Group[PORTA].IN.reg & PORT_PA18)  ;  // bei 1-Pegel warten
> PORT->Group[PORTA].OUTCLR.reg= PORT_PA00; // Ausgang ändern

Aha. Du versuchst es also auf die dummstmögliche Weise. Nochmal:

Axel S. schrieb:
> Ein wesentliches Charakteristikum der µC-Programmierung liegt
> darin, daß man Probleme nicht (nur) mit brachialer CPU-Power
> rein softwaremäßig löst, sondern daß man die vorhandenen
> spezialisierten Hardware-Einheiten benutzt.

Bei einem SAMD spielt da das Event-System natürlich die erste Geige. 
Hatte ich gar nicht so auf dem Radar.

>>> 6µs Reaktionszeit sind eine Ewigkeit bei 48MHz Taktfrequenz.
>>> Das kann man mit einem Interrupt lösen.

> Ja, das muss ich mir nochmal durchdenken, da ich andere INTs solange
> sperren kann.

Wozu das denn? Ein Cortex-M kann verschachtelte Interrupts.

> Ich dachte halt, dass sich die Probleme mit effektiven
> Assembler-Anweisungen direkt lösen lässt.

Du mußt dich davon lösen, alles von der CPU machen lassen zu wollen. 
Damit kommst du auf keinen grünen Zweig. Es sei denn, deine CPU ist sehr 
sehr sehr viel schneller als die Signale, die sie verarbeiten muß.

von Uwe Bonnes (Gast)


Lesenswert?

Welche Peripheriefunctionenhaben PA18 und PA02?

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


Lesenswert?

Uwe Bonnes schrieb:
> Welche Peripheriefunctionenhaben PA18 und PA02?

Dazu müsste er wohl erstmal schreiben, welcher Controller es konkret ist 
… den SAMD21 hatte ich nur in den Ring geworfen, weil es einer der 
ersten Cortex-M0+ von Atmel war (OK, es gab auch noch einen SAMD20 
davor).

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.