Forum: Mikrocontroller und Digitale Elektronik STM32 USART Interrupt nur für RX


von stm32 (Gast)


Lesenswert?

Hallo Leute,

folgendes Problem habe ich:

meine UART schickt Blockweise (1024 Byte Blöcke + Checksumme) ne Menge 
Daten an meinen PC. Dafür setzt eine Timer Interrupt Routine eine Flag, 
die in der Main abgefragt wird und wenn der Puffer (eben die 1024 Byte) 
voll ist, wird das gesamte Array an sendchar(int size,int *data) 
übergeben.
Das funktioniert soweit auch alles fein.

Ich möchte nun aber von außen Parametrierungen vornehmen können. Ich 
möchte, dass die Reaktionsgeschwindigkeit relativ hoch ist, daher dachte 
ich ich an der selben Uart an einen Interrupt. Nun ist natürlich das 
Problem, dass zig Mal hintereinander der Interrupt ausgelöst wird, weil 
TXE gesetzt wird, weil wieder ein Byte verschickt wurde. Jedes Mal auf 
RXNE zu prüfen ist ja eher ineffektiv.

Gibt es daher eine Möglichkeit, den UART Interrupt NUR auf eingehende 
Daten zu "triggern"? Da beide das DR Register verwenden fürchte ich das 
nicht. Und wenn ich den Interrupt deaktiviere, während ich den Puffer 
verschicke, verliere ich möglicherweise Eingaben.

Was kann man also noch machen, außer bei oben genannter gesetzter Timer 
Flag auf RXNE zu prüfen (das ginge, aber ist je nach Timereinstellung 
halt nicht reaktionsfreudig!)?

Und ja, ich kann auch eine zweite Uart nehmen, bedeutet aber ein Kabel 
und einiges an Konfiguration mehr. Möchte ich möglichst vermeiden.

Danke und schöne Grüße

von stm32 (Gast)


Lesenswert?

Oh man. Ja, vergesst das oben Geschriebene, man kann ja die Interrupts 
ja doch für einzelne Ereignisse konfigurieren..
1
USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState)
Dann mit USART_IT_RXNE nur RXNE anschalten.

Sorry :/

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Bei Start der Übertragung USART_CR1_TXEIE Interrupt aktivieren, wenn das 
letzte Zeichen verschickt ist den deaktivieren.
So habe ich das gelöst und es braucht keinen extra Timer.

von Nonam (Gast)


Lesenswert?

>Ich möchte nun aber von außen Parametrierungen vornehmen können.
Aha. Welche Parameter möchtest Du ändern können?

>Ich möchte, dass die Reaktionsgeschwindigkeit relativ hoch ist, daher >dachte ich 
ich an der selben Uart an einen Interrupt.
Wessen Reaktionsgeschwindigkeit? Welche Reaktion soll schnell erfolgen. 
Was ist "relativ hoch"? 1ms, 1s?

>Nun ist natürlich das Problem, dass zig Mal hintereinander der Interrupt 
>ausgelöst wird, weil TXE gesetzt wird, weil wieder ein Byte verschickt >wurde. 
Jedes Mal auf RXNE zu prüfen ist ja eher ineffektiv.
Hm. Der Effekt soll doch sein, ein empfangenes Byte zu erkennen. Also 
ist es effektiv. Was verstehst Du unter effektiv?

Hm. Naja. Klingt eher nach nem Konzeptproblem und nach 
Anfänger-Herumgeschwafel unter Verwendung von "geilen" Fachworten.

Schreib mal was das Gesamtprojekt ist und welche Reaktionszeiten du 
tatsächlich brauchst. "Schnell" lässt sich leider nicht im STM 
konfigurieren.

von Strickwettbewerbgewinner (Gast)


Lesenswert?

Auch wenn ich deinen Text nicht wirklich verstehe, folgendermaßen kannst 
du Interrupts für das TXE und das RXNE Event seperat aktivieren:
1
USART_ITConfig (USART1, USART_IT_TXE, ENABLE); // IRQ wird ausgeführt wenn Daten gesendet werden können
2
USART_ITConfig (USART1, USART_IT_RXNE, ENABLE); // IRQ wird ausgeführt wenn Daten empfangen wurden

von stm32 (Gast)


Lesenswert?

