基于I2C协议的AHT20温湿度传感器的数据采集

一、I2C总线通信协议

软件I2C

        软件I2C,也称为模拟I2C或bit-bang I2C,是一种通过微控制器的通用输入输出(GPIO)引脚来模拟I2C总线通信的方式。它不依赖于专门的硬件I2C接口,而是通过编程控制GPIO引脚的电平状态来实现I2C协议的数据传输。在软件I2C中,通常需要两个GPIO引脚:一个是SCL(时钟线),另一个是SDA(数据线)。通过精确地控制这两个引脚上的电压变化,可以发送和接收数据。

硬件I2C

        硬件I2C是一种利用微控制器或其他设备上的专用硬件模块来进行I2C通信的方法。这种硬件模块内置了I2C协议的逻辑,能够自动处理时钟信号(SCL)和数据线(SDA)的操作,从而允许微控制器以更高效和可靠的方式与其他I2C兼容设备通信。

二、AHT20芯片

        了解AHT20芯片的相关信息,具体信息请到官方下载对应产品介绍文档。
        资料链接:http://www.aosong.com/class-36.html        
        官方代码使用的是PB14,PB15引脚需要修改对应的引脚才可以正常使用。

下图为AHT20芯片的典型电路(芯片正面有孔)。

三、工程配置

        要求:每隔2秒钟采集一次温湿度数据,显示到OLED上,同时通过串口发送到上位机的“串口助手”软件。
        首先进入CubeMX新疆工程,选择STM32F103C8T6芯片。

1.RCC配置。

2.SYS配置。

3.TIM1配置。

4.UASART串口配置。

5.I2C1配置(用于AHT20)。

6..I2C2配置(用于u8g2)。

7.时钟树配置。

8.代码配置。

四、代码修改

首先参考作者上篇文章进行u8g2的基础配置,以及字模的获取。
STM32—U8g2图形库练习

然后在usart.c文件中添加如下代码(添加头文件#include "stdio.h")。

 /* USER CODE BEGIN 1 */
 int fputc(int ch,FILE *f){
     HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,0xffff);
     return ch;
 }
 /* USER CODE END 1 */

