STM32F030 Nucleo-多样的SPI通信之Master标准模式-SPIFlash读写

2018-07-10 21:56:27编辑:什么鱼 关键字:STM32F030  SPI通信  Master标准模式

我个人认为,学习单片机,在硬件上和驱动上,我们无非学习这么几个东西:

1.能灵活的操作GPIO端口

2.理解单片机各个引脚的功能和作用和外围最小系统的设计

3.各种通信协议比如:并口协议(LCD1602等),UART/USART协议,IIC协议,485通信协议,SPI通信协议,IIS音频流传输协议,CAN通信协议,单总线通信协议(DS18B20等),三总线协议(DS1302等)等等通信协议。

4.ADC/DAC 模数/数模转换

5.单片机内部提供的一些运输协议或者特殊功能,比如DMA,RTC,定时器Timer等,这些功能的操作有单片机本身确定,经过协议相同目标相同,但是操作等可能各家单片机不尽相同;咱只需要理解它完成的是什么功能/任务就好。

通过学习各种协议、一些基本的操作和所使用的这款单片机的内核功能或者特殊功能(与内核和厂商设计相关),就基本上能利用单片机与外设或者其他MCU或CPU实现通信交流了,都交流上了!那自然就是有关系了!哈哈哈!那至于想搞什么关系(男女关系还是朋友关系<开玩笑>)那就自己想喽!哈哈哈哈!

关系都搞通了!那么借钱(读取)或者还钱(写入)就有机会啦!!!

那么其实问题就来了!有人会疑问,不是还有算法啊!数据结构等等这些吗??其实这是一个显而易见的问题:

建议:

1.在我们写代码的时候,最好将我们的代码封装起来,分成与硬件相关的代码(层)和与硬件无关的层。

2.与硬件无关的层可能有继续划分,比如分一些总线层或者书中间调度层等等,这些层和我们的产品功能实现可能没有太大关系,但是却为我们的功能进行调度或者作为基础,是的我们的代码的可移植性更高。

3.当然,万事没有绝对,在RAM和ROM/Flash紧缺的情况下,用上面1和2点的方法显然是不合适的,因为咱的ROM/Flash一不小心就装不了咱的代码了,那就没得玩了,何况还有RAM的情况也是这样,所以这时候咱就尽量的减少代码,优化代码,这样可能就会使得与硬件相关的代码和功能代码混合在一起了,这样的代码的可移植性是非常低的,但是没办法嘛!这是一种解决方案!哈哈!

4.基于上面三点的建议,做一下总结。首先说明一下实际的情况,绝大部分的初学者管你内存多大,他们的代码都采用的是第3种方法,这可以说是一种不好的习惯,建议还是尽量的模仿使用1和2中方法学习,当然也不是那么简单的,这需要一个长久的学习和阅读一些好的开源项目代码,比如一些实时操作系统源码(UCosII、FreeRTOS,小型用于SD卡或者SPIFlash等的文件系统源码等等),这样理解开源项目的架构,才能自己慢慢学习构建架构的,这是一个比较漫长的过程,需要有心人在学习的过程中慢慢的关注。

OK!废话了半天!言归正传!这里咱要学习的是SPI通信,身边刚好有SPIFlash,咋就用咱的STM32F030 Nucleo板卡作为主机与它通信吧。

首先呢,有必要先介绍一下SPI通信协议。

SPI通信总线协议最开始是由Motorola(摩托罗拉)提出或者发明的。她提供了三线制全双工同步串行外围接口,采用主从模式架构。在一同一个通信系统中,支持多从机单一主机。也就是说,每一个SPI总线通信上只存在一个主机。

它的通信方式是:通信时钟CLK有主机控制,数据在时钟脉冲下按位传输,先传高位再传低位。()这一点非常重要!在单片机不支持硬件SPI通信时,与具有SPI通信接口的外设传感器等通信就必须使用MCU的I/O口模拟SPI时序与之进行数据通信,从而实现功能。

还有一个非常好的好处就是,通信速率能达到几M到十几M,哈!好快。

好!基本上几句话就知道SPI的基本信息了!那么,干啥呢??当然是。。。。。。。。分析分析通信过程了哇!哈哈!

硬件通信接口:

CLK-------CLOCK Signal;时钟线

MISO-----Master Input Slave Output;主机输入从机输出数据线

MOSI-----Master Output Slave Input;主机输出从机输入数据线

NSS-------Slave Select pin;从设备使能线

咦!咋觉得不太对呢?上面明明说是三线制啊!咋的这里有四根线呢(CLK时钟线、MISO数据线,MOSI数据线和NSS片选线)?

