基于I2C协议下利用AHT20的温度采集
简介:
(1)AHT20简介
AHT20,新一代温湿度传感器在尺寸与智能方面建立了新的标准:它嵌入了适于回流焊的双列扁平无引脚SMD 封装,底面 3 x 3mm ,高度1.0mm。传感器输出经过标定的数字信号,AHT20,新一代温湿度传感器在尺寸与智能方面建立了新的标准:它嵌入了适于回流焊的双列扁平无引脚SMD 封装,底面 3 x 3mm ,高度1.0mm。传感器输出经过标定的数字信号,标准 I2C 格式。
应用范围
暖通空调 、除湿器、测试及检测设备、消费品、汽车 、自动控制、数据记录器、气象站、家电、湿度调节、医疗及其他相关温湿度检测控制。
产品特性
•完全标定
•数字输出,I²C接口
•优异的长期稳定性
•采用SMD封装适于回流焊
•响应迅速、抗干扰能力强
(2)I2C简介
- I2C 总线上产生时钟信号通常是主机器件的责任 当在总线上传输数据时 每个主机产生自己的时钟信号 主机发出的总线时钟信号只有在以下的情况才能被改变 慢速的从机器件控制时钟线并延长时钟信号 或者在发生仲裁时被另一个主机改变
- I²C 只是用两条双向的线,一条 Serial Data Line (SDA),另一条 Serial Clock (SCL。)
SCL:上升沿将数据输入到每个 EEPROM 器件中;下降沿驱动 EEPROM 器件输出数
据。(边沿触发)
SDA:双向数据线,为 OD 门,与其它任意数量的 OD 与 OC 门成"线与"关系。
每一个 I2C 总线器件内部的 SDA、SCL 引脚电路结构都是一样的,引脚的输出驱动与输入缓冲连在一起。其中输出为漏极开路的场效应管,输入缓冲为一只高输入阻抗的同相器,这种电路具有两个特点:
(1)连到总线上的任一器件输出的低电平,都将使总线的信号变低,即各器件的 SDA 及 SCL都是线"与"关系。
(2)引脚在输出信号的同时还将引脚上的电平进行检测,检测是否与刚才输出一致,为" 时钟同步"和"总线仲裁"提供了硬件基础。
一、I2C软件与硬件的区别
硬件I2C对应芯片上的I2C外设,有相应I2C驱动电路,其所使用的I2C管脚也是专用的,因而效率要远高于软件模拟的I2C;一般也较为稳定,但是程序较为繁琐。
硬件(固件)I2C是直接调用内部寄存器进行配置;而软件I2C是没有寄存器这个概念的。
软件I2C一般是使用GPIO管脚,用软件控制SCL,SDA线输出高低电平,模拟i2c协议的时序。
主要对比:
1.硬件IIC用法比较复杂,模拟IIC的流程更清楚一些。
2.硬件IIC速度比模拟快,并且可以用DMA
3.模拟IIC可以在任何管脚上,而硬件只能在固定管脚上。
二、实验进行温度采集
(1)实验要求
- 每隔2秒钟采集一次温湿度数据
- 通过串口发送到上位机(win10)
(2)实验代码实现
#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("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);
}
(3)效果展示
可以看见对着传感器哈一口气之后,湿度和温度都会上升,注意这是非常不专业的做法,哈气之后要用纸插一下芯片。
三、总结
此次实验主要是利用I2C的方式,实现AHT20模块对温度的采集,实验后加深了对I2C的理解。文中有不足之处希望大家指出,博主会及时改正。
四、参考文献:
[1]奥松电子官网资料
[2]AHT20源码
[3]I2C总线简介
[4]I2C软件与硬件的区别