0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

SPI协议详解(以ADS1118为例)

云深之无迹 来源:云深之无迹 2024-05-07 14:58 次阅读

最近要写一个协议,所以再复习一次SPI。(存草稿太久了,再不发就忘了)

一开始先分析了SPI的协议特点,使用ADS1118这个器件作为承载物进行分析,后面用逻辑分析仪从位到字节进行解码,最后使用TI给的demo移植到STM32平台。

SPI是一个环形总线结构,由ss(cs)、sck、sdisdo构成,其时序其实很简单,主要是在sck的控制下,两个双向移位寄存器进行数据交换。

上升沿发送、下降沿接收、高位先发送。

上升沿到来的时候,sdo上的电平将被发送到从设备的寄存器中。

下降沿到来的时候,sdi上的电平将被接收到主设备的寄存器中。 各家的名字可能不一样,反正你就看传输方向就行。

239e7bf4-0a00-11ef-a297-92fbcf53809c.png

这个是时序图,因为是双向的传输,在主机发给从机这段时间,从机也是发数据的,但是相当于乱发无意义的:

23af1554-0a00-11ef-a297-92fbcf53809c.png

另外:密封的菱形部分,注意要密封,表示数据有效,Valid Data这个词也显示了这点。

关于时间的标注,这也是个十分重要的信息,这些时间的标注表明了某些状态所要维持的最短或最长时间。

因为器件的工作速度也是有限的,一般都跟不上主控芯片的速度,所以它们直接之间要有时序配合。

外部12MHz晶振,指令周期就是一个时钟周期为(1/12MHz)us,所以至少确定了它执行一条指令的时间是us级别的。我们看到,以上给的时间参数全部是ns级别的,所以即便我们在程序里不加延时程序

23b39782-0a00-11ef-a297-92fbcf53809c.png

10的-3次方

23d25cc6-0a00-11ef-a297-92fbcf53809c.png

时序时间

专有的时钟引脚上面是有施密特输入的

23dcff1e-0a00-11ef-a297-92fbcf53809c.png

这个名字好,DIN,然后数据锁存在下降沿上:

23f5b018-0a00-11ef-a297-92fbcf53809c.png

GPIO开启了引脚的弱上拉电阻

24042080-0a00-11ef-a297-92fbcf53809c.png

上升沿移出,下降沿准备:

24085998-0a00-11ef-a297-92fbcf53809c.png

这个是输出的一个时钟周期

24138c1e-0a00-11ef-a297-92fbcf53809c.png

这个样子的意思是,数据有高有低,靠后的线是数据输出,前面是数据准备。或者是被锁定

24221d24-0a00-11ef-a297-92fbcf53809c.png

2428ccf0-0a00-11ef-a297-92fbcf53809c.png

不确定是不是所有的这样。和上面的分析差不多

2445cd1e-0a00-11ef-a297-92fbcf53809c.png

看一个连续输出

2452825c-0a00-11ef-a297-92fbcf53809c.png

在时序上面

MCU的数据中,一个大的时钟周期由32个小周期组成,两个字节来说明转换的结果,也就是本身的数据,MSB在前。后面两个是寄存器的回读,这里我理解是把输出的控制命令又回流一次。

2459cc42-0a00-11ef-a297-92fbcf53809c.png

2^16,两个16位

DIN是MCU给器件的信息,MSB+LSB发一次,剩下二分之一如果你不变化,就可以让这个DIN的引脚在后一个周期里面一直低或者高都可以。

246e86c8-0a00-11ef-a297-92fbcf53809c.png

你看嘛,就是这样

2472a6d6-0a00-11ef-a297-92fbcf53809c.png

还有16为输出模式,可以交替的拉低CS来输出

247a788e-0a00-11ef-a297-92fbcf53809c.png

这个是输出16位值的寄存器的样子,0~15,上面每一位都是一个0或者1,一次16位。

248f54de-0a00-11ef-a297-92fbcf53809c.png

这个是配置的寄存器,从0开始写,一直配好到15,组成一个16位的序列,发送。

数据手册里面的写法是倒着来,先15,说这个寄存器的位置在15,名字叫SS,可以读可以写,重启之后是0h,描述是断电的时候设置一次,在转换过程中换不了。

2493be66-0a00-11ef-a297-92fbcf53809c.png

这个是3位,8种情况,对应个个采集方式:

