0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

STM32F10x_SPI (硬件接口 + 软件模拟)读写Flash(25Q16)

黄工的嵌入式技术圈 来源:黄工的嵌入式技术圈 2020-03-25 13:59 次阅读

Ⅰ、写在前面

SPI(Serial Perripheral Interface)串行外设通信接口,主要实现设备(主从)之间的通信硬件上由CS、SCK、MISO、MOSI四根通信线连接而成。关于SPI更多介绍不再详细描述,本文主要以STM32F103为主机、W25Q16为从机进行SPI通信实验。

本文将提供STM32硬件SPI、软件模拟SPI两实例工程代码供大家参考、掌握两种方式的区别。

STM32硬件SPI:控制简单、运行效率高、使用方便等。

软件模拟SPI:移植性强,只需要简单修改接口,就能在其他MCU芯片(如:51、430等)上使用。

实例实验效果:

两个实例SPI通信控制方式不一样,但实验效果是一样的。

W25Q16设备ID:

上电,读取W25Q16设备ID,并通过串口打印出来;

写数据:

SFLASH_WriteNByte((uint8_t*)"ABCDEF",0, 6); 通过该函数在W25Q16的0地址处 连续写入6字节“ABCDEF”数据。(测试的时候:第一次下载之后让程序运行一次,即写入W25Q16数据。再将该函数屏蔽、下载。断电重新让程序运行看读出来的数据是否是前面写入的数据)

读数据:

SFLASH_ReadNByte(read_buf,0, 6); 通过该函数从W25Q16的0地址连续读取6字节数据,保存在read_buf里面。(地址、数据及数据长度都可以修改,但读写的地址要相同,读出来的数据才是写入的数据)

关于本文的更多详情请往下看。

Ⅱ、实例工程下载

笔者针对于初学者提供的例程都是去掉了许多不必要的功能,精简了官方的代码,对初学者一看就明白,以简单明了的工程供大家学习。

笔者提供的实例工程都是在板子上经过多次测试并没有问题才上传至360云盘,欢迎下载测试、参照学习。

提供下载的软件工程是基于Keil(MDK-ARM) V5版本、STM32F103ZE芯片,但F1其他型号也适用(适用F1其他型号:关注微信,回复“修改型号”)。

STM32F10x_SPI(硬件接口)读写Flash(25Q16)实例源代码工程:

https://yunpan.cn/c6mfRJWva6AJ2 访问密码 4bc4

STM32F10x_SPI(软件模拟)读写Flash(25Q16)实例源代码工程:

https://yunpan.cn/c6mf6zyzCaMwd 访问密码 cf45

STM32F1资料

https://yunpan.cn/crBUdUGdYKam2 访问密码 ca90

Ⅲ、STM32硬件SPI

STM32所有系列芯片都带有SPI硬件控制器,根据芯片型号不同,SPI数量也不同,有些有一个SPI,有些有3个SPI。STM32的SPI控制器功能也是很强大的,只需要简单的配置就能高效的进行SPI通信。

1.SPI原理


上面是SPI的系统框图,来自STM32F1的参考手册.

A.引脚

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

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

SCK:串口时钟,为通信提供时钟。(作为主设备的输出,从设备的输入)。

NSS:从设备选择。这是一个可选的引脚,用来选择主/从设备。它的功能是用来作为“片选引脚”,让主设备可以单独地与特定从设备通讯,避免数据线上的冲突。

B.缓冲区SPI->DR

发送缓冲区:只要往SPI1->DR写入数据,它自动将存入发送缓冲区,并执行发送操作。这就是高效的一点,而不像模拟SPI,还需要我们控制时钟,控制MOSI引脚输出高低电平。

接收缓冲区:原理和发送缓冲区差不多,只是这个是接收数据。接收满了,才通知我们需要去读取数据。

C.波特率发生器

STM32的硬件SPI还可以通过配置来控制通信的速度。

2.SPI引脚


