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.
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.
Juan Jin
DKNguyen