STM32再学习 -- 工程师眼中的SPI

发布者:脑洞飞扬最新更新时间:2021-07-14 来源: eefocus关键字:STM32  工程师  SPI 手机看文章 扫描二维码
随时随地手机看文章

简介: 前些天,有位网友谈到通过FPGA来实现SPI通讯。通过帖子的回复发现好多网友对SPI通讯还有些疑惑,于是今天就带着大家从SPI的标准协议,SPI在STM32单片机上的配置及在74HC595逻辑芯片通讯的实例来全方面认识一下这个既复杂又简单的通讯协议。


SPI 是Serial Peripheral Interface的缩写,直译为串行外围设备接口,SPI是Motorola公司推出的一种同步串行通讯方式,是一种四线同步总线,因其硬件功能很强,与SPI有关的软件就相当简单,使MCU有更多的时间处理其他事务。这里要说明一下,专利在电子行业还是很关键的,因此,部分其它厂商将SPI通讯协议更名以规避高昂的专利费,但其硬件处理方式是一样的,只是换了一个名称而已,例如德仪单片机里的SSI通讯。


常用的SPI通讯方式是标准四线制,如下图电路示意图所示:

MISO:主设备输入/从设备输出引脚。该引脚在从模式下发送数据,在主模式下接收数据。


MOSI:主设备输出/从设备输入引脚。该引脚在主模式下发送数据,在从模式下接收数据。


SCK:串口时钟,作为主设备的输出,从设备的输入


NSS:从设备选择。这是一个可选的引脚,用来选择主/从设备。


MOSI脚相互连接,MISO脚相互连接。这样,数据在主和从之间串行地传输(MSB位在前)。通信总是由主设备发起。主设备通过MOSI脚把数据发送给从设备,从设备通过MISO引脚回传数据。这意味全双工通信的数据输出和数据输入是用同一个时钟信号同步的;时钟信号由主设备通过SCK脚提供。


比较复杂的是这个从选择(NSS)脚。其有两种模式:软件NSS模式与硬件NSS模式。


软件NSS模式下:在该模式下说得简单一些就是此引脚当作普通的GPIO来使用。其输入/输出的功能与操作GPIO是一样的。我们通过STM32来操作片外设备时多采用此模式。


硬件NSS模式下:此模式又下分两种情况:情况一、NSS输出被使能:当STM32工作为主SPI,并且NSS输出已经使能,这时NSS引脚被拉低,所有NSS引脚与这个主SPI的NSS引脚相连并配置为硬件NSS的SPI设备,将自动变成从SPI设备;情况二、NSS输出被关闭:允许操作于多主环境。


硬件的连接我们说完了,下面我再来介绍时钟线与信号线。


在学习数字逻辑电路时,我们都听老师讲过数据的锁存方式,例如上升沿锁存等。我们的SPI通讯方式在硬件上非常灵活的处理数据锁存方式,通过两个参数的配置提供了四种不同的数据传输模式,如下图所示:从上图我们可以看出,当CPHA置高时,其数据锁存在第二个时钟边沿;CPHA清零时,数据锁存在第一个时钟边沿。而CPOL参数置高时,数据锁存在时钟信号的下降沿,时钟线空闲状态为常高,反之,数据锁存在时钟信号的上升沿,空闲状态为常低。


对于数据的发送过程,帧格式也是可以修改的,例如可以选择MSB方式(最高位先发送)或是LSB方式(最低位先发送),还可以选择插入CRC校验的方式等,这里对于这些高级的应用,由于本文片幅有限就不再详细讲解了。


接下来,我们通过STM32单片机对于SPI外设的初始化过程再来看一下SPI的硬件标准。


void SPI_init(void)


{


RCC_APB2PeriphClockCmd(sFLASH_CS_GPIO_CLK | sFLASH_SPI_MOSI_GPIO_CLK | sFLASH_SPI_MISO_GPIO_CLK |


sFLASH_SPI_SCK_GPIO_CLK, ENABLE);


/*!< 配置SPI的外设时钟,并使能 */


RCC_APB2PeriphClockCmd(sFLASH_SPI_CLK, ENABLE);


/*!< 配置SCK引脚 */


GPIO_InitStructure.GPIO_Pin = sFLASH_SPI_SCK_PIN;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //此处根据具体应用而设置,例如可配置为开漏输出


GPIO_Init(sFLASH_SPI_SCK_GPIO_PORT, &GPIO_InitStructure);


/*!< 配置MOSI引脚 */


GPIO_InitStructure.GPIO_Pin = sFLASH_SPI_MOSI_PIN;


GPIO_Init(sFLASH_SPI_MOSI_GPIO_PORT, &GPIO_InitStructure);


/*!< 配置MISO引脚 */


GPIO_InitStructure.GPIO_Pin = sFLASH_SPI_MISO_PIN;


GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;


GPIO_Init(sFLASH_SPI_MISO_GPIO_PORT, &GPIO_InitStructure);


/*!< 配置NSS引脚为GPIO输出 */


GPIO_InitStructure.GPIO_Pin = sFLASH_CS_PIN;


GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;


GPIO_Init(sFLASH_CS_GPIO_PORT, &GPIO_InitStructure);


/*!< SPI配置 */


SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;


//数据线两线,双向全双半


SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //


SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //


SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;


//CPOL置高,时钟线在闲时常高,下降沿锁存数据


SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //CPHA置高,则第二个时钟沿锁存数据


SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //从引脚为软件配置方式


SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; //SPI时钟频率为4分频


SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //MSB最高位优先发送


SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC检验公式选择第7项


SPI_Init(sFLASH_SPI, &SPI_InitStructure);


/*!< 使能SPI */


SPI_Cmd(sFLASH_SPI, ENABLE);


}


