STM32F407 USART1 mit DMA IRQ bei weniger Bytes

OP #3719279
Lesenswert?
• ▲
▼
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

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.