你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

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

[复制链接]
就叫不死鸟 提问时间:2017-1-11 16:15 /
本帖最后由 就叫不死鸟 于 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校验数据都是没有的,不知道问题在哪。
请了解的人帮忙指点一二,多谢了!
代码如下初始化

  1. void SDIO_Init_Reg()
  2. {

  3.         NVIC_InitTypeDef NVIC_InitStructure;

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

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

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

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

  12.         //SDIO 寄存器复位
  13.         SDIO->POWER = 0x00000000;
  14.         SDIO->CLKCR = 0x00000000;
  15.         SDIO->ARG = 0x00000000;
  16.         SDIO->CMD = 0x00000000;
  17.         SDIO->DTIMER = 0x00000000;
  18.         SDIO->DLEN = 0x00000000;
  19.         SDIO->DCTRL = 0x00000000;
  20.         SDIO->ICR = 0x00C007FF;
  21.         SDIO->MASK = 0x00000000;

  22.         //SDIO 寄存器设置
  23.         //分频值为178  0xb2  得到时钟400KHz  
  24.         //分频值为70   0x46  得到时钟1MHz
  25.         //分频值为2    0x02  得到时钟18MHz
  26.         //分频值为1    0x01  得到时钟24MHz   24MHz时使用8bit数据线数据发送有错误  原因暂时不明       
  27.         SDIO->CLKCR |= SDIO_CLK_DIV_36MHz;
  28.         SDIO->CLKCR &= ~(1<<9);//关闭省电模式   时钟一直存在

  29.         SDIO->CLKCR &= ~(1<<14);  //禁用硬件流控  必须禁用
  30.         //SDIO->CLKCR |= 1<<14;  //使能硬件流控
  31.         SDIO->CLKCR |= 1<<13;  //主时钟下降沿产生SDIO时钟

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

  36.         SDIO->POWER |= 0x03; //上电
  37.         SDIO->CLKCR |= 1<<8; //时钟使能
  38.        
  39.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);        //设置中断分组
  40. #if 1
  41.         NVIC_InitStructure.NVIC_IRQChannel = DMA2_Channel4_5_IRQn;                                                                //设置中断通道
  42.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;                                                                //抢先优先级                    
  43.         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;                                                                                //响应优先级
  44.         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                                                                        //使能中断

  45. #endif

  46. }

复制代码
数据发送代码:
  1. void SDIO_Send_Data_DMA_Reg(u32* pu32data,u16 u16block,u32 u32length)
  2. {
  3.         /*
  4.         */
  5.         while(!u8SDIO_Trans_End)
  6.         {
  7.                 //等待上一次传输完成
  8.                 //delay_us(1);
  9.         }

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

  16.         //SDIO->DCTRL &= 0xffffff08;                        //清除之前的设置
  17.         SDIO->DCTRL &= 0;                        //清除之前的设置
  18.         SDIO->DCTRL &= ~(1<<2);              //数据块传输
  19.         SDIO->DCTRL |= u16block&0xF0;           //数据块长度
  20.         SDIO->DCTRL &= ~(1<<1);                            //数据由控制器向外设发送
  21.         SDIO->DCTRL |= (1<<3);              //使能DMA  
  22.         SDIO->DCTRL |=0x01;                                 //使能传输
  23.        
  24.         DMA2->IFCR |= 0x0000f000;                        //清除DMA2通道4相关中断标志位

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

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

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

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

  35.         /
  36.         DMA2_Channel4->CNDTR = u32length/4;
  37.        
  38.         DMA2_Channel4->CPAR  = (uint32_t)&SDIO->FIFO;        //外设地址
  39.         DMA2_Channel4->CMAR  = (uint32_t)pu32data;                //存储器地址寄存器
  40.         DMA2_Channel4->CCR |= 0x0A;                                           //开启传输错误中断和传输结束中断
  41.         DMA2_Channel4->CCR |= 1<<0;                                            //通道开启,使能DMA2
  42.         u8SDIO_Trans_End = 0;                                                             //传输未完成
  43. }
复制代码

测试代码如下:
u32 gg[4] = {5,2,4,7};
SDIO_Send_Data_DMA_Reg(&gg[0],SDIO_BLK_8_Byte,8);

赞 收藏 2 评论13 发布时间:2017-1-11 16:15

举报

13个回答
就叫不死鸟 回答时间:2017-1-11 16:18:52
先自己顶一下,搞了这么久未能吃透很惭愧。
jackten 回答时间:2017-1-11 17:23:38
过来看看               
就叫不死鸟 回答时间:2017-1-11 18:27:35

有什么建议么?
andypanfan 回答时间:2017-1-12 09:05:48
没有使用过   这个功能   学习学习!!!
peter001 回答时间:2017-1-17 08:07:21
学习学习
无薪税绵 回答时间:2017-1-17 08:29:44
没有遇到过,估计是分频错了。

评分

参与人数 1ST金币 +2 收起 理由
zero99 + 2

查看全部评分

队长shiwo 回答时间:2017-1-17 09:04:25
来学习学习
小小超 回答时间:2017-1-17 09:09:48
SDIO驱动什么?如果是驱动SD卡的话,一般用4位数据模式即可。不大清楚楼主的用途

评分

参与人数 1ST金币 +2 收起 理由
zero99 + 2

查看全部评分

cldym 回答时间:2017-1-17 10:00:19
学习学习
就叫不死鸟 回答时间:2017-1-17 10:16:30
ts2000 发表于 2017-1-17 09:09
SDIO驱动什么?如果是驱动SD卡的话,一般用4位数据模式即可。不大清楚楼主的用途 ...

多谢您的 回答,我要用SDIO接口与FPGA进行通信,低时钟下的正常通信已经可以使用了,我想知道的是极限接口速度。
lulugl 回答时间:2017-1-17 10:31:27
我不会,但我顶你
zbber 回答时间:2017-1-17 10:58:09
学习学习,好帖,赞一个,顶楼主
就叫不死鸟 回答时间:2017-1-17 11:06:08
zbber 发表于 2017-1-17 10:58
学习学习,好帖,赞一个,顶楼主

谢谢,也希望你有了答案能够告诉我
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版