I2C和SPI总线以及通信

通讯属性 概括

  • Serial/parallel 串行/并行
  • Synchronous/asynchronous 同步/异步
  • Point-to-point / bus 点对点 总线
  • Half-duplex/full-duplex 半双工/全双工
  • Master-slave/ equal partners 主从/对等
  • single-ending / differential 单端/差分

点对点和总线

  • 点对点通讯
    只有两个通讯点 only two comunication partners
    没有地址请求 no addressing required
  • 总线通讯
    若干个通信点 several communication partners
    地址请求 addressing required

同步(Synchronous)和异步(Asynchronous)

  • 同步
    时钟接收者和时钟发送者共享一个时钟。 Clock of receiver is linker to clock of sender
    快速通信。Fast communication
  • 异步
    约定好通信速率 进行通讯。independent clocks for sender and receiver
    Receiver knows the transmission speed in advance
    Requires packet frame with start/stop bit
    Normally an over-samping scheme is required
    Communication is slower

Half duplex 半双工和Full duplex 全双工

  • 半双工
    只有一个通信通道。需要进行发送和接收的时候占用通道。不用的时候,应当释放信道。你发我听, 我发你听。
  • 全双工
    双方都可以通信。

对等(Equal partners)和 主从(Master-slave)方式

  • 对等
    any node may transmit if medium(媒介) is free。
    Arbitration(仲裁) is required 需要仲裁
  • 主从
    主从设备之间没有对等的权利
    只有主设备可以开始通信。Only master can start a communication.
    Slave get permission to communicate form master.
    e.g. USB鼠标和PC的主从通信。PC作为通信的host,USB作为通信的device。鼠标和PC的通讯时,PC按照一定的频率去读取鼠标的中断方式的通讯信息。

通信信号区分

  • Single-ended 单端信号
    以单线的电平高低判断信号
  • differential 差分信号
    用两根双绞线传递这两个差模(差分)的信号。承载差模信号的数字信号0或者1的判断,是以两根线的信号的差值来判断。

iic简介

IIC(Inter-Integrated Circuit)总线是两线式串行总线,用于连接MCU和外设。由数据线SDA和时钟线SCL构成串行总线,可发送和接受数据。高速IIC总线速率可达400Kbps以上。
I2C是半双工、支持多从机(即I2C控制器下可以挂多个I2C从设备)。不同的从机有不同的器件地址,I2C主机可以通过I2C设备的器件地址访问指定I2C设备。
多设备连接图
在这里插入图片描述如上图,SDA和SCL信号线都有一个4.7K上拉电阻,空闲时都为高。

I2C总线在传送数据过程中分四种类型信号

信号SCLSDA
开始信号由高变低开始传送数据
结束信号由低变高结束传送数据,可不要
数据传输数据稳定不变SDA的数据变化只能在SCL为低电平期间
应答信号接收ic(I2C从机)向发送ic(I2C主机)的SDA发出特定的低电平,表示己收到数据

下图为数据传输中数据读写和数据变化的时序图在这里插入图片描述

IIC总线时序图
IIC总线时序图

I2C写时序

I2C主从机之间相同通讯不外乎读写两个操作。

I2C单字节写时序

在这里插入图片描述如上图写时序,按照序号可以反馈写时序的具体步骤:

  1. 开始信号
  2. 从机设备地址。每个I2C设备有一个设备地址,通过发送I2C设备地址(从机设备地址)来决定访问哪个I2C器件。8位数据,前7位代表设备地址,Most Significant Bit最高有限位。
  3. 8位数据最后一位代表读写地址,用R/~w表示,1位读操作,0位写操作
  4. 从机发送的ACK应答信号。
  5. 重新发送开始信号。
  6. 发送要写的写入数据的从机寄存器地址。
  7. 从机发送的ACK应答信号。
  8. 发送从机要写入寄存器的数据(值)。
  9. 从机发送的ACK应答信号。
    10.停止信号。

I2C读时序

I2C单字节读时序

