I2C接口实现温湿度(AHT20)的采集【嵌入式】

 

目录

一 I2C原理

1. I2C简介

2.软件I2C

3.硬件I2C

二 实现温湿度输出

 三 参考文献


一 I2C原理

1. I2C简介

I2C总线是由Philips公司开发的一种简单、双向二线制同步串行总线。它只需要两根线即可在连接于总线上的器件之间传送信息。

主器件用于启动总线传送数据,并产生时钟以开放传送的器件,此时任何被寻址的器件均被认为是从器件.在总线上主和从、发和收的关系不是恒定的,而取决于此时数据传送方向。如果主机要发送数据给从器件,则主机首先寻址从器件,然后主动发送数据至从器件,最后由主机终止数据传送;如果主机要接收从器件的数据,首先由主器件寻址从器件.然后主机接收从器件发送的数据,最后由主机终止接收过程。在这种情况下.主机负责产生定时时钟和终止数据传送

2.软件I2C

直接使用 CPU 内核按照 I2C 协议的要求控制 GPIO 输出高低电平,从而模拟I2C。

    软件I2C的使用
    需要在控制产生 I2C 的起始信号时,控制作为 SCL 线的 GPIO 引脚输出高电平,然后控制作为 SDA 线的 GPIO 引脚在此期间完成由高电平至低电平的切换,最后再控制SCL 线切换为低电平,这样就输出了一个标准的 I2C 起始信号。


3.硬件I2C

直接利用 STM32 芯片中的硬件 I2C 外设。

    硬件I2C的使用
    只要配置好对应的寄存器,外设就会产生标准串口协议的时序。在初始化好 I2C 外设后,只需要把某寄存器位置 1,此时外设就会控制对应的 SCL 及 SDA 线自动产生 I2C 起始信号,不需要内核直接控制引脚的电平。
 

二 实现温湿度输出

在奥松官网下载AHT20芯片代码:

软件下载-温湿度传感器 温湿度芯片 温湿度变送器模块 气体传感器 流量传感器 广州奥松电子股份有限公司

main代码如下:

/* 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();
	
	//初始化AHT20
	AHT20_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****/

编译:

 烧录运行:

while循环没两秒左右读取一次温湿度并且通过串口打印:

 三 参考文献

https://blog.csdn.net/wanerXR/article/details/121552993

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个基于Linux 4.9内核的AHT20 IIC驱动,用于采集温湿度的功能代码。在此之前,您需要先编写一个用户空间程序,用于打开IIC设备节点并读取温湿度数据。以下代码假设您已经完成了这一步骤,并定义了一个名为`aht20_read`的函数,用于读取AHT20温湿度数据。 ``` #include <linux/i2c.h> #include <linux/init.h> #include <linux/module.h> #include <linux/delay.h> #include <linux/kernel.h> // AHT20 I2C Address #define AHT20_I2C_ADDR 0x38 // AHT20 Commands #define AHT20_CMD_INIT 0b1110001 #define AHT20_CMD_MEASURE 0b10101100 #define AHT20_CMD_SOFT_RESET 0b10111010 static int aht20_probe(struct i2c_client *client, const struct i2c_device_id *id) { int ret; u8 buf[3]; // Initialize AHT20 buf[0] = AHT20_CMD_INIT; ret = i2c_master_send(client, buf, 1); if (ret < 0) { dev_err(&client->dev, "Failed to send AHT20 initialization command\n"); return ret; } msleep(20); // Soft reset AHT20 buf[0] = AHT20_CMD_SOFT_RESET; ret = i2c_master_send(client, buf, 1); if (ret < 0) { dev_err(&client->dev, "Failed to send AHT20 soft reset command\n"); return ret; } msleep(20); return 0; } static int aht20_read_measurement(struct i2c_client *client, u16 *humidity, u16 *temperature) { int ret; u8 buf[6]; // Send measure command to AHT20 buf[0] = AHT20_CMD_MEASURE; ret = i2c_master_send(client, buf, 1); if (ret < 0) { dev_err(&client->dev, "Failed to send AHT20 measure command\n"); return ret; } msleep(80); // Read measurement data from AHT20 ret = i2c_master_recv(client, buf, sizeof(buf)); if (ret < 0) { dev_err(&client->dev, "Failed to read AHT20 measurement data\n"); return ret; } // Convert measurement data to humidity and temperature values *humidity = (buf[1] << 12) | (buf[2] << 4) | (buf[3] >> 4); *temperature = ((buf[3] & 0x0F) << 16) | (buf[4] << 8) | buf[5]; return 0; } static int aht20_read(struct i2c_client *client, u16 *humidity, u16 *temperature) { int ret; // Read measurement data from AHT20 ret = aht20_read_measurement(client, humidity, temperature); if (ret < 0) { dev_err(&client->dev, "Failed to read AHT20 measurement data\n"); return ret; } return 0; } static const struct i2c_device_id aht20_id[] = { { "aht20", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, aht20_id); static struct i2c_driver aht20_driver = { .driver = { .name = "aht20", }, .probe = aht20_probe, .id_table = aht20_id, }; module_i2c_driver(aht20_driver); MODULE_AUTHOR("Your Name"); MODULE_DESCRIPTION("AHT20 IIC Driver"); MODULE_LICENSE("GPL"); ``` 这段代码实现了从AHT20读取温湿度数据的功能。在用户空间程序中,您可以打开IIC设备节点并调用`aht20_read`函数来读取温湿度数据。例如: ``` int fd = open("/dev/i2c-1", O_RDWR); if (fd < 0) { perror("Failed to open IIC device node"); return -1; } int addr = 0x38; if (ioctl(fd, I2C_SLAVE, addr) < 0) { perror("Failed to set IIC slave address"); close(fd); return -1; } u16 humidity, temperature; if (read(fd, &humidity, sizeof(humidity)) != sizeof(humidity)) { perror("Failed to read humidity data"); close(fd); return -1; } if (read(fd, &temperature, sizeof(temperature)) != sizeof(temperature)) { perror("Failed to read temperature data"); close(fd); return -1; } printf("Humidity: %d%%\n", humidity); printf("Temperature: %d.%d C\n", temperature / 100, temperature % 100); close(fd); ``` 请注意,这只是一个示例代码,并且可能需要根据您的具体需求进行修改和调整。在实际使用中,请务必小心谨慎,以确保您的设备和数据的安全。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值