1.源码
GitHub - armink/SFUD: An using JEDEC's SFDP standard serial (SPI) flash universal driver library | 一款使用 JEDEC SFDP 标准的串行 (SPI) Flash 通用驱动库
2.介绍

这个通用驱动库,实际就是帮你封装好了读写spiflash的函数, 我们只需要对接以下底层,就可以轻松实现spiflash的读写.
3.移植
1.将sfud.c, sfud_sfdp.c sfud_port.c添加到工程
2.包含头文件路径.
3.实现sfud_port.c中的函数
static sfud_err spi_write_read(const sfud_spi *spi, const uint8_t *write_buf, size_t write_size, uint8_t *read_buf,
        size_t read_size) {
    sfud_err result = SFUD_SUCCESS;
    uint8_t send_data, read_data;
HAL_GPIO_WritePin(GPIOG, GPIO_PIN_8, GPIO_PIN_RESET);
    /**
     * add your spi write and read code
     */
            if(write_size)
            result = (sfud_err)HAL_SPI_Transmit(&hspi1, (uint8_t *)write_buf, write_size, 2000);
            if(read_size)
            result = (sfud_err)HAL_SPI_Receive(&hspi1, read_buf, read_size, 2000);
            HAL_GPIO_WritePin(GPIOG, GPIO_PIN_8, GPIO_PIN_SET);
    return result;
}sfud_err sfud_spi_port_init(sfud_flash *flash) {
    sfud_err result = SFUD_SUCCESS;
    /**
     * add your port spi bus and device object initialize code like this:
     * 1. rcc initialize
     * 2. gpio initialize
     * 3. spi device initialize
     * 4. flash->spi and flash->retry item initialize
     *    flash->spi.wr = spi_write_read; //Required
     *    flash->spi.qspi_read = qspi_read; //Required when QSPI mode enable
     *    flash->spi.lock = spi_lock;
     *    flash->spi.unlock = spi_unlock;
     *    flash->spi.user_data = &spix;
     *    flash->retry.delay = null;
     *    flash->retry.times = 10000; //Required
     */
    flash->spi.wr = spi_write_read;
    flash->retry.times = 10000;
    return result;
}4.移植遇到的问题
1.sfud_write_read()函数, 一定要在里面增加片选先使能再失能, 这个问题导致我排查了很久, 实际上这个是必不可少的,以前学习的时候可能糊弄就过了.如果不增加这个会发现第一次读写都是成功的,后面一直返回0,.
2.我用的是W25Q128,SFUD说不支持, 可能是最新出的flash他们也开始支持了吧, 如何测试支不支持SFUD标准,可以将SFUD_FLASH_CHIP_TABLE这个表中对应的flash删除.看是否还能够正常初始化成功.

3.如果不支持SFUD标准, 则需要根据The flash device manufacturer ID is 0xEF, memory type ID is 0x40, capacity ID is 0x18.这三个参数, 在SFUD_FLASH_CHIP_TABLE表中添加对应的设备信息.
5.使用
在main.c中调用函数
int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_SPI1_Init();
  MX_USART1_UART_Init();
sfud_init();
const sfud_flash *flash = sfud_get_device_table() + 0;
sfud_err result = sfud_erase(flash, 0, 100);
 if (result == SFUD_SUCCESS) {
        printf("Erase the %s flash data finish. Start from 0x%08X, size is %ld.\r\n", flash->name, 0,
                100l);
    } else {
        printf("Erase the %s flash data failed.\r\n", flash->name);
    }
    sfud_write(flash, 0, 11, "hello world");
  while (1)
  {
      HAL_Delay(1000);
      printf("test\r\n");
      uint8_t buf[100] = {0};
      sfud_read(flash, 0, 10, buf);
      for(int i = 0; i< 11;i++)
      {
        printf("%c ", buf[i]);
      }
  }
  /* USER CODE END 3 */
}


















