初学 SMBus

本文介绍了System Management Bus (SMBus) 的基本概念,它是Intel在1995年提出的一种用于主板设备间通信的总线。SMBus与I2C类似,由时钟线SMBCLK和数据线SMBDAT组成。通讯协议分为物理层、数据链路层和网络层。物理层涉及电压电平和噪声容限;数据链路层包括Start/Stop信号、ACK确认和数据传输;网络层则涉及具体的指令解析和执行。SMBus通讯允许主设备与从设备间进行数据交换,如读取EEPROM、温度传感器等信息。

(这篇主要对象为固件工程师,简单介绍SMBus的一些基本概念而已)

概述

System Management Bus (简称SMBus或是SMB) ,是1995年由Intel提出的,用来访问主机板上的设备(EEPROM、温度感测器、电压感测器等) 并收集相应的资讯(SPD、温度、电压、版本号)。 SMBus和I2C很相近,都是由两条线: Clock (SMBCLK) 和 Data (SMBDAT) 所组成的。

SMBus 通讯协议主要可以分为物理层,数据链路层和网络层三层

The Physical Layer (物理层):

不同的设备要在同一条SMBus上进行沟通预计将在至少两个具有不同电气要求的互斥环境中运行。这部分主要定义电压电平、噪声容限等。 (主要偏硬体,我也不太熟)

可以注意的地方是,SMBCLK和SMBDAT必须要设为 open drain,并且在bus没有使用的时候,两条线都需要 pull up

The Data Link Layer (数据链路层):

收到讯号之后,就可以解析讯号。 SMBCLK 通常由Master操作,目前SMBus spec定义三种频率:100 kHz、400 kHz 和 1 MHz。一般SMBDAT 是在SMBCLK low 变化,SMBCLK high 时是有效值,所以经验上来看,SMBus 两端device 的 clock frequency不需要设成一样,运作上slave 不用知道 clock frequency,只要它来得及处理就可以。解析讯号可以分为三个部分:

(1) Start and Stop

Start:在SMBCLK为high的时候,SMBDAT从high变low,表示开始通讯

Stop:在SMBCLK为high的时候,SMBDAT从low变high,表示结束通讯

​​​​​​​

 

(2) ACK (Acknowledge)

ACK表示收到了,就是SMBCLK为high的时候,SMBDAT为low

如下图,红色和蓝色的动作都是指在同一条SMBDAT上,前面有提到SMBDAT是必须设为 open drain,所以传送者和接收者两端都可以对其做操作。

 

因为SMBDAT没有人操作的时候,需要pull up,因此如果传送完8个bit,接收者没有回覆ack,就表示not ack(没人收到东西)

(3) Data Transfer

在 START 条件 (“S”) 之后,Master会先传送欲沟通的设备之 7 bits address。 Address后边跟的第8个bit是R/W#,0表示写入,而1表示数据读取。

在传送数据的时候,如果SMBCLK high的时候 SMBDAT 为high表示要传送的数据是1,反之如果SMBDAT为low表示要传送的数据为0。

最后资料传输由Master产生的 STOP (P) 条件终止。

 

Network Layer (网路层) :

这边就是将数据链路层解析出来的数据,解析欲执行动作,并作相对应处理。 SMBus有定义一些指令,例如下图,详情参阅 SMBus Specifications

但是通常这部分详细指令对应行为,还是会去参考设备的文件,这边用4-Kbit Serial Presence Detect (SPD) EEPROM compatible with JEDEC EE1004 (st.com) 举个简单的例子

它的spec中定义,Start之后第一个byte为slave address,第8个bit设为0表示write,后面接的byte就表示想要读取的offset (偏移量)

接着传送一个Re-Start,传送slave address,第8个bit设为1,Slave回复ack之后,会接着回覆该offset所存放的数据,直到Master发起Stop讯号

下图的Random Address Read对应SMBus Command 就是Read Byte

Seqential Random Read应该比较像 Read 32吧,不完全一样,有一点点变形

### 使用 Python 访问 SMBus Python 是一种易于使用的编程语言,尤其适合初学者,因为它不需要像 C 或 C++ 那样处理复杂的指针和内存管理问题[^1]。为了与 SMBus 进行交互,可以使用 `smbus` 库来实现这一功能。 #### 安装 smbus 库 在 Raspberry Pi 上启用 I2C 功能之前,需要先通过 `raspi-config` 工具或手动编辑 `/boot/config.txt` 文件来进行设置[^2]。之后安装 `smbus` 库: ```bash sudo apt-get update sudo apt-get install python-smbus ``` 如果使用的是 Python 3,则可能需要额外安装支持库: ```bash sudo apt-get install python3-smbus ``` #### 编写代码访问 SMBus 下面是一个简单的例子,展示如何读取和写入 SMBus 设备上的数据: ```python import smbus import time # 创建 SMBus 对象实例 bus = smbus.SMBus(1) # 使用 /dev/i2c-1 总线 (Raspberry Pi 的默认) # 假设设备地址为 0x48(可以根据实际硬件调整) device_address = 0x48 def write_to_device(value): """向指定的 SMBus 地址写入单字节""" bus.write_byte(device_address, value) def read_from_device(): """从指定的 SMBus 地址读取单字节""" return bus.read_byte(device_address) if __name__ == "__main__": try: while True: # 向设备发送一个值 write_to_device(0xFF) # 等待一段时间以便观察效果 time.sleep(1) # 从设备读回数据并打印到控制台 data = read_from_device() print(f"Read from device: {data}") except KeyboardInterrupt: print("Program terminated by user.") ``` 上述代码展示了基本的 SMBus 数据交换操作,包括写入和读取单字节数据的功能。需要注意的是,在某些情况下,还需要考虑多字节通信以及特定协议的支持情况,比如 MODBUS 协议的应用场景[^3]。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值