Electrical – Stop DMA USART in STM32

keilstm32

In a noisy media, I need to receive 10bytes with DMA (about 1Mb). I have set the DMA and its interrupt as shown below:


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

My buffer receives 10bytes. In a noisy media, some noises can deceive my receiver. I implement another pin for telling the receiver I need to send:


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

}

But I can't Enable and Disable DMA correctly(for example by getting 1-10 bytes it stop working in receiving mode). I disabled my DMA with different ways:

Disabling:
DMA_DeInit(DMA1_Channel3);
USART_DMACmd(USART3, USART_DMAReq_Rx, DISABLE);
DMA_Cmd(DMA1_Channel3, DISABLE);

Enabling:
Calling DMA_Configuration();
USART_DMACmd(USART3, USART_DMAReq_Rx, ENABLE);
DMA_Cmd(DMA1_Channel3, ENABLE);

I will be thankful if you could help me.

Best Answer

You have to reset your DMA counter (DMA_CNDTRx) every time it finishes. It doesn't automatically reset on its own when it reaches zero unless you are in circular mode.