Hallo, früher habe ich bei meinem Mikrocontroller einen FIFO Baustein eingesetzt, der die Bytes empfangen hat. im Timer interrupt des Mikrocontroller habe ich dann immer geschaut ob in dem FIFO was drin steht und wenn ja ausgelesen. Dadurch waren höhere Übertragungsraten möglich ohne das der Controller immer im UART Interrupt fest hängt. Nun setzt ich einen STM32 ein, dieser besitz ja ein DMA Modul. Dieses wollte ich für des damalige FIFO einsetzen. aber mittlwerweile hab ich gelesen das DMA pollen schwachsinnig ist oder es nicht geht. Aber wie sollte ich es dann machen, wenn die empfangene Telegrammlänge sich immer ändern kann? Am liebsten wäre es mir wenn ich das DMA so einsetzen könnte wie damals das FIFO. kennt sich jemand damit aus und kann mir helfen? DANKE
Wenn die STM32 auch Cortex-M3 Kerne haben, könnte man von den EFM32 Controllern (Energy Micro) die Beispiele im Prinzip übernehmen. Dort wird die Low Energy UART per DMA verwendet. Blackbird
meine Konfiguration sieht wie folgt aus von dem DMA void DMA_Configuration(void) { DMA_InitTypeDef DMA_InitStructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); DMA_DeInit(DMA1_Channel1); DMA_InitStructure.DMA_BufferSize = (uint16_t)3; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)RxBuffer1; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART3->DR; DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_Init(DMA1_Channel1, &DMA_InitStructure); /* Enable the USART Rx DMA request */ USART_DMACmd(USART3, USART_DMAReq_Rx, ENABLE); /* Enable DMA Stream Half Transfer and Transfer Complete interrupt */ DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE); DMA_ITConfig(DMA1_Channel1, DMA_IT_HT, ENABLE); DMA_Cmd(DMA1_Channel1, ENABLE); /* Enable the UART4 RX DMA Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } Da die Schnittstelle über Interrupt funktioniert, geh ich davon aus das die Konfiguration stimmt, allerdings hab ich jetzt den Interrupt ausgeschalten, damit es über DMA funktioniert
Beim MSP habe ich immer so gemacht das ich dem DMA die Gesamtmenge der Bytes gegeben habe welche in meinen Puffer reinpassen. Dann habe ich 10msec Takt geschaut aob sich Menge "der noch nicht Empfangenen*" Bytes geändert hat. Wenn diese runtergegangen ist und an einem Punkt für eine Bestimmte Zeit stehen geblieben ist habe ich den EMpfang als beendet angesehen und das Telegram ausgewertet. Das hat hervorragend funktioniert. Du brauchst aber irgendeine Bytemenge. * Beim MSP steht im Entsprechenden Register nur die menge der Bytes welche noch nicht verarbeitet wurden.
danke, interesanter hinweis. aber bin noch dabei meinen DMA generell zum laufen zu bekommen, aber es klappt einfach nicht. hab mir schon einige beispiele angeschaut aber irgendwie geht es trotzdem nicht
Ja der DMA ist allg. nicht ganz einfach da man ihm nicht beim Arbeiten zuschauen kann um zu sehen wo was schiefläuft. Hab auch ne ganze Weile gebraucht bis ich Ihn beim MSP430 zum laufen gebracht hatte.
Problem gelöst!!!! Das hauptproblem lag darin das ich den falschen Kanal gewählt hatte, dachte des wäre egal welcher. aber ein Blick ins Ref. Manual hilft
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.