百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

SPI总线协议工作原理(spi总线协议 中文版)

bigegpt 2024-08-02 11:00 18 浏览

一、概述

SPI,串行外围设备接口,是Motorola公司推出的一种同步串行接口技术.SPI总线在物理上是通过接在外围设备微控制器(PICmicro)上面的微处理控制单元(MCU)上叫作同步串行端口(SynchronousSerialPort)的模块(Module)来实现的,它允许MCU以全双工的同步串行方式,与各种外围设备进行高速数据通信。

SPI主要应用在EEPROM,Flash,实时时钟(RTC),数模转换器(ADC),数字信号处理器(DSP)以及数字信号解码器之间。它在芯片中只占用四根管脚(Pin)用来控制以及数据传输,节约了芯片的pin数目,同时为PCB在布局上节省了空间.正是出于这种简单易用的特性,现在越来越多的芯片上都集成了SPI技术。

二、特点

1、采用主-从模式(Master-Slave)的控制方式

SPI规定了两个SPI设备之间通信必须由主设备(Master)来控制次设备(Slave).一个Master设备可以通过提供Clock以及对Slave设备进行片选(SlaveSelect)来控制多个Slave设备,SPI协议还规定Slave设备的Clock由Master设备通过SCK管脚提供给Slave设备,Slave设备本身不能产生或控制Clock,没有Clock则Slave设备不能正常工作。

2、采用同步方式(Synchronous)传输数据

Master设备会根据将要交换的数据来产生相应的时钟脉冲(ClockPulse),时钟脉冲组成了时钟信号(ClockSignal),时钟信号通过时钟极性(CPOL)和时钟相位(CPHA)控制着两个SPI设备间何时数据交换以及何时对接收到的数据进行采样,来保证数据在两个设备之间是同步传输的。

3、数据交换(DataExchanges)

SPI设备间的数据传输之所以又被称为数据交换,是因为SPI协议规定一个SPI设备不能在数据通信过程中仅仅只充当一个"发送者(Transmitter)"或者"接收者(Receiver)"。在每个Clock周期内,SPI设备都会发送并接收一个bit大小的数据,相当于该设备有一个bit大小的数据被交换了。

一个Slave设备要想能够接收到Master发过来的控制信号,必须在此之前能够被Master设备进行访问(Access)。所以,Master设备必须首先通过SS/CSpin对Slave设备进行片选,把想要访问的Slave设备选上。

在数据传输的过程中,每次接收到的数据必须在下一次数据传输之前被采样.如果之前接收到的数据没有被读取,那么这些已经接收完成的数据将有可能会被丢弃,导致SPI物理模块最终失效。因此,在程序中一般都会在SPI传输完数据后,去读取SPI设备里的数据,即使这些数据(DummyData)在我们的程序里是无用的。

三、工作机制

1、概述

上图只是对SPI设备间通信的一个简单的描述,下面就来解释一下图中所示的几个组件(Module):

SSPBUF,SynchronousSerialPortBuffer,泛指SPI设备里面的内部缓冲区,一般在物理上是以FIFO的形式,保存传输过程中的临时数据;

SSPSR,SynchronousSerialPortRegister,泛指SPI设备里面的移位寄存器(ShiftRegitser),它的作用是根据设置好的数据位宽(bit-width)把数据移入或者移出SSPBUF;

Controller,泛指SPI设备里面的控制寄存器,可以通过配置它们来设置SPI总线的传输模式。

通常情况下,我们只需要对上图所描述的四个管脚(pin)进行编程即可控制整个SPI设备之间的数据通信:

SCK,SerialClock,主要的作用是Master设备往Slave设备传输时钟信号,控制数据交换的时机以及速率;

SS/CS,SlaveSelect/ChipSelect,用于Master设备片选Slave设备,使被选中的Slave设备能够被Master设备所访问;

SDO/MOSI,SerialDataOutput/MasterOutSlaveIn,在Master上面也被称为Tx-Channel,作为数据的出口,主要用于SPI设备发送数据;

SDI/MISO,SerialDataInput/MasterInSlaveOut,在Master上面也被称为Rx-Channel,作为数据的入口,主要用于SPI设备接收数据;

