目录

一、物理层、协议层

二、stm32的SPI外设

①正点原子SPI接口:(SPI1相同)

②野火SPI接口:(SPI1相同)

三、stm32的SPI固件库

① SPI_Direction

②SPI_Mode

③SPI_DataSize

④SPI_CPOL和SPI_CPHA

⑤SPI_NSS

⑥SPI_BaudRatePrescaler

⑦SPI_FirstBit

⑧SPI_CRCPolynomial

四、代码——SPI初始化

五、代码——读取FLASH的ID

六、代码——擦除操作

七、代码——读写操作

八、代码——例程及存储小数


一、物理层、协议层

CS = 0;选中片选

全双工 

CPHA = 0;奇数边沿采样

CPHA = 1;偶数边沿采样

二、stm32的SPI外设

①正点原子SPI接口:(SPI1不相同)

②野火SPI接口:(SPI1不相同)

三、stm32的SPI固件库

① SPI_Direction

本成员设置SPI的通讯方向,可设置为

双线全双工(SPI_Direction_2Lines_FullDuplex),

双线只接收(SPI_Direction_2Lines_RxOnly),

单线只接收(SPI_Direction_1Line_Rx)、

单线只发送模式(SPI_Direction_1Line_Tx)。

②SPI_Mode

本成员设置SPI工作在主机模式(SPI_Mode_Master)或从机模式(SPI_Mode_Slave  ),

这两个模式的最大区别为SPI的SCK信号线的时序,SCK的时序是由通讯中的主机产生的。若被配置为从机模式,STM32的SPI外设将接受外来的SCK信号。

③SPI_DataSize

本成员可以选择SPI通讯的数据帧大小是为8位(SPI_DataSize_8b)还是16(SPI_DataSize_16b)。

④SPI_CPOL和SPI_CPHA

这两个成员配置SPI的时钟极性CPOL时钟相位CPHA,这两个配置影响到SPI的通讯模式,

时钟极性CPOL成员,可设置为高电平(SPI_CPOL_High)或低电平(SPI_CPOL_Low )。

时钟相位CPHA 则可以设置为SPI_CPHA_1Edge(在SCK的奇数边沿采集数据) 或SPI_CPHA_2Edge (在SCK的偶数边沿采集数据) 。

⑤SPI_NSS

本成员配置NSS引脚的使用模式,可以选择为硬件模式(SPI_NSS_Hard )与软件模式(SPI_NSS_Soft ),在硬件模式中的SPI片选信号由SPI硬件自动产生,而软件模式则需要亲自把相应的GPIO端口拉高或置低产生非片选和片选信号。实际中软件模式应用比较多。

⑥SPI_BaudRatePrescaler

本成员设置波特率分频因子,分频后的时钟即为SPI的SCK信号线的时钟频率。这个成员参数可设置为fpclk的2、4、6、8、16、32、64、128、256分频。

⑦SPI_FirstBit

所有串行的通讯协议都会有MSB先行(高位数据在前)还是LSB先行(低位数据在前)的问题,而STM32的SPI模块可以通过这个结构体成员,对该特性编程控制。

⑧SPI_CRCPolynomial

这是SPI的CRC校验中的多项式,若我们使用CRC校验时,就使用这个成员的参数(多项式),来计算CRC的值。

配置完这些结构体成员后,要调用SPI_Init函数把这些参数写入到寄存器中,实现SPI的初始化,然后调用SPI_Cmd来使能SPI外设。

四、代码——SPI初始化

