之前一篇文章里用了模拟i2c,我这边给大家介绍一下
模拟i2c本质上就是用gpio开关来模拟i2c协议,当然,i2c协议本质上也就是电平的高低
在理解如何使用软件模拟i2c前,你需要理解i2c协议,网上又很多相关文章,我也就不在多说
模拟软件i2c需要实现以下步骤
1.gpio引脚需要是开漏输出,因为只有开漏输出,从机设备才能应答,开漏输出具有“线与”的性质
2.实现i2c协议,i2c协议是由起始型号,终止信号,应答信号,数据信号来构成的。
第一步没什么好说的,我使用的cubemx进行配置,无论是固件库还是hal库,配置起来都不难
第二步要分成很多步,我们慢慢来看
首先看一个宏定义和一个结构体
typedef struct i2c_bit_ops
{
void (*set_sda)(int32_t state);
void (*set_scl)(int32_t state);
int32_t (*get_sda)(void);
void (*udelay)(uint32_t us);
uint32_t delay_us; /* scl and sda line delay */
uint8_t writeAddr;
}soft_i2c_driver;
先看这个结构体,这个结构体是软件i2c描述,里面包含了对sda线的读写,对scl线的写,以及每个操作的延时时间,延时函数指针,以及从机地址。
#define soft_i2c_Delay() i2c_Delay(i2c_driver)
#define soft_i2c_SDA_H() i2c_SDA_H(i2c_driver)
#define soft_i2c_SDA_L() i2c_SDA_L(i2c_driver)
#define soft_i2c_SCL_H() i2c_SCL_H(i2c_driver)
#define soft_i2c_SCL_L() i2c_SCL_L(i2c_driver)
#define soft_i2c_SDA_Read() i2c_SDA_Read(i2c_driver)
#define soft_i2c_Start() soft_i2c_start(i2c_driver)
#define soft_i2c_Stop() soft_i2c_stop(i2c_driver)
static void i2c_DelayUs(soft_i2c_driver *i2c_driver,uint16_t time)
{
i2c_driver->udelay(time);
}
static void i2c_Delay(soft_i2c_driver *i2c_driver)
{
i2c_DelayUs(i2c_driver,i2c_driver->delay_us);
}
static void i2c_SCL_H(soft_i2c_driver *i2c_driver)
{
i2c_driver->set_scl(soft_i2c_high);
}
static void i2c_SCL_L(soft_i2c_driver *