day06(单片机)IIC+STH20
目录
IIC+SHT20
I2C基础简介
为什么I2C需要使用上拉电阻?
I2C特点
时序图分析
起始信号与终止信号
数据传输时序
字节传输和应答信号·
I2C寻址
主机给从机发送一个字节
主机给从机发送多个字节
主机从从机接收一个字节
主机从从机接收多个字节
I2C寄存器
I2C_RXDR(I2C 接收数据寄存器)
I2C_TXDR(I2C 发送数据寄存器)
温度传感器实验
模块简介
SHT20通讯原理
起始和终止时序
通信时序
IIC地址
I2C相关命令
hold master通信时序
no hold master通信时序
SHT20信号转换
湿度转换
温度转换
硬件IIC实验-SHT20读取实验
引脚定位
cubeMX配置
驱动代码移植
重定向相关
程序编写
IIC+SHT20
I2C基础简介
IIC(Inter-Integrated Circuit)是一个多主从的串行总线,又叫I2C,是由飞利浦公司发明的通讯总线,属于半双工同步传输类型总线。IIC总线是非常常见的数据总线,仅仅使用两条线就能完成多机通讯,一条SCL时钟线,另外一条双向数据线SDA。不同的器件,都是并联接在这两条线上,I2C总线上的每个设备都自己一个唯一的地址,来确保不同设备之间访问的准确性。
SDA(Serial data)是数据线,D代表Data也就是数据,Send Data 也就是用来传输数据的
SCL(Serial clock line)是时钟线,C代表Clock 也就是时钟 也就是控制数据发送的时序的
为什么I2C需要使用上拉电阻?
答:总线空闲的时候,SDA和SCL都是高电平。当其中一个设备拉低总线,整条线就全是低电平,器件与器件之间变为"与"关系。
为了避免总线信号收到从设备的干扰,各设备连接到总线的输出端时必须是漏极开路(OD)输出,即高阻态,无法主动输出高电平,需要外部上拉电阻才可以获得高电平。
I2C特点
通常我们为了方便把IIC设备分为主设备和从设备,基本上谁控制时钟线(控制SCL的电平高低变换)谁就是主设备。
- IIC主设备功能:主要产生时钟,产生起始信号和停止信号
- IIC从设备功能:可编程的IIC地址检测,停止位检测
- IIC的一个优点是它支持多主控(multimastering),其中任何一个能够进行发送和接收的设备都可以成为主总线。一个主控能够控制信号的传输和时钟频率。当然,在任何时间点上只能有一个主控。
- 支持不同速率的通讯速度,标准速度(最高速度100kHZ), 快速(最高400kHZ),比uart高,比spi低
- SCL和SDA都需要接上拉电阻 (大小由速度和容性负载决定一般在3.3K-10K之间) 保证数据的稳定性,减少干扰。
- IIC是半双工,而不是全双工 ,同一时间只可以单向通信,IIC协议首先是发送从机硬件地址,然后发送命令,再发送数据/寄存器编号或者读取数据。IIC协议可以多字节连续读写数据。
- 各设备连接到总线的输出端时必须是漏极开路(OD)输出或集电极开路(OC)输出。
时序图分析
起始信号与终止信号
- SCL线为高电平期间,SDA线由高电平向低电平的变化表示起始信号;
- SCL线为高电平期间,SDA线由低电平向高电平的变化表示终止信号;
- 起始和终止信号都是由主机发出,起始信号产生后,总线就处于占用的态;
- 终止信号产生后,总线就处于空闲态。
数据传输时序
- I2C总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定; 只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化。
- 在时钟为低电平期间,发送器向数据线上写入数据,因此数据线上的数据运行变化; 在时钟为高电平期间,接收器从数据线上读取数据,因此必须保持数据线上的数据稳定。
- 最终完成一个时钟周期内,发送器发生一个bit位数据,接收器接收一个bit位数据。
字节传输和应答信号·
- 每一个字节必须保证是8位长度。数据传送时,先传送最高位(MSB),每一个被传送的字节后面都必须跟随一位应答位(即一帧共有9位)。
- 在第9个时钟周期的低电平期间,接收器向数据线上写入数据。
- 在第9个时钟周期的高电平期间,发送器从数据线上读取数据。
- 如果读到的是低电平信号,表示应答信号。
- 如果读到的是高电平信号,表示非应答信号。
I2C寻址
- I2C总线上传送的数据信号是广义的,既包括地址信号,又包括真正的数据信号。
- 主机在起始信号后必须传送一个从机的地址(7位),第8位是数据的传送方向位(R/W),用“0”表示主机发送数据(W),“1”表示主机接收数据(R)。
- 总线上的每个从机都将这7位地址码与自己的地址进行比较,如果相同,则认为自己被主机寻址,根据R/W位将自己定为发送器或接收器。
主机给从机发送一个字节
主机给从机发送多个字节
主机从从机接收一个字节
主机从从机接收多个字节
I2C寄存器
I2C_RXDR(I2C 接收数据寄存器)
- 位 31:8 保留,必须保持复位值。
- 位 7:0 RXDATA[7:0]:8 位接收数据 (8-bit receive data) 从 I2C 总线接收的数据字节
I2C_TXDR(I2C 发送数据寄存器)
- 位 31:8 保留,必须保持复位值。
- 位 7:0 TXDATA[7:0]:8 位发送数据 (8-bit transmit data) 待发送到 I2C 总线的数据字节
温度传感器实验
模块简介
SHT20 温湿度传感器是一种数字式温湿度传感器,它采用超薄膜式湿度传感器和热敏电阻式温度传感器,在测量环境温度和湿度方面具有高精度和可靠性。
SHT20 传感器使用 I2C 总线接口进行数据通信,它能够快速、准确地测量环境的温度和相对湿度。
可知,该器件和主控单元采用IIC进行通信
可知,最小供电电压为2.1v,最大供电电压为3.6V,推荐供电电压为3.0V,符合单片机引脚供电范围,适配!
IIC通信引脚如图
SHT20通讯原理
起始和终止时序
SHT20 采用标准的 I2C 协议进行通讯,每个传输序列都以 Start 状态作为开始并以 Stop 状态作为结束。
启动传输状态: 当 SCL 为高电平时,SDA 由高电平转换为低电平:
停止传输状态: 当 SCL 高电平时,SDA 线上从低电平转换为高电平:
通信时序
IIC地址
开始传输后,随后先传输首字节包括 I2C 设备地址(7bit)和一个 SDA 方向位(R:1, W:0)。
一个时钟发送一个位,在第 8 个下降沿之后,通过拉低 SDA 引脚(ACK 位 为 0),只是传感器数据接收正常。
在发出测量命令之后(‘1110’‘0011’代表温度测量,‘1110’‘0101’代表相对湿度测量 ,这种为主机模式), MCU 必须等待测量完成。
I2C相关命令
SHT20命令从上到下依次是:
触发温度测量(保持主机模式)
触发湿度测量(保持主机模式)
触发温度测量(非保持主机模式)
触发湿度测量(非保持主机模式)
写用户寄存器
读用户寄存器
复位
命令又分为hold与no hold两种模式。
其中hold master 和 no hold master 的意思就是,如果是hold,那么在测量过程中SHT20会主导并占用着IIC的总线,IIC总线上的其他设备无法占用,而no hold就是测量过程中SHT20不占用IIC总线,那其他设备也可以使用该数据线。
常用no hold master,但如果IIC总线上就SHT20一个设备,那么其实无所谓用哪一种。
hold master通信时序
此时序图表示的是SDA总线的状态,浅色代表当前总线控制权在主机手里,相应的数据就是主机发送的,深色代表当前总线控制权在SHT20传感器手里,相应的数据就是SHT20发送的。
刚开始主机发送起始标志,然后发送了7位IIC地址+1位写标志,表示要向当前地址模块发出指令,从机回复确认
主机发送指令代码,此处发送的是11100101,根据前面提供的指令表可知,此时发送的控制指令是在holdmaster模式下读取湿度,SHT20模块回复确认SHT20模块控制着SDA总线开始进入采样测量阶段,并在测量期间将时钟线SCL拉低,由于IIC要求高电平读取数据,所以主机在测量期间无法接收任何数据。
当测量完毕后,SHT20会释放掉时钟线,此时SCL线被上拉电阻拉高,主机可以读取数据,SHT20先发高8位,主机回复确认后,SHT20模块再发低8位数据,此时主机可发送NACK+P停止接收,也可回复ACK,SHT20模块会继续发送8位的CRC校验,主机收到后发送NACK+停止位结束当前通信。(图上是按照接收CRC校验来的)
可知上图共收到三个字节的数据,包含2个字节的湿度信息+1个字节的CRC校验
湿度信息:0110001101010010,共16位,但需要注意的是
最大的分辨率只有14位(数据最多能解析出14位来),所以最后的两位不能算进去.
手册中说43、44着两位被用来表示状态信息,43是1表示当前测量的是湿度,是0的话表示当前测量的是温度,44位的0,目前还没有被分配用处
所以湿度数据最后两位必为10,温度必为00
这并不是说明我们需要把采集的16位数据当成14位数据来用,而是我们需要把最后两位给清0,也就是将(16位数据)& 0xFFFC(1111 1111 1111 1100),
所以最后的湿度数据是0110001101010000
no hold master通信时序
刚开始主机发送起始标志,然后发送了7位IIC地址+1位写标志,表示要向当前地址模块发出指令,从机回复确认。然后主机发送指令代码,此处发送的是11110101,根据前面提供的指令表可知,此时发送的控制指令是在no holdmaster模式下读取湿度,主机等待20us后发送停止标志,由于是no holdmaster,可见在测量阶段颜色为浅色,SHT20让出了SDA总线控制,这样在测量期间主机就可以和其他从机通信了。
然后主机可以选择一个时间向SHT20发送起始标志+地址+读指令 来读取数据,如果发送时SHT20还没有测量完毕则主机收不到SHT20的ACK,SHT20会是NACK,主机收到NACK后发送停止位,再过一段时间主机会继续向SHT20发送起始标志+地址+读指令 来读取数据,如果此时SHT20测量完毕,则会回复ACK,然后主机让出SDA总线控制权,SHT20发送湿度数据。
剩下的跟上面一样,SHT20先发高8位,主机回复确认后,SHT20模块再发低8位数据,此时主机可发送NACK+P停止接收,也可回复ACK,SHT20模块会继续发送8位的CRC校验,主机收到后发送NACK+停止位结束当前通信。(图上是按照接收CRC校验来的)
同样,此时我们需要把最后两位给清0,也就是将(16位数据)& 0xFFFC(1111 1111 1111 1100),
最后的湿度数据是0110001101010000
SHT20信号转换
湿度转换
温度转换
硬件IIC实验-SHT20读取实验
引脚定位
PB7——I2C1_SDA
PB6——I2C1_SCL
cubeMX配置
驱动代码移植
重定向相关
#include<stdio.h>
int fputc(int ch, FILE * p)
{
while(!(USART1->ISR & 1<<7));//等待TDR为空,即TXE置1,跳出while,然后往TDR中放数据
USART1->TDR=ch;
}
程序编写
效果