OpenEdv-开源电子网

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

求助: 原子例程的FATFS的读函数想要更快的读取速度

[复制链接]

28

主题

150

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
488
金钱
488
注册时间
2016-9-29
在线时间
113 小时
发表于 2018-6-23 16:33:53 | 显示全部楼层 |阅读模式
10金钱
    在使用原子关于SD卡例程的部分程序时发现f_read()函数执行跨块读取时速度不理想,我想要使用f_read()函数读取600个字节,然后再下面程序的红色字体那里占用了大量时间,以下是原子例程的某函数。(可以直接去看红色字体部分)

    //SD卡读取一个块
//buf:读数据缓存区(必须4字节对齐!!)
//addr:读取地址
//blksize:块大小
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_Send_Data_Cfg(SD_DATATIMEOUT,0,0,0);        //清除DPSM状态机配置
        if(SDIO->RESP1&SD_CARD_LOCKED)return SD_LOCK_UNLOCK_FAILED;//卡锁了
        if((blksize>0)&&(blksize<=2048)&&((blksize&(blksize-1))==0))
        {
                power=convert_from_bytes_to_power_of_two(blksize);                      
                SDIO_Send_Cmd(SD_CMD_SET_BLOCKLEN,1,blksize);        //发送CMD16+设置数据长度为blksize,短响应           
                errorstatus=CmdResp1Error(SD_CMD_SET_BLOCKLEN);        //等待R1响应   
                if(errorstatus!=SD_OK)return errorstatus;           //响应错误         
        }else return SD_INVALID_PARAMETER;                                                                                                
          SDIO_Send_Data_Cfg(SD_DATATIMEOUT,blksize,power,1);        //blksize,卡到控制器          
           SDIO_Send_Cmd(SD_CMD_READ_SINGLE_BLOCK,1,addr);                //发送CMD17+从addr地址出读取数据,短响应           
        errorstatus=CmdResp1Error(SD_CMD_READ_SINGLE_BLOCK);//等待R1响应   
        if(errorstatus!=SD_OK)return errorstatus;                   //响应错误         
        if(DeviceMode==SD_POLLING_MODE)                                                //查询模式,轮询数据         
        {
                INTX_DISABLE();//关闭总中断(POLLING模式,严禁中断打断SDIO读写操作!!!)
                while(!(SDIO->STA&((1<<5)|(1<<1)|(1<<3)|(1<<10)|(1<<9))))//无上溢/CRC/超时/完成(标志)/起始位错误
                {
                        if(SDIO->STA&(1<<15))                                                //接收区半满,表示至少存了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->STA&(1<<3))                //数据超时错误
                {                                                                                  
                         SDIO->ICR|=1<<3;                 //清错误标志
                        return SD_DATA_TIMEOUT;
                 }else if(SDIO->STA&(1<<1))        //数据块CRC错误
                {
                         SDIO->ICR|=1<<1;                 //清错误标志
                        return SD_DATA_CRC_FAIL;                  
                }else if(SDIO->STA&(1<<5))         //接收fifo上溢错误
                {
                         SDIO->ICR|=1<<5;                 //清错误标志
                        return SD_RX_OVERRUN;                 
                }else if(SDIO->STA&(1<<9))         //接收起始位错误
                {
                         SDIO->ICR|=1<<9;                 //清错误标志
                        return SD_START_BIT_ERR;                 
                }   
                while(SDIO->STA&(1<<21))        //FIFO里面,还存在可用数据
                {
                        *tempbuff=SDIO->FIFO;        //循环读取数据
                        tempbuff++;
                }
                INTX_ENABLE();//开启总中断
                SDIO->ICR=0X5FF;                         //清除所有标记
        }else if(DeviceMode==SD_DMA_MODE)
        {
              SD_DMA_Config((u32*)buf,blksize,0);
                TransferError=SD_OK;
                StopCondition=0;                        //单块读,不需要发送停止传输指令
                TransferEnd=0;                                //传输结束标置位,在中断服务置1
                SDIO->MASK|=(1<<1)|(1<<3)|(1<<8)|(1<<5)|(1<<9);        //配置需要的中断
                 SDIO->DCTRL|=1<<3;                         //SDIO DMA使能
                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;
}


     上面红色字体部分在跨块读取时都要占用近280μs,我在想既然起用了DMA传输,那能不能直接去屏蔽红色的语句呢(去掉红色字体的话也得去掉上面的SDIO中断?)?各位有没有对上面程序进行修改的办法?

最佳答案

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

单次读取数据越多,速度越快
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2018-6-23 16:33:54 | 显示全部楼层
ZDawn 发表于 2018-6-23 17:10
我的程序每次读取一个512字节的块要300μs,请问有人试过能比这更快的速度吗?

单次读取数据越多,速度越快
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

28

主题

150

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
488
金钱
488
注册时间
2016-9-29
在线时间
113 小时
 楼主| 发表于 2018-6-23 16:36:20 | 显示全部楼层
还是说查询模式会更快?没用过
回复

使用道具 举报

28

主题

150

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
488
金钱
488
注册时间
2016-9-29
在线时间
113 小时
 楼主| 发表于 2018-6-23 17:10:17 | 显示全部楼层
我的程序每次读取一个512字节的块要300μs,请问有人试过能比这更快的速度吗?
回复

使用道具 举报

28

主题

150

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
488
金钱
488
注册时间
2016-9-29
在线时间
113 小时
 楼主| 发表于 2018-6-25 11:19:49 | 显示全部楼层
正点原子 发表于 2018-6-24 01:20
单次读取数据越多,速度越快

恩,如果每次都按512字节的倍数进行读取的话,速度的确能上到接近5M
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-7-18 09:00

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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