/* Private typedef -----------------------------------------------------------*/
//#define  sFLASH_ID                       0xEF3015     //W25X16
//#define  sFLASH_ID                       0xEF4015     //W25Q16
//#define  sFLASH_ID                        0XEF4017     //W25Q64
#define  sFLASH_ID                       0XEF4018     //W25Q128//#define SPI_FLASH_PageSize            4096
#define SPI_FLASH_PageSize              256
#define SPI_FLASH_PerWritePageSize      256/* Private define ------------------------------------------------------------*/
/*命令定义-开头*******************************/
#define W25X_WriteEnable              0x06
#define W25X_WriteDisable             0x04
#define W25X_ReadStatusReg          0x05
#define W25X_WriteStatusReg       0x01
#define W25X_ReadData                   0x03
#define W25X_FastReadData             0x0B
#define W25X_FastReadDual             0x3B
#define W25X_PageProgram              0x02
#define W25X_BlockErase               0xD8
#define W25X_SectorErase              0x20
#define W25X_ChipErase                0xC7
#define W25X_PowerDown                0xB9
#define W25X_ReleasePowerDown     0xAB
#define W25X_DeviceID                   0xAB
#define W25X_ManufactDeviceID       0x90
#define W25X_JedecDeviceID          0x9F #define WIP_Flag                  0x01  /* Write In Progress (WIP) flag */
#define Dummy_Byte                0xFF
/*命令定义-结尾*******************************//*SPI接口定义-开头****************************/
#define FLASH_SPI                           SPI1
#define FLASH_SPI_CLK                       RCC_APB2Periph_SPI1
#define FLASH_SPI_CLK_INIT                  RCC_APB2PeriphClockCmd#define FLASH_SPI_SCK_PIN                   GPIO_Pin_3
#define FLASH_SPI_SCK_GPIO_PORT             GPIOB
#define FLASH_SPI_SCK_GPIO_CLK              RCC_AHB1Periph_GPIOB
#define FLASH_SPI_SCK_PINSOURCE             GPIO_PinSource3
#define FLASH_SPI_SCK_AF                    GPIO_AF_SPI1#define FLASH_SPI_MISO_PIN                  GPIO_Pin_4
#define FLASH_SPI_MISO_GPIO_PORT            GPIOB
#define FLASH_SPI_MISO_GPIO_CLK             RCC_AHB1Periph_GPIOB
#define FLASH_SPI_MISO_PINSOURCE            GPIO_PinSource4
#define FLASH_SPI_MISO_AF                   GPIO_AF_SPI1#define FLASH_SPI_MOSI_PIN                  GPIO_Pin_5
#define FLASH_SPI_MOSI_GPIO_PORT            GPIOB
#define FLASH_SPI_MOSI_GPIO_CLK             RCC_AHB1Periph_GPIOB
#define FLASH_SPI_MOSI_PINSOURCE            GPIO_PinSource5
#define FLASH_SPI_MOSI_AF                   GPIO_AF_SPI1#define FLASH_CS_PIN                        GPIO_Pin_6
#define FLASH_CS_GPIO_PORT                  GPIOG
#define FLASH_CS_GPIO_CLK                   RCC_AHB1Periph_GPIOG//软件模拟模式#define SPI_FLASH_CS_LOW()      {FLASH_CS_GPIO_PORT->BSRRH=FLASH_CS_PIN;}
#define SPI_FLASH_CS_HIGH()     {FLASH_CS_GPIO_PORT->BSRRL=FLASH_CS_PIN;}
/*SPI接口定义-结尾****************************/void SPI_FLASH_Init(void)
{SPI_InitTypeDef  SPI_InitStructure;GPIO_InitTypeDef GPIO_InitStructure;/* 使能 FLASH_SPI 及GPIO 时钟 *//*!< SPI_FLASH_SPI_CS_GPIO, SPI_FLASH_SPI_MOSI_GPIO, SPI_FLASH_SPI_MISO_GPIO,SPI_FLASH_SPI_SCK_GPIO 时钟使能 */RCC_AHB1PeriphClockCmd (FLASH_SPI_SCK_GPIO_CLK | FLASH_SPI_MISO_GPIO_CLK|FLASH_SPI_MOSI_GPIO_CLK|FLASH_CS_GPIO_CLK, ENABLE);/*!< SPI_FLASH_SPI 时钟使能 */FLASH_SPI_CLK_INIT(FLASH_SPI_CLK, ENABLE);//设置引脚复用GPIO_PinAFConfig(FLASH_SPI_SCK_GPIO_PORT,FLASH_SPI_SCK_PINSOURCE,FLASH_SPI_SCK_AF); GPIO_PinAFConfig(FLASH_SPI_MISO_GPIO_PORT,FLASH_SPI_MISO_PINSOURCE,FLASH_SPI_MISO_AF); GPIO_PinAFConfig(FLASH_SPI_MOSI_GPIO_PORT,FLASH_SPI_MOSI_PINSOURCE,FLASH_SPI_MOSI_AF); /*!< 配置 SPI_FLASH_SPI 引脚: SCK */GPIO_InitStructure.GPIO_Pin = FLASH_SPI_SCK_PIN;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  GPIO_Init(FLASH_SPI_SCK_GPIO_PORT, &GPIO_InitStructure);/*!< 配置 SPI_FLASH_SPI 引脚: MISO */GPIO_InitStructure.GPIO_Pin = FLASH_SPI_MISO_PIN;GPIO_Init(FLASH_SPI_MISO_GPIO_PORT, &GPIO_InitStructure);/*!< 配置 SPI_FLASH_SPI 引脚: MOSI */GPIO_InitStructure.GPIO_Pin = FLASH_SPI_MOSI_PIN;GPIO_Init(FLASH_SPI_MOSI_GPIO_PORT, &GPIO_InitStructure);  /*!< 配置 SPI_FLASH_SPI 引脚: CS */GPIO_InitStructure.GPIO_Pin = FLASH_CS_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;GPIO_Init(FLASH_CS_GPIO_PORT, &GPIO_InitStructure);/* 停止信号 FLASH: CS引脚高电平*/SPI_FLASH_CS_HIGH();/* FLASH_SPI 模式配置 */// FLASH芯片 支持SPI模式0及模式3,据此设置CPOL CPHASPI_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;SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;SPI_InitStructure.SPI_CRCPolynomial = 7;SPI_Init(FLASH_SPI, &SPI_InitStructure);/* 使能 FLASH_SPI  */SPI_Cmd(FLASH_SPI, ENABLE);
}