249771e6-0a00-11ef-a297-92fbcf53809c.png

如果对地的话,那就是差分

增益放大器

24a7d1bc-0a00-11ef-a297-92fbcf53809c.png

速率:

24abb58e-0a00-11ef-a297-92fbcf53809c.png

连续还是单发:

24c2c724-0a00-11ef-a297-92fbcf53809c.png

默认是单发

找了找就这个图出现的次数最多。

24ca9fbc-0a00-11ef-a297-92fbcf53809c.png

OK

扩展SPI还增加了SDR(Single Data Rate)和DDR(Double Data Rate)两种模式。在标准SPI 协议的SDR 模式下,只在SCK 的单边沿进行数据传输,即一个SCK 时钟只传输一位数据;而在DDR 模式下,会在SCK 的上升沿和下降沿都进行数据传输,即一个SCK 时钟能传输两位数据,传输速率提高一倍。

24e6a496-0a00-11ef-a297-92fbcf53809c.png

就是这样

24ebeb5e-0a00-11ef-a297-92fbcf53809c.png

没问题,可以看到时序图内在CLK的上下沿,数据线上的电平确实是稳定的,可以读取。

1. 2-bit Dual SPI模式

2-bit Dual SPI模式,也称为Dual SPI模式,是标准SPI的一个变体,它使用两条数据线(通常是MOSI和MISO)同时传输数据。在此模式下,数据在时钟信号的上升沿和下降沿同时被发送和接收,使得数据吞吐量相比单线SPI翻倍。

它只是针对SPI Flash而言,不是针对所有SPI外设。对于SPI Flash,全双工并不常用,因此扩展了mosi和miso的用法,让它们工作在半双工,用以加倍数据传输。也 就是对于Dual SPI Flash,可以发送一个命令字节进入dual mode,这样mosi变成SIO0(serial io 0),mosi变成SIO1(serial io 1),这样一个时钟周期内就能传输2个bit数据,加倍了数据传输。

数据线:使用MOSI和MISO同时传输数据。

数据速率:相比于标准SPI,数据传输速率翻倍,因为它同时使用两条线传输数据。

使用场景:适用于需要比标准SPI更高数据传输率但又不需要四线Quad SPI的场景。

2. DDR SPI模式

DDR SPI(双数据率SPI)模式在每个时钟周期的上升沿和下降沿都进行数据传输。这意味着在每个时钟脉冲上,都可以发送或接收数据,从而有效地加倍了数据传输速率。这种模式通常用于高速数据采集系统中。

数据线:通常使用一条或多条数据线,但每个时钟周期传输两次数据。

数据速率:数据速率是标准SPI的两倍,因为它在时钟的上升沿和下降沿都传输数据。

使用场景:适合高性能需求的应用,如高速数据采集或高分辨率视频传输。

区别 数据传输方式:Dual SPI利用两条数据线在时钟的每个边沿传输数据;而DDR SPI可能只使用一条数据线,但在每个时钟的上升沿和下降沿都传输数据。

复杂性:DDR SPI通常在实现上更复杂,因为它要求在时钟的每个边缘精确控制数据的采样和输出,这对时钟同步提出了更高的要求。

效率:尽管两者都提高了数据传输速率,但在具体实现和系统兼容性方面,它们各有优势和局限。

如果你的设计对时钟同步的要求极高,可能会更倾向于使用Dual SPI而不是DDR SPI,因为后者需要更精确的控制和可能导致的时钟偏差问题。

相反,如果需要极高的数据传输效率,DDR SPI可能是更好的选择。

24fbbd22-0a00-11ef-a297-92fbcf53809c.png

HI-Z是什么?

补充:

Hi-Z是数字电路常见术语,指的是电路的一种输出状态,既不是高电平也不是低电平,如果高阻态再输入下一级电路的话,对下级电路无任何影响,和没接一样,如果用万用表测的话有可能是高电平也有可能是低电平,随它后面接的东西定。高阻态: 高阻态的实质电路分析时高阻态可做开路理解。

模式1:

250d89f8-0a00-11ef-a297-92fbcf53809c.png

上升沿改变,下降沿读取。

手边还有一个ESP32-C3的单片机,这个是它的数据手册,有三个SPI,或者是一个SPI配六个CS线。

251327aa-0a00-11ef-a297-92fbcf53809c.png

