STM32读取dht11温湿度变量写入SD卡(SPI模式)

1.实验工具

  1. STM32f103RCT6板子
  2. Dht11温湿度传感器
  3. 外接SD卡模块(淘宝都差不多)

2.接线说明

1.SD卡模块,采用SPI1接线
(CLK)SCK <—>PA5
(DATA0)MISO <—>PA6
(CMD)MOSI <—>PA7
(DATA3)CS <—>PA4
VCC <—> 3.3V
前面小括号里的是SDIO模式的接线,可以忽略。
2.DHT11模块
DATA <—>PC7
可以自己选择任意IO口,代码对应就行。

3.部分代码说明

代码是在野火的SD卡测试代码上更新修改的,所以接口初始化啥的直接参考野火或者其它的就可以,主要写一下读取变量写入SD卡的实现。

1.文件的覆盖问题

刚开始移植野火代码是,每次写入的数据总是会把上一次的内容覆盖,所以这里需要注意两个问题:

1.文件系统的文件打开方式

res_sd = f_open(&fnew, "0:test.csv",FA_OPEN_ALWAYS | FA_WRITE ); 

f_open函数有三个参数,文件对象,文件名,文件打开方式,文件打开方式如下图:
在这里插入图片描述
这里英文解释很容易明白,我们选择FA_OPEN_ALWAYS模式,如果文件存在直接打开,不存在就创建。

2.移动文件初始写入指针位置

//文件对象的读写指针移动到文件结束处
	  f_lseek (&fnew,f_size (&fnew));
		printf("%lu",f_size (&fnew));

f_lseek函数移动指针,此函数用于文件指针的移动,共有两个参数,第一个参数为文件对象,第二个参数为移动的字节数。 f_size函数获取文件字节大小。

完成这两个才可以保证下一次的写入数据是接着之前写入。

2.变量的转换及写入问题

1.因为SD卡只能写入字符串类型,所以采集的变量数据必须先转换为字符串,然后再进行写入操作即可,要将变量数据转换为字符串,就用到了sprintf函数。

1.sprintf函数

Sprintf函数具体形式: int sprintf( char *buffer, const char *format, [ argument,…] );
解释:整形输出 sprintf(输出数组地址,<格式字符串>,参量表……)
注:只要在printf中可以使用的格式化字符串,在sprintf都可以使用。
如:

	sprintf(buff,"%d.%d %RH,%d.%d℃\n",
	DHT11_Data.humi_int,DHT11_Data.humi_deci,
	DHT11_Data.temp_int,DHT11_Data.temp_deci);

buff为已经定义的char类型的一个字符串接收数组,将后面四个参数即温湿度的高位和低位都为整形存入buff数组,注意换行符前不要有空格,否则可能无效。

2.CSV文件创建

//创建CSV文件
	res_sd = f_open(&fnew, "0:test.csv",FA_OPEN_ALWAYS | FA_WRITE ); 
res_sd= f_write(&fnew,buff,sizeof(buff),&fnum);

在打开文件那一步创建的,与txt文件一样,只是后缀不同,写入数据时,逗号即代表下一列写入,逗号对应sprintf转换里第二个参数里几个逗号。

sprintf(buff,"%d.%d %RH,%d.%d℃\n",
				DHT11_Data.humi_int,DHT11_Data.humi_deci,
				DHT11_Data.temp_int,DHT11_Data.temp_deci);

3.文件系统函数位置(主函数代码)

读取温湿度数据,所以只有当数据读取成功后才可以进行文件的相关写入工作,在外面再加个延时函数,不要采集太频繁。

int main(void)
{
	DHT11_Data_TypeDef DHT11_Data;
	/* 初始化系统定时器 */
	SysTick_Init();

	/* 初始化调试串口,一般为串口1 */
	USART_Config();	
	/*初始化DTT11的引脚*/
	DHT11_Init ();
  
	while(1)
	{	
		char buff[20];//存储sprintf转换后的字符串

			/*调用DHT11_Read_TempAndHumidity读取温湿度,若成功则输出该信息*/
			if( DHT11_Read_TempAndHumidity ( & DHT11_Data ) == SUCCESS)
			{
				printf("\r\n读取DHT11成功!\r\n\r\n湿度为%d.%d %RH ,温度为 %d.%d℃ \r\n",
				DHT11_Data.humi_int,DHT11_Data.humi_deci,DHT11_Data.temp_int,DHT11_Data.temp_deci);
				//\n前不要有空格,否则换行符失效
				sprintf(buff,"%d.%d %RH,%d.%d℃\n",
				DHT11_Data.humi_int,DHT11_Data.humi_deci,DHT11_Data.temp_int,DHT11_Data.temp_deci);
				
				//在外部SPI Flash挂载文件系统,文件系统挂载时会对SPI设备初始化
	      res_sd = f_mount(&fs,"0:",1);
				/*----------------------- 格式化测试 ---------------------------*/  
	/* 如果没有文件系统就格式化创建创建文件系统 */
	if(res_sd == FR_NO_FILESYSTEM)
	{
		printf("》SD卡还没有文件系统,即将进行格式化...\r\n");
    /* 格式化 */
		res_sd=f_mkfs("0:",0,0);							
		
		if(res_sd == FR_OK)
		{
			printf("》SD卡已成功格式化文件系统。\r\n");
      /* 格式化后,先取消挂载 */
			res_sd = f_mount(NULL,"0:",1);			
      /* 重新挂载	*/			
			res_sd = f_mount(&fs,"0:",1);
		}
		else
		{
			LED_RED;
			printf("《《格式化失败。》》\r\n");
			while(1);
		}
	}
  else if(res_sd!=FR_OK)
  {
    printf("!!SD卡挂载文件系统失败。(%d)\r\n",res_sd);
    printf("!!可能原因:SD卡初始化不成功。\r\n");
		while(1);
  }
  else
  {
    printf("》文件系统挂载成功,可以进行读写测试\r\n");
  }
	
	/*----------------------- 文件系统测试:写测试 -----------------------------*/
	/* 打开文件,如果文件不存在则创建它 */
	printf("\r\n****** 即将进行文件写入测试... ******\r\n");	
	//注意f_open第三个参数,打开文件模式设置要注意
	//创建CSV文件
	res_sd = f_open(&fnew, "0:test.csv",FA_OPEN_ALWAYS | FA_WRITE );   
	if ( res_sd == FR_OK )
	{
		printf("》打开/创建test.csv文件成功,向文件写入数据。\r\n");
		//文件对象的读写指针移动到文件结束处
	  f_lseek (&fnew,f_size (&fnew));
		printf("%lu",f_size (&fnew));
		 
    /* 将指定存储区内容写入到文件内 */
		res_sd= f_write(&fnew,buff,sizeof(buff),&fnum);
    if(res_sd==FR_OK)
    {
      printf("》文件写入成功,写入字节数据:%d\n",fnum);
    }
    else
    {
      printf("!!文件写入失败:(%d)\n",res_sd);
    }    
		/* 不再读写,关闭文件 */
    f_close(&fnew);
		f_mount(NULL,"0:",1);
	}
	else
	{	
		LED_RED;
		printf("!!打开/创建文件失败。\r\n");
	}
			}			
			else
			{
				printf("Read DHT11 ERROR!\r\n");
			}
			printf("等待下一次记录");
		 Delay_ms(5000);
	}
	
}

4.数据采集结果

在这里插入图片描述

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

无敌最俊朗-

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值