OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6374|回复: 5

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

[复制链接]

7

主题

27

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
450
金钱
450
注册时间
2017-12-13
在线时间
90 小时
发表于 2017-12-25 20:32:03 | 显示全部楼层 |阅读模式
1金钱


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\r\n",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();
}

2.PNG
1.PNG

最佳答案

查看完整内容[请看2#楼]

[mw_shl_code=applescript,true]/** ***************************************************************************** * @name : 串口接收中断服务程序 * * @Brief : none * * @Input : none * * @Output : none * * @Return : none ***************************************************************************** **/ void USART1_IRQHandler(void) { u32 status = 0; ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

120

主题

7878

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12012
金钱
12012
注册时间
2013-9-10
在线时间
427 小时
发表于 2017-12-25 20:32:04 | 显示全部楼层
本帖最后由 八度空间 于 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]
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165516
金钱
165516
注册时间
2010-12-1
在线时间
2116 小时
发表于 2017-12-26 00:30:21 | 显示全部楼层
参考下我发的dma接收代码,在我们正点原子培训板块下下面
回复

使用道具 举报

7

主题

27

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
450
金钱
450
注册时间
2017-12-13
在线时间
90 小时
 楼主| 发表于 2017-12-26 14:35:46 | 显示全部楼层
八度空间 发表于 2017-12-26 09:18
[mw_shl_code=applescript,true]/**
  *************************************************************** ...

status = taskENTER_CRITICAL_FROM_ISR();  是什么 ??我的一直卡在 中断里 打印 128 128 没有接受也打印
回复

使用道具 举报

120

主题

7878

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12012
金钱
12012
注册时间
2013-9-10
在线时间
427 小时
发表于 2017-12-26 14:46:54 | 显示全部楼层
Maximilian 发表于 2017-12-26 14:35
status = taskENTER_CRITICAL_FROM_ISR();  是什么 ??我的一直卡在 中断里 打印 128 128 没有接受也打印

那是FreeRTOS里边临界语句,你没用OS的话将它删掉
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复

使用道具 举报

7

主题

27

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
450
金钱
450
注册时间
2017-12-13
在线时间
90 小时
 楼主| 发表于 2017-12-26 15:19:55 | 显示全部楼层
八度空间 发表于 2017-12-26 14:46
那是FreeRTOS里边临界语句,你没用OS的话将它删掉

谢了 可以
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-19 19:56

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表