Hallo Ich empfange mit einem STM32F4 über die USART1 mit dem DMA Datenpakete, die 16Bytes lang sein müssen. Es kommt jetzt beim Aufstarten aber vor, dass vom Sender aus schon ein 0x00 geschickt wird, das ich ausfiltern möchte. Ich habe jetzt den idle IRQ vom USART1 konfiguriert, um in so einem Fall den Inhalt des DMA zu löschen. Leider weiss ich jetzt nicht wie man ins Register vom DMA kommt, denn in "meinem" Register liegen die Daten erst, wenn 16 Bytes im Buffer sind. DMA_InitStruct.DMA_Memory0BaseAddr = (uint32_t)&RS485_RX_Buffer; Ich müsste also bei einem idle IRQ von UASART1 den DMA Inhalt löschen um bei den korrekt eintreffenden 16Bytes wieder einen leeren Buffer zu haben, da ansonsten die 16Bytes um 1 Stelle verschoben werden und ich das Kommando nicht mehr kenne. Danke für Inputs
Das unerwünschte 0x00 Paket kommt nur nach einem Reset? Hast du schon probiert, nach dem Empfang des Pakets den DMA Controller zurückzusetzen (Enable->Disable->Enable) oder die DMA_Memory0BaseAddr neu zu schreiben? Wann der interne DMA-Zähler auf null zurückspringt sollte ja im Datenblatt stehen. Oder gibt es vielleicht ein Register, in dem der akutelle Zählwert steht? Dem Sender das Verschicken des unerwünschten Pakets abzügewöhnen ist keine Alternative?
Markus R. schrieb: > Das unerwünschte 0x00 Paket kommt nur nach einem Reset? Hast du schon > probiert, nach dem Empfang des Pakets den DMA Controller zurückzusetzen > (Enable->Disable->Enable) oder die DMA_Memory0BaseAddr neu zu schreiben? > Wann der interne DMA-Zähler auf null zurückspringt sollte ja im > Datenblatt stehen. Oder gibt es vielleicht ein Register, in dem der > akutelle Zählwert steht? > > Dem Sender das Verschicken des unerwünschten Pakets abzügewöhnen ist > keine Alternative? nein leider nicht denn Störungen können dasselbe bewirken
Mach Fax schrieb: > nein leider nicht denn Störungen können dasselbe bewirken wenn du von Störungen bei der Kommunikation ausgehen musst, können die zu jedem Zeitpunkt zuschlagen und nicht nur beim start somit kommst du um eine Verifizierung der Daten mit entsprechendem Protokoll nicht drum rum bedeutet : A. Daten per Checksumme sichern und bei Fehler neu anfordern B. Daten nach RX-Timeout verwerfen und neu anfordern C. was dir sonst noch so einfällt Gruss Uwe
:
Bearbeitet durch User
mache ich schon mit checksum usw, alles geklärt. Das Problem ist dass mir der IRQ der Kommunikation erst kommt wenn die 16Bytes des DMA voll sind und wenn jetzt der Buffer schon mit "Müll" gefüllt ist bekomme ich beim IRQ vom DMA nur die Hälfte der Daten
so wie ich es verstanden habe, hast du einen Buffer (und einen IRQ) für 16 Bytes Daten und bei einem Fehler kommen mehr als die 16 Bytes an (z.B. durch ein Fehlerhaftes 0x00 am Anfang vom Packet) dann bekommst du aber doch einen IRQ, nämlich nach dem 15ten richtigen Zeichen was du dann machen kannst in der ISR 1. erkennen das das Packet falsch ist (z.B. durch Checksumme) 2. Packet verwerfen 3. DMA reseten (damit ist auch ein etwaiger "rest" gelöscht) 4. Packet neu anfordern oder versteh ich da noch was falsch
Uwe B. schrieb: > so wie ich es verstanden habe, hast du einen Buffer (und einen IRQ) > für 16 Bytes Daten > > und bei einem Fehler kommen mehr als die 16 Bytes an > (z.B. durch ein Fehlerhaftes 0x00 am Anfang vom Packet) > > dann bekommst du aber doch einen IRQ, > nämlich nach dem 15ten richtigen Zeichen > > was du dann machen kannst > > in der ISR > 1. erkennen das das Packet falsch ist (z.B. durch Checksumme) > 2. Packet verwerfen > 3. DMA reseten (damit ist auch ein etwaiger "rest" gelöscht) > 4. Packet neu anfordern > > oder versteh ich da noch was falsch Nein genau so muss es sein. Ich bekomme einen Interrupt wenn der DMA auslöst (nach 16 Zeichen) und einen wenn die UART in einen Timeout geht (nach jeder Übertragung von Bytes, die irgendwann fertig ist) Ich muss jetzt in dieser Routine vom Timeout, (der nach dem einen Byte kommt) den DMA Inhalt löschgen, nur weiss ich nicht wie...
so wie es Markus oben schon geschrieben hat, probier mal: DMA-Disable Interrupt-Flags löschen DMA-Enable
Hier die Lösung: Beim Idle IRQ muss die USART1 ausgelesen werden um diesen IRQ zu löschen, dann DMA deaktivieren und wieder aktivieren um DMA Buffer zu löschen. //RS485 receive IRQ void DMA2_Stream5_IRQHandler (void) { /* Test on DMA Stream Receive Complete interrupt */ if (DMA_GetITStatus(DMA2_Stream5, DMA_IT_TCIF5)) { /* Clear DMA Stream Receive Complete interrupt pending bit */ DMA_ClearITPendingBit(DMA2_Stream5, DMA_IT_TCIF5); RS485_GetData(); RS485_RX_Init(); DMA_Cmd(DMA2_Stream5, ENABLE); //RX enable -> receive } } void USART1_IRQHandler(void) { if (USART_GetITStatus(USART1, USART_IT_IDLE) != RESET) { USART_ReceiveData(USART1); //read to clear the IRQ //diable and enable the DMA to clear the Buffer DMA_Cmd(DMA2_Stream5, DISABLE); //RX disable DMA_Cmd(DMA2_Stream5, ENABLE); //RX enable -> receive } }
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.