在这里插入图片描述如上图读时序,可分为4大步骤,1 发送设备地址 ,2 发送要读取的寄存器地址, 3. 重新发送设备地址,4 I2C从期间输出要读取的寄存器只。按照序号可以反馈读时序的具体步骤:

  1. 主机发送起始信号。
  2. 主机发送要读取的从机设备地址。
  3. 读写控制位,由于要向I2C从设备发送 要读取的寄存器数据,因此是写信号
  4. 从机发送的ACK应答信号。
  5. 重新发送START信号。
  6. 主机发送要读取的寄存器地址。
  7. 从机发送的ACK应答信号。
  8. 重新发送START信号。
  9. 重新发送要读取的I2C从设备地址。
  10. 读写控制位,读信号,因为要从I2C从设备读取寄存器的值。
  11. 从机发送的ACK应答信号。
  12. 从I2C器件里面读取的数据。
  13. 主机发送NO ACK信号信号,表示读取完成,不需要从机发送ACK信号。
  14. 主机发送STOP信号,停止I2C通信。

实操

代码

TI-TDA4VL的MCU1_0操作MCU_I2C0 代码如下。
目的:MCU1_0 在MCU_I2C0总线上,在地址0x12的PMIC芯片上读取0x01寄存器的值。

    #define SENSOR_I2C_TIMEOUT    (5000U)
    I2C_Handle      handle;
    I2C_Params      i2cParams;
    I2C_HwAttrs const  *hwAttrs = NULL;
    uint8_t status = 0;

    I2C_Params_init(&i2cParams);
    i2cParams.bitRate = I2C_400kHz;

    send_iic_message i2c_pmic;
    i2c_pmic.bus = 0;   //  MCU_I2C0's memory map is 40B0 0000h
    i2c_pmic.i2cAddr = 0x12;
    i2c_pmic.addr = 0x1;    //register address 
    i2c_pmic.read_write_flag = 0;  
    handle = I2C_open(i2c_pmic.bus, &i2cParams);
    if (handle == NULL)appLogPrintf("I2C_open err!!!\n");
	status = Board_i2c8BitRegRd(handle, i2c_pmic.i2cAddr, i2c_pmic.addr, &i2c_pmic.value, 1U,SENSOR_I2C_TIMEOUT);
    if (0 == status)
    {
        appLogPrintf("addr 0x%x read 0x%x :0x%x\n",i2c_pmic.i2cAddr,i2c_pmic.addr,i2c_pmic.value);
	}

调试打印如下
[MCU1_0] 625.891937 s: addr 0x12 read 0x1 :0x0

测试IIC信号波形

写设备地址波形
在这里插入图片描述写寄存器地址时序波形
在这里插入图片描述
读取寄存器值的时序波形
在这里插入图片描述

I2C寄存器多字节读写时序

有时候我们需要读写多个字节,多字节读写时序和单字节的基本一致,只是在读写数据的时候可以连续发送多个自己的数据,其他的控制时序都是和单字节一样的。

实操

寄存器多字节读代码
#define SENSOR_I2C_TIMEOUT    (5000U)
    I2C_Handle      handle;
    I2C_Params      i2cParams;
    uint8_t     status=0;
    I2C_HwAttrs const  *hwAttrs = NULL;

    send_iic_message i2c_pmic = {
        .bus = 0,
        .i2cAddr = 0x12,
        .addr = 0x409,
    };
    I2C_Params_init(&i2cParams);
    i2cParams.bitRate = I2C_400kHz;
    
    handle = I2C_open(i2c_pmic.bus, &i2cParams);
    while(1)
    {
        Osal_delay(1000); //appLogWaitMsecs(100u)
        status = Board_i2c16BitRegRd(handle, i2c_pmic.i2cAddr, i2c_pmic.addr, &i2c_pmic.value, 1U,BOARD_I2C_REG_ADDR_MSB_FIRST, SENSOR_I2C_TIMEOUT);
        if (0 == status)
        {
            appLogPrintf("addr 0x%x read 0x%x :0x%x\n",i2c_pmic.i2cAddr,i2c_pmic.addr,i2c_pmic.value);
        }
	}

