前言
本篇文章讲解了IIC协议的应用,区分了软件IIC和硬件IIC的区别,以及AHT20 向STM32 使用IIC 协议传输数据,并在上位机上面显示出来。-
使用芯片:STM32F103ZET6(正点原子)、AHT20(奥松)
-
实验环境:KEIL5
IIC简介
IIC(Inter Integrated Circuit) 总线是一种由 PHILIPS 公司开发的两线式串行总线,用于连接微控制器及其外围设备
。它是由数据线 SDA
和时钟SCL
构成的串行总线,可发送和接收数据。在CPU与被控 IC 之间、IC与IC之间进行双向传送, 高速 IIC 总线 一般可达 400kbps 以上 。
IIC总线在传送数据过程中共有三种类型信号, 它们分别是:开始信号、结束信号和应答信号。
开始信号:SCL为高电平时,SDA由高电平向低电平跳变,开始传送数据。
结束信号:SCL为高电平时,SDA由低电平向高电平跳变,结束传送数据。
应答信号:接收数据的IC在接收到8bit数据后,向发送数据的IC发出特定的低电平脉冲,表示已收到数据。CPU向受控单元发出一个信号后,等待受控单元发出一个应答信号,CPU接收到应答信号后,根据实际情况作出是否继续传递信号的判断。若未收到应答信号,由判断为受控单元出现故障。
硬件IIC
硬件IIC对应芯片上的IIC外设,有相应IIC驱动电路,其所使用的IIC管脚也是专用的,就是配置寄存器
,硬件产生IIC读写时序。
硬件IIC的效率要远高于软件的,而软件IIC由于不受管脚限制,接口比较灵活。
软件IIC
软件IIC一般是用GPIO管脚,用软件控制管脚状态以模拟IIC通信波形。
模拟IIC 是通过GPIO
,软件模拟寄存器
的工作方式,而硬件(固件)IIC是直接调用内部寄存器进行配置。STM32的硬件IIC一直是令人诟病的地方,以至于很多情况下我们不得不选择使用模拟IIC的方式来在STM32上进行iic通讯。 软件模拟IIC简单方便,不必为繁琐的事件检测而费心。
AHT20简介
有关AHT20 的详细简介请查看博主之前的博客,这里只做简单介绍。
显示温湿度
编程实现
首先新建一个工程文件,在新建的工程文件目录下新建一个HARDWARE文件夹,在文件夹中添加IIC以及AHT20 文件夹。
其中IIC和LED的文件夹可以在其他例程文件中copy到该目录下,AHT20 文件可以在官网下载。
下载位置:
添加文件夹:
(其中的LCD文件可以不添加)
然后在工程中添加新的分组,在分组中添加已经存在的文件。
(其中LCD和LED文件可以不添加,博主试过添加LED代码,添加进去,串口输出结果就不正确,目前还不太明白是什么原因。)
这里是博主已经完成好配置,并且编译成功后,所以在.c文件前面有
+
号。
接下来,在工程中找到AHT20.c文件(下载下来不是这个名称,就是里面的.c文件)里面有一个主函数,将主函数剪切出来,到工程中的主函数去。
以下是AHT20.c中的主函数
int32_t main(void)
{
uint32_t CT_data[2];
volatile int c1,t1;
SensorDelay_us(40000);//刚上电,延时40ms才可以读取状态
if(!((AHT20_Read_Status()&0x08)==0x08))//首先发0x71读取状态字bit[3],如果=1,为校准输出,无须初始化!!! 正常情况下读回来的状态是0x1C或者是0x18,读回来是0x80表示忙状态;
{
AHT20_Init(); //初始化AHT20
}
while(1)
{
//DisableIrq(); //由于是模拟I2C,为读取数据更准确 ,读取之前禁止中断;
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倍)
}
}
然后根据调用的函数,更改里面的IIC的调用为新添加进去的IIC调用。(因为在AHT20中的函数,调用的IIC函数与STM32标准库中的IIC函数是不兼容的,所以需要一个一个的更改)类似以下方式的更改。
原AHT20.c
void AHT20_Init(void) //初始化AHT20
{
Init_I2C_Sensor_Port();
I2C_Start();
AHT20_WR_Byte(0x70);
Receive_ACK();
AHT20_WR_Byte(0xa8);//0xA8进入NOR工作模式
Receive_ACK();
AHT20_WR_Byte(0x00);
Receive_ACK();
AHT20_WR_Byte(0x00);
Receive_ACK();
Stop_I2C();
SensorDelay_us(11038);//延时10ms左右
I2C_Start();
AHT20_WR_Byte(0x70);
Receive_ACK();
AHT20_WR_Byte(0xbe);//0xBE初始化命令,AHT20的初始化命令是0xBE, AHT10的初始化命令是0xE1
Receive_ACK();
AHT20_WR_Byte(0x08);//相关寄存器bit[3]置1,为校准输出
Receive_ACK();
AHT20_WR_Byte(0x00);
Receive_ACK();
Stop_I2C();
SensorDelay_us(11038);//延时10ms左右
}
改AHT20.c
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();
SensorDelay_us(11038);//延时10ms左右
IIC_Start();
IIC_Send_Byte(0x70);
IIC_Wait_Ack();
IIC_Send_Byte(0xbe);//0xBE初始化命令,AHT20的初始化命令是0xBE, AHT10的初始化命令是0xE1
IIC_Wait_Ack();
IIC_Send_Byte(0x08);//相关寄存器bit[3]置1,为校准输出
IIC_Wait_Ack();
IIC_Send_Byte(0x00);
IIC_Wait_Ack();
IIC_Stop();
SensorDelay_us(11038);//延时10ms左右
}
注意:是要根据自己的IIC 中的函数进行更改。
- 将所用用到的函数更改即可
- 其中延时函数可以保留(无影响)
主函数
#include "stm32f10x.h"
#include "AHT20.h"
#include "myiic.h"
#include "usart.h"
#include "delay.h"
int32_t main(void)
{
uint32_t CT_data[2];
volatile int c1,t1;
SensorDelay_us(40000);//刚上电,延时40ms才可以读取状态
delay_init();
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
uart_init(115200); //串口初始化为115200
delay_ms(40);//刚上电,延时40ms才可以读取状态
if(!((AHT20_Read_Status()&0x80)==0x80))//首先发0x71读取状态字bit[3],如果=1,为校准输出,无须初始化!!! 正常情况下读回来的状态是0x1C或者是0x18,读回来是0x80表示忙状态;
{
AHT20_Init(); //初始化AHT20
}
while(1)
{
AHT20_Read_CTdata(CT_data); //不经过CRC校验,直接读取AHT20的温度和湿度数据 推荐每隔大于1S读一次
c1 = CT_data[0]*100*10/1024/1024; //计算得到湿度值(放大了10倍)
t1 = CT_data[1]*200*10/1024/1024-500;//计算得到温度值(放大了10倍)
printf("湿度:%d ",(c1/10));
printf("温度:%d\n",(t1/10));
delay_ms(20000);
}
}
硬件连接
硬件连接表:
AHT20 | STM32 |
---|---|
VDD | 3.3V |
GND | GND |
SCL | PB6 |
SDA | PB7 |
硬件连接实物图:
实验结果
哈一口气,可以看到温度和湿度的变化。
本篇文章就讲到这里啦~