该函数位于spi.c文件下面;

使用的SPI需与引脚对应,CS片选信号我们这里是通过普通IO来控制的,若不同请在spi.h里面修改为你开发板上的引脚。

3.SPI配置


该函数位于spi.c文件下面;

该函数是文章的重要一项,主要是对硬件SPI进行的一些初始化配置。

SPI为主模式,时钟线平时为高,上升沿采集数据,8位数据格式,软件控制片选,数据高位在前。

1.传输方向:SPI_Direction =SPI_Direction_2Lines_FullDuplex;

总共有四个方式:

两线全双工:SPI_Direction_2Lines_FullDuplex

两线只接收:SPI_Direction_2Lines_RxOnly

单线只接收:SPI_Direction_1Line_Rx

单线只发送:SPI_Direction_1Line_Tx

2.模式:SPI_Mode = SPI_Mode_Master;

总共有两种模式:

主机模式:SPI_Mode_Master

从机模式:SPI_Mode_Slave

3.数据:SPI_DataSize = SPI_DataSize_8b;

8位数据长度:SPI_DataSize_8b

16位数据长度:SPI_DataSize_16b

4.时钟极性:SPI_CPOL = SPI_CPOL_High;

也就是我们平时不操作时,时钟的电平。

低电平:SPI_CPOL_Low

高电平:SPI_CPOL_High

5.时钟相位:SPI_CPHA = SPI_CPHA_2Edge;

也就是我们需要等多少个“时钟”操作通信口MOSI、MISO。

1个时钟:SPI_CPHA_1Edge

2个时钟:SPI_CPHA_2Edge

6.片选信号:SPI_NSS = SPI_NSS_Soft;

也就是我们如果控制NSS片选引脚;

软件控制:SPI_NSS_Soft

硬件控制:SPI_NSS_Hard

7.波特率(时钟)分频:SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;

也就是我们控制SPI通信的速率,和USART串口的波特率类似。

这里的参数有很多种,请见源代码。

8.第一位传输数据:SPI_FirstBit = SPI_FirstBit_MSB;

在一根通信线上一字节(8Bit)数据分8次传输才能完成,这里是高位先传输,还是低位先传输的意思。

高位:SPI_FirstBit_MSB

低位:SPI_FirstBit_LSB

9.校验:SPI_CRCPolynomial = 7;

校验的数据位长度。

4.SPI读写数据


函数位于spi.c文件下面;

这两个函数就是我们使用到的接口,在上面SPI配置好之后,操作这两个函数就可以控制其引脚读写了。

这两个函数就是我们上面说的“发送缓冲区”和“接收缓冲区”所需要使用到的部分。

这里需要注意:发送和接收数据都是通过SPI->DR寄存器,读、写操作会控制数据的流向。

Ⅳ、软件模拟SPI

从51学习过来的朋友就应该知道,51的资源很少,没有SPI硬件控制器,要想使用SPI通信方式,就需要使用IO口模拟的方式来实现SPI通信。只需要按照通信的时序就能控制其通信。

使用软件模拟SPI通信有优点,也有缺点。

优点:移植很方便,代码只需要简单修改就可以使用在其他芯片上;

缺点:控制IO麻烦,对时序要求高;

1.模拟SPI引脚


该函数位于spi.c文件下面;

这个主要配置模拟SPI引脚。(如果你板子上使用的引脚不同,请修改spi.h文件的定义即可)

2.模拟SPI初始化


该函数位于spi.c文件下面;

这里初始化需要把状态定好,不然第一次操作会有问题。

3.模拟SPI写函数(时序)


该函数位于spi.c文件下面;

这种时序的写法在学习过51的朋友来看再熟悉不过了。

注意:

1、高字节在前,说以上面红色标记的的部分就是将高位先输出,依次移位输出。

2、在时钟的上升沿将数据输出,所以在“时钟-高”之前将数据输出。

4.模拟SPI读函数(时序)


