目录
1、I2C简介
2、I2C时序单元
2.1 起始条件
2.2 终止条件
2.3 发送一个字节
2.4 接收一个字节
2.5 发送应答
2.6 接收应答
3、I2C完整时序
3.1 指定地址写一个字节
指定地址写一个字节的时序分析如下:
如果需要连续写多个字节,只需要最后主机不需要主动拉低SDA,并且重复⑥⑦步,直到写完所有字节,再执行⑧步即可。④~⑦步传输的数据含义是双方约定的,不一定是这个时序中的含义。
3.2 当前地址读一个字节
如果主机还需要继续接收,那么③步应答0,从机继续发送数据(重复②,但是寄存器地址会自增),直到主机不再需要读数据,那么执行③④步表示结束。
3.2 指定地址读一个字节
如果主机还需要继续接收,那么最后重复当前地址读中的③步应答0,从机继续发送数据(重复②,但是寄存器地址会自增),直到主机不再需要读数据,那么执行③④步表示结束。
4、简单软件I2C代码(HAL)
4.1 软件I2C
可以看到除了结束条件,任何一个时序单元,SCL都以低电平结束,便于拼接、避免错误
#include "stm32f1xx_hal.h"
#include "Dealy.h"
//PB6和PB7配置成普通开漏输出模式
#define SCL_PORT GPIOB
#define SDA_PORT GPIOB
#define SCL_PIN GPIO_PIN_6
#define SDA_PIN GPIO_PIN_7
/**
* 函 数:I2C写SCL引脚电平
* 参 数:BitValue 协议层传入的当前需要写入SCL的电平,范围0~1
* 返 回 值:无
* 注意事项:此函数需要用户实现内容,当BitValue为0时,需要置SCL为低电平,当BitValue为1时,需要置SCL为高电平
*/
void MyI2C_W_SCL(uint8_t BitValue)
{
HAL_GPIO_WritePin(SCL_PORT, SCL_PIN, (GPIO_PinState)BitValue); //根据BitValue,设置SCL引脚的电平
Delay_us(10); //延时10us,防止时序频率超过要求
}
/**
* 函 数:I2C写SDA引脚电平
* 参 数:BitValue 协议层传入的当前需要写入SDA的电平,范围0~0xFF
* 返 回 值:无
* 注意事项:此函数需要用户实现内容,当BitValue为0时,需要置SDA为低电平,当BitValue非0时,需要置SDA为高电平
*/
void MyI2C_W_SDA(uint8_t BitValue)
{
HAL_GPIO_WritePin(SDA_PORT, SDA_PIN, (GPIO_PinState)BitValue); //根据BitValue,设置SDA引脚的电平,BitValue要实现非0即1的特性
Delay_us(10); //延时10us,防止时序频率超过要求
}
/**
* 函 数:I2C读SDA引脚电平
* 参 数:无
* 返 回 值:协议