本文介绍基于STM32F103C8T6的案例使用,主要从AHT10的详细功能和在STM32代码实现功能上面进行说明。
AHT10传感器是一款由艾普比(AIPT)生产的高精度数字温湿度传感器。它被设计用于提供精确的温度和湿度测量,适用于各种应用场景。以下是AHT10传感器的主要参数和使用背景:
主要参数
1. **测量范围**:
- **温度**:-40°C 到 +85°C
- **湿度**:0% RH 到 100% RH
2. **精度**:
- **温度**:±0.3°C(在0°C 到 50°C范围内)
- **湿度**:±2% RH(在20% RH 到 80% RH范围内)
3. **分辨率**:
- **温度**:0.01°C
- **湿度**:0.1% RH
4. **响应时间**:
- **温度**:约2秒
- **湿度**:约5秒
5. **接口类型**:通常使用I2C数字接口,便于与微控制器或处理器进行通信。
6. **工作电压**:通常在2.2V到5.5V之间,适合多种电源配置。
7. **功耗**:
- **测量模式**:通常在0.1mA到1mA范围内
- **待机模式**:极低功耗,延长电池寿命
使用背景
1. **家居环境监测**:AHT10传感器可用于智能家居系统,监测室内的温湿度,为用户提供舒适的居住环境。例如,用于空气质量监测、智能空调调节等。
2. **气象站**:用于个人和专业气象站,提供准确的温湿度数据,帮助气象预测和环境监测。
3. **工业应用**:在生产过程中,温湿度控制对产品质量至关重要,AHT10可以用于工业设备的环境监测和控制。
4. **汽车**:在汽车中用于车内环境监测,优化空调系统和提升乘客舒适度。
5. **农业**:在温室和农田中监测环境条件,优化作物生长条件,提高农业生产效率。
AHT10传感器以其高精度和可靠性,在许多需要精确温湿度测量的应用中表现出色。
由上述文字可以了解到AHT10传感器的使用参数以及各类用途,因此介绍在单片机STM32中如何实现当前的功能,采用IIC协议所以是要先进行配置IIC协议的,IIC的起始信号,终止信号,接受应答,发送信号,接受信号等函数,
这一段代码用于从AHT10传感器的采集数据中提取相应的湿度(RH)和温度(ST)值。下面是对这段代码的详细解释:
SRH = (databuff[0] << 12) + (databuff[1] << 4) + (databuff[2] >> 4);
ST = ((databuff[2] & 0x0f) << 16) + (databuff[3] << 8) + (databuff[4]);
databuff`**:存储从AHT10传感器读取的数据的字节数组。
### 湿度值 (SRH) 的提取
SRH = (databuff[0] << 12) + (databuff[1] << 4) + (databuff[2] >> 4);
1. **`databuff[0] << 12`**:将第一个字节左移12位,表示湿度值的最高12位。
2. **`databuff[1] << 4`**:将第二个字节左移4位,表示湿度值的次高12位。
3. **`databuff[2] >> 4`**:将第三个字节右移4位,提取出湿度值的最低4位。
第一个字节是8则,左移12位,是1000 0000 0000
第二个字节是4则 左移4位,是0100 0000
第三个字节是取最高位的四位,若是64 则是1000
将这些值相加,组合成一个完整的湿度值(SRH)。
#### 温度值 (ST) 的提取
ST = ((databuff[2] & 0x0f) << 16) + (databuff[3] << 8) + (databuff[4]);
1. **`databuff[2] & 0x0f`**:通过与0x0f(即00001111)进行按位与操作,提取出第三个字节的最低4位,表示温度值的最高4位。
2. **`(databuff[2] & 0x0f) << 16`**:将提取出的最低4位左移16位,表示温度值的最高16位。
3. **`databuff[3] << 8`**:将第四个字节左移8位,表示温度值的中间8位。
4. **`databuff[4]`**:直接取第五个字节,表示温度值的最低8位。
将这些值相加,组合成一个完整的温度值(ST)。
总结
- **湿度值**(SRH)是通过将三个字节的数据按位组合而成,获取传感器提供的湿度信息。
- **温度值**(ST)是通过将另外三个字节的数据按位组合而成,获取传感器提供的温度信息。
这段代码是用于将AHT10传感器输出的原始数据转换为实际的湿度和温度值。
#include "stm32f10x.h" // Device header
#include "Delay.h"
uint8_t ACK,DATA[6];
void MyI2C_W_SCL(uint8_t BitValue) //配置SCL
{
GPIO_WriteBit(GPIOB, GPIO_Pin_0, (BitAction)BitValue);
Delay_us(10);
}
void MyI2C_W_SDA(uint8_t BitValue) //配置SDA
{
GPIO_WriteBit(GPIOB, GPIO_Pin_1, (BitAction)BitValue);
Delay_us(10);
}
uint8_t MyI2C_R_SDA(void) //SDA读数据
{
uint8_t BitValue;
BitValue = GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1);
Delay_us(10);
return BitValue;
}
void MyI2C_Init(void) //初始化GPIO
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB, GPIO_Pin_0 | GPIO_Pin_1);
}
void MyI2C_Start(void) //配置起始信号
{
MyI2C_W_SDA(1);
MyI2C_W_SCL(1);
MyI2C_W_SDA(0);
MyI2C_W_SCL(0);
}
void MyI2C_Stop(void) //停止信号
{
MyI2C_W_SDA(0);
MyI2C_W_SCL(1);
MyI2C_W_SDA(1);
}
void IIC_Ack(void) //发送应答信号
{
MyI2C_W_SCL(0);
MyI2C_W_SDA(0);
Delay_us(2);
MyI2C_W_SCL(1);
Delay_us(2);
MyI2C_W_SCL(0);
}
void IIC_NAck(void) //不发送应答信号
{
MyI2C_W_SCL(0);
MyI2C_W_SDA(1);
Delay_us(2);
MyI2C_W_SCL(1);
Delay_us(2);
MyI2C_W_SCL(0);
}
void MyI2C_SendByte(uint8_t Byte) //发送主机数据
{
uint8_t i;
for (i = 0; i < 8; i ++)
{
MyI2C_W_SDA(Byte & (0x80 >> i));
MyI2C_W_SCL(1);
MyI2C_W_SCL(0);
}
}
uint8_t MyI2C_ReceiveByte(uint8_t ack) //接受传感器数据并发送应答信号
{
uint8_t i, Byte = 0x00;
MyI2C_W_SDA(1);
for (i = 0; i < 8; i ++)
{
MyI2C_W_SCL(1);
if (MyI2C_R_SDA()) {Byte |= (0x80 >> i);}
MyI2C_W_SCL(0);
}
if (!ack)
IIC_NAck();//发送nACK
else
IIC_Ack(); //发送ACK
return Byte;
}
void MyI2C_SendAck(uint8_t AckBit) //发送应答信号
{
MyI2C_W_SDA(AckBit);
MyI2C_W_SCL(1);
MyI2C_W_SCL(0);
}
uint8_t MyI2C_ReceiveAck(void) //接受应答信号
{
uint8_t AckBit;
MyI2C_W_SDA(1);
MyI2C_W_SCL(1);
AckBit = MyI2C_R_SDA();
MyI2C_W_SCL(0);
return AckBit;
}
void at10init() //配置传感器
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB, GPIO_Pin_0 | GPIO_Pin_1);
MyI2C_Start();
MyI2C_SendByte(0x70);
MyI2C_SendByte(0xe1);
MyI2C_SendByte(0x08);
MyI2C_SendByte(0x00);
MyI2C_Stop();
Delay_ms(40);
}
void ah10_review()
{
MyI2C_SendByte(0x70);
MyI2C_ReceiveAck();
MyI2C_SendByte(0xe1);
MyI2C_ReceiveAck();
MyI2C_SendByte(0x08);
MyI2C_ReceiveAck();
MyI2C_SendByte(0x00);
MyI2C_ReceiveAck();
MyI2C_Stop();
Delay_ms(40);
}
uint8_t ath10_state()
{
uint8_t ack;
MyI2C_Start();
MyI2C_SendByte(0x70);
ack=MyI2C_ReceiveAck();
MyI2C_Stop();
return ack;
}
void ah10_write_reset()
{
MyI2C_Start();
MyI2C_SendByte(0x70);
MyI2C_ReceiveAck();
MyI2C_SendByte(0xba);
MyI2C_ReceiveAck();
MyI2C_Stop();
Delay_ms(20);
}
uint8_t at10_humi_temp(float *humi,float *temp)
{
u8 ack;
u32 SRH=0,ST=0;
u8 databuff[6];
MyI2C_Start();
MyI2C_SendByte(0X70);
MyI2C_ReceiveAck();
MyI2C_SendByte(0xac);
MyI2C_ReceiveAck();
MyI2C_SendByte(0x33);
MyI2C_ReceiveAck();
MyI2C_SendByte(0x00);
MyI2C_ReceiveAck();
MyI2C_Stop();
Delay_ms(80);//延时一会等待数据读出
MyI2C_Start();
MyI2C_SendByte(0X71);
MyI2C_ReceiveAck();
ack=MyI2C_ReceiveByte(1);
if((ack&0x40)==0)
{
databuff[0]=MyI2C_ReceiveByte(1);
databuff[1]=MyI2C_ReceiveByte(1);
databuff[2]=MyI2C_ReceiveByte(1);
databuff[3]=MyI2C_ReceiveByte(1);
databuff[4]=MyI2C_ReceiveByte(0);
MyI2C_SendAck(0);
MyI2C_Stop();
SRH=(databuff[0]<<12)+(databuff[1]<<4)+(databuff[2]>>4); //湿度数据
ST=((databuff[2]&0X0f)<<16)+(databuff[3]<<8)+(databuff[4]);//温度数据
*humi=(int)(SRH*100.0/1024/1024+0.5);
*temp=((int)(ST*2000.0/1024/1024+0.5))/10.0-50;
return 0;
}
MyI2C_Stop();
return 1;
}