一:spi初始化
hspi.Instance = SPI;
hspi.Init.Mode = SPI_MODE_MASTER;
hspi.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi.Init.NSS = SPI_NSS_SOFT;
hspi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
hspi.Init.FirstByte = SPI_LITTLEENDIAN;
二:io初始化
__HAL_RCC_SPI_CLK_ENABLE();
__HAL_AFIO_REMAP_SPI_CS(GPIOB, GPIO_PIN_4);//22 or 18
__HAL_AFIO_REMAP_SPI_CLK(GPIOB, GPIO_PIN_2);//24
__HAL_AFIO_REMAP_SPI_MISO(GPIOB, GPIO_PIN_3);//25
__HAL_AFIO_REMAP_SPI_MOSI(GPIOB, GPIO_PIN_5);//26
三:下载fatfs
//#define DEV_RAM 0 /* Example: Map Ramdisk to physical drive 0 */
//#define DEV_MMC 1 /* Example: Map MMC/SD card to physical drive 1 */
//#define DEV_USB 2 /* Example: Map USB MSD to physical drive 2 */
#define DEV_SPI 0 /* Example: Map USB MSD to physical drive 2 */
//修改添加 spi
/*-----------------------------------------------------------------------*/
/* Low level disk I/O module SKELETON for FatFs (C)ChaN, 2019 */
/*-----------------------------------------------------------------------*/
/* If a working storage control module is available, it should be */
/* attached to the FatFs via a glue function rather than modifying it. */
/* This is an example of glue functions to attach various exsisting */
/* storage control modules to the FatFs module with a defined API. */
/*-----------------------------------------------------------------------*/
#include "ff.h" /* Obtains integer types */
#include "diskio.h" /* Declarations of disk functions */
#include "../src/wq25128.h"
/* Definitions of physical drive number for each drive */
//#define DEV_RAM 0 /* Example: Map Ramdisk to physical drive 0 */
//#define DEV_MMC 1 /* Example: Map MMC/SD card to physical drive 1 */
//#define DEV_USB 2 /* Example: Map USB MSD to physical drive 2 */
#define DEV_SPI 0 /* Example: Map USB MSD to physical drive 2 */
/*-----------------------------------------------------------------------*/
/* Get Drive Status */
/*-----------------------------------------------------------------------*/
DSTATUS disk_status (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
DSTATUS stat;
// int result;
uint8_t id[2] = {0};
switch (pdrv) {
case DEV_SPI:
//BSP_W25Q128_Init();
BSP_W25Q128_Read_ID(id);
//result = id[0] << 8 | id[1];
if(id[0] == 0xEF && id[1] == 0x17)//0x18 is w25q256
stat = !STA_NOINIT;
else
stat = STA_NOINIT;
return stat;
}
return STA_NOINIT;
}
/*-----------------------------------------------------------------------*/
/* Inidialize a Drive */
/*-----------------------------------------------------------------------*/
DSTATUS disk_initialize (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
//DSTATUS stat;
//int result;
switch (pdrv) {
case DEV_SPI:
//BSP_W25Q128_Init();
return !STA_NOINIT;//disk_status(DEV_SPI);
}
return STA_NOINIT;
}
/*-----------------------------------------------------------------------*/
/* Read Sector(s) */
/*-----------------------------------------------------------------------*/
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 */
)
{
//DRESULT res;
//int result;
switch (pdrv) {
case DEV_SPI:
if(pdrv != 0 || count == 0) return RES_PARERR;
if(BSP_W25Q128_Read(buff, sector * W25Q128FV_SECTOR_SIZE, count * W25Q128FV_SECTOR_SIZE) == W25Q128_OK)
return RES_OK;
else return RES_ERROR;
}
return RES_PARERR;
}
/*-----------------------------------------------------------------------*/
/* Write Sector(s) */
/*-----------------------------------------------------------------------*/
#if FF_FS_READONLY == 0
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 */
)
{
//DRESULT res;
//int result;
uint8_t i = 0;
switch (pdrv) {
case DEV_SPI:
if(pdrv != 0 || count == 0) return RES_PARERR;
for(i = 0; i < count; i++)
{
if(BSP_W25Q128_Erase_Sector((sector + i) * W25Q128FV_SECTOR_SIZE) != W25Q128_OK)
return RES_ERROR;
if(BSP_W25Q128_Write((uint8_t*)buff + (i * W25Q128FV_SECTOR_SIZE), (sector + i) * W25Q128FV_SECTOR_SIZE, W25Q128FV_SECTOR_SIZE) != W25Q128_OK)
return RES_ERROR;
}
return RES_OK;
}
return RES_PARERR;
}
#endif
/*-----------------------------------------------------------------------*/
/* Miscellaneous Functions */
/*-----------------------------------------------------------------------*/
DRESULT disk_ioctl (
BYTE pdrv, /* Physical drive nmuber (0..) */
BYTE cmd, /* Control code */
void *buff /* Buffer to send/receive control data */
)
{
DRESULT res;
//int result;
switch (pdrv) {
case DEV_SPI:
if(pdrv != 0) return RES_PARERR;
switch(cmd)
{
case CTRL_SYNC:
res = RES_OK;
break;
case GET_SECTOR_COUNT:
*(DWORD*)buff = W25Q128FV_FLASH_SIZE / W25Q128FV_SECTOR_SIZE;
res = RES_OK;
break;
case GET_SECTOR_SIZE:
*(WORD*)buff = W25Q128FV_SECTOR_SIZE;
res = RES_OK;
break;
case GET_BLOCK_SIZE:
*(DWORD*)buff = 1;
res = RES_OK;
break;
default:
res = RES_PARERR;
break;
}
return res;
}
return RES_PARERR;
}
根据需要 修改 配置 文件
#define FF_USE_MKFS 1 //支持格式化函数
#define FF_CODE_PAGE 936 //中文支持
#define FF_USE_LFN 1 //长文件名支持
#define FF_MAX_SS 4096 //扇区块字节
#define FF_MAX_SS 4096 //文件日期
上一篇:国产W806 I2C硬件模块
下一篇:W801 W800 W806串口下载失败的原因
推荐阅读最新更新时间:2024-11-16 20:35
设计资源 培训 开发板 精华推荐
- 使用 Aimtec 的 AM3G-4815DH30Z 的参考设计
- 具有低噪声旁路的 LTM8068EY 12V 反激式转换器的典型应用电路
- MC06XS3517AFK智能高边开关模块典型应用电路
- 【CW32】基于CW32的焊武帝专属排风扇
- S12ZVM 12 V电气燃料泵(EFP)参考设计
- LTC1148、具有故障保护功能的 5V 至 3.3V 稳压器
- LT3669/LT3669-2 的典型应用 - 具有集成降压稳压器和 LDO 的 IO-Link 收发器
- EB7760,用于 SPT7760、8 位、1 GSPS 示波器模数转换器的评估板
- 使用基于 ZICM3588SP2-1-R Ember EM35x 收发器模块的 Mesh Connect EM35x 迷你模块的典型应用电路
- 【创意PCB】立方灯