满船清梦i 2022-05-24 20:04 采纳率: 100%
浏览 28
已结题

关于#fatfs#的问题,如何解决?

flash型号:w25q32

/4K擦除/
/
*****************************************************************/
void W25q16_4KErase(uint32_t addr)
{
Spi_Write_Enable();

CS_L;

Spi_WR_Byte(0x20);
Spi_WR_Byte((addr & 0xFF0000)>>16);
Spi_WR_Byte((addr & 0x00FF00)>>8);
Spi_WR_Byte(addr & 0xFF);

CS_H;

SPI_Wait_WriteEnd();

}

/页写/
/
*****************************************************************/
void SPI_PageProgram_Write(uint8_t *rx,uint32_t len,uint32_t addr)
{

Spi_Write_Enable();
CS_L;
Spi_WR_Byte(0x02);
Spi_WR_Byte((addr & 0xFF00)>>16);
Spi_WR_Byte((addr & 0xFF00)>>8);
Spi_WR_Byte(addr& 0xFF);

for(int i=0;i<len;i++)
{
        Spi_WR_Byte(*rx++);
}
CS_H;

SPI_Wait_WriteEnd();
//nrf_delay_ms(10);

}

/跨页写/
/
*****************************************************************/
void SPI_Write_Data(uint8_t *buf,uint32_t len,uint32_t addr)
{

uint16_t pagenum;
uint16_t addrbyte;//最低八位地址

addrbyte = addr%256;
if (len > (256 - addrbyte))//跨页了
{
    SPI_PageProgram_Write(buf, 256 - addrbyte, addr);//写满本页
    addr += 256-addrbyte;
    buf += 256-addrbyte;
    len -= 256-addrbyte;
    pagenum = len/256;

    while (pagenum--)
    {
        SPI_PageProgram_Write(buf, 256, addr);
        addr += 256;
        buf += 256;
        len -= 256;
    }
    SPI_PageProgram_Write(buf, len, addr);
}
else
{
    SPI_PageProgram_Write(buf, len, addr);
}
//nrf_delay_ms(10);

}
/读flash/
/
*****************************************************************/
void SPI_Read_Data(uint8_t *rx,uint32_t len,uint32_t addr)
{
CS_L;
Spi_WR_Byte(0x03);
Spi_WR_Byte((addr & 0xFF0000)>>16);
Spi_WR_Byte((addr & 0x00FF00)>>8);
Spi_WR_Byte(addr & 0xFF);

while(len--)
{
    *rx=Spi_WR_Byte(0xff);
    rx++;
}
CS_H;
//nrf_delay_ms(10);

}
/-----------------------------------------------------------------------/
/* fatfs读接口 /
/
-----------------------------------------------------------------------*/

DRESULT disk_read (
BYTE pdrv, /* Physical drive nmuber to identify the drive */
BYTE buff, / Data buffer to store read data /
DWORD sector, /
Start sector in LBA /
UINT count /
Number of sectors to read */
)
{

printf("disk_read---sector:%d,count:%d\r\n",sector,count);
if(pdrv == SPI_FLASH) 
{
     SPI_Read_Data(buff,count<<12,sector<<12);//spi flash的读接口,注意函数参数类型一致性

    return RES_OK;
}
else
{
    printf("!!!disk_read ERR\r\n");
    return RES_PARERR;
}

}
/-----------------------------------------------------------------------/
/* fatfs写接口 /
/
-----------------------------------------------------------------------/
DRESULT disk_write (
BYTE pdrv, /
Physical drive nmuber to identify the drive */
const BYTE buff, / Data to be written /
DWORD sector, /
Start sector in LBA /
UINT count /
Number of sectors to write */
)
{
printf("disk_write---sector:%d,count:%d\r\n",sector,count);

if(pdrv == SPI_FLASH) 
{
    W25q16_4KErase(sector<<12);
    nrf_delay_ms(10);
    SPI_Write_Data((uint8_t *)buff,count<<12,sector<<12);//spi flash的写接口,注意函数参数类型一致性
    return RES_OK;
}
else
{
    printf("!!!disk_write ERR\r\n");
    return RES_PARERR;
}

}
/-----------------------------------------------------------------------/
/* Miscellaneous Functions /
/
-----------------------------------------------------------------------*/

