搜索
bottom↓
回复: 56

SPIFLASH +FATFS 在文件系统写入出现BUG

  [复制链接]

出0入0汤圆

发表于 2014-4-1 18:16:20 | 显示全部楼层 |阅读模式
spiflash是 W25Q128 已经用USB格式化成16M U盘,fatfs已经移植上去,读取里面.txt文件内容没问题。但是只要写入一些数据就会导致U盘 .txt文本乱码  U盘的FAT系统崩溃等等,求大侠指教SPIFLASH的写入该如何移植到FATFS

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

发表于 2014-4-1 18:35:55 | 显示全部楼层
注意文件簇的大小以及注意W25Q128的扇区大小

出0入0汤圆

 楼主| 发表于 2014-4-1 18:45:39 | 显示全部楼层
yy625 发表于 2014-4-1 18:35
注意文件簇的大小以及注意W25Q128的扇区大小

族大小在哪里设置? 那个扇区都是4096,和SD卡的驱动512有区别,我在怀疑是不是SPIflash不能进行写操作。。。

出130入129汤圆

发表于 2014-4-1 18:53:01 来自手机 | 显示全部楼层
我用过8M SPI FLASH,文本格式没问题。

出0入0汤圆

 楼主| 发表于 2014-4-1 19:07:22 | 显示全部楼层
68336016 发表于 2014-4-1 18:53
我用过8M SPI FLASH,文本格式没问题。

大侠~能给我看看文件系统接口部分的源码吗?284466231@qq.com

出130入129汤圆

发表于 2014-4-1 19:39:35 | 显示全部楼层
zc_jky 发表于 2014-4-1 19:07
大侠~能给我看看文件系统接口部分的源码吗?
  1. /*-----------------------------------------------------------------------*/
  2. /* Low level disk I/O module skeleton for FatFs     (C)ChaN, 2013        */
  3. /*-----------------------------------------------------------------------*/
  4. /* If a working storage control module is available, it should be        */
  5. /* attached to the FatFs via a glue function rather than modifying it.   */
  6. /* This is an example of glue functions to attach various exsisting      */
  7. /* storage control module to the FatFs module with a defined API.        */
  8. /*-----------------------------------------------------------------------*/

  9. #include "diskio.h"                /* FatFs lower layer API */
  10. //#include "usbdisk.h"        /* Example: USB drive control */
  11. //#include "atadrive.h"        /* Example: ATA drive control */
  12. #include "spi_flash.h"                /* Example: MMC/SDC contorl */
  13. #include "rtc.h"
  14. /* Definitions of physical drive number for each media */
  15. #define ATA                0
  16. #define MMC                1
  17. #define USB                2

  18. #define FLASH_PAGE_SIZE                        256
  19. #define FLASH_SECTOR_SIZE                4096
  20. #define FLASH_SECTOR_COUNT                2048
  21. #define FLASH_BLOCK_SIZE                65536
  22. /*-----------------------------------------------------------------------*/
  23. /* Inidialize a Drive                                                    */
  24. /*-----------------------------------------------------------------------*/

  25. DSTATUS disk_initialize (
  26.         BYTE pdrv                                /* Physical drive nmuber (0..) */
  27. )
  28. {
  29.         //DSTATUS stat;
  30.         int result;

  31.         if (pdrv)
  32.         {
  33.                 return        STA_NOINIT;        //pdrv只能等于0,否则返回参数错误
  34.         }

  35.         result = SPI_FLASH_Init();
  36.         if (result == STA_NODISK)
  37.         {
  38.                 return STA_NODISK;
  39.         }
  40.         else if(result != 0)
  41.         {
  42.                 return STA_NOINIT;
  43.         }
  44.         else
  45.         {
  46.                 return RES_OK;
  47.         }
  48. }



  49. /*-----------------------------------------------------------------------*/
  50. /* Get Disk Status                                                       */
  51. /*-----------------------------------------------------------------------*/

  52. DSTATUS disk_status (
  53.         BYTE pdrv                /* Physical drive nmuber (0..) */
  54. )
  55. {
  56.         //DSTATUS stat;
  57. //         int result;

  58.         if (pdrv)
  59.         {
  60.                 return        STA_NOINIT;        //pdrv只能等于0,否则返回参数错误
  61.         }

  62.         return RES_OK;
  63. }



  64. /*-----------------------------------------------------------------------*/
  65. /* Read Sector(s)                                                        */
  66. /*-----------------------------------------------------------------------*/

  67. DRESULT disk_read (
  68.         BYTE pdrv,                /* Physical drive nmuber (0..) */
  69.         BYTE *buff,                /* Data buffer to store read data */
  70.         DWORD sector,        /* Sector address (LBA) */
  71.         BYTE count                /* Number of sectors to read (1..128) */
  72. )
  73. {
  74.         u32 i;
  75.        
  76.         if (pdrv || !count)
  77.         {
  78.                 return RES_PARERR; //pdrv只能等于0,count不能等于0,否则返回参数错误
  79.         }

  80.         for (i=0; i<count; i++)
  81.         {
  82.                 W25X_ReadSector(sector, buff);
  83.                 sector++;
  84.                 buff += 4096;
  85.         }
  86.        
  87.         return RES_OK;
  88. }



  89. /*-----------------------------------------------------------------------*/
  90. /* Write Sector(s)                                                       */
  91. /*-----------------------------------------------------------------------*/

  92. #if _USE_WRITE
  93. DRESULT disk_write (
  94.         BYTE pdrv,                        /* Physical drive nmuber (0..) */
  95.         const BYTE *buff,        /* Data to be written */
  96.         DWORD sector,                /* Sector address (LBA) */
  97.         BYTE count                        /* Number of sectors to write (1..128) */
  98. )
  99. {
  100.         u32 i;

  101.         if (pdrv || !count)
  102.         {
  103.                 return RES_PARERR; //count不能等于0,否则返回参数错误
  104.         }

  105.         for (i=0; i<count; i++)
  106.         {
  107.                 W25X_EraseSector(sector);
  108.                 W25X_WriteSector(sector, (u8*)buff);
  109.                 sector++;
  110.                 buff += 4096;
  111.         }
  112.         return RES_OK;       
  113. }
  114. #endif


  115. /*-----------------------------------------------------------------------*/
  116. /* Miscellaneous Functions                                               */
  117. /*-----------------------------------------------------------------------*/

  118. #if _USE_IOCTL
  119. DRESULT disk_ioctl (
  120.         BYTE pdrv,                /* Physical drive nmuber (0..) */
  121.         BYTE cmd,                /* Control code */
  122.         void *buff                /* Buffer to send/receive control data */
  123. )
  124. {
  125.         DRESULT res = RES_OK;
  126.         char *buf = buff;
  127. //         int result;

  128.         if (pdrv)
  129.         {
  130.                 return RES_PARERR; //count不能等于0,否则返回参数错误
  131.         }

  132.         //FATFS目前版本仅需处理CTRL_SYNC,GET_SECTOR_COUNT,GET_BLOCK_SIZ三个命令
  133.         switch(cmd)
  134.         {
  135.         case CTRL_SYNC: /* Make sure that all data has been written on the media */;
  136.                 break;

  137.         case GET_SECTOR_COUNT:/* Get number of sectors on the disk (DWORD) */
  138.                 buf[0] = (u8)(FLASH_SECTOR_COUNT & 0xFF);
  139.                 buf[1] = (u8)(FLASH_SECTOR_COUNT >> 8);
  140.                 res = RES_OK;
  141.                 break;
  142.        
  143.         case GET_SECTOR_SIZE :        /* Get sectors on the disk (WORD) */
  144.                 buf[0] = (u8)(FLASH_SECTOR_SIZE & 0xFF);
  145.                 buf[1] = (u8)(FLASH_SECTOR_SIZE >> 8);
  146.                 break;

  147.         case GET_BLOCK_SIZE :        /* Get erase block size in unit of sectors (DWORD) */                        
  148.                 buf[1] = (u8)(FLASH_BLOCK_SIZE & 0xFF);
  149.                 buf[0] = (u8)(FLASH_BLOCK_SIZE >> 8);
  150.                 break;

  151.         default:
  152.                 res = RES_PARERR;
  153.                 break;
  154.         }

  155.         return res;
  156. }
  157.        
  158. #endif

  159. /*-----------------------------------------------------------------------*/
  160. /* User defined function to give a current time to fatfs module          */
  161. /* 31-25: Year(0-127 org.1980), 24-21: Month(1-12), 20-16: Day(1-31) */                                                                                                                                                                                                                                          
  162. /* 15-11: Hour(0-23), 10-5: Minute(0-59), 4-0: Second(0-29 *2) */                                                                                                                                                                                                                                                
  163. DWORD get_fattime (void)
  164. {
  165.         Time t;
  166.         DWORD date = 0;
  167.         RTC_GetCalendarTime(&t);
  168.     t.tm_year -= 60;
  169.         date = (t.tm_year<<25) | (t.tm_mon<<21) | (t.tm_mday<<16) | (t.tm_hour<<11) | (t.tm_min<<5) | (t.tm_sec);
  170.         return date;
  171. }
