你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

关于FATFS写操作的问题

[复制链接]
meixu 提问时间:2017-6-11 21:21 /
悬赏10ST金币未解决
关于fatfs文件写操作,有个小问题困扰我很长时间了,请教一下

      f_open(&MyFile, (char *)Node, FA_WRITE);
      f_write(&MyFile, UID, 5, (void *)&byteswritten);
      f_write(&MyFile, ID,  9, (void *)&byteswritten);  
      f_write(&MyFile, Msg, 9, (void *)&byteswritten);  
      f_write(&MyFile, &myGPS, 39, (void *)&byteswritten);  
      f_write(&MyFile, "\r\n", 2, (void *)&byteswritten);            
      f_close(&MyFile);
      f_open(&MyFile, (char *)Node, FA_WRITE);
      f_lseek(&MyFile,f_size(&MyFile));

      f_write(&MyFile, UID, 5, (void *)&byteswritten);
      f_write(&MyFile, ID,  9, (void *)&byteswritten);  
      f_write(&MyFile, Msg, 9, (void *)&byteswritten);  
      f_write(&MyFile, &myGPS, 39, (void *)&byteswritten);  
      f_write(&MyFile, "\r\n", 2, (void *)&byteswritten);            
      f_close(&MyFile);

其实我主要是想用f_lseek函数,关闭文件之后下次再写时从结尾开始写,但是我才用上面的方法测试了好几遍,关闭文件前的内容能写进去,但是关闭之后再打开怎么也写不进去,调试时我在每行语句前加了res=  ,来看res,都返回FR_OK,但是U盘里没有后面的内容,请问是什么情况?
Node="0:/BJUT/TEST.TXT"

收藏 评论11 发布时间:2017-6-11 21:21

举报

11个回答
Taonsh 回答时间:2017-6-11 21:39:12
本帖最后由 taonsh 于 2017-6-11 21:43 编辑

查一下f_size(&MyFile)是多少?还有你写的东西宏定义还是啥,没看到。
奏奏奏 回答时间:2017-6-12 09:42:39
这是我项目中相关的参考代码:
  1.                         res_debug= f_open(&fsrc3,"历史.csv",FA_OPEN_EXISTING | FA_WRITE);
  2.                         res_debug=f_lseek(&fsrc3,fsrc3.fsize);
  3.                         res_debug=f_write(&fsrc3,"16/08/03 06:26:36,1234567890,阳性,0.777\r\n17/08/03 06:26:36,1234567890,阳性,0.777\r\n18/08/03 06:26:36,1234567890,阳性,0.777\r\n",123,&bw);
复制代码
我觉得你可以消化一下
先用f_open打开
再用f_lseek找到并定位到文件尾部,注意fsrc3.fsize这个输入形参
然后就可以f_write将数据写到文件尾部接着了
meixu 回答时间:2017-6-12 10:39:03
taonsh 发表于 2017-6-11 21:39
查一下f_size(&MyFile)是多少?还有你写的东西宏定义还是啥,没看到。

不是宏定义,那是字符数组的名字
meixu 回答时间:2017-6-12 10:58:10
第一张图片是我调试时的截图,我每次写64个字节,f_size是对的,两个就是128个字节,0x80,第二张图是我U盘的截图,可以看到只有第一次写的64个字节,第二次写的就没有。
123.png
456.png
奏奏奏 回答时间:2017-6-12 11:15:20
打包一个工程你自己看一下吧

我觉得关键在于:f_open(&fsrc3,"历史.csv",FA_OPEN_EXISTING | FA_WRITE)
这里形参要多加一个 FA_OPEN_EXISTING |
因为可能如果不加这个,就会每次都新建一个这个文件

高速写入CSV与XLS表格测试DEMO金龙板.zip

下载

3.51 MB, 下载次数: 1898, 下载积分: ST金币 -1

meixu 回答时间:2017-6-12 16:48:51
奏奏奏 发表于 2017-6-12 11:15
打包一个工程你自己看一下吧

我觉得关键在于:f_open(&fsrc3,"历史.csv",FA_OPEN_EXISTING | FA_WRITE)

嗯嗯,我在官方的例程中试了试,关闭之后能写进去,但是这段程序一到我自己的工程中就不行了,不知道哪儿出了点问题,我再看看。
chinacool 回答时间:2017-6-13 09:45:41
你第二次打开的模式可能不对,试下 f_open(&MyFile, (char *)Node, FA_WRITE|FA_READ);   
以只写的方式打开,是先把内容清空,然后再写吧。PC上是这样,FATFS 上不知道是不是这样,我是没有遇到 过。
我是这么做的:
fr = f_open(&file, pathbuf, FA_OPEN_EXISTING|FA_WRITE|FA_READ);     

连续打开写入关闭 30次不会有问题
chinacool 回答时间:2017-6-13 09:50:58
下面这个函数中也用到了f_lseek 函数

