Linux用I2C驱动OLED,i2c_transfer()报错,error = -6

平台:基于imx6ull开发板使用I2C驱动OLED

问题:无法驱动OLED, 在i2c_transfer()中报错, 返回error为-6.

分析思路:查看-6代表什么意思,上网搜索,得到:

 查看可以知道,有两种情况可能会出错,参考网上资料,

通信协议 I2C 子系统之 Debug-i2c通信协议 (51cto.com)

讲的很详细,很有帮助。

使用i2c-tools查看设备地址,看是不是物理地址出错。

如何使用i2c-tools看这教程:

手把手教你使用 i2c-tools-i2c-tools使用 (51cto.com)

排除是否因为设备地址出错,使用I2c-tools查看设备地址:

 查看系统的I2C总线为I2c-0 和i2c-1

21a0000.i2c表示寄存器的外设的地址,查看芯片手册可以知道:

 

所以本次OLED使用的IIC外设是I2C1,系统为我们在sys目录下自动生成的名字是i2c-0.

也可以手动在驱动源码修改。

这下总算明白了,因为之前使用STM32驱动OLED是用了软件IIC,误以为就是0x78,其实并不是。这里是使用硬件IIC,需要纯正的物理地址,最后面一位不加写bit,0。可以看OLED芯片手册:

 可以看到地址不包括R/W位。

也就是说真正是物理地址不包含bo, 而看物理接线图,b1为0.真正地址为0x3C!!!

修改设备树节点地址:

OLED成功亮起! 

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的模拟I2C驱动OLED的示例代码,使用STM32 HAL库进行编程: 1. 定义OLEDI2C地址和命令码: ```c #define OLED_ADDR 0x78 /* OLED I2C地址 */ #define OLED_CMD_SET_COL_ADDR 0x21 /* 设置列地址命令码 */ #define OLED_CMD_SET_PAGE_ADDR 0x22 /* 设置行地址命令码 */ #define OLED_CMD_SET_CONTRAST_CTRL 0x81 /* 设置对比度命令码 */ #define OLED_CMD_SET_NORMAL_DISPLAY 0xA6 /* 设置正常显示命令码 */ ``` 2. 定义I2C读写函数: ```c #define I2C_TIMEOUT 1000 /* I2C超时时间 */ /* I2C写函数 */ HAL_StatusTypeDef I2C_Write(uint8_t addr, uint8_t *data, uint16_t len) { HAL_StatusTypeDef status = HAL_OK; status = HAL_I2C_Master_Transmit(&hi2c1, addr, data, len, I2C_TIMEOUT); return status; } /* I2C读函数 */ HAL_StatusTypeDef I2C_Read(uint8_t addr, uint8_t *data, uint16_t len) { HAL_StatusTypeDef status = HAL_OK; status = HAL_I2C_Master_Receive(&hi2c1, addr, data, len, I2C_TIMEOUT); return status; } ``` 3. 定义OLED初始化函数: ```c void OLED_Init(void) { uint8_t cmd[2]; cmd[0] = OLED_CMD_SET_COL_ADDR; /* 设置列地址 */ cmd[1] = 0; I2C_Write(OLED_ADDR, cmd, 2); cmd[0] = OLED_CMD_SET_PAGE_ADDR; /* 设置行地址 */ cmd[1] = 0; I2C_Write(OLED_ADDR, cmd, 2); cmd[0] = OLED_CMD_SET_CONTRAST_CTRL; /* 设置对比度 */ cmd[1] = 0xCF; I2C_Write(OLED_ADDR, cmd, 2); cmd[0] = OLED_CMD_SET_NORMAL_DISPLAY; /* 设置正常显示 */ cmd[1] = 0; I2C_Write(OLED_ADDR, cmd, 2); /* ...其他初始化操作... */ } ``` 4. 定义OLED写入数据函数: ```c void OLED_WriteData(uint8_t *data, uint16_t len) { uint8_t cmd[2]; cmd[0] = 0x40; /* 写入数据 */ I2C_Write(OLED_ADDR, cmd, 1); I2C_Write(OLED_ADDR, data, len); } ``` 5. 调用上述函数进行OLED的初始化和写入数据: ```c /* OLED初始化 */ OLED_Init(); /* 写入数据 */ uint8_t data[8] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}; OLED_WriteData(data, 8); ``` 以上代码仅供参考,具体实现还需要根据具体的OLED型号和使用的I2C接口进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值