SPI通讯(Serial Peripheral interface)
1. SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线:SCLK,MISO,MOSI,CS
2. SPI结构简图:

可以看出,SPI主从设备两端都有一个位移寄存器,数据在位移寄存器上通过逐位移动来实现同步双工通信,在主机发送数据的同时也会收到从机发来的数据。类似一个循环。(图片不好编辑,将就着看),需要注意的是传输过程是通过主机写入一个需要发送的数据来开始的。
如果只进行写操作,主机只需忽略接收到的字节;反之,若主机要读取从机的一个字节,就必须发送一个空字节来引发从机的传输。发送结束可以设置中断。
3. 时钟极性(POL)和相位(PHA),通过配置极性及相位为0或1,可配置成为4种不同的传输时序:极性为0,时钟空闲为低电平,反之为高;相位为0,据在第一个时钟跳变沿被采集,为1的话在第二个跳变沿被采集。如图:


4. SPI 时钟最多可以到 18Mhz,支持 DMA,可以配置为 SPI 协议或者 I2S (一种音频传输总线,集成电路内置音频总线)。
5. NSS引脚:主从模式选择,简单了解,用到时再具体了解。
7. 数据帧格式:可软件设置MSB或LSB哪个在先(SPI_CR1寄存器中LSBFIRST位),也可设置输入输出数据帧是8位或者16位(SPI_CR1寄存器DFF位)。
8. 状态标志位:① 发送缓冲器空闲标志(TXE),为1时表明发送缓冲为空,可写入数据,写入后自动置0;
② 接受缓冲器非空(RXNE),为1表示接收缓冲器中有有效接收数据,读数据自动置0;
③ Busy位,由硬件管理。
FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG);
void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG);
ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT);
void SPI_I2S_ClearITPendingBit(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT);
9. SPI中断:

