在项目中使用了HP6心率血压、SHT20温湿度、MPU6050传感器,今天开始分别复习一下
因为这是一个比较庞大的复习工程,不是分分钟就写完的,请读者见谅,如果要看记得关注,如果有要讨论的,直接在下面留言就可
HP6心率血压
使用的是IIC接口,那么顺便复习一下IIC的知识
IIC复习
IIC简介:
IIC(Inter-Integrated Circuit)总线是一种由 PHILIPS 公司开发的两线式串行总线, 用于连接微控制器及其外围
设备。 它是由数据线 SDA 和时钟 SCL 构成的串行总线, 可发送和接收数据。 在 CPU 与被控 IC 之间、 IC 与 IC 之
间进行双向传送, 高速 IIC 总线一般可达 400kbps 以上。
I2C 总线在传送数据过程中共有三种类型信号, 它们分别是: 开始信号、 结束信号和应答信号。
开始信号: SCL 为高电平时, SDA 由高电平向低电平跳变, 开始传送数据。
结束信号: SCL 为高电平时, SDA 由低电平向高电平跳变, 结束传送数据。
应答信号: 接收数据的 IIC 器件在接收到 8bit 数据后, 向发送数据的主控发出特定的低电平脉冲, 表示已
收到数据。 主控向被控制的 IIC 器件发出 8bit 数据后, 等待被控制的 IIC 器件发出一个应答信号, 主控 接收到应
答信号后, 根据实际情况作出是否继续传递数据的判断。 若未收到应答信号, 则判断被控制的 IIC 器件出现故障。
这些信号中, 起始信号时必须的, 结束信号和应答信号, 都可以不要。 下面是他的时序图:
IIC数据接口
两条:
SDA 串行的数据线
SCL 串行的时钟信号线
IIC通讯速度
SCL 的频率就是 IIC 的通信速度,IIC 的通信速度分:标准 IIC ( 100KHz),快速 IIC ( 400KHz),高速 IIC ( 3.4MHz)。
平常使用得多的: 标准 IIC( 100Khz) , 快速 IIC( 400Khz) 。
IIC 速度为 100KHz, 则一个时钟周期为:T=1/f=10us。IIC的通讯速度由器件决定的,具体要看器件的相关数据手册。
器件地址
IIC 靠器件地址来区分不同的芯片, 不同的芯片有它的器件地址, IIC 协议早期的器件地址只有 7 位, 现在扩展到 10 位。 7 位设备地址的芯片居多。
用一个字节里面的高 7 位代表器件的地址, 最低位用来代替要对芯片进行操作( 读写操作) 最低位为’0’的时候,
就是写操作; 最低位为’1’的时候, 就是读操作。
举例: 一个芯片它的设备地址: 1100 000b, 如果我们在通信的时候发送的是: 1100 0000b 代表要对芯片进行写
操作; 同理如果我们在通信的时候发送的是: 1100 0001 代表要对芯片进行读操作。
软件模拟
目前大部分的MCU有IIC总线接口,但是STM32为了规避专利问题,他的硬件的iic并不稳定。所以我们使用软件模拟的方法,这样不仅解决稳定问题,还可以方便后期的移植工作。
起始信号
两个芯片之间通信, 主机在通信的时候, 第一个发送的信号。 具体为: 在 SCL 为高电平的时候, SDA 从高电
平变为低电平。
IIC_SDA = 1;
IIC_SCL = 1;
IIC_SDA = 0;
//快速 IIC:延时 0.6us 标准 IIC: 延时 4us
结束信号
结束信号: 两个芯片之间通信, 主机在通信的时候, 最后一个发送的信号, 具体为: 在 SCL 为高电平的时候,
SDA 从低电平变为高电平。
IIC_SDA = 0;
IIC_SCL = 1;
//快速 IIC:延时 0.6us 标准 IIC: 延时 4us
IIC_SDA = 1;
应答信号
应答信号 ACK: 两个芯片之间通信, 谁接收到 8 位数据, 谁要给发送方应答信号。 应答信号: 把数据线 SDA
拉低电平( 谁给应答谁就拉低) 。
不给应答: 只有主机可以不给应答, 什么情况可以不给应答? 主机接到最后一个数据, 它不需要从机再给数据
主机了, 不给应答( 把数据线拉高电平) 。
从机收到数据, 从机给出应答( 谁去接收应答? 主机) , 从机只会给应答 0。
主机在时钟线 SCL 为高电平的时候, 读取应答信号
主机收到数据, 主机给出应答( 谁去接收应答? 从机) 。 给应答信号: 代表主机要继续要数据。 不给应答: 代
表主机不再需要数据。
接收数据的器件( slave) 在接收到 8 位数据后, 向发送数据的器件( master) 发出特定的低电平脉冲, 表示已
收到数据。 主器件在第 9 个时钟位上释放数据总线 SDA, 使其处于高电平状态, 此时从器件输出低电平拉低数据总
线 SDA 为应答信号。
//get 应答信号
u8 master_get_ack(void) //读应答
{
u8 ack;
SCL=0;
SDAOUT=1; //SDA 切换为读模式
iic_delay( );
SCL=1;
iic_delay( );
ack=SDAIN;
SCL=0;
return ack;
} //
give 应答信号
void master_give_ack(u8 ack)
{
SCL=0;
SDAOUT=ack;
iic_delay( );
SCL=1;
iic_delay( );
SCL=0;
}
读字节/写字节
在 I2C 总线上, 数据是伴随着时钟脉冲, 一位一位地传送的, 数据位由高到低传送, 每位数据占一个时钟脉冲。
I2C 总线上的在时钟线 SCL 高电平期间, 数据线 SDA 的状态就表示要传送的数据, 高电平为数据 1, 低电平为数据
0。 在数据传送时, SDA 上数据的改变在时钟线为低电平时完成, 而 SCL 为高电平时, SDA 必须保持稳定, 否则
SDA 上的变化会被当作起始或终止信号而致使数据传输停止。
总线空闲: SCL 和 SDA 都保持高电平。
总线忙: 在数据传送开始以后, SCL 为高电平的时候, SDA 的数据必须保持稳定, 只有当 SCL 为低电平的时
候才允许 SDA 上的数据改变。
在 SCL 为高电平的时候, SDA 的跳变都是信号的产生。 数据只能在 SCL 上升沿的时候给。
IIC 的写字节函数( 主机给从机发送数据) :
主机在时钟线 SCL 上升沿, 给出数据
连续给 8 个数据位, 最先给出的是最高位
IIC 的读字节函数( 从机给主机发送数据) :
主机在时钟线 SCL 上升沿, 读取数据
连续读 8 个数据位, 最先读到位是最高位
注意: 在主机读取从机给出的数据的时候, 数据线给从机用, 如果主机没有把数据线放掉, 从机发的都是 0。所以主机如果把数据线给从机用, 在从机使用之前要主动放弃数据总线( 主机输出一个 1 就可以了) 。