ATMEGA的SPI总线 - 第1部分
转自:
1. https://www.yiboard.com/thread-782-1-1.html
2.https://mansfield-devine.com/speculatrix/2018/01/avr-basics-spi-on-the-atmega-part-1/
当AVR与其他器件进行数据交互时,我们需要选择采用哪种方式。这里可以使用UART、I2C等经典的串口方式,也可以选择串行外设接口(SPI)。我比较喜欢SPI总线方式。那么让我们来聊一聊这种总线形式。
关系
在SPI中的一个重要的概念就是主从关系。一个设备作为主机,负责产生时钟信号并启动每次通信。除了时钟之外,其他设备在很多方面都像主机一样操作,而且只有在被呼叫时才会回应。
一般情况下,SPI总线至少由四条线组成 - 也就是说,它需要每个器件的四个引脚。 他们是:
● MOSI:主机输出,从机输入 - 数据从主机传输到从机。
● MISO:主机输入,从机输出 - 用于从从机到主机的数据传输。
● SCK:时钟线,有时也被标记为CLK。
● SS:从机选择 - 有时也被标记为片选(CS);这根线激活从机并启动通信。
和其他总线不一样的是,SPI总线总是只有一根MOSI、一根MISO和一根SCK。但是该总线是设计用于连接多个设备。每个总线上只有一个主机设备(不同于提供多主设备模式的I2C)。但是你可以有多个从设备,每个都需要自己的SS线。
这被认为是SPI的弱势之一,尤其是当您尝试使用GPIO数目较少的微控制器时。它至少需要将四个引脚连接在一个从机设备上,每个附加的从设备需要另一个引脚。但是,这种总线方式非常简单,通讯速度可以很快。
专用硬件
谈到GPIO引脚,可以使用任何GPIO引脚来实现一种“软件模拟串行”方式的SPI。事实上,在使用移位寄存器等设备时,我已经做到了这一点。但是,您需要负责切换时钟引脚,以产生必要的脉冲,并将数据移入或移出数据引脚。这并不难,但像AVR微控制器这样的设备已经内置了硬件来为您做所有这些。
我使用ATMEGA328P进行实验,所以我将指出这一点,但所有这些都应该轻松转移到其他微控制器。我们来看看ATMEG328P的引脚分布。
<ignore_js_op>
在右下角你会看到四个粉红色的标签,表明引脚16-19是我们的SPI引脚。当然,它们也是普通的GPIO,但是当启用SPI功能时,它们承担SPI的角色,我们稍后会看到。通过使用这些引脚分配的目的,你需要在代码中做更少的工作。
不同之处在于SS引脚。说实话,你用这个GPIO是非常随意的。即使启用SPI,您仍然必须将SS引脚设置为输出,并在适当的时刻将其切换为高电平或低电平。如果你想用另一个引脚,可以自己选择。如果你想要连接不止一个从设备,你必须使用其他的GPIO。
转移数据
在讨论如何使用SPI之前,让我们花点时间考虑它是如何工作的。
您可以将每个器件(主器件和从器件)的SPI部分视为一个移位寄存器,在每个时钟脉冲中,一次输入一位和输出一位。
当时钟滴答时,从主机的移位寄存器发送一位到从机上,其余位移位。从机的移位寄存器有足够的空间来接受这个位,因为在同一个时钟脉冲上,从机已经向主机发送了一位数据,并且也一起移动了。在八个时钟脉冲之后,两个器件已经交换了这些移位寄存器中的全部字节。
这就是SPI的秘密:每当主机发送数据时,无论数据是否有意义(通常不是),它都会返回。事实上,有很多时候,主机只是想刺激从机放弃一些数据,而这是通过发送任何东西来实现的。它可以是全0或全1,这并不重要 - 这只是让从机发送任何已经准备好的移位寄存器的一种方式。
启用SPI
像微控制器上的许多事情一样,SPI通过巧妙地使用寄存器来控制。和往常一样,在AVR中,宏(通过avr / io.h)定义了寄存器和其中的位,所以我们可以简单地使用这些名称来处理接口。
我们不会在这里详细介绍SPI,但是我们将看看能让您获得简单的SPI解决方案的关键要素。我们的重点在于使用AVR作为主设备。
SPCR - SPI控制寄存器
SPCR是建立SPI的关键寄存器。所有八位用于配置接口,它们是:
7
|
6
|
5
|
4
|
3
|
2
|
1
|
0
|
SPIE
|
SPE
|
DORD
|
MSTR
|
CPOL
|
CPHA
|
SPR1
|
SPR0
|
根据数据表,当ATMEGA328P上电时,SPCR设置为0。个人而言,我并不介意花费一个或两个时钟周期,在我的SPI设置例程开始时,写到:
- 1SPCR = 0;
复制代码
那我们来看看这些位的含义:
● SPIE - SPI中断使能。将其设置为1时,只要另一个寄存器中的另一个位(SPSR中的SPIF精确)被置位,就会触发SPI中断。
● SPE - SPI启用。这是至关重要的,因为它有效地打开SPI并使这些引脚承担SPI的角色。
● DORD - 数据顺序。这控制数据是首先发送最高有效位(MSB - 即第7位)还是最低有效位(LSB,第0位)。在默认状态(0)是MSB,这就是我喜欢它。如果您以此方式滚动或者从属设备期望它,则将此设置为1为Little-Endian。
● CPOL、CPHA - 时钟极性和时钟相位。这些需要更多的解释,我们马上就会谈到。
● SPR1、SPR0 - SPI时钟频率。它们与SPSR寄存器中的SPI2X位一起使用来设置时钟速度,从而设置数据移动的速率。这是一个与处理器的振荡器时钟频率(Fosc)相关的预分频器。
相位和极性
时钟极性和相位的设置取决于从机的工作方式和期望值。有四种模式:
SPI模式
|
条件
|
前边沿
|
后边沿
|
0(0,0)
|
CPOL = 0,CPHA = 0
|
采样(上升沿)
|
设置(下降沿)
|
1(0,1)
|
CPOL = 0,CPHA = 1
|
设置(上升沿)
|
采样(下降沿)
|
2(1,0)
|
CPOL = 1,CPHA = 0
|
采样(下降沿)
|
设置(上升沿)
|
3(1,1)
|
CPOL = 1,CPHA = 1
|
设置(下降沿)
|
采样(上升沿)
|
您需要阅读从设备的数据表以了解其要求。例如,我最近搞砸了一个23LCV512的串行RAM芯片。其数据表说明如下:
The device is accessed via the SI pin, with data being clocked in on the rising edge of SCK.
数据在上升沿“锁存”(又称锁存或采样)意味着它必须是上表中的模式0或模式3。这取决于上升沿是被认为是“领先”还是“落后”。你怎么知道的?回到数据表。它应该显示时序图。这里是我们的RAM芯片的例子:
<ignore_js_op>
在输入版本中的所有内容开始之前,看看SCK线路是如何变低的?当SCK变高时,'MSB'发生。所以这里的上升沿也是领先的,这意味着我们想要模式0,在很多圈子里也被称为0,0。
设置速度
设置SPCR中的SPR0和SPR1位以及SPSR中的SPI2X位可将时钟频率设置为用于运行微控制器(Fosc)的振荡器的特定频率的一小部分。所以,如果你像我一样在16MHz下运行你的处理器,并且设置一个预分频值(比如16),那么SPI总线将以1MHz运行。预分频值越大,SPI总线越慢。
你可能会认为你想尽可能快地走,但是你可能会遇到问题,特别是如果你的从机的电线很长。正如我在面包板上做了很多这样的事情,我倾向于使用第二个最慢的64位设置,推测我可以随时尝试提高速度。
SPI2X
|
SPR1
|
SPR0
|
SCK频率
|
0
|
0
|
0
|
Fosc / 4
|
0
|
0
|
1
|
Fosc / 16
|
0
|
1
|
0
|
Fosc / 64
|
0
|
1
|
1
|
Fosc / 128
|
1
|
0
|
0
|
Fosc / 2
|
1
|
0
|
1
|
Fosc / 8
|
1
|
1
|
0
|
Fosc / 32
|
1
|
1
|
1
|
Fosc / 64
|
SPSR - SPI状态寄存器
在这里我们只关心三个位,如果说实话,我主要关心的只有一个位。
7
|
6
|
5
|
4
|
3
|
2
|
1
|
0
|
SPIF
|
WCOL
|
-
|
-
|
-
|
-
|
-
|
SPI2X
|
● SPIF - SPI中断标志。当数据传输和输入完成时自动设置。如果您已经使能了全局中断和SPCR中的SPIE位,则当该标志置位时将触发中断。处理该中断将自动清除该标志,就像读取SPI数据寄存器(SPDR)一样。所以大多数情况下,你只需要读取这个标志就可以了。
● WCOL - 写入碰撞标志。
● SPI2X - 时钟速度设置的一部分。
准备设置
在我们检查第三个寄存器之前,让我们来设置SPI。我将假定AVR将作为一个主机,我们不会搞乱中断,数据顺序将是MSB第一。我将要进行通讯的是串行RAM芯片,它的时钟极性(CPOL)为0,时钟相位(CPHA)为0。我将使用处理器速度的1/64作为总线的速度。
让我们配置SPCR的八位。我将逐一浏览所有八位数据 - 即使是我没有使用的数据 - 你可以看到:
- SPCR = 0; // just to be sure
- // SPCR |= (1 << SPIE); // not using interrupts, so leaving this at 0
- SPCR |= (1 << SPE); // enable SPI
- // SPCR |= (1 << DORD); // we want to keep the default MSB first, so not using this
- SPCR |= (1 << MSTR); // set master mode
- // SPCR |= (1 << CPOL); // leaving this set to 0
- // SPCR |= (1 << CPHA); // leaving this set to 0
- SPCR |= (1 << SPR1); // using a prescaler setting of 64 (1,0) in this register
- // SPCR |= (1 << SPR0);
复制代码
这样我们就准备好了。 在第2部分中,我们将开始使用SPI总线。
ATMEGA的SPI总线 - 第1部分的更多相关文章
- ATMEGA的SPI总线 - 第2部分
参考: 1.https://www.yiboard.com/thread-783-1-1.html 2.https://mansfield-devine.com/speculatrix/2018/01 ...
- SPI总线
一.概述. SPI, Serial Perripheral Interface, 串行外围设备接口, 是 Motorola 公司推出的一种同步串行接口技术. SPI 总线在物理上是通过接在外围设备微控 ...
- MSP430单片机的两种SPI总线实现方式
MSP430单片机上的SPI总线的实现方式分为两种:硬件实现和软件实现. 二者的抽象层次不同,硬件实现方式下程序员只需要完成总线协议的寄存器层,即一字节(char,8位二进制)数据,而软件实现方式下程 ...
- SPI总线协议及SPI时序图详解
SPI,是英语Serial Peripheral Interface的缩写,顾名思义就是串行外围设备接口.SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚 ...
- SPI总线(同步)
一.SPI总线简介 串行外围设备接口SPI(serial peripheral interface)总线技术是Motorola公司推出的一种同步串行接口.SPI 用 于CPU与各种外围器件进行全双工. ...
- STM32学习笔记(八) SPI总线(操作外部flash)
1. SPI总线简介 SPI全称串行外设接口,是一种高速,全双工,同步的外设总线:它工作在主从方式,常规需要至少4根线才能够正常工作.SPI作为基本的外设接口,在FLASH,EPPROM和一些数字通讯 ...
- SPI总线的特点、工作方式及常见错误解答
1.SPI总线简介 SPI(serial peripheral interface,串行外围设备接口)总线技术是Motorola公司推出的一种同步串行接口.它用于CPU与各种外围器件进行全双工.同步串 ...
- SPI总线通信电路设计
数据带宽=(总线频率×数据位宽)÷8 B表示带宽,F表示存储器时钟频率,D表示存储器数据总线位数,则带宽为: B(峰值带宽)=F(时钟频率MHz)×D(总线位数bit)/8 例如,PC-100的SDR ...
- linux内核SPI总线驱动分析(一)(转)
linux内核SPI总线驱动分析(一)(转) 下面有两个大的模块: 一个是SPI总线驱动的分析 (研究了具体实现的过程) 另一个是SPI总线驱动的编写(不用研究具体的实现过程) ...
随机推荐
- 树(Tree)解题总结
定义 树是一种抽象数据类型(ADT)或是实现这种抽象数据类型的数据结构,用来模拟具有树状结构性质的数据集合.它是由 n(n>0) 个有限节点组成一个具有层次关系的集合.. 二叉搜索树(Binar ...
- Nodejs模块:fs
/** * @description fs模块常用api */ // fs所有的文件操作都是异步IO,如果要以同步的方式去调用,都会加一个在原同步api的基础上加Sync // 同步的方式会在最后传入 ...
- Android开发工具资料Android Manifest 权限描述大全 随时随地查询权限描述。
作者:程序员小冰,CSDN博客:http://blog.csdn.net/qq_21376985转载请说明出处. 在文章最后面赠送了markdown格式的此文章内容下载.(不要再问问什么用markdo ...
- LoadRunner回放脚本遇到的问题(遇到就补上)
问题一:Error-26612:HTTP Status-code=500(Internal Server Error) 解决过程:google找到了关于这个错误有多种解决的方法,但是都不是我要的,最重 ...
- 02_套接字编程(socket抽象层)
1.套接字概述 1.套接概述: 套接是进行网络通信的一种手段(socket) 2.套接字分类: 流式套接字(SOCK_STREAM): 传输层基于tcp协议进行通信 数 ...
- tomcat-8.0.18 cluster 使用Redis共享Session 配置
事实证明 这位作者提在https://jingyan.baidu.com/article/ac6a9a5e10415f2b653eace8.html 最底下的http://pan.baidu.com/ ...
- springcloudalibaba与nacos服务注册流程图
springboot + springcloud + springcloudalibaba + nacos 服务注册流程图: springboot ①WebApplicationContext ②st ...
- Tomcat源码分析(下载、启动)
1.下载Tomcat源代码: https://tomcat.apache.org/download-80.cgi 2. 解压以及创建必要目录和配置 解压.新建catalina-home目录,同时将目录 ...
- Android组件化 + MVP + MVVM
前言 组件化和插件化已经提出了很久了,到现在也是比较稳定的一种架构方案了,在三年前,组件化和插件提出来没多久,前公司就已经在项目中使用了,只是当时还只是菜鸟,没有资格参与到架构的建设中,只是在大佬搭好 ...
- python文件的读写权限以及相关应用read、write和文件指针
f=open('ceshi.txt','a',encoding='utf-8')r=open('ceshi.txt','r',encoding='utf-8')上面的2种写法可以用with来写:wit ...