五、代码——读取FLASH的ID

spi_flash.c:

 /*** @brief  读取FLASH ID* @param   无* @retval FLASH ID*/
u32 SPI_FLASH_ReadID(void)
{u32 Temp = 0, Temp0 = 0, Temp1 = 0, Temp2 = 0;/* 开始通讯:CS低电平 */SPI_FLASH_CS_LOW();/* 发送JEDEC指令,读取ID */SPI_FLASH_SendByte(W25X_JedecDeviceID);/* 读取一个字节数据 */Temp0 = SPI_FLASH_SendByte(Dummy_Byte);/* 读取一个字节数据 */Temp1 = SPI_FLASH_SendByte(Dummy_Byte);/* 读取一个字节数据 */Temp2 = SPI_FLASH_SendByte(Dummy_Byte);/* 停止通讯:CS高电平 */SPI_FLASH_CS_HIGH();/*把数据组合起来,作为函数的返回值*/Temp = (Temp0 << 16) | (Temp1 << 8) | Temp2;return Temp;
}/*** @brief  读取FLASH Device ID* @param   无* @retval FLASH Device ID*/
u32 SPI_FLASH_ReadDeviceID(void)
{u32 Temp = 0;/* Select the FLASH: Chip Select low */SPI_FLASH_CS_LOW();/* Send "RDID " instruction */SPI_FLASH_SendByte(W25X_DeviceID);SPI_FLASH_SendByte(Dummy_Byte);SPI_FLASH_SendByte(Dummy_Byte);SPI_FLASH_SendByte(Dummy_Byte);/* Read a byte from the FLASH */Temp = SPI_FLASH_SendByte(Dummy_Byte);/* Deselect the FLASH: Chip Select high */SPI_FLASH_CS_HIGH();return Temp;
}

main.c:

/* 16M串行flash W25Q128初始化 */SPI_FLASH_Init();/* 获取 Flash Device ID */DeviceID = SPI_FLASH_ReadDeviceID();Delay( 200 );/* 获取 SPI Flash ID */FlashID = SPI_FLASH_ReadID();printf("\r\nFlashID is 0x%X,  Manufacturer Device ID is 0x%X\r\n", FlashID, DeviceID);

六、代码——擦除操作

/*** @brief  擦除FLASH扇区* @param  SectorAddr:要擦除的扇区地址* @retval 无*/
void SPI_FLASH_SectorErase(u32 SectorAddr)
{/* 发送FLASH写使能命令 */SPI_FLASH_WriteEnable();SPI_FLASH_WaitForWriteEnd();/* 擦除扇区 *//* 选择FLASH: CS低电平 */SPI_FLASH_CS_LOW();/* 发送扇区擦除指令*/SPI_FLASH_SendByte(W25X_SectorErase);/*发送擦除扇区地址的高位*/SPI_FLASH_SendByte((SectorAddr & 0xFF0000) >> 16);/* 发送擦除扇区地址的中位 */SPI_FLASH_SendByte((SectorAddr & 0xFF00) >> 8);/* 发送擦除扇区地址的低位 */SPI_FLASH_SendByte(SectorAddr & 0xFF);/* 停止信号 FLASH: CS 高电平 */SPI_FLASH_CS_HIGH();/* 等待擦除完毕*/SPI_FLASH_WaitForWriteEnd();
}/*** @brief  擦除FLASH扇区,整片擦除* @param  无* @retval 无*/
void SPI_FLASH_BulkErase(void)
{/* 发送FLASH写使能命令 */SPI_FLASH_WriteEnable();/* 整块 Erase *//* 选择FLASH: CS低电平 */SPI_FLASH_CS_LOW();/* 发送整块擦除指令*/SPI_FLASH_SendByte(W25X_ChipErase);/* 停止信号 FLASH: CS 高电平 */SPI_FLASH_CS_HIGH();/* 等待擦除完毕*/SPI_FLASH_WaitForWriteEnd();
}

七、代码——读写操作

八、代码——例程及存储小数

