xzyang 发表于 2019-11-24 17:47:28

请教:TK499的Uart1串口DMA接收进不了中断

由于项目需要,串口速率为2.5Mbps,只能启用DMA接收,现在问题:无法进入DMA中断,如果打开串口接收中断,DMA可以进入中断,但串口也同时中断了,不是我想要的,代码如下:

/********************************************************************************************/
void Uart1_Rx_DMA_Init(u32 srcAdd,u32 len)
{
         NVIC_InitTypeDef   NVIC_InitStructure;       
   
       //SYSCFG->CFGR&=~(1<<11);//UART1_RX_映射到 bit11=0映射到DMA2_CH3,默认是映射到CH3,bit11=1映射到DMA2_CH6
       
       // RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);//DMA2时钟使能
          RCC->AHB1ENR|=1<<22;//DMA2时钟使能,21=DMA1,22=DMA2,
   
          while(DMA2_Channel3->CCR&0X01);//等待DMA可配置

       
          DMA2_Channel3->CPAR=(u32)& UART1->RDR;        //DMA1 外设地址 Uart1接收
          DMA2_Channel3->CMAR=(u32)srcAdd;//DMA1, 内存地址

          DMA2_Channel3->CNDTR=len;   //DMA2,传输数据量
       
          DMA2_Channel3->CCR=0;      //复位
          
          DMA2_Channel3->CCR|=1<<4;//从存储器读
          DMA2_Channel3->CCR|=0<<5;//普通模式
          DMA2_Channel3->CCR|=0<<6;//外设地址非增量模式
          DMA2_Channel3->CCR|=1<<7;//存储器增量模式
          DMA2_Channel3->CCR|=0<<8;//外设数据宽度为8位 9:8
          DMA2_Channel3->CCR|=0<<10; //存储器数据宽度8位 11:10
          DMA2_Channel3->CCR|=1<<12; //中等优先级      13:12
          DMA2_Channel3->CCR|=0<<14; //非存储器到存储器模式
               

          //DMA2_Channel3->CCR|=1<<3; //允许传输错误中断
          //MA2_Channel3->CCR|=1<<2; //允许半传输完中断
          DMA2_Channel3->CCR|=1<<1; //允许传输完中断
               
               
          DMA2_Channel3->CCR&=~(1<<0);       //先关闭DMA传输
               
               
          NVIC_InitStructure.NVIC_IRQChannel =DMA2_Channel3_IRQn;
          NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
          NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
          NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
          NVIC_Init( & NVIC_InitStructure);


          
}
/********************************************************************************************/
//开启一次DMA传输
void Uart1_DMA_Enable(u32 LEN)
{
          DMA2_Channel3->CCR&=~(1<<0);       //关闭DMA传输
          while(DMA2_Channel3->CCR&0X1);   //确保DMA可以被设置       
          DMA2_Channel3->CNDTR=LEN;          //DMA1,传输数据量
          DMA2_Channel3->CCR|=1<<0;          //开启DMA传输
}
/********************************************************************************************/
void DMA2_Channel3_IRQHandler(void)
{
        /*DMA_ISR:
          TEIF 1-8:   31,27,23,19,15,11,7,3通道x的传输错误标志
          HTIF 1-8:   30,26,22,18,14,10,6,2通道x的半传输标志
          TCIF 1-8:   29,25,21,17,13,9, 5,1通道x的传输完成标志
          GIF1-8:   28,24,20,16,12,8, 4,0通道x的全局中断标志
        */
       
       
        if((DMA2->ISR)&(1<<9))      //判断传输完成中断位是否置位 为嘛 是CH6的标志位?
       {
                        DMA2->IFCR |= 1<<8 ; //清除完成传输中断
                        DMA2->IFCR |= 1<<9 ; //清除完成传输中断
                        DMA2->IFCR |= 1<<10 ; //清除完成传输中断
                        DMA2_Channel3->CCR &= ~(1<<0);       //关闭DMA传输
                        Uart1_DMA_Enable(72);//再次开启DMA接收
                       
                       
                       
       }

      //printf("DMA2->ISR= %d\r\n",DMA2->ISR);//观察ISR状态

}
/********************************************************************************************/

void Uart1_Init(u32 BaudRate)
{
        UART_InitTypeDef       UART_InitStructure;
        GPIO_InitTypeDefGPIO_InitStructure;

      Uart1_Rx_DMA_Init((u32)uart1_rx_buf,72);//初始化DMA2_CH3
      
       
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
        GPIO_InitStructure.GPIO_Pin= GPIO_Pin_9;   //uart1_txPA9
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 推免复用输出
      GPIO_Init(GPIOA, &GPIO_InitStructure);

      GPIO_InitStructure.GPIO_Pin= GPIO_Pin_10;//uart1_rxPA10
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入   

      GPIO_Init(GPIOA, &GPIO_InitStructure);
       
        GPIO_PinAFConfig(GPIOA, GPIO_Pin_9 | GPIO_Pin_10, GPIO_AF_UART_1); //PA9、PA10复用为串口1



        RCC_APB2PeriphClockCmd(RCC_APB2Periph_UART1, ENABLE);
        UART_InitStructure.UART_BaudRate = BaudRate; //波特率
      UART_InitStructure.UART_WordLength = UART_WordLength_8b;//数据位
      UART_InitStructure.UART_StopBits = UART_StopBits_1;//停止位
      UART_InitStructure.UART_Parity = UART_Parity_No ;
      UART_InitStructure.UART_Mode = UART_Mode_Rx | UART_Mode_Tx;//输入输出模式
      UART_InitStructure.UART_HardwareFlowControl = UART_HardwareFlowControl_None;        
        UART_Init(UART1, &UART_InitStructure);
       
        //UART_DMACmd(UART1, UART_DMAReq_EN, ENABLE);//DMA使能
        //UART_Cmd(UART1, ENABLE);//UART 模块使能
       
        //全局寄存器GCR设置
        // GCR:bit4=TXEN, bit3=RXEN, bit2=自动流控,bit1=DMAMODE,bit0=UARTEN
      UART1->GCR |= 1<<0;//UART模块使能
        UART1->GCR |= 1<<1;//激活DMA模式
        UART1->GCR |= 1<<3;//开启RXEN接收
      UART1->GCR |= 1<<4;//开启TXEN发送
       

       
       
        //不需要串口接收中断,已知长度72字节,通过DMA完成接收中断处理
        //问题:如果此处打开接收中断, DMA2_CH3可以进入中断,但是串口也同时中断,如果不打开,DMA2_CH3 无法中断 !!!!
        /*
      UART_ClearITPendingBit(UART1, 0xff);
       
        UART_ITConfig(UART1, UART_IT_RXIEN, ENABLE);//使能接收中断UART_IER_RXBRKEN

       
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//2:2,全局性函数,仅需设置一次
        NVIC_SetPriority(UART1_IRQn,3);
        NVIC_EnableIRQ(UART1_IRQn);
      */

      Uart1_DMA_Enable(72);                   //开启DMA接收传输
}       

GunGun 发表于 2019-11-26 10:30:40

理论上那个串口中断空置不用不就行了?好像不耗费资源的?

eddia2012 发表于 2021-8-3 18:44:25

楼主,搞好了没有?
页: [1]
查看完整版本: 请教:TK499的Uart1串口DMA接收进不了中断