外部焊盘,通过MUX,多路转换到接口上面,可以走DMA或者Cache到CPU,等等,之后再说。

251ebab6-0a00-11ef-a297-92fbcf53809c.png

25304b78-0a00-11ef-a297-92fbcf53809c.png

这个就更专业啦

SPI 主机驱动允许总线上连接多个设备(共享单个 ESP32-C3 SPI 外设)。每个设备仅由一个任务访问时,驱动程序线程安全。反之,若多个任务尝试访问同一 SPI 设备,则驱动程序非线程安全。

254efea6-0a00-11ef-a297-92fbcf53809c.png

所有的SPI协议都可以分成这样的步骤。

当传输事务数据等于或小于 32 位时,为数据分配一个缓冲区将是次优的选择。

SPI 主机逐字节地将数据读入和写入内存。默认情况下,数据优先以最高有效位 (MSB) 发送,极少数情况下会优先使用最低有效位 (LSB)。如果需要发送一个小于 8 位的值,这些位应以 MSB 优先的方式写入内存。

例如,如果需要发送 0b00010,则应将其写成 uint8_t 变量,读取长度设置为 5 位。此时,设备仍然会收到 8 位数据,并另有 3 个“随机”位,所以读取过程必须准确。

传输速度主要有以下三个限制因素:

传输事务间隔时间

SPI 时钟频率

缓存缺失的 SPI 函数,包括回调

影响大传输事务传输速度的主要参数是时钟频率。而多个小传输事务的传输速度主要由传输事务间隔时长决定。

256078c0-0a00-11ef-a297-92fbcf53809c.png

在捕捉的时候可以对 SPI 进行详细设置

2564ad64-0a00-11ef-a297-92fbcf53809c.png

三个解码层级的设置

256f7672-0a00-11ef-a297-92fbcf53809c.png

这里的解码有几个层级,首先是bit级别,就是0,1,接着是转换,就是0,1拼成别的进制数据。还有就是转换成数据。

25776fd0-0a00-11ef-a297-92fbcf53809c.png

全是0

257cf75c-0a00-11ef-a297-92fbcf53809c.png

16进制的我喜欢使用

25835a20-0a00-11ef-a297-92fbcf53809c.png

可以看到是一个不断分组,组装的过程

258c1b56-0a00-11ef-a297-92fbcf53809c.png

先看一个时钟的变化

259b3528-0a00-11ef-a297-92fbcf53809c.png

有八个上升沿,也就是8个0,也就是下面的00.是转换的层级,8个字节是一位-00.

下面就是两个字节变成了一word-16bit

25a7f858-0a00-11ef-a297-92fbcf53809c.png

25af52a6-0a00-11ef-a297-92fbcf53809c.png

第二个字节

25ba3d6a-0a00-11ef-a297-92fbcf53809c.png

大概就是这样的解码啦

25bec704-0a00-11ef-a297-92fbcf53809c.png

这就是解码出来的第一个数据

25c5ea7a-0a00-11ef-a297-92fbcf53809c.png

前面是bit位,下一个是字节位,下一个是word位

25cbba5e-0a00-11ef-a297-92fbcf53809c.png

按照16字节来解码

25dc87f8-0a00-11ef-a297-92fbcf53809c.png

因为可以自由的传输任意的字节数据,也可以在这里自己定义这个事情

这里就开始移植,看这个TI的意思是随便整,推荐自己实现SPI的接口:

25f00be8-0a00-11ef-a297-92fbcf53809c.png

下载最后一个

2642dc92-0a00-11ef-a297-92fbcf53809c.png

这里先说一下头文件如何加

我们的工作是要在代码里面实现STM32的SPI接口移植,然后在线测量所有的参数来更加详细的学习SPI。

先看懂给的代码,明白要干啥:

2646f71e-0a00-11ef-a297-92fbcf53809c.png

这些是TI的库

NSS管脚及我们熟知的片选信号,作为主设备NSS管脚为高电平,从设备NSS管脚为低电平。

当NSS管脚为低电平时,该spi设备被选中,可以和主设备进行通信。在stm32中,每个spi控制器的NSS信号引脚都具有两种功能,即输入和输出。所谓的输入就是NSS管脚的信号给自己。所谓的输出就是将NSS的信号送出去,给从机。

对于NSS的输入,又分为软件输入和硬件输入。

