Hallo Leute,
habe mal wieder eine Frage an euch. Ich habe hier ein STM32VL-Discovery
Board liegen. Ich programmiere gerade eine Art Gateway, welches einen
Computer mit einem I/O-Modul verbindet, für meine Bachelorarbeit. Ich
möchte hier jetzt nicht den ganzen Code posten, da er zu lang ist, aber
hier folgt der Code für den USART2, welcher für die Kommunikation mit
einem Computer zuständig ist.
1
// Handle Interrupts on USART2 (USB connection)
2
voidUSART2_IRQHandler()
3
{
4
uint8_ti;
5
uint16_tcrc;
6
7
// Receive-Interrupt
8
if(USART_GetITStatus(USART2,USART_IT_RXNE))
9
{
10
// Reset the interrupt-flag
11
USART_ClearFlag(USART2,USART_FLAG_RXNE);
12
13
TIM4->CNT=0x00;
14
15
// Enable the status LED "Connection to computer okay"
Die Kommunikation funktioniert soweit prima. Wenn ich zum Computer jede
Menge Daten vom I/O-Modul schicke, ohne das der Computer sich einmischt,
klappt das auch soweit. Da habe ich schon über Millionen Daten rüber
geschaufelt. Wenn der Computer aber nun während der Übertragung noch
anfragen nach dem aktuellen Status des Gateways stellen soll,
funktioniert dies zunächst auch noch und dann bricht die Kommunikation
zusammen. Wenn ich nun mit Atolic TrueStudio debugge und schau wo er
hängen geblieben ist, dann springt er immer wieder in die oben
aufgeführte ISR, aber beide abfragen (Receive-Interrupt und
Transmit-Interrupt) sind falsch. Kurz danach springt er wieder rein und
die abfragen sind wieder beide falsch. Irgendwie scheint er also in
dieser ISR zu hängen, obwohl es keinen Interrupt gibt. Die
Interrupt-Flags setzte ich aber immer wieder sofort zurück.
Ich weiß, es sind nicht viele Infos und wahrscheinlich könnt ihr mir da
nicht groß weiter helfen. Vielleicht hat aber der ein oder andere von
euch doch so eine Vermutung, woran der Fehler liegen könnte.
Gruß
Mister232
Also bisher hat das immer sehr gut funktioniert. Das Problem ist ja
auch, dass er in die ISR springt, aber beide Abfragen (TXE und RXNE) das
Ergebnis falsch liefern
Aber warum wird die ISR aufgerufen, wenn kein Interrupt vorliegt? Und
es passiert auch erst nach einer kurzen Weile.
Andere Interrupt-Ursache wie z.b. frame Error oder overrun ? Schon mal
das gesamte Interruptstatus-register ausgelesen, ob noch andere Bits als
die von dir getesteten gesetzt sind?
Jens K. schrieb:> Aber warum wird die ISR aufgerufen, wenn kein Interrupt vorliegt?
So, Bachelor willst du werden. Damit?
Eine ISR wird nicht aufgerufen, jedenfalls nicht im landläufigen Sinne,
sondern sie ist die Reaktion der Hardware auf einen zur Reaktion
anstehenden Interrupt. Es gibt je nach µC und Peripherie ganz
unterschiedliche Interrupt-Verhaltensweisen. Manchmal ist es so, daß ein
Interrupt gnadenlos "kommt", wenn eine statische Bedingung erfüllt ist.
Aber meistens ist es so, daß ein Interrupt ausgelöst wird, wenn eine
statische Bedingung erfüllt wird (also von NEIN auf JA wechselt).
Bei den mir bekannten UART-Cores von NXP und ST ist letzteres der Fall,
also der Interrupt "kommt" nur dann, wenn das Sende-Puffer-Register
gerade leer wird. Wenn es erstmal leer ist_ und leer _bleibt dann
gibt's keinen Interrupt.
Mein dringender Rat: schmeiße diese ST-Lib aus deinen Programmen raus
und lerne, die Peripherie SELBST zu verstehen. Zumindest dies würde
ich von einem angehenden Bachelor erwarten.
W.S.
Jim Meba schrieb:> Kann man das TXE Interrupt Flag beim STM32VL einfach so "clear"en?
Nein, das kann man nicht. Man stellt ggf. den entsprechenden Interrupt
ab, und wieder an, wenn im Puffer was drin ist.
Sein Umgang mit RXNE ist ähnlich sinnlos. Weil unnötig.
Danke für deinen Rat. Dafür habe ich aber leider keine Zeit mehr. Ich
bin Hardwareentwickler und kein Softwareentwickler. Die Software gehörte
nur leider mit zur Bachelorarbeit dazu, also versuche ich mich ein wenig
damit anzufreunden. Ich bin überhaupt schon froh das sie bis jetzt
zumindest einigermaßen läuft.
Jens K. schrieb:> aufgeführte ISR, aber beide abfragen (Receive-Interrupt und> Transmit-Interrupt) sind falsch.
Was bedeutet, sie "sind falsch"?
> Interrupt-Flags setzte ich aber immer wieder sofort zurück.
TXE nicht, weil das schlicht nicht geht. Und RXNE setzt sich beim Lesen
vom Datenregister selbst zurück.
Es gibt aber neben RXNE und TXE weitere Interrupt-Möglichkeiten. Wenn
die eingeschaltet sind, aber nicht behandelt werden, dann gibts
Dauerarbeit für den armen Handler.
Jens K. schrieb:> Und welche sind das?
Schau ins CR1 rein, da sind alle IE-Bits aufgereiht.
> Wie lassen sie sich ausschalten?
Indem man sie nicht erst einschaltet. Genauer wirds nicht, weil ich
ebenso wie W.S. kein Freund der Lib bin, sondern auf die Register gehe.
Aber du kannst ja mal den übrigen Code der USART hier reinstellen. Also
Init, und was sonst noch damit arbeitet.