SPI设备在进行通信的过程中,Master设备和Slave设备之间会产生一个数据链路回环(DataLoop),就像上图所画的那样,通过SDO和SDI管脚,SSPSR控制数据移入移出SSPBUF,Controller确定SPI总线的通信模式,SCK传输时钟信号.

2、Timing.

上图通过Master设备与Slave设备之间交换1Byte数据来说明SPI协议的工作机制。

首先,在这里解释一下两个概念:

CPOL:时钟极性,表示SPI在空闲时,时钟信号是高电平还是低电平。若CPOL被设为1,那么该设备在空闲时SCK管脚下的时钟信号为高电平。当CPOL被设为0时则正好相反。

CPHA:时钟相位,表示SPI设备是在SCK管脚上的时钟信号变为上升沿时触发数据采样,还是在时钟信号变为下降沿时触发数据采样。若CPHA被设置为1,则SPI设备在时钟信号变为下降沿时触发数据采样,在上升沿时发送数据。当CPHA被设为0时也正好相反。

上图里的"Mode1,1"说明了本例所使用的SPI数据传输模式被设置成CPOL=1,CPHA=1.这样,在一个Clock周期内,每个单独的SPI设备都能以全双工(Full-Duplex)的方式,同时发送和接收1bit数据,即相当于交换了1bit大小的数据.如果SPI总线的Channel-Width被设置成Byte,表示SPI总线上每次数据传输的最小单位为Byte,那么挂载在该SPI总线的设备每次数据传输的过程至少需要8个Clock周期(忽略设备的物理延迟).因此,SPI总线的频率越快,Clock周期越短,则SPI设备间数据交换的速率就越快。

3、SSPSR.

SSPSR是SPI设备内部的移位寄存器(ShiftRegister)。它的主要作用是根据SPI时钟信号状态,往SSPBUF里移入或者移出数据,每次移动的数据大小由Bus-Width以及Channel-Width所决定。

Bus-Width的作用是指定地址总线到Master设备之间数据传输的单位。

例如,我们想要往Master设备里面的SSPBUF写入16Byte大小的数据:首先,给Master设备的配置寄存器设置Bus-Width为Byte;然后往Master设备的Tx-Data移位寄存器在地址总线的入口写入数据,每次写入1Byte大小的数据(使用writeb函数);写完1Byte数据之后,Master设备里面的Tx-Data移位寄存器会自动把从地址总线传来的1Byte数据移入SSPBUF里;上述动作一共需要重复执行16次。

Channel-Width的作用是指定Master设备与Slave设备之间数据传输的单位.与Bus-Width相似,Master设备内部的移位寄存器会依据Channel-Width自动地把数据从Master-SSPBUF里通过Master-SDO管脚搬运到Slave设备里的Slave-SDI引脚,Slave-SSPSR再把每次接收的数据移入Slave-SSPBUF里。

通常情况下,Bus-Width总是会大于或等于Channel-Width,这样能保证不会出现因Master与Slave之间数据交换的频率比地址总线与Master之间的数据交换频率要快,导致SSPBUF里面存放的数据为无效数据这样的情况。

4、SSPBUF.

我们知道,在每个时钟周期内,Master与Slave之间交换的数据其实都是SPI

内部移位寄存器从SSPBUF里面拷贝的。我们可以通过往SSPBUF对应的寄存器(Tx-Data/Rx-Dataregister)里读写数据,间接地操控SPI设备内部的SSPBUF。

例如,在发送数据之前,我们应该先往Master的Tx-Data寄存器写入将要发

送出去的数据,这些数据会被Master-SSPSR移位寄存器根据Bus-Width自动移入Master-SSPBUF里,然后这些数据又会被Master-SSPSR根据Channel-Width从Master-SSPBUF中移出,通过Master-SDO管脚传给Slave-SDI管脚,Slave-SSPSR则把从Slave-SDI接收到的数据移入Slave-SSPBUF里.与此同时,Slave-SSPBUF里面的数据根据每次接收数据的大小(Channel-Width),通过Slave-SDO发往Master-SDI,Master-SSPSR再把从Master-SDI接收的数据移入Master-SSPBUF。在单次数据传输完成之后,用户程序可以通过从Master设备的Rx-Data寄存器读取Master设备数据交换得到的数据。

5、Controller.

Master设备里面的Controller主要通过时钟信号(ClockSignal)以及片选信号(SlaveSelectSignal)来控制Slave设备。Slave设备会一直等待,直到接收到Master设备发过来的片选信号,然后根据时钟信号来工作。

