一、在cubemx上配置sd和fatfs示例演示
一、sd和fatfs的配置流程界面
1、选择sd4bits 根据自己的sd卡的硬件插槽进行选择。
2、fatfs配置由于使用的是sd卡所以直接选择sd选项
3、程序中对sd卡的初始化需要进行改动,直接使用默认的参数sd卡是挂载不上的。
4、在sd卡挂载好后,就可以使用文件系统的函数进行操作了。
写入
读取
注意:f_open后写和读取要分开操作,即写完后f_close以保持写入的内容,当需要读取时重新打开文件进行读取。
调试结果显示:
二、sd和fatfs的配置打开dma进行处理的流程界面
在使用f_write和f_read时会调用disk_write和disk_read。
下图就是其调用关系,f_read同理。
默认的disk_write和disk_read没用使用到dma,需要自己编辑对应的dma调用函数。
1、重新编写disk_write和disk_read函数
DRESULT disk_write (BYTE pdrv, /* Physical drive nmuber to identify the drive */const BYTE *buff, /* Data to be written */DWORD sector, /* Sector address in LBA */UINT count /* Number of sectors to write */
)
//{
// DRESULT res;// res = disk.drv[pdrv]->disk_write(disk.lun[pdrv], buff, sector, count);
// return res;
//}{uint8_t res=0; if (!count)return RES_PARERR;//count不能等于0,否则返回参数错误 switch(pdrv){case 0://SD卡res=SD_WriteDisk((uint8_t*)buff,sector,count);while(res)//写出错{MX_SDIO_SD_Init(); //重新初始化SD卡res=SD_WriteDisk((uint8_t*)buff,sector,count); //printf("sd wr error:%d\r\n",res);}res=0;break;default:res=1; }if(res == 0x00)return RES_OK; else return RES_ERROR;
} DRESULT disk_read (BYTE pdrv, /* Physical drive nmuber to identify the drive */BYTE *buff, /* Data buffer to store read data */DWORD sector, /* Sector address in LBA */UINT count /* Number of sectors to read */
)
//{
// DRESULT res;// res = disk.drv[pdrv]->disk_read(disk.lun[pdrv], buff, sector, count);
// return res;
//}
{uint8_t res=0; if (!count)return RES_PARERR;//count不能等于0,否则返回参数错误 switch(pdrv){case 0://SD卡res=SD_ReadDisk(buff,sector,count); while(res)//读出错{MX_SDIO_SD_Init(); //重新初始化SD卡res=SD_ReadDisk(buff,sector,count); //printf("sd rd error:%d\r\n",res);}res=0;break;default:res=1; }if(res==0x00)return RES_OK; else return RES_ERROR;
}
2、编写写sd卡的写入操作函数
//获取SD运行状态
uint8_t SD_GetCardState(void)
{return((HAL_SD_GetCardState(&hsd)==HAL_SD_CARD_TRANSFER )?SD_TRANSFER_OK:SD_TRANSFER_BUSY);
}//写SD卡
//buf:写数据缓存区
//sector:扇区地址
//blocksize:扇区大小(一般都是512字节)
//cnt:扇区个数
//返回值:错误状态;0,正常;其他,错误代码;
uint8_t SD_WriteBlocks_DMA(uint32_t *buf,uint64_t sector,uint32_t blocksize,uint32_t cnt)
{uint8_t err=0; uint32_t timeout=100000000;err=HAL_SD_WriteBlocks_DMA(&hsd,(uint8_t*)buf,sector,cnt);//通过DMA写SD卡n个扇区if(err==0){//等待SD卡写完while(SD_GetCardState()!=SD_TRANSFER_OK){if(timeout-- == 0){ err=SD_TRANSFER_BUSY;}} }return err;
}//写SD卡操作
//buf:写数据缓存区
//sector:扇区地址
//cnt:扇区个数
//返回值:错误状态;0,正常;其他,错误代码;
uint8_t SD_WriteDisk(uint8_t *buf,uint32_t sector,uint32_t cnt)
{ uint8_t sta=HAL_OK;long long lsector=sector;sta=SD_WriteBlocks_DMA((uint32_t*)buf,lsector,512,cnt);//多个sector的写操作return sta;
}
3、编写写sd卡的读取操作函数
//通过DMA读取SD卡一个扇区
//buf:读数据缓存区
//sector:扇区地址
//blocksize:扇区大小(一般都是512字节)
//cnt:扇区个数
//返回值:错误状态;0,正常;其他,错误代码;
uint8_t SD_ReadBlocks_DMA(uint32_t *buf,uint64_t sector,uint32_t blocksize,uint32_t cnt)
{uint8_t err=0;uint32_t timeout=100000000;err=HAL_SD_ReadBlocks_DMA(&hsd,(uint8_t*)buf,sector,cnt);//通过DMA读取SD卡n个扇区if(err==0){//等待SD卡读完while(SD_GetCardState()!=SD_TRANSFER_OK){if(timeout-- == 0){ err=SD_TRANSFER_BUSY;}} }return err;
}//读SD卡
//buf:读数据缓存区
//sector:扇区地址
//cnt:扇区个数
//返回值:错误状态;0,正常;其他,错误代码;
uint8_t SD_ReadDisk(uint8_t* buf,uint32_t sector,uint32_t cnt)
{uint8_t sta=HAL_OK;long long lsector=sector;sta=SD_ReadBlocks_DMA((uint32_t*)buf,lsector, 512,cnt);return sta;
}