SP8627 NY10F - I2C
题目描述
I $ ^{2} $ C(集成电路间通信)是一种串行通信协议,用于将低速外设(100 kbit/sec)连接到主板、嵌入式系统或手机。一个 I $ ^{2} $ C 数据总线可以连接多个设备,每个设备具有不同的 7 位地址。I $ ^{2} $ C 的一个优点是只需要两条信号线:SCL(时钟)和 SDA(数据)。每当时钟(SCL)触发一次,就在 I2C 数据总线(SDA 线)上呈现一位数据。通常,总线上的一个设备被指定为主设备,其他设备为从设备。主设备通过在总线上指定特定设备的地址来发起通信。
如果 I $ ^{2} $ C 总线上没有活动,SCL 和 SDA 信号都处于高状态(1)。主设备通过在 SCL 信号为高(1)时将 SDA 信号拉低(0)来在总线上发起一个事务:这被称为 START 位。此时,总线上的所有从设备必须开始关注信号,以查看该事务是否指向它们。然后,主设备将发送 7 位从设备地址(最高有效位优先),每次发送一位。这是通过将 SCL 信号拉低(0),在 SDA 线上呈现下一个比特值,然后释放 SCL 信号使其变高(1)来完成的。从设备将在时钟变高(1)时读取 SDA 信号。这个操作重复 7 次,对应于所需的从设备地址的每一位。再以同样的方式在总线上呈现另一位数据。这最后一位表示主设备是要从(1)还是写入(0)所寻址的从设备。当从设备在总线上识别出其地址时,它必须通过将 SDA 线拉低来确认(ACK)其可用并准备好。主设备将在下次将时钟拉高时看到这一点,此时,数据传输可以开始。如果没有看到 ACK,则表示由地址指定的从设备不存在。注意:如果没有任何设备将信号拉低,默认情况下信号会变高;设备只需释放信号,信号就会变高。
数据总是以 8 位字节的形式传输,每次传输一位,最高有效位优先。在每个字节之后,从设备必须通过将 SDA 线拉低来确认主设备。如果从设备尚未准备好发送(或接收)下一个字节的数据,它可以将 SCL 线拉低。这将使主设备进入等待模式,直到从设备准备好。从设备通过将 SDA 拉低,并释放 SCL 线使其变高来表示已准备好。然后可以传输下一个字节的数据。该序列重复,直到主设备决定所有数据都已传输完毕,此时它将发送 STOP 位。这是在主设备让 SDA 线在 SCL 线为高时变高来完成的。
对于这个问题,你需要编写一个程序来嗅探 I $ ^{2} $ C 总线信号并显示事务的详细信息。
输入格式
输入的第一行包含一个整数 $P$($1 \le P \le 1000$),表示接下来的数据集数量。每个数据集由多行组成,代表一个 I $ ^{2} $ C 事务。第一行包含两个十进制整数值:问题编号,后跟空格,后跟信号样本数量 $S$($1 \le S \le 1161$)。剩余的行包含信号样本。每行包含 40 个样本(最后一行可能少于 40 个)。每个样本由 2 个二进制数字字符表示 SCL 和 SDA 的顺序。
输出格式
对于每个数据集,输出一行,包含一个十进制整数表示数据集编号,后跟一个空格,后跟事务的描述。只有六种不同的描述(两种非错误情况和四种错误情况):
非错误情况:
- 写入 _n_ 字节到从设备 _xx_
- 从从设备 _xx_ 读取 _n_ 字节
错误情况:
- 错误:无 START 位
- 错误:无 STOP 位
- 错误:从设备 _xx_ 无 ACK
- 错误:数据无 ACK
其中,_n_ 是一个十进制整数(1 - 128),表示数据字节数;_xx_ 是一个两位十六进制值(00-7F),表示从设备地址。
对于错误情况,仅显示检测到的第一个错误。
说明/提示
- $1 \le P \le 1000$
- $1 \le S \le 1161$