Hallo zusammen, versuche mich gerade mit DMA in Verbindung mit UART auseinander zu setzen und habe ein Problem was ich nicht recht nachvollziehen kann. Ich habe einen Buffer u8 u8ByteBuffer[] = "UART Test...0."; Im DMA-Interrupt disable ich DMA mit DMA_Cmd(DMA2_Stream7, DISABLE); - TX complete Alle 200ms erhöhe ich die Stelle mit der 0 um eins mit i++; u8ByteBuffer[12] = i; und enable es nach Ändern des Buffers mit DMA_Cmd(DMA2_Stream7, ENABLE); An Stelle der 0 erscheint aber nicht der jeweils inkrementierte Wert, sondern so wie es aussieht etwas zufälliges. Halte ich im Keil-Debugger an der Stelle, sehe ich schön wie sich der Wert an Stelle 12 des Buffers jedesmal um 1 erhöht, wird aber irgendwie nicht per DMA übertragen. Ohne inkrementieren wird der String sauber alle 200ms im HTerm ausgegeben. Hat jemand eine Idee, woran das liegen kann? Vielen Dank schon mal, Frohe Weihnachten! :-) Hier meine Konfiguration: DMAStream7_Channel4_Init(); DMA_ITConfig(DMA2_Stream7, DMA_IT_TC, ENABLE); USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE); DMA_Cmd(DMA2_Stream7, ENABLE); void DMA2_Stream7_IRQHandler(void) { if(DMA_GetITStatus(DMA2_Stream7, DMA_IT_TCIF7) != RESET) { DMA_ClearITPendingBit(DMA2_Stream7, DMA_IT_TCIF7); OnUartDMA(); } } void OnUartDMA(void) { DMA_Cmd(DMA2_Stream7, DISABLE); } void DMAStream7_Channel4_Init(void) { RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); DMA_InitTypeDef DMA_InitStruct; DMA_StructInit(&DMA_InitStruct); DMA_InitStruct.DMA_Channel = DMA_Channel_4; DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&(USART1->DR); DMA_InitStruct.DMA_Memory0BaseAddr = (uint32_t)&u8ByteBuffer[0]; DMA_InitStruct.DMA_DIR = DMA_DIR_MemoryToPeripheral; DMA_InitStruct.DMA_BufferSize = 14; DMA_InitStruct.DMA_Priority = DMA_Priority_Medium; DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStruct.DMA_Mode = DMA_Mode_Normal; // DMA_InitStruct.DMA_Mode = DMA_Mode_Circular; DMA_InitStruct.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA_InitStruct.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; DMA_InitStruct.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStruct.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(DMA2_Stream7, &DMA_InitStruct); } static void USART_Config(void) { USART_InitTypeDef USART_InitStructure; USART_InitStructure.USART_BaudRate = 9600; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; STM_EVAL_COMInit(COM1, &USART_InitStructure); }
AndreasS schrieb: > An Stelle der 0 erscheint aber nicht der jeweils inkrementierte > Wert, sondern so wie es aussieht etwas zufälliges. Denk mal nach was Du da rein schreibst. Es sollte schon ein char sein, also ASCII 30..39.
AndreasS schrieb: > enable es nach Ändern des Buffers mit > DMA_Cmd(DMA2_Stream7, ENABLE); Reicht nicht. Musst auch Anfang des DMA Puffers neu setzen - sonst läuft der einfach nach Pufferende in den übrigen RAM rein. EDIT: Mach mal
1 | u8ByteBuffer[12] = i + '0'; |
Jim M. schrieb: > Reicht nicht. Musst auch Anfang des DMA Puffers neu setzen - sonst läuft > der einfach nach Pufferende in den übrigen RAM rein. Okay, und wie setze ich den DMA Puffer zurück? @hp-freund - Danke, aber es war erst mal unwichtig, ob es tatsächlich chars sind, zumindest der hex-wert sollte hochzählen ab 0x30, oder bin ich auf dem falschen Weg?
AndreasS schrieb: > Jim M. schrieb: >> Reicht nicht. Musst auch Anfang des DMA Puffers neu setzen - sonst läuft >> der einfach nach Pufferende in den übrigen RAM rein. > > Okay, und wie setze ich den DMA Puffer zurück? > > @hp-freund - Danke, aber es war erst mal unwichtig, ob es tatsächlich > chars sind, zumindest der hex-wert sollte hochzählen ab 0x30, oder bin > ich auf dem falschen Weg? @Jim, eine Ergänzung noch, es ist nur das Byte 12 was nicht passt, der Rest ist in Ordnung...
Noch eine Ergänzung: Wenn ich mit dem Debugger durchsteppe, werden die korrekten Werte an HTerm gesendet... Weiß jemand einen Rat? :-)
Was ist das physikalische Medium drunter? RS485? Beim letzten Zeichen sind dort Timingprobleme beim Richtungsswitchen ein sehr heißer Kandidat.
Jim M. schrieb: > u8ByteBuffer[12] = i + '0'; Das wird es wohl nicht sein. Bilde mal die differenz der hex Zahlen. Da hast du einen Offset mit drin.
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.