main.c文件修改

 #include "main.h"
 #include "dma.h"
 #include "i2c.h"
 #include "tim.h"
 #include "usart.h"
 #include "gpio.h"
 #include "u8g2.h"
 ​
 /* Private includes ----------------------------------------------------------*/
 /* USER CODE BEGIN Includes */
 #include<stdio.h>
 /* USER CODE END Includes */
 ​
 /* Private typedef -----------------------------------------------------------*/
 /* USER CODE BEGIN PTD */
 ​
 //温
 static const unsigned char  wen[] =
 {0x00,0x00,0xC4,0x1F,0x48,0x10,0x48,0x10,0xC1,0x1F,0x42,0x10,0x42,0x10,0xC8,0x1F,0x08,0x00,0xE4,0x3F,0x27,0x25,0x24,0x25,0x24,0x25,0x24,0x25,0xF4,0x7F,0x00,0x00};
 ​
 //湿
 static const unsigned char  shi[] ={0x00,0x00,0xE4,0x1F,0x28,0x10,0x28,0x10,0xE1,0x1F,0x22,0x10,0x22,0x10,0xE8,0x1F,0x88,0x04,0x84,0x04,0x97,0x24,0xA4,0x14,0xC4,0x0C,0x84,0x04,0xF4,0x7F,0x00,0x00};
 ​
 //度 
 static const unsigned char  du[] ={0x80,0x00,0x00,0x01,0xFC,0x7F,0x44,0x04,0x44,0x04,0xFC,0x3F,0x44,0x04,0x44,0x04,0xC4,0x07,0x04,0x00,0xF4,0x0F,0x24,0x08,0x42,0x04,0x82,0x03,0x61,0x0C,0x1C,0x70};
 ​
 //待 
 static const unsigned char  dai[]={0x10,0x02,0x10,0x02,0x08,0x02,0xC4,0x3F,0x12,0x02,0x10,0x02,0xE8,0x7F,0x0C,0x08,0x0A,0x08,0xE9,0x7F,0x08,0x08,0x48,0x08,0x88,0x08,0x88,0x08,0x08,0x0A,0x08,0x04};
 ​
 //检 
 static const unsigned char  jian[]={0x08,0x02,0x08,0x02,0x08,0x05,0x08,0x05,0xBF,0x08,0x48,0x10,0xAC,0x6F,0x1C,0x00,0x2A,0x11,0x0A,0x12,0x49,0x12,0x88,0x0A,0x88,0x08,0x08,0x04,0xE8,0x7F,0x08,0x00};
 ​
 //测 
 static const unsigned char  che[]={0x00,0x20,0xE4,0x23,0x28,0x22,0x28,0x2A,0xA1,0x2A,0xA2,0x2A,0xA2,0x2A,0xA8,0x2A,0xA8,0x2A,0xA4,0x2A,0xA7,0x2A,0x84,0x20,0x44,0x21,0x44,0x22,0x24,0x28,0x10,0x10};
 ​
 /* USER CODE END PTD */
 ​
 /* Private define ------------------------------------------------------------*/
 /* USER CODE BEGIN PD */
 ​
 /* USER CODE END PD */
 ​
 /* Private macro -------------------------------------------------------------*/
 /* USER CODE BEGIN PM */
 ​
 /* USER CODE END PM */
 ​
 /* Private variables ---------------------------------------------------------*/
 ​
 /* USER CODE BEGIN PV */
 ​
 /* USER CODE END PV */
 ​
 /* Private function prototypes -----------------------------------------------*/
 void SystemClock_Config(void);
 /* USER CODE BEGIN PFP */
 ​
 /* USER CODE END PFP */
 ​
 /* Private user code ---------------------------------------------------------*/
 /* USER CODE BEGIN 0 */
 ​
 void oled_write(int temperature,int humidity){
 ​
     char t[5]; // 创建一个足够大的字符数组来存储转换后的数字
     char h[5];
     double t1=( double)temperature;
     double h1=(double)humidity;
   sprintf(t, "%.2f",t1/10 ); // 使用sprintf将int变量转换为字符串
     sprintf(h, "%.2f",h1/10);
     
     u8g2_t u8g2;
   u8g2Init(&u8g2);  
     u8g2_ClearBuffer(&u8g2); 
     u8g2_SetFont(&u8g2,u8g2_font_ncenB12_tf);//设置字体格式
     u8g2_DrawXBMP(&u8g2,16,0,16,16,wen);//(参数顺序依次是,结构体、x、y、字宽、字高、储存要显示的字点阵的数组)
     u8g2_DrawXBMP(&u8g2,32,0,16,16,du);
     u8g2_DrawStr(&u8g2,48,16,":");
     u8g2_DrawXBMP(&u8g2,16,32,16,16,shi);
     u8g2_DrawXBMP(&u8g2,32,32,16,16,du);
     u8g2_DrawStr(&u8g2,48,48,":");
     u8g2_DrawUTF8(&u8g2,55,16,t);
     u8g2_DrawUTF8(&u8g2,55,48,h);
     
     u8g2_SendBuffer(&u8g2);
  }
  void oled_write_init(){
     u8g2_t u8g2;
   u8g2Init(&u8g2);  
     u8g2_ClearBuffer(&u8g2); 
     u8g2_SetFont(&u8g2,u8g2_font_ncenB12_tf);//设置字体格式
     u8g2_DrawXBMP(&u8g2,16,0,16,16,wen);//(参数顺序依次是,结构体、x、y、字宽、字高、储存要显示的字点阵的数组)
     u8g2_DrawXBMP(&u8g2,32,0,16,16,du);
     u8g2_DrawStr(&u8g2,48,16,":");
     u8g2_DrawXBMP(&u8g2,16,32,16,16,shi);
     u8g2_DrawXBMP(&u8g2,32,32,16,16,du);
     u8g2_DrawStr(&u8g2,48,48,":");
     u8g2_DrawXBMP(&u8g2,58,0,16,16,dai);
     u8g2_DrawXBMP(&u8g2,74,0,16,16,jian);
     u8g2_DrawXBMP(&u8g2,90,0,16,16,che);
     u8g2_DrawXBMP(&u8g2,58,32,16,16,dai);
     u8g2_DrawXBMP(&u8g2,74,32,16,16,jian);
     u8g2_DrawXBMP(&u8g2,90,32,16,16,che);
     u8g2_SendBuffer(&u8g2);
  }
 ​
 /* USER CODE END 0 */
 ​
 /**
   * @brief  The application entry point.
   * @retval int
   */
 int main(void)
 {
 ​
   /* USER CODE BEGIN 1 */
     uint32_t CT_data[2]={0,0};
     volatile int  c1,t1;
     
     Delay_1ms(500);
   /* USER CODE END 1 */
 ​
   /* MCU Configuration--------------------------------------------------------*/
 ​
   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
   HAL_Init();
 ​
   /* USER CODE BEGIN Init */
 ​
   /* USER CODE END Init */
 ​
   /* Configure the system clock */
   SystemClock_Config();
 ​
   /* USER CODE BEGIN SysInit */
 ​
   /* USER CODE END SysInit */
 ​
   /* Initialize all configured peripherals */
   MX_GPIO_Init();
   MX_DMA_Init();
   MX_USART1_UART_Init();
   MX_I2C1_Init();
   MX_TIM1_Init();
   MX_I2C2_Init();
   /* USER CODE BEGIN 2 */
     
     //初始化AHT20
     AHT20_Init();
     Delay_1ms(500);
     u8g2_t u8g2;
   u8g2Init(&u8g2);
     
   /* USER CODE END 2 */
 ​
   /* Infinite loop */
   /* USER CODE BEGIN WHILE */
     oled_write_init();
   while (1)
   {
     /* USER CODE END WHILE */
 ​
         AHT20_Read_CTdata(CT_data);       //不经过CRC校验,直接读取AHT20的温度和湿度数据    推荐每隔大于1S读一次
         //AHT20_Read_CTdata_crc(CT_data);  //crc校验后,读取AHT20的温度和湿度数据 
     
 ​
         c1 = CT_data[0]*1000/1024/1024;  //计算得到湿度值c1(放大了10倍)
         t1 = CT_data[1]*2000/1024/1024-500;//计算得到温度值t1(放大了10倍)
         printf("正在检测");
         for(int i=0;i<10;i++)
         {
             HAL_Delay(100);
             printf(".");
         }
         printf("\r\n");
         HAL_Delay(1000);
         printf("温度:%d%d.%d",t1/100,(t1/10)%10,t1%10);
         printf("湿度:%d%d.%d",c1/100,(c1/10)%10,c1%10);
         printf("\r\n");
         printf("等待");
         for(int i=0;i<10;i++)
         {
             HAL_Delay(100);
             printf(".");
         }
         printf("\r\n");
         HAL_Delay(1000);
         oled_write(t1,c1);
         
     /* USER CODE BEGIN 3 */
   }
   /* USER CODE END 3 */
 }
 ​

