onlycook 发表于 2021-11-18 10:43

STM32F103 DMA+空闲中断接收不固定长度资料问题

STM32F103C8T6单晶片,使用USART1+DMA接收资料,RX
DMA_BufferSize设定为30 bytes,当接收长度<30 bytes,进USART1_IRQHandler(void)的空闲中断,但当资料长度=30 bytes时,会先进DMA1_Channel5_IRQHandler(void)的DMA 传输缓冲完成中断,然後再进USART1_IRQHandler(void)的空闲中断,想请问当资料长度=DMA_BufferSize时,如何不要进空闲中断,谢谢!


void RCC_Configuration(void)
{
         RCC_APB2PeriphclockCmd(RCC_APB2Periph_GPIOA| RCC_APB2Periph_USART1 ,ENABLE);
         RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
}

void GPIO_Configuration(void)
{
         GPIO_InitTypeDefGPIO_InitStructure;

         GPIO_DeInit(GPIOA);
         GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_9;                                                                            //TX
         GPIO_InitStructure.GPIO_Mode= GPIO_Mode_AF_PP;
         GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;
         GPIO_Init(GPIOA,&GPIO_InitStructure);

         GPIO_InitStructure.GPIO_Pin= GPIO_Pin_10;                                                                               //RX
         GPIO_InitStructure.GPIO_Mode= GPIO_Mode_IN_FLOATING;
         GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;
         GPIO_Init(GPIOA,&GPIO_InitStructure);
}

void USART_Configuration(void)
{
         USART_InitTypeDefUSART_InitStructure;
         
         USART_DeInit(USART1);
         USART_InitStructure.USART_BaudRate= 115200;
         USART_InitStructure.USART_WordLength= USART_WordLength_8b;
         USART_InitStructure.USART_StopBits= USART_StopBits_1;
         USART_InitStructure.USART_Parity= USART_Parity_No;
         USART_InitStructure.USART_HardwareFlowControl= USART_HardwareFlowControl_None;
         USART_InitStructure.USART_Mode= USART_Mode_Rx | USART_Mode_Tx;
         USART_Init(USART1,&USART_InitStructure);
         USART_Cmd(USART1,ENABLE);
         USART_ITConfig(USART1,USART_IT_IDLE,ENABLE);
}

void DMA_Configuration(void)
{
         DMA_InitTypeDefDMA_InitStructure;
         
         DMA_DeInit(DMA1_Channel4);
         DMA_InitStructure.DMA_PeripheralBaseAddr= (uint32_t)(&USART1->DR);
         DMA_InitStructure.DMA_MemoryBaseAddr= (uint32_t)TxBuffer;
         DMA_InitStructure.DMA_DIR= DMA_DIR_PeripheralDST;
         DMA_InitStructure.DMA_BufferSize= 256;
         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_InitStructure.DMA_Priority= DMA_Priority_VeryHigh;
         DMA_InitStructure.DMA_M2M= DMA_M2M_Disable;
         DMA_Init(DMA1_Channel4,&DMA_InitStructure);
         DMA_Cmd(DMA1_Channel4,ENABLE);
         DMA_ITConfig(DMA1_Channel4,DMA_IT_TC| DMA_IT_TE,ENABLE);
         
         DMA_DeInit(DMA1_Channel5);
         DMA_InitStructure.DMA_PeripheralBaseAddr= (uint32_t)(&USART1->DR);
         DMA_InitStructure.DMA_MemoryBaseAddr= (uint32_t)RxBuffer;
         DMA_InitStructure.DMA_DIR= DMA_DIR_PeripheralSRC;
         DMA_InitStructure.DMA_BufferSize= 30;
         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_PeripheralDataSize_Byte;
         DMA_InitStructure.DMA_Mode= DMA_Mode_Normal;
         DMA_InitStructure.DMA_Priority= DMA_Priority_VeryHigh;
         DMA_InitStructure.DMA_M2M= DMA_M2M_Disable;
         DMA_Init(DMA1_Channel5,&DMA_InitStructure);
         DMA_Cmd(DMA1_Channel5,ENABLE);
         DMA_ITConfig(DMA1_Channel5,DMA_IT_TC| DMA_IT_TE,ENABLE);
}