复制代码

出10入0汤圆

发表于 2014-4-1 19:42:57 | 显示全部楼层
mark   真准备做

出0入0汤圆

发表于 2014-4-1 19:51:30 | 显示全部楼层
W25Q128的扇区大小为4096,文件系统一般扇区大小都为512,因此文件系统的一个扇区(512)写入到W25Q128时,要先把那个扇区(4096)不改写的数据先读出来,再擦除一个扇区(4096),然后回写扇区(4096)数据。

出130入129汤圆

发表于 2014-4-1 20:06:30 | 显示全部楼层
ffconf.h
// #define        _MAX_SS                512                /* 512, 1024, 2048 or 4096 */
#define        _MAX_SS                4096                /* 512, 1024, 2048 or 4096 */
/* Maximum sector size to be handled.

出0入0汤圆

发表于 2014-4-1 20:15:49 | 显示全部楼层
我去,果断MARK

出0入0汤圆

发表于 2014-4-2 00:08:17 | 显示全部楼层
果断MARK了

出0入0汤圆

 楼主| 发表于 2014-4-2 14:36:40 | 显示全部楼层
68336016 发表于 2014-4-1 20:06
ffconf.h
// #define        _MAX_SS                512                /* 512, 1024, 2048 or 4096 */
#define        _MAX_SS                4096                /* 512, 1024, ...

非常谢谢大侠~~

出0入0汤圆

 楼主| 发表于 2014-4-3 09:37:34 | 显示全部楼层

我照着你的代码修改 读取操作没问题,都能读对,但是自己修改(写操作的时候)    还是会出现.txt文本(乱码,文本消失,U盘系统崩溃等。。。)

出130入129汤圆

