Hallo Zusammen,
Ich habe hier ein kleines Testsystem mit zwei Slaves und einem Master.
Die Kommunikation realisiere ich über UART. Der Master ist ein STM32 und
die Slaves STM8Ss.
Die Slaves lauschen auf Daten vom Master, welche an den jeweiligen Slave
adressiert sind (ID im Bytestream). Das ganze läuft für eine gewisse
Zeit sehr gut (30Sek-2Min). Danach jedoch sehen die beiden(!) Slaves mit
einem Mal keine eingehenden Daten mehr, als ob sich der UART an den
STM8ern abgeschaltet hätte (Auf der Leitung sind die Daten aber
vorhanden, - mit Oszilloskop gemessen).
Ich habe mit dem Interrupt getestet und bin nun beim pollen angelangt.
Jede Variante zeigt dieses Verhalten.
Meine Empfangsroutine startet so:
/* Read one byte from the receive data register */
9
byValue=UART1_ReceiveData8();
10
11
/* check for frame start */
12
if(START_OF_FRAME==byValue)
13
14
....
Im Fehlerfall hängen die STMs immer beim „while
(UART1_GetFlagStatus(UART1_FLAG_RXNE)“. Wenn ich das umgehe und einfach
immer nur per UART1_ReceiveData8() ein Byte vom UART DR lese und auf
mein Frame Start Byte warte, passiert nichts -> zum Beispiel:
1
while(UART1_ReceiveData8()!=START_OF_FRAME);
Wenn ich nur einen STM8 allein betreibe habe ich keine Probleme. Es kann
hin und wieder vorkommen, dass beide STM8s zur selben Zeit etwas senden,
was aber vom Master erkannt wird. Könnte das ein Problem für die STM8s
darstellen? Suche ich an der falschen Stelle? Hat jemand einen Tipp?
Danke!
Grüße
Chris
Servus,
mache das lieber per ISR und einen Protokoll. Pollen kann man schon aber
nur wenn man DMA hat oder einen Sender mit Buffer...
Du bekommst mit Sicherheit ein Overflow, weil die Daten zu langsam
abgearbeitet werden.
Programmiere also per ISR ein FIFO und werte die Daten per Protokoll
aus. Erstelle eine ISR die Fehler abarbeitet.
mfg
aSma>> schrieb:> Servus,> mache das lieber per ISR und einen Protokoll. Pollen kann man schon aber> nur wenn man DMA hat oder einen Sender mit Buffer...>> Du bekommst mit Sicherheit ein Overflow, weil die Daten zu langsam> abgearbeitet werden.>> Programmiere also per ISR ein FIFO und werte die Daten per Protokoll> aus. Erstelle eine ISR die Fehler abarbeitet.>> mfg
Hallo aSma
Meine erste Version sah genau so aus, also ISR + FIFO + Protokoll. das
einzige was ich da getestet habe, war das erste Byte des Frames ->
Startbyte. Sowie das Zweite Frame -> Länge des kommenden Frames.
Was für Fehler meinst du, die ich in der ISR abarbeiten sollte? Gibt es
da noch mehr Flags die man auswerten kann, bzw. zurücksetzen muss?
Ich hatte mal ausprobiert das OR Flag noch zurück zu setzen, aber da ist
mir der STM auch immer eingefroren
1
UART1_ClearFlag(UART1_FLAG_OR);
Wenn ich nur einen Slave nutze, läuft meine Lösung wirklich gut bei
250KBaud (sehr kurze Leitungen werden genutzt), ob ich nun Interrupt
oder Polling nehme.
Danke und Grüße
Chris
Christopher B. schrieb:> Check mal ob du nen Error bekommst UART_SR:(FE|OR). Manche> Controller> empfange nicht mehr wenn ein Fehler aufgetreten ist.
Hi Christopher,
das ist ein guter Hinweis, dass bestimmte Controller nicht mehr
empfangen. Was muss man dann im allgemeinen tun? Einfach die Fehler
Register wieder zurücksetzen?
(Ich teste mich da mal durch!)
Danke und Grüße!
Chris
Christoph R. schrieb:> /* wait here for first data byte */> while (UART1_GetFlagStatus(UART1_FLAG_RXNE) == RESET);
Fehler Quelle 1
>> /* Read one byte from the receive data register */> byValue = UART1_ReceiveData8();>> /* check for frame start */> if(START_OF_FRAME == byValue)
Fehler Quelle 2
Hier mein Beispiel für !stm32 aber:
USART_ClearITPendingBit(USART1,USART_IT_TXE);//clear flag
19
20
if(Usart_Tx_Buffer[Send_C]!='\0')
21
{
22
USART_SendData(USART1,Usart_Tx_Buffer[Send_C]);
23
Send_C++;
24
}else{
25
Send_C=0;
26
USART_ITConfig(USART1,USART_IT_TXE,DISABLE);
27
}
28
}
29
30
}
Alle Var in der ISR sind global und volatile!
Jetzt musst du nur noch eine Fkt. schreiben, in der du den Header,
Daten, Terminator bearbeitest. Ein Header aus nur einen Char ist halt
Fehler anfällig.
aSma, Christopher, ihr seids super :) Danke!
es ist eine Kombination aus beidem. Mit dem reinen Polling habe ich mich
etwas verzettelt. Initial warte ich nun auf einen USART_IT_RXNE
Interrupt, polle danach dann aber weiter (mit Timeout) - funktioniert
wunderbar. Mein Protokoll besteht übrigens aus einigen mehr bytes + crc
usw, - hatte es hier nur zur Vereinfachung weggelassen :)
In der ISR werte ich nun alle Flags aus, - und wie Christopher schon
vermutet, poppt irgendwann ein OR Interrupt auf. Genau da hängt es dann.
So ungefähr:
1
INTERRUPT_HANDLER(UART1_RX_IRQHandler,18)
2
{
3
if(UART1_GetFlagStatus(UART1_FLAG_RXNE)==SET)
4
{
5
IRQHandler_Rx();//-> Emfangsroutine
6
}
7
else
8
{
9
if(UART1_GetFlagStatus(UART1_FLAG_OR)==SET)
10
{
11
UART1_ReceiveData8();// -> clear!
12
}
13
if(UART1_GetFlagStatus(UART1_FLAG_FE)==SET)
14
{
15
UART1_ReceiveData8();
16
}
17
}
18
}
Interessant ist nur, warum immer beide Slaves gleichzeitig blockiert
wurden. Das liegt sicher irgendwo an der Tatsache, dass beide manchmal
zur selben Zeit senden.
Naja, so oder so, - es läuft jetzt erstmal :)
Danke nochmal für eure Zeit und euren Input!
Grüße
Chris
Eine eigene Frage?
Dieser Thread ist über 10 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.