Hallo zusammen Ich möchte die USART1 über den DMA starten, was aber nicht richtig gelingt, denn jetzt habe ich endlos Zeichen auf dem Port, das heisst das Senden funktioniert, aber stellt nicht mehr ab, wieso das? unsigned char bufferRS485[129] = "Hello World, this is a DMA test. If you can read this the DMA is still working!\n"; void USART1_Init(void) { GPIO_InitTypeDef GPIOA_InitStructure; USART_InitTypeDef USART1_InitStructure; //USART 1 Init RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); USART1_InitStructure.USART_BaudRate = 115200; USART1_InitStructure.USART_WordLength = USART_WordLength_8b; USART1_InitStructure.USART_StopBits = USART_StopBits_1; USART1_InitStructure.USART_Parity = USART_Parity_No; USART1_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART1_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART1, &USART1_InitStructure); USART_Cmd(USART1, ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); GPIOA_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIOA_InitStructure.GPIO_OType = GPIO_OType_PP; GPIOA_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; GPIOA_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIOA_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIOA_InitStructure); GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1); GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1); } void DMA_RS485_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)&bufferRS485; DMA_InitStruct.DMA_DIR = DMA_DIR_MemoryToPeripheral; DMA_InitStruct.DMA_BufferSize = 129; DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStruct.DMA_Mode = DMA_Mode_Circular; DMA_InitStruct.DMA_Priority = DMA_Priority_Medium; 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); } Im Main läuft dies (nur 1mal) USART1_Init(); DMA_RS485_Init(); USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE); DMA_Cmd(DMA2_Stream7, ENABLE); NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream7_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x07; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); void DMA2_Channel4_IRQHandler(void) { DMA_ClearFlag(DMA2_Stream2, DMA_FLAG_TCIF2); DMA_ClearFlag(DMA2_Stream7, DMA_FLAG_TCIF2); DMA_ClearFlag(DMA2_Stream2, DMA_FLAG_HTIF2); DMA_ClearFlag(DMA2_Stream7, DMA_FLAG_HTIF2); } Was mache ich da falsch? Danke.
Vielen Dank! Passt jetzt, ausser dass die Ausgabe zu lange ist (siehe Bild)
>Passt jetzt, ausser dass die Ausgabe zu lange ist (siehe Bild)
DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
Ein char ist kein Halfword.
holger schrieb: >>Passt jetzt, ausser dass die Ausgabe zu lange ist (siehe Bild) > > DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; > > Ein char ist kein Halfword. Ok, habe es jetzt so gemacht: 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)&bufferRS485; DMA_InitStruct.DMA_DIR = DMA_DIR_MemoryToPeripheral; DMA_InitStruct.DMA_BufferSize = 81; 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_Priority = DMA_Priority_Medium; DMA_InitStruct.DMA_FIFOMode = DMA_FIFOMode_Enable; DMA_InitStruct.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; DMA_InitStruct.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStruct.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(DMA2_Stream7, &DMA_InitStruct); Trotzdem habe ich am Anfang 0x00 vor dem 0x48 (H), warum dies? Danke Holger
>> Ein char ist kein Halfword. > >Das heisst wie macht man das richtig? Man sucht in der Headerdatei nach DMA_MemoryDataSize_HalfWord. Bei Eclipse z.B. muss man nur mal das Wort markieren und F3 drücken. Dann schaut man nach was es da noch so gibt und besser passt.
>Trotzdem habe ich am Anfang 0x00 vor dem 0x48 (H), warum dies?
Man könnte darauf kommen das dies schon mit Ausgabe der Uhrzeit
und Datum gesendet wurde.
holger schrieb: >>Trotzdem habe ich am Anfang 0x00 vor dem 0x48 (H), warum dies? > > Man könnte darauf kommen das dies schon mit Ausgabe der Uhrzeit > und Datum gesendet wurde. Nein ist es leider nicht, kommt definitiv über die USART1 raus
>> Man könnte darauf kommen das dies schon mit Ausgabe der Uhrzeit >> und Datum gesendet wurde. > >Nein ist es leider nicht, kommt definitiv über die USART1 raus Das widerspricht meiner Theorie nicht. Wo kommt diese Ausgabe von Datum und Uhrzeit her?
holger schrieb: > Das widerspricht meiner Theorie nicht. > > Wo kommt diese Ausgabe von Datum und Uhrzeit her? Vom Terminal Programm Docklight. Ist jetzt aber gelöst, hatte zweimal die Anweisung: DMA_Cmd(DMA2_Stream7, ENABLE); drin, einmal im main, einmal im config... Danke
> DMA_InitStruct.DMA_Memory0BaseAddr = (uint32_t)&bufferRS485; > DMA_InitStruct.DMA_BufferSize = 81; Ist dein String wirklich 81 Zeichen lang? Versuchs mal so: DMA_InitStruct.DMA_BufferSize = strlen(bufferRS485);
holger schrieb: > Ist dein String wirklich 81 Zeichen lang? > > Versuchs mal so: > > DMA_InitStruct.DMA_BufferSize = strlen(bufferRS485); Nein waren 80, aber habe dies schon gefunden gehabt, DANKE! Etwas anderes -> wegen dem Interrupt Controller für diesen DMA: void DMA2_Stream7_IRQHandler (void) { /* Test on DMA Stream Transfer Complete interrupt */ if (DMA_GetITStatus(DMA2_Stream7, DMA_IT_TCIF4)) { /* Clear DMA Stream Transfer Complete interrupt pending bit */ DMA_ClearITPendingBit(DMA2_Stream7, DMA_IT_TCIF4); // USART_SendData(UART1, 'C'); } /* Test on DMA Stream Half Transfer interrupt */ if (DMA_GetITStatus(DMA2_Stream7, DMA_IT_HTIF4)) { /* Clear DMA Stream Half Transfer interrupt pending bit */ DMA_ClearITPendingBit(DMA2_Stream7, DMA_IT_HTIF4); // USART_SendData(UART4, 'H'); } } Die Routine wird aufgerufen aber beide if sind false, da auch eine Idee was falsch ist? Herzlichen Dank!
nicht nur stur kopieren/einfügen sondern auch mal nachlesen
1 | DMA2_Stream7, DMA_IT_HTIF4 |
wenn Stream7 dann "DMA_IT_HTIF7" das gilt für alle 4 stellen im Code Gruss Uwe
Uwe B. schrieb: > nicht nur stur kopieren/einfügen sondern auch mal nachlesen > >
1 | > DMA2_Stream7, DMA_IT_HTIF4 |
2 | > |
> > wenn Stream7 dann "DMA_IT_HTIF7" > > das gilt für alle 4 stellen im Code > > Gruss Uwe Ok Danke. Aber wie soll dann bei Stream7 zwischen USART1 und 6 unterschieden werden? (siehe Bild)
Das sagst du dem doch schon in dieser Zeile:
1 | DMA_InitStruct.DMA_Channel = DMA_Channel_4; //USART1 ausgewählt |
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.