I2C和SPI协议

Posted Dufre.WC

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了I2C和SPI协议相关的知识,希望对你有一定的参考价值。

I2C

I2C(Inter-Integrated Circuit)是Philips公司开发的两线式串行总线,I2C支持多主控(Multi-Mastering)模式,任何能够进行发送和接收的设备都可以成为Master,Master能够控制数据的传输和时钟频率,在任意时刻只能有一个主控。

组成I2C总线的两个信号为数据线SDA和时钟SCL。I2C规定:

  • 每一支I2C设备都有一个唯一的七位设备地址
  • 数据帧大小为8位的字节
  • 数据帧中的某些数据位用于控制通信的开始、停止、方向(读写)和应答机制

I2C数据有以下几种模式:

  • 标准模式(100kbps)
  • 快速模式(400kbps)
  • 高速模式(3.4Mbps)

I2C通信过程大致如下:

  • 首先Master发一个START信号,告诉其他设备开始监听总线以准备接收数据。
  • 接着,主设备发送一个7位设备地址加一位的读写操作的数据帧。
  • 当设备接收数据后,比对地址自己是否为目标设备
    • 不是目标设备:设备进入等待状态,等待STOP信号的来临
    • 是目标设备:设备会发送一个应答信号-ACKNOWLEDGE作回应
  • 主设备收到应答后,便开始传送或接收数据,数据帧大小为8位,尾随一位的应答信号
  • 主设备发送数据,从设备应答;主设备接数据,主设备应答
  • 当数据传送完毕,主设备发送一个STOP信号,向其它设备宣告释放总线,其它设备回到初始状态



I2C消息结构

  • addr:发送地址
  • flags
  • len:msg长度
  • buf:msg数据

include/uapi/linux/i2c.h

struct i2c_msg 
	__u16 addr;	/* slave address */
	__u16 flags;
#define I2C_M_RD 0x0001 /* read data, from slave to master */
					/* I2C_M_RD is guaranteed to be 0x0001! */
#define I2C_M_TEN 0x0010 /* this is a ten bit chip address */
#define I2C_M_DMA_SAFE 0x0200 /* the buffer of this message is DMA safe */
					/* makes only sense in kernelspace */
					/* userspace buffers are copied anyway */
#define I2C_M_RECV_LEN 0x0400 /* length will be first received byte */
#define I2C_M_NO_RD_ACK 0x0800 /* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_NOSTART 0x4000 /* if I2C_FUNC_NOSTART */
#define I2C_M_STOP 0x8000 /* if I2C_FUNC_PROTOCOL_MANGLING */
	__u16 len;		/* msg length */
	__u8 *buf;		/* pointer to msg data */
;

SPI

SPI(Serial Peripheral Interface),四根线:

  • SCLK:Serial Clock(output from master)
  • MOSI:Master Output,Slave Input(output from master)
  • MISO:Master Input,Slave Output
  • SS:Slave Select(active low,output from master)

SPI的速率一般只有几十M左右,而且发送数据一般没有ACK回应。


SPI是单主设备(single-master)通信协议,这意味着总线中的只有一支中心设备能够发起通信。当SPI主设备想读/写从设备时:

  • 拉低从设备对应的SS线(SS低电平有效)
  • 发送工作脉冲到时钟线上
  • 在相应脉冲时间上
    • 主设备把信号发到MOSI实现“写”
    • 对MISO采样而实现读

在SPI中要注意以下的配置,其中:

  • SPI_CPHA:采样的时机
    • 0表示每个时钟周期的第一个沿采样
    • 1表示每个时钟周期的第二个沿采样
  • SPI_CPOL:时钟开始的极性
    • 0表示低电平开始,
    • 1表示高电平开始

SPI_CPHA和SPI_CPOL有四种组合,对应SPI_MODE_0 ~ SPI_MODE_3

include/linux/spi/spi.h

#define SPI_CPHA 0x01 /* clock phase */
#define SPI_CPOL 0x02 /* clock polarity */
#define SPI_MODE_0 (0|0) /* (original MicroWire) */
#define SPI_MODE_1 (0|SPI_CPHA)
#define SPI_MODE_2 (SPI_CPOL|0)
#define SPI_MODE_3 (SPI_CPOL|SPI_CPHA)

Reference

关于I2C和SPI总线协议

以上是关于I2C和SPI协议的主要内容,如果未能解决你的问题,请参考以下文章

I2C(smbus pmbus)和SPI分析

spi和dmx区别

SPI通信协议

裸机上I2C的设计

[SPI&I2C]I2C和SPI协议介绍

SPI总线协议理解