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.