本帖最后由 就叫不死鸟 于 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 寄存器设置
- //分频值为178 0xb2 得到时钟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[4] = {5,2,4,7};
SDIO_Send_Data_DMA_Reg(&gg[0],SDIO_BLK_8_Byte,8);
|
有什么建议么?
评分
查看全部评分
评分
查看全部评分
多谢您的 回答,我要用SDIO接口与FPGA进行通信,低时钟下的正常通信已经可以使用了,我想知道的是极限接口速度。
谢谢,也希望你有了答案能够告诉我