Hallo zusammen Ich arbeite auf einem STM32F407 Ich benutze den DMA um bei der USART1 die Daten einzulesen. Die Länge ist auf 16Bytes eingestellt. void DMA_RS485_Init(void) { RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); DMA_InitTypeDef DMA_InitStruct; //USART1 TX IRQ Configuration over the DMA Controller DMA_DeInit(DMA2_Stream7); 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)&RS485_TX_Buffer; DMA_InitStruct.DMA_DIR = DMA_DIR_MemoryToPeripheral; DMA_InitStruct.DMA_BufferSize = RS485_data_size; 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); //USART1 RX IRQ Configuration over the DMA Controller DMA_DeInit(DMA2_Stream5); 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)&RS485_RX_Buffer; DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralToMemory; DMA_InitStruct.DMA_BufferSize = RS485_data_size; 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_Stream5, &DMA_InitStruct); /* Enable the USART Rx DMA request */ USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE); USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE); /* Enable DMA Stream Transfer Complete interrupt */ DMA_ClearITPendingBit(DMA2_Stream7, DMA_IT_TCIF7); DMA_ITConfig(DMA2_Stream7, DMA_IT_TC, ENABLE); /* Enable DMA Stream Receive Complete interrupt */ DMA_ClearITPendingBit(DMA2_Stream7, DMA_IT_TCIF5); DMA_ITConfig(DMA2_Stream5, DMA_IT_TC, ENABLE); DMA_ClearITPendingBit(DMA2_Stream7, DMA_IT_FEIF5); DMA_ITConfig(DMA2_Stream5, DMA_IT_FE, ENABLE); DMA_Cmd(DMA2_Stream5, ENABLE); //RX enable -> receive } /* Defines */ #define RS485_Port GPIOA #define RS485_RX GPIO_Pin_10 #define RS485_TX GPIO_Pin_9 #define RS485_RTS GPIO_Pin_12 #define RS485_CTS GPIO_Pin_11 #define RS485_data_size 16 Wenn jetzt warum auch immer nicht 16Bytes ankommen, sondern 1 Byte (Störung z.Bsp) und danach korrekt die 16 Bytzes dann löst der Interrupt aus und die Daten sind im Buffer, nur dass das 1. Byte dann den Wert der Störung hat und bei den 16Bytes die korrekt reinkommen somit 1 Byte fehlt. Wie kann man dies umgehen? Ich müsste ja einen Interrupt bei jedem Byte haben und wenn innerhalb von einer Zeit die restlichen Bytes nicht kommen den Buffer wieder löschen. Wenn ich den DMA auf 1 Byte einstelle ist die schöne DMA Funktion aber dahin und ich muss von Hand die Bytes zusammensetzen. Jemand ne Idee? Vielen Dank
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.