电子产业一站式赋能平台

PCB联盟网

搜索
查看: 902|回复: 0
收起左侧

【HarmonyOS_Hi3861学习笔记】【连载】--oled上显示温湿度信息

[复制链接]

2607

主题

2607

帖子

7472

积分

高级会员

Rank: 5Rank: 5

积分
7472
发表于 2021-1-9 11:56:37 | 显示全部楼层 |阅读模式
【HarmonyOS_Hi3861学习笔记】【连载】--oled上显示温湿度信息, 写在前面的话:这个demo需要结合前面的oLED部分。另外在调试aht20的驱动的时候遇到有问题,卡了差不多两三天吧。今天晚上才解决掉。明天上午单独发个贴说明怎定位问题并解决问题的。

AHT20和OLED一样都是I2C驱动的。有了前面oled的基础了,移植这个的驱动就简单很多了。

查看原理图可以看到,AHT20和OLED共用相同的I2C,都是GPIO13_I2C0_SDA、GPIO4_I2C0_SCL.只是地址有区分而已。





查看AHT20 的数据手册,得到其地址为0x38,读命令为0x71,写命令为0x70;



剩下的就是根据手册中的读取流程读取数据就行了。



Snipaste_2021-01-08_22-23-32.png (365.41 KB, 下载次数: 0)

下载附件  保存到相册  

读取流程

昨天 22:24 上传



