就叫不死鸟 发表于 2017-1-11 16:15:31

STM32F103SDIO时钟以及多块发送的问题

本帖最后由 就叫不死鸟 于 2017-1-11 16:17 编辑

近来遇到两个SDIO发送的问题:1:在调试过程中我想发送64Bytes的数据,如果SDIO块大小(DBLOCKSIZE)设置为64Bytes,长度(DLEN)设置为64Bytes,是可以正常发送出去的,但是如果设置为块大小为32Bytes,长度为64Bytes,那么实际上只能发出去长度为32Bytes的数据,也就是说实际发送的数据是和块大小相同的,而不是和数据长度相同,不知是哪里出了问题,
2:前提是我使用了8Bits数据线,当我使用18MHz时钟时,发送任意大小的数据块(1Bytes--16KBytes)通过示波器观察波形数据都是正常而且正确的,但是当使用24MHz时钟时,发送的数据块只能是小于8Bytes,当使用36MHz时钟时,数据块只能是4Bytes,否则就只能看到第一个4字节的数据,后面的CRC校验数据都是没有的,不知道问题在哪。
请了解的人帮忙指点一二,多谢了!
代码如下初始化

void SDIO_Init_Reg()
{

        NVIC_InitTypeDef NVIC_InitStructure;

        GPIOC->CRL &= 0X00FFFFFF;
        GPIOC->CRL |= 0XBB000000;//PC6 PC7 对应 D6 D7 设置为推挽输出

        GPIOC->CRH &= 0XFFF00000;
        GPIOC->CRH |= 0X000BBBBB; //PC8 PC9 PC10 PC11 PC12 分别对应 D0 D1 D2 D3 CLK 设置为推挽输出

        GPIOB->CRH &= 0XFFFFFF00;
        GPIOB->CRH |= 0X000000BB; //PB8 PB9 分别对应 D4 D5设置为推挽输出

        GPIOD->CRL &= 0XFFFFFFF0; //PD2 对应 CMD设置为推挽输出
        GPIOD->CRL |= 0X0000000B;

        //SDIO 寄存器复位
        SDIO->POWER = 0x00000000;
        SDIO->CLKCR = 0x00000000;
        SDIO->ARG = 0x00000000;
        SDIO->CMD = 0x00000000;
        SDIO->DTIMER = 0x00000000;
        SDIO->DLEN = 0x00000000;
        SDIO->DCTRL = 0x00000000;
        SDIO->ICR = 0x00C007FF;
        SDIO->MASK = 0x00000000;

        //SDIO 寄存器设置
        //分频值为1780xb2得到时钟400KHz
        //分频值为70   0x46得到时钟1MHz
        //分频值为2    0x02得到时钟18MHz
        //分频值为1    0x01得到时钟24MHz   24MHz时使用8bit数据线数据发送有错误原因暂时不明       
        SDIO->CLKCR |= SDIO_CLK_DIV_36MHz;
        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);        //设置中断分组
#if 1
        NVIC_InitStructure.NVIC_IRQChannel = DMA2_Channel4_5_IRQn;                                                                //设置中断通道
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;                                                                //抢先优先级              
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;                                                                                //响应优先级
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                                                                        //使能中断

#endif

}

数据发送代码:
void SDIO_Send_Data_DMA_Reg(u32* pu32data,u16 u16block,u32 u32length)
{
        /*
        */
        while(!u8SDIO_Trans_End)
        {
                //等待上一次传输完成
                //delay_us(1);
        }

        //SDIO->MASK|= 1<<8;//数据传输结束中断
        //SDIO->MASK|= 1<<10; //数据块结束中断
        //SDIO->MASK|= 1<<1;//数据块CRC校验错误中断
       
        SDIO->DTIMER = 0xFFFFFFFF; //超时时间
        SDIO->DLEN = u32length&0x01FFFFFF;   //长度共25bit

        //SDIO->DCTRL &= 0xffffff08;                        //清除之前的设置
        SDIO->DCTRL &= 0;                        //清除之前的设置
        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
        u8SDIO_Trans_End = 0;                                                           //传输未完成
}
测试代码如下:
u32 gg = {5,2,4,7};
SDIO_Send_Data_DMA_Reg(&gg,SDIO_BLK_8_Byte,8);

就叫不死鸟 发表于 2017-1-11 16:18:52

先自己顶一下,搞了这么久未能吃透很惭愧。

jackten 发表于 2017-1-11 17:23:38

过来看看               

就叫不死鸟 发表于 2017-1-11 18:27:35

jackten 发表于 2017-1-11 17:23
过来看看

有什么建议么?

andypanfan 发表于 2017-1-12 09:05:48

没有使用过   这个功能   学习学习!!!

peter001 发表于 2017-1-17 08:07:21

学习学习

无薪税绵 发表于 2017-1-17 08:29:44

没有遇到过,估计是分频错了。

队长shiwo 发表于 2017-1-17 09:04:25

来学习学习

ts2000 发表于 2017-1-17 09:09:48

SDIO驱动什么?如果是驱动SD卡的话,一般用4位数据模式即可。不大清楚楼主的用途

cldym 发表于 2017-1-17 10:00:19

学习学习
页: [1] 2
查看完整版本: STM32F103SDIO时钟以及多块发送的问题