首页 > 其他分享 >基于CH592x的硬件I2C驱动(AHT20)调试记录

基于CH592x的硬件I2C驱动(AHT20)调试记录

时间:2024-03-07 11:11:21浏览次数:38  
标签:字节 uint8 AHT20 humi CH592x I2C data

前言:AHT20是一个I2C器件,恰好CH592芯片资源有硬件I2C我们可以尝试使用592的硬件I2C去驱动AHT20。

资料:I2C接口使用指南(可见EVT中I2C例程文件下),AHT20数据手册(可以在立创商城直接下载)

数据手册中对这个器件的驱动流程也有说明,

分别对几个步骤进行解读:

 1、根据手册提示开机后,要等待40ms才能够与AHT20通信。0x71地址实际上AHT20作为IIC从机的地址。按照AHT20手册,在启动传输后,随后传输的 I2C首字节包括 7位的 I2C设备地址0x38。因为IIC通信一般使用7位地址码,但是读写数据都是一个字节一个字节的读写。0x38的七位二进制为0111000。规定从机地址要左一位。多出来的第八位就是读写位。IIC协议规定,如果主机发起通信的目的是为了写从机,那么读写位是0,此时AHT20的地址是01110000,即0x70.如果主机发起通信的目的是为了读从机传入的数据,那么读写位就是1。此时AHT20的地址是0x71。

2、直接发送按照命令。按照(0xac,0x33,0x00)依次发送;

3、等待75ms后,读取6个字节数据,里面包含了状态信息,湿度信息,和温度信息。其中第0个字节是状态位,需获取bit[7]判断设备是否空闲。而后,湿度数据由20个bit位组成:第1个字节是湿度的高8位,第2个字节是湿度的次高8位.第3个字节的高4个bit位是湿度的低4位。温度数据也由20个bit位组成。第3个字节的低4个bit位是温度的高4位,第4个字节是温度的次高8位,第5个字节是温度的低8位。

4、根据手册的计算公式将获取的温度、湿度值计算出来。

接下来就可可以看代码实现部分:
AHT20.h

#ifndef DRIVER_CODE_AHT20_H_
#define DRIVER_CODE_AHT20_H_

#include "CH59x_common.h"
#include "app_i2c.h"

extern uint8_t send_data[4];

#define AHT20_Slave_Adress 0x38
#define AHT20_Init_REG_Adress   0x71

extern void AHT20_READ_Status(uint8_t slave_adress , uint8_t reg_adress , uint32_t *cb_data );

AHT20.c

#include "aht20.h"

uint8_t send_data[4]={0xac , 0x33, 0x00};
uint8_t receive_data[7];
uint8_t Inspection_data;

void AHT20_READ_Status(uint8_t slave_adress , uint8_t reg_adress ,uint32_t *cb_data)
{
    uint8_t i = 0;
    uint32_t humi_temp_data =0;

    I2C_Init(I2C_Mode_I2C, 400000, I2C_DutyCycle_16_9, I2C_Ack_Enable, I2C_AckAddr_7bit, 0x42);
    DelayMs(40);

    while(I2C_GetFlagStatus(I2C_FLAG_BUSY) != RESET);

    I2C_GenerateSTART(ENABLE);

    while(!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));
    I2C_Send7bitAddress(slave_adress<<1, I2C_Direction_Transmitter);


    while(!I2C_CheckEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

    while(i < 3)
                {
                    if(I2C_GetFlagStatus(I2C_FLAG_TXE) != RESET)
                    {
                        I2C_SendData(send_data[i]);
                        i++;
                    }
                }

    while(!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED));

    I2C_GenerateSTART(ENABLE);                                          //重起始信号

    while(!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));               //判断BUSY, MSL and SB flags
    I2C_Send7bitAddress(reg_adress, I2C_Direction_Receiver);                  //发送地址+最低位1表示为“读”
    while(!I2C_CheckEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));    //判断BUSY, MSL and ADDR flags
    //I2C_GenerateSTOP(DISABLE);

    for(uint8_t j=0; j<7; j++)
        {
            if(j == 7-1)
            I2C_AcknowledgeConfig(DISABLE);         //清除ACK位               主设备为了能在收到最后一个字节后产生一个NACK脉冲,
                                                    //必须在读取倒数第二个字节之后(倒数第二个RxNE 事件之后)清除ACK位(ACK=0)
            while(!I2C_GetFlagStatus(I2C_FLAG_RXNE));                       //获取RxEN的状态,等待收到数据
            receive_data[j] = I2C_ReceiveData();
        }
    I2C_GenerateSTOP(ENABLE);            //停止信号
    humi_temp_data = 0;

    humi_temp_data =(humi_temp_data | receive_data[1])<<8;
    humi_temp_data =(humi_temp_data | receive_data[2])<<8;
    humi_temp_data =(humi_temp_data | receive_data[3]);
    humi_temp_data = humi_temp_data >>4;
    cb_data[0] = humi_temp_data;

    humi_temp_data = 0;
    humi_temp_data =(humi_temp_data | receive_data[3])<<8;
    humi_temp_data =(humi_temp_data | receive_data[4])<<8;
    humi_temp_data =(humi_temp_data | receive_data[5]);
    humi_temp_data = humi_temp_data&0xfffff;
    cb_data[1] = humi_temp_data;

    PRINT("湿度 %d\r\n",cb_data[0]*100/1048576);
    PRINT("温度 %d\r\n",(cb_data[1]*200/1048576)-50);
};

 仅是个人学习分享;如有任何错漏敬请留言指正。

 