其实是这样的,前面介绍SPI的时候,说是三线制,主要是说数据通信所需要的线,即CLK、MISO、MOSI这三根线是SPI通信的基础,而NSS片选线有时候在特定情况下是不必要的(这个下一篇文章中我会详细介绍),所以,问题就这样愉快的解决了。哈哈!这种感觉是不是很爽!!嘿嘿。

当然,这其实只是SPI通信硬件接口的一部分,而且是最基础的部分。那么现在就STM32F030的硬件SPI资源进行讲解。打开参考手册《STM32F030x468C and STM32F070x6B advanced ARM®-based 32-bit MCUs.pdf》

打开到SPI通信的讲解章节,如下:

这就是SPI的简介了!哈哈!好!不废话了!继续往下:


这里就说明了这款芯片的SPI的特点和功能,再往下:


注意红线框出的部分,这就是我们这款单片机拥有的SPI外设资源和支持的功能资源。非常重要!!!

讲到资源,那我们还必须要牢记这款芯片的资源对应的单片机引脚。这个要从Datasheet来看了。如下:

哈!看见没!这就是这款芯片的资源了,特别关注红框标注的地方,而且还要注意哪些复用是我们的STM32F030 Nucleo板卡的主控MCU STM32F030R8T8才有的,这一点非常重要!别写半天引脚的配置都不对。这是一件很悲催很丢脸的事。

OK!咱来看看我们的单片机的SPI内脏,如下:

有必要先说明一下:FIFO:First Input First Output,即先进先出队列!哈哈!还记得在学习数据结构是的队列吗??就是这个了!嘿嘿!

发送数据:当不使用Tx FIFO缓冲区时,直接就是将1Byte数据从MOSI上传移位寄存器,然后移位寄存器自己根据时钟CLK的边沿将数据按位移动到IO口,然后传送出去;当使用Tx FIFO的时候,咱们就直接将一堆数据放在Tx FIFO中,然后使能传输,它就自己讲数按照SPI协议发送出去了(如红色线)。

接收数据:当不使用Rx FIFO缓冲区的时候,MCU根据时钟CLK的边沿对MISO引脚进行数据采集,然后放在移位寄存器上,当采集满8bit了,时钟就好停下来啦!然后就是读取数据出来啦!哈哈!当使用Rx FIFO时,就将数据放大Rx FIFO中,然后当FIFO满的时候,产生标志或者中断,然后就将数据搬到内存中就好喽!嘿嘿!(如蓝色线)。

对于时钟线和NSS,当然是分别作为产生数据传输是所需要的时钟脉冲和片选了哈!

那么其实在这个SPI“内脏”中,还包含了CRC校验控制器和同学控制器,顾名思义肯定是用来校验和控制SPI通了的拉!嘿嘿!

那么粉色框是啥意思呢??最下面那个一看就知道这是波特率了!嘿嘿!就是控制速度的拉!两个设备要通信,肯定是要站在同一个水平上交流嘛!如果一个快一个慢,那就没法交流了!嘿嘿!那上面的粉色框是啥呢??RXONLY就是只读喽!但是其实参考手册上都有表述,先不纠结这个。咱要关注的应该是:CPOL和CPHA。这两东西到底是啥呢??其实呢CPOL表示SPI通信的时钟极性,即表示时钟线在空闲时的电平状态;CPHA表示SPI通信的时钟相位,即表示在时钟线脉冲的什么时候对数据进行捕捉和输出。可以配置出两种SPI通信协议(它对SPI通信影响极大)。

CPOL和CPHA的配置表述:

CPOL:CPOL= 0;时钟线空闲状态时为低电平;CPOL=1;时钟线空闲状态时为高电平。

CPHA:CPHA=0;在时钟线的第一个跳变沿(上升沿/下降沿)数据被采集;CPHA=1;在时钟线的第二个跳变沿(上升沿/下降沿)数据被采集。

注:在进行SPI通信时,通过一总线上的所有设备必须保证CPOL和CPHA的一致性;这是非常重要的,反正意思就是在同一水平上进行交流。

得到以上消息之后,咱组合一下就有如下情况了,其实就是2的2次方等于4种SPI通信模式,如下:

(1)SPI0:CPOL=0,CPHA=0

(2)SPI1:CPOL=0,CPHA=1

(3)SPI2:CPOL=1,CPHA=0

(4)SPI3:CPOL=1,CPHA=1

嘿嘿!以上就是SPI通信的四种模式了!也可以理解成SPI通信的四种协议!还有就是至于SPI0~SPI3到底表示的是啥就不要纠结了(有些人不知道咋的,就是要纠结这东西,然后然后连自己都分不清楚这到底是啥)!咱至于记住CPOL和CPHA分别在不同状态下表示的是啥就够了!然后组合!哈哈哈哈!你懂的。

