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


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Elektolurch (Gast)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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. (jojos)


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

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


Bewertung
1 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht lesenswert
Welche Peripheriefunctionenhaben PA18 und PA02?

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


Bewertung
1 lesenswert
nicht 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).

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.