/*********************************************************************************
向指定文件中添加一条记录
返回值: 0 成功,1 失败
*********************************************************************************/
u8 write_record(record_t *record, u8 wtype, u8 n)
{
    u8 res = 0;

    char *path="0:";
    char pathbuf[48];
    //float dat;
    u32 wr;
   
    FRESULT fr;
    FIL file;  

    if( (record->date.year < 2017 || record->date.year > 2026) ||
        (record->date.mon < 1 || record->date.mon > 12) ||
        (record->date.day < 1 || record->date.day > 31))
    {
        Printf("ERROR: write_record 记录日期错误\r\n");
        return 2;
    }

    memset(pathbuf, 0, sizeof(pathbuf));

    switch(wtype)
    {
        case RECORD_TYPE_YEAR: //年记录
            sprintf(pathbuf, "%s/%d/year.re", path, record->date.year);
            break;
        case RECORD_TYPE_MON:
            sprintf(pathbuf, "%s/%d/%d/mon.re", path,record->date.year, record->date.mon);
            break;
        case RECORD_TYPE_DAY:
            sprintf(pathbuf, "%s/%d/%d/day%d.re", path, record->date.year, record->date.mon, record->date.day);
            break;
        default:
            break;
    }

    //return 0;

    fr = f_open(&file, pathbuf, FA_OPEN_EXISTING|FA_WRITE|FA_READ);        
    if (fr == FR_OK)
    {
        Printf("f_open  %s OK \r\n", pathbuf );  

        //写入内容 -- 24小时,第0条写入日累计数据,共25条数据
        switch(wtype)
        {
            case RECORD_TYPE_YEAR: //年记录
                #if 1
                f_lseek(&file, n*4);
                fr = f_write(&file, &record->yearflow[n], 4, &wr);         

                if (fr == FR_OK)
                {
                    Printf("year: write_record %d,%.2f, %d byte \r\n", n,record->yearflow[n], wr);  
                    res = 0;
                }
                else
                {         
                    Printf("write_record failed(year)!!\r\n");
                                        res = 4;
                }  

                #else  //PC上需要这样做
                dat = record->yearflow[n];
                fread(record->yearflow , sizeof(record->yearflow[0]) , 13 , pFile );
                record->yearflow[n] = dat;
                fwrite(&record->yearflow[n] , sizeof(record->yearflow[n]) , 13 , pFile );
                #endif
                break;
            case RECORD_TYPE_MON: //月记录
                #if 1
                f_lseek(&file, n*4);
                fr = f_write(&file, &record->monflow[n], 4, &wr);         

                if (fr == FR_OK)
                {
                    Printf("mon: write_record %d,%.2f, %d byte \r\n", n,record->monflow[n], wr);  
                    res = 0;
                }
                else
                {         
                    Printf("write_record failed(mon)!!\r\n");
                                         res = 3;
                }  
                #else //PC上需要这样做
                dat = record->monflow[n];
                fread(record->monflow , sizeof(record->monflow[0]) , 32 , pFile );
                record->monflow[n] = dat;
                fwrite(record->monflow , sizeof(record->monflow[0]) , 32 , pFile );
                #endif
                break;
            case RECORD_TYPE_DAY:// 日记录
                #if 1
                f_lseek(&file, n*4);
                fr = f_write(&file, &record->dayflow[n], 4, &wr);         

                if (fr == FR_OK)
                {
                    Printf("day: write_record %d,%.2f, %d byte \r\n", n,record->dayflow[n], wr);  
                    res = 0;
                }
                else
                {         
                    Printf("write_record failed(day)!!\r\n");
                                         res = 2;
                }
                #else //PC上需要这样做
                dat = record->dayflow[n];
                fread(record->dayflow , sizeof(record->dayflow[0]) , 25 , pFile );
                record->dayflow[n] = dat;
                fwrite(record->dayflow , sizeof(record->dayflow[0]) , 25 , pFile );
                #endif // 0
                break;
            default:
                                res = 5;
                break;
        }

        f_close(&file);   
    }
    else
    {
        Printf("f_open %s failed\r\n", pathbuf);  
        res = 1;
    }
   
    return res;
}
meixu 回答时间:2017-6-15 15:52:05
bwu 发表于 2017-6-13 09:45
你第二次打开的模式可能不对,试下 f_open(&MyFile, (char *)Node, FA_WRITE|FA_READ);   
以只写的方式打 ...

试了试,不是这的问题,如上楼所言,我在别的工程里是没有问题的,不知道问什么在现在的工程里就有问题,还得再找找是怎么回事。
IZ 回答时间:2017-6-16 22:13:34
试试把这个FIL file;定义成全局变量
zyzyxj 回答时间:2019-3-12 16:11:19
奏奏奏 发表于 2017-6-12 11:15
打包一个工程你自己看一下吧

我觉得关键在于:f_open(&fsrc3,"历史.csv",FA_OPEN_EXISTING | FA_WRITE)

请问在实际应用中open,write,sync与close怎么使用,现在需要持续的写文件,但是不断的open操作及sync操作太占资源,导致别的任务出错,所以选择只open一次,然后不断的写,这样会有个问题,什么时候close文件实现保存。想了解下大家在实际工程中是怎么操作的

所属标签

相似问题

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版