10. 时钟配置最大为(Fpclk/2),这里的PCLK为PCLK1(SPI为APB1的外设),PCLK1最大为系统时钟的1/2。
(贴一个刚才百度的:SYSCLK 系统时钟,最大72MHzHCLK :AHB总线时钟,由系统时钟SYSCLK 分频得到,一般不分频,等于系统钟经过总线桥AHB--APB,通过设置分频,可由HCLK得到 PCLK1与PCLK2时钟不过PCLK2时钟最高可达72MHz,而PCLK1最大36MHz。PCLK2对应APB2外设。PCLK1对应APB1外设。)
下次整理一下关于时钟配置!!!
11. CRC校验(可配置中断):在发送模式下CRC位可被作为最后一个值发送;
全双工模式下对接收到的最后一个字节自动进行CRC校验。
12. SPI一般配置步骤:
配置相关引脚的复用功能,使能SPIx时钟。调用函数:void GPIO_Init();
初始化SPIx,设置SPIx工作模式。调用函数:void SPI_Init();
使能SPIx。调用函数:void SPI_Cmd();
SPI传输数据。调用函数:void SPI_I2S_SendData();uint16_t SPI_I2S_ReceiveData();
查看SPI传输状态。调用函数:SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE
13. 相关代码(以STM32F103x为例):
#include "spi.h" void SPI2_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure; RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE );//PORTB时钟使能
RCC_APB1PeriphClockCmd( RCC_APB1Periph_SPI2, ENABLE );//SPI2时钟使能 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //PB13/14/15¸复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化 GPIO_SetBits(GPIOB,GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15); //PB13/14/15上拉 SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //设置SPI单向或者双向的数据模式:双向双线全双工
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //设置SPI工作模式为主SPI
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //设置SPI数据帧大小为8位
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //时钟空闲为高电平
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //时钟极性为1,第二个跳变沿采集数据
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由软件或者硬件管理,软件通过SSI位
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; //定义波特率预分频值位256
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //指定数据传输从最高位开始
SPI_InitStructure.SPI_CRCPolynomial = ; //CRC值计算的多项式,因该是说7位数据之后校验,标记下,我去找找再补回来
SPI_Init(SPI2, &SPI_InitStructure); //根据指定参数初始化SPI SPI_Cmd(SPI2, ENABLE); //使能SPI SPI2_ReadWriteByte(0xff);//启动传输发送0xff,可随意赋值 }
//SPI 速度设置函数
//SpeedSet:
//SPI_BaudRatePrescaler_2 2分频
//SPI_BaudRatePrescaler_8 8分频
//SPI_BaudRatePrescaler_16 16分频
//SPI_BaudRatePrescaler_256 256分频 void SPI2_SetSpeed(u8 SPI_BaudRatePrescaler)
{
assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler));
SPI2->CR1&=0XFFC7;
SPI2->CR1|=SPI_BaudRatePrescaler; //根据传入参数设置分频系数
SPI_Cmd(SPI2,ENABLE); } //SPIx 读写一个字节
//TxData:要写入的字节
//返回值:要读取的字节
u8 SPI2_ReadWriteByte(u8 TxData)
{
u8 retry=;
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET) //检查发送缓冲器空标志位是否为1
{
retry++;
if(retry>)return ;
}
SPI_I2S_SendData(SPI2, TxData); //通过SPI2发送一个数据
retry=; while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET) //检查接收缓存是否非空
{
retry++;
if(retry>)return ;
}
return SPI_I2S_ReceiveData(SPI2); //返回通过SPIx最近接收的数据
}
14. 好啦好啦,祝大家都能做个好梦~~~Goodnight....
SPI通讯(Serial Peripheral interface)的更多相关文章
- 理解AXI Quad Serial Peripheral Interface(SPI) IP核
reference : PG153-AXI Quad SPI v3.2 LogiCORE IP Product Guide.pdf 在使用MicroBlaze过程中,调用了此IP,所以有必须仔细学 ...
- SPI的学习和ESP8266的SPI通讯测试
SPI简介: SPI是串行外设接口(Serial Peripheral Interface)的缩写.SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时 ...
- Linux学习 :SPI通讯协议
SPI接口的全称是"Serial Peripheral Interface",意为串行外围接口,是Motorola首先在其MC68HCXX系列处理器上定义的.SPI接口主要应用在E ...
- SPI通讯协议
一.SPI概述 SPI,是英语Serial Peripheral Interface的缩写,顾名思义就是串行外围设备接口.SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线, ...
- 【Java实战】源码解析Java SPI(Service Provider Interface )机制原理
一.背景知识 在阅读开源框架源码时,发现许多框架都支持SPI(Service Provider Interface ),前面有篇文章JDBC对Driver的加载时应用了SPI,参考[Hibernate ...
- 【STM8】SPI通讯
这篇内容有点长,如果有人想透过我的博客学习STM8的SPI,那是我的荣幸 首先我要先说大纲,这样大家心里比较有底,可以把精力都用在SPI理解上 [SPI初步介绍]:介绍SPI如何接线.名称解释.通讯注 ...
- [Andorid] 通过JNI实现kernel与app进行spi通讯
CPU:RK3399 系统:Android 7.1 人脸识别的要求越来越高,因此主板增加了 SE 加密芯片,加密芯片通过 spi 接口与 CPU 通讯. 对于 kernel 层的代码,Linux 原始 ...
- LPC1768的SPI通讯
SPI是一种全双工串行接口,可处理多个连接到指定总线上的主机和从机.在数据传输过程中总线上只能有一个主机和一个从机通信.在数据传输中,主机总是会向从机发送一帧8到16个位的数据,而从机也总会向主机发送 ...
- STM32学习笔记——SPI串行通讯(向原子哥学习)
一.SPI 简介 SPI是 Serial Peripheral interface 的缩写,就是串行外围设备接口.SPI 接口主要应用在 EEPROM, FLASH,实时时钟,AD 转换器,还有数 ...
随机推荐
- pgloader 学习(四)一些简单操作例子
上边已经说明了pgloader 的基本使用(篇理论),但是对于实际操作偏少,以下是一个简单的操作 不像官方文档那样,我为了方便,直接使用docker-compose 运行,同时这个环境,会在后边大部分 ...
- vue中父级与子组件生命周期的先后顺序
1.vue的生命周期 2.views/createrCustormer.vue为父级 <template> <expressService /> </ ...
- mysql 字段拼接
mysql> select concat(name,"**",id) as test from test; +----------------+ | test | +---- ...
- Java实现RS485串口通信,发送和接收数据进行解析
最近项目有一个空气检测仪,需要得到空气检测仪的实时数据,保存到数据库当中.根据了解得到,硬件是通过rs485进行串口通讯的,需要发送16进制命令给仪器,然后通过轮询来得到数据. 需要先要下载RXTX的 ...
- ICEM-四分之一带孔圆板
原视频下载地址:http://yunpan.cn/cLHCeDyzqT2Uh 访问密码 52cf
- 第07组 Beta冲刺(4/5)
队名:摇光 队长:杨明哲 组长博客:求戳 作业博客:求再戳 队长:杨明哲 过去两天完成了哪些任务 文字/口头描述:已经完成代码编辑器,暂时没有其他任务 展示GitHub当日代码/文档签入记录:(组内共 ...
- spring @Autowired注入map
注入map,平常一般不会这么做,今天看一段老代码时发现有这么个用法.补习一下. @Autowired 标注作用于 Map 类型时,如果 Map 的 key 为 String 类型,则 Spring 会 ...
- java算法 -- 基数排序
基数排序(英语:Radix sort)是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较.由于整数也可以表达字符串(比如名字或日期)和特定格式的浮点数,所以基数排 ...
- 【技术】Arduino PID自整定库
最近看到了Brett Beauregard发表的有关PID的系列文章,感觉对于理解PID算法很有帮助,于是将系列文章翻译过来!在自我提高的过程中,也希望对同道中人有所帮助.作者Brett Beaure ...
- HTML-头部
HTML <head> 元素 <head> 元素是所有头部元素的容器.<head> 内的元素可包含脚本,指示浏览器在何处可以找到样式表,提供元信息,等等. 以下标签 ...