SDIO DMA模式无法进入SDIO发送结束中断

2019-10-15 18:45发布

我一直在搞SDIO的驱动,使用了DMA,可以进入DMA发送结束中断,但是无法进入SDIO结束中断,不明原因,请各位指点一下。@正点原子 [mw_shl_code=c,true]SDIO 初始化以及中断初始化
//SDIO 寄存器设置
        SDIO->CLKCR |= 0xB2; //分频值为178   得到时钟400KHz
        SDIO->CLKCR &= ~(1<<9);//关闭省电模式   时钟一直存在

        //SDIO->CLKCR &= ~(1<<14);  //禁用硬件流控
        SDIO->CLKCR |= 1<<14;  //
        SDIO->CLKCR |= 1<<13;  //主时钟下降沿产生SDIO时钟

        SDIO->CLKCR &= ~(3<<11); // 总线模式清零 使用1bit数据线 方便示波器观测数据
        //SDIO->CLKCR |= 2<<11;   //使用8bit数据线
       
        SDIO->CLKCR &= ~(1<<10); //关闭时钟旁路

        SDIO->POWER |= 0x03; //上电
        SDIO->CLKCR |= 1<<8; //时钟使能
       
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);        //设置中断分组

        NVIC_InitStructure.NVIC_IRQChannel = DMA2_Channel4_5_IRQn;                                                                //设置中断通道
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;                                                                //抢先优先级                    
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;                                                                                //响应优先级
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                                                                        //使能中断

        NVIC_Init(&NVIC_InitStructure);        //初始化中断

        NVIC_InitStructure.NVIC_IRQChannel = SDIO_IRQn;                                                                                        //设置中断通道
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;                                                                //抢先优先级                    
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;                                                                                //响应优先级
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                                                                        //使能中断

        NVIC_Init(&NVIC_InitStructure);        //初始化中断[/mw_shl_code]
[mw_shl_code=c,true]数据发送代码

SDIO->MASK  |= 1<<8;  //数据传输结束中断
        SDIO->MASK  |= 1<<10; //数据块结束中断
        SDIO->MASK        |= 1<<1;  //DCRC检测失败

        //SDIO_ITConfig(SDIO_IT_DBCKEND|SDIO_IT_DATAEND|SDIO_IT_DCRCFAIL,ENABLE);
        SDIO->DTIMER = 0xFFFFFFFF; //超时时间
        SDIO->DLEN = u32length&0x01FFFFFF;   //长度共25bit
        SDIO->DCTRL &= 0xffffff08;                        //清除之前的设置
        SDIO->DCTRL &= ~(1<<2);              //数据块传输
        SDIO->DCTRL |= u16block&0xF0;           //数据块长度
        SDIO->DCTRL &= ~(1<<1);                            //数据由控制器向外设发送
        SDIO->DCTRL |= (1<<3);              //使能DMA  
        SDIO->DCTRL |=0x01;                                 //使能传输


       
        DMA2->IFCR |= 0x0000f000;        //清除DMA2通道4相关中断标志位

        DMA2_Channel4->CCR &= !(1 << 0);                //通道不工作,关闭DMA2

        DMA2_Channel4->CCR &= 0x00000000;                //清除之前的设置
        DMA2_Channel4->CCR |= 0<<14;                        //非存储器到存储器模式
        DMA2_Channel4->CCR |= 2<<12;                        //通道优先级高

        DMA2_Channel4->CCR |= 2<<10;                //存储器数据宽度32bits
        DMA2_Channel4->CCR |= 2<<8;                        //外设数据宽度32bits

       
        DMA2_Channel4->CCR |= 1<<7;                                //执行存储器地址增量操作
        DMA2_Channel4->CCR |= 0<<6;                                //不执行外设地址增量操作
        DMA2_Channel4->CCR |= 0<<5;                                //不执行循环操作
        DMA2_Channel4->CCR |= (0x01<<4);                //设置传输方向

        DMA2_Channel4->CNDTR = u32length/4;
       
        DMA2_Channel4->CPAR  = (uint32_t)&SDIO->FIFO;        //外设地址
        DMA2_Channel4->CMAR  = (uint32_t)pu32data;                //存储器地址寄存器
        DMA2_Channel4->CCR |= 0x0A;                                           //开启传输错误中断和传输结束中断
        DMA2_Channel4->CCR |= 1<<0;                                            //通道开启,使能DMA2[/mw_shl_code]

[mw_shl_code=c,true]两个中断处理函数
void DMA2_Channel4_5_IRQHandler()
{
        int ii = 0;
        ii++;
        u8 u8sta = 0;

        u8sta = DMA_GetITStatus(DMA2_IT_TE4);
        if(u8sta == 1)
        {
                DMA_ClearITPendingBit(DMA2_IT_TE4);
                DMA_Cmd(SDIO_DMA_CH, DISABLE);
                u8SDIO_Trans_Error = 1; // 传输错误
        }
       
        u8sta = DMA_GetITStatus(DMA2_IT_TC4);
        if(u8sta == 1)
        {
                DMA_ClearITPendingBit(DMA2_IT_TC4);
                DMA_Cmd(SDIO_DMA_CH, DISABLE); // 传输完成
                u8SDIO_Trans_End = 1;
        }
        else
        {
                jj++;
        }
       
}


void SDIO_IRQHandler()
{
        if((SDIO->STA>>8)&0x01 == 1) //传输结束中断
        {
                SDIO->ICR |= 1<<8;
        }
       
        if((SDIO->STA>>1)&0x01 == 1) //CRC校验错误
        {
                SDIO->ICR |= 1<<1;
        }
       
        if((SDIO->STA>>10)&0x01 == 1) //块传输结束
        {
                SDIO->ICR |= 1<<10;
        }
}

[/mw_shl_code]





友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。