STM32温湿度采集与OLED显示

STM32温湿度采集与OLED显示

一、温湿度采集

题目:学习I2C总线通信协议,使用STM32F103完成基于I2C协议的AHT20温湿度传感器的数据采集,并将采集的温度-湿度值通过串口输出

1.学习I2C总线通信协议

硬件 I2C
  1. 基本概念
    硬件 I2C 是指微控制器(如单片机等)内部集成了专门用于实现 I2C 通信协议的硬件模块。这个硬件模块由芯片厂商设计并集成在芯片内部,它能自动按照 I2C 协议规定的时序来产生时钟信号(SCL,Serial Clock Line)、控制数据传输线(SDA,Serial Data Line)的电平变化,从而完成数据的发送和接收操作。
  2. 工作原理及特点
    • 时序控制精确:硬件 I2C 模块内部的电路按照标准的 I2C 协议时序逻辑来运行,例如起始条件(SCL 为高电平时,SDA 由高电平向低电平跳变)、停止条件(SCL 为高电平时,SDA 由低电平向高电平跳变)以及数据位的采样和发送等操作,其时间控制都非常精准,由硬件电路本身的时钟驱动来保证符合协议要求,能够可靠地实现高速稳定的数据传输。
    • 减轻 CPU 负担:因为整个 I2C 通信过程中的复杂时序操作都由硬件模块自动处理,不需要 CPU 频繁地介入去手动控制引脚电平变化以及进行严格的时间延迟控制等,CPU 只需要配置好相关寄存器(如设置 I2C 通信的从机地址、通信速率等参数),然后发起传输请求以及在传输完成后去读取接收到的数据或者检查传输状态等,所以大大节省了 CPU 资源,使得 CPU 可以有更多精力去处理其他任务,比如同时进行数据运算、控制其他外设等。
    • 通信速率相对较高:由于硬件电路的优化设计,硬件 I2C 通常能支持较高的通信速率,在一些高性能微控制器中可以达到较高的时钟频率,实现快速的数据交换,满足对实时性要求较高、数据量较大的应用场景,像在一些传感器数据的快速采集以及存储设备快速读写等应用中比较有优势。
软件 I2C
  1. 基本概念
    软件 I2C 则是通过软件编程的方式,利用微控制器普通的通用输入输出引脚(GPIO 引脚)来模拟 I2C 协议规定的时序进行数据通信。也就是说,它并没有使用芯片内部专门的 I2C 硬件模块,而是完全依靠 CPU 执行程序代码,手动控制相应 GPIO 引脚的电平高低变化以及精确的时间延迟来模仿 I2C 的各种操作,比如产生起始信号、停止信号、发送和接收每一位数据等。
  2. 工作原理及特点
    • 灵活度高:可以在任何没有内置硬件 I2C 模块的微控制器上或者即使有硬件 I2C 但需要额外特殊功能的情况下实现 I2C 通信。只要微控制器有可用的 GPIO 引脚,就能通过编程来模拟 I2C 时序,方便移植到不同的硬件平台上。比如一些比较简单的、资源有限的 8 位单片机,如果本身不带硬件 I2C,就能用软件模拟的方式来实现与 I2C 设备通信。
    • 对硬件资源要求低:不需要芯片内部有专门的 I2C 硬件电路支持,仅利用 GPIO 引脚就可以开展,尤其适用于引脚资源相对丰富但功能集成度不是特别高的微控制器,降低了对特定硬件模块的依赖,节约了硬件成本。
    • 实现相对复杂且速率受限:由于所有的 I2C 协议时序都是靠软件代码控制 GPIO 引脚电平变化来实现的,这就需要编写大量精确的延时函数来保证每个操作符合 I2C 协议的时间要求,比如要精确控制 SCL 时钟信号的高低电平持续时间、SDA 数据信号在合适时间变化等。而且 CPU 需要花费较多时间在控制这些引脚电平以及等待合适的延迟时间上,这就导致整体通信速率相对硬件 I2C 来说会比较低,不太适合对高速通信要求较高的应用场景。

2.将采集的温度-湿度值通过串口输出

1.首先打开stm32CubeMX,建立新工程选择自己使用的芯片类型,然后开始配置

配置RCC

在这里插入图片描述

配置SYS

在这里插入图片描述

配置12C1,连接温湿度传感器,其使用的引脚在CubeMX中,如下图