DRESULT disk_ioctl (
BYTE pdrv, /* Physical drive nmuber (0..) /
BYTE cmd, /
Control code */
void buff / Buffer to send/receive control data */
)
{
if (pdrv == SPI_FLASH)
{
switch (cmd)
{
case CTRL_SYNC:
return RES_OK;

     case GET_SECTOR_COUNT:

         *(DWORD * )buff = 1024;//W25Q32 有1024个大小为4k bytes 的扇区
         return RES_OK;

     /* 扇区大小 */

     case GET_SECTOR_SIZE :

         *(WORD * )buff = 4096;//spi flash的扇区大小是 4K Bytes
         return RES_OK;

     /*块大小 */

     case GET_BLOCK_SIZE :
          *(DWORD * )buff = 1;
         return RES_OK;
         
     default:
          return RES_PARERR;
     }
}
else
{
    printf("!!!disk_ioctl ERR\r\n");
    return RES_PARERR;
}

}
/-----------------------------------------------------------------------/
/* ff conf.h /
/
-----------------------------------------------------------------------/
#define FF_MIN_SS 512
#define FF_MAX_SS 4096
#define FF_USE_MKFS 1
/
-----------------------------------------------------------------------/
/
主函数 /
/
-----------------------------------------------------------------------*/
static int fileSystemInit()
{

res = f_mount (&sysFs,"0:",1); //挂载
printf("f_mount函数的返回值是%d\r\n",res);
if(res != 0)
{
    res = f_mkfs("0:",FM_FAT,4096,gFsWork,sizeof(gFsWork)); //格式化
    printf("f_mkfs函数的返回值是%d\r\n",res);
    if(res == 0)
    {
    
        res = f_mount (&sysFs,"0:",1);   //在挂载
        printf("f_mount2函数的返回值是%d\r\n",res);
        if(res == 0)
        {
            gFsInited = 1;
            return 0;
        }
        else
            return -1;
    }
    else
        return -1;
}
else
    gFsInited = 1;
return 0;

}
/-----------------------------------------------------------------------/
/* 串口打印结果 /
/
-----------------------------------------------------------------------*/
DeviceID=ef15 //设备id可以读出来
disk_read---sector:0,count:1
disk_read---sector:63,count:1
f_mount函数的返回值是13
disk_write---sector:63,count:1
disk_write---sector:64,count:1
disk_write---sector:65,count:1
disk_write---sector:66,count:1
disk_write---sector:67,count:1
disk_write---sector:68,count:1
disk_write---sector:0,count:1
f_mkfs函数的返回值是0
disk_read---sector:0,count:1
disk_read---sector:63,count:1
f_mount2函数的返回值是13
gFsInited=0

  • 写回答

1条回答 默认 最新

  • qllaoda 2022-05-25 18:47
    关注

    disk_write函数,只擦除了一个扇区,假如有多个扇区写入,这里就有问题了。 不过这个可能不是主要问题,因为从串口输出信息看,每次只写了一个扇区。

    怀疑底层驱动有问题 建议手动调试一下disk_ioctl函数,看获取参数是否正确,
    然后试验一下disk_write和disk_read,对比一下写入数据和读出数据是否匹配。如果不匹配,用更底层的SPI_Read_Data和SPI_Write_Data测试一下。

    对了,检查一下SPI Flash是不是被写保护了。
    SPI Flash擦除,写入函数,都需要等待,通过查询Flash的状态寄存器来确认操作是否完成,特别是擦除,等待时间还有点长,SPI_Wait_WriteEnd是在干这个事情吗?看不到具体代码,不好说。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录

报告相同问题?

问题事件

  • 系统已结题 6月4日
  • 已采纳回答 5月27日
  • 创建了问题 5月24日

悬赏问题

  • ¥15 echarts动画效果失效的问题。官网下载的例子。
  • ¥60 许可证msc licensing软件报错显示已有相同版本软件,但是下一步显示无法读取日志目录。
  • ¥15 Attention is all you need 的代码运行
  • ¥15 一个服务器已经有一个系统了如果用usb再装一个系统,原来的系统会被覆盖掉吗
  • ¥15 使用esm_msa1_t12_100M_UR50S蛋白质语言模型进行零样本预测时,终端显示出了sequence handled的进度条,但是并不出结果就自动终止回到命令提示行了是怎么回事:
  • ¥15 前置放大电路与功率放大电路相连放大倍数出现问题
  • ¥30 关于<main>标签页面跳转的问题
  • ¥80 部署运行web自动化项目
  • ¥15 腾讯云如何建立同一个项目中物模型之间的联系
  • ¥30 VMware 云桌面水印如何添加