当前位置: 首页 > article >正文

AHT20 HAL库驱动

首先需要你自己实现delay_us和delay_ms这两个函数,建议使用正点原子的方法,使用systick来计数,systick中断优先级调高一点,就不会被卡住了。

AHT20是一款温湿度传感器,采用I2C接口,其7位设备地址为0x38。第八位是读写位,写为0读为1。具体细节请参看数据手册。网上给出的都是标准库的,我在这里修改成HAL库的硬件IIC驱动。

硬件买的是一个AHT20和BMP280在一起的模块,并夕夕卖家竟然没有资料,没办法只好自己搞一个。

//AHT20.h HAL库版本
#ifndef AHT20_H
#define AHT20_H
#include "delay.h"
#include "stm32f1xx_hal.h"
#include "stm32f1xx_hal_i2c.h"

#define ATH20_SLAVE_ADDRESS    0x38		/* AHT20 I2C 7位从机地址,不带读写位 */
#define AHT20_WRITE_ADDR (ATH20_SLAVE_ADDRESS<<1)/*设备写地址*/
#define AHT20_READ_ADDR ((ATH20_SLAVE_ADDRESS<<1)+1)/*设备读地址*/
#define AHT20_READWRITE_TIMOUT 200 //iic 读写超时时间
//****************************************
// 定义 AHT20 内部地址
//****************************************
#define	INIT		    0xBE	//初始化
#define	SoftReset		0xBA	//软复位
#define	StartTest		0xAC	//开始测试
extern I2C_HandleTypeDef* AHT20_hi2c;
uint8_t AHT20_Read_Status(void);//读取AHT10的状态寄存器,测试用
//init需要传入AHT20挂在的I2C结构体
uint8_t AHT20_Init(I2C_HandleTypeDef* hi2c);//取数据需要先初始化一次
uint8_t ATH20_Read_Cal_Enable(void);  //查询cal enable位有没有使能
void ATH20_Read_CTdata(uint32_t *ct); //读取AHT10的温度和湿度数据

#endif
//AHT20.c
#include "AHT20.h"
I2C_HandleTypeDef* AHT20_hi2c;//AHT挂载在那条IIC上。

uint8_t AHT20_Read_Status(void)//读取AHT10的状态寄存器
{
  uint8_t Byte_first,tmp=0x71;
	//读状态需要先发送一个0x71,然后获取一字节。
	//HAL_I2C_Master_Transmit(AHT20_hi2c,AHT20_WRITE_ADDR,&tmp,1,AHT20_READWRITE_TIMOUT);
	//HAL_I2C_Master_Receive(AHT20_hi2c,AHT20_READ_ADDR,&Byte_first,1,0xFFFF);
	HAL_I2C_Mem_Read(AHT20_hi2c,AHT20_READ_ADDR,0x71,I2C_MEMADD_SIZE_8BIT,&Byte_first,1,AHT20_READWRITE_TIMOUT);
	return Byte_first;
}

uint8_t ATH20_Read_Cal_Enable(void)
{
    uint8_t val = 0;//ret = 0,

    val = AHT20_Read_Status();
    if((val & 0x68) == 0x08)  //判断NOR模式和校准输出是否有效
        return 1;
    else
        return 0;
}

void ATH20_Read_CTdata(uint32_t *ct) //读取AHT10的温度和湿度数据
{
  uint32_t RetuData = 0;
	uint16_t cnt = 0;
  uint8_t Data[10];
  uint8_t tmp[10];

  tmp[0] = 0x33;
  tmp[1] = 0x00;
	// StartTest 0xAC
	HAL_I2C_Mem_Write(AHT20_hi2c,AHT20_WRITE_ADDR,StartTest,I2C_MEMADD_SIZE_8BIT,tmp,2,AHT20_READWRITE_TIMOUT);
	delay_ms(80);//等待75ms

    cnt = 0;
	while(((AHT20_Read_Status()&0x80) == 0x80))//等待忙状态结束
	{
        delay_ms(1);
        if(cnt++ >= 100)
        {
            break;
        }
	}

	HAL_I2C_Master_Receive(AHT20_hi2c,AHT20_READ_ADDR,Data,7,AHT20_READWRITE_TIMOUT);
	//不进行CRC校验了,直接转换数据。,需要校验的可以自己加。
	RetuData = 0;
  RetuData = (RetuData|Data[1]) << 8;
	RetuData = (RetuData|Data[2]) << 8;
	RetuData = (RetuData|Data[3]);
	RetuData = RetuData >> 4;
	ct[0] = RetuData;

  RetuData = 0;
	RetuData = (RetuData|Data[3]) << 8;
	RetuData = (RetuData|Data[4]) << 8;
	RetuData = (RetuData|Data[5]);
	RetuData = RetuData&0xfffff;
	ct[1] = RetuData;
}