stm32F407------SPI相关推荐

  1. STM32F407 SPI SD卡驱动的验证

    试验原因 网上靠谱的STM32F4的SPI方式SD卡驱动不多. 包括ST官方板子,都不用SPI_SD的驱动方式,而是用SDIO. 如果没有官方资料加持,出问题时真头疼, 相当于一个人在玩. 自己板子上 ...

  2. STM32F407 SPI使用DMA传输16bit数据

    一.DMA SPI外设地址配置 查找 STM32F407 芯片手册,可以看到 SPI1的 DR地址为 0x4001 3000+0x0C,即0x40001300C 配置DMA时,指定SPI1的 外设地址 ...

  3. MPU6500驱动调试笔记(STM32F407+SPI)

    一.问题背景 本来最开始实验室使用MPU6050芯片,采集陀螺仪原始数据做生理信号采集,但算法发现用IIC接口采样率(200hz)达不到要求.故寻找同类型支持SPI协议的芯片去替代,发现了这块MPU6 ...

  4. STM32F407——SPI笔记

    SPI 协议是由摩托罗拉公司提出的通讯协议(Serial Peripheral Interface),即串行外围设备接口,是一种高速全双工的通信总线.它被广泛地使用在 ADC. LCD 等设备与 MC ...

  5. STM32环境下AS5048A14位磁旋转编码器SPI通讯调试记录——我学到的东西、遇到的问题、解决的过程

    ❤ 2019.3.16 事情是这样的. 在很多天以前,老师接了个项目,问我有没有意向,我谨慎的表达了我对新事物的好奇心,对新知识的求知欲,同时又委婉的表达了我的能力有限的实际情况,然后我以为事情就这么 ...

  6. STM32 SPI+DMA 驱动 SRAM LY68L6400SLIT 应用笔记

    关键词:库函数,STM32F407,SPI+DMA ,SPI-DMA,SRAM , LY68L6400SLIT,STM32CubeMX 编 辑:大黄蜂 说明:本笔记记录 基于 STM32F407 + ...

  7. FatFs R0.14 - FF_USE_LFN

    试验原因 产品板子上想改下程序,改之前好好的. 将lwip换到最新版后,在FatFs操作时崩溃. 是调用 f_stat()引起的,在FatFs里面崩了.莫名奇妙- 想单独作个试验,移植最新版的FatF ...

  8. STM32F407控制AD7606 采用HAL库的TIM和SPI

    前言 本文介绍基于STM32F407的AD7606 8通道同步采集控制方式,总体思路:PWM驱动AD7606完成模数转换,AD7606转换完成后其BUSY引脚给出下降沿,STM32捕获外部中断并在中断 ...

  9. 20191027(32)RT-Thread SPI 设备挂载——ADS1256 后续提供具体实现源码(stm32f407)

    目的 1 实现 ADS 1256 采集芯片在 RT-Thread 上的应用 2 了解 SPI 挂载的方式 特别说明 在中断 ISR 中调用 SPI 发送数据相关函数,导致 assertion 报错.F ...

  10. STM32F407通过SPI连接W5100S进行TCP网络通信

    STM32F407通过SPI连接W5100S进行网络通信 一.W5100S硬件 1.HS-NM5100SA模块 模块厂家:成都浩然电子http://www.hschip.com HS-NM5100SA ...

最新文章

  1. oracle中怎么用累计,oracle实现累加,累计百分比计算
  2. 8月下旬国内域名注册商净增量Top10
  3. C语言函数调用的原理
  4. java 线程加载类_java JVM-线程上下类加载器
  5. 前端又省事了,Chrome直接支持lazyload延迟加载
  6. 美法院起诉黑客组织成员 为暴雪服务器攻击者
  7. slider轮播插件的多种写法
  8. 《HTTP权威指南》– 6.代理
  9. Ynote源码涉及功能解剖
  10. android自定义wifi列表,Android开发之Wifi基础教程
  11. 深入浅出数据分析(一)——MySQL+EXCEL+R统计问卷调查
  12. MyEclipse暗黑主题设置
  13. 使用VSCode运行C语言
  14. Excel里怎么设置输入可以打钩的选择框?
  15. ftp上传软件,推荐5款好用的ftp上传软件
  16. 前端快速上手APICloud App开发
  17. 委外采购订单 Subcontract PO
  18. Joy Catalog
  19. 第一章 程序设计和C语言
  20. QT学习之路(一)ubuntu 18.04的Qt Creator在线安装

热门文章

  1. 软考高级 真题 2017年下半年 信息系统项目管理师 案例分析
  2. ld.so.conf.d文件修改命令
  3. 公司裁员前后 你应该怎么做?(结尾有开庭流程)
  4. SAP开发框架系列之 自动单据
  5. 最新ECShop小米商城模板堂商业源码+手机版/整站数据/团购
  6. dz安装教程php,DZ论坛网站安装,设置步骤
  7. Vitamix 5200和BlendTec等三个品牌评测
  8. 从科研切入点到方法论创新、从选刊投稿到写作方法,详细聊聊如何完成一篇学术论文的写作
  9. HDU4507 吉哥系列故事――恨7不成妻 数位DP
  10. Python以太坊智能合约开发指南