Ich versuche, UART an einem STM32F0-Teil zum Laufen zu bringen, und kann die Interrupts nicht herausfinden. Laut Referenzhandbuch
Bit 7 TXE: Transmit data register empty
This bit is set by hardware when the content of the USARTx_TDR register has been
transferred into the shift register. It is cleared by a write to the USARTx_TDR register.
An interrupt is generated if the TXEIE bit =1 in the USARTx_CR1 register.
Allerdings kann ich das TXE-Flag nie klar sehen. Folgendes habe ich in meinem IRQ-Handler:
if(USART_GetITStatus(EVAL_COM1, USART_IT_TXE) != RESET)
{
/* Write one byte to the transmit data register */
if (TxBuffer[TxCount] != '\0')
{
USART_SendData(EVAL_COM1, TxBuffer[TxCount++]);
}
//else{
// USART_ITConfig(EVAL_COM1, USART_IT_TXE, DISABLE);
//}
}
Wenn ich die else-Anweisung nicht auskommentiere, wird der Sende-Interrupt endlos ausgelöst, auch wenn ich aufhöre, Bytes an das TDR zu senden. Gibt es eine Möglichkeit, die Interrupts zu stoppen, ohne sie zu deaktivieren? Oder muss ich jedes Mal neu aktivieren, wenn ich etwas senden möchte?
Wenn USARTx_TDR
das Register leer ist, USART_ISR_TXE
wird das Flag auf 1 gesetzt. Wenn USARTx_CR1_TXEIE
( TXE
Interrupt Enable Flag) aktiviert ist, TXE=1
wird der Interrupt angehalten.
Daher ist das Codebeispiel mit dem Deaktivieren des Interrupts nach abgeschlossener Übertragung eine gute Lösung.
Wenn Sie die Übertragung regelmäßig starten, schreiben Sie einfach das erste Byte (es wird gelöscht TXE
) und aktivieren Sie den Interrupt.
Oder wenn möglich DMA verwenden - etwas mehr Code, aber nachdem Sie strlen
es berechnet und konfiguriert haben, ist es eher Feuer und Vergessen ;)
Anstatt TXE als Flag zu betrachten, das gelöscht werden muss, sollte man es als Hinweis darauf betrachten, dass der UART bereit ist, Daten zur Übertragung anzunehmen. Die Tatsache, dass Sie keine Daten für Übertragungsdaten haben, bedeutet nicht, dass sie nicht bereit sind.
Einige Mikrocontroller wie der 8051 haben ein Flag, das gesetzt wird, wenn der UART das Setzen eines Bytes beendet hat, aber auch manuell gelöscht werden kann. Solche Konstruktionen neigen dazu, selbst bei einfach gepufferten UARTs Probleme zu verursachen, und sind für UARTs, die doppelt gepuffert sein können, völlig ungeeignet.
Der richtige Ansatz besteht einfach darin, den Transmit-Data-Empty-Interrupt immer dann zu aktivieren, wenn Sie etwas Interessantes zu sagen haben, und ihn zu deaktivieren, wenn Sie dies nicht tun. In manchen Fällen kann es hilfreich sein, einen Interrupt im Sende-Leerlauf zu aktivieren, wenn Sie etwas übertragen, und den Interrupt-Handler dafür auf die abgeschlossene Übertragung reagieren zu lassen und den Interrupt zu deaktivieren. Obwohl es ungewöhnlich erscheinen mag, dass ein Interrupt-Handler den Interrupt deaktiviert, ohne die Ursache zu "beheben", ist dies in Fällen, in denen eine andere Aktion im System dazu führt, dass der Interrupt wieder aktiviert wird, durchaus angemessen.
Tut
spizzak
Tut