标签:字节,uint8,AHT20,humi,CH592x,I2C,data
From: https://www.cnblogs.com/frontier/p/18048882

相关文章

  • MPR121 Breakout 更改 I2C 地址
    MPR121Breakout是一个 接近电容式触摸传感器,连接到arduino、esp32等单片机,可以用来做一些触摸感应的小玩意。他有12个触摸点,使用i2c协议来操控,非常方便。    默认情况下,Add引脚接地了,板子的i2c地址是0x5A,如果你要同时连接多个板子,那么i2c地址就冲突了。你......
  • 17_I2C通信外设
    I2C通信外设I2C外设简介固定多主机:固定多个主机和多个从机可变多主机:没用固定的主机和从机,任何从机都可以变成主机,通信完成后变回从机10位地址模式:使用第一二个字节当地址,第一个字节是11110开头就是10位地址模式(除了11110之后的2位+第二个字节的8位)I2C框图I2C基......
  • 全国产T3+FPGA的SPI与I2C通信方案分享
    近年来,随着中国新基建、中国制造2025规划的持续推进,单ARM处理器越来越难胜任工业现场的功能要求,特别是如今能源电力、工业控制、智慧医疗等行业,往往更需要ARM+FPGA架构的处理器平台来实现例如多路/高速AD采集、多路网口、多路串口、多路/高速并行DI/DO、高速数据并行处理等特定......
  • Arduino - ESP8266和ESP32的I2C接口使用(超全)
    简介深入讲解I2C通信协议,以及,Arduino和ESP8266微控制器通过I2C连接设备需要哪些引脚、该通信协议的优缺点以及如何使用I2C多路复用器详解Arduino/ESP8266与其他设备通信,例如OLED显示器、气压传感器等,可以使用I2C通信协议。也可以使用两外两个通信协议:SPI和UARTI2C全称是Inte......
  • Verdi信号平移+研发管理体系+malloc和calloc函数区别+使用__FILE__只打印文件名+使用i
    Verdi信号平移信号左移是将光标移动在双引号以内的信号名左边,然后先输入数字,可以带上单位,如[ns|n]、[ps|p],然后按<<-按键。https://blog.csdn.net/qq_40268672/article/details/132915499信号右移信号右移是数字在右边,信号在左边,用右移符号,其它不变。研发管理体系https://......
  • i2c私有数据保存
    相信在i2c驱动中,会经常看到有i2c_set_clientdatai2c_get_clientdata这两个经常碰到,知道就是保存是有数据,但是一直没有跟下去,今天得空跟了一下,一目了然不同的版本内核会有区别,我这个是基于kernel-4.19 首先看下原函数staticinlinevoidi2c_set_clientdata(structi2c_......
  • STM32CubeMX教程19 I2C - MPU6050驱动
    1、准备材料正点原子stm32f407探索者开发板V2.4STM32CubeMX软件(Version6.10.0)野火DAP仿真器keilµVision5IDE(MDK-Arm)ST-LINK/V2驱动XCOMV2.6串口助手逻辑分析仪nanoDLA2、实验目标使用STM32CubeMX软件配置STM32F407开发板的I2C1与MPU6050芯片通信,读取MPU6050的三轴加......
  • 【驱动】I2C驱动分析(二)-驱动框架
    I2C驱动框架简介I2C驱动属于总线-设备-驱动模型的,与I2C总线设备驱动模型相比,大体框架是一样,系统的整体框架如下所示。最上层是应用层,在应用层用户可以直接用openreadwrite对设备进行操作,往下是设备驱动层,这个就是外围的比如一些用I2C总线连接到SOC的传感器或者EEPROM的驱......
  • 【驱动】I2C驱动分析(三)-关键数据类型
    I2Cbusi2c_bus_type用于表示I2C总线类型。bus_type是Linux内核中用于表示总线类型的结构体,用于管理该类型总线上的设备。structbus_typei2c_bus_type={ .name ="i2c", .match =i2c_device_match, .probe =i2c_device_probe, .remove =i2c_device_remove,......
  • 【驱动】I2C驱动分析(五)-模拟I2C驱动
    在drivers/i2c/busses下包含各种I2C总线驱动,使用GPIO模拟I2C总线的驱动i2c-gpio.c,这里只分析i2c-gpio.c。i2c-gpio.c它是gpio模拟I2C总线的驱动,总线也是个设备,在这里将总线当作平台设备处理,那驱动当然是平台设备驱动,看它的驱动注册和注销函数。i2c_gpio_initi2c_gpio_init调用......