有引导的网站,wordpress贴心插件,哪个网站可以做代码题目,香奈儿网站设计分析一、下载FATFS源码
大家都知道使用CubMAX可以很快的将#xff0c;FATFS文件管理系统移植到单片机上#xff0c;但是别的芯片没有这么好用的工具#xff0c;就需要自己从官网下载源码进行移植。我们首先解决SD卡的驱动问题#xff0c;然后再移植FATFS文件管理系统。 二、SD…一、下载FATFS源码
大家都知道使用CubMAX可以很快的将FATFS文件管理系统移植到单片机上但是别的芯片没有这么好用的工具就需要自己从官网下载源码进行移植。我们首先解决SD卡的驱动问题然后再移植FATFS文件管理系统。 二、SD卡的DMA读写实现 这个我们直接使用工具生成就可以了需要注意上面的那几点不然会工作不正常。为了让大家看得更加清楚下面的几个函数下的都比较简单没有过多的判断。尽可能地缩短代码。下面这几个函数的实现是必须的不能在减少了。
//获取卡的状态
uint8_t SD_GetCardState(void)
{HAL_SD_CardStatusTypeDef pStatus;if (HAL_SD_GetCardStatus(hsd, pStatus) ! 0){return HAL_BUSY;}else{return HAL_OK;}}
void SD_ReadBlocks_DMA(uint8_t *buf, uint32_t sector, uint32_t cnt)
{HAL_SD_ReadBlocks_DMA(hsd, buf, sector, cnt);//通过DMA读取SD卡n个扇区while(SD_GetCardState() ! SD_TRANSFER_OK)//等待SD卡读完
}
uint8_t SD_WriteBlocks_DMA(uint8_t *buf, uint32_t sector, uint32_t cnt)
{HAL_SD_WriteBlocks_DMA(hsd, (uint8_t*)buf, sector, cnt);//通过DMA写SD卡n个扇区//等待SD卡写完while(SD_GetCardState()!SD_TRANSFER_OK)
} 三、FATFS中diskio.c里面相关函数的实现
#define DEV_FALSH 0
#define DEV_SD 1#define SECTOR_SIZE 4096 //定义扇区大小DSTATUS disk_status (BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{DSTATUS stat;switch (pdrv) {case DEV_FALSH :stat EN25QXX_ReadSR(); //读取FLASH状态的函数return stat;case DEV_SD :stat SD_GetCardState(); //读取SD卡状态的函数return stat; }return STA_NOINIT;
}
DSTATUS disk_initialize (BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{DSTATUS stat 0;;switch (pdrv) {case DEV_FALSH : return stat; //如果你在外面已经做过了相关模块的初始化啥的这里直接返回接可以了case DEV_SD :return stat;}return STA_NOINIT;
}
DRESULT disk_read (BYTE pdrv, /* Physical drive nmuber to identify the drive */BYTE *buff, /* Data buffer to store read data */LBA_t sector, /* Start sector in LBA UINT count /* Number of sectors to read */
)
{uint32_t i 0;uint8_t result 0;switch (pdrv) {case DEV_FALSH :{uint32_t addr sector*SECTOR_SIZE;for (i0; icount; i){EN25QXX_Read((BYTE *)buff, addr, SECTOR_SIZE);addr SECTOR_SIZE;buff SECTOR_SIZE;}return RES_OK;}case DEV_SD :{SD_ReadBlocks_DMA(buff, sector, count);return RES_OK;}}return RES_PARERR;
}这里需要注意的是FLASH和SD卡里面的两个函数是不太一样的FLASH里面的函数只能写一个扇区要想写多个扇区那你就得循环写在FATFS文件系统里面他的sector地址是从0-0xffffffff他是一个连续的地址一个sector就是一个地址但是在FLASH里面他的最小单位不是扇区他有比扇区更小的操作也就是页但是他最小的单位是可以按字节来读取的也就是说他是一个字节一个地址如果我们直接将FATFS里面的地址传过来在FLASH里面他就会认为是字节地址因此我们需要一个地址的偏移也就是FLASH里面一个扇区的大小也就是4096.理解这里你需要知道他们呢两个的基本操作的单元是不一样的。但是在SD卡里面就不需要这样的偏移因为SD卡里面他就是以扇区为大小来进行读取的。也就是SD卡里面每个地址是512个字节。他的最小读写单元就是512个字节也就是一个扇区。因此我们在传入参数的时候不需要将地址进行偏移。而且SD卡的读写函数是一次可以读多个扇区的因此可以直接将count传入他也是可以直接读的。其实说白了就是如果你的最小读写单元就是512个字节那么你就不需要地址的偏倚否则你就要根据自己设置的扇区大小进行偏移。
DRESULT disk_write (BYTE pdrv, /* Physical drive nmuber to identify the drive */const BYTE *buff, /* Data to be written */LBA_t sector, /* Start sector in LBA */UINT count /* Number of sectors to write */
)
{uint32_t i 0;uint8_t result 0;switch (pdrv) {case DEV_FALSH :{uint32_t addr sector*SECTOR_SIZE;for (i0; icount; i){EN25QXX_Erase_Sector(addr);EN25QXX_Write_Sector((BYTE *)buff, addr, SECTOR_SIZE);addr SECTOR_SIZE;buff SECTOR_SIZE;}return RES_OK;}case DEV_SD :{SD_WriteBlocks_DMA((BYTE *)buff, sector, count);return RES_OK;}}return RES_PARERR;
}DRESULT disk_ioctl (BYTE pdrv, /* Physical drive nmuber (0..) */BYTE cmd, /* Control code */void *buff /* Buffer to send/receive control data */
)
{
// DRESULT res 0;
// int result;switch (pdrv) {case DEV_FALSH :{switch (cmd){case CTRL_SYNC:return RES_OK;case GET_SECTOR_COUNT:{*(DWORD *)buff 4096; //表示扇区的个数return RES_OK;} case GET_SECTOR_SIZE:{*(WORD *)buff SECTOR_SIZE; //表示每个扇区的大小return RES_OK;} }}case DEV_SD :{switch (cmd){case CTRL_SYNC:return RES_OK;case GET_SECTOR_COUNT:{*(DWORD *)buff 31116288; //表示扇区的个数return RES_OK;} case GET_SECTOR_SIZE:{*(WORD *)buff 512; //表示每个扇区的大小return RES_OK;} case GET_BLOCK_SIZE:{*(DWORD *)buff 512; //表示每个扇区的大小return RES_OK;}default :return RES_PARERR;}}}return RES_PARERR;
}
上面这个函数的实现我是直接将数据写到里面的这样操作如果换了别的SD卡就完蛋了严谨一点的操作是使用相关函数读出来。我这里就比较粗糙的实现了主打一个能用就行。
四、进行挂载
如果你的挂载直接就返回0那么恭喜你直接就成功了但是在大多数的情况下我们的挂载是不能成功的。下面就针对几个返回值进行故障的排除。
f_mount返回11 也就是你要使用几个外设如果你就一个SD卡那么问题如果有2个你这里就得改成2不然就会返回错误代码11 f_mount返回1当这些函数没有正确的返回值就会报这个错误我将哪里注释掉之后就会产生这个错误。 还有一种就是返回值是13的错误他的意思是卡上面没有文件系统导致的。但是我将卡格式化后发现还是识别不上。还是返回13。经过一夜的查找发现是DMA设置那里没有设置地址的递增就导致他一次只能读几个字节后面的读写完全就是不正常的内存里面是有一个缓冲区的如果地址传完不发生偏移那这个缓冲区就是没有意义的因此只要你传入的DMA里面的buf[]数组里面的元素不止一个那么这里就得设置地址偏移。 res f_mount(fs, 1:/, 1); 一般来讲只要能挂载成功其他的函数都是可以正常工作的前提是你挂载的时候后面选项里面一定要是 1如果是0就算有问题他写会显示挂载成功的这时候肯定是不行的。