在这里插入图片描述

配置USART

在这里插入图片描述

配置时钟树

在这里插入图片描述

配置工程

在这里插入图片描述

打开keil工程

在这里插入图片描述

2.keil代码编写和烧录

首先创建一个左侧的文件,命名为AHT20

在这里插入图片描述

然后添加自己的文件,点击右键选择添加新的文件

在这里插入图片描述

选择文件类型,我们需要添加一个.c和.h,所以需要操作两次,给文件自己命名

在这里插入图片描述

然后aht20.c中代码

#include "aht20.h"

#define AHT20_ADDRESS 0x70 // 从机地址
//AHT20 的驱动程序
 void AHT20_Init () //AHT20初始化函数  记住要在"aht20.h"中声明
{
  uint8_t readBuffer;//用于接收状态信息
  HAL_Delay(40);
  HAL_I2C_Master_Receive(&hi2c1, AHT20_ADDRESS, &readBuffer, 1, HAL_MAX_DELAY);//I2C读取函数,读数据函数 readBuffer此时获得了一个字节的状态字。
  if((readBuffer & 0x08) == 0x00) //判断第三位是否为0 发送0xBE命令初始化
  {
	  uint8_t sendBuffer [3] = {0xBE , 0x08 , 0x00};
	  HAL_I2C_Master_Transmit(&hi2c1, AHT20_ADDRESS, sendBuffer, 3, HAL_MAX_DELAY);//I2C发送函数
  }

}

 void AHT20_Read(float *Temperature , float *Humidity) //AHT20读取温度湿度函数  记住要在"aht20.h"中声明
{
	uint8_t sendBuffer [3] = {0xAC , 0x33 , 0x00};
	uint8_t readBuffer [6];
	HAL_I2C_Master_Transmit(&hi2c1, AHT20_ADDRESS, sendBuffer, 3, HAL_MAX_DELAY);
	HAL_Delay(75);
	HAL_I2C_Master_Receive(&hi2c1, AHT20_ADDRESS, readBuffer, 6, HAL_MAX_DELAY);
	if((readBuffer[0] & 0x80) == 0x00)
	{
		uint32_t date = 0;//接收温湿度需要2个半字节 所以要32
		date = ((uint32_t )readBuffer[3] >> 4) + ((uint32_t )readBuffer[2] << 4) + ((uint32_t )readBuffer[1] << 12);//对数据进行移位拼接.
		*Humidity = date * 100.0f / (1 << 20);//(1 << 20) 意为2的20次方. 乘100.0可以表示为百分数

		date = (((uint32_t )readBuffer[3] & 0x0F)<< 16) + ((uint32_t )readBuffer[4] << 8) + (uint32_t )readBuffer[5];//& 0x0F: 将这个无符号整数与十六进制数0x0F进行按位与操作。0x0F的二进制表示为00001111,这个操作会保留readBuffer[3]的低四位,即将高四位清零。
		*Temperature = date * 200.0f / (1 << 20) - 50;
	}
}


aht20.h中代码

/*
 * aht20.h
 *
 *  Created on: Apr 25, 2024
 *      Author: lenovo
 */

#ifndef INC_AHT20_H_
#define INC_AHT20_H_

#include "i2c.h"
 void AHT20_Init (void);

 void AHT20_Read(float *Temperature , float *Humidity);
#endif /* INC_AHT20_H_ */


找到文件的位置创建AHT20文件夹,然后将创建的两个文件剪切到里面

在这里插入图片描述

在这里插入图片描述

然后在keil中添加读取文件的路径,

在这里插入图片描述

重新打开下面的页面,用右面的❌将两个文件删除,重新点击下面的添加文件,找到文件所在位置重新添加进去

在这里插入图片描述

修改main函数为

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2024 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "i2c.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "i2c.h"
#include <stdio.h>
#include "string.h"
#include "aht20.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* 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 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* 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_I2C1_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
  AHT20_Init ();//初始化AHT20

  float temperature , humidity ;
  char message [50];
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	  AHT20_Read( &temperature , &humidity); //读取AHT20
	  sprintf(message ,"温度: %f℃ , 湿度: %f.\r\n",temperature , humidity);//拼接
	  HAL_UART_Transmit(&huart1, (uint8_t*)message,strlen(message) , HAL_MAX_DELAY);//串口发???函??
	  HAL_Delay(1000);
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInit
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值