SD卡+FATFS文件系统实时存储采集到的温湿度值

(部分代码借鉴原子哥的STM32Mini开发板)

SD卡一般支持两种读写模式,SPI和SDIO模式,SD卡的引脚排序如下图所示。

 

SPI模式下有几个重要的操作命令,分别是:

 

SD卡R1回应的格式如下

#include "led.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "lcd.h"
#include "key.h"
#include "usmart.h" 
#include "malloc.h"  
#include "MMC_SD.h" 
#include "ff.h"  
#include "exfuns.h"
#include "rtc.h" 
#include "diskio.h" 
#include "integer.h" 
#include "ffconf.h" 

#include "stdint.h"
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
//int类型转换为string类型
//Int_i:	  要转换的int类型
//String_s:转换后的string类型
void Int_To_Str(int Int_i,char *String_s)
{
	int a;
	int b= 0;	 								//用于计数
	char *ptrfing,pBuffer[5];	//定义一个字符串数组和字符串指针,
	ptrfing = String_s; 			//内部指针指向外部指针,进行参数传递,是属于源参数传递(通过地址),
	if(Int_i< 10)		  				// 当整数小于10,转换为0x格式
	{
		*ptrfing ++ = '0'; 			//单个数字前面补0
		*ptrfing ++ =Int_i+0x30;
	}
	else
	{
		while(Int_i> 0)
		{
			a= Int_i% 10;
			Int_i=Int_i/ 10;
			pBuffer[b++] =a+0x30;	// 通过计算把数字编成ASCII码形式
		}
		b-- ;
		for(;b>= 0;b--) 		// 将得到的字符串倒序
		{
			*(ptrfing++) = pBuffer[b];
		}
	}
	*ptrfing = '\0';
}
int main(void)
{ 
	FIL fdst; 
	u8 res;
	FRESULT fr;
	
	//存放转换类型后的日期和时间和次数
	char w_year_s[6];
	char w_month_s[2];
	char w_date_s[2];
	char hour_s[2];
	char min_s[2];
	char sec_s[2];
	char Numa_s[1];
	short Numa=0; 
	//存放采集的数据
	char enter_s[2]={"50"};	//进
	char out_s[2]={"18"};			//出
	char plate_s[2]={"20"};//盘子
	char air_s[2]={"15"};	
	char humidity_s[2]={"70"};//湿度	
	u8 key=0;
 	u32 total,free;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2 
	delay_init();	    	 //延时函数初始化	  
	uart_init(9600);	 	//串口初始化为9600
 	exfuns_init();		//为fatfs相关变量申请内存				 
	LCD_Init();			//初始化液晶 
	LED_Init();         //LED初始化	 													    
	usmart_dev.init(72);	
 	mem_init();			//初始化内存池	
	KEY_Init();				//按键初始化
	 
 	POINT_COLOR=RED;//设置字体为红色	   	    
	while(RTC_Init())		//RTC初始化	,一定要初始化成功
	{ 
		LCD_ShowString(60,30,200,16,16,"RTC ERROR!   ");	
		delay_ms(800);
		LCD_ShowString(60,30,200,16,16,"RTC Trying...");	
	}		    						
	//显示时间
	POINT_COLOR=BLUE;//设置字体为蓝色					 
	LCD_ShowString(60,30,200,16,16,"    -  -     ");	   
	LCD_ShowString(60,62,200,16,16,"  :  :  ");	
	
	while(SD_Initialize())					//检测SD卡
	{
		LCD_ShowString(60,150,200,16,16,"SD Card Error!");
		delay_ms(200);
		LCD_Fill(60,150,240,150+16,WHITE);//清除显示			  
		delay_ms(200);
		LED0=!LED0;//DS0闪烁
	}
 	exfuns_init();							//为fatfs相关变量申请内存				 
  f_mount(fs[0],"0:",1); 					//挂载SD卡 
 	f_mount(fs[1],"1:",1); 					//挂载FLASH.	  
	while(exf_getfree("0",&total,&free))	//得到SD卡的总容量和剩余容量
	{
		LCD_ShowString(60,150,200,16,16,"Fatfs Error!");
		delay_ms(200);
		LCD_Fill(60,150,240,150+16,WHITE);//清除显示			  
		delay_ms(200);
		LED0=!LED0;//DS0闪烁
	} 
 	POINT_COLOR=BLUE;//设置字体为蓝色	   
	LCD_ShowString(60,150,200,16,16,"FATFS OK!");	 
	LCD_ShowString(60,170,200,16,16,"SD Total Size:     MB");	 
	LCD_ShowString(60,190,200,16,16,"SD  Free Size:     MB"); 	    
 	LCD_ShowNum(172,170,total>>10,5,16);					//显示SD卡总容量 MB
 	LCD_ShowNum(172,190,free>>10,5,16);						//显示SD卡剩余容量 MB	

	res=f_open (&fdst,"0:/采集数据.txt",FA_OPEN_ALWAYS |FA_WRITE); //新建文件和写操作
	res = f_puts ( "开始采集温度:\r\n\r\n\r\n\r\n", &fdst);  //从文件内数据的最后写入字符串
	f_close(&fdst);			//关闭文件,必须和 f_open 函数成对出现
	
	while(1)
	{

		//日期 时间
		LCD_ShowNum(60,30,calendar.w_year,4,16);									  
		LCD_ShowNum(100,30,calendar.w_month,2,16);									  
		LCD_ShowNum(124,30,calendar.w_date,2,16);	 

		LCD_ShowNum(60,62,calendar.hour,2,16);									  
		LCD_ShowNum(84,62,calendar.min,2,16);									  
		LCD_ShowNum(108,62,calendar.sec,2,16);

		
		key=KEY_Scan(0);
		switch(key)
		{				 
			case KEY0_PRES: 		//按下了key0,就存储采集到的数据
				fr=f_open (&fdst,"0:/采集数据.txt",FA_WRITE); //写操作 
				if(fr==FR_OK)//判断是否正确打开
				{
					for(Numa=1;Numa<=300;Numa++)		 //采集并存储5次
					{
						Int_To_Str(calendar.w_year,w_year_s);//类型转换
						Int_To_Str(calendar.w_month,w_month_s);//类型转换
						Int_To_Str(calendar.w_date,w_date_s);//类型转换
						Int_To_Str(calendar.hour,hour_s);//类型转换
						Int_To_Str(calendar.min,min_s);//类型转换
						Int_To_Str(calendar.sec,sec_s);//类型转换
						Int_To_Str(Numa,Numa_s);//类型转换
						
						delay_ms(20);			 //每隔50ms写入一次
						res= fdst.fsize;   //获得文件大小		
						f_lseek(&fdst,f_size(&fdst));  //移动文件指针
						
						res=f_puts ( Numa_s, &fdst);  
						res=f_puts ( " ", &fdst);  		
						res=f_puts ( w_year_s, &fdst);
						res=f_puts ( "-", &fdst);  		
						res=f_puts ( w_month_s, &fdst);
						res=f_puts ( "-", &fdst);  		
						res=f_puts ( w_date_s, &fdst);
						res=f_puts ( " ", &fdst);  		
						res=f_puts ( hour_s, &fdst);  
						res=f_puts ( ":", &fdst);  		
						res=f_puts ( min_s, &fdst);  	
						res=f_puts ( ":", &fdst);  		
						res=f_puts ( sec_s, &fdst);  	
						res=f_puts ( "     ", &fdst);
						res=f_puts ( "进水:", &fdst);  //从文件内数据的最后写入字符串
						res=f_puts ( enter_s, &fdst);  //从文件内数据的最后写入字符串
						res=f_puts ( "℃ ", &fdst);  //从文件内数据的最后写入字符串
						res=f_puts ( "出水:", &fdst);  		//从文件内数据的最后写入字符串
						res=f_puts ( out_s, &fdst);  //从文件内数据的最后写入字符串
						res=f_puts ( "℃ ", &fdst);  //从文件内数据的最后写入字符串
						res=f_puts ( "Air:", &fdst);  		//从文件内数据的最后写入字符串
						res=f_puts ( air_s, &fdst);  //从文件内数据的最后写入字符串
						res=f_puts ( "℃ ", &fdst);  //从文件内数据的最后写入字符串
						res=f_puts ( humidity_s, &fdst);  //从文件内数据的最后写入字符串
						res=f_puts ( "%rh ", &fdst);  //从文件内数据的最后写入字符串
						res=f_puts ( "平均:", &fdst);//从文件内数据的最后写入字符串
						res=f_puts ( plate_s, &fdst);  //从文件内数据的最后写入字符串
						res=f_puts ( "℃\r\n", &fdst);  //从文件内数据的最后写入字符串
						res=f_sync(&fdst);					//冲洗缓冲数据
						LCD_ShowNum(172,210, Numa,5,16);//显示第几次
					
					}
				}
				f_close (&fdst);	//关闭文件
				LED0=!LED0;	    
				break;
			case KEY1_PRES: 
				LED0=!LED0;
				break;
			case WKUP_PRES: 
				f_unlink("0:/采集数据.txt");   //删除文件	
				LED0=!LED0;
				break;
			default:
				delay_ms(10);
		}
		delay_ms(100);				
		LED0=!LED0;
	} 
}

2. 按Key0存储数据:

3.在PC端打开采集数据的SD卡

 

 

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 技术黑板 设计师: CSDN官方博客
应支付0元
点击重新获取
扫码支付

支付成功即可阅读