软件输入: NSS分为内部管脚和外部管脚,通过设置spi_cr1寄存器的ssm位和ssi位都为1可以设置NSS管脚为软件输入模式且内部管脚提供的电平为高电平,其中SSM位为使能软件输入位。SSI位为设置内部管脚电平位。同理通过设置SSM和SSI位1和0则此时的NSS管脚为软件输入模式但内部管脚提供的电平为0。若从设备是一个其他的带有spi接口的芯片,并不能选择NSS管脚的方式,则可以有两种办法,一种是将NSS管脚直接接低电平。另一种就是通过主设备的任何一个gpio口去输出低电平选中从设备。

硬件输入: 主机接高电平,从机接低电平。

265e61a6-0a00-11ef-a297-92fbcf53809c.png

2662917c-0a00-11ef-a297-92fbcf53809c.png

这样

26669d6c-0a00-11ef-a297-92fbcf53809c.png

cs 自己换普通gpio,好像是自动的引脚有些问题

267774de-0a00-11ef-a297-92fbcf53809c.png

外部晶振为8MHz

1选择外部时钟HSE 8MHz

2PLL锁相环倍频9倍

3系统时钟来源选择为PLL

4设置APB1分频器为 /2

5使能CSS监视时钟

2688506a-0a00-11ef-a297-92fbcf53809c.png

后来我找到了中文的数据手册

269cb352-0a00-11ef-a297-92fbcf53809c.png

这个地方 4 种模式选择

26e186b2-0a00-11ef-a297-92fbcf53809c.png

打开窗口

26e5db18-0a00-11ef-a297-92fbcf53809c.png

打开中断

26f07000-0a00-11ef-a297-92fbcf53809c.png

编译 Ok

26f50ef8-0a00-11ef-a297-92fbcf53809c.png

这个是TI硬件层的所有东西,一会儿就重写

27053e0e-0a00-11ef-a297-92fbcf53809c.png

ti 的板子我用的少

272a75c0-0a00-11ef-a297-92fbcf53809c.png

中断状态

27465c40-0a00-11ef-a297-92fbcf53809c.png

开启中断

275e6b14-0a00-11ef-a297-92fbcf53809c.png

开启中断引脚

276272b8-0a00-11ef-a297-92fbcf53809c.png

下降边沿触发中断

27735182-0a00-11ef-a297-92fbcf53809c.png

这个有用

因为STM32的SPI中断和TI的中断对不上,下面就看HAL的API:

2787d864-0a00-11ef-a297-92fbcf53809c.png

SPI的中断有这些

27a5461a-0a00-11ef-a297-92fbcf53809c.png

所有的函数

27b1c200-0a00-11ef-a297-92fbcf53809c.png

中断

27be89c2-0a00-11ef-a297-92fbcf53809c.png

在main里面的文件

27d29106-0a00-11ef-a297-92fbcf53809c.png

我要做的工作是在HAL文件里面构建STM32 SPI的硬件重构

27e25b0e-0a00-11ef-a297-92fbcf53809c.png

需要实现的是ms和us的延时,CS的控制和收发功能

27ee1cb4-0a00-11ef-a297-92fbcf53809c.png

SPI函数

280c9126-0a00-11ef-a297-92fbcf53809c.png

这里是延时和CS的实现

ADS1118的内部就可以不用管了。别看写的简单,debug也很耗时。

28289e2a-0a00-11ef-a297-92fbcf53809c.png

编译无错误,移植完成

283f5322-0a00-11ef-a297-92fbcf53809c.png

可以看看ADS1118的定位

https://www.stmcu.com.cn/Designresource/detail/software/711298

术语表:

Standard SPI: CLK, /CS, DI, DO, /WP, /Hold Dual SPI: CLK, /CS, IO0, IO1, /WP, /Hold Quad SPI: CLK, /CS, IO0, IO1, IO2, IO3 SIO0(serial io 0)

接口说明

CLK(Serial Clock):时钟线

/CS(Chip Select):片选接口

DI(Serial Data Input):数据输入端口

DO(Serial Data Output):输出输出端口

2919473a-0a00-11ef-a297-92fbcf53809c.png

2930b12c-0a00-11ef-a297-92fbcf53809c.png