OK!对于SPI总线通信的基本说明就到这了!当然了,还有时序的说明,但是呢,这个比较长!就不一个个分析了,看看SPI通信协议更靠谱!嘿嘿!我会附上我认为比较好的SPI协议文档进行参考。

下面咱要继续挖SPI了!

SPI主机-从机全双工通信:

看见了没!现在知道为毛是三线了吧?上面已经表示出了主机和从机之间的接口连接方式,有时候只需要一直讲NSS处于一个低电平状态,就可以一直正常通信了。至于发送数据那就是CLK,NISO,MOSI的事了。

SPI主机-从机半双工通信:

看见了没有??这样也是可以的!这就有点像IIC了,但是,但是协议是不一样的!主机的MOSI与从机的MISO接口相连!既然是半双工,那么就意味着它不能同时发送和接收数据了,所以,主机应该是先发完数据,然后再读取数据,呵呵!!!这样的通信方式,到目前为止,俺遇到的传感器等等设备也是没用过哇。不过不管它!既然支持,那么有机会就要使用它!嘿嘿!

SPI主机-从机单工通信:

在参考手册中有如下图的一段话:

讲述了SPI可以工作在单工模式下雨设备通信!和它的配置!那么说明时候用

[1] [2]

关键字:STM32F030  SPI通信  Master标准模式

来源: eefocus 引用地址:http://www.eeworld.com.cn/mcu/2018/ic-news071040230.html
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:STM32F030 USART2配置函数 波特率不对导致无法进入中断
下一篇:keil环境下stm32f030R8 APP程序中断向量的重映射

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

STM32F407学习笔记——GPIO_按键控制LED亮灭

#include <stm32f4xx.h>#include "stm32f4xx_conf.h"#include "delay.h" GPIO_TypeDef* io_led=GPIOC;//定义一个指向结构体GPIO_TypeDef的io_led  const u16 pin_led=GPIO_Pin_1;//引脚GPIO_TypeDef* io_key=GPIOC;const u16 pin_key=GPIO_Pin_0; void Led_Init(){ GPIO_InitTypeDef GPIO_init_l;//用于初始化的结构体
发表于 2018-07-21 11:07:23

【stm32f407】外部中断实现按键中断方式

一.外部中断STM32F4的每个IO都可以作为外部中断的中断输入口,这点也是STM32F4的强大之处。STM32F407的中断控制器支持22个外部中断/事件请求。每个中断设有状态位,每个中断/事件都有独立的触发和屏蔽设置。STM32F407的22个外部中断为:EXTI线0~15:对应外部IO口的输入中断。EXTI线16:连接到PVD输出。EXTI线17:连接到RTC闹钟事件。EXTI线18:连接到USB OTG FS唤醒事件。EXTI线19:连接到以太网唤醒事件。EXTI线20:连接到USB OTG HS(在FS中配置)唤醒事件。EXTI线21:连接到RTC入侵和时间戳事件。EXTI线22:连接到RTC唤醒事件。从上面可以看出
发表于 2018-07-20 21:14:56

STM32F103的SysTick使用方法

写下来,方便以后用。void SysTick_Configuration(void){  /* Setup SysTick Timer for 10 msec interrupts  */  if (SysTick_Config(SystemCoreClock / 100))                //SysTick配置函数  {     /* Capture error */ 
发表于 2018-07-20 21:06:43

STM32F407ZGT6使用Systic定时器实现延时

------------------------------------------------------------*//* Private macro -------------------------------------------------------------*//* Private variables ---------------------------------------------------------*/  u8 per_us; //每1us定时器节拍u32 per_ms; //每1ms节拍,注意168MHz下值为168000,需要32位,移植自STM32F0,此处谨慎   /* Private function prototypes
发表于 2018-07-20 20:21:48

STM32F072在8M下的软件延时

    使用定时器产生的延时精度确实是高,但是也相对麻烦,软件延时虽然精度不高,但也相对简单,使用方便,在精度要求不高的情况的可以使用。                使用的是STM32F032 Nucleo开发板,为内部8M晶振。    以下延时函数用示波器测得,精度小于1us。//STM32F072RB Nucleo//在内部晶振为8M的情况下 void delay3us()//3us{ int i; for(i=0;i<1;i++);} void delay10us()//10us
发表于 2018-07-20 20:21:10

Stm32f01x_SysTick定时器_延时功能

;stm32f10x.h>#include <sys.h>//配置systick 寄存器void SysTick_Configuration(void) { SysTick->VAL = 0;  SysTick->LOAD = (72000000/8000000)*1000;//´ú±íÿ¸ömsÐèÒªµÄ9000¸ösystickʱÖÓÊý SysTick->CTRL |= 0x06;  } //中断处理函数void SysTick_Handler(void) //???? { extern unsigned
发表于 2018-07-20 20:01:49

小广播

何立民专栏

单片机及嵌入式宝典

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

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