ESP32学习笔记-IIC驱动

发布时间 2023-11-17 07:08:33作者: 能跑就行_NPJX

IIC驱动OLED屏幕

ESP32有两个I2C通道,任何管脚都可以设置为SDA或SCL。 如果要使用其他管脚,在使库函数时,只需调用:Wire.begin(SDA, SCL);

用IIC硬件刷后,发现屏幕不亮,没有深究下去,以后要深究下去,而不是傻乎乎弄了一下,不行,找了一下,就不管了

逻辑分析仪,使用方法要总结一下

数据手册总结

  • POR 是 Power-On Reset(上电复位)的缩写,它是指在设备上电启动时,各个硬件部件被初始化为默认或预设的初始状态。

ESP32 IIC整个数据发送流程

flowchart LR 新建操作IIC句柄 --> 启动信号 --> 写数据,单个或多个 --> 停止信号 --> IIC发送函数 --> 删除IIC句柄

ESP32 IIC整个数据读取流程

flowchart LR 新建操作IIC句柄 --> 启动信号 --> 写数据-地址 --> 读数据,单个或多个 --> 停止信号 --> IIC发送函数 --> 删除IIC句柄

具体硬件IIC接口

I2C 配置函数:
	i2c_param_config();
I2C 功能安装使能函数:
	i2c_driver_install();
创建 I2C 连接函数:
	i2c_cmd_link_create();
写启动信号到缓存函数:
	i2c_master_start(); 
写一个字节的命令放到到缓存函数:
	i2c_master_write_byte();
写停止信号到缓存函数:
	i2c_master_stop();
I2C 发送函数:
	i2c_master_cmd_begin();
删除 I2C 连接函数:
	i2c_cmd_link_delete();

IIC注意事项(补充上述驱动OLED没记录到的)

笔记背景:

上述OLED驱动,基本只用写就完了,我又移植了一个BMP180的驱动,关于上次笔记没记详细的地方,重新补充一些

IIC的IO配置

今天重新新建一个工程,从零添加,发现可以不用 idf.py menuconfig配置IO,目前我也还不知道怎么用idf.py menuconfig

#define IIC_SDA_IO  13				//IO序号
#define IIC_SCL_IO  12				//IO序号

#define I2C_MASTER_SCL_IO           IIC_SCL_IO      			/*!< GPIO number used for I2C master clock */
#define I2C_MASTER_SDA_IO           IIC_SDA_IO      			/*!< GPIO number used for I2C master data  */
#define I2C_MASTER_NUM              0                          /*!< I2C master i2c port number, the number of i2c peripheral interfaces available will depend on the chip */
#define I2C_MASTER_FREQ_HZ          100000                     /*!< I2C master clock frequency */
#define I2C_MASTER_TX_BUF_DISABLE   0                          /*!< I2C master doesn't need buffer */
#define I2C_MASTER_RX_BUF_DISABLE   0                          /*!< I2C master doesn't need buffer */
#define I2C_MASTER_TIMEOUT 关于读写函数的例程代码

关于驱动函数IIC的基本读写,看笔记的时候没注意到 ----很重要的一点,缓存完数据要用i2c_master_cmd_begin()函数发送数据,折腾死我了!!

//写一个数据到BMP180
void BMP_WriteOneByte(uint8_t WriteAddr,uint8_t DataToWrite)
{
    i2c_cmd_handle_t cmd = i2c_cmd_link_create();			/* 创建一个句柄,分配空间 */

    i2c_master_start(cmd);									/* 发送起始信号 */
    i2c_master_write_byte(cmd, 0xEE, I2C_MASTER_ACK);		/* 发送地址 (是否应答) */
    i2c_master_write_byte(cmd, WriteAddr, I2C_MASTER_ACK);	/* 发送寄存器地址 (是否应答) */
    i2c_master_write_byte(cmd, DataToWrite, I2C_MASTER_ACK);/* 发送数据 (是否应答) */
    i2c_master_stop(cmd);									/* 停止信号 */

	/* 上诉我理解是 类似把一套流程压到栈里,等流程走完,再按顺序依次发送 */
	i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, I2C_MASTER_TIMEOUT_MS);	

    i2c_cmd_link_delete(cmd);								/* 删除句柄,释放空间 */
}
//从BMP180读一个字节数据
uint8_t BMP_ReadOneByte(uint8_t ReadAddr)
{
	uint8_t data = 0;

    i2c_cmd_handle_t cmd = i2c_cmd_link_create();			/* 创建一个句柄,分配空间 */

    i2c_master_start(cmd);									/* 发送起始信号 */
    i2c_master_write_byte(cmd, 0xEE, I2C_MASTER_ACK);		/* 发送地址 (是否应答) */
    i2c_master_write_byte(cmd, ReadAddr, I2C_MASTER_ACK);	/* 发送寄存器地址 (是否应答) */
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, 0xEF, I2C_MASTER_ACK);		
    i2c_master_read_byte(cmd, &data, I2C_MASTER_ACK);		/* 读一个字节数据 */
    i2c_master_stop(cmd);									/* 停止信号 */
	i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, I2C_MASTER_TIMEOUT_MS);	/* 发送 */
	
    i2c_cmd_link_delete(cmd);								/* 删除句柄,释放空间 */

	return data;
}