uint8_t count;
uint8_t AHT20_Init(I2C_HandleTypeDef* hi2c)
{
    uint8_t tmp[10];
		AHT20_hi2c = hi2c;
	//上电后需等待40ms
    delay_ms(40);
	//数据手册上说要求先查看较准使能位是否为1,然后才发送初始化命令,为了简单我们直接初始化一次,再检测。
    tmp[0] = 0x08;
    tmp[1] = 0x00;
		HAL_I2C_Mem_Write(AHT20_hi2c,AHT20_WRITE_ADDR,INIT,I2C_MEMADD_SIZE_8BIT,tmp,2,AHT20_READWRITE_TIMOUT);

    delay_ms(500);
    count = 0;

    while(ATH20_Read_Cal_Enable() == 0)//需要等待状态字status的Bit[3]=1时才去读数据。如果Bit[3]不等于1 ,发软件复位0xBA给AHT10,再重新初始化AHT10,直至Bit[3]=1
    {
			HAL_I2C_Mem_Write(AHT20_hi2c,AHT20_WRITE_ADDR,SoftReset,I2C_MEMADD_SIZE_8BIT,tmp,0,AHT20_READWRITE_TIMOUT);
			/*uint8_t buf[2];
			buf[0]=SoftReset;
			HAL_I2C_Master_Transmit(AHT20_hi2c,AHT20_WRITE_ADDR,buf,1,AHT20_READWRITE_TIMOUT);*/
      delay_ms(200);

			HAL_I2C_Mem_Write(AHT20_hi2c,AHT20_WRITE_ADDR,INIT,I2C_MEMADD_SIZE_8BIT,tmp,2,AHT20_READWRITE_TIMOUT);

      count++;
      if(count >= 10)
				return 0;
      delay_ms(500);
    }
    return 1;
}

调用示例:

uint32_t CT_data[2];
int  c1,t1;    
uint8_t status = AHT20_Init(&hi2c1);
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℃
uint8_t transBuf[40];
sprintf(transBuf,"AHT20 Temp: %d.%d \r\n",(t1/10),(t1%10));
HAL_UART_Transmit(&huart1, (uint8_t *)transBuf, strlen(transBuf),200);
sprintf(transBuf,"AHT20 Humi: %d.%d %%\r\n",(c1/10),(c1%10));
HAL_UART_Transmit(&huart1, (uint8_t *)transBuf, strlen(transBuf),200);


http://www.kler.cn/a/372949.html

相关文章:

  • 数据结构-希尔排序(ShellSort)笔记
  • 深度强化学习-学习笔记
  • 【文心智能体 | AI大师工坊】如何使用智能体插件,完成一款旅游类智能体的开发,来体验一下我的智能体『​​​​​​​背包客』
  • WPF的行为(Behavior)
  • 开源项目-投票管理系统
  • 华为云开源项目Sermant正式成为CNCF官方项目
  • 人工智能:开启未来之门
  • 如何分析算法的执行效率和资源消耗
  • 将本地某个commit 提交另一个分支上
  • Unity BesHttp插件修改Error log的格式
  • 数字信封原理解析:安全高效,一次一密!
  • 基于Hadoop和Hive的健康保险数据分析
  • 现代Web酒店客房管理:基于Spring Boot的实现
  • Linux scp命令语法
  • 00 硬件、嵌入式硬件知识-目录篇
  • R语言机器学习算法实战系列(十五)随机森林生存预后模型+SHAP值 (Random Survival Forest + SHAP)
  • AI虚拟主播实时互动模块的搭建与开发!
  • XSS小游戏【1-13关】
  • HTML入门教程22:HTML文件路径
  • 物联网监控数据采集,传输和存储方案:使用 GreptimeDB 和 YoMo
  • Flink CDC系列之:调研应用Flink CDC将 ELT 从 MySQL 流式传输到 Doris方案
  • 如何解决RabbitMQ消息的重复消费问题
  • ubuntu 24 (wayland)如何实现无显示器远程桌面
  • 基于Python的A*算法实现路径规划
  • 农村扶贫管理:SpringBoot解决方案
  • PPT / Powerpoint中利用LaTeX输入公式