Nonam schrieb:
>>Ich möchte nun aber von außen Parametrierungen vornehmen können.
> Aha. Welche Parameter möchtest Du ändern können?
>
z.B. verschiedene Log Modi (es wird per Encoder Interface die aktuelle 
Position eines Getriebes ausgelesen), die mir mal den absoluten Winkel, 
mal die Geschwindigkeit etc anzeigen.

>>Ich möchte, dass die Reaktionsgeschwindigkeit relativ hoch ist, daher >dachte 
ich
> ich an der selben Uart an einen Interrupt.
> Wessen Reaktionsgeschwindigkeit? Welche Reaktion soll schnell erfolgen.
> Was ist "relativ hoch"? 1ms, 1s?
>

Alle 500us wird das Encoder Register ausgelesen also gibt es jede halbe 
Sekunde einen Block an Daten. Die Ansteuerung/Auswertung geschieht per 
matlab Skript, die Parameterveränderung soll möglichst zeitnah geschehen 
(die halbe Sekunde wird in der Praxis wohl nichts ausmachen, aber es 
geht hier doch auch um eine elegante Lösung)

>>Nun ist natürlich das Problem, dass zig Mal hintereinander der Interrupt
>>ausgelöst wird, weil TXE gesetzt wird, weil wieder ein Byte verschickt >wurde.
> Jedes Mal auf RXNE zu prüfen ist ja eher ineffektiv.
> Hm. Der Effekt soll doch sein, ein empfangenes Byte zu erkennen. Also
> ist es effektiv. Was verstehst Du unter effektiv?
>

Ja da hast du Recht. Es ist in der Tat effektiv, aber nicht effizient. 
Danke für den Hinweis

> Hm. Naja. Klingt eher nach nem Konzeptproblem und nach
> Anfänger-Herumgeschwafel unter Verwendung von "geilen" Fachworten.
>
jo ziemlich geile Fachwörter. Anfänger kommt hin, ja.
> Schreib mal was das Gesamtprojekt ist und welche Reaktionszeiten du
> tatsächlich brauchst. "Schnell" lässt sich leider nicht im STM
> konfigurieren.

Hab' ich ja jetzt verstanden.
Projekt wurde oben erläutert, die Parameter werden on the fly verändert, 
die Veränderung sollte mit einer vom Menschen möglichst nicht 
wahrnehmbarer Verzögerung erfolgen, sprich es wird auf einen Button 
geklickt, der schickt eine Anweisung, der uC empfängt und prüft das 
Paket (Paketlänge, Prüfsumme) und führt die Anweisung aus.

Strickwettbewerbgewinner schrieb:
> Auch wenn ich deinen Text nicht wirklich verstehe, folgendermaßen kannst
> du Interrupts für das TXE und das RXNE Event seperat aktivieren:...

Japs, vielen Dank. Ist mir oben auch (zu spät leider) aufgefallen.

von Reinhard B. (brainstorm)


Lesenswert?

stm32 schrieb:
> die Veränderung sollte mit einer vom Menschen möglichst nicht
> wahrnehmbarer Verzögerung erfolgen

Hallo stm32,

Frage ist zwar geklärt, aber noch eine Anmerkung:
Wenn man den STM32 nicht gerade mit einer Taktfrequenz der Größenordnung 
1Hz versorgt, dann hat das Prüfen des einen Bits auf die Wahrnehmung 
eines Menschen ca. Null Auswirkung.

Mach dir klar, wie lange der Controller (ungefähr) für die Abarbeitung 
der entsprechenden Befehle benötigt - und im Vergleich dazu, was für 
einen Menschen noch als "sofort" wahrnehmbar ist. Da liegen Welten 
dazwischen.

mfg
Reinhard

von Karl Heinz (Gast)


Lesenswert?

Hi,

ich versuche genau das gleiche. Koenntest du den Code vielleicht 
posten/hochladen?

Ich hab eine Main() Loop  in der ich bei jedem durchgang die serielle 
schnittstelle abfrage (usart2). Ich wuerde aber gerne lieber bei 
empfangenen bytes einen interrupt ausloesen um eine entsprechende 
funktion auszuloesen (je nach empfangenen zeichen).

Waere wirklich sehr dankbar!

VG
KH

von Ersi (cell85)


Lesenswert?


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.