如下是demo程序




  •   
  • static hi_u32 aht20_i2c_write(hi_u8 *sendbuf, hi_u32 send_len)
      
  • {
      
  •     hi_u32 status;
      
  •     hi_i2c_data aht20_i2c_data = { 0 };
      

  •   
  •     aht20_i2c_data.send_buf = sendbuf;
      
  •     aht20_i2c_data.send_len = send_len;
      
  •     status = hi_i2c_write(HI_I2C_IDX_0, AHT20_SLAVE_WRITE_ADDR, &aht20_i2c_data);
      
  •     if (status != HI_ERR_SUCCESS) {
      
  •         printf(“===== Error: AHT20 I2C write status = 0x%x! =====\r\n“, status);
      
  •         return status;
      
  •     }
      

  •   
  •     return HI_ERR_SUCCESS;
      
  • }
      

  •   
  • static hi_u32 aht20_i2c_read(hi_u8 *recvbuf, hi_u32 read_len)
      
  • {
      
  •     hi_u32 status;
      
  •     hi_i2c_data aht20_i2c_data = {0};
      

  •   
  •     aht20_i2c_data.receive_buf = recvbuf;
      
  •     aht20_i2c_data.receive_len = read_len;
      
  •     status = hi_i2c_read(HI_I2C_IDX_0, AHT20_SLAVE_READ_ADDR, &aht20_i2c_data);
      
  •     if (status != HI_ERR_SUCCESS) {
      
  •         printf(“===== Error: AHT20 I2C read status = 0x%x! =====\r\n“, status);
      
  •         return status;
      
  •     }
      

  •   
  •     return HI_ERR_SUCCESS;
      
  • }
      

  •   
  • /**
      
  •   * @Brief  读AHT20 设备状态字
      
  •   * @param  void
      
  •   * @retval hi_u8 设备状态字
      
  •   */
      
  • static hi_u8 AHT20_ReadStatusCmd(void)
      
  • {
      
  •     hi_u8 tmp = 0;
      
  •         aht20_i2c_read(&tmp, 1);
      
  •         return tmp;
      
  • }
      

  •   
  • /**
      
  •   * @brief  读AHT20 设备状态字 中的Bit3: 校准使能位
      
  •   * @param  void
      
  •   * @retval hi_u8 校准使能位:1 - 已校准; 0 - 未校准
      
  •   */
      
  • static hi_u8 AHT20_ReadCalEnableCmd(void)
      
  • {
      
  •         hi_u8 tmp;
      
  •         tmp = AHT20_ReadStatusCmd();
      
  •         return (tmp>>3)&0x01;
      
  • }
      

  •   
  • /**
      
  •   * @brief  读AHT20 设备状态字 中的Bit7: 忙标志
      
  •   * @param  void
      
  •   * @retval hi_u8 忙标志:1 - 设备忙; 0 - 设备空闲
      
  •   */
      
  • static hi_u8 AHT20_ReadBusyCmd(void)
      
  • {
      
  •         hi_u8 tmp;
      
  •         tmp = AHT20_ReadStatusCmd();
      
  •         return (tmp>>7)&0x01;
      
  • }
      

  •   
  • //发送获取状态字命令
      
  • static hi_u32 AHT20_StatusCmd(void)
      
  • {
      
  •     hi_u8 cmd[1] = {AHT20_STATUS_REG};
      
  •     return aht20_i2c_write(cmd, 1);
      

  •   
  • }
      
  • /**
      
  •   * @brief  AHT20 芯片初始化命令
      
  •   * @param  void
      
  •   * @retval void
      
  •   */
      
  • static hi_u32 AHT20_IcInitCmd(void)
      
  • {
      
  •         hi_u8 cmd[3] = {AHT20_INIT_REG, AHT20_INIT_REG_ARG0, AHT20_INIT_REG_ARG1};
      
  •         return aht20_i2c_write(cmd, 3);
      
  • }
      

  •   
  • /**
      
  •   * @brief  AHT20 触发测量命令
      
  •   * @param  void
      
  •   * @retval void
      
  •   */
      
  • static hi_u32 AHT20_TrigMeasureCmd(void)
      
  • {
      
  •         hi_u8 cmd[3] = {AHT20_TrigMeasure_REG, AHT20_TrigMeasure_REG_ARG0, AHT20_TrigMeasure_REG_ARG1};
      
  •         return aht20_i2c_write(cmd, 3);
      
  • }
      

  •   
  • /**
      
  •   * @brief  AHT20 软复位命令
      
  •   * @param  void
      
  •   * @retval void
      
  •   */
      
  • static hi_u32 AHT20_SoftResetCmd(void)
      
  • {
      
  •         hi_u8 cmd[1] = {AHT20_SoftReset};
      
  •         return aht20_i2c_write(cmd, 3);
      
  • }
      

  •   
  • /**
      
  •   * @brief  AHT20 设备初始化
      
  •   * @param  void
      
  •   * @retval uint8_t:0 - 初始化AHT20设备成功; 1 - 初始化AHT20失败,可能设备不存在或器件已损坏
      
  •   */
      
  • static hi_u8 AHT20_Init(void)
      
  • {
      
  •         hi_u8 rcnt = 2+1;//软复位命令 重试次数,2次
      
  •         hi_u8 icnt = 2+1;//初始化命令 重试次数,2次
      
  •         hi_u32 retVal = 0;  //记录返回状态
      

  •   
  •     usleep(40000);
      
  •         while(--rcnt)
      
  •         {
      
  •                 icnt = 2+1;
      
  •                 retVal = AHT20_StatusCmd();
      
  •         if(retVal != HI_ERR_SUCCESS)
      
  •             return retVal;
      

  •   
  •                 // 读取温湿度之前,首先检查[校准使能位]是否为1
      
  •                 while((!AHT20_ReadCalEnableCmd()) && (--icnt))// 2次重试机会
      
  •                 {
      
  •                         usleep(20000);
      
  •                         // 如果不为1,要发送初始化命令
      
  •                         AHT20_IcInitCmd();
      
  •                         usleep(40000);
      
  •                 }
      
  •                
      
  •                 if(icnt)//[校准使能位]为1,校准正常
      
  •                 {
      
  •                         break;//退出rcnt循环
      
  •                 }
      
  •                 else//[校准使能位]为0,校准错误
      
  •                 {
      
  •                         AHT20_SoftResetCmd();//软复位AHT20器件,重试
      
  •                         usleep(40000);//这个时间不确定,手册没讲
      
  •                 }
      
  •         }
      
  •         
      
  •         if(rcnt)
      
  •         {
      
  •                 usleep(10000);//这个时间不确定,手册没讲
      
  •                 return 0;// AHT20设备初始化正常
      
  •         }
      
  •         else
      
  •         {
      
  •                 return 1;// AHT20设备初始化失败
      
  •         }
      
  • }
      

  •   
  • /**
      
  •   * @brief  AHT20 设备读取 相对湿度和温度(原始数据20Bit)
      
  •   * @param  hi_u32 *HT:存储20Bit原始数据的uint32数组
      
  •   * @retval uint8_t:0-读取数据正常; 1-读取设备失败,设备一直处于忙状态,不能获取数据
      
  •   */
      
  • static hi_u8 AHT20_ReadHT(hi_u32 *HT)
      
  • {
      
  •         hi_u8 cnt=3+1;//忙标志 重试次数,3次
      
  •         hi_u8 tmp[6];
      
  •         hi_u32 RetuData = 0;
      
  •         
      
  •         // 发送触发测量命令
      
  •         AHT20_TrigMeasureCmd();
      
  •         
      
  •         do{
      
  •                 usleep(76000);//等待75ms待测量完成,忙标志Bit7为0
      
  •         }while(AHT20_ReadBusyCmd() && (--cnt));//重试3次
      
  •         
      
  •         if(cnt)//设备闲,可以读温湿度数据
      
  •         {
      
  •                 usleep(5000);
      
  •                 // 读温湿度数据
      
  •                 aht20_i2c_read(tmp, 6);
      
  •                 // 计算相对湿度RH。原始值,未计算为标准单位%。
      
  •                 RetuData = 0;
      
  •                 RetuData = (RetuData|tmp[1]) << 8;
      
  •                 RetuData = (RetuData|tmp[2]) << 8;
      
  •                 RetuData = (RetuData|tmp[3]);
      
  •                 RetuData = RetuData >> 4;
      
  •                 HT[0] = RetuData;
      
  •                
      
  •                 // 计算温度T。原始值,未计算为标准单位°C。
      
  •                 RetuData = 0;
      
  •                 RetuData = (RetuData|tmp[3]) << 8;
      
  •                 RetuData = (RetuData|tmp[4]) << 8;
      
  •                 RetuData = (RetuData|tmp[5]);
      
  •                 RetuData = RetuData&0x0fffff;
      
  •                 HT[1] = RetuData;
      
  •                
      
  •                 return 0;
      
  •         }
      
  •         else//设备忙,返回读取失败
      
  •         {
      
  •                 return 1;
      
  •         }
      
  • }
      

  •   
  • /**
      
  •   * @brief  AHT20 温湿度信号转换(由20Bit原始数据,转换为标准单位RH=%,T=°C)
      
  •   * @param  struct m_AHT20* aht:存储AHT20传感器信息的结构体
      
  •   * @retval uint8_t:0-计算数据正常; 1-计算数据失败,计算值超出元件手册规格范围
      
  •   */
      
  • static hi_u8 StandardUnitCon(struct m_AHT20* aht)
      
  • {
      
  •         aht->RH = (double)aht->HT[0] *100 / 1048576;//2^20=1048576 //原式:(double)aht->HT[0] / 1048576 *100,为了浮点精度改为现在的
      
  •         aht->Temp = (double)aht->HT[1] *200 / 1048576 -50;
      
  •         
      
  •         //限幅,RH=0~100%; Temp=-40~85°C
      
  •         if((aht->RH >=0)&&(aht->RH <=100) && (aht->Temp >=-40)&&(aht->Temp <=85))
      
  •         {
      
  •                 aht->flag = 0;
      
  •                 return 0;//测量数据正常
      
  •         }
      
  •         else
      
  •         {
      
  •                 aht->flag = 1;
      
  •                 return 1;//测量数据超出范围,错误
      
  •         }
      
  • }
      

  •   
  • #define AHT20_TASK_STACK_SIZE 1024
      
  • #define AHT20_TASK_PRIO 26
      
  • struct m_AHT20 AHT20_Reseult = {0};
      

  •   
  • static void *AHT20_Task(const char *arg)
      
  • {
      
  •     hi_u8 result = 0;
      
  •    
      
  •     hi_u32 ht_raw[2] = {0};
      
  •     (void)arg;
      
  •     usleep(100000);
      
  •     result = AHT20_Init();
      
  •     if(result == 0)
      
  •         printf(“AHT20 Init Success\r\n“);
      
  •     else
      
  •         printf(“AHT20 Init Failed\r\n“);
      
  •    
      
  •     while(1)
      
  •     {
      
  •         result = AHT20_ReadHT(ht_raw);
      
  •         if(result)
      
  •             printf(“read HT data Failed\r\n“);
      
  •         else
      
  •         {
      
  •             AHT20_Reseult.HT[0] = ht_raw[0];
      
  •             AHT20_Reseult.HT[1] = ht_raw[1];
      
  •             result = StandardUnitCon(&AHT20_Reseult);
      
  •             if(result)
      
  •                 printf(“cal HT data Failed\r\n“);
      
  •             else
      
  •             {
      
  •                 printf(“HT:%.2f temp:%.2f\r\n“, AHT20_Reseult.RH, AHT20_Reseult.Temp);
      
  •                 OLED_ShowFloat(56,32,AHT20_Reseult.RH,2,16);
      
  •                 OLED_ShowFloat(56,48,AHT20_Reseult.Temp,2,16);
      
  •                 OLED_Refresh();
      
  •             }
      
  •             
      
  •         }
      

  •   
  •         usleep(1000000);
      
  •     }
      
  •     return NULL;
      
  • }
      

  •   
  • static void AHT20ExampleEntry(void)
      
  • {
      
  •     osThreadAttr_t attr;
      

  •   
  •     attr.name = “AHT20Task“;
      
  •     attr.attr_bits = 0U;
      
  •     attr.cb_mem = NULL;
      
  •     attr.cb_size = 0U;
      
  •     attr.stack_mem = NULL;
      
  •     attr.stack_size = AHT20_TASK_STACK_SIZE;
      
  •     attr.priority = AHT20_TASK_PRIO;
      

  •   
  •     if (osThreadNew((osThreadFunc_t)AHT20_Task, NULL, &attr) == NULL) {
      
  •         printf(“[AHT20 Example] Falied to create AHT20Task!\n“);
      
  •     }
      
  • }
      

  •   
  • SYS_RUN(AHT20ExampleEntry);