发表于 2014-4-3 09:39:07 | 显示全部楼层
zc_jky 发表于 2014-4-3 09:37
我照着你的代码修改 读取操作没问题,都能读对,但是自己修改(写操作的时候)    还是会出现.txt文本(乱码 ...

怎么写的,发几行你写的代码来

出0入0汤圆

 楼主| 发表于 2014-4-3 09:45:33 | 显示全部楼层
68336016 发表于 2014-4-3 09:39
怎么写的,发几行你写的代码来

//向文件最后一行追加数据
void my_inserend(const u8 *path,u8* inset)
{
        u16 i=0,ofset=0,j=0,k=0;
                u8 line_buf[2];
                u8 end[2]="\r\n";
                u32 value=0;

                res= f_open(&fsrc,path,        FA_READ | FA_WRITE);//打开a.txt
               
                if(res==FR_OK)
                {
                        printf("打开文件成功!\r\n");       
                        f_lseek(&fsrc,0);//把文件偏移量设置回0
                        br=1;
                       
                        f_lseek(&fsrc,fsrc.fsize-2);
                        f_read(&fsrc, line_buf,2,&br);
                        if(line_buf[0]!='\r'&&line_buf[0]!='\n')//检查文本最后有没有换行符号
                        {
                                f_lseek(&fsrc,fsrc.fsize);
                                res=f_write(&fsrc,end,2,&bw);//加入换号
                        }
                        res=f_lseek(&fsrc,fsrc.fsize);
                        res=f_write(&fsrc,inset,strlen(inset),&bw);
                        f_close(&fsrc);
                 }
                else
                {
                                return;//文件不存在
                }
       
}
这个函数有时候可以看到文本最后行 插入的字符串有时候却不行文本还会消失。太奇怪。。。 不只是这个函数 只要调用写入数据都会有异常问题。。。

出0入0汤圆

 楼主| 发表于 2014-4-3 09:47:38 | 显示全部楼层
这是我的工程 实现了STM32 USB和VCOM切换, USB U盘 现在写操作有问题哎。。。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2014-4-5 13:46:44 | 显示全部楼层
68336016 发表于 2014-4-3 09:39
怎么写的,发几行你写的代码来

大神能帮我看看吗或者能看看你的工程吗?

出0入20汤圆

发表于 2014-4-5 16:30:40 | 显示全部楼层
你自己要做一个FAT-512字节扇区读写程序,套进FALSH里的4K.

出0入20汤圆

发表于 2014-4-5 16:31:20 | 显示全部楼层
/****************************************Copyright (c)**************************************************                        

********************************************************************************************************/

/* Includes ------------------------------------------------------------------*/
#include "SST25.h"
#include "USE.h"
//**********************************************************************************************
#define Nf0        0xffffffff
#define Nf1        Nf0,Nf0,Nf0,Nf0,Nf0,Nf0,Nf0,Nf0,Nf0,Nf0,Nf0,Nf0,Nf0,Nf0,Nf0,Nf0 //16个=16*4=64个字节
#define Nf2        Nf1,Nf1,Nf1,Nf1,Nf1,Nf1,Nf1,Nf1,Nf1,Nf1,Nf1,Nf1,Nf1,Nf1,Nf1,Nf1 //16*(16*4)=1024 字节
#define BYTE_1K         (1024)
#define BYTE_4K         (1024*4)
#define BYTE_512         (1024/2)
//**********************************************************************************************
extern unsigned int FAT_Wr_Flash(unsigned int byteAddr,unsigned char *p,unsigned int byteCnt);
extern unsigned int FAT_Rd_Flash(unsigned int byteAddr,unsigned char *p,unsigned int byteCnt);
extern unsigned int FAT_Erase_Flash(unsigned int sectorAddr);
extern void Clr_RTC_ram_flag(void);
extern FLASH_INFO   FLASH_info;

//**********************************************************************************************
//设置一个4K的0XFF空间
const unsigned int MASK_FF[]={
        Nf2,Nf2,Nf2,Nf2
};
//-------------------------------------------------------------------------------------------------------
//磁盘的信息读出!
unsigned int SST25_FS_Read_MSG(unsigned int *ser,unsigned int *rd_len,unsigned int *wr_len,unsigned int *sectCnt ){
        *ser                 =0x01222 ;
        *rd_len         =512;          //固定不变
        *wr_len         =512;          //固定不变
        *sectCnt          =(FLASH_info.Fat_size/512); //计算扇区的个数( 1个物理扇区=4096==8个文件扇区!)
        return 1;
}
//**********************************************************************************************
//读取FLASH的文件扇区数量
unsigned int FATFS_Get_DISK_Sectors(void){
                return (FLASH_info.Fat_size/512);
}
//**********************************************************************************************
//文件系统操作读        传入=SECT(扇区512个字节),CNT=扇区的个数;考虑跨页读和跨快读
unsigned int SST25_FS_Rd_Sector(unsigned int sect,unsigned char *buf,unsigned int cnt){
        FAT_Rd_Flash(sect<<9,buf,cnt<<9);        //从芯片的物理256扇区(256*4=1M)开始读数据】】
        return 0;
}
//**********************************************************************************************
extern void SaveData_To_Ram(unsigned char *buf,unsigned int sector_cnt);   //写入2个地方RAM+fw25 ,标记由对方程序写入
//*******************************************************************************************************
//对指定一个扇区的写入
//sect=物理扇区地址,OFFSET=物理地址偏移量,CNT是字节数!!
//返回=文件扇区数 cnt
unsigned int SST25_ONE_Sector_Wr(unsigned int sect,unsigned offset,unsigned char *buf,unsigned int cnt){
        unsigned char *p;
        p=Set_RTC_RAM(); //备份数据到rtc-ram
        FAT_Rd_Flash(sect<<12,p,4096);        //全部读出来。
        if(memcmp(&p[offset],buf,cnt)){ //数据不相等就要比较是否为0XFF!
                if(memcmp(&p[offset],(unsigned char *)MASK_FF,cnt)){ //数据不是0XFF!
                        memcpy(&p[offset],buf,cnt);    //写入数据到BUFF。
                        SaveData_To_Ram(buf,sect);   //写入2个地方RAM+fw25 ,标记由对方程序写入
                        FAT_Erase_Flash(sect);                          //删除对应的物理扇区 不是字节地址 4K
                        FAT_Wr_Flash(sect<<12,p,4096);//写一个文件扇区4096字节
                        //*************************************************************
                        //清楚标记!!!
                        Clr_RTC_ram_flag();
                }else{//扇区里的内容是0xff可以直接写。
                         FAT_Wr_Flash((sect*4096 + offset),buf,cnt);//写一个文件扇区512字节
                }
        }
        return cnt/512; //返回文件扇区数量!
}
//**********************************************************************************************
//文件系统操作写        传入=SECT(文件扇区512个字节),CNT=扇区的个数;//从芯片的物理256扇区(256*4=1M)开始读数据】】
//=1 有错误;=0 OK
unsigned int SST25_FS_Wr_Sector(unsigned int sect,unsigned char *buf,unsigned int cnt){
        unsigned int n,Sect,offset;        //Sect=物理地址4K扇区;sect=文件扇区512字节
       
        n=0;//文件扇区的个数
        while(1){
                buf  +=n*512;                                                        //缓存地址增加
                Sect  =(n+sect)/8;                                //确定地址,除以8 ,是4K一个扇区! //从芯片的物理256扇区(256*4=1M)开始读数据】】
                offset=(n+sect) % 8;                        //物理扇区内的文件扇区偏移量!
                n=8-offset;                                                                //单物理扇区内的剩余文件扇区的个数:0-8
                if(cnt>n){
                        n=SST25_ONE_Sector_Wr(Sect,offset*512,buf,n*512);
                        cnt -=n;
                }else{
                        n=SST25_ONE_Sector_Wr(Sect,offset*512,buf,cnt*512);
                        break;
                }
        }
        return 0;
}

出0入20汤圆

发表于 2014-4-5 16:32:30 | 显示全部楼层
//****************************************************************************
//文件接口的读、写、删除
unsigned int FAT_Wr_Flash(unsigned int byteAddr,unsigned char *p,unsigned int byteCnt){
        byteAddr +=FLASH_info.Fat_start_adr;
        SST25_Page_Program(byteAddr,p,byteCnt);
        return 0;
}
//****************************************************************************
//文件接口的读、写、删除
unsigned int FAT_Rd_Flash(unsigned int byteAddr,unsigned char *p,unsigned int byteCnt){
        byteAddr +=FLASH_info.Fat_start_adr;
        SST25_Page_Read(byteAddr,p,byteCnt);
        return 0;
}
//****************************************************************************
//文件接口的读、写、删除
unsigned int FAT_Erase_Flash(unsigned int sectorAddr){
        sectorAddr +=(FLASH_info.Fat_start_adr/FLASH_info.oneSectorByte); //计算出物理地址所在的扇区
        SST25_Erase_Sector(sectorAddr);
        return 0;       
}

出0入20汤圆

发表于 2014-4-5 16:34:07 | 显示全部楼层
FLASH_INFO   FLASH_info;
//-------------------------------------------------------------------------------------------------------
/* 宏,用于定义SST25VF016B的片选引脚 */
#define        SST25V16_CS1                                                         (GPIO_Pin_9)                          //PC9
//********************************************************************************************************************
#define SPI_FLASH_CS(x) ((x>0)?         (GPIO_SetBits(GPIOC, SST25V16_CS1)) : (GPIO_ResetBits(GPIOC, SST25V16_CS1) ))//设置1,0
//**********************************************************************************************
//修改状态寄存器,允许芯片存储器被写
unsigned char SST25_SPI_Flash_Init(void){
                SPI3_Config();                             //初始化SPI
                SST25_ReadID();
                SST25_Page_Program_SR(0x02);        //使能状态寄存器中的写存储器
                Get_Data_To_Flash ();                                        //检测是否有掉电保护数据!
                return 0;        //0k       
}
//***************************************************************
unsigned char  Flash_ReadWriteByte(unsigned char  data){
        return SPI_ReadWriteByte(data);
}
//***************************************************************
//读取SPI_FLASH的状态寄存器
//BIT7  6   5   4   3   2   1   0
//SPR   RV  TB BP2 BP1 BP0 WEL BUSY
//SPR:默认0,状态寄存器保护位,配合WP使用
//TB,BP2,BP1,BP0:FLASH区域写保护设置
//WEL:写使能锁定
//BUSY:忙标记位(1,忙;0,空闲)
//默认:0x00
unsigned char SST25_Page_ReadSR(void){
         unsigned char byte=0;  
         SPI_FLASH_CS(0);         //使能器件  
         Flash_ReadWriteByte(SST25_ReadStatusReg);    //发送读取状态寄存器命令   
         do{
                byte=Flash_ReadWriteByte(0Xff);             //读取一个字节
         }while((byte & 0x01)==SET);
         SPI_FLASH_CS(1);                            //取消片选   
         return byte;  
}
//*************************************************************************
//写SPI_FLASH状态寄存器
//只有SPR,TB,BP2,BP1,BP0(bit 7,5,4,3,2)可以写!!!
void SST25_Page_Program_SR(unsigned char sr){  
        SPI_FLASH_CS(0);    //片选
        Flash_ReadWriteByte(SST25_EnableWriteStatusReg);  //使能写状态寄存器命令  
        SPI_FLASH_CS(1);    //取消片选
        SPI_FLASH_CS(0); //片选                        
        Flash_ReadWriteByte(SST25_WriteStatusReg);   //发送写取状态寄存器命令   
        Flash_ReadWriteByte(sr);                                       //写入一个字节
        SPI_FLASH_CS(1);                                   //取消片选                 
}  
//****************************************************************************
//SPI_FLASH写使能
//将WEL置位  
void SST25_Page_Program_Enable(void){
        SPI_FLASH_CS(0);                            //使能器件  
        Flash_ReadWriteByte(SST25_WriteEnable);      //发送写使能
        SPI_FLASH_CS(1);                            //取消片选               
}
//****************************************************************************
//SPI_FLASH写禁止
//将WEL清零
void SST25_Page_Program_Disable(void){
        SPI_FLASH_CS(0);                            //使能器件  
        Flash_ReadWriteByte(SST25_WriteDisable);    //发送写禁止指令   
        SPI_FLASH_CS(1);                            //取消片选               
}                             
//*********************************************************************************
//发送程序 COM=命令;adr=地址
void SPI_SendAdrOut(unsigned char com,unsigned int adr){
        Flash_ReadWriteByte(com);                                                                             /* 发送字节数据烧写命令        */
        Flash_ReadWriteByte((adr & 0xFFFFFF) >> 16);          /* 发送3个字节的地址信息 */
        Flash_ReadWriteByte((adr & 0xFFFF) >> 8);
        Flash_ReadWriteByte(adr & 0xFF);
}
//****************************************************************************
//读取芯片ID SST25VF016的是 0XBF41  sst25vf064_ID=bf4b
//文帮的是0xEF17
unsigned int SST25_ReadID(void){
        unsigned int Temp = 0;      
        SPI_FLASH_CS(0);   
        SPI_SendAdrOut(SST25_ManufactDeviceID,0);//发送读取ID命令
        //读取返回的16位值                              
        Temp =Flash_ReadWriteByte(0xFF)<<8;                //高8位数据
        Temp +=Flash_ReadWriteByte(0xFF);      //底八位数据
        SPI_FLASH_CS(1);                                   
        return Temp;
}
//****************************************************************************
//读取SPI FLASH
//在指定地址开始读取指定长度的数据
//pBuffer:数据存储区
//ReadAddr:开始读取的地址(24bit)
//NumByteToRead:要读取的字节数(最大65535即64k)
unsigned int SST25_Page_Read(unsigned int ReadAddr,unsigned char* pBuffer,unsigned int NumByteToRead){
        unsigned int i;   

        //计算物理地址?? 2014-1-20
        //if ((ReadAddr+NumByteToRead) >(SST25_MAX_SECTORS*SST25_SECTOR_SIZE)) return 5;  //地址错误!
        SPI_FLASH_CS(0);                                                    //使能器件  
        SPI_SendAdrOut(SST25_FastReadData,ReadAddr);                        //发送读取命令
        Flash_ReadWriteByte(0XFF);                                                                                           //发送一个哑数据!
        for(i=0;i<NumByteToRead;i++)                pBuffer[i]=Flash_ReadWriteByte(0XFF);   //循环读数
        SPI_FLASH_CS(1);                            //取消片选      
        return 0;
}
//****************************************************************************
//写入扇区已经擦除干净, NumByteToWrite 最好是8,16,32,64,128,256
//pBuffer:为待写数据组
//WriteAddr:所写数据的起始地址
//NumByteToWrite:所要写的数据的长度
unsigned int SST25_Page_Write(unsigned char* pBuffer,unsigned int WriteAddr,unsigned int NumByteToWrite){
        unsigned int i;
       
        if(NumByteToWrite==0) return 0;
        SST25_Page_Program_Enable();                  //SET WEL
        SPI_FLASH_CS(0);
        SPI_SendAdrOut(SST25_ByteProgram,WriteAddr);                                        //发送写页命令
        //发送待写的数据
        for(i=0;i<NumByteToWrite;i++)         Flash_ReadWriteByte(*pBuffer++);
        SPI_FLASH_CS(1);
        SST25_Wait_Busy();//等待写完成
        return NumByteToWrite;
}
//****************************************************************************
//写入扇区已经擦除干净, NumByteToWrite 最好是8,16,32,64,128,256
//pBuffer:为待写数据组
//WriteAddr:所写数据的起始地址
//NumByteToWrite:所要写的数据的长度
unsigned int  SST25_Page_Program(unsigned int WriteAddr,unsigned char* pBuffer,unsigned int NumByteToWrite){
        unsigned int i,page,offset;
       
        if(NumByteToWrite==0) return 3;                                                                                                                                        //溢出
        //if((WriteAddr+NumByteToWrite) >(SST25_MAX_SECTORS*SST25_SECTOR_SIZE)) return 5;  //地址错误!
       
        offset=WriteAddr % SST25_PAGE_SIZE; //一个页内(256)的偏移地址
        //*********************************************************************
        if(offset){//>0未对其地址!!!!!
                offset =256-offset;
                //*************************************************************************
                //开始地址从WriteAddr,一次写入(256-WriteAddr%256)个字节,以便对齐边界!
                if(NumByteToWrite > offset){
                        SST25_Page_Write(pBuffer,WriteAddr,offset);
                        //*****************************************************************************
                        //重新计算后面的写入字节数!
                        NumByteToWrite -=offset;
                        WriteAddr +=offset;
                        pBuffer +=offset;
                }else{
                        SST25_Page_Write(pBuffer,WriteAddr,NumByteToWrite); //写入字节数小于一个页内剩余的字节数,直接写完返回。
                        return 0;
                }
        }
        //---------------------------------------------------------------------------
        page=NumByteToWrite/SST25_PAGE_SIZE;           //要写几页
        offset=NumByteToWrite%SST25_PAGE_SIZE;        //最后一页的字节数
        //*************************************************************************
        //开始地址从0 ,便可以一次写入256个字节
        for(i=0;i<page;i++){
                SST25_Page_Write(pBuffer+i*256,WriteAddr+i*256,256);
        }
        //*************************************************************************
        //继续写完不到一页的数据
        if(offset>0){
                SST25_Page_Write(pBuffer,WriteAddr,offset);
        }
        return 0;
}
//****************************************************************************
//擦除整个芯片
//整片擦除时间:
//W25X16:25s
//W25X32:40s
//W25X64:40s
//等待时间超长...
void SST25_Erase_Chip(void){                                            
        SST25_Page_Program_Enable();                  //SET WEL
        SST25_Wait_Busy();  
        SPI_FLASH_CS(0);                            //使能器件  
        Flash_ReadWriteByte(SST25_ChipErase);       //发送片擦除命令
        SPI_FLASH_CS(1);                            //取消片选               
        SST25_Wait_Busy();                     //等待芯片擦除结束
}  
//****************************************************************************
//擦除一个扇区  Sector_Dst_Addr  物理扇区地址号!!
//Dst_Addr:扇区地址 0~511 for w25x16
//擦除一个山区的最少时间:150ms
unsigned int SST25_Erase_Sector(unsigned int Sector_Dst_Addr){  
        SST25_Page_Program_Enable();                                                  //SET WEL           
        SST25_Wait_Busy();  
        SPI_FLASH_CS(0);                                                           //使能器件  
        SPI_SendAdrOut(SST25_4KByte_BlockERASE,(Sector_Dst_Addr)*SST25_SECTOR_SIZE);//发送扇区擦除指令  必须输入绝对物理地址
        SPI_FLASH_CS(1);                                                                    //取消片选               
        return SST25_Wait_Busy();                                    //等待擦除完成
}
//****************************************************************************
//等待空闲
unsigned int SST25_Wait_Busy(void){
//        unsigned int i;
/*
        while ((SST25_Page_ReadSR() & 0x01)==0x01){   // 等待BUSY位清空
                        if(i++>20000) return 1; //一直忙!
        }
*/
        return SST25_Page_ReadSR();
}

出0入20汤圆

发表于 2014-4-5 16:34:58 | 显示全部楼层
#ifndef __sst25vf_FLASH_H
#define __sst25vf_FLASH_H                        
//SST25VF016读写
//4Kbytes为一个Sector
//16个扇区为1个Block
//SST25VF016B
//容量为2M字节,共有32个Block(块),512个Sector(扇区)
//初始化SPI FLASH的IO口
#define FLASH_ID 0XBF41
//指令表
#define SST25_ReadData                         0x03
#define SST25_FastReadData                     0x0B
#define SST25_4KByte_BlockERASE                0x20
#define SST25_32KByte_BlockErase               0x52
#define SST25_64KByte_BlockErase               0xD8
#define SST25_ChipErase                        0xC7
#define SST25_ByteProgram                      0x02
#define SST25_AAI_WordProgram                  0xAD
#define SST25_ReadStatusReg                    0x05
#define SST25_EnableWriteStatusReg             0x50
#define SST25_WriteStatusReg                   0x01
#define SST25_WriteEnable                      0x06
#define SST25_WriteDisable                     0x04
#define SST25_ManufactDeviceID                 0x90
#define SST25_JedecDeviceID                    0x9F
#define SST25_EBSY                             0x70
#define SST25_DBSY                             0x80

//****************************************************************************
//sst25  256 byte=page  4096 byte=sectors (16 page ==sectors)  1 blk=共有2048个扇区!
//w25q128  == 1024*16*1024/4096   =4096 扇区!

#define SST25_SECTOR_SIZE                        (4096)
#define SST25_PAGE_SIZE                                (256)
#define SST25_MAX_SECTORS                        (1024l*16l*1024l/SST25_SECTOR_SIZE)                                        //芯片共有的扇区数! 2048*2个扇区!

//#define SST25_SYS_SECTORS                                        (256)                                                                        //预留1M的空间在开始做其他使用!系统使用扇区
//#define SST25_SYS_SECTOR_ADR                        (0)                                                                                //系统开始的扇区号
//-------------------------------------------------------------------------------------------------------
#define SST25_KEY_ID_SECTORS_ADR        (SST25_SYS_SECTOR_ADR+SST25_SYS_SECTORS)                //预留1个扇区,保存键盘ID号!
//#define SST25_FAT_SECTOR_ADR                        (SST25_KEY_ID_SECTORS_ADR+1)                                                                //文件系统开始的扇区号
//#define SST25_MAX_SECTORS                                        (1024l*16l*1024l/SST25_SECTOR_SIZE)                                        //芯片共有的扇区数! 2048*2个扇区!
//#define SST25_FAT_SECTORS                                        (SST25_MAX_SECTORS-SST25_FAT_SECTOR_ADR+1)        //文件系统使用的扇区
//-----------------------------------
typedef struct{
        unsigned int Sys_start_adr; //非文件系统开始的物理地址
        unsigned int Sys_size; //非文件系统的空间字节数,必须4096 对齐。
        unsigned int Fat_start_adr;        //文件系统开始的地址。
        unsigned int Fat_size;        //文件系统的空间,字节数。
        unsigned int maxByte;                //芯片共有的字节数!
        unsigned int maxSector;        //芯片共有的扇区数!
        unsigned int oneSectorByte;//一个扇区的字节数
        unsigned int onePageByte;        //写一个页的最大字节数
}FLASH_INFO;
// 定义FLASH操作返回值定义
#define   DATAFLASH_BUSY                                                     0x01                    // 忙                                      
#define   DATAFLASH_OK                                                             0x00                        // 操作OK                                
#define   DATAFLASH_ERROR                                                     0x02                        // 错误                                 
#define   DATAFLASH_MEMORY_OVERFLOW            0x03                        // 溢出                                       
#define   DATAFLASH_BAD_COMMAND                             0x04                        // 命令                                    
#define   DATAFLASH_BAD_ADDRESS                             0x05                        // 地址                                   
/**************************************************************************************************************
                                                                                          类 型
**************************************************************************************************************/
typedef  unsigned int  RET_FLASH_TYPE;                       // 定义FLASH操作返回状态类型定义   
//******************************************************************************
//初始化各存储位置的参数
//必须传入扇区个数,不是物理地址!!!范围:0~4095 个扇区
//*******************************************************************************
unsigned char FLASH_ROM_Init(unsigned int sys_sector_start,unsigned int sys_sector_size,
                                                                                                                unsigned int fat_sector_start,unsigned int fat_sector_size);

//*****************************************************************************
void SST25_Page_Program_SR(unsigned char sr);
unsigned char SST25_SPI_Flash_Init(void);
unsigned int  SPI_Flash_ReadID(void);                //读取FLASH ID
unsigned char   SPI_Flash_ReadSR(void);        //读取状态寄存器
void SPI_FLASH_Write_SR(unsigned char sr);     //写状态寄存器
void SPI_FLASH_Write_Enable(void);  //写使能
void SPI_FLASH_Write_Disable(void); //写保护
void SPI_Flash_Read(unsigned char* pBuffer,unsigned int ReadAddr,unsigned int NumByteToRead);   //读取flash
unsigned int SST25_Erase_Sector(unsigned int Dst_Addr);//扇区擦除
unsigned int SST25_Wait_Busy(void);           //等待空闲
void SST25V_EBSY(void);
void SST25V_DBSY(void);
void Flash_WriteByte(unsigned char* pBuffer,unsigned int WriteAddr);//写入1Byte数据
void SPI_Flash_Write(unsigned char pBuffer[],unsigned int WriteAddr,unsigned int NumByteToWrite);//结合AB构成的地址自动增加的连续数据的写入
unsigned int SST25_Page_Read(unsigned int ReadAddr,unsigned char* pBuffer,unsigned int NumByteToRead);
unsigned int SST25_Page_Program(unsigned int WriteAddr,unsigned char* pBuffer,unsigned int NumByteToWrite);
void SST25_Erase_Chip(void);
unsigned int SST25_ReadID(void);
extern void SPI3_Config(void);
extern unsigned char SPI_ReadWriteByte(unsigned char TxData);
//-------------------------------------------------------------------------------------------------------
//磁盘的信息读出!
unsigned int SST25_FS_Read_MSG(unsigned int *ser,unsigned int *rd_len,unsigned int *wr_len,unsigned int *sectCnt );
//**********************************************************************************************
//读取FLASH的文件扇区数量
unsigned int FATFS_Get_DISK_Sectors(void);
//**********************************************************************************************
//文件系统操作读        传入=SECT(扇区512个字节),CNT=扇区的个数;考虑跨页读和跨快读
unsigned int SST25_FS_Rd_Sector(unsigned int sect,unsigned char *buf,unsigned int cnt);
//*******************************************************************************************************
//对指定一个扇区的写入
//sect=物理扇区地址,OFFSET=物理地址偏移量,CNT是字节数!!
//返回=文件扇区数 cnt
unsigned int SST25_ONE_Sector_Wr(unsigned int sect,unsigned offset,unsigned char *buf,unsigned int cnt);
//**********************************************************************************************
//文件系统操作写        传入=SECT(文件扇区512个字节),CNT=扇区的个数;//从芯片的物理256扇区(256*4=1M)开始读数据】】
//=1 有错误;=0 OK
unsigned int SST25_FS_Wr_Sector(unsigned int sect,unsigned char *buf,unsigned int cnt);
//================================================================================================
//FLASH SPI配置与初始化                                                
RET_FLASH_TYPE  HW_Flash_Init( void );
//********************************************************************                                          
// 连续的读FLASH数据       (可以跨页读) 多页
RET_FLASH_TYPE HW_Flash_Read( unsigned int addr, unsigned int size, unsigned char *buffer );
//**********************************************************************************************************
//一个物理扇区的写入处理 sect =扇区地址号   内部函数!!!
//对指定一个扇区的写入,cnt=字节个数1-4096
//sect=物理扇区地址
//返回=cnt 写入的字节数!
unsigned int HW_Flash_ONE_Sector_Wr(unsigned int sect,unsigned offset,unsigned char *buf,unsigned int cnt);
//**********************************************************************************************************
// 高级的连续向FLASH写数据 (可以跨页写) 多页 有擦除   
RET_FLASH_TYPE HW_Flash_EraseWrite( unsigned int dest,        unsigned int size, unsigned char *src );
//************************************************************************************************************                                                                                                                                                                           
// 高级的连续向FLASH写数据  (可以跨页写) 多页 无擦除
RET_FLASH_TYPE HW_Flash_NotEraseWrite( unsigned int dest, unsigned int size, unsigned char *src );
//************************************************************************************************************                                                                                                                                                                           
// 高级的连续向FLASH写数据  (可以跨页写) 多页  当写入数据为页开始地址时,自动擦除本页
RET_FLASH_TYPE HW_Flash_SmartWrite( unsigned int addr, unsigned int size, unsigned char *src );
//***********************************************************************************************************
// 擦除FLASH一页  一个扇区内有8个512字节页,但不是528字节
RET_FLASH_TYPE HW_Flash_PageErase( unsigned int page );


#endif

出0入0汤圆

发表于 2014-4-5 17:32:36 | 显示全部楼层
我去,果断MARK

出0入0汤圆

 楼主| 发表于 2014-4-5 18:31:47 | 显示全部楼层
mon51 发表于 2014-4-5 16:34
#ifndef __sst25vf_FLASH_H
#define __sst25vf_FLASH_H                        
//SST25VF016读写

4096的SPIflash  的写操作确实有问题是吗 大神。。。谢谢指教。。

出0入20汤圆

发表于 2014-4-5 20:02:20 | 显示全部楼层
zc_jky 发表于 2014-4-5 18:31
4096的SPIflash  的写操作确实有问题是吗 大神。。。谢谢指教。。

上面发的就是w25q128的代码,是在早期的SST的代码上改的。

出0入0汤圆

发表于 2014-4-5 20:30:18 | 显示全部楼层
内容精彩,留着备学。

出0入0汤圆

 楼主| 发表于 2014-4-7 18:56:57 来自手机 | 显示全部楼层
mon51 发表于 2014-4-5 20:02
上面发的就是w25q128的代码,是在早期的SST的代码上改的。

兄弟是不是文件系统支持4096但是实际上还是得按512进行写操作?这是这个文件系统的缺陷么?

出0入0汤圆

 楼主| 发表于 2014-4-7 19:09:02 来自手机 | 显示全部楼层
mon51 发表于 2014-4-5 20:02
上面发的就是w25q128的代码,是在早期的SST的代码上改的。

还有我usb那部分也是按4096进行格式化这部分是否有影响?

出0入20汤圆

发表于 2014-4-7 20:08:07 | 显示全部楼层
USB 里的读写只要调用FLASH的读写即可。

出0入20汤圆

发表于 2014-4-7 20:12:14 | 显示全部楼层
请分清2个概念:
1:文件系统的一个扇区:512字节
2:FLASH芯片的物理一个扇区:4096字节。
你只要明白:一个物理扇区里可以装入8个文件扇区,就可以了。

出0入20汤圆

发表于 2014-4-7 20:16:03 | 显示全部楼层
zc_jky 发表于 2014-4-7 18:56
兄弟是不是文件系统支持4096但是实际上还是得按512进行写操作?这是这个文件系统的缺陷么? ...

一个物理扇区可以4K-8K-16K----256K ,与文件系统一个扇区512字节是2吗事。STM32F20X的片子flash后面全是128K一个扇区,我们同样可以格式化一个很小的硬盘,通过USB接口让电脑识别,然后下文件进去。

出0入20汤圆

发表于 2014-4-7 20:19:19 | 显示全部楼层
//*******************************************************************************************************
//对指定一个扇区的写入
//sect=物理扇区地址,OFFSET=物理地址偏移量,CNT是字节数!!
//返回=文件扇区数 cnt
unsigned int SST25_ONE_Sector_Wr(unsigned int sect,unsigned offset,unsigned char *buf,unsigned int cnt){
         unsigned char *p;
         p=Set_RTC_RAM(); //备份数据到rtc-ram
         FAT_Rd_Flash(sect<<12,p,4096);        //全部读出来。
        if(memcmp(&p[offset],buf,cnt)){ //数据不相等就要比较是否为0XFF!
                if(memcmp(&p[offset],(unsigned char *)MASK_FF,cnt)){ //数据不是0XFF!
                        memcpy(&p[offset],buf,cnt);    //写入数据到BUFF。
                        SaveData_To_Ram(buf,sect);   //写入2个地方RAM+fw25 ,标记由对方程序写入
                        FAT_Erase_Flash(sect);                          //删除对应的物理扇区 不是字节地址 4K
                         FAT_Wr_Flash(sect<<12,p,4096);//写一个文件扇区4096字节
                        //*************************************************************
                         //清楚标记!!!
                        Clr_RTC_ram_flag();
                 }else{//扇区里的内容是0xff可以直接写。
                         FAT_Wr_Flash((sect*4096 + offset),buf,cnt);//写一个文件扇区512字节
                }
         }
         return cnt/512; //返回文件扇区数量!
}
//**********************************************************************************************
//文件系统操作写        传入=SECT(文件扇区512个字节),CNT=扇区的个数;//从芯片的物理256扇区(256*4=1M)开始读数据】】
//=1 有错误;=0 OK
unsigned int SST25_FS_Wr_Sector(unsigned int sect,unsigned char *buf,unsigned int cnt){
         unsigned int n,Sect,offset;        //Sect=物理地址4K扇区;sect=文件扇区512字节
        
         n=0;//文件扇区的个数
        while(1){
                 buf  +=n*512;                                                        //缓存地址增加
                Sect  =(n+sect)/8;                                //确定地址,除以8 ,是4K一个扇区! //从芯片的物理256扇区(256*4=1M)开始读数据】】
                offset=(n+sect) % 8;                        //物理扇区内的文件扇区偏移量!
                n=8-offset;                                                                //单物理扇区内的剩余文件扇区的个数:0-8
                 if(cnt>n){
                         n=SST25_ONE_Sector_Wr(Sect,offset*512,buf,n*512);
                         cnt -=n;
                 }else{
                         n=SST25_ONE_Sector_Wr(Sect,offset*512,buf,cnt*512);
                         break;
                 }
         }
         return 0;
}
这2个函数,就是把文件扇区套入物理扇区的。

出0入0汤圆

发表于 2014-4-7 22:21:52 | 显示全部楼层
呵呵,跟我前一阵的问题一样,我是在官网上的例程序修改的,修改读写擦函数,数据字节数为4096,就基本没有问题了。

我现在的问题是把这个代码移植到rt-thread上就跑飞,rt-thread只要一调用USB的初始化就跑飞了。

出0入0汤圆

 楼主| 发表于 2014-4-8 08:19:52 | 显示全部楼层
labi40 发表于 2014-4-7 22:21
呵呵,跟我前一阵的问题一样,我是在官网上的例程序修改的,修改读写擦函数,数据字节数为4096,就基本没有 ...

我也是4096啊我写文件有问题呢。。

出0入0汤圆

 楼主| 发表于 2014-4-8 11:23:07 | 显示全部楼层
mon51 发表于 2014-4-7 20:19
//************************************************************************************************** ...

你好我正在移植你的代码请问这个 extern FLASH_INFO   FLASH_info; 在哪里初始化的。还有  SaveData_To_Ram(buf,sect);   Get_Data_To_Flash (); 函数有何作用?

出0入0汤圆

 楼主| 发表于 2014-4-8 11:35:20 | 显示全部楼层
mon51 发表于 2014-4-7 20:19
//************************************************************************************************** ...

大神能否 付费帮我移植一下你的层转化。。我实在搞不定了。。

出0入0汤圆

发表于 2014-4-8 12:59:53 | 显示全部楼层
都是高手啊!

出0入20汤圆

发表于 2014-4-8 16:43:34 | 显示全部楼层
zc_jky 发表于 2014-4-8 11:23
你好我正在移植你的代码请问这个 extern FLASH_INFO   FLASH_info; 在哪里初始化的。还有  SaveData_To_R ...

FLASH_INFO   FLASH_info   初始化FLASH芯片的空间的,并不需要整片做文件系统,可以留出一些做系统参数保存用。
SaveData_To_RAM  
这是把一个4k的物理扇区数据全部存入RAM,保护起来。一般用RTC-RAM即可,也可用RAM,但要考虑正好删除了一个物理扇区,还没有回写完,就停电了。则数据损坏的情况。F103的片子最好用一片铁电FLASH。F20X以上的可以用RTC-RAM 正好4K。
程序全部给你了,不需要什么付费!

出0入0汤圆

 楼主| 发表于 2014-4-8 18:46:55 | 显示全部楼层
mon51 发表于 2014-4-8 16:43
FLASH_INFO   FLASH_info   初始化FLASH芯片的空间的,并不需要整片做文件系统,可以留出一些做系统参数 ...

谢谢热心的网友,但是为何我移植上你的代码 读取文件虽然可以,但是写入文件还是会乱码~文本丢失,文件系统崩溃。。。。

出0入0汤圆

 楼主| 发表于 2014-4-9 09:11:36 | 显示全部楼层
mon51 发表于 2014-4-8 16:43
FLASH_INFO   FLASH_info   初始化FLASH芯片的空间的,并不需要整片做文件系统,可以留出一些做系统参数 ...

问题解决了,fatfs 文件系统的4096读写底层是没问题的,问题出在,USB如果在与电脑连接的时候 此时调用fatfs的写入函数 会导致文本的乱码,U盘崩溃,等情况。再次还是感谢论坛的各个网友

出0入0汤圆

发表于 2014-4-10 20:47:55 | 显示全部楼层
zc_jky 发表于 2014-4-9 09:11
问题解决了,fatfs 文件系统的4096读写底层是没问题的,问题出在,USB如果在与电脑连接的时候 此时调用fat ...

我也遇到你同样的问题,请问你是怎么解决的?

出0入0汤圆

 楼主| 发表于 2014-4-11 07:48:37 | 显示全部楼层
黑暗深处 发表于 2014-4-10 20:47
我也遇到你同样的问题,请问你是怎么解决的?

在用fatfs写 spiflash关闭USB使能,就好了。

出0入0汤圆

发表于 2014-4-11 08:05:24 | 显示全部楼层
很好,正准备用呢

出0入0汤圆

发表于 2014-4-13 10:11:51 | 显示全部楼层
zc_jky 发表于 2014-4-11 07:48
在用fatfs写 spiflash关闭USB使能,就好了。

请问在用fatfs写 spiflash关闭USB使能你调用的是哪个关闭函数?我关闭USB时钟、强制USB下电后还是一样U盘崩溃

出0入0汤圆

 楼主| 发表于 2014-5-19 12:42:47 | 显示全部楼层
黑暗深处 发表于 2014-4-13 10:11
请问在用fatfs写 spiflash关闭USB使能你调用的是哪个关闭函数?我关闭USB时钟、强制USB下电后还是一样U盘 ...

关闭usb的连接,在电路里留了一个使能io 即usb_DP

出0入0汤圆

发表于 2014-5-19 15:22:00 | 显示全部楼层
mark      

出0入0汤圆

发表于 2015-8-7 17:30:00 | 显示全部楼层
为何我读取文件总是出现FR_NO_FILESYSTEM

出0入0汤圆

发表于 2016-5-1 14:59:36 | 显示全部楼层
标记 学习...

出0入0汤圆

发表于 2016-5-5 15:47:40 | 显示全部楼层
mon51 发表于 2014-4-5 16:34
#ifndef __sst25vf_FLASH_H
#define __sst25vf_FLASH_H                        
//SST25VF016读写

我遇到的一个问题,求指点http://www.amobbs.com/thread-5649930-1-1.html

出0入0汤圆

发表于 2016-5-5 15:49:02 | 显示全部楼层
果断MARK了

出0入0汤圆

发表于 2016-5-6 07:27:39 | 显示全部楼层
标记 学习......

出0入0汤圆

发表于 2016-5-31 22:50:13 | 显示全部楼层

前辈,请教几个问题:
1、在SPI Flash上的fatfs速度怎么样?
2、您的代码在写的流程是都是扇区对齐的,而且是直接擦出就写,fatfs能不保证对齐访问?如果扇区中有需要的保留的数据fatfs在调用写之前是否已读取保留的数据(flash特性:读-改-擦-写)?
3、您是否使用过Keil 官方自带的RL-FlashFS 速度能到2MByte/S,它的读写是非对齐的,不过我移植的删除大文件时小文件也跟着被删除了,不知道什么原因?

出0入0汤圆

发表于 2016-6-1 09:23:39 | 显示全部楼层

学习了!

出0入0汤圆

发表于 2016-6-22 22:33:43 | 显示全部楼层
正好需要这个功能,学习下

出0入0汤圆

发表于 2016-6-23 10:02:22 | 显示全部楼层
学习了,讲的太精彩

出0入0汤圆

发表于 2017-10-19 12:02:16 | 显示全部楼层
mark!!!!!!!!!!!!!!!!!

出0入0汤圆

发表于 2019-5-10 22:26:50 | 显示全部楼层
经典案例 值得学习,
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-26 12:23

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表