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
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.