stm32f302 使用DMA+USART 接收 一直在空闲中断中 出不来

2019-07-20 10:21发布



stm32f302 使用DMA+USART 接收 一直在空闲中断中 出不来  一直打印的都是

The lenght:128
The lenght:128  
The lenght:128



#define USART2_RDR_ADDRESS         ((u32)(USART2_BASE+0x24))  
u8 dma_flag = 0;

__IO char  receive_data[128]={0};


void Usart2_Init(uint32_t bound){

  GPIO_InitTypeDef GPIO_InitStructure;
        USART_InitTypeDef USART_InitStructure;

       
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA,ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);

        /* ′®¿ú2¶Ôó|òy½Å¸′óÃó3éä
         * GPIOA2¸′óÃÎaUSART2
         * GPIOA3¸′óÃÎaUSART2
         */
        GPIO_PinAFConfig(GPIOA,GPIO_PinSource2,GPIO_AF_7);
        GPIO_PinAFConfig(GPIOA,GPIO_PinSource3,GPIO_AF_7);
       

        /* USART2¶Ë¿úÅäÖÃ
         * GPIOA2,GPIOA3
         */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
        GPIO_Init(GPIOA,&GPIO_InitStructure);

//USART2 3õê¼»ˉéèÖÃ
        USART_InitStructure.USART_BaudRate = bound;
        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(USART2, &USART_InitStructure);

       
#if 1
        NVIC_InitTypeDef NVIC_InitStructure;
        //Usart2 NVIC ÅäÖÃ
        NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority =1;               
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                       
        NVIC_Init(&NVIC_InitStructure);               
#endif


//---USRAT_DMA
    USART_ITConfig(USART2, USART_IT_IDLE, ENABLE);
    USART_DMACmd(USART2,USART_DMAReq_Rx,ENABLE);
    USART_Cmd(USART2, ENABLE);
}


#if 1       
void USART2_IRQHandler(void)
{           
        u16 num;
        if(USART_GetITStatus(USART2,USART_IT_IDLE) != RESET)
        {  
               
                num = USART1->ISR;         
                num = USART1->RDR;     
                DMA_Cmd(DMA1_Channel6,DISABLE);        
                num = 128 - DMA_GetCurrDataCounter(DMA1_Channel6);
                 printf ("The lenght:%d ",num);
                DMA1_Channel6->CNDTR=128;
                USART_ClearITPendingBit(USART1, USART_IT_IDLE);  
                DMA_Cmd(DMA1_Channel6,ENABLE);

  }
}
#endif

void Usart2_DMA_Config()
{
        DMA_InitTypeDef  DMA_InitStructure;
        // ------------------DMA Init ½á11ìå2Îêy 3õê¼»ˉ--------------------------
  /* Enable DMA1 clock */
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);                        
  DMA_DeInit(DMA1_Channel6);
  DMA_Cmd(DMA1_Channel6, DISABLE);                                                                                    
  DMA_InitStructure.DMA_PeripheralBaseAddr = ((u32)USART2_RDR_ADDRESS);               
  DMA_InitStructure.DMA_MemoryBaseAddr = (u32)receive_data;                     
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;                           
  DMA_InitStructure.DMA_BufferSize = 128;                                         
  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_Medium;                             
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;                                      
    /* Enable DMA1 Channel6 */

  DMA_Init(DMA1_Channel6, &DMA_InitStructure);                 
  DMA_Cmd(DMA1_Channel6, ENABLE);   
       
       
}


void USART2_DMA_Init(uint32_t bound)
{
   Usart2_Init(115200);
   Usart2_DMA_Config();
}

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
5条回答
八度空间
1楼-- · 2019-07-20 16:15
本帖最后由 八度空间 于 2017-12-26 09:22 编辑

[mw_shl_code=applescript,true]/**
  *****************************************************************************
  * @name   : 串口接收中断服务程序
  *
  * @Brief  : none
  *
  * @Input  : none
  *
  * @Output : none
  *
  * @Return : none
  *****************************************************************************
**/
void USART1_IRQHandler(void)
{
        u32 status = 0;
        
        if (USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)  //产生了空闲中断
        {
                status = taskENTER_CRITICAL_FROM_ISR();
                DMA_Cmd(DMA1_Channel3, DISABLE);  //先关闭,预防干扰
                RX_Index = DMA_BUF_SIZE - DMA_GetCurrDataCounter(DMA1_Channel3);  //获取当前接收到的数据长度
                DMA1_Channel3->CNDTR = (uint16_t)DMA_BUF_SIZE;  //重新配置接收长度
                DMA_Cmd(DMA1_Channel3, ENABLE);
               
                (void)USART_ReceiveData(USART1);
               
                taskEXIT_CRITICAL_FROM_ISR(status);
        }
        USART_ClearITPendingBit(USART1, USART_IT_IDLE);
}[/mw_shl_code]

这是我的空闲中断处理

上面的做法是中断里边逗留的时间非常短,为了避免意外发生,改为下面的安全一点
[mw_shl_code=applescript,true]/**
  *****************************************************************************
  * @Name   : 串口接收中断服务程序
  *
  * @Brief  : none
  *
  * @Input  : none
  *
  * @Output : none
  *
  * @Return : none
  *****************************************************************************
**/
void USART1_IRQHandler(void)
{
        u32 status = 0;
       
        status = taskENTER_CRITICAL_FROM_ISR();
       
        if (USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)  //产生了空闲中断
        {
                DMA_Cmd(DMA1_Channel3, DISABLE);  //先关闭,预防干扰
                RX_Index = DMA_BUF_SIZE - DMA_GetCurrDataCounter(DMA1_Channel3);  //获取当前接收到的数据长度
                DMA1_Channel3->CNDTR = (uint16_t)DMA_BUF_SIZE;  //重新配置接收长度
                DMA_Cmd(DMA1_Channel3, ENABLE);
               
                (void)USART_ReceiveData(USART1);
        }
        USART_ClearITPendingBit(USART1, USART_IT_IDLE);
       
        taskEXIT_CRITICAL_FROM_ISR(status);
}[/mw_shl_code]
正点原子
2楼-- · 2019-07-20 21:29
 精彩回答 2  元偷偷看……
Maximilian
3楼-- · 2019-07-20 23:54
 精彩回答 2  元偷偷看……
八度空间
4楼-- · 2019-07-21 03:47
Maximilian 发表于 2017-12-26 14:35
status = taskENTER_CRITICAL_FROM_ISR();  是什么 ??我的一直卡在 中断里 打印 128 128 没有接受也打印

那是FreeRTOS里边临界语句,你没用OS的话将它删掉
Maximilian
5楼-- · 2019-07-21 08:12
 精彩回答 2  元偷偷看……

一周热门 更多>