该函数位于spi.c文件下面;

读时序和写时序原理类似,但还是存在差异。

注意:

1、高位先输出来(从机输出),所以,需要将读取的数据依次移向高位。

2、在时钟的下降沿读出数据,所以,我红色标记的部分可以看得出来,是在时钟为低之后才去读取数据。

Ⅴ、修改代码,适应开发板

看见这篇文章,你可能觉得芯片型号(STM32F103ZE)不是你的芯片芯片型号,硬件接口(SPI1)、(USART1)也不是板子上的接口,那怎么办呢,其实很简单,适当修改一下就行。

1.修改芯片型号

该工程适合STM32F1系列的所有芯片,只需要修改一下型号。修改芯片型号,可以看我的另外一篇文章:

如何将工程(修改来)运行在自己开发板上

当然,其他系列(F0、F2、F3、F4等)也可以使用该配置,但需要更换外设库。

2.修改硬件接口

笔者提供的工程源代码,在个人看来整理的还算比较整洁(名称清晰、排版整齐、文件分类明确)、相比很多开发板卖家提供的例程来说,要好的多。所以,看了之后,你应该知道如何修改。

1、LED灯的IO,位于bsp.h下,修改为你的LED灯IO口就行了。

2、USART,本文是使用USART1,如果你使用USART2的话,需要usart.c文件下“USART_GPIO_Configuration”引脚配置、USART_Configuration串口配置、发送接收函数USART1 改为USART2等。

3、SPI接口

这个在上面讲述中都提及了修改,就是修改spi.c和spi.h文件里面的配置。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • FlaSh
    +关注

    关注

    10

    文章

    1621

    浏览量

    147735
  • SPI
    SPI
    +关注

    关注

    17

    文章

    1700

    浏览量

    91291
  • STM32F10x
    +关注

    关注

    1

    文章

    81

    浏览量

    20655
