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温湿度采集相关推荐

  1. 基于stm32单片机的模拟IIC时序(附源码)

    我下面要说的是基于stm32单片机的模拟IIC时序,以及是一些要注意的事项:结合自己所做的MMA7455加速度传感器,我把模拟IIC的源代码贴了出来,大家可以参考一下. 1.因为在IIC协议中,当总线 ...

  2. STM32 软件模拟IIC

    0.系列目录 STM32 软件模拟IIC STM32 使用DMP库处理MPU6050数据 STM32 MPU6050与匿名上位机通讯(V2.6版) 1.IIC通讯过程 SCL和SDA在空闲时候均为高电 ...

  3. STM32 软件模拟 IIC 代码,标准库、HAL库可用

    1 #ifndef _IIC_H 2 #define _IIC_H 3 4 #include "stdio.h" 5 #include "stm32f1xx_hal.h& ...

  4. STM32 Cube MX 之hal库软件模拟IIC 可直接移植使用

    此为软件模拟IIC,可以直接移植到HAL库使用..h文件需要自己做函数声明这里就不再放出,如有问题大家可以讨论. 使用的时候只需要更改SDA 和SCL引脚的宏定义就可以移植使用,当然IIC协议其实就是 ...

  5. STM32F103单片机软件模拟IIC并读取TMP112数字温度传感器

    本文利用STM32F103系列单片机读取TMP112数字温度传感器的温度信息,TMP112数字传感器采用IIC总线协议通信.STM32自身含有硬件IIC资源,分别是PB6-->SCL.PB7-- ...

  6. 基于STM32开发板实现传感数据采集-DHT11温湿度采集

    基于STM32开发板实现传感数据采集-DHT11温湿度采集 一.项目简介 本次项目是基于STM32开发板实现传感数据采集-DHT11温湿度采集.采用ARM结构中最为代表的Cortex-M4系列的芯片, ...

  7. STM32实例——基于STM32开发板实现传感数据采集-DHT11温湿度采集

    STM32开发板实现传感数据采集-DHT11温湿度采集 一.前言 本项目是基于STM32开发板的温湿度采集,传感器采用DHT11温湿度传感器,软件采用keil5等.本项目采用ARM结构中最为代表的Co ...

  8. 软件模拟IIC主从机

    软件模拟IIC 从机部分 从机接收部分 从机发送部分 主机部分 阻塞式发送 定时器中断方式发送 从机部分 因为项目简单,就只有数据接收,数据命令处理,显示.显示部分使用定时器中断动态扫描方式,主函数用 ...

  9. STM32模拟IIC驱动sht30温湿度传感器

    最近有在使用sht30这个传感器,相比于新手常用的dht11传感器,sht30更精确,自己花了半小时调好了 所以拿出来分享给大家. sht30外观 驱动不是自己写的, 是采用CSDN上的一位朋友的 , ...

最新文章

  1. 上传图片被防火墙拦截_Web安全:文件上传漏洞
  2. Office 2016使用NTKO OFFICE控件提示“文件存取错误”的解决办法
  3. SAP WM初阶之MIGO过账后自动调用LT06事务代码
  4. solrlucene3.6.0源码解析(三)
  5. linux rpc语言,Linux下RPC的hello world
  6. 文巾解题 176. 第二高的薪水
  7. 【TensorFlow2.0】数据读取与使用方式
  8. SpringBoot_数据访问-整合MyBatis(一)-基础环境搭建
  9. android 图片特征提取比对_判断ImageView当前的图片是哪个图片,然后比对资源文件的操作...
  10. Java—数据库技术
  11. 面向.NET开发人员的Dapr——参考应用程序
  12. 360 nginx+php,windows Nginx+PHP7+Mysql独立环境部署
  13. Golang 新手入门教程(一):Go 安装与配置
  14. 牛牛游戏牛型判断算法实现
  15. 237. 删除链表中的节点
  16. 计算机系统系统时间不准,windows7系统时间不对怎么办_windows7系统时间不准如何恢复-win7之家...
  17. 淘宝Push智能文案生成
  18. 解读 intriguing properties of neural networks
  19. 原生js做一个简单的仿幻灯片放映
  20. 数据库与身份认证:MySQL的基本使用

热门文章

  1. bzoj 1123: [POI2008]BLO (tarjan求点双+树形DP)
  2. 用C语言读取.txt文本,并保存在二维数组中
  3. 华师大 OJ 2876
  4. windows下实现定时任务重启多台tomcat
  5. python函数(八)-- 魔方方法
  6. Android修行手册 - Toolbar实践
  7. Freemarker导出word图片不显示可能的原因
  8. 论文格式设置(封面、页码、目录、参考文献编号)
  9. RRDTool (比较全)
  10. 图像处理的仿射变换与透视变换