[MCU1_0] 2464.065029 s: addr 0x12 read 0x409 :0x9

寄存器多字节读时序波形

第一部分开始写设备地址
在这里插入图片描述第二部分:16位寄存器分两次写8位寄存器地址
如下图写16位寄存器0x409。
在这里插入图片描述
第三部分:返回寄存器的值
在这里插入图片描述

spi简介

SPI(Seial Peripheral interface)串行外围设备接口。SPI(Serial Peripheral Interface) 同步串行通讯方式,适用于短距离通讯。SPI是一种高速的,全双工、同步的通信总线。
spi是4线同步串行通讯接口。

SPI的特点

  • 串行接口 Serial Interface
  • 同步 Synchronous
  • 主从配置 Master-slave configuration
  • 数据交换-DMA/PIO Date Exchange
  • 全双工 Full duplex operation
  • 灵活的时钟极性/相位格式 Flexible clock polarity/phase format
  • 4到16位的可变字节帧
  • 总线竞争保护

spi内部简明图

在这里插入图片描述
从上图看,SPI有4个线通信

引脚描述
MOSI(Master Out Slave In)主出从入,主设备发送到从设备的信号
MISO(Master IN slave OUT)主入从出。从设备发送到主设备的信号
SCKserial clock,主设备产生的时钟信号,每个SCK周期完成一个bit的传输。
SS/CSSlave/Chip Select,从设备选择端,当从设备收到该段为低电平时,设备有效;对于主设备,该端平时为高电平,可以用于在有效传输周期内给出低电平选通。

spi工作方式

spi模块要与外设进行数据交互,需要配置串行同步时钟极性CPOL(同步作用)和时钟相位CPHA(采样作用)在相同的工作模式。在SPI通信中,时钟极性决定了时钟信号在空闲状态时的电平,而数据采样相位则决定了数据采样的时机。

CPOL时钟极性 Clock Polarity

CPOL描述
0串行同步时钟的空闲状态为低电平
1串行同步时钟的空闲状态为高电平

CPHA时钟相位

可选择2种采样方式 Data Sampling Phase

CPHA描述
0在串行同步时钟的第一个跳变沿(上升或下降)数据被采样
1在串行同步时钟的第二个跳变沿(上升或下降)数据被采样

工作流程

SS片选信号拉低(或拉高)–> 主从机双方准备传递信息,MISO MOSI引脚开始把数据准备好 --> 当时钟的第一个边沿出现时(上升沿或下降沿),开始观察各自的输入引脚进行bit采样 --> 当时钟出现第二边沿时,主从机驱动自己的输出引脚准备发送第二个bit。

传输时序

在这里插入图片描述

主模式

  • 控制整个传输过程
    • 通过SS信号选择对应的通信从节点
    • 决定SCK波特率,相位,极性
    • 产生SCK时钟信号
    • 驱动MOSI信号
    • 采用MISO信号
  • CPU通过向SPIx_D写入数据来启动一次传输过程

从模式 Slave mode

  • 响应主节点的信号
    • 当SS信号被选通时才激活
    • 根据预先约定的相位/极性来检测SCK
    • 按照主机的通信速度驱动MISO信号
    • 采样MOSI信号

注意点

  • 通常,SPI是点对点结构的
  • 必须预先约定SCK时钟的相位/极性和数据帧位数
  • 从节点的CPU需要在数据帧开始前 将待发数据准备好并写入SPIx_D
  • SCK信号必须干净不能有毛刺 SCK保证主从机都能接收的范围

实例

例子以spi 模式为Polarity 0 Phase 1,极性为0,采样相位为1,即时钟信号在空闲状态时的电平为低,数据采样的时机为第二个跳变沿。
发送数据16个bit为0x8108。

结合下图TLE9255W收发器的SPI命令格式,即主机在地址0x01上写0x08的数据。
在这里插入图片描述Master 时钟和片选信号
在这里插入图片描述
Master时钟和MOSI
在这里插入图片描述

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值