第17周实验---温湿度采集与OLED显示

一、关于软件I2C和硬件I2C的介绍和理解

I2C(Inter-Integrated Circuit)是一种由飞利浦公司(现恩智浦半导体)开发的串行通信协议,用于连接低速外围设备。它是一种多主控、多从机、半双工的通信协议,可以在同一总线上连接多个设备。

硬件I2C: 硬件I2C是指微控制器(MCU)内置的I2C接口。这种接口通过硬件电路实现I2C协议的所有功能,包括起始位、停止位、数据传输和时钟信号。使用硬件I2C时,软件只需通过内置的寄存器配置I2C模块,并读写数据,而无需手动控制I2C协议的每一个细节。硬件I2C的优点是速度快,可以减少CPU的负担,允许CPU处理其他任务。

软件I2C: 软件I2C,又称为模拟I2C,是指通过通用输入输出(GPIO)引脚,由软件程序模拟I2C协议的时序来实现的I2C通信。在软件I2C中,开发者需要编写程序来控制GPIO引脚的电平,以产生SCL(时钟线)和SDA(数据线)所需的信号。这意味着软件必须精确地控制时序,模拟起始位、停止位、确认位和数据传输。软件I2C的优点是灵活性高,可以在没有硬件I2C支持的微控制器上实现I2C通信,但缺点是速度较慢,且会占用较多的CPU资源。

简单来说,硬件I2C是利用微控制器内置的I2C硬件模块来实现的,而软件I2C是通过软件编程控制GPIO引脚来模拟I2C协议的时序。

二、每隔2秒钟采集一次温湿度数据,显示到OLED上,同时通过串口发送到上位机的“串口助手”软件

按如下图配置STM32CubeMX各个端口
在这里插入图片描述

在奥松官网下载AHT20芯片代码,之后修改对应引脚SDA和SCL

再次移植u8g2图形库,对应输出到oled即可

部分main.c代码如下:

#include "main.h"

#include "dma.h"

#include "i2c.h"

#include "usart.h"

#include "gpio.h"

  

#include <stdio.h>

#include "AHT20-21_DEMO_V1_3.h"

  

void SystemClock_Config(void);

  

int fputc(int ch, FILE *f)

  

{

  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);

  

  while (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_TC) != SET)

  {

  }

  

  return ch;

}

  

int main(void)

{

  

  uint32_t CT_data[2] = {0, 0};

  volatile int c1, t1;

  

  Delay_1ms(500);

  

  HAL_Init();

  

  SystemClock_Config();

  

  MX_GPIO_Init();

  MX_DMA_Init();

  MX_USART1_UART_Init();

  

  AHT20_Init();

  Delay_1ms(500);

  

  while (1)

  {

  

    AHT20_Read_CTdata(CT_data);

  

    c1 = CT_data[0] * 1000 / 1024 / 1024;

    t1 = CT_data[1] * 2000 / 1024 / 1024 - 500;

    printf("正在检测");

    HAL_Delay(100);

    printf(".");

    HAL_Delay(100);

    printf(".");

    HAL_Delay(100);

    printf(".");

    HAL_Delay(100);

    printf(".");

    HAL_Delay(100);

    printf(".");

    HAL_Delay(100);

    printf(".");

    HAL_Delay(100);

    printf(".");

    HAL_Delay(100);

    printf(".");

    HAL_Delay(100);

    printf(".");

    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("等待");

    HAL_Delay(100);

    printf(".");

    HAL_Delay(100);

    printf(".");

    HAL_Delay(100);

    printf(".");

    HAL_Delay(100);

    printf(".");

    HAL_Delay(100);

    printf(".");

    HAL_Delay(100);

    printf(".");

    HAL_Delay(100);

    printf(".");

    HAL_Delay(100);

    printf(".");

    HAL_Delay(100);

    printf(".");

    HAL_Delay(100);

    printf(".");

    printf("\r\n");

    HAL_Delay(1000);

  }

}

  

void SystemClock_Config(void)

{

  RCC_OscInitTypeDef RCC_OscInitStruct = {0};

  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  

  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();

  }

  

  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;

  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;

  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;

  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)

  {

    Error_Handler();

  }

}

  

void Error_Handler(void)

{

  

  __disable_irq();

  while (1)

  {

  }

}

  

#ifdef USE_FULL_ASSERT

  

void assert_failed(uint8_t *file, uint32_t line)

{

}

#endif

三、结果

串口现象:
在这里插入图片描述

oled屏幕:
在这里插入图片描述

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值