STM32 SPI通信

SPI通信:

  1. SPI(Serial Peripheral Interface 串行外设接口 是由Motorola公司开发的一种通用数据总线
  2. 四根通信线:

SCK(Serial Clock)串行时钟线

MOSI(Master Output Slave Input)主机输出从机输入

MISO(Master Input Slave Output)主机输入从机输出

当是缩写DO和DI时,应该先分辨主机从机,然后DI和DO就好分别谁是MISO和MOSI了

SS、CS(Slave Select、Chip Select)从机选择、片选(即指定哪个从机进行通信)

  1. 同步,全双工(数据发送和数据接收单独占据一根线)
  2. SPI没有应答机制的设计,且高位先行
  3. 支持总线挂载多设备(一主多从)

SPI的特点:SPI传输快,设计比较简单,硬件开销比较大,通信线比较多并且在通信中通常会出现浪费的现象。

SPI的硬件电路:

  1. 所有SPI设备的SCK、MOSI、MISO分别连在一起
  2. 主机另外引出多条SS控制线,分别接到各从机的SS引脚
  3. 输出引脚配置为推挽输出,输入引脚配置为浮空或上拉输入
  4. 在下图输出引脚和输入引脚都用箭头标识了
  5. 在从机未被选中时,从机输出端要置高阻态

SPI的移位示意图:

SPI是高位先行

模拟数据移位过程:

假设有组数据要从主机发送至从机, 从机也要发送一组数据到主机,那么在SCK高电平期间,主机从机都将数据左移1位放进输出数据寄存器中;在SCK低电平期间,主机和从机都会进行数据采样输入,将两机的最高位采样到各自的最低位,形成一个圈,循环八次,就可以完成主机从机的一个数据的数据交换。

最后上图就会变成这样:

如果只想发送或接收时,也是用这个交换字节的时序,接收一个字节的同时,随便发送出去一个数据(0x00/0xff),只读取接收的字节,不管发送的字节,这样就是只接收了;只发送同理。

SPI的时序:

  1. 起始条件:SS从高电平切换到低电平(选中某从机)
  2. 终止条件:SS从低电平切换到高电平(结束从机选中状态)

SPI基本时序单元:

CPOL(Clock Polarity)时钟极性

CPHA(Clock Phase) 时钟相位

*在从机未被选中时,从机输出端要置高阻态

  1. 重点】交换一个字节(模式0)
  2. CPOL=0:空闲状态时,SCK为低电平
  3. CPHA=0:SCK第一个边沿移入数据,第二个边沿移出数据

提前将数据移出,在SS为下降沿时MOSI和MISO就开始移出数据,然后到了SCK上升沿移入数据,然后在下降沿移出下一个数据,以此往复。

  1. 交换一个字节(模式1)
  2. CPOL=0:空闲状态时,SCK为低电平
  3. CPHA=1:SCK第一个边沿移出数据,第二个边沿移入数据

  1. 交换一个字节(模式2)
  2. CPOL=1:空闲状态时,SCK为高电平
  3. CPHA=0:SCK第一个边沿移入数据,第二个边沿移出数据

  1. 交换一个字节(模式3)
  2. CPOL=1:空闲状态时,SCK为高电平
  3. CPHA=1:SCK第一个边沿移出数据,第二个边沿移入数据

SPI的几个时序:

I2C和SPI数据流的区别:

I2C的数据流:

有效数据流第一个字节是寄存器的地址,之后依次是读写的数据,使用的是读写寄存器的模型。

SPI的数据流:

通常采用指令码加读写数据的模型

这个过程是:SPI起始后,第一个交换发送给从机的数据一般叫做指令码。在从机中,对应的会定义一个指令集,当我们需要发送什么指令时,就可以在起始后第一个字节发送指令集里的数据这样就可以指定从机完成指定的功能了

不同的指令,可以有不同的数据个数,有的指令,只需要一个字节的指令码就可以完成,比如:W25Q64的写使能/失能等,而有的指令,后面就需要根要读写的数据,例如:W25Q64的写数据读数据等等。

以下是及各位SPI的指令波形:

发送指令:

  • 主机向SS指定的设备,发送指令(0x06)

采用的模式0()

CPOL=0:空闲状态时,SCK为低电平

CPHA=0:SCK第一个边沿移入数据,第二个边沿移出数据

提前将数据移出,在SS为下降沿时MOSI和MISO就开始移出数据,然后到了SCK上升沿移入数据,然后在下降沿移出下一个数据,以此往复。

指定地址写:

  • 向SS指定的设备,发送写指令(0x02),

随后在指定地址(Address[23:0])下,写入指定数据(Data)

规定指令之后的字节定义是地址的高八位(23~16位)

SPI和I2C一样有地址指针,每读写一个字节,地址指针自动加1,如果发送一个字节之后不终止,继续发送的字节就会依次写入到后续的存储空间里。这样既可以实现从指定地址开始写入多个字节了。

指定地址读:

向SS指定的设备,发送读指令(0x03),

随后在指定地址(Address[23:0])下,读取从机数据(Data)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值