不考虑PEC,SMBus有6种数据传输格式。
1,快速命令
2,发送字节和接收字节
3,写字节/字 和 读字节/字
4,字的读写的过程调用(Process Call)
5,块的读和写
6,块的读写的过程调用(Process Call)
如果考虑PEC,除了 快速命令 模式没有PEC外,其余5种都有带PEC的格式。
1,快速命令
这种模式,没有数据的发送和接收。Slave address中的Rd/Wr表示了主设备发给从设备的命令(part of the slave address denotes the command – the R/W# bit)。Rd=1, Wr=0,Rd/Wr用来开启从设备的某项功能(The R/W# bit may be used to simply turn a device function on or off, or enable/disable a low-power standby mode)。可见这里的Rd/Wr就不再是主设备对从设备的读和写了。
下面就是SMBus的快速模式协议,工作原理是:主设备通过Slave Address的高七位寻址到从设备,然后通过Rd/Wr来开启或者关闭该从设备的某项功能。从设备接收到开启关闭命令后,导通开漏MOS管拉低DATA 为低电平,产生应答信号ACK告诉主设备,我已经被你寻址到并收到你发来的开关信号。最后由主设备产生一个STOP条件结束两者的通信。
显然,快速命令 模式适合于主控制器对设备进行简单的控制的情况。
注意,快速命令协议中的第9位总是ACK低电平,就算是第8位为高电平1,第9位也是ACK,而不是NACK,因为快速命令协议中的第8位不是主设备对从设备的读和写指令,只是对从设备的某项功能的开关位。
2, 发送字节和接收字节
发送字节: 主设备可向从设备传送一个字节(注意,只有1个哦!)的数据,由于一个字节由8个bit组成,所以这个数据可有28 =256种命令。这个字节的整体或者部分构成了主设备发给从设备的命令command。比如,该字节的高7位可能会为主设备指定一种访问从设备某种特殊功能的方法(如选择从设备的某种工作模式),而最低位也就是第8位用来开启和关闭从设备这种特殊功能。又比如,主设备向从设备发送让从设备可有28 =256种可能大小的某种输出量的指标,如让CPU core供电芯片产生各种大小的电压,类似SVID的功能。
接收字节:主机从从设备中读取所需要的信息,就采用接收字节的协议。注意,接收字节协议以主机的NACK作为主机接收结束标志。
注意:不论是 发送字节协议 还是 接收字节协议 ,主设备寻址到从设备后,都没有在这两种协议中给出数据要读取或者存放的偏移地址(index),这是因为前面已经有了目标偏移地址,只需要在前面已经指定的偏移地址上操作数据(读取或者存放数据)。
下面是发送字节协议和接收字节协议。
3, 写字节/字 和 读字节/字
写字节:写字节 协议 和 发送字节 协议 在数据格式上,差别就在于写字节多了一个命令字节(command code),通常这个命令字节用来指定从设备中数据操作的偏移地址。可见,“写”和“发送”的区别在于,“写”是专门向从设备某一地址index处存放一个数据data,是附庸在 偏移地址 上的一个含义。
写字:一个字(word)等于2个字节(byte),分为Low Byte和High Byte,只要把上面的“写字节”协议中的字节换成字(两个字节)即可。
读字节 / 读字 协议和 写字节 / 写字 协议基本类似,只是在主设备向从设备发出命令command code并得到从设备ACK后,主设备再发起repeat start来启动读的指令。最后,读数据操作结束后,由主设备发出NACK来标志。
注意:
1, 比较容易忽略的是,字word的两个高低字节byte之间的ACK,因为SMBus规定,每个字节后都必须跟一个应答位,即ACK或NACK。写字协议 中字word的两个高低字节byte之间的ACK由从设备发出,而 读字协议 中字word的两个高低字节byte之间的ACK由主设备发出。
2, 主设备发起repeat start来启动读的指令时,只需要对该从设备进行重复的寻址,而不需要再发一个Command Code,因为这个Command Code在repeat start前面的字节已经完成了。
3,字节(byte)的读和写只能是1个数据字节;字(word)的读和写只能是1个数据字,也就是高低2个字节(Low Byte, High Byte)。
问题:深度比较 发送字节协议 和 字节/字的写协议;接收字节协议 和 字节/字的读协议
1, 为什么没有“发送字协议”和“接收字协议”?
2, 为什么“发送字节协议”和“接收字节协议”都没有像“写”和“读”协议一样有专门的Command Code?
4, 字的读写的过程调用(Process Call)
字的读写的过程调用(Process Call),简称 过程调用(Process Call),是一种既有字的写,又有字的读的协议。注意,这里是字word,不是字节byte !换句话说,字节byte的读写是没有过程调用的。
过程调用的 “先写后读”要求:这个协议要求,字的“写”一定是在字的“读”的前面,也就是说,主设备向从设备写一个字,然后,从设备根据这个来自于主设备的字在相同的偏移地址处作出相应的反应,发出一个字给主设备,让主设备读取。
同 字节/字读协议,主设备发起repeat start来启动读的指令时,只需要对该从设备进行重复的寻址,而不需要再发一个Command Code,因为这个Command Code在repeat start前面的字节已经完成了。一个典型情况就是,主设备给从设备的某个偏移地址写一个字后,从设备作出相应的响应,从同一个偏移地址处回馈给主设备一个字,这个过程中,读的时候,主设备就不需要再告诉从设备读取数据的偏移地址了,因为,前面写字的偏移地址就是现在读字的偏移地址!这就是过程调用的第二个要求:“读写同址”
5,块的读和写
这里的“块”的结构包括两个部分:字节数N和各个数据字节(Bytes),其中N(写的字节数或读的字节数)都不能为0,但都不能大于32,即0 块的读和写 的工作原理(以“写”为例,说明Byte Count字节):从设备接收到主设备发送来的Byte Count字节,实际就是主设备要告诉从设备,我要给你写N个字节,你做好该做的准备。 注意 1, 32不包括:Slave Address Byte, ACKs, NACK 2, 比较容易忽略的是,每个字节后面的ACK,特别是Byte Count后面和每个Data Byte后面的ACK(和最后的NACK,在读协议中)。 3,字节/字/块 的读写都涉及到一个Command Code的写入,即偏移地址的写入,所以字节/字/块 的读写的协议数据格式的第一个字节的第8位总是“写”,即为0。 6, 块的读和写的过程调用(Process Call) 把字的读和写的过程调用中的字word换成块(字节数字节和数据字节),就变成了块的读和写的过程调用。 同字的读写过程调用,块的读写过程调用也有“先写后读”和“读写同址”的要求。 深入研究: 1, 字节的读和写为什么没有过程调用? 2, 字节的读和写,以及字的读和写过程中,为什么没有字节数字节? 解析: 对字节的读和写:该协议规定了,只能读或者写一个字节,所以不需要再指定个数了。 对字的读和写:一个字(word)等于2个字节(byte),分为Low Byte和High Byte。字节数字节 Data Byte Count的作用是指定写和读的数据字节的个数,而字就是由2个字节构成,个数就是2,已经固定了,不需要再指定个数了。 3, 块的读写中,数据字节数data byte count为什么不能为0? 解析: 如果数据字节数data byte count N=0,那么就是说这个块的数据字节数目为0,这显然不是块的定义。还可能会误会为数据值为00H的字节的读写。 深化: 如果数据字节数data byte count N=1,那么就是说这个块的数据字节数目为1,这时,尽管“字节byte的读写协议”中数据字节数也是1,但由于块的定义包括Data Byte Count字节和数据字节,即比“字节的读写协议”多了一个Data Byte Count字节,所以两者还是不同的,不可混淆! 如果数据字节数data byte count N=2,那就是说这个块的数据字节数目为2,这时,尽管“字word的读写协议”中数据字节数也是2,但由于块的定义包括Data Byte Count字节和数据字节,即比“字的读写协议”多了一个Data Byte Count字节,所以两者也还是不同的,不可混淆! 从上分析可以看出,字节(byte)的读写,字(word)的读写 和 块(block)的读写三者是互斥的,没有包含和被包含的关系。但三者的数据格式有类似变量替换的关系,即设读写的数据field为X,当X为单个字节时,就是字节的读写,当X为字(高低字节)时,就是字的读写,当X为块(包括数据字节数字节 和 数据字节)时,就是块的读写。 4,过程调用(Process Call)的本质是什么,为什么要用它,为什么会是先写后读,后面的读和前面的写的Command Code (偏移地址index)为什么是一样的? 解析: 过程调用(Process Call)的本质是一次SMBus既有字或者块的写,又有字或者块的读,即字或者块的读写同时出现,但是两者的先后顺序必须是:先写后读。 过程调用的目的是:主设备向从设备的某个偏移地址写入某个字或者块后,需要该从设备的这个偏移地址处作出基于前面写入的字或块的响应。即“后读是基于前写的响应”。而过程调用能满足客户的这一要求。 那么,有没有这种情况,主设备在偏移地址index1处向该设备写入内容,后要求该从设备在偏移地址index2处(index1≠index2)向主设备回馈内容呢,即写的偏移地址和读的偏移地址不用的情况? 在实际中,这样的情况肯定是经常遇到的,这时,我们就不需要用过程调用的读写协议来完成了,因为过程调用要求“先写后读”2次动作的偏移地址是相同的。 总之,不论是 字的读写过程调用 还是 块的读写过程调用,都要满足两个要求:“先写后读”和“读写同址”。 5,过程调用的“先写后读”要求与字节/字/块的读写协议的第一个字节的第8位读写位总是为“写”之间是什么关系? 解析: 字节/字/块的读写协议的第一个字节的第8位读写位总是为“写”,是因为,主设备要想从设指明需要数据操作的偏移地址,而这个偏移地址是需要主设备发送给从设备的,不然从设备怎么主设备要在哪个偏移地址处进行数据的读和写呢。 而过程调用的“先写后读”要求,是指主设备对从设备的数据操作的顺序必须是“先写后读”。可见,两者的对象是不同的,字节/字/块的读写协议的第一个字节的第8位读写位总是为“写”,“写”的是数据操作所在的偏移地址,对象是index或者说command;而过程调用的“先写后读”,“写”的data,是数据。下载本文