Detener DMA USART en STM32

En un medio ruidoso, necesito recibir 10 bytes con DMA (alrededor de 1 Mb). He configurado el DMA y su interrupción como se muestra a continuación:


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);
        }
    }

Mi búfer recibe 10 bytes. En un medio ruidoso, algunos ruidos pueden engañar a mi receptor. Implemento otro pin para decirle al receptor que necesito enviar:


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);
}

}

Pero no puedo habilitar y deshabilitar DMA correctamente (por ejemplo, al obtener de 1 a 10 bytes, deja de funcionar en modo de recepción). Deshabilité mi DMA de diferentes maneras:

Deshabilitar: DMA_DeInit(DMA1_Channel3); USART_DMACmd(USART3, USART_DMAReq_Rx, DESHABILITAR); DMA_Cmd(DMA1_Channel3, DESHABILITAR);

Habilitación: Llamar a DMA_Configuration(); USART_DMACmd(USART3, USART_DMAReq_Rx, HABILITAR); DMA_Cmd(DMA1_Channel3, HABILITAR);

Estaré agradecido si usted me puede ayudar.

Gracias por tu comentario. Usted asume que necesito iniciar y detener DMA con una interrupción externa para deshabilitar y habilitar el receptor USART. El ruido puede ser de un motor eléctrico, interrupción en el cable durante el envío de los datos, etc. Agradecería si me pudieran ayudar a detener e iniciar el DMA durante este ciclo que les he mencionado.
Creo que entendí mal tu pregunta. Su problema es que no puede hacer que su DMA funcione más de una vez, ¿verdad? Tienes que restablecer tu contador DMA (DMA_CNDTRx) cada vez que finaliza. No se reinicia solo a menos que esté en modo circular.

Respuestas (1)

Tienes que restablecer tu contador DMA (DMA_CNDTRx) cada vez que finaliza. No se restablece automáticamente por sí solo cuando llega a cero, a menos que esté en modo circular.

Gracias, pero como puede ver usé DMA_DeInit(DMA1_Channel3); y luego DMA_Configuration(); antes de cada transmisión y en DMA_DeInit tenemos DMAx_Channey->CNDTR = 0; Sin embargo, he agregado DMA1_Channel3->CNDTR = 0;DMA1_Channel3->CMAR = 0; líneas a mi rutina de interrupción pero no funciona de nuevo.
@Parisa ¿Está deshabilitando el DMA antes de deinit? ¿O deinit deshabilita el canal en sí? CNDTR es de solo lectura mientras el canal DMA está habilitado
gracias por tu comentario
@Parisa ¿Eso resolvió el problema?
Perdón por la demora en mi respuesta. Acabo de cambiar el modo a circular y deshabilité la habilitación final de DMA, USART, Interrupciones en la función EXTI. En la biblioteca CMSIS deshabilitar y habilitar la función, cambie las variables mencionadas.