基于I2C的温湿度采集初体验

实验准备

本次实验需要用到主要器件为STM32核心板,AHT20
对于STM32我们已经使用了几次,有了一定了解,接下来了解AHT20芯片

AHT20

AHT20,新一代温湿度传感器在尺寸与智能方面建立了新的标准:它嵌入了适于回流焊 的双列扁平无引脚SMD封装,底面3x3mm ,高度1.0mm。传感器输出经过标定的数字信号,标准 I2C 格式。
AHT20优点如下:
完全标定
数字输出,I2C 接口
优异的长期稳定性
采用SMD封装适于回流焊
响应迅速、抗干扰能力强

I2C总线通信协议

I2C总线内部结构图:
在这里插入图片描述
I2C总线只使用两条双向漏极开路的信号线(串行数据线:SDA,及串行时钟线:SCL),并利用电阻上拉。I2C总线仅仅使用SCL、SDA两根信号线,就实现了设备间的数据交互,极大地简化了对硬件资源和PCB板布线空间的占用。I2C总线广泛应用在EEPROM、实时时钟、LCD、及其他芯片的接口。I2C允许相当大的工作电压范围,典型的电压基准为:+3.3V或+5V。

SCL(Serial Clock):串行时钟线,传输CLK信号,一般是主设备向从设备提供
SDA(Serial Data):串行数据线,传输通信数据

I2C硬件与软件的对比

硬件I2C对应芯片上的I2C外设,有相应I2C驱动电路,其所使用的I2C管脚也是专用的,因而效率要远高于软件模拟的I2C;一般也较为稳定,但是程序较为繁琐。

硬件I2C是直接调用内部寄存器进行配置;而软件I2C是没有寄存器这个概念的。

主要对比:
1.硬件IIC用法比较复杂,模拟IIC的流程更清楚一些。
2.硬件IIC速度比模拟快,并且可以用DMA
3.模拟IIC可以在任何管脚上,而硬件只能在固定管脚上

实验要求

本次实验要求:每隔2秒钟采集一次温湿度数据,并通过串口发送到上位机(win10)

硬件连线

STM32核心板和AHT20的连线
SCL——B6
GND——GND
SDA——B7
VCC——GND

代码实现

#include "stm32f10x.h"
#include "stm32f10x_usart.h"
#include "misc.h"
#include "stdio.h"
#include "delay.h"
#include "bsp_i2c.h"
#include "ATH20.h"

void RCC_Configuration(void);
void GPIO_Configuration(void);

GPIO_InitTypeDef GPIO_InitStructure;

#pragma import(__use_no_semihosting)
struct __FILE
{
	int handle;

};
FILE __stdout;
_sys_exit(int x)
{
	x = x;
}
int fputc(int ch, FILE *f)
{
	while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);
    USART_SendData(USART1,(uint8_t)ch);
	return ch;
}

void uart_init(u32 bound)
{
    //GPIO端口设置
    GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);	//使能USART1,GPIOA时钟
 	USART_DeInit(USART1);  //复位串口1
    //USART1_TX   PA.9
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出
    GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PA9

    //USART1_RX	  PA.10
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
    GPIO_Init(GPIOA, &GPIO_InitStructure);  //初始化PA10

    //USART 初始化设置
	USART_InitStructure.USART_BaudRate = bound;//一般设置为9600;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
	USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	//收发模式

    USART_Init(USART1, &USART_InitStructure); //初始化串口

    USART_Cmd(USART1, ENABLE);                    //使能串口
}

int main(void)
{
    uint8_t ret = 0;
    float P,T,ALT;
    uint32_t CT_data[2];
	int  c1,t1;
    uint8_t LED_Stat = 0;

    RCC_Configuration();					   	//设置系统时钟
    GPIO_Configuration();					    //IO口设
    I2C_Bus_Init();

    uart_init(115200);

    ret = ATH20_Init();
    if(ret == 0)
    {
        printf("ATH20传感器初始化错误\n");
        while(1);
    }



    while(1)
    {
        /* 读取 ATH20 传感器数据*/
        while(ATH20_Read_Cal_Enable() == 0)
        {
            ATH20_Init();//如果为0再使能一次
            SoftDelay_ms(30);
        }
        ATH20_Read_CTdata(CT_data);  //读取温度和湿度
        c1 = CT_data[0] * 1000 / 1024 / 1024;  //计算得到湿度值(放大了10倍,如果c1=523,表示现在湿度为52.3%)
        t1 = CT_data[1] * 200 *10 / 1024 / 1024 - 500;//计算得到温度值(放大了10倍,如果t1=245,表示现在温度为24.5℃)

        printf("---------------------------\n");
        printf("AHT20温湿度传感器测试数据:\n");
        printf("温度: %d.%d ℃\n",(t1/10),(t1%10));
        printf("湿度: %d.%d %%\n",(c1/10),(c1%10));
        printf("\n");
       

        SoftDelay_ms(1000);//每隔两秒读一次数

        if(LED_Stat == 0)
        {
            LED_Stat = 1;
            GPIO_ResetBits(GPIOC, GPIO_Pin_2);
        }
        else
        {
            LED_Stat = 0;
            GPIO_SetBits(GPIOC, GPIO_Pin_2);
        }
    }
}

void RCC_Configuration(void)
{
  SystemInit();

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC
  						| RCC_APB2Periph_GPIOD| RCC_APB2Periph_GPIOE , ENABLE);
}

void GPIO_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_7;				     //状态LED1
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;			 //通用推挽输出模式
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;			 //输出模式最大速度50MHz
  GPIO_Init(GPIOC, &GPIO_InitStructure);
}

将程序移植到STM32上,来看看效果

实验成果

依然是使用到串口调试助手
为了验证温度的变化,我隔着一定距离哈了一口气,当然建议不要太近,因为芯片很灵敏,避免损坏芯片,温度和湿度都提高了
在这里插入图片描述

总结

通过这次实验让我对I2C和AHT20的使用有了初步了解,现在已经可以完成简单的温度测量了,相信今后的实验能够实现更多的功能,本次体验良好。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值