STM32下基于IIC协议的AHT20温湿度采集

一、软件I2C和硬件I2C

• I2C 通讯协议(Inter-Integrated Circuit)是由 Phiilps 公司开发的,由于它引脚少,硬件实现简单,可扩展性强,不需要 USART、CAN 等通讯协议的外部收发设备现在被广泛地使用在系统内多个集成电路(IC)间的通讯。
在计算机科学里,大部分复杂的问题都可以通过分层来简化。如芯片被分为内核层和片上外设;STM32 标准库则是在寄存器与用户代码之间的软件层。对于通讯协议,我们也以分层的方式来理解,最基本的是把它分为物理层和协议层。物理层规定通讯系统中具有机械、电子功能部分的特性,确保原始数据在物理媒体的传输。协议层主要规定通讯逻辑,统一收发双方的数据打包、解包标准。简单来说物理层规定我们用嘴巴还是用肢体来交流,协议层则规定我们用中文还是英文来交流。
在这里插入图片描述

1.软件IIC

• 一般是使用GPIO管脚,用软件控制SCL,SDA线输出高低电平,模拟i2c协议的时序。

2.硬件IIC

• 对应芯片上的I2C外设,有相应I2C驱动电路,其所使用的I2C管脚也是专用的,因而效率要远高于软件模拟的I2C;一般也较为稳定,但是程序较为繁琐。硬件(固件)I2C是直接调用内部寄存器进行配置;而软件I2C是没有寄存器这个概念的。

3.区别

• 硬件I2C的效率要远高于软件的,而软件I2C由于不受管脚限制,接口比较灵活。
• 可以看IIC写函数,看里面有木有调用现成的函数或者给某个寄存器赋值,如果有,则肯定是固件IIC功能,没有的话肯定是数据一个bit一个bit模拟发生送的,肯定用到了循环,则为模拟。
• 根据代码量判断,模拟的代码量肯定比固件的要大。

  1. 硬件IIC用法比较复杂,模拟IIC的流程更清楚一些。
  2. 硬件IIC速度比模拟快,并且可以用DMA
  3. 模拟IIC可以在任何管脚上,而硬件只能在固定管脚上。
    • 软件i2c是程序员使用程序控制SCL,SDA线输出高低电平,模拟i2c协议的时序。一般较硬件i2c稳定,但是程序较为繁琐,但不难。
    • 硬件i2c程序员只要调用i2c的控制函数即可,不用直接的去控制SCL,SDA高低电平的输出。但是有些单片机的硬件i2c不太稳定,调试问题较多。

二、基于I2C的AHT20温湿数据采集

1.下载所需文件

• 之前实验百度网盘的裸机工程。(我选用的是一个流水灯裸机文件)
• 在官网下载:AHT20的DEMO文件
• 也可使用如下:STM32的AHT20温湿度测量
• 可在上述网站下载文件目录下的HARDWAWRE和SYSTEM找到所需文件:
在这里插入图片描述

在这里插入图片描述
• 其中TEMHUM为AHT20文件。
注:以上文件在其他地方也可找到下载。

1.添加.c文件

• 打开一个裸机工程。
• 将上述添加的文件的.c文件添加在USER文件目录下:
在这里插入图片描述
myiic是IIC协议代码,temhum是AHT20读取代码

2.添加文件路径

• 打开目标选项选择C/C++配置路径,添加以下文件:
在这里插入图片描述

3.主函数代码

• 将主函数代码修改为如下:

#include "delay.h"
#include "temhum.h"
#include "sys.h"
#include "usart.h"

 int main(void)
 {	 	
    u32 CT_data[2]={0};
    volatile float  hum=0,tem=0;     
     
    delay_init();	    	 //延时函数初始化	  
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
    uart_init(115200);	 //串口初始化为115200

    temphum_init();     //ATH20初始化    
	
	while(1)
	{
        AHT20_Read_CTdata(CT_data);       //不经过CRC校验,直接读取AHT20的温度和湿度数据 

        hum = CT_data[0]*100*10/1024/1024;  //计算得到湿度值(放大了10倍)
        tem = CT_data[1]*200*10/1024/1024-500;//计算得到温度值(放大了10倍)

        printf("湿度:%.1f%%\r\n",(hum/10));
        printf("温度:%.1f度\r\n",(tem/10));
        printf("\r\n");
        delay_ms(1000);   
        delay_ms(1000);
	 }
}

该主函数在上述下载文件中有,修改即可。

4.管脚连线

• 将AHT20芯片连接在STM32指南者开发板上, SCL端接B6,SDA端接B7,VCC端接3V3,GND接地:
在这里插入图片描述
在这里插入图片描述

5.运行结果

• 之后在首先确保在目标选项下output栏create hex打勾。
• 点击编译->构建。
在这里插入图片描述
打开前面实验所用到过的烧录程序选择创建好的hex文件进行烧录:

在这里插入图片描述
• 打开串口助手,点击打开串口:
在这里插入图片描述
• 向芯片哈气升温:
在这里插入图片描述
• 实验完成。
• 参考资料:
《零死角玩转STM32—F103指南者》
硬件I2C与模拟I2C
硬件IIC和软件IIC区别

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 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、付费专栏及课程。

余额充值