I2C
前置知识
I2C(Inter-Integrated Circuit)是一种多主机、两线制、低速串行通信总线,广泛用于微控制器和各种外围设备之间的通信。常见应用于传感器(如温度传感器TMP101、加速度计MPU6050)、存储器(如EEPROM芯片AT24CXX系列)、实时时钟、数字电位器等模块的通信。
接口说明
C1201具有2组I2C接口
硬件编号 |
位置 |
引脚编号 |
Linux设备文件 |
扫描命令 |
|---|---|---|---|---|
I2C0 |
40pin引脚 |
pin27,I2C0_SDA |
/dev/i2c-1 |
i2cdetect -y 1 |
I2C1(默认) |
40pin引脚 |
pin3,I2C1_SDA |
/dev/i2c-7 |
i2cdetect -y 7 |
接口实验
通过I2C接口在OLED屏显示图形
OLED屏
OLED显示屏通常通过一个4引脚的I2C接口与Jetson设备连接。Jetson设备接口与OLED屏幕基于I2C协议进行通讯。
OLED驱动芯片(如SSD1306)内部有一块图形显示数据RAM,这块显存直接映射到屏幕上的每一个像素。本实验采用128x64像素的屏幕,其显存被组织为一个1024字节(128 x 64 / 8)的矩阵。每个字节的8个比特(bit)控制着屏幕上垂直一列的8个像素。比特值为1表示像素点亮,为0则表示熄灭。
Python驱动库封装了I2C通信细节和显存操作。当调用Python库的函数绘制图形或文字时,库底层就是在计算并修改这块显存对应位置的值。Python通过驱动库控制OLED屏的显存来显示图形。
在Jetson设备上使用Python通过I2C接口控制OLED显示屏的流程如下:
引脚接口
实验步骤
1.连接Jetson设备与OLED
2.使用i2cdetect工具扫描I2C设备地址
sudo i2cdetect -l
i2c-0 i2c 3160000.i2c I2C adapter
i2c-1 i2c c240000.i2c I2C adapter
i2c-2 i2c 3180000.i2c I2C adapter
i2c-4 i2c Tegra BPMP I2C adapter I2C adapter
i2c-5 i2c 31b0000.i2c I2C adapter
i2c-7 i2c c250000.i2c I2C adapter
i2c-9 i2c i2c-2-mux (chan_id 1) I2C adapter
i2c-10 i2c i2c-2-mux (chan_id 0) I2C adapter
i2c-11 i2c NVIDIA SOC i2c adapter 0 I2C adapter
I2C1对应i2c-7
3.扫描i2c-7,OLED屏幕地址位0X3c
sudo i2cdetect -y -r 7
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- 3c -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
4.安装OLED驱动和图形库
luma.oled:用于控制SSD1306显示屏。
pillow:用于图像绘制(luma.oled的依赖)
sudo pip install luma.oled pillow
5.通过I2C接口显示正方形
#!/usr/bin/env python3
"""
Jetson Orin Nano OLED显示实验
功能:通过I2C连接SSD1306 OLED屏,显示一个正方形
硬件:Jetson Orin Nano + 0.96寸OLED(I2C地址0x3C)
"""
import time
from luma.oled.device import ssd1306
from luma.core.interface.serial import i2c
from luma.core.render import canvas
from PIL import ImageDraw
def main():
try:
# 初始化I2C接口和OLED设备
# 参数说明:
# port=7: 使用Jetson的I2C总线7(对应/dev/i2c-7)
# address=0x3C: OLED的I2C地址(常见为0x3C或0x3D)
serial = i2c(port=7, address=0x3C)
device = ssd1306(serial)
print("OLED显示屏初始化成功!")
print(f"屏幕分辨率:{device.width} x {device.height}")
# 使用绘图画布绘制图形
with canvas(device) as draw:
# 绘制一个正方形:左上角坐标(30, 15),右下角坐标(98, 49)
# 轮廓色(outline)为白色,填充色(fill)为黑色(即不填充)
draw.rectangle([(30, 15), (98, 49)], outline="white", fill="black")
# 可选:添加标签说明
draw.text((10, 50), "Square Demo", fill="white")
print("正方形已显示在OLED屏幕上。")
print("按 Ctrl+C 退出程序。")
# 保持显示,直到用户中断
while True:
time.sleep(1)
except Exception as e:
print(f"错误发生:{e}")
print("可能的原因:")
print("1. I2C连接错误:检查硬件连接和I2C地址")
print("2. 权限问题:尝试使用sudo运行脚本")
print("3. 库未安装:确认已安装luma.oled和pillow")
if __name__ == "__main__":
main()
显示效果:
关键问题
Q1.I2C设备的地址如何确定?
1)查阅数据手册。 地址通常为7位。数据手册直接给出一个值,例如 0x48;在实际通信时,需要将这7位地址左移一位(即乘以2),并在最低位加上读写方向位(0为写,1为读),构成一个8位的“从机地址”字节 。例如,设备地址 0x48(二进制 1001000) 对应的写地址为 0x90(10010000),读地址为 0x91(10010001);
2)某些I2C设备给出一个地址格式,说明其中一部分是固定的,另一部分由硬件引脚决定 。例如,某传感器地址格式为 1100 A2 A1 A0,其中 1100是固定的,A2 A1 A0三位由引脚电平决定。查看芯片引脚定义,找到地址引脚;检查这些引脚是连接至GND(低电平 0)还是VCC(高电平 1);根据数据手册中的地址格式,将电平值代入对应的位,计算出唯一的7位地址。允许在同一总线上连接多个同型号器件
Q2.OLED屏幕的地址?
SSD1306驱动的OLED屏,地址通常由OLED模块上的一个地址选择引脚(如A0)的电平或电阻的焊接位置决定。通常为0X3C或0X3D。
Linux安装了i2c-tools后,可以运行以下命令扫描地址:
sudo i2cdetect -y -r 7
(OLED屏连接于I2C1)