STM32通过FatFs实现时间存储

实验要求:每1s输出一次最新RTC时间。定时把RTC时间存入到FLASH中,当系统重新启动后,能够恢复FLASH中的RTC时间,继续进行计时。
项目下载地址:https://pan.baidu.com/s/1NGh6u9MMCn_9fhaP8DopKg 提取码:whv6
实验思路:系统上电后先读取fatfs文件信息,当读到time标志后将后面的时间数据提取出来进行解析并赋值给my_sTime和my_sDate,如果没有读到time标志则认为fatfs数据不可用 并给my_sTime和my_sDate赋默认值,进入主循环后获取当前时间并输出,然后将当前信息存储到SD卡中,延时1s。
主函数中代码较多,所以讲挂载、格式化、读磁盘状态、读文件、写文件的相应代码分别封装成函数以便使用
函数详解:
写文件:

void file_write(uint8_t res, FIL *pf, RTC_TimeTypeDef *my_sTime, RTC_DateTypeDef *my_sDate)
{

  res = f_open(pf, "0:/test.txt", FA_OPEN_ALWAYS | FA_WRITE);
  if (res == FR_OK)
  {
    printf("creat ok\n"); 				
  }
  else
  {
    printf("creat failed\n");
    printf("error code: %d\n",res);	
  }
  
//	char tr1[]="1234567890abc!\n";
		f_printf(pf, "time%d-%d-%d    %d:%d:%d*",my_sDate->Year, my_sDate->Month, my_sDate->Date, my_sTime->Hours, \
		my_sTime->Minutes, my_sTime->Seconds);		//	格式化输出
		//f_printf(pf, "0000000000000000000000000000000000000000000000000000");
		res = f_close(pf);
    if (res != FR_OK)
    {
      printf("close file error\n");
      printf("error code: %d\n",res);				
    }
		else
		{
		//		printf("write data OK");
		}
}

将时间数据格式化写入SD卡,并在数据前加上time作为标志。
读文件:

uint8_t *file_read(uint8_t res, FIL *file, uint8_t num)
{
		//FIL file;
  //FRESULT res;
  unsigned int bw;
  uint8_t static rbuf[100] = {0};
  
  res = f_open(file, "0:/test.txt", FA_READ);
  if (res != FR_OK)
  {
    printf("open error: %d\n",res);
  }
	else
	{
		f_read(file, rbuf, num, &bw);
		
		printf("read data:%s\n", rbuf);
  
		res = f_close(file);
		if (res != FR_OK)
		{
     printf("close file error\n");
     printf("error code: %d\n",res);				
		}
	}
	return rbuf;
}

传入参数新增num,用来控制读取几个字节数据。

时间字符串解析:

void fuckme(uint8_t *buf)
{
	int i = 5;
	while(buf[i] != '-' && buf[i] != ':')
		i++;
	year = (buf[i-2]-0x30)*10 + (buf[i-1]-0x30);
	i++;
	while(buf[i] != '-' && buf[i] != ':')
		i++;
	if(buf[i-2] == '-' || buf[i-2] == ':')
		month = (buf[i-1]-0x30);
	else
		month = (buf[i-2]-0x30)*10 + (buf[i-1]-0x30);
	if(buf[i+2] == 0x20)
		date = (buf[i+1]-0x30);
	else
		date = (buf[i+1]-0x30)*10 + (buf[i+2]-0x30);
	i++;
	while(buf[i] != '-' && buf[i] != ':')
		i++;
	if(buf[i-2] == '-' || buf[i-2] == ':' || buf[i-2] == 0x20)
		hour = (buf[i-1]-0x30);
	else
		hour = (buf[i-2]-0x30)*10 + (buf[i-1]-0x30);
	i++;
	while(buf[i] != '-' && buf[i] != ':')
		i++;
	if(buf[i-2] == '-' || buf[i-2] == ':')
		minutes = (buf[i-1]-0x30);
	else
		minutes = (buf[i-2]-0x30)*10 + (buf[i-1]-0x30);
	if(buf[i+2] == '*')
		seconds = (buf[i+1]-0x30);
	else
		seconds = (buf[i+1]-0x30)*10 + (buf[i+2]-0x30);
}

在SD卡中有时间数据的情况下将读到的数据进行解析,这块代码有些繁琐,有更好的方法请教教我。
主函数逻辑:

	rebuf = file_read(res, &file, 4);  
	if (!strcmp(rebuf, "time"))
	{
		f_read(&file, rbuf, 25, &bw);
		fuckme(rbuf);	
		RTC_init(hour, minutes, seconds, 1, date, month, year);
	}
	else
		RTC_init(1,1,1,1,1,1,19);
	while (1)
  {	
		RTC_TimeTypeDef my_sTime;
   		RTC_DateTypeDef my_sDate;
		HAL_RTC_GetTime(&hrtc,&my_sTime,RTC_FORMAT_BIN);
		printf("%d:%d:%d    ",my_sTime.Hours,my_sTime.Minutes,my_sTime.Seconds);
		HAL_RTC_GetDate(&hrtc,&my_sDate,RTC_FORMAT_BIN);
		printf("%d-%d-%d\n",my_sDate.Year,my_sDate.Month,my_sDate.Date);
		file_write(res, pf, &my_sTime, &my_sDate);
		
		HAL_Delay(1000);
    /* USER CODE BEGIN 3 */

  }

这块为了方便理解,我把和逻辑无关的代码都去掉了(只是为了更好理解,程序中必须写全)。先读4个字节并判断是不是“time”,是的话再从头读25个字节,通过fuckme函数解析数据(解析好的数据在函数中已经赋值给hour、minuts…)调用时钟初始化函数。否则将时间修改为默认值19-1-1 1:1:1。在while循环内疯狂获取时间、输出时间、向SD卡写入时间数据、延时1s。
实验效果
当SD卡中没有时间数据时:
在这里插入图片描述
当SD卡中有时间数据时:
在这里插入图片描述
项目的实现和实验要求并非完全相同,项目代码还需稍加修改。

原文地址: https://www.jhxblog.cn/article/?articleid=6

  • 3
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

举个锤子²³³³

有钱的捧个钱场,没钱的借去

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值