上面的源代码是示例是ST公司操作SPI flash的Demo示例。我们再以74HC595芯片的硬件操作操作来配置,初始化SPI外设。


我们先来看一下74HC595的硬件操作时序图:



从上图,我们可以看出,时钟线(SH_CP)在空闲状态为常低,并且为第一个时钟沿的上升沿锁存数据。因此,我们需要将上面配置初始化的两个参数修改为如下:


SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //CPOL置高,时钟线在闲时常低,上降沿锁存数据


SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //CPHA清零,则第一个时钟沿锁存数据


其它参数不做修改即可。上述源代码已经通过STM32F103与8片74HC595串联实验通过,示例完整工程源代码可以到电子产品世界论坛片自行查找、下载。


标准四线的SPI通讯不仅为我们节省了宝贵的单片机引脚数,而且其规范的硬件协议也为我们嵌入式软件编程提供了极大的便利。丰富的外围器件支持,例如SPI的flash存储,SPI接口的SD读卡器,SPI接口的网络通讯模块都已经非常普及,可以看到应用好外设SPI通讯已经成为一名工程师必要的技能之一。

关键字:STM32  工程师  SPI 引用地址:STM32再学习 -- 工程师眼中的SPI

上一篇:防盗功能的智能车模型举例
下一篇:STM32 UART的使用过程

推荐阅读最新更新时间:2024-11-10 14:37

