STM32 USART Interrupt nur für RX

Gast #2711886
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
Gast #2711899
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 :/
Gast #2711902
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.
Gast #2711907
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
Gast #2711947
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.
#2712428
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
Gast #2815713
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren