STM32 F030C8 AHT10驱动程序 温湿度传感器
程序员文章站
2024-02-25 18:26:21
...
本工程通过STM32CubeMX创建,使用HAL库。
添加.h和.c文件可以使用。
以下是.h文件(需要修改对应引脚与延迟函数):
#ifndef _AHT10_H__
#define _AHT10_H__
#include "stm32f0xx.h"
#include "delay.h"
#define AHT10_Delay_us(time) delay_us(time)
#define AHT10_Delay_ms(time) delay_ms(time)
#define AHT10_ADDRESS 0x70
#define AHT10_WRITE 0x70
#define AHT10_READ 0x71
#define AHT10_I2C_SCL_PIN GPIO_PIN_6
#define AHT10_I2C_SCL_GPIO_PORT GPIOB
#define AHT10_I2C_SCL_GPIO_RCC __HAL_RCC_GPIOB_CLK_ENABLE()
#define AHT10_I2C_SDA_PIN GPIO_PIN_7
#define AHT10_I2C_SDA_GPIO_PORT GPIOB
#define AHT10_I2C_SDA_GPIO_RCC __HAL_RCC_GPIOB_CLK_ENABLE()
/* Private define ------------------------------------------------------------*/
#define AHT10_SCL_H HAL_GPIO_WritePin(AHT10_I2C_SCL_GPIO_PORT, AHT10_I2C_SCL_PIN, GPIO_PIN_SET)
#define AHT10_SCL_L HAL_GPIO_WritePin(AHT10_I2C_SCL_GPIO_PORT, AHT10_I2C_SCL_PIN, GPIO_PIN_RESET)
#define AHT10_SDA_H HAL_GPIO_WritePin(AHT10_I2C_SDA_GPIO_PORT, AHT10_I2C_SDA_PIN, GPIO_PIN_SET)
#define AHT10_SDA_L HAL_GPIO_WritePin(AHT10_I2C_SDA_GPIO_PORT, AHT10_I2C_SDA_PIN, GPIO_PIN_RESET)
#define AHT10_READ_SDA HAL_GPIO_ReadPin(AHT10_I2C_SDA_GPIO_PORT,AHT10_I2C_SDA_PIN)
/*****************函数声明,对外接口******************/
void AHT10Init(void);
uint8_t AHT10Check(void);
void AHT10Reset(void);
uint8_t AHT10ReadData(uint16_t *temperature,uint16_t *humidity);
#endif
以下是.c文件:
#include "AHT10.h"
//初始化IIC
static void AHT10_IIC_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
AHT10_I2C_SCL_GPIO_RCC;
AHT10_I2C_SDA_GPIO_RCC;//使能GPIO时钟
GPIO_InitStruct.Pin = AHT10_I2C_SCL_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(AHT10_I2C_SCL_GPIO_PORT, &GPIO_InitStruct);
GPIO_InitStruct.Pin = AHT10_I2C_SDA_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(AHT10_I2C_SDA_GPIO_PORT, &GPIO_InitStruct);
AHT10_SDA_H;
AHT10_SCL_H;
}
static void AHT10_SDA_OUT(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
AHT10_I2C_SDA_GPIO_RCC; //使能GPIO时钟
GPIO_InitStruct.Pin = AHT10_I2C_SDA_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(AHT10_I2C_SDA_GPIO_PORT, &GPIO_InitStruct);
}
static void AHT10_SDA_IN(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
AHT10_I2C_SDA_GPIO_RCC; //使能GPIO时钟
GPIO_InitStruct.Pin = AHT10_I2C_SDA_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(AHT10_I2C_SDA_GPIO_PORT, &GPIO_InitStruct);
}
//产生IIC起始信号
static void AHT10_IIC_Start(void)
{
AHT10_SDA_OUT(); //sda线输出
AHT10_SDA_H;
AHT10_SCL_H;
AHT10_Delay_us(4);
AHT10_SDA_L;//START:when CLK is high,DATA change form high to low
AHT10_Delay_us(4);
AHT10_SCL_L;//钳住I2C总线,准备发送或接收数据
}
//产生IIC停止信号
static void AHT10_IIC_Stop(void)
{
AHT10_SDA_OUT();//sda线输出
AHT10_SCL_L;
AHT10_SDA_L;//STOP:when CLK is high DATA change form low to high
AHT10_Delay_us(4);
AHT10_SCL_H;
AHT10_SDA_H;//发送I2C总线结束信号
AHT10_Delay_us(4);
}
//等待应答信号到来
//返回值:1,接收应答失败
// 0,接收应答成功
static uint8_t AHT10_IIC_Wait_Ack(void)
{
uint8_t ucErrTime=0;
AHT10_SDA_IN(); //SDA设置为输入
AHT10_SDA_H;
AHT10_Delay_us(1);
AHT10_SCL_H;
AHT10_Delay_us(1);
while(AHT10_READ_SDA)
{
ucErrTime++;
if(ucErrTime>250)
{
AHT10_IIC_Stop();
return 1;
}
}
AHT10_SCL_L;//时钟输出0
return 0;
}
//产生ACK应答
static void AHT10_IIC_Ack(void)
{
AHT10_SCL_L;
AHT10_SDA_OUT();
AHT10_SDA_L;
AHT10_Delay_us(2);
AHT10_SCL_H;
AHT10_Delay_us(2);
AHT10_SCL_L;
}
//不产生ACK应答
static void AHT10_IIC_NAck(void)
{
AHT10_SCL_L;
AHT10_SDA_OUT();
AHT10_SDA_H;
AHT10_Delay_us(2);
AHT10_SCL_H;
AHT10_Delay_us(2);
AHT10_SCL_L;
}
//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答
static void AHT10_IIC_Send_Byte(uint8_t txd)
{
uint8_t t;
AHT10_SDA_OUT();
AHT10_SCL_L;//拉低时钟开始数据传输
for(t=0;t<8;t++)
{
//IIC_SDA=(txd&0x80)>>7;
if((txd&0x80)>>7)
AHT10_SDA_H;
else
AHT10_SDA_L;
txd<<=1;
AHT10_Delay_us(2); //对TEA5767这三个延时都是必须的
AHT10_SCL_H;
AHT10_Delay_us(2);
AHT10_SCL_L;
AHT10_Delay_us(2);
}
}
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK
static uint8_t AHT10_IIC_Read_Byte(unsigned char ack)
{
unsigned char i,receive=0;
AHT10_SDA_IN();//SDA设置为输入
for(i=0;i<8;i++ )
{
AHT10_SCL_L;
AHT10_Delay_us(2);
AHT10_SCL_H;
receive<<=1;
if(AHT10_READ_SDA)receive++;
AHT10_Delay_us(1);
}
if (!ack)
AHT10_IIC_NAck();//发送nACK
else
AHT10_IIC_Ack(); //发送ACK
return receive;
}
/**
brief 检查AHT10是否存在
param NONE
return 0存在 1不存在
*/
uint8_t AHT10Check(void)
{
uint8_t ack=0;
AHT10_IIC_Start();
AHT10_IIC_Send_Byte(AHT10_ADDRESS);
ack=AHT10_IIC_Wait_Ack();
AHT10_IIC_Stop();
return ack;
}
/**
brief AHT10软复位
param NONE
return NONE
*/
void AHT10Reset(void)
{
AHT10_IIC_Start();
AHT10_IIC_Send_Byte(AHT10_WRITE);
AHT10_IIC_Wait_Ack();
AHT10_IIC_Send_Byte(0xba);
AHT10_IIC_Wait_Ack();
AHT10_IIC_Stop();
}
/**
brief AHT10初始化函数
param NONE
return NONE
*/
void AHT10Init()
{
AHT10_IIC_Init();
AHT10_IIC_Start();
AHT10_IIC_Send_Byte(AHT10_ADDRESS);
AHT10_IIC_Send_Byte(0xe1);
AHT10_IIC_Send_Byte(0x08);
AHT10_IIC_Send_Byte(0x00);
AHT10_IIC_Stop();
AHT10_Delay_ms(40);//延时20ms让传感器稳定
}
/**
brief 检查AHT10读温湿度数据
param *temperature:需要读出的温度数据,uint16_t指针类型,精度范围+-0.3C
param *humidity:需要读出的湿度数据,uint16_t指针类型,精度范围+-2RH
return 1 读数据正常 0读数据失败
*/
uint8_t AHT10ReadData(uint16_t *temperature,uint16_t *humidity)
{
uint8_t ack;
uint32_t SRH=0,ST=0;
uint8_t databuff[6];
AHT10_IIC_Start();
AHT10_IIC_Send_Byte(AHT10_WRITE);
AHT10_IIC_Wait_Ack();
AHT10_IIC_Send_Byte(0xac);
AHT10_IIC_Wait_Ack();
AHT10_IIC_Send_Byte(0x33);
AHT10_IIC_Wait_Ack();
AHT10_IIC_Send_Byte(0x00);
AHT10_IIC_Wait_Ack();
AHT10_IIC_Stop();
AHT10_Delay_ms(80);//延时一会等待数据读出
AHT10_IIC_Start();
AHT10_IIC_Send_Byte(AHT10_READ);
AHT10_IIC_Wait_Ack();
ack=AHT10_IIC_Read_Byte(1);
if((ack&0x40)==0)
{
databuff[0]=AHT10_IIC_Read_Byte(1);
databuff[1]=AHT10_IIC_Read_Byte(1);
databuff[2]=AHT10_IIC_Read_Byte(1);
databuff[3]=AHT10_IIC_Read_Byte(1);
databuff[4]=AHT10_IIC_Read_Byte(0);
AHT10_IIC_Stop();
SRH=(databuff[0]<<12)+(databuff[1]<<4)+(databuff[2]>>4);
ST=((databuff[2]&0X0f)<<16)+(databuff[3]<<8)+(databuff[4]);
// *humidity=(int)(SRH*100.0/1024/1024+0.5);//未放大
// *temperature=((int)(ST*2000.0/1024/1024+0.5))/10.0-50;//未放大,不过返回值最好为float
*humidity = SRH*1000/1024/1024; //计算得到湿度值(放大了10倍,如果c1=523,表示现在湿度为52.3%)
*temperature = ST *200*10/1024/1024-500;//计算得到温度值(放大了10倍,如果t1=245,表示现在温度为24.5℃)
//为读取的数据更稳定,还可以使用平均值滤波或者窗口滤波,或者前面读取的值与后面的值相差不能太大。
return 1;
}
AHT10_IIC_Stop();
return 0;
}
工程文件以及AHT10规格书:AHT10驱动程序
上一篇: 二代身份证验证示例
下一篇: stm32学习--串口中断