审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 上拉电阻
    +关注

    关注

    5

    文章

    359

    浏览量

    30606
  • 寄存器
    +关注

    关注

    31

    文章

    5336

    浏览量

    120224
  • STM32
    +关注

    关注

    2270

    文章

    10895

    浏览量

    355715
  • 增益放大器
    +关注

    关注

    2

    文章

    100

    浏览量

    29045
  • SPI协议
    +关注

    关注

    0

    文章

    18

    浏览量

    8361

原文标题:SPI协议详解以ADS1118为例

文章出处:【微信号:TT1827652464,微信公众号:云深之无迹】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    请问ADS1120在热电偶测温度能否完全代替ADS1118

    目前想测一种K型热电偶,测温范围约为1000度,看中了ADS1118这款芯片。然后偶然间发现了ADS1120这款芯片,简单对比了一下性能指标,ADS1120的采样率和可调增益范围要优于
    发表于 08-27 07:13

    ADS1118默认上电状态,是低功耗模式,怎么启动转换呢?

    ADS1118是上电之后,先选中芯片,将CS拉低,直接送配置字,然后拉高CS。再就是直接读数据? SPI_CS_Low(); //拉低CS SPI_Write_byte(0x85
    发表于 12-13 16:33

    STC12C5A60S2与ADS1118通过SPI通讯的问题

    问题:STC的SPI是8位的,ADS1118的命令和数据都是16位的,都有SPI功能,两者通过SPI协议通讯,是否可以使用STC的
    发表于 11-07 17:18

    STC12C5A60S2与ADS1118通过SPI通讯的问题

    问题:STC的SPI是8位的,ADS1118的命令和数据都是16位的,都有SPI功能,两者通过SPI协议通讯,是否可以使用STC的
    发表于 11-08 08:32

    ADS1118测试

    求助一下各位大神:我用的是51开发板调试ADS1118的,并且用的是串口调试,但为什么一直输出同样的值:如图所示:模拟输入量我给的是一个直流量,而且可以通过一个电位器改变电压值,做了几天了一直没效果。马上就要交工了,希望各位大神帮帮我
    发表于 07-05 19:01

    ADS1118

    哪位用过ADS1118 ,请教个问题:关于多通道采集的问题,如何控制选择指定的通道采集?
    发表于 04-20 17:13

    ADS1118产品选型及参考设计指南

    ADS1118程序关于51单片机调试ADS1118芯片ADS1118请教 关于ADS1118的程序问题 :返回的数据不对 抱歉我只有35分STC12C5A60S2与
    发表于 08-29 19:25

    请问如何才从ADS1118中读回命令寄存器中的值

    参照ADS1118的说明书,我使用CC2530的串口1的SPI方式向ADS1118连接写入4个字节的命令,我想问一下我如何才从ADS1118中读回命令寄存器中的值呢。意思就是在我写入命
    发表于 05-27 07:37

    请问怎么在ADS1118中读取第二通道的值?

    再次求助,ads1118要读取第二通道,按如下设置,读到的都是第一通道的值,无法读取第二通道的值,请高人再次指点。感谢!!#include "msp430x54xA.h"void
    发表于 06-06 11:23

    关于ADS1118的调试笔记(基于STM32)精选资料分享

    最近调试了ADS1118芯片,单片机用的是STM32ZET6,用IO口模拟SPI通信,连接两片1118AD采集芯片,讲采集到的八通道数据在串口显示界面打印出来。下面是.c代码#include
    发表于 08-17 08:23

    ADS1118转换寄存器

    0x01:寄存器ADS1118有两个寄存器可以通过SPI接口访问。转换寄存器包含最后一次转换的结果。配置寄存器允许用户改变ADS1118的工作模式。并查询设备的状态。1、转换寄存器[reset
    发表于 08-23 07:31

    ADS1118寄存器的基本功能有哪些呢

    传感器。ADS1118寄存器ADS1118的寄存器非常简单,只有2个16bit的寄存器。其中一个位只读寄存器,保存ADC转换后的值;另一个配置寄存器,配置采集通道、正负量程、采集模式、采集速率、采集...
    发表于 12-10 07:32

    ADS1115和ADS1118的主要区别是什么?

    ADS1115和ADS1118的主要区别是什么
    发表于 10-09 06:39

    ads1118

    ADS1118 Introduction ASD1118的基本介绍。
    发表于 05-04 11:09 31次下载

    ads1118中文手册

    ADS1118的中文手册,希望能够帮助到别人。
    发表于 05-09 14:36 189次下载