Master设备的片选操作必须由程序所实现。例如:由程序把SS/CS管脚的时钟信号拉低电平,完成SPI设备数据通信的前期工作;当程序想让SPI设备结束数据通信时,再把SS/CS管脚上的时钟信号拉高电平。

相关推荐

Go语言泛型-泛型约束与实践(go1.7泛型)

来源:械说在Go语言中,Go泛型-泛型约束与实践部分主要探讨如何定义和使用泛型约束(Constraints),以及如何在实际开发中利用泛型进行更灵活的编程。以下是详细内容:一、什么是泛型约束?**泛型...

golang总结(golang实战教程)

基础部分Go语言有哪些优势?1简单易学:语法简洁,减少了代码的冗余。高效并发:内置强大的goroutine和channel,使并发编程更加高效且易于管理。内存管理:拥有自动垃圾回收机制,减少内...

Go 官宣:新版 Protobuf API(go pro版本)

原文作者:JoeTsai,DamienNeil和HerbieOng原文链接:https://blog.golang.org/a-new-go-api-for-protocol-buffer...

Golang开发的一些注意事项(一)(golang入门项目)

1.channel关闭后读的问题当channel关闭之后再去读取它,虽然不会引发panic,但会直接得到零值,而且ok的值为false。packagemainimport"...

golang 托盘菜单应用及打开系统默认浏览器

之前看到一个应用,用go语言编写,说是某某程序的windows图形化客户端,体验一下发现只是一个托盘,然后托盘菜单的控制面板功能直接打开本地浏览器访问程序启动的webserver网页完成gui相关功...

golang标准库每日一库之 io/ioutil

一、核心函数概览函数作用描述替代方案(Go1.16+)ioutil.ReadFile(filename)一次性读取整个文件内容(返回[]byte)os.ReadFileioutil.WriteFi...

文件类型更改器——GoLang 中的 CLI 工具

我是如何为一项琐碎的工作任务创建一个简单的工具的,你也可以上周我开始玩GoLang,它是一种由Google制作的类C编译语言,非常轻量和快速,事实上它经常在Techempower的基准测...

Go (Golang) 中的 Channels 简介(golang channel长度和容量)

这篇文章重点介绍Channels(通道)在Go中的工作方式,以及如何在代码中使用它们。在Go中,Channels是一种编程结构,它允许我们在代码的不同部分之间移动数据,通常来自不同的goro...

Golang引入泛型:Go将Interface「」替换为“Any”

现在Go将拥有泛型:Go将Interface{}替换为“Any”,这是一个类型别名:typeany=interface{}这会引入了泛型作好准备,实际上,带有泛型的Go1.18Beta...

一文带你看懂Golang最新特性(golang2.0特性)

作者:腾讯PCG代码委员会经过十余年的迭代,Go语言逐渐成为云计算时代主流的编程语言。下到云计算基础设施,上到微服务,越来越多的流行产品使用Go语言编写。可见其影响力已经非常强大。一、Go语言发展历史...

Go 每日一库之 java 转 go 遇到 Apollo?让 agollo 来平滑迁移

以下文章来源于GoOfficialBlog,作者GoOfficialBlogIntroductionagollo是Apollo的Golang客户端Apollo(阿波罗)是携程框架部门研...

Golang使用grpc详解(golang gcc)

gRPC是Google开源的一种高性能、跨语言的远程过程调用(RPC)框架,它使用ProtocolBuffers作为序列化工具,支持多种编程语言,如C++,Java,Python,Go等。gR...

Etcd服务注册与发现封装实现--golang

服务注册register.gopackageregisterimport("fmt""time"etcd3"github.com/cor...

Golang:将日志以Json格式输出到Kafka

在上一篇文章中我实现了一个支持Debug、Info、Error等多个级别的日志库,并将日志写到了磁盘文件中,代码比较简单,适合练手。有兴趣的可以通过这个链接前往:https://github.com/...

如何从 PHP 过渡到 Golang?(php转golang)

我是PHP开发者,转Go两个月了吧,记录一下使用Golang怎么一步步开发新项目。本着有坑填坑,有错改错的宗旨,从零开始,开始学习。因为我司没有专门的Golang大牛,所以我也只能一步步自己去...