打印
[STM32H7]

H743 DMA传输中断的问题(续)

[复制链接]
995|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
阿尔法99|  楼主 | 2020-7-10 18:49 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
根据香水城老师的建议把DMA传输模式由内存-内存改为外设-内存,DMA中断寄存器DMA1->LISR相应标志位正常。但是有新的问题。需要两次启动DMA传输后,才能出现一次DMA中断。相关程序如下。

//DMA配置函数
void MYDMA_Config(DMA_Stream_TypeDef *DMA_Streamx,uint8_t chx,uint32_t par,uint32_t mar,uint16_t ndtr)
{
        DMA_TypeDef *DMAx;
        DMAMUX_Channel_TypeDef *DMAMUXx;
        uint8_t streamx;
        if((uint32_t)DMA_Streamx>(uint32_t)DMA2)//得到当前stream是属于DMA2还是DMA1
        {
                DMAx=DMA2;
                RCC->AHB1ENR|=1<<1;                //DMA2时钟使能  
        }else
        {
                DMAx=DMA1;
                RCC->AHB1ENR|=1<<0;                //DMA1时钟使能
        }
        while(DMA_Streamx->CR&0X01);//等待DMA可配置
        streamx=(((uint32_t)DMA_Streamx-(uint32_t)DMAx)-0X10)/0X18;                        //得到stream通道号
        if(streamx>=6)DMAx->HIFCR|=0X3D<<(6*(streamx-6)+16);                //清空之前该stream上的所有中断标志
        else if(streamx>=4)DMAx->HIFCR|=0X3D<<6*(streamx-4);                //清空之前该stream上的所有中断标志
        else if(streamx>=2)DMAx->LIFCR|=0X3D<<(6*(streamx-2)+16);        //清空之前该stream上的所有中断标志
        else DMAx->LIFCR|=0X3D<<6*streamx;                                                        //清空之前该stream上的所有中断标志

        if((uint32_t)DMA_Streamx>(uint32_t)DMA2)streamx+=8;                                        //如果是DMA2,通道编号+8
        DMAMUXx=(DMAMUX_Channel_TypeDef *)(DMAMUX1_BASE+streamx*4);        //得到对应的DMAMUX通道控制地址
        DMAMUXx->CCR=chx&0XFF;                //通道选择
       
        DMA_Streamx->PAR=par;                        //DMA外设地址
        DMA_Streamx->M0AR=mar;                //DMA 存储器0地址
        DMA_Streamx->NDTR=ndtr;                //DMA 存储器0地址
        DMA_Streamx->CR=0;                                //先全部复位CR寄存器值
       
        DMA_Streamx->CR|=0<<6;
        DMA_Streamx->CR|=0<<7;                //外设到存储器模式               
        DMA_Streamx->CR|=0<<8;                //非循环模式(即使用普通模式)
        DMA_Streamx->CR|=0<<9;                //外设非增量模式
        DMA_Streamx->CR|=1<<10;                //存储器增量模式
        DMA_Streamx->CR|=1<<11;                //外设数据长度:16位
        DMA_Streamx->CR|=1<<13;                //存储器数据长度:16位
        DMA_Streamx->CR|=1<<16;                //中等优先级
        DMA_Streamx->CR|=0<<21;                //外设突发单次传输
        DMA_Streamx->CR|=0<<23;                //存储器突发单次传输
       
        DMA_Streamx->CR|=1<<4;                //传输完成产生中断
        DMA_Streamx->CR|=1<<3;                //传输完成一半产生中断
        DMA_Streamx->CR|=1<<2;                //传输错误产生中断
        DMA_Streamx->CR|=1<<1;                //直接模式错误产生中断  
       
        //DMA_Streamx->FCR=0X21;        //FIFO控制寄存器
         
   // DMA interrupt init
  // DMA1_Stream0_IRQn interrupt configuration
  HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, 3, 0);
  HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn);
}

//开启一次DMA传输
//DMA_Streamx:DMA数据流,DMA1_Stream0~7/DMA2_Stream0~7
//ndtr:数据传输量  
void MYDMA_Enable(DMA_Stream_TypeDef *DMA_Streamx,uint16_t ndtr)
{

        DMA_Streamx->CR&=~(1<<0);         //关闭DMA传输
        while(DMA_Streamx->CR&0X1);        //确保DMA可以被设置  
       
        DMA_Streamx->NDTR=ndtr;                //DMA 存储器0地址
        DMA_Streamx->CR|=1<<0;                //开启DMA传输
}         

// dma传输完成中断处理
void DMA1_Stream0_IRQHandler(void)
{
  HAL_DMA_IRQHandler(&hdma_memtomem_dma1_stream0);
  /* USER CODE BEGIN DMA1_Stream0_IRQn 1 */
  if(__HAL_DMA_GET_FLAG(&hdma_memtomem_dma1_stream0,DMA_FLAG_TCIF0_4))//判断是否为DMA传输完成中断
  {
               
                        __HAL_DMA_CLEAR_FLAG(&hdma_memtomem_dma1_stream0,DMA_FLAG_TCIF0_4);//清除中断标志位
                        HAL_DMA_Abort_IT(&hdma_memtomem_dma1_stream0);      //传输完成以后关闭DMA
                        //在此添加dma传输完成后的函数
  }
}

//FIFO中断 外部中断1 PB1
void EXTI1_IRQHandler(void)
{
  /* USER CODE BEGIN EXTI1_IRQn 0 */

  /* USER CODE END EXTI1_IRQn 0 */
        DisADsample();
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1);
  /* USER CODE BEGIN EXTI1_IRQn 1 */
  MYDMA_Enable(DMA1_Stream0,16000);//开始一次DMA传输!                
  /* USER CODE END EXTI1_IRQn 1 */
}

//DMA初始化
MYDMA_Config(DMA1_Stream0,0,(uint32_t)0x64000000,(uint32_t) 0x24001000,16000);//DMA1,STEAM0,CH0,外设为FIFO,存储器为SendBuff,长度为:16000.

为什么两次启动DMA传输才能有一次DMA中断?
       

使用特权

评论回复
沙发
阿尔法99|  楼主 | 2020-7-10 18:54 | 只看该作者
我在外部中断函数里,启动两次DMA传输,DMA中断就正常了。但是这样处理总感觉哪里不对?
因为外部中断不能直接触发DMA,所以才这么处理。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

21

主题

219

帖子

1

粉丝