OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2112|回复: 6

SD卡读取函数的blksized的疑问

[复制链接]

40

主题

137

帖子

0

精华

高级会员

Rank: 4

积分
579
金钱
579
注册时间
2019-8-4
在线时间
187 小时
发表于 2019-12-10 21:10:23 | 显示全部楼层 |阅读模式
1金钱
SD_Error SD_ReadBlock(u8 *buf,long long addr,u16 blksize)
{          
        SD_Error errorstatus=SD_OK;
        u8 power;
           u32 count=0,*tempbuff=(u32*)buf;//转换为u32指针
        u32 timeout=SDIO_DATATIMEOUT;   
           if(NULL==buf)return SD_INVALID_PARAMETER;
           SDIO->DCTRL=0x0;        //数据控制寄存器清零(关DMA)   
        if(CardType==SDIO_HIGH_CAPACITY_SD_CARD)//大容量卡
        {
                blksize=512;
                addr>>=9;
        }   

                SDIO_DataInitStructure.SDIO_DataBlockSize= SDIO_DataBlockSize_1b ;//清除DPSM状态机配置
          SDIO_DataInitStructure.SDIO_DataLength= 0 ;
          SDIO_DataInitStructure.SDIO_DataTimeOut=SD_DATATIMEOUT ;
          SDIO_DataInitStructure.SDIO_DPSM=SDIO_DPSM_Enable;
          SDIO_DataInitStructure.SDIO_TransferDir=SDIO_TransferDir_ToCard;
          SDIO_DataInitStructure.SDIO_TransferMode=SDIO_TransferMode_Block;
    SDIO_DataConfig(&SDIO_DataInitStructure);
       
       
        if(SDIO->RESP1&0x02000000)return SD_LOCK_UNLOCK_FAILED;//卡锁了,第25位,锁卡位
       
        if((blksize>0)&&(blksize<=2048)&&((blksize&(blksize-1))==0))//什么意思
        {
                power=convert_from_bytes_to_power_of_two(blksize);            

                SDIO_CmdInitStructure.SDIO_Argument =  blksize;
    SDIO_CmdInitStructure.SDIO_CmdIndex = 16;
    SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
    SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
    SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
    SDIO_SendCommand(&SDIO_CmdInitStructure);//发送CMD16+设置数据长度为blksize,短响应
               
                errorstatus=CmdResp1Error(16);        //等待R1响应  
               
                if(errorstatus!=SD_OK)return errorstatus;           //响应错误         
        }
                else return SD_INVALID_PARAMETER;                                                                                                
          SDIO_DataInitStructure.SDIO_DataBlockSize= power<<4 ;//清除DPSM状态机配置
          SDIO_DataInitStructure.SDIO_DataLength= blksize ;
          SDIO_DataInitStructure.SDIO_DataTimeOut=SD_DATATIMEOUT ;
          SDIO_DataInitStructure.SDIO_DPSM=SDIO_DPSM_Enable;
          SDIO_DataInitStructure.SDIO_TransferDir=SDIO_TransferDir_ToSDIO;
          SDIO_DataInitStructure.SDIO_TransferMode=SDIO_TransferMode_Block;
      SDIO_DataConfig(&SDIO_DataInitStructure);
       
          SDIO_CmdInitStructure.SDIO_Argument =  addr;
    SDIO_CmdInitStructure.SDIO_CmdIndex = 17;//CMD17
    SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
    SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
    SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
    SDIO_SendCommand(&SDIO_CmdInitStructure);//发送CMD17+从addr地址出读取数据,短响应
       
        errorstatus=CmdResp1Error(17);//等待R1响应   
        if(errorstatus!=SD_OK)return errorstatus;                   //响应错误         
        if(DeviceMode==0)                                                //查询模式,轮询数据         
        {
                INTX_DISABLE();//关闭总中断(POLLING模式,严禁中断打断SDIO读写操作!!!)
                while(!(SDIO->STA&((1<<5)|(1<<1)|(1<<3)|(1<<10)|(1<<9))))//无上溢/CRC/超时/完成(标志)/起始位错误
                {
                        if(SDIO_GetFlagStatus(0x00008000) != RESET)//接收区半满,表示至少存了8个字
                        {
                                for(count=0;count<8;count++)                        //循环读取数据
                                {
                                        *(tempbuff+count)=SDIO->FIFO;
                                }
                                tempbuff+=8;         
                                timeout=0X7FFFFF;         //读数据溢出时间
                        }else         //处理超时
                        {
                                if(timeout==0)return SD_DATA_TIMEOUT;
                                timeout--;
                        }
                }
                if(SDIO_GetFlagStatus(0x00000008) != RESET)                //数据超时错误
                {                                                                                  
                         SDIO_ClearFlag(0x00000008);         //清错误标志
                        return SD_DATA_TIMEOUT;
                 }else if(SDIO_GetFlagStatus(0x00000002) != RESET)        //数据块CRC错误
                {
                         SDIO_ClearFlag(0x00000002);                  //清错误标志
                        return SD_DATA_CRC_FAIL;                  
                }else if(SDIO_GetFlagStatus(0x00000020) != RESET)         //接收fifo上溢错误
                {
                         SDIO_ClearFlag(0x00000020);                //清错误标志
                        return SD_RX_OVERRUN;                 
                }else if(SDIO_GetFlagStatus(0x00000200) != RESET)         //接收起始位错误
                {
                         SDIO_ClearFlag(0x00000200);//清错误标志
                        return SD_START_BIT_ERR;                 
                }   
                while(SDIO_GetFlagStatus(0x00200000) != RESET)        //FIFO里面,还存在可用数据
                {
                        *tempbuff=SDIO_ReadData();        //循环读取数据
                        tempbuff++;
                }
                INTX_ENABLE();//开启总中断
                SDIO_ClearFlag(SDIO_STATIC_FLAGS);//清除所有标记
        }else if(DeviceMode==1)
        {
          SD_DMA_Config((u32*)buf,blksize,DMA_DIR_PeripheralSRC);
                TransferError=SD_OK;
                StopCondition=0;                        //单块读,不需要发送停止传输指令
                TransferEnd=0;                                //传输结束标置位,在中断服务置1
                SDIO->MASK|=(1<<1)|(1<<3)|(1<<8)|(1<<5)|(1<<9);        //配置需要的中断
                SDIO_DMACmd(ENABLE);
                while(((DMA2->ISR&0X2000)==RESET)&&(TransferEnd==0)&&(TransferError==SD_OK)&&timeout)timeout--;//等待传输完成
                if(timeout==0)return SD_DATA_TIMEOUT;//超时
                if(TransferError!=SD_OK)errorstatus=TransferError;  
    }   
        return errorstatus;
}

