完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
大家好,我在使用SSI0模块和DMA模块时碰到了一个很费解的问题,我在连续读取SD卡多个扇区时发现每当读取奇数个扇区时最后一个扇区的数据不完整,只能读到200多字节数据,后面的数据全为0,但是读偶数个扇区一切正常。并且我尝试使用单扇区读取函数连续读奇数个扇区却没问题,于是我把这个单扇区读取函数嵌入到多扇区读取函数里面问题又出现了,两个函数最大的区别就是接收的目的地址,我觉得可能DMA的RX通道在计算目的地址出现了问题,因为它的目的地址是连续的计算出来的:&pbuffer[i*512]。但是我尝试了多个办法都解决不了,希望有人能可以帮我看看,下面是一些主要函数的程序,谢谢大家了!
void SD_SPI_Init() [ HWREG(GPIO_PORTA_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY; //PA3解锁操作 HWREG(GPIO_PORTA_BASE + GPIO_O_CR) |= GPIO_PIN_3; GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE, GPIO_PIN_3); //PA3选为SSI0_CS引脚 HWREG(GPIO_PORTA_BASE + GPIO_O_LOCK) = GPIO_LOCK_LOCKED; GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_3, GPIO_PIN_3); //SSI0_CS默认高电平 GPIOPinConfigure(GPIO_PA2_SSI0CLK); //PA2选为SSI0_CLK引脚 GPIOPinConfigure(GPIO_PA4_SSI0RX); //PA4选为SSI0_RX引脚 GPIOPinConfigure(GPIO_PA5_SSI0TX); //PA5选为SSI0_TX引脚 GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_2|GPIO_PIN_4|GPIO_PIN_5); //SSI0端口功能使能 SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0); //使能SSI0模块 SSIClockSourceSet(SSI0_BASE, SSI_CLOCK_SYSTEM); //SSI0时钟选择系统主时钟 SSIConfigSetExpClk(SSI0_BASE, SysCtlClockGet(), //SSI0作为主机,工作模式为0 SSI_FRF_MOTO_MODE_3, SSI_MODE_MASTER, 20000000, 8); //Fclk为20Mhz,数据帧8位 SSIEnable(SSI0_BASE); //使能SSI0 #ifdef SD_CARD_USE_DMA uDMAChannelAssign(UDMA_CH11_SSI0TX); //配置Channel11_SSI0TX通道 uDMAChannelAssign(UDMA_CH10_SSI0RX); uDMAChannelAttributeEnable(UDMA_CH11_SSI0_TX, UDMA_ATTR_USEBURST //通道11突发模式,高优先级 |UDMA_ATTR_HIGH_PRIORITY); uDMAChannelAttributeEnable(UDMA_CH10_SSI0_RX, UDMA_ATTR_USEBURST //通道10突发模式,高优先级 |UDMA_ATTR_HIGH_PRIORITY); uDMAChannelControlSet(UDMA_CH11_SSI0_TX | UDMA_PRI_SELECT, //配置Channel11_PRI结构,数据单位字节 UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_4); //原地址增加,目的地址不变,一次传输8个item uDMAChannelControlSet(UDMA_CH10_SSI0_RX | UDMA_PRI_SELECT, //配置Channel10_PRI结构,数据单位字节 UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_4); //原地址不变,目的地址增加,一次传输8个item #endif ] uint8_t SD_Read_Sector(uint32_t uiAddr, uint8_t *pbuffer) [ uint8_t ucGet, ucTry; uint8_t pCMD17[]=[0x51,0x00,0x00,0x00,0x00,0x01]; //CMD17的字节序列 if(!SD_Addr_Mode) [ uiAddr<<=9; //sector = sector * 512 将块地址(扇区地址)转为字节地址 ] pCMD17[1]=uiAddr>>24; //将字节地址写入到CMD17字节序列中 pCMD17[2]=uiAddr>>16; pCMD17[3]=uiAddr>>8; pCMD17[4]=uiAddr; ucTry=0; do [ ucGet=SD_Write_Cmd(pCMD17); //写入CMD17 ucTry++; if(ucTry==TRY_tiME) [ return(READ_BLOCK_ERROR); //读块失败 ] ]while(ucGet!=0); while(SD_Read_Byte()!=0xFE); //一直读,当读到0xFE时,说明后面的是512字节的数据了 #ifdef SD_CARD_USE_DMA uint8_t uiDMA_Temp=0xFF; uDMAChannelControlSet(UDMA_CH11_SSI0_TX | UDMA_PRI_SELECT, //配置Channel11_PRI结构 UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_NONE | UDMA_ARB_4); //原地址不变,目的地址不变 uDMAChannelTransferSet(UDMA_CH11_SSI0_TX | UDMA_PRI_SELECT, //基本传输模式,原地址和目的地址指针 UDMA_MODE_BASIC, &uiDMA_Temp, (void *)(SSI0_BASE + SSI_O_DR), 512); //传输的item为512 uDMAChannelTransferSet(UDMA_CH10_SSI0_RX | UDMA_PRI_SELECT, //基本传输模式,原地址和目的地址指针 UDMA_MODE_BASIC, (void *)(SSI0_BASE + SSI_O_DR), pbuffer, 512); //传输的item为512 SSIDMAEnable(SSI0_BASE, SSI_DMA_TX|SSI_DMA_RX); uDMAChannelEnable(UDMA_CH10_SSI0_RX); //使能一次item传输 uDMAChannelEnable(UDMA_CH11_SSI0_TX); //使能一次item传输 while(uDMAChannelIsEnabled(UDMA_CH10_SSI0_RX)); //等待一次DMA传输完成 SSIDMADisable(SSI0_BASE, SSI_DMA_TX|SSI_DMA_RX); uDMAChannelControlSet(UDMA_CH11_SSI0_TX | UDMA_PRI_SELECT, //配置Channel11_PRI结构 UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_4); //原地址增加,目的地址不变 #else uint16_t j; for(j=0; j<512; j++) [ pbuffer[j] = SD_Read_Byte(); ] #endif SD_Read_Byte(); SD_Read_Byte(); //读取两个字节的CRC校验码,不用关心它们 SD_CS_SET; SD_Write_Byte(0xFF); //按照SD卡的操作时序在这里补8个时钟 return(0); //返回0,说明写扇区操作成功 ] uint8_t SD_Read_nSector(uint32_t uinSec, uint32_t uiAddr, uint8_t *pbuffer) [ uint16_t i; uint8_t ucGet, ucTry; uint8_t pCMD18[6]=[0x52,0x00,0x00,0x00,0x00,0x01]; //CMD18的字节序列 uint8_t pCMD12[6]=[0x1C,0x00,0x00,0x00,0x00,0x01]; //CMD12,强制停止命令 if(!SD_Addr_Mode) [ uiAddr<<=9; //sector = sector * 512 将块地址(扇区地址)转为字节地址 ] pCMD18[1]=uiAddr>>24; //将字节地址写入到CMD17字节序列中 pCMD18[2]=uiAddr>>16; pCMD18[3]=uiAddr>>8; pCMD18[4]=uiAddr; ucTry=0; do [ ucGet=SD_Write_Cmd(pCMD18); //写入CMD18 ucTry++; if(ucTry==TRY_TIME) [ return(READ_CMD18_ERROR); //写入CMD18失败 ] ]while(ucGet!=0); for(i=0; i while(SD_Read_Byte()!=0xFE); //一直读,当读到0xfe时,说明后面的是512字节的数据了 #ifdef SD_CARD_USE_DMA uint8_t uiDMA_Temp=0xFF; uDMAChannelControlSet(UDMA_CH11_SSI0_TX | UDMA_PRI_SELECT, //配置Channel11_PRI结构 UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_NONE | UDMA_ARB_4); //原地址不变,目的地址不变 uDMAChannelTransferSet(UDMA_CH11_SSI0_TX | UDMA_PRI_SELECT, //基本传输模式,原地址和目的地址指针 UDMA_MODE_BASIC, &uiDMA_Temp, (void *)(SSI0_BASE + SSI_O_DR), 512); //传输的item为512 uDMAChannelTransferSet(UDMA_CH10_SSI0_RX | UDMA_PRI_SELECT, //基本传输模式,原地址和目的地址指针 UDMA_MODE_BASIC, (void *)(SSI0_BASE + SSI_O_DR), &pbuffer[i*512], 512);//传输的item为512 SSIDMAEnable(SSI0_BASE, SSI_DMA_TX|SSI_DMA_RX); uDMAChannelEnable(UDMA_CH10_SSI0_RX); //使能一次item传输 uDMAChannelEnable(UDMA_CH11_SSI0_TX); //使能一次item传输 while(uDMAChannelIsEnabled(UDMA_CH10_SSI0_RX)); //等待一次DMA传输完成 SSIDMADisable(SSI0_BASE, SSI_DMA_TX|SSI_DMA_RX); uDMAChannelControlSet(UDMA_CH11_SSI0_TX | UDMA_PRI_SELECT, //配置Channel11_PRI结构 UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_4); //原地址增加,目的地址不变 #else uint16_t j; for(j=0; j<512; j++) [ pbuffer[i*512+j] = SD_Read_Byte(); ] #endif SD_Read_Byte(); SD_Read_Byte();//读取两个字节的CRC校验码,不用关心它们 ] SD_Write_Cmd(pCMD12); //写入CMD12命令,停止数据读取 SD_CS_SET; SD_Write_Byte(0xFF); //按照SD卡的操作时序在这里补8个时钟 return(0); //返回0,说明写扇区操作成功 ] |
|
相关推荐 |
|
只有小组成员才能发言,加入小组>>
341 浏览 1 评论
539 浏览 2 评论
NA555DR VCC最低电压需要在5V供电,为什么用3.3V供电搭了个单稳态触发器也使用正常?
781 浏览 3 评论
MSP430F249TPMR出现高温存储后失效了的情况,怎么解决?
655 浏览 1 评论
对于多级放大电路板,在PCB布局中,电源摆放的位置应该注意什么?
1138 浏览 1 评论
AT32F407在USART2 DMA发送数据时,接包接到了要发送的数据,程序还是处于等待传输完成的标识判断中,为什么?
69浏览 29评论
209浏览 23评论
请问下tpa3220实际测试引脚功能和官方资料不符,哪位大佬可以帮忙解答下
256浏览 20评论
请教下关于TAS5825PEVM评估模块原理图中不太明白的地方,寻求答疑
205浏览 14评论
两个TMP117传感器一个可以正常读取温度值,一个读取的值一直是0,为什么?
65浏览 13评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-25 09:02 , Processed in 0.871095 second(s), Total 38, Slave 32 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号