void NVIC_Configuration(void)
{
         NVIC_InitTypeDefNVIC_InitStructure;

         NVIC_InitStructure.NVIC_IRQChannel= USART1_IRQn;
         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= 2;
         NVIC_InitStructure.NVIC_IRQChannelSubPriority= 0;
         NVIC_InitStructure.NVIC_IRQChannelCmd= ENABLE;
         NVIC_Init(&NVIC_InitStructure);
         
         NVIC_InitStructure.NVIC_IRQChannel= DMA1_Channel4_IRQn;
         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= 1;
         NVIC_InitStructure.NVIC_IRQChannelSubPriority= 0;
         NVIC_InitStructure.NVIC_IRQChannelCmd= ENABLE;
         NVIC_Init(&NVIC_InitStructure);
         
         NVIC_InitStructure.NVIC_IRQChannel= DMA1_Channel5_IRQn;
         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= 0;
         NVIC_InitStructure.NVIC_IRQChannelSubPriority= 0;
         NVIC_InitStructure.NVIC_IRQChannelCmd= ENABLE;
         NVIC_Init(&NVIC_InitStructure);
}

void USART1_IRQHandler(void)
{
         uint8_t clear;
         if(USART_GetITStatus(USART1,USART_IT_IDLE)!=RESET)                           // forUSART_IT_IDLE
         {
                     clear= USART1->SR;                                                                                       //clear IT_IDLE
                     clear= USART1->DR;
                     data_len = 30- DMA_GetCurrDataCounter(DMA1_Channel5);
                     DMA_Cmd(DMA1_Channel5,DISABLE);                                                                     
                     DMA_SetCurrDataCounter(DMA1_Channel5,30);
                     DMA_Cmd(DMA1_Channel5,ENABLE);
         }
}

void DMA1_Channel4_IRQHandler(void)
{
         if(DMA_GetITStatus(DMA1_FLAG_TC4)!= RESET)                                                   //for DMA_IT_TC
         {
                     DMA_ClearITPendingBit(DMA1_IT_TC4);
         }
}

void DMA1_Channel5_IRQHandler(void)
{
         if(DMA_GetITStatus(DMA1_IT_TC5)!= RESET)                                              //for DMA_IT_TC
         {
                     DMA_ClearITPendingBit(DMA1_IT_TC5);
                     DMA_Cmd(DMA1_Channel5,DISABLE);                                                                     
                     DMA_SetCurrDataCounter(DMA1_Channel5,30);
                     DMA_Cmd(DMA1_Channel5,ENABLE);
         }
}

内政奇才 发表于 2021-11-18 10:46

全部使用空闲中断来判尾。

麻花油条 发表于 2021-11-18 10:47

把DMA发送中断关了,只用串口的空闲中断

豌豆爹 发表于 2021-11-18 10:48

抄空闲中断来接收

gwsan 发表于 2021-12-10 21:08

这个缓冲大小可以设置吗

kxsi 发表于 2021-12-10 21:09

这样判断会引起歧义吗

nawu 发表于 2021-12-10 21:12

可以自己进行定义啊

qcliu 发表于 2021-12-10 21:17

两个中断都开启了吗

tfqi 发表于 2021-12-10 21:19

不定长度的话如何判定发送完成了呢

香水城 发表于 2021-12-11 11:11

如果空闲中断和DMA传输完成中断都开的话,可以考虑进完成中断时先关闭空闲中断,处理后再开启。
反正空闲中断主要监测是否结束传输了或长时间没发生传输了的事件。
页: [1]
查看完整版本: STM32F103 DMA+空闲中断接收不固定长度资料问题