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);
先自己顶一下,搞了这么久未能吃透很惭愧。 过来看看 jackten 发表于 2017-1-11 17:23
过来看看
有什么建议么? 没有使用过 这个功能 学习学习!!! 学习学习 没有遇到过,估计是分频错了。 来学习学习 SDIO驱动什么?如果是驱动SD卡的话,一般用4位数据模式即可。不大清楚楼主的用途 学习学习
页:
[1]
2