五、实验结果

六、总结

        本次STM32编程练习结合了串口通信、AHT20的温湿度检测和u8g2的oled显示,让我学到了很多。

七、参考资料

stm32通过I2C接口实现温湿度(AHT20)的采集

I2C总线通信协议及实操stm32通过I2C实现温湿度(AHT20)采集 

STM32F103基于I2C协议的AHT20温湿度传感器的数据采集(HAL库,提供源码)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/736811.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

我在高职教STM32——LCD液晶显示(3)

大家好&#xff0c;我是老耿&#xff0c;高职青椒一枚&#xff0c;一直从事单片机、嵌入式、物联网等课程的教学。对于高职的学生层次&#xff0c;同行应该都懂的&#xff0c;老师在课堂上教学几乎是没什么成就感的。正因如此&#xff0c;才有了借助 CSDN 平台寻求认同感和成就…

前端开发流程与技术选型

目录 一、简介 二、前端职责 三、开发步骤 四、技术选型 五、页面展示 一、简介 做一个网站时&#xff0c;能看到的一切都是前端程序员的工作&#xff0c;负责网页或者app的结构、样式、用户操作网站时的事件逻辑&#xff08;比如点击一个按钮&#xff09;。 二、前端职…

一、系统学习微服务遇到的问题集合

