STM32基于软件模拟IIC进行AHT21B温湿度采集
STM32基于软件模拟IIC进行AHT21B温湿度采集
- 一、 IIC简介
- 1.1 IIC简介
- 1.2 实现方式
- 1.3 实现方式对比
- 二、 AHT21B简介
- 2.1 简介
- 2.2 产品特点
- 2.3 外观
- 2.4 技术参数
- 2.5 引脚定义
- 三、 工程编写
- 3.1 实验要求
- 3.2 主要代码
- 3.3 烧录
- 3.4 结果展示
- 四、 总结
- 五、 参考资料
摘要:通过学习软件IIC来进行实操AHT21B采集温湿度。
前期准备:
- 软件:Keil 5.28,FlyMcu v0.188(烧录软件),XCOM v2.6(串口通信软件)
- 硬件:stm32F103C8,AHT21B(温湿度采集模块),USB转TTL模块
以下工程案例基于正点原子,请各位注意。
一、 IIC简介
1.1 IIC简介
IIC(Inter-Integrated Circuit)其实是IICBus简称,所以中文应该叫集成电路总线,它是一种串行通信总线,使用多主从架构,由飞利浦公司在1980年代为了让主板、嵌入式系统或手机用以连接低速周边设备而发展。百度百科-IIC
IIC串行总线一般有两根信号线,一根是双向的数据线SDA,另一根是时钟线SCL。所有接到IIC总线设备上的串行数据SDA都接到总线的SDA上,各设备的时钟线SCL接到总线的SCL上。
在I2C总线传输过程中,将两种特定的情况定义为开始和停止条件:
- 当SCL保持“高”时,SDA由“高”变为“低”为开始条件;
- 当SCL保持“高”且SDA由“低”变为“高”时为停止条件。
开始和停止条件均由主控制器产生。使用硬件接口可以很容易地检测到开始和停止条件,没有这种接口的微机必须以每时钟周期至少两次对SDA取样,以检测这种变化。百度百科-IIC
具有三种传输模式:标准模式传输速率为 100kbit/s ,快速模式为 400kbit/s ,高速模式下可达 3.4Mbit/s,但目前大多 I2C 设备尚不支持高速模式。
1.2 实现方式
目前有两种实现IIC的方式:(1)软件IIC(2)硬件IIC
- 软件IIC
软件IIC一般是用GPIO管脚,用软件控制管脚状态以模拟I2C通信波形。
- 硬件IIC
硬件I2C对应芯片上的I2C外设,有相应I2C驱动电路,其所使用的I2C管脚也是专用的
1.3 实现方式对比
- 硬件IIC的效率要远高于软件IIC
- 软件I2C由于不受管脚限制,接口比较灵活,而硬件IIC只能在固定管脚上。
- 硬件IIC速度比模拟快,并且可以用DMA
- 软件IIC代码容量少且流程清晰简单
二、 AHT21B简介
2.1 简介
AHT21B数字温湿度模块是一款经过校准数字信号输出的温湿度复合传感器。它以专用的数字模块采集技术和温湿度传感技术,确保产品具有非常高的可靠性与卓越的长期稳定性。该产品具有品质卓越、响应迅速、抗干扰能力强、性价比高等优点。每个传感器都在专业的湿度校验室中进行校准,使产品达到更高的精度标准。标准I²C接口,使系统集成变得简易快捷。产品体积小、功耗低使其成为各类应用甚至最为苛刻的应用场合的最佳选择。奥松电子官网
2.2 产品特点
• 完全标定• 数字输出,I²C接口• 优异的长期稳定性• 响应迅速• 抗干扰能力强• 多种配件可供选择• 量身定制应用方案
2.3 外观
2.4 技术参数
参数 | 说明 |
---|---|
供电电压 | DC:2-5.5V |
测量范围 | 温度:-40~+80°C; 湿度:0~100%RH |
测量精度 | 温度:±0.3℃; 湿度:±2%RH(25℃) |
分辨率 | 温度:0.01℃ 湿度:0.024%RH |
输出信号 | I²C信号 |
包装 | 吸塑盘 |
2.5 引脚定义
名称 | 描述 |
---|---|
VCC | 供电电压 |
SDA | 串行数据,双向口 |
GND | 电源地 |
SCL | 串行时钟,双向口 |
电源引脚( VDD GND)
AHT21B的供电范围为2.0-5.5V,推荐电压为3.3V,并且在VCC和GND之间必须加上去耦电容10uF,起到滤波作用。
串行时钟SCL
SCL用于微处理器与AHT21B之间的通讯同步。由于接口包含了完全静态逻辑,因而不存在最小SCL频率。
串行数据SDA
SDA引脚用于传感器的数据输入和输出。当向传感器发送命令时,SDA在串行时钟SCL的上升沿有效,且当SCL为高电平时,SDA必须保持稳定。在SCL下降沿之后,SDA值可被改变。为确保通信安全,SDA的有效时间在SCL上升沿之前,和下降沿之后应该分别延长至 TSU AND THO,当从传感器读取数据时,SDA在SCL变低以后有效(TV),且维持到下一个SCL的下降沿
三、 工程编写
3.1 实验要求
1.采集温湿度并进行串口输出显示
3.2 主要代码
- main.c
int main(void){ u32 CT_data[2]={0};volatile float c1=0,t1=0; delay_init(); //延时函数初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级uart_init(115200); //串口初始化为115200LED_Init(); //LED端口初始化temphum_init(); delay_ms(40);//刚上电,延时40ms才可以读取状态if(!((AHT20_Read_Status()&0x08)==0x08))//首先发0x71读取状态字bit[3],如果=1,为校准输出,无须初始化!!! 正常情况下读回来的状态是0x1C或者是0x18,读回来是0x80表示忙状态;{AHT20_Init(); //初始化AHT20 }while(1){//DisableIrq(); //由于是模拟I2C,为读取数据更准确 ,读取之前禁止中断;delay_ms(1000);AHT20_Read_CTdata(CT_data); //不经过CRC校验,直接读取AHT20的温度和湿度数据 推荐每隔大于1S读一次//AHT20_Read_CTdata_crc(CT_data); //crc校验后,读取AHT20的温度和湿度数据 c1 = CT_data[0]*100*10/1024/1024; //计算得到湿度值(放大了10倍)t1 = CT_data[1]*200*10/1024/1024-500;//计算得到温度值(放大了10倍)//printf("%d %d\r\n",*CT_data,*(CT_data+1));LED=0;delay_ms(500);LED=1;printf("湿度:%.1f%%\r\n",(c1/10));printf("温度:%.1f℃\r\n",(t1/10));printf("\r\n");delay_ms(500);}}
- myiic.c
#include "myiic.h"
#include "delay.h"
//
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK精英STM32开发板
//IIC驱动 代码
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//修改日期:2012/9/9
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2009-2019
//All rights reserved
////初始化IIC
void IIC_Init(void)
{ GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE ); //使能GPIOB时钟GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);GPIO_SetBits(GPIOB,GPIO_Pin_6|GPIO_Pin_7); //PB6,PB7 输出高
}
//产生IIC起始信号
void IIC_Start(void)
{SDA_OUT(); //sda线输出IIC_SDA=1; IIC_SCL=1;delay_us(4);IIC_SDA=0;//START:when CLK is high,DATA change form high to low delay_us(4);IIC_SCL=0;//钳住I2C总线,准备发送或接收数据
}
//产生IIC停止信号
void IIC_Stop(void)
{SDA_OUT();//sda线输出IIC_SCL=0;IIC_SDA=0;//STOP:when CLK is high DATA change form low to highdelay_us(4);IIC_SCL=1; IIC_SDA=1;//发送I2C总线结束信号delay_us(4);
}
等待应答信号到来
返回值:1,接收应答成功
0,接收应答失败
u8 IIC_Wait_Ack(void)
{u8 ucErrTime=0;SDA_IN(); //SDA设置为输入 IIC_SDA=1;delay_us(1); IIC_SCL=1;delay_us(1); while(READ_SDA){ucErrTime++;if(ucErrTime>250){IIC_Stop();return 0;}}IIC_SCL=0;//时钟输出0 return 1;
} //产生ACK应答
void IIC_Ack(void)
{IIC_SCL=0;SDA_OUT();IIC_SDA=0;delay_us(2);IIC_SCL=1;delay_us(2);IIC_SCL=0;
}
//不产生ACK应答
void IIC_NAck(void)
{IIC_SCL=0;SDA_OUT();IIC_SDA=1;delay_us(2);IIC_SCL=1;delay_us(2);IIC_SCL=0;
}
//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答
void IIC_Send_Byte(u8 txd)
{ u8 t; SDA_OUT(); IIC_SCL=0;//拉低时钟开始数据传输for(t=0;t<8;t++){ IIC_SDA=(txd&0x80)>>7;txd<<=1; delay_us(2); //对TEA5767这三个延时都是必须的IIC_SCL=1;delay_us(2); IIC_SCL=0; delay_us(2);}
}
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK
u8 IIC_Read_Byte(unsigned char ack)
{unsigned char i,receive=0;SDA_IN();//SDA设置为输入for(i=0;i<8;i++ ){IIC_SCL=0; delay_us(2);IIC_SCL=1;receive<<=1;if(READ_SDA)receive++; delay_us(1); } if (!ack)IIC_NAck();//发送nACKelseIIC_Ack(); //发送ACK return receive;
}
- temhum.c
#include "temhum.h"//读取AHT20的状态寄存器
u8 AHT20_Read_Status(void)
{u8 Byte_first,flag; IIC_Start();IIC_Send_Byte(0x71);flag=IIC_Wait_Ack();Byte_first = IIC_Read_Byte(flag);IIC_NAck();IIC_Stop();return Byte_first;
}void AHT20_SendAC(void) //向AHT20发送AC命令
{IIC_Start();IIC_Send_Byte(0x70);IIC_Wait_Ack();IIC_Send_Byte(0xac);//0xAC采集命令IIC_Wait_Ack();IIC_Send_Byte(0x33);IIC_Wait_Ack();IIC_Send_Byte(0x00);IIC_Wait_Ack();IIC_Stop();}void AHT20_Init(void) //初始化AHT20
{ IIC_Init();IIC_Start();IIC_Send_Byte(0x70);IIC_Wait_Ack();IIC_Send_Byte(0xa8);//0xA8进入NOR工作模式IIC_Wait_Ack();IIC_Send_Byte(0x00);IIC_Wait_Ack();IIC_Send_Byte(0x00);IIC_Wait_Ack();IIC_Stop();delay_ms(10);//延时10ms左右IIC_Start();IIC_Send_Byte(0x70);IIC_Wait_Ack();IIC_Send_Byte(0xbe);//0xBE初始化命令,AHT20的初始化命令是0xBE, AHT10的初始化命令是0xE1IIC_Wait_Ack();IIC_Send_Byte(0x08);//相关寄存器bit[3]置1,为校准输出IIC_Wait_Ack();IIC_Send_Byte(0x00);IIC_Wait_Ack();IIC_Stop();delay_ms(10);//延时10ms左右
}void temphum_init()
{delay_ms(40);//刚上电,延时40ms才可以读取状态//首先发0x71读取状态字bit[3],如果=1,为校准输出,无须初始化!!!正常情况下读回来的状态是0x1C或者是0x18,读回来是0x80表示忙状态;if(!((AHT20_Read_Status()&0x08)==0x08)){AHT20_Init(); //初始化AHT20 }
}void AHT20_Read_CTdata(u32 *ct) //没有CRC校验,直接读取AHT20的温度和湿度数据
{volatile u8 Byte_1th=0;volatile u8 Byte_2th=0;volatile u8 Byte_3th=0;volatile u8 Byte_4th=0;volatile u8 Byte_5th=0;volatile u8 Byte_6th=0;u32 RetuData = 0;u16 cnt = 0,flag;AHT20_SendAC();//向AHT20发送AC命令delay_ms(80); //大约延时80mscnt = 0;while(((AHT20_Read_Status()&0x80)==0x80))//直到状态bit[7]为0,表示为空闲状态,若为1,表示忙状态{delay_ms(1);if(cnt++>=100) break;}IIC_Start();IIC_Send_Byte(0x71);flag=IIC_Wait_Ack();Byte_1th = IIC_Read_Byte(flag);//状态字//IIC_Ack();Byte_2th = IIC_Read_Byte(flag);//湿度//IIC_Ack();Byte_3th = IIC_Read_Byte(flag);//湿度//IIC_Ack();Byte_4th = IIC_Read_Byte(flag);//湿度/温度//IIC_Ack();Byte_5th = IIC_Read_Byte(flag);//温度//IIC_Ack();Byte_6th = IIC_Read_Byte(!flag);//温度//IIC_NAck();IIC_Stop();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; //温度}
部分代码参考基于I2C通信协议的温湿度采集
3.3 烧录
1.USB转TTL连线
stm32核心板 | USB转串口 |
---|---|
PA9 (USART1-TX) | RXD |
PA10 (USART1-RX) | TXD |
3V3 | 3V3 |
GND | GND |
跳线BOOT0为1,BOOT1为0.
2.AHT21B与STM32F103C8
AHT20 | STM32F10X |
---|---|
SCL | PB6 |
SDA | PB7 |
VCC | 3V3 |
GND | GND |
3.4 结果展示
- 正常室内温湿度采集
- 升温采集
通过实验结果可以看出,AHT21B可以正常采集温湿度进行串口显示。
四、 总结
通过此次学习,我初步了解了软件IIC与硬件IIC的基本知识。通过实操AHT21B采集温湿度,学习并掌握了软件IIC的代码编写以及工程调试。其中遇到了很多问题,特别感谢我的老师和不#曾&轻听博主对我的帮助。
五、 参考资料
1.奥松官网
2.AHT21B温湿度采集-GitHub
3.基于I2C通信协议的温湿度采集
4.硬件IIC和软件IIC区别
STM32基于软件模拟IIC进行AHT21B温湿度采集相关推荐
- 基于stm32单片机的模拟IIC时序(附源码)
我下面要说的是基于stm32单片机的模拟IIC时序,以及是一些要注意的事项:结合自己所做的MMA7455加速度传感器,我把模拟IIC的源代码贴了出来,大家可以参考一下. 1.因为在IIC协议中,当总线 ...
- STM32 软件模拟IIC
0.系列目录 STM32 软件模拟IIC STM32 使用DMP库处理MPU6050数据 STM32 MPU6050与匿名上位机通讯(V2.6版) 1.IIC通讯过程 SCL和SDA在空闲时候均为高电 ...
- STM32 软件模拟 IIC 代码,标准库、HAL库可用
1 #ifndef _IIC_H 2 #define _IIC_H 3 4 #include "stdio.h" 5 #include "stm32f1xx_hal.h& ...
- STM32 Cube MX 之hal库软件模拟IIC 可直接移植使用
此为软件模拟IIC,可以直接移植到HAL库使用..h文件需要自己做函数声明这里就不再放出,如有问题大家可以讨论. 使用的时候只需要更改SDA 和SCL引脚的宏定义就可以移植使用,当然IIC协议其实就是 ...
- STM32F103单片机软件模拟IIC并读取TMP112数字温度传感器
本文利用STM32F103系列单片机读取TMP112数字温度传感器的温度信息,TMP112数字传感器采用IIC总线协议通信.STM32自身含有硬件IIC资源,分别是PB6-->SCL.PB7-- ...
- 基于STM32开发板实现传感数据采集-DHT11温湿度采集
基于STM32开发板实现传感数据采集-DHT11温湿度采集 一.项目简介 本次项目是基于STM32开发板实现传感数据采集-DHT11温湿度采集.采用ARM结构中最为代表的Cortex-M4系列的芯片, ...
- STM32实例——基于STM32开发板实现传感数据采集-DHT11温湿度采集
STM32开发板实现传感数据采集-DHT11温湿度采集 一.前言 本项目是基于STM32开发板的温湿度采集,传感器采用DHT11温湿度传感器,软件采用keil5等.本项目采用ARM结构中最为代表的Co ...
- 软件模拟IIC主从机
软件模拟IIC 从机部分 从机接收部分 从机发送部分 主机部分 阻塞式发送 定时器中断方式发送 从机部分 因为项目简单,就只有数据接收,数据命令处理,显示.显示部分使用定时器中断动态扫描方式,主函数用 ...
- STM32模拟IIC驱动sht30温湿度传感器
最近有在使用sht30这个传感器,相比于新手常用的dht11传感器,sht30更精确,自己花了半小时调好了 所以拿出来分享给大家. sht30外观 驱动不是自己写的, 是采用CSDN上的一位朋友的 , ...
最新文章
- 上传图片被防火墙拦截_Web安全:文件上传漏洞
- Office 2016使用NTKO OFFICE控件提示“文件存取错误”的解决办法
- SAP WM初阶之MIGO过账后自动调用LT06事务代码
- solrlucene3.6.0源码解析(三)
- linux rpc语言,Linux下RPC的hello world
- 文巾解题 176. 第二高的薪水
- 【TensorFlow2.0】数据读取与使用方式
- SpringBoot_数据访问-整合MyBatis(一)-基础环境搭建
- android 图片特征提取比对_判断ImageView当前的图片是哪个图片,然后比对资源文件的操作...
- Java—数据库技术
- 面向.NET开发人员的Dapr——参考应用程序
- 360 nginx+php,windows Nginx+PHP7+Mysql独立环境部署
- Golang 新手入门教程(一):Go 安装与配置
- 牛牛游戏牛型判断算法实现
- 237. 删除链表中的节点
- 计算机系统系统时间不准,windows7系统时间不对怎么办_windows7系统时间不准如何恢复-win7之家...
- 淘宝Push智能文案生成
- 解读 intriguing properties of neural networks
- 原生js做一个简单的仿幻灯片放映
- 数据库与身份认证:MySQL的基本使用