最佳答案

查看完整内容[请看2#楼]

SCR计算我没有研究,直接用的别人的,没有问题。 至于这个判断,是判断块大小不能大于2048,而且必须是偶数。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165516
金钱
165516
注册时间
2010-12-1
在线时间
2116 小时
发表于 2019-12-10 21:10:24 | 显示全部楼层
taomao 发表于 2019-12-12 10:52
原子哥,
ACMD51得到的SCR值为什么顺序颠倒,我看了手册,SCR寄存器48—51位设置数据宽度,
然后(scr[1 ...

SCR计算我没有研究,直接用的别人的,没有问题。
至于这个判断,是判断块大小不能大于2048,而且必须是偶数。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

5

主题

424

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1020
金钱
1020
注册时间
2014-9-4
在线时间
199 小时
发表于 2019-12-11 10:25:19 | 显示全部楼层
回复

使用道具 举报

40

主题

137

帖子

0

精华

高级会员

Rank: 4

积分
579
金钱
579
注册时间
2019-8-4
在线时间
187 小时
 楼主| 发表于 2019-12-11 10:44:40 | 显示全部楼层
QQ971645053
望赐教
                  if(nblks*blksize>0x01FFFFFF)return SD_INVALID_PARAMETER;//判断是否超过最大接收长度
    我算了一下,0x01FFFFFF*512=16G,最多读取16个G是吧
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165516
金钱
165516
注册时间
2010-12-1
在线时间
2116 小时
发表于 2019-12-11 23:13:48 | 显示全部楼层
taomao 发表于 2019-12-11 10:44
QQ971645053
望赐教
                  if(nblks*blksize>0x01FFFFFF)return SD_INVALID_PARAMETER;//判断是否超过最大 ...

没有这个限制
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

40

主题

137

帖子

0

精华

高级会员

Rank: 4

积分
579
金钱
579
注册时间
2019-8-4
在线时间
187 小时
 楼主| 发表于 2019-12-12 10:52:08 | 显示全部楼层

原子哥,
ACMD51得到的SCR值为什么顺序颠倒,我看了手册,SCR寄存器48—51位设置数据宽度,
然后(scr[1]&0x00040000),刚好判断第50位,是1则4位数据宽度,为什么要

        //把数据顺序按8位为单位倒过来.           
        *(pscr+1)=((tempscr[0]&SD_0TO7BITS)<<24)|((tempscr[0]&SD_8TO15BITS)<<8)|((tempscr[0]&SD_16TO23BITS)>>8)|((tempscr[0]&SD_24TO31BITS)>>24);
        *(pscr)=((tempscr[1]&SD_0TO7BITS)<<24)|((tempscr[1]&SD_8TO15BITS)<<8)|((tempscr[1]&SD_16TO23BITS)>>8)|((tempscr[1]&SD_24TO31BITS)>>24);

2. if((blksize>0)&&(blksize<=2048)&&((blksize&(blksize-1))==0))//什么意思
回复

使用道具 举报

0

主题

53

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
354
金钱
354
注册时间
2019-12-7
在线时间
27 小时
发表于 2019-12-13 08:29:15 | 显示全部楼层
顶一顶
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-21 21:52

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表