1、启动了nacos服务&#xff0c;没有在注册列表 应该是版本问题 Alibaba-nacos版本 nacos-文档 Spring Cloud Alibaba-中文 Spring-Cloud-Alibaba-英文 Spring-Cloud-Gateway 写的很好的一篇文章 在Spring initial上面配置 start.aliyun.com 重新下载 < 2、 No Feign…

嵌入式系统中的加解密签名

笔者来了解一下嵌入式系统中的加解密 1、背景与名词解释 笔者最近在做安全升级相关的模块&#xff0c;碰到了一些相关的概念和一些应用场景&#xff0c;特来学习记录一下。 1.1 名词解释 对称加密&#xff1a;对称加密是一种加密方法&#xff0c;使用相同的密钥&#xff08;…

力扣刷题 杨辉三角(使用c++ vector解法)

杨辉三角 题目描述示例1示例2提示:代码 题目描述 给定一个非负整数 numRows&#xff0c;生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 示例1 输入: numRows 5 输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]] 示例2 …

4、SpringMVC 实战小项目【加法计算器、用户登录、留言板、图书管理系统】

SpringMVC 实战小项目 3.1 加法计算器3.1.1 准备⼯作前端 3.1.2 约定前后端交互接⼝需求分析接⼝定义请求参数:响应数据: 3.1.3 服务器代码 3.2 ⽤⼾登录3.2.1 准备⼯作3.2.2 约定前后端交互接⼝3.2.3 实现服务器端代码 3.3 留⾔板实现服务器端代码 3.4 图书管理系统准备后端 3…

【内存管理】页面分配机制

前言 Linux内核中是如何分配出页面的&#xff0c;如果我们站在CPU的角度去看这个问题&#xff0c;CPU能分配出来的页面是以物理页面为单位的。也就是我们计算机中常讲的分页机制。本文就看下Linux内核是如何管理&#xff0c;释放和分配这些物理页面的。 伙伴算法 伙伴系统的…

Visual Studio开发环境搭建

原文&#xff1a;https://blog.c12th.cn/archives/25.html Visual Studio开发环境搭建 测试&#xff1a;笔记本原装操作系统&#xff1a;Windows 10 家庭中文版 资源分享链接&#xff1a;提取码&#xff1a;qbt2 注意事项&#xff1a;注意查看本地硬盘是否够用&#xff0c;建议…

在阿里云使用Docker部署MySQL服务,并且通过IDEA进行连接

阿里云使用Docker部署MySQL服务&#xff0c;并且通过IDEA进行连接 这里演示如何使用阿里云来进行MySQL的部署&#xff0c;系统使用的是Linux系统 (Ubuntu)。 为什么使用Docker? 首先是因为它的可移植性可以在任何有Docker环境的系统上运行应用&#xff0c;避免了在不通操作系…

SpringBoot+ENC实现密钥加密及使用原理

&#x1f60a; 作者&#xff1a; 一恍过去 &#x1f496; 主页&#xff1a; https://blog.csdn.net/zhuocailing3390 &#x1f38a; 社区&#xff1a; Java技术栈交流 &#x1f389; 主题&#xff1a; SpringBootENC实现密钥加密及使用原理 ⏱️ 创作时间&#xff1a; 202…

AtCoder Beginner Contest 359 A~C(D~F更新中...)