STM32】HAL库 STM32CubeMX教程九---ADC
前言: 本系列教程将 对应外设原理,HAL库与STM32CubeMX结合在一起讲解,使您可以更快速的学会各个模块的使用 所用工具: 1、芯片: STM32F407ZET6/ STM32F103ZET6 2、STM32CubeMx软件 3、IDE: MDK-Keil软件 4、STM32F1xx/STM32F4xxHAL库 知识概括: 通过本篇博客您将学到: ACD工作原理 STM32CubeMX创建ADC例程 HAL库定时器ADC函数库 什么是ADC Analog-to-Digital Converter的缩写。指模/数转换器或者模拟/数字转换器。是指将连续变量的模拟信号转换为离散的数字信号的器件。 典型的模拟数字
[单片机]
【<font color='red'>STM32</font>】HAL库 STM32CubeMX教程九---ADC
工程师设计小Tips:PCB设计接地问题精要
模拟地/数字地以及模拟电源/数字电源只不过是相对的概念。提出这些概念的主要原因是数字电路对模拟电路的干扰已经到了不能容忍的地步。 目前的标准处理办法 如下:   1. 地线从整流滤波后就分为2根,其中一根作为模拟地,所有模拟部分的电路地全部接到这个模拟地上面;另一根为数字地,所有数字部分的电路地全部接到这个数字地上面。   2. 直流电源稳压芯片出来,经过滤波后同样分为2根,其中一根经过LC/RC滤波后作为模拟电源,所有模拟部分的电路电源全部接到这个模拟电源上面;另一根为数字电源,所有数字部分的电路电源全部接到这个数字电源上面    注意 :模拟地/数字地以及模拟电源/数字电源除了在电源的开始部分有一点连接外,不能再有任何连
[模拟电子]
<font color='red'>工程师</font>设计小Tips:PCB设计接地问题精要
利用STM32编码器进行任意位置确定
车轮位置的确定是在制作小车的过程中必不可少的部件,好在STM32中包含了硬件的编码器。但使用的过程中却存在诸多不方便。下面由我一一道来: 1。编码器原理 什么是正交?如果两个信号相位相差90度,则这两个信号称为正交。由于两个信号相差90度,因此可以根据两个信号哪个先哪个后来判断方向、根据每个信号脉冲数量的多少及整个编码轮的周长就可以算出当前行走的距离、如果再加上定时器的话还可以计算出速度。 2。为什么要用编码器 从上图可以看出,由于TI,T2一前一后有个90度的相位差,所以当出现这个相位差时就表示轮子旋转了一个角度。但有人会问了:既然都是脉冲,为什么不用普通IO中断?实际上如果是轮子一直正常旋转当
[单片机]
利用<font color='red'>STM32</font>编码器进行任意位置确定
AVR单片机(学习ing)—(十)、ATMEGA16的同步串行接口SPI—03
十、ATMEGA16的同步串行接口SPI 十—(03)、ATMEGA16的同步串行接口SPI的串行通讯实验—通过效率最高的中断法~~ 然后就是程序了~~ IAR10_2_M.c //------------------------------------------------------------------------------ //这是ATMEGA16作为主机发送的文件 //主机每隔1s发送数组的一个数据给从机,从机收到后则发送自己的数组的一个数据给主机,这样实现数组内容的交换 //数组的内容在主机和从机的数码管上显示 #include ioavr.h #include intrinsics.h #includ
[单片机]
AVR单片机(学习ing)—(十)、ATMEGA16的同步串行接口<font color='red'>SPI</font>—03
STM32 AD采用外部电压基准IC提高精度和稳定性
STM32F103系列的单片机64脚和64脚以下的都把VDDA和VREF内部连在一起,没独立开管脚。而100脚和100脚以上却是单独分开。 一般如果我们对采集精度不高,VDDA和VREF都直接接到3.3V电源VDD上,采用稳定和精度高的电源稳压IC,在电路上加滤波电路或在软件上做滤波处理,即可满足正常使用。 如果对AD精度要求高,AD供电和基准电压输入必须与MCU电源分开单独供电,REF电压基准IC可以为AD提供高度基准电压,其中REF31系列采用SOT23-3小封装,提供1.25、2.048、2.5、3.0、3.3、4.096电压输出,其中REF3133提供3.3V基准电压,0.2%精度,最大+-10ma电流输出。 项目
[单片机]
<font color='red'>STM32</font> AD采用外部电压基准IC提高精度和稳定性
unity在stm32上的使用
按照本文的描述,应该可以在你所处的 硬件 上跑通代码。 先决条件:装有编译和集成的开发环境,比如: Keil uVision5。 板子硬件要求:无, 芯片 自带的串口功能即可完成。 源码获取 Unity 是一个轻量级的 C 语言单元测试框架,它的设计理念是简单易用。 Unity 支持测试套件和测试用例,同时提供了丰富的断言函数,包括比较、异常和日志等。 源码入口: GitHub - ThrowTheSwitch/Unity: Sim ple Unit Te sting f or C https://github.com/ThrowTheSwitch/Unity/ 源码里面结构,接下来准备一个stm32的基础工程,把相关代码
[单片机]
unity在<font color='red'>stm32</font>上的使用
STM32 编译指令 #pragma pack 的配对使用
#pragma pack 可以用来指定数据结构的成员变量的内存对齐数值。 可选值为: 1、2、4、8、16。 使用 pack 指令要配对使用,以避免意外影响项目中其他源文件的结构成员的内存对齐。 如果影响了其他源文件的结构成员内存对齐,那么在你按照默认对齐来计算那些结构成员占用内存大小或者使用指针移动计算结构成员偏移位置的时候,就可能会出现意料之外的异常。 主要可能的异常是内存定位错误或非法内存访问,结果可能导致错误的定位或数值,极端的情况下可能导致程序崩溃。 下面的例子用来展示基本的配对使用方式。 1)#pragma pack(n)的配对使用 #pragma pack(1) //内存对齐设置为1个字节
[单片机]
贸泽电子为电子设计工程师提供先进的医疗技术资源和产品
2024年10月17日 – 专注于推动行业创新的知名新品引入 (NPI) 代理商™贸泽电子 (Mouser Electronics) 推出内容动态更新的医疗资源中心,探索改变医疗保健产业并且拯救生命的技术 。随着数字化转型的蓬勃发展,医疗保健系统突飞猛进,实现了更快、更准确的诊断,大幅缩短了等待时间,并且还采用了各种先进的数字疗法。人工智能 (AI) 的分析能力正在重新定义患者护理工作,提供前所未有的深入健康数据,同时改变慢性病和无法治愈的疾病的治疗方法。 这个内容丰富的资源中心将为设计工程师提供所需的工具,帮助其开发高精度的技术,改善患者的生活。资源中心收录了丰富的文章、博客、电子书和产品信息,读者可以从中了解到改变传
[医疗电子]
贸泽电子为电子设计<font color='red'>工程师</font>提供先进的医疗技术资源和产品
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved