【stm32】检测传感器温湿度



一、软件I2C

示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。
是Philips公司在八十年代初推出的一种串行、半双工的总线,主要用于近距离、低速的芯片之间的通信。
12C Bus(IIC, Inter-Integrated Circuit Bus)是由一根数据线SDA用于收发数据,一根时钟线SCL用于通信双方时钟的同步,利用上拉电阻将它们拉成高电平(表示总线空闲),其典型的电压准位为+3.3V或+5V,具有电路简单、连接线少、控制简单、通信速率高等优点。

​​​​​​​​在这里插入图片描述
I2C总线是一种主从结构(Master/Slave)总线, I2C总线上的每一个设备都可以作为主设备或者从设备,但一个总线上一般只有一个主设备,可以带多个从设备。其中主设备用来产生允许传输的时钟信号,并初始化总线的数据传输,所以主设备通常是CPU,而从设备只能被动响应主设备发起的通信请求,所以各种12C接口芯片将作为从设备使用。

(2)I2C从设备地址
因为一个12C总线上可以有多个从设备,这样主设备需要通过地址来确定与哪个器件进行通信。I2C总线上每个从设备都有一个唯一的7bit地址物理识别,这个地址固化在芯片内部,并可以从芯片datasheet上找到。因为12C地址全0为广播地址,所以12C总线理论上最多能带2^7-1=127个从设备。

其中I2C的从器件地址(我只用到了7位的)的组成如下:

1byte = 7bit地址 + 1bit读写标志

注:1bit读写标志中,0-发送数据(写),1-请求数据(读)
在这里插入图片描述

2- I2C通信时序

在12C总线上传送的每一位数据都由一个同步时钟脉冲相对应,即在SCL串行时钟的配合下,数据在SDA上从高位向低位依次串行传送每一位的数据。下面是12C通信的时序图:
在这里插入图片描述
(1)起始位
12C总线在空闲时SDA和SCL都处于高电平状态(由上拉电阻拉成高电平),当主设备要开始一次12C通信时就发送一个START(S)信号,这个起始位就可以告诉所有12C从机, “我”要开始进行12C通信了;当要结束一次12C通信时,则发送一个STOP§信号结束本次通信。

START(S):当SCL保持高电平时候,SDA出现下降沿,产生一个起始位,注意SCL一定要在高电平。
STOP( P ):当SCL保持高电平时候,SDA出现上升沿,产生一个停止位,注意SCL一定要在高电平。
在这里插入图片描述
(2)读写地址
主机在发送START信号之后,第2个时序应该立刻给出要通信的目标从机物理地址。此外,I2C总线是一种能够实现半双工通信的同步串行通信协议,站在主设备的角度来看应该具有读/写从设备的功能。

这时候12C的读写地址除了7bit物理地址以外,还有1bit用来标识读/写方向位。这样12C的从设备读写地址通常是一个字节,其中高7bit是上面描述的物理地址,最低位用来表示读写方向(0为写操作, 1为读操作)
在这里插入图片描述
(3)I2C应答信号
主机往12C总线上传输器件地址,所有的从机接收到这个地址后与自己的地址相比较若相同则发出一个应答ACK(Acknowledge)信号,主机收到这个应答信号后通讯连接建立成功,若未收到应答信号则表示寻址失败。
在这里插入图片描述
此外,主/从机在之后的数据通信中,数据接收方(可能是主机也可能是从机)收到传输的一个字节数据后,需要给出响应,此时处在第九个时钟,发送端释放SDA线控制权,将SDA电平拉高,由接收方控制。

若希望继续,则给出“应答(ACK, Acknowledge)”信号,即SDA为低电平
若不希望继续,则给出“非应答(NACK,Not Acknowledge) ”信号,即SDA为高电平
(4)数据位发送与接收
主机在收到从机的应答信号之后,开始给从机发送数据。SDA数据线上的每个字节必须是8位,每次传输的字节数量没有限制,每个字节发送完成之后,从机必须跟一个应答信号。
在这里插入图片描述
12C总线通信时数据位传输采用MSB(最高位优先)方式发送,其中高电平表示数据位1,低电平表示数据位0。
当传输的数据位需要改变时(如上一个位发送的是1,下一个位要发送0),必须发生在SCL为低电平期间。另外在传输过程中, SDA上的数据位在SCL高电平期间必须保持稳定不变。

假设SCL在高电平,想一下是不是就会触发起始位或者终止位。想一想起始信号与停止信号是怎么发送的就会明白为什么SCl一定要在高电平才能改变SDA。

3- I2C协议主机收发数据流程

1)主机发送数据
主机在检测到总线为“空闲状态”(即 SDA、SCL 线均为高电平)时,发送一个启动信号“S”,开始一次通信的开始;
主机接着发送一个从设备地址,它由7bit物理地址和1bit读写控制位R/w组成(此时R/W=0);
相对应的从机收到命令字节后向主机回馈应答信号 ACK(ACK=0);
主机收到从机的应答信号后开始发送第一个字节的数据;
从机收到数据后返回一个应答信号 ACK;
主机收到应答信号后再发送下一个数据字节;
当主机发送最后一个数据字节并收到从机的 ACK 后,通过向从机发送一个停止信号P结束本次通信并释放总线。从机收到P信号后也退出与主机之间的通信。
在这里插入图片描述
注意:

主机通过发送地址码与对应的从机建立了通信关系,而挂接在总线上的其它从机虽然同时也收到了地址码,但因为与其自身的地址不相符合,因此提前退出与主机的通信;
主机的一次发送通信,其发送的数据数量不受限制。主机是通过 P 信号通知发送的结束,从机收到 P 信号后退出本次通信;
主机的每一次发送后都是通过从机的 ACK 信号了解从机的接收状况,如果应答错误则重发。
(2)主机接收数据
主机发送起始信号后,接着发送地址字节(其中R/W=1);
对应的从机收到地址字节后,返回一个应答信号并向主机发送数据;
主机收到数据后向从机反馈一个应答信号ACK;
从机收到应答信号后再向主机发送下一个数据;
当主机完成接收数据后,向从机发送一个NAK,从机收到非应答信号后便停止发送;
主机发送非应答信号后,再发送一个停止信号,释放总线结束通信。
在这里插入图片描述
注意:
主机所接收数据的数量是由主机自身决定,当发送“非应答信号NAK”时从机便结束传送并释放总线。
非应答信号的两个作用:前一个数据接收成功,停止从机的再次发送。

二、创建工程

1.配置RCC

​​在这里插入图片描述

2.配置SYS

在这里插入图片描述

3.开启IC2

在这里插入图片描述

4.IC2协议对应的引脚是PB7和PB6

在这里插入图片描述

5.配置串口 引脚为(PA9和PA10)

在这里插入图片描述

6.配置时钟

在这里插入图片描述

7.工程配置

在这里插入图片描述

三、工程

1.主函数

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2022 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 "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" 
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
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;
}
/* 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 */
	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_USART1_UART_Init();
  MX_DMA_Init();
  MX_I2C1_Init();	
  MX_USART1_UART_Init();
	
  /* USER CODE BEGIN 2 */
  AHT20_Init();
	Delay_1ms(500);

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值