复制代码

头文件内容



  • #define ATH20_SLAVE_ADDRESS                0x38                /* I2C从机地址 */
      
  • #define AHT20_SLAVE_READ_ADDR       (ATH20_SLAVE_ADDRESS<<1 | 0x01) //读命令
      
  • #define AHT20_SLAVE_WRITE_ADDR      (ATH20_SLAVE_ADDRESS<<1 | 0x00) //写命令
      

  •   
  • //****************************************
      
  • // 定义 AHT20 内部地址
      
  • //****************************************
      
  • #define        AHT20_STATUS_REG                0x71        //状态字 寄存器地址
      

  •   
  • #define        AHT20_INIT_REG                        0xBE        //初始化 寄存器地址
      
  • #define        AHT20_INIT_REG_ARG0                0x08        //初始化 寄存器参数1
      
  • #define        AHT20_INIT_REG_ARG1                0x00        //初始化 寄存器参数2
      

  •   
  • #define        AHT20_SoftReset                        0xBA        //软复位 单指令
      

  •   
  • #define        AHT20_TrigMeasure_REG        0xAC        //触发测量 寄存器地址
      
  • #define        AHT20_TrigMeasure_REG_ARG0        0x33        //触发测量 寄存器参数1
      
  • #define        AHT20_TrigMeasure_REG_ARG1        0x00        //触发测量 寄存器参数2
      

  •   
  • // 存储AHT20传感器信息的结构体
      
  • struct m_AHT20
      
  • {
      
  •         hi_u8 alive;        // 0-器件不存在; 1-器件存在
      
  •         hi_u8 flag;        // 读取/计算错误标志位。0-读取/计算数据正常; 1-读取/计算设备失败
      
  •         hi_u32 HT[2];        // 湿度、温度 原始传感器的值,20Bit
      
  •         
      
  •         float RH;                // 湿度,转换单位后的实际值,标准单位%
      
  •         float Temp;                // 温度,转换单位后的实际值,标准单位°C
      
  • };
      


复制代码 编译成功后,串口间隔1s打印温湿度信息以及oled上显示当前温湿度信息。
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /1 下一条


联系客服 关注微信 下载APP 返回顶部 返回列表