中级会员
 
- 积分
- 488
- 金钱
- 488
- 注册时间
- 2016-9-29
- 在线时间
- 113 小时
|
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中断?)?各位有没有对上面程序进行修改的办法?
|
|