STM32基于HAL库配置IIC采集AHT20的温湿度

只要看进去就一定能收获满满!

发送命令 

在启动传输后,随后传输的I2C首字节包括7位的I2C设备地址 0x38和一个SDA方向位  x (读R:‘1’,写W:‘0’)。在第8个SCL时钟下降沿之后,通过拉低 SDA引脚 (ACK位),指示传感器数据接收正常。在发出初始化命令之后 (‘1011’1110')代表初始化,‘1010’1100’ 代表温湿度测量), MCU必须等到测量完成。注意:图中标注设备地址:0x38,后面再加上一位读写位也就是 0111000 0/1(0x70 0x71)

                       

传感器读取流程 

一共分为四步

1.上电后要等待40ms,读取温湿度值之前, 首先要看状态字的校准使能位Bit[3]是否为 1(通过发送0x71可以获取一个字节的状态字),如果不为1,要发送0xBE命令(初始化),此命令参数有两个字节, 第一个字节为0x08,第二个字节 为0x00。

2.直接发送 0xAC命令(触发测量),此命令参数 有两个字节,第一个字节为 0x33,第二个字节为0x00。

3.等待75ms待测量完成,忙状态Bit[7]为0,然 后可以读取六个字节(发0X71即可以读取)。

4.计算温湿度值。 

                             

                              

                             

根据上图,主机首先发送AHT20的数据地址0x70(实际发送的是0x71,IlC协议规定如果主机发起通信的目的是为了设置(写)从机,那这一位就为0,如果主机发起通信目的是为了从从机读取数据,那这一位就为1)不过对于这一位的设置HAL的相关函数会自动帮我们处理,所以我们一般也就认为这一位是默认为0就好了。发送完八位,也就是一字节数据,数据的接收方需要发送一个ACK信号(应答信号,就是在时钟线低电平时由接收方也就是此处的从机将数据线拉低一下)确认自己已经收到数据。

接下来就是作为从机的AHT20发送数据了:在时钟线低电平时,设置数据线,主机在时钟线高电平时读取数据线上的数据,如此反复直到发送完一字节。然后再由现在的接收方也就是主机来一次ACK信号,得到应答信号后,AHT20继续接收,如此反复,直到发送完所以数据,然后主机会在时钟线处于高电平时将数据线拉高(IIC通信的结束信号)。

一、STM32cubemx配置

我用的是STM32F103C8T6 时钟配置为72Mhz就可以了

USART 打开,用于串口传输数据

IIC配置为标准的iic模式

project Manager勾选上.c/.h文件,生成代码

右键新建AHT20的.c和.h文件

                               

用到IIC函数

HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);
HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);

功能:IIC读一个字节
参数:

*hi2c: 设置使用的是那个IIC 例:&hi2c1

DevAddress: 写入的地址 设置写入数据的地址 例 0xA0

*pDat:a 存储读取到的数据

Size: 发送的字节数

Timeout: 最大读取时间,超过时间将自动退出读取函数

AHT20.h 

#define AHT20_ADDRESS 0x70
//AHT20的初始化函数
void AHT20_Init()
{
   uint8_t readbuffer;//用于接收状态信息
   HAL_Delay(40);//延时40ms,因为第一步的上电后要等待40ms
   HAL_I2C_Master_Receive(&hi2c1,AHT20_ADDRESS , &readbuffer, 1,HAL_MAX_DELAY)//上面介绍了函数的参数作用
   if((readbuffer & 0x08) = 0x00)//根据手册,首先要看状态字的校准使能位Bit[3]是否为 1(通过发送 
                                    0x71可以获取一个字节的状态字),如果不为1,要发送0xBE命令(初 
                                    始化),此命令参数有两个字节, 第一个字节为0x08,第二个字节 
                                    为0x00。
    {
      uint8_t sendbuffer[3]={0xBE,0x08,0x00};
      HAL_I2C_Master_Transmit(&hi2c1,AHT20_ADDRESS,readbuffer,3,HAL_Max_Delay);
     }
}

根据手册读取温湿度的步骤 

2.直接发送 0xAC命令(触发测量),此命令参数 有两个字节,第一个字节为 0x33,第二个字节为0x00。

3.等待75ms待测量完成,忙状态Bit[7]为0,然后可以读取六个字节(发0X71即可以读取)。

4.计算温湿度值。

  信号转换

                        

分为两部分,红框是湿度,黄框是温度
    data = ((uint32_t)readbuff[3]>>4)+((uint32_t)readbuff[2]<<4)+((uint32_t)readbuff[1]<<12);

    *Humidity = data * 100.0f/ (1<<20);//湿度信号转换

    data = (((uint32_t)readbuff[3] & 0X0F)<<16)+((uint32_t)readbuff[4]<<8)+((uint32_t)readbuff[5]);

    *Temperature = data * 200.0f)/(1<<20) - 50;//温度信号转换

                           

AHT20.h  

void AHT20_Read(float *Temperature, float *Humidity)//读取温湿度的函数
{
   uint8_t sendbuffer[3] = {0xAC,0x33,0x00};
   uint8_t readBuffer[6];

   HAL_I2C_Master_Transmit(&hi2c1,AHT20_ADDRESS,sendbuff,3,HAL_Max_Delay);

   HAL_Delay(75);
  
   HAL_I2C_Master_Receive(&hi2c1,AHT20_ADDRESS,readbuff,1,HAL_Max_Delay);
 if((readbuff[0] & 0x80) = 0x00)
  {
    uint32_t data = 0;

    data = ((uint32_t)readbuff[3]>>4)+((uint32_t)readbuff[2]<<4)+((uint32_t)readbuff[1]<<12);

    *Humidity = data * 100.0f/ (1<<20);

    data = (((uint32_t)readbuff[3] & 0X0F)<<16)+((uint32_t)readbuff[4]<<8)+((uint32_t)readbuff[5]);

    *Temperature = data * 200.0f)/(1<<20) - 50;
}

主函数main.c 


int main()
{
  AHT20_Init();
  float temperature , humidity;
  char message [50];

  while(1)
   {
      AHT20_Read(&temperature,&humidity);
      sprintf(message,"温度:% .1f ℃,湿度: %.1f %%\r\n"temperature , humidity);
      HAL_Uart_Transmit(&huart2,(uint8_t*)message ,strlen(message),HAL_Max_Delay);
      HAL_Delay(1000);
   }
}
  • 6
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值