A.Count Takahashi 题意 给出 N N N个字符串&#xff0c;每个字符串为以下两种字符串之一&#xff1a; "Takahashi" "Aoki" 请你统计"Takahashi"出现了多少次。 分析 输入并统计即可。 代码 #include <bits/stdc.h>using namespa…

web集群-nginx(nginx三种文件模块,nginx用户请求流程,域名访问网站,虚拟主机,搭建大型直播购物平台)

nginx文件模块 lineinfile未来修改配置文件使用&#xff0c;类似于sed -i ‘sg’ 和sed ‘cai’ 掌握file模块&#xff1a;创建文件&#xff0c;目录&#xff0c;创建软链接&#xff0c;修改权限和所有者&#xff0c;删除文件目录 服务管理systemd systemctl相当于linux sys…

[stm32]温湿度采集与OLED显示

一、I2C总线协议 I2C&#xff08;Inter-integrated circuit &#xff09;是一种允许从不同的芯片或电路与不同的主芯片通信的协议。它仅用于短距离通信&#xff0c;是一种用于两个或多个设备之间进行数据传输的串行总线技术&#xff0c;它可以让你在微处理器、传感器、存储器、…

UE5开发游戏Tutorial

文章目录 PlayerStart 初始化设置默认 LevelBP_Character 初始化BP_Character 添加动画BP_Character 攻击BP_Enemy 初始化 以及 AI 运动Camera Collision 相机碰撞BP_Character 生命以及伤害Wave Spawner 波生成UI 初始化以及 Damage Screen指定位置随机生成添加声音环境 Envir…

使用SpringCache实现Redis缓存

目录 一 什么是Spring Cache 二 Spring Cache 各注解作用 ①EnableCaching ②Cacheable ③CachePut ④CacheEvict 三实现步骤 ①导入spring cache依赖和Redis依赖 ②配置Redis连接信息 ③在启动类上加上开启spring cache的注解 ④ 在对应的方法上加上需要的注解 一 什么…

PINN解偏微分方程实例4

PINN解偏微分方程实例4 一、正问题1. Diffusion equation2. Burgers’ equation3. Allen–Cahn equation4. Wave equation 二、反问题1. Burgers’ equation3. 部分代码示例 本文使用 PINN解偏微分方程实例1中展示的代码求解了以四个具体的偏微分方程&#xff0c;包括Diffusio…

长亭谛听教程部署和详细教程

PPT 图片先挂着 挺概念的 谛听的能力 hw的时候可能会问你用过的安全产品能力能加分挺重要 溯源反制 反制很重要感觉很厉害 取证分析 诱捕牵制 其实就是蜜罐 有模板直接爬取某些网页模板进行伪装 部署要求 挺低的 对linux内核版本有要求 需要root 还有系统配置也要修改 …

论文阅读--Efficient Hybrid Zoom using Camera Fusion on Mobile Phones

这是谷歌影像团队 2023 年发表在 Siggraph Asia 上的一篇文章&#xff0c;主要介绍的是利用多摄融合的思路进行变焦。 单反相机因为卓越的硬件性能&#xff0c;可以非常方便的实现光学变焦。不过目前的智能手机&#xff0c;受制于物理空间的限制&#xff0c;还不能做到像单反一…

long long ago

一、long 众所周知&#xff0c;英文单词 long&#xff0c;表示长,长的。 但是&#xff0c;还有很多你不知道到的东西&#xff0c;根据英文单词首字母象形原则&#xff0c;我们可以做一下单词long结构分析&#xff1a; long l长 ong长 什么意思&#xff1f;就是说首字线 l…

Maven的依赖传递、依赖管理、依赖作用域

在Maven项目中通常会引入大量依赖&#xff0c;但依赖管理不当&#xff0c;会造成版本混乱冲突或者目标包臃肿。因此&#xff0c;我们以SpringBoot为例&#xff0c;从三方面探索依赖的使用规则。 1、 依赖传递 依赖是会传递的&#xff0c;依赖的依赖也会连带引入。例如在项目中…