Stoppen Sie DMA USART in STM32

In einem lauten Medium muss ich 10 Bytes mit DMA empfangen (ca. 1 MB). Ich habe den DMA und seinen Interrupt wie unten gezeigt eingestellt:


void DMA_Configuration(void)
{
    DMA_InitTypeDef DMA_InitStructure;
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

DMA_DeInit(DMA1_Channel3);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART3->DR;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)Buffer;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = sizeof(Buffer) - 1;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode =DMA_Mode_Normal  ;//DMA_Mode_Circular
DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel3, &DMA_InitStructure);
USART_DMACmd(USART3, USART_DMAReq_Rx, ENABLE);
/* Enable DMA Stream Transfer Complete interrupt */
DMA_ITConfig(DMA1_Channel3, DMA_IT_TC, ENABLE);
DMA_Cmd(DMA1_Channel3, ENABLE);


}
void DMA1_Channel3_IRQHandler(void) // USART1_RX
    {
    if (DMA_GetITStatus(DMA1_IT_TC3))
        {
            SendTest=Buffer[2];
            DMA_ClearITPendingBit(DMA1_IT_TC3);
        }
    }

Mein Puffer erhält 10 Bytes. In einem lauten Medium können einige Geräusche meinen Empfänger täuschen. Ich implementiere einen weiteren Pin, um dem Empfänger mitzuteilen, dass ich senden muss:


void EXTI15_10_IRQHandler(void){

if (EXTI_GetITStatus(EXTI_Line10) != RESET) {
            if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_10)==0 ){DMA_Configuration();GPIO_ResetBits(GPIOA,GPIO_Pin_5);}
            else
            {       //USART_DMACmd(USART3, USART_DMAReq_Rx, ENABLE);

                    GPIO_SetBits(GPIOA,GPIO_Pin_5);
                    DMA_DeInit(DMA1_Channel3);
                    //USART_DMACmd(USART3, USART_DMAReq_Rx, DISABLE);

            }

    EXTI_ClearITPendingBit(EXTI_Line10);
}

}

Aber ich kann DMA nicht richtig aktivieren und deaktivieren (wenn ich zum Beispiel 1-10 Bytes bekomme, funktioniert es nicht mehr im Empfangsmodus). Ich habe mein DMA auf verschiedene Arten deaktiviert:

Deaktivieren: DMA_DeInit(DMA1_Channel3); USART_DMACmd (USART3, USART_DMAReq_Rx, DEAKTIVIEREN); DMA_Cmd (DMA1_Channel3, DEAKTIVIEREN);

Aktivieren: Aufruf von DMA_Configuration(); USART_DMACmd (USART3, USART_DMAReq_Rx, ENABLE); DMA_Cmd (DMA1_Channel3, ENABLE);

Ich wäre Ihnen dankbar, wenn Sie mir helfen könnten.

Danke für deinen Kommentar. Sie gehen davon aus, dass ich DMA mit einem externen Interrupt starten und stoppen muss, um den USART-Empfänger zu deaktivieren und zu aktivieren. Das Geräusch kann von einem elektrischen Motor, einer Unterbrechung des Kabels während des Sendens der Daten usw. stammen. Ich wäre Ihnen dankbar, wenn Sie mir beim Stoppen und Starten des DMA während dieses von mir erwähnten Zyklus helfen könnten.
Ich glaube ich habe deine Frage falsch verstanden. Ihr Problem ist, dass Sie Ihren DMA nicht mehr als einmal zum Laufen bringen können, richtig? Sie müssen Ihren DMA-Zähler (DMA_CNDTRx) jedes Mal zurücksetzen, wenn er fertig ist. Es wird nicht von selbst zurückgesetzt, es sei denn, Sie befinden sich im kreisförmigen Modus.

Antworten (1)

Sie müssen Ihren DMA-Zähler (DMA_CNDTRx) jedes Mal zurücksetzen, wenn er fertig ist. Es wird nicht automatisch zurückgesetzt, wenn es Null erreicht, es sei denn, Sie befinden sich im Zirkularmodus.

Danke, aber wie Sie sehen können, habe ich DMA_DeInit(DMA1_Channel3) verwendet; und dann DMA_Configuration(); vor jeder Übertragung und in DMA_DeInit haben wir DMAx_Channey->CNDTR = 0; Ich habe jedoch DMA1_Channel3->CNDTR = 0 hinzugefügt; DMA1_Channel3->CMAR = 0; Linien zu meiner Interrupt-Routine, aber es funktioniert wieder nicht.
@Parisa Deaktivierst du den DMA vor deinit? Oder deaktiviert Deinit den Kanal selbst? CNDTR wird nur gelesen, während der DMA-Kanal aktiviert ist
Danke für deinen Kommentar
@Parisa Hat das das Problem gelöst?
Entschuldigen Sie die Verzögerung meiner Antwort. Ich habe gerade den Modus auf Circular geändert und die Endaktivierung von DMA, USART und Interrupts in der EXTI-Funktion deaktiviert. Ändern Sie in der Disable- und Enable-Funktion der CMSIS-Bibliothek die genannten Variablen.