收藏 人收藏

    评论

    相关推荐

    Air780E开发板SPI接口:实现W25Q64读写不是事儿!

    一直有人向我咨询开发板的SPI接口,对W25Q64进行读写操作很难,今天我便做一个详细解析,让你下回觉得这都不是事儿。
    的头像 发表于 11-02 11:56 293次阅读
    Air780E开发板<b class='flag-5'>SPI</b><b class='flag-5'>接口</b>:实现W<b class='flag-5'>25Q</b>64<b class='flag-5'>读写</b>不是事儿!

    STM32CUBEMX(13)--SPI,W25Q128外部Flash移植

    开发板,这里我准备的是NUCLEO-F030R8的开发板: Flash就是淘宝上SPI接口的W25Q128模块。 视频教学 选择芯片型
    发表于 09-30 14:41

    物联网行业中Nor Flash软件设计分享_W25Q128的软件设计方案

    一 概述 W25Q128是一种NOR Flash芯片,掉电后数据不丢失的特点。 W25Q128FV阵列被组织成65,536个可编程页面,每个页面256字节。每次最多可编程256字节。可以以16
    的头像 发表于 09-26 11:20 368次阅读
    物联网行业中Nor <b class='flag-5'>Flash</b>的<b class='flag-5'>软件</b>设计分享_W<b class='flag-5'>25Q</b>128的<b class='flag-5'>软件</b>设计方案

    STM32CUBEMX(10)--Flash读写

    概述 本例程主要讲解如何对芯片自带Flash进行读写,用芯片内部Flash可以对一些需要断电保存的数据进行保存,无需加外部得存储芯片,本例程采用的是STM32F030R8T6,64K大
    发表于 09-10 15:36

    【GD32 MCU 移植教程】9、从 STM32F10x 系列移植到 GD32F30x 系列

    GD32F30x 系列 MCU 是基于 Arm® Cortex®-M4 处理器的 32 位通用微控制器,与 STM32F10x 系列 MCU 保持高度兼容。本文主要从以下三个方面进行介绍:硬件资源
    的头像 发表于 09-07 09:57 501次阅读
    【GD32 MCU 移植教程】9、从 <b class='flag-5'>STM32F10x</b> 系列移植到 GD32<b class='flag-5'>F30x</b> 系列

    ESP32外部flashspi外设冲突怎么解决?

    硬件: ESP32 ,W25Q128 SPI显示器 库:IDF4.0.1 使用hspi挂载了外部16MB的W25Q128,并同时挂载了
    发表于 06-25 06:19

    【GD32F303红枫派开发板使用手册】第二十讲 SPI-SPI NAND FLASH读写实验

    通过本实验主要学习以下内容: •SPI通信协议,参考19.2.1东方红开发板使用手册 •GD32F303 SPI操作方式,参考19.2.2东方红开发板使用手册 •NAND FLASH
    的头像 发表于 06-20 09:50 788次阅读
    【GD32<b class='flag-5'>F</b>303红枫派开发板使用手册】第二十讲 <b class='flag-5'>SPI-SPI</b> NAND <b class='flag-5'>FLASH</b><b class='flag-5'>读写</b>实验

    【GD32H757Z海棠派开发板使用手册】第十一讲 SPI-SPI NOR FLASH读写实验

    通过本实验主要学习以下内容: •SPI简介 •GD32H7 SPI简介 •SPI NOR FLASH——GD25Q128ESIGR简介 •使
    的头像 发表于 06-04 11:42 858次阅读
    【GD32H757Z海棠派开发板使用手册】第十一讲 <b class='flag-5'>SPI-SPI</b> NOR <b class='flag-5'>FLASH</b><b class='flag-5'>读写</b>实验

    【GD32F470紫藤派开发板使用手册】第十一讲 SPI-SPI NOR FLASH读写实验

    通过本实验主要学习以下内容: •SPI简介 •GD32F470 SPI简介 •SPI NOR FLASH——GD
    的头像 发表于 05-17 09:57 1642次阅读
    【GD32<b class='flag-5'>F</b>470紫藤派开发板使用手册】第十一讲 <b class='flag-5'>SPI-SPI</b> NOR <b class='flag-5'>FLASH</b><b class='flag-5'>读写</b>实验

    如何使用SPI的DMA模式读写FLASH

    环境:HAL库 + USB + W25Q64 + Fatfs 硬件stm32f103c8t6 + MX25L64 我使用普通模式,完成在W25Q
    发表于 04-16 07:59

    STM32H7 SPI使用DMA模式,W25Q256数据读写不正确的原因?

    主芯片是 STM32H743XSPI-FLASH是 W25Q256,使用HAL库(V1.8)。 如果SPI不使用DMA模式,则 W25Q2
    发表于 04-11 06:34

    STM32F103ZET6将SPI+W25QXX的程序移植后,步进电机均转速转慢的原因?

    本人学机械出身,现遇一问题,打不到突破办法,还请各位大虾相助。 CPU:STM32F103ZET6功能:多个步进电机控制,数据读写,串口收发等 原程序:采取内部FLASH, 现程序:增加
    发表于 04-02 08:30

    关于STM32F103从外设到存储器DMA通道数据格式的问题

    在基于STM32F103开发过程中遇到了一个瓶颈,就是图片取模后的数据放在W25Q64当中,通过硬件SPI+DMA的方式直接将数据发送给FSMC,FSMC被用来驱动
    发表于 03-07 07:11

    STM32F407ZGT6 spi flash片选引脚无法被拉低的原因?怎么解决?

    我用的芯片是STM32F407ZGT6,RTThread版本5.0.2,spi flash挂载在spi1总线,设备号是spi10 int
    发表于 02-20 07:13

    stm32f103 flash模拟eeprom

    STM32F103的Flash存储器可以模拟EEPROM的功能,在本文中我们将详细介绍如何使用STM32F103的Flash存储器来实现E
    的头像 发表于 01-09 11:21 1887次阅读