【STM32】STM32通过I2C实现温湿度采集与显示

2024-06-23 19:20

本文主要是介绍【STM32】STM32通过I2C实现温湿度采集与显示,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

一、I2C总线通信协议

1.I2C通信特征

2.I2C总线协议

3.软件I2C和硬件I2C

二、stm32通过I2C实现温湿度(AHT20)采集

1.stm32cube配置

RCC配置:

SYS配置:

I2C1配置:

USART1配置:

GPIO配置:

时钟配置:

project配置:

2.KEil代码配置

添加AHT20文件:

添加路径:

AHT20.c代码:

AHT20.h代码:

main.c代码:

3.实物图连接

4.实验效果

项目代码:

参考博客:


一、I2C总线通信协议

1.I2C通信特征

SCL:时钟线,用于传输CLK信号,一般是I2C主设备向从设备提供时钟的通道。 SDA: 数据线,通信数据都通过SDA线传输

I2C通信时,分为主设备和从设备,其中主设备一个、从设备多个。主设备要主导整个通信过程,从设备根据I2C协议被动的响应主设备; 主设备负责调度总线,决定某个时间和其中一个从设备通信。在同一时间,只有主设备和其中一个从设备通信,其余的从设备处于等待状态,等待主设备与其通信;每个从设备在I2C总线上都有唯一的地址,主设备就是通过地址来区分不同的从设备,从而决定和哪一个从设备通信。

2.I2C总线协议

(1)主设备发送一个起始信号; (2)主设备接着发送8bit数据,其中7位是从设备的地址,一位表示此次主设备是要读数据海思写数据; (3)和主设备发送的地址匹配的从设备发出一个ack响应信号; (4)主/从设备将数据发送到SDA总线上,每次传输都是8bit数据; (5)主/从设备从SDA线上接收数据,并发送一个ACK响应信号; (6)还可以接着n个发送和接收的过程; (7)主设备发送停止信号,停止本次通信;

3.软件I2C和硬件I2C

软件I2C:软件I2C是通过软件控制GPIO管脚来模拟I2C协议的时序。其

1.可以使用任意的GPIO管脚来实现,可适应不同的硬件平台和需求。 2.不依赖于特定的硬件电路,可在不同的平台上进行移植和使用。 3.可在没有硬件I2C支持的情况下使用,也可以用于扩展硬件I2C的功能。

硬件I2C:硬件I2C是通过专门的硬件电路实现的,通常由微控制器或其他集成电路上的硬件模块提供支持。其

1.使用专门的硬件电路,可以实现高速的数据传输。 2.传输过程由硬件电路完成,不需要CPU的干预,因此可以释放CPU的资源。 3.时序由硬件电路控制,不容易受到外部干扰的影响。

二、stm32通过I2C实现温湿度(AHT20)采集

1.stm32cube配置

RCC配置:

SYS配置:

I2C1配置:

USART1配置:

GPIO配置:

时钟配置:

project配置:

2.KEil代码配置

添加AHT20文件:

添加路径:

AHT20.c代码:

/*******************************************/
/*@????:??????????          */
/*@??:?????????                */
/*@??:V1.2                              */
/*******************************************/
//#include "main.h" 
#include "AHT20-21_DEMO_V1_3.h" 
#include "gpio.h"
#include "i2c.h"void Delay_N10us(uint32_t t)//????
{uint32_t k;while(t--){for (k = 0; k < 2; k++);//110}
}void SensorDelay_us(uint32_t t)//????
{for(t = t-2; t>0; t--){Delay_N10us(1);}
}void Delay_4us(void)		//????
{	Delay_N10us(1);Delay_N10us(1);Delay_N10us(1);Delay_N10us(1);
}
void Delay_5us(void)		//????
{	Delay_N10us(1);Delay_N10us(1);Delay_N10us(1);Delay_N10us(1);Delay_N10us(1);}void Delay_1ms(uint32_t t)		//????
{while(t--){SensorDelay_us(1000);//??1ms}
}//void AHT20_Clock_Init(void)		//????
//{
//	RCC_APB2PeriphClockCmd(CC_APB2Periph_GPIOB,ENABLE);
//}void SDA_Pin_Output_High(void)   //?PB7????? , ???????, PB7??I2C?SDA
{GPIO_InitTypeDef  GPIO_InitStruct;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;//????GPIO_InitStruct.Pin = GPIO_PIN_7;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOB,& GPIO_InitStruct);HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_SET);
}void SDA_Pin_Output_Low(void)  //?P7?????  ???????
{GPIO_InitTypeDef  GPIO_InitStruct;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;//????GPIO_InitStruct.Pin = GPIO_PIN_7;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOB,& GPIO_InitStruct);HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_RESET);
}void SDA_Pin_IN_FLOATING(void)  //SDA???????
{GPIO_InitTypeDef  GPIO_InitStruct;GPIO_InitStruct.Mode = GPIO_MODE_INPUT;//??GPIO_InitStruct.Pin = GPIO_PIN_7;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init( GPIOB,&GPIO_InitStruct);
}void SCL_Pin_Output_High(void) //SCL?????,P14??I2C?SCL
{HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_SET);
}void SCL_Pin_Output_Low(void) //SCL?????
{HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_RESET);
}void Init_I2C_Sensor_Port(void) //???I2C??,??????
{	GPIO_InitTypeDef  GPIO_InitStruct;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;//????GPIO_InitStruct.Pin = GPIO_PIN_7;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOB,& GPIO_InitStruct);HAL_GPIO_WritePin(GPIOB,GPIO_PIN_15,GPIO_PIN_SET);GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;//????GPIO_InitStruct.Pin = GPIO_PIN_6;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOB,& GPIO_InitStruct);HAL_GPIO_WritePin(GPIOB,GPIO_PIN_15,GPIO_PIN_SET);}
void I2C_Start(void)		 //I2C????START??
{SDA_Pin_Output_High();SensorDelay_us(8);SCL_Pin_Output_High();SensorDelay_us(8);SDA_Pin_Output_Low();SensorDelay_us(8);SCL_Pin_Output_Low();SensorDelay_us(8);   
}void AHT20_WR_Byte(uint8_t Byte) //?AHT20?????
{uint8_t Data,N,i;	Data=Byte;i = 0x80;for(N=0;N<8;N++){SCL_Pin_Output_Low(); Delay_4us();	if(i&Data){SDA_Pin_Output_High();}else{SDA_Pin_Output_Low();}	SCL_Pin_Output_High();Delay_4us();Data <<= 1;}SCL_Pin_Output_Low();SensorDelay_us(8);   SDA_Pin_IN_FLOATING();SensorDelay_us(8);	
}	uint8_t AHT20_RD_Byte(void)//?AHT20??????
{uint8_t Byte,i,a;Byte = 0;SCL_Pin_Output_Low();SDA_Pin_IN_FLOATING();SensorDelay_us(8);	for(i=0;i<8;i++){SCL_Pin_Output_High();Delay_5us();a=0;//if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_15)) a=1;if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_7)) a=1;Byte = (Byte<<1)|a;//SCL_Pin_Output_Low();HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_RESET);Delay_5us();}SDA_Pin_IN_FLOATING();SensorDelay_us(8);	return Byte;
}uint8_t Receive_ACK(void)   //?AHT20?????ACK
{uint16_t CNT;CNT = 0;SCL_Pin_Output_Low();	SDA_Pin_IN_FLOATING();SensorDelay_us(8);	SCL_Pin_Output_High();	SensorDelay_us(8);	while((HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_7))  && CNT < 100) CNT++;if(CNT == 100){return 0;}SCL_Pin_Output_Low();	SensorDelay_us(8);	return 1;
}void Send_ACK(void)		  //????ACK??
{SCL_Pin_Output_Low();	SensorDelay_us(8);	SDA_Pin_Output_Low();SensorDelay_us(8);	SCL_Pin_Output_High();	SensorDelay_us(8);SCL_Pin_Output_Low();	SensorDelay_us(8);SDA_Pin_IN_FLOATING();SensorDelay_us(8);
}void Send_NOT_ACK(void)	//?????ACK
{SCL_Pin_Output_Low();	SensorDelay_us(8);SDA_Pin_Output_High();SensorDelay_us(8);SCL_Pin_Output_High();	SensorDelay_us(8);		SCL_Pin_Output_Low();	SensorDelay_us(8);SDA_Pin_Output_Low();SensorDelay_us(8);
}void Stop_I2C(void)	  //??????
{SDA_Pin_Output_Low();SensorDelay_us(8);SCL_Pin_Output_High();	SensorDelay_us(8);SDA_Pin_Output_High();SensorDelay_us(8);
}uint8_t AHT20_Read_Status(void)//??AHT20??????
{uint8_t Byte_first;	I2C_Start();AHT20_WR_Byte(0x71);Receive_ACK();Byte_first = AHT20_RD_Byte();Send_NOT_ACK();Stop_I2C();return Byte_first;
}uint8_t AHT20_Read_Cal_Enable(void)  //??cal enable??????
{uint8_t val = 0;//ret = 0,val = AHT20_Read_Status();if((val & 0x68)==0x08)return 1;else  return 0;}void AHT20_SendAC(void) //?AHT20??AC??
{I2C_Start();AHT20_WR_Byte(0x70);Receive_ACK();AHT20_WR_Byte(0xac);//0xAC????Receive_ACK();AHT20_WR_Byte(0x33);Receive_ACK();AHT20_WR_Byte(0x00);Receive_ACK();Stop_I2C();}//CRC????:CRC8/MAXIM
//???:X8+X5+X4+1
//Poly:0011 0001  0x31
//????????? 1000 1100 0x8c
//C????:
uint8_t Calc_CRC8(uint8_t *message,uint8_t Num)
{uint8_t i;uint8_t byte;uint8_t crc=0xFF;for(byte=0; byte<Num; byte++){crc^=(message[byte]);for(i=8;i>0;--i){if(crc&0x80) crc=(crc<<1)^0x31;else crc=(crc<<1);}}return crc;
}void AHT20_Read_CTdata(uint32_t *ct) //??CRC??,????AHT20????????
{volatile uint8_t  Byte_1th=0;volatile uint8_t  Byte_2th=0;volatile uint8_t  Byte_3th=0;volatile uint8_t  Byte_4th=0;volatile uint8_t  Byte_5th=0;volatile uint8_t  Byte_6th=0;uint32_t RetuData = 0;uint16_t cnt = 0;AHT20_SendAC();//?AHT10??AC??Delay_1ms(80);//??80ms??	cnt = 0;while(((AHT20_Read_Status()&0x80)==0x80))//????bit[7]?0,???????,??1,?????{SensorDelay_us(1508);if(cnt++>=100){break;}}I2C_Start();AHT20_WR_Byte(0x71);Receive_ACK();Byte_1th = AHT20_RD_Byte();//???,??????0x98,??????,bit[7]?1;???0x1C,??0x0C,??0x08???????,bit[7]?0Send_ACK();Byte_2th = AHT20_RD_Byte();//??Send_ACK();Byte_3th = AHT20_RD_Byte();//??Send_ACK();Byte_4th = AHT20_RD_Byte();//??/??Send_ACK();Byte_5th = AHT20_RD_Byte();//??Send_ACK();Byte_6th = AHT20_RD_Byte();//??Send_NOT_ACK();Stop_I2C();RetuData = (RetuData|Byte_2th)<<8;RetuData = (RetuData|Byte_3th)<<8;RetuData = (RetuData|Byte_4th);RetuData =RetuData >>4;ct[0] = RetuData;//??RetuData = 0;RetuData = (RetuData|Byte_4th)<<8;RetuData = (RetuData|Byte_5th)<<8;RetuData = (RetuData|Byte_6th);RetuData = RetuData&0xfffff;ct[1] =RetuData; //??}void AHT20_Read_CTdata_crc(uint32_t *ct) //CRC???,??AHT20????????
{volatile uint8_t  Byte_1th=0;volatile uint8_t  Byte_2th=0;volatile uint8_t  Byte_3th=0;volatile uint8_t  Byte_4th=0;volatile uint8_t  Byte_5th=0;volatile uint8_t  Byte_6th=0;volatile uint8_t  Byte_7th=0;uint32_t RetuData = 0;uint16_t cnt = 0;// uint8_t  CRCDATA=0;uint8_t  CTDATA[6]={0};//??CRC????AHT20_SendAC();//?AHT10??AC??Delay_1ms(80);//??80ms??	cnt = 0;while(((AHT20_Read_Status()&0x80)==0x80))//????bit[7]?0,???????,??1,?????{SensorDelay_us(1508);if(cnt++>=100){break;}}I2C_Start();AHT20_WR_Byte(0x71);Receive_ACK();CTDATA[0]=Byte_1th = AHT20_RD_Byte();//???,??????0x98,??????,bit[7]?1;???0x1C,??0x0C,??0x08???????,bit[7]?0Send_ACK();CTDATA[1]=Byte_2th = AHT20_RD_Byte();//??Send_ACK();CTDATA[2]=Byte_3th = AHT20_RD_Byte();//??Send_ACK();CTDATA[3]=Byte_4th = AHT20_RD_Byte();//??/??Send_ACK();CTDATA[4]=Byte_5th = AHT20_RD_Byte();//??Send_ACK();CTDATA[5]=Byte_6th = AHT20_RD_Byte();//??Send_ACK();Byte_7th = AHT20_RD_Byte();//CRC??Send_NOT_ACK();                           //??: ?????NAKStop_I2C();if(Calc_CRC8(CTDATA,6)==Byte_7th){RetuData = (RetuData|Byte_2th)<<8;RetuData = (RetuData|Byte_3th)<<8;RetuData = (RetuData|Byte_4th);RetuData =RetuData >>4;ct[0] = RetuData;//??RetuData = 0;RetuData = (RetuData|Byte_4th)<<8;RetuData = (RetuData|Byte_5th)<<8;RetuData = (RetuData|Byte_6th);RetuData = RetuData&0xfffff;ct[1] =RetuData; //??}else{ct[0]=0x00;ct[1]=0x00;//???????,????????????}//CRC??
}void AHT20_Init(void)   //???AHT20
{	Init_I2C_Sensor_Port();I2C_Start();AHT20_WR_Byte(0x70);Receive_ACK();AHT20_WR_Byte(0xa8);//0xA8??NOR????Receive_ACK();AHT20_WR_Byte(0x00);Receive_ACK();AHT20_WR_Byte(0x00);Receive_ACK();Stop_I2C();Delay_1ms(10);//??10ms??I2C_Start();AHT20_WR_Byte(0x70);Receive_ACK();AHT20_WR_Byte(0xbe);//0xBE?????,AHT20???????0xBE,   AHT10???????0xE1Receive_ACK();AHT20_WR_Byte(0x08);//?????bit[3]?1,?????Receive_ACK();AHT20_WR_Byte(0x00);Receive_ACK();Stop_I2C();Delay_1ms(10);//??10ms??
}
void JH_Reset_REG(uint8_t addr)
{uint8_t Byte_first,Byte_second,Byte_third;I2C_Start();AHT20_WR_Byte(0x70);//???0x70Receive_ACK();AHT20_WR_Byte(addr);Receive_ACK();AHT20_WR_Byte(0x00);Receive_ACK();AHT20_WR_Byte(0x00);Receive_ACK();Stop_I2C();Delay_1ms(5);//??5ms??I2C_Start();AHT20_WR_Byte(0x71);//Receive_ACK();Byte_first = AHT20_RD_Byte();Send_ACK();Byte_second = AHT20_RD_Byte();Send_ACK();Byte_third = AHT20_RD_Byte();Send_NOT_ACK();Stop_I2C();Delay_1ms(10);//??10ms??I2C_Start();AHT20_WR_Byte(0x70);///Receive_ACK();AHT20_WR_Byte(0xB0|addr);//?????Receive_ACK();AHT20_WR_Byte(Byte_second);Receive_ACK();AHT20_WR_Byte(Byte_third);Receive_ACK();Stop_I2C();Byte_second=0x00;Byte_third =0x00;
}void AHT20_Start_Init(void)
{JH_Reset_REG(0x1b);JH_Reset_REG(0x1c);JH_Reset_REG(0x1e);
}

AHT20.h代码:

#ifndef _AHT20_DEMO_
#define _AHT20_DEMO_#include "main.h"  void Delay_N10us(uint32_t t);//????
void SensorDelay_us(uint32_t t);//????
void Delay_4us(void);		//????
void Delay_5us(void);		//????
void Delay_1ms(uint32_t t);	
void AHT20_Clock_Init(void);		//????
void SDA_Pin_Output_High(void)  ; //?PB15????? , ???????, PB15??I2C?SDA
void SDA_Pin_Output_Low(void);  //?P15?????  ???????
void SDA_Pin_IN_FLOATING(void);  //SDA???????
void SCL_Pin_Output_High(void); //SCL?????,P14??I2C?SCL
void SCL_Pin_Output_Low(void); //SCL?????
void Init_I2C_Sensor_Port(void); //???I2C??,??????
void I2C_Start(void);		 //I2C????START??
void AHT20_WR_Byte(uint8_t Byte); //?AHT20?????
uint8_t AHT20_RD_Byte(void);//?AHT20??????
uint8_t Receive_ACK(void);   //?AHT20?????ACK
void Send_ACK(void)	;	  //????ACK??
void Send_NOT_ACK(void);	//?????ACK
void Stop_I2C(void);	  //??????
uint8_t AHT20_Read_Status(void);//??AHT20??????
uint8_t AHT20_Read_Cal_Enable(void);  //??cal enable??????
void AHT20_SendAC(void); //?AHT20??AC??
uint8_t Calc_CRC8(uint8_t *message,uint8_t Num);
void AHT20_Read_CTdata(uint32_t *ct); //??CRC??,????AHT20????????
void AHT20_Read_CTdata_crc(uint32_t *ct); //CRC???,??AHT20????????
void AHT20_Init(void);   //???AHT20
void JH_Reset_REG(uint8_t addr);///?????
void AHT20_Start_Init(void);///?????????????
#endif

main.c代码:

/* USER CODE BEGIN Header */
/********************************************************************************* @file           : main.c* @brief          : Main program body******************************************************************************* @attention** <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.* All rights reserved.</center></h2>** This software component is licensed by ST under BSD 3-Clause license,* the "License"; You may not use this file except in compliance with the* License. You may obtain a copy of the License at:*                        opensource.org/licenses/BSD-3-Clause********************************************************************************/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "dma.h"
#include "i2c.h"
#include "usart.h"
#include "gpio.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */#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)
{/* USER CODE BEGIN 1 */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();//³õʼ»¯AHT20AHT20_Init();Delay_1ms(500);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("ÕýÔÚ¼ì²â");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);/* 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_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();}
}/* USER CODE BEGIN 4 *//* USER CODE END 4 *//*** @brief  This function is executed in case of error occurrence.* @retval None*/
void Error_Handler(void)
{/* USER CODE BEGIN Error_Handler_Debug *//* User can add his own implementation to report the HAL error return state */__disable_irq();while (1){}/* USER CODE END Error_Handler_Debug */
}#ifdef  USE_FULL_ASSERT
/*** @brief  Reports the name of the source file and the source line number*         where the assert_param error has occurred.* @param  file: pointer to the source file name* @param  line: assert_param error line source number* @retval None*/
void assert_failed(uint8_t *file, uint32_t line)
{/* USER CODE BEGIN 6 *//* User can add his own implementation to report the file name and line number,ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT *//************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

3.实物图连接

注:VDD接5v.

4.实验效果

注:若串口为显示信息,可尝试将STlink拔掉后重新插入再打开串口。

项目代码:

STM32温湿度采集项目包和AHT20: 存放STM32温湿度采集的KEil项目包和AHT20代码

参考博客:

I2C总线通信协议及实操stm32通过I2C实现温湿度(AHT20)采集_stm32 aht20-CSDN博客

使用STM32F103完成基于I2C协议的AHT20温湿度传感器的数据采集-CSDN博客

I2C通信协议详解和通信流程分析_i2c协议-CSDN博客

软件I2C与硬件I2C的区别_软件i2c和硬件i2c-CSDN博客

这篇关于【STM32】STM32通过I2C实现温湿度采集与显示的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1088047

相关文章

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

第10章 中断和动态时钟显示

第10章 中断和动态时钟显示 从本章开始,按照书籍的划分,第10章开始就进入保护模式(Protected Mode)部分了,感觉从这里开始难度突然就增加了。 书中介绍了为什么有中断(Interrupt)的设计,中断的几种方式:外部硬件中断、内部中断和软中断。通过中断做了一个会走的时钟和屏幕上输入字符的程序。 我自己理解中断的一些作用: 为了更好的利用处理器的性能。协同快速和慢速设备一起工作

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

安卓链接正常显示,ios#符被转义%23导致链接访问404

原因分析: url中含有特殊字符 中文未编码 都有可能导致URL转换失败,所以需要对url编码处理  如下: guard let allowUrl = webUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else {return} 后面发现当url中有#号时,会被误伤转义为%23,导致链接无法访问

C#实战|大乐透选号器[6]:实现实时显示已选择的红蓝球数量

哈喽,你好啊,我是雷工。 关于大乐透选号器在前面已经记录了5篇笔记,这是第6篇; 接下来实现实时显示当前选中红球数量,蓝球数量; 以下为练习笔记。 01 效果演示 当选择和取消选择红球或蓝球时,在对应的位置显示实时已选择的红球、蓝球的数量; 02 标签名称 分别设置Label标签名称为:lblRedCount、lblBlueCount

Kubernetes PodSecurityPolicy:PSP能实现的5种主要安全策略

Kubernetes PodSecurityPolicy:PSP能实现的5种主要安全策略 1. 特权模式限制2. 宿主机资源隔离3. 用户和组管理4. 权限提升控制5. SELinux配置 💖The Begin💖点点关注,收藏不迷路💖 Kubernetes的PodSecurityPolicy(PSP)是一个关键的安全特性,它在Pod创建之前实施安全策略,确保P

工厂ERP管理系统实现源码(JAVA)

工厂进销存管理系统是一个集采购管理、仓库管理、生产管理和销售管理于一体的综合解决方案。该系统旨在帮助企业优化流程、提高效率、降低成本,并实时掌握各环节的运营状况。 在采购管理方面,系统能够处理采购订单、供应商管理和采购入库等流程,确保采购过程的透明和高效。仓库管理方面,实现库存的精准管理,包括入库、出库、盘点等操作,确保库存数据的准确性和实时性。 生产管理模块则涵盖了生产计划制定、物料需求计划、