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