ESP8266 SPI通信
设备与设备之间的通信往往都伴随着总线的使用,而用得比较多的就当属于SPI总线和I2C总线,而恰巧NodeMcu也支持这两种总线通信
1. SPI总线——SPI类库的使用
SPI是串行外设接口(Serial Peripheral Interface)的缩写。是Motorola公司推出的一种同步串行接口技术,是一种高速的、全双工、同步的通信总线。通过它可以连接使用同样接口的外部设备。例如,ESP8266模组上,ESP8266EX芯片就是通过SPI接口与外接flash芯片连接的
SPI作为一种总线通信方式,可以通过SPI接口连接多个从设备,并通过片选控制来选择对某一设备进行连接使用。如下图所示:
1.1 SPI总线概述
SPI的通信原理很简单,它是全双工主从通信方式,这种模式下通常有一个主设备和一个或者多个从设备(注意,同一时刻,只有一个主设备和一个从设备进行通信),需要至少4根线,特殊情况下(单向传输时)3根线也可以。
SPI的器件工作在SPI规定下的两种基本模式,即SPI主模式和SPI从模式。在一个SPI设备中,通常有如下表的几个引脚:
主设备负责启动通信,负责输出时钟信号以及选择通信的从设备。当有多个从设备的时候,因为每个从设备上都有一个CS引脚接入到主设备中,当我们主设备和某个从设备通信时将需要将从设备的CS引脚电平设置为低电平或者高电平(根据实际情况而定)。数据的收发通过MISO和MOSI进行
1.2 NodeMcu SPI
NodeMcu的SPI(注意与HSPI区分)引脚(SD0-SD3、CLK、CMD)专门用于与ESP-12E的外接flash芯片进行Quad-SPI通信,因此不能用于SPI应用。
基于ESP8266的NodeMcu具有HSPI,具有4个可用于SPI通信的引脚(GPIO12-GPIO15)。通过这个SPI接口,我们可以将任何支持SPI的设备与NodeMcu连接起来,并与其进行通信
知识扩展——标准SPI、Dual SPI和Quad-SPI
1.标准SPI
标准SPI通常就叫做SPI,它是一种串行外设接口规范,有4根引脚信号:clk、cs、mosi、miso;
2.Dual 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数据,加倍了数据传输;
3.Quad SPI
与Dual SPI类似,也是针对SPI Flash,Quad SPI Flash增加了两根I/O线(SIO2,SIO3),目的是一个时钟内传输4个bit。所以可以理解为:在传输速度上,Quad SPI=2Dual SPI=4SPI。
所以对于SPI Flash,有标准spi flash,dual spi , quad spi 三种类型,分别对应3-wire, 4-wire, 6-wire,在相同clock下,线数越多,传输速率越高。
温馨提示
读者可以自行了解一下NodeMcu的flash是什么标准。说不定烧录代码失败就是因为这个原因(Flash模式是QIO或者DIO)
1.3 ESP8266 SPI类库成员函数
Arduino Core For ESP8266的SPI类库定义在SPI.h头文件中。该类库只提供了作为SPI主设备的API,其成员函数如下:
1.begin()
该功能用于初始化SPI通信。
语法:SPI.begin()
参数:无;
返回值: 无;
2.end()
该功能用于关闭SPI通信。
语法:SPI.end()
参数:无;
返回值: 无;
3.setBitOrder()
设置数据传输顺序。
语法:SPI.setBitOrder(order)
参数:
order,传输顺序,取值为:
~ LSBFIRST,低位在前;
~ MSBFIRST,高位在前。
返回值: 无;
4.setClockDivider()
设置通信时钟。时钟信号由主机产生,从机不用配置。但主机的SPI时钟频率应该在从机允许的处理速度范围内。
语法:SPI.setClockDivider(divider)
参数:
divider,SPI通信的时钟是由系统时钟分频得到的。可使用的分频配置为:
~ SPI_CLOCK_DIV2,2分频;
~ SPI_CLOCK_DIV4,4分频(默认配置);
~ SPI_CLOCK_DIV8,8分频;
~ SPI_CLOCK_DIV16,16分频;
~ SPI_CLOCK_DIV32,32分频;
~ SPI_CLOC K_DIV64,64分频;
~ SPI_CLOCK_DIV128,128分频;
返回值: 无;
5.setDataMode()
该功能用于设置数据模式。
语法:SPI.setDataMode(mode)
参数:
mode,可配置的模式,包括:
~ SPI_MODE0;
~ SPI_MODE1;
~ SPI_MODE2;
~ SPI_MODE3;
返回值: 无;
注意点:
SPI四种模式中,SPI的相位(CPHA)和极性(CPOL)分别可以为0或者1,对应的4种组合构成了4种模式:
~ SPI_MODE0:CPOL=0,CPHA=0;
~ SPI_MODE1:CPOL=0,CPHA=1;
~ SPI_MODE2:CPOL=1,CPHA=0;
~ SPI_MODE3:CPOL=1,CPHA=1;
时钟极性CPOL:即SPI空闲时,时钟信号SCLK的电平(1是空闲时高电平,0是空闲时低电平)。
时钟相位CPHA:即SPI在SCLK第几个边沿开始采样(0是第一个边沿开始,1是第二个边沿开始)
6.transfer()
该功能用于传输1B的数据,参数为发送的数据,返回值为接收到的数据。SPI是全双工通信,因此每发送1B的数据,也会接收到1B的数据。
语法:SPI.transfer(val)
参数:
val,要发送的字节数据。
返回值: 从机返回的1B数据;
7.transfer16()
该功能用于传输2B的数据,参数为发送的数据,返回值为接收到的数据。
语法:SPI.transfer16(val)
参数:
val,要发送的16位(uint16_t)数据。
返回值: 从机返回的2B数据;
注意点: 发送的uint16_t数据,其实底层也是分开两个字节分别发送两次,接收到的2B数据,也会重新组装成uint16_t数据;
8.transferBuf()
该功能用于传输一个缓冲区数据,参数为发送的缓冲区buf。
语法:SPI.transfer(buf,count)
参数:
buf,要发送的缓冲区(uint8_t*)数据。
count,缓冲区的大小。
返回值: 无;
注意点: 虽然没有返回值,但是从从机传输回来的数据会替换掉buf缓冲区的数据,所以调用完整个方法之后,buf里面的数据就是从机返回的数据;
9.pins()
该功能用于切换SPI引脚映射,需要在SPI.begin()之前调用SPI.pins(6,7,8,0)。
语法:SPI.pins(sck, miso, mosi, ss)
参数:
sck,时钟引脚,固定为6;
miso,主设备输入,从设备输出引脚,固定为7;
mosi,主设备输出,从设备输入,固定为8;
ss,使能信号引脚,固定为0。
返回值: 无;
注意点: 通常情况下,ESP8266的SPI对应引脚为MOSI-GPIO13,MISO-GPIO12,SCLK-GPIO14,SS-GPIO15。如果在调用SPI.begin()之前调用SPI.pins(6,7,8,0),那么引脚映射就会变成MOSI-SD1,MISO-SD0,SCLK-CLK,HWCS-GPIO0。可以看出它们和ESP8266模块的外接Flash共享了SPI引脚。这个时候SPI的SS控制位就不是由我们的代码来控制,而是由系统硬件本身来调配,因为它必须确保外接Flash的优先级是最高的。在此,笔者不建议这么用
1.4 SPI寄存器
所有的SPI设置都由Arduino SPI控制寄存器(SPCR)来决定。这个寄存器就是微控制器内存的一个字节,它是可读写的。寄存器提供的服务通常有3类:控制、数据和状态。
控制寄存器(SPCR)
编码设置控制多种微控制器的功能。通常控制寄存器中的一个位影响某个特定的设置(学过单片机系统的读者应该比较了解这个,比如中断允许控制寄存器IE、中断优先级控制寄存器IP、定时器/计数器控制寄存器TCON等)。
数据寄存器(SPDR)
存储数据的寄存器,比如串行口锁存器SBUF,仅仅hold住了一个字节。比如,SPI数据寄存器hold住了要发往MOSI线的一个字节,或者这个数据是要从MISO线传入的。
状态寄存器(SPSR)
根据多种微控制器的条件改变其状态。比如,SPI状态寄存器(SPSR)的第七位被设置为1表示有数据从SPI传入或传出。
在这里,我们主要讲解一下SPI控制寄存器(SPCR),一共有8位,每一个都控制了一种特定的SPI设置
天子骄龙
ESP8266 SPI通信的更多相关文章
- ESP8266开发之旅 基础篇⑤ ESP8266 SPI通信和I2C通信
设备与设备之间的通信往往都伴随着总线的使用,而用得比较多的就当属于SPI总线和I2C总线,而恰巧NodeMcu也支持这两种总线通信,所以本章的主要内容就是讲解ESP8266 SPI和I2C总线 ...
- 三,ESP8266 SPI
重点是说SPI通信协议,,,, 不要害怕协议因为协议是人规定的,,刚好我也是人......规定的协议既然能成为规范让所有人所接受,那么必然有它的优势和优点,必然值得学习,, 害怕协议的人是因为当初碰到 ...
- 三,ESP8266 SPI(基于Lua脚本语言)
https://www.cnblogs.com/yangfengwu/p/7520260.html 重点是说SPI通信协议,,,, 不要害怕协议因为协议是人规定的,,刚好我也是人......规定的协议 ...
- 理解一下单片机的I2C和SPI通信
应某位网友要求,今天说一下单片机的I2C SPI通信,可能说不清楚,因为这毕竟要做实验才可完全理解. I2C和SPI是两种不同的通信协议. 听到协议,似乎高不可攀,其实协议就是人们定义的一个标准而已, ...
- SPI通信实验---verilog(FPGA作为从机,使用可读可写)
本实验讲究实用性,故设计思想为:主机先向从机发送地址,若是向从机写入数据,则向从机发送数据,若是读取从机数据,则向从机发送时钟,然后在时钟下降沿读取数据即可.cs信号上升沿作为SPI通信的结束信号.r ...
- SPI通信
SPI是由Motorola公司提出的一种同步串行外围接口:它在速度要求不高,低功耗,需要保存少量参数的智能化传感系统中得到了广泛应用: SPI是一个全双工的同步串行接口,在数据传输过程中,总线上只能是 ...
- 关于SPI通信原理与程序实现
第一次接触SPI是因为当时用到NRF24L01,需要用SPI进行通信.因为2401上面写着MOSI.MISO.SS.RST,当时以为只要用到SPI就肯定有这几个引脚,以至于限制了自己的思维.只认识MI ...
- [转]SPI通信原理简介
[转自]http://www.cnblogs.com/deng-tao/p/6004280.html 1.前言 SPI是串行外设接口(Serial Peripheral Interface)的缩写.是 ...
- linux 下SPI通信注意事项(待续)
一.2台Linux设备之间使用SPI通信 1.标准Linux只支持Master 模式.但是可以在驱动中修改为Slave模式: 2.硬件SPI可能支持Slave模式,也可能不支持.这个要提前确认好: 3 ...
随机推荐
- ElasticSearch的中文分词器ik
一.前言 为什么要在elasticsearch中要使用ik这样的中文分词呢,那是因为es提供的分词是英文分词,对于中文的分词就做的非常不好了,因此我们需要一个中文分词器来用于搜索和使用. 二.IK ...
- Day02:对象和类(下)
构造方法 什么是构造方法 在类实例化对象时运行的一种特殊的方法 为什么需要构造方法 构造方法适合为对象的属性赋初值 编写构造方法 public 类名(){ //方法体 } 构造方法不写返回值 构造方法 ...
- Multi-Object-Edit With Django FormSets
I had to write a multi-object edit table the other day for a Django project and as such I dove into ...
- LeetCode.961-2N数组中N次重复的元素(N-Repeated Element in Size 2N Array)
这是悦乐书的第365次更新,第393篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第227题(顺位题号是961).在大小为2N的数组A中,存在N+1个唯一元素,并且这些元 ...
- P1141 01迷宫(连通块模板)
题目描述 有一个仅由数字0与1组成的n×n格迷宫.若你位于一格0上,那么你可以移动到相邻4格中的某一格1上,同样若你位于一格1上,那么你可以移动到相邻4格中的某一格0上. 你的任务是:对于给定的迷宫, ...
- 【神经网络与深度学习】卷积神经网络-进化史:从LeNet到AlexNet
[卷积神经网络-进化史]从LeNet到AlexNet 本博客是[卷积神经网络-进化史]的第一部分<从LeNet到AlexNet> 如需转载,请附上本文链接:http://blog.csdn ...
- Linux系统搭建并管理Git服务器
搭建Git服务器 GitHub就是一个免费托管开源代码的远程仓库.但是对于某些视源代码如生命的商业公司来说,既不想公开源代码,又舍不得给GitHub交保护费,那就只能自己搭建一台Git服务器作为私有仓 ...
- 声明一个LIst类型的数组
ArrayList[] graphArrayList = new ArrayList[4]; for(int i=0;i<graphArrayList.length;i++){ graphArr ...
- Ubuntu下更新Pycharm时权限不够(PyCharm does not have write access to...)
问题描述 更新Pycharm时,出现如下问题 PyCharm does not have write access to /usr/local/software/pycharm-2019.1.3. P ...
- Linux文档整理之【Jenkins+Docker自动化部署.Net Core】
这次整理的文档是Jenkins+Docker实现自动化部署,很早之前就写的,今天有时间就搬到博客园做个记录. Jenkins是基于Java开发的一种持续集成工具,主要用于持续.自动的构建/测试软件等相 ...