基于IIC和SPI协议的温湿度采集

一、认识I2C协议

(1)软件I2C协议:
直接使用 CPU 内核按照 I2C 协议的要求控制 GPIO 输出高低电平,从而模拟I2C。

(2)硬件I2C协议:
对应 STM32 芯片中的硬件 I2C 外设,有相应的I2C驱动电路,其所使用的I2C管脚也是专用。

(3)两者的区别:
所谓硬件I2C对应芯片上的I2C外设,有相应I2C驱动电路,其所使用的I2C管脚也是专用的;软件I2C一般是用GPIO管脚,用软件控制管脚状态以模拟I2C通信波形。
硬件I2C的效率要远高于软件的,而软件I2C由于不受管脚限制,接口比较灵活。
模拟I2C 是通过GPIO,软件模拟寄存器的工作方式,而硬件(固件)I2C是直接调用内部寄存器进行配置。

二、了解AHT20温湿度传感器

本次实验所使用的AHT20温湿度传感器:
在这里插入图片描述
1、相关参数:
GND 地线
SCL I2C通信模式时钟信号,双向
SDA I2C通信模式数据信号,双向
NC 保持悬空

2、温湿度测量范围:
温度范围为: 测量范围为 -40 ℃ ~+ 85 ℃ 精度±0.3℃,转化如下图:
在这里插入图片描述
湿度范围为:测量范围为0% - 100% 精度为±2%RH,转化如下图:
在这里插入图片描述
3、通讯方式:
采用I2C的接口方式 ,i2c通讯方式:SCL --> 时钟线、SDI --> 数据线

4、优点:
(1)高精度,完全校准
(2)极高的可靠性与卓越的长期稳定性(较上一代aht10有 极大的提升)
(3)抗干扰能力强
(4)性价比极高
(4)适用于恶劣的环境条件下

三、使用STM32F103完成基于I2C协议的AHT20温湿度传感器的数据采集

1.完成接线

在这里插入图片描述
本次实验中本人的接线如下:

AHT20 STM32
VDD 3.3V
GND GND
SCL B0
SDA B1

截图效果如下图:
在这里插入图片描述

2、代码实现

main.c
#include "stm32f10x.h"                  // Device header
#include "AHT20-21_DEMO_V1_3.h"
#include "Serial.h"

int main(void)
{
   
    uint32_t CT_data[2];
	volatile int  c1,t1;
	float c,t;
	/***********************************************************************************/
	/**///上电初始化SDASCLIO/***********************************************************************************/
	Init_I2C_Sensor_Port();
	/***********************************************************************************/
	/**///①刚上电,产品芯片内部就绪需要时间,延时100~500ms,建议500ms
	/***********************************************************************************/
	Delay_1ms(500);
	/***********************************************************************************/
	/**///②上电第一次发0x71读取状态字,判断状态字是否为0x18,如果不是0x18,进行寄存器初始化
	/***********************************************************************************/
	if((AHT20_Read_Status()&0x18)!=0x18)
	{
   
	AHT20_Start_Init(); //重新初始化寄存器
	Delay_1ms(10);
	}
	Serial_Init();
	/***********************************************************************************/
	/**///③根据客户自己需求发测量命令读取温湿度数据,当前while1)循环发测量命令读取温湿度数据,仅供参考
	/***********************************************************************************/
	while(1)
	{
   
		// AHT20_Read_CTdata(CT_data);       //不经过CRC校验,直接读取AHT20的温度和湿度数据    推荐每隔大于1S读一次
		AHT20_Read_CTdata_crc(CT_data);  //crc校验后,读取AHT20的温度和湿度数据 
		

		 c1 = CT_data[0]*100*10/1024/1024;  //计算得到湿度值c1(放大了10倍)
		 t1 = CT_data[1]*200*10/1024/1024-500;//计算得到温度值t1(放大了10倍)
		 c=c1/10.0;
		 t=t1/10.0;
		
		下一步客户处理显示数据,
		/***********************************************************************************/
		/**///延时2s
		/***********************************************************************************/
		Delay_1ms(4000);
		printf("温度:%.3f\n",t);
		printf("湿度:%.3f\n",c);
	 }

 }	

Interface.c
#include "stm32f10x.h"                  // Device header
#include <stdio.h>
#include <stdarg.h>

uint8_t Interface_RxData;
uint8_t Interface_RxFlag;

void Interface_Init()
{
   
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);	//打开USART1的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);	//打开GPIOA的时钟
	
	
	GPIO_InitTypeDef	GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin	= GPIO_Pin_9;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin	= GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	USART_InitTypeDef	USART_InitStructure;
	USART_InitStructure.USART_BaudRate = 115200;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	
	USART_Init(USART1,&USART_InitStructure);
	
	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	NVIC_InitTypeDef	NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStructure);
	
	USART_Cmd(USART1,ENABLE);
}

void Interface_SendByte(uint8_t Byte)
{
   
	USART_SendData(USART1,Byte);
	while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);
		
}

void Interface_SendByteArray(uint8_t *Array,uint16_t Length)
{
   
	uint16_t i;
	for(i=0;i<Length;i++)
	{
   
		Interface_SendByte(Array[i]);
	}
}

void Interface_SendString(char *String)
{
   
	uint8_t i;
	for(i=0;String[i] !='\0';i++)
	{
   
		Interface_SendByte(String[i]);
	}
}

uint32_t Interface_Pow(uint32_t X,uint32_t	Y)
{
   
	uint32_t Result = 1;
	while(Y--)
	{
   
		Result *= X;
	}
	return Result;
}

void Interface_SendNumber(uint32_t	Number,uint8_t Length)
{
   
	uint8_t i;
	for(i=0;i<Length;i++)
	{
   
		Interface_SendByte((Number/Interface_Pow
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值