• 【STM32】SPI初步使用 读写FLASH W25Q64


    硬件连接

    在这里插入图片描述

    (1) SS( Slave Select):从设备选择信号线,常称为片选信号线,每个从设备都有独立的这一条 NSS 信号线,当主机要选择从设备时,把该从设备的 NSS 信号线设置为低电平,该从设备即被选中,即片选有效,接着主机开始与被选中的从设备进行 SPI通讯。所以 SPI通讯以 NSS 线置低电平为开始信号,以 NSS 线被拉高作为结束信号。

    (2) SCK (Serial Clock):时钟信号线,用于通讯数据同步。它由通讯主机产生,决定了通讯的速率,不同的设备支持的最高时钟频率不一样,如 STM32 的 SPI 时钟频率最大为fpclk/2,两个设备之间通讯时,通讯速率受限于低速设备。

    (3) MOSI (Master Output, Slave Input):主设备输出/从设备输入引脚。

    (4) MISO(Master Input,,Slave Output):主设备输入/从设备输出引脚。

    通信协议

    在这里插入图片描述

    起始信号:NSS 信号线由高变低,是 SPI 通讯的起始信号。
    数据有效性:MOSI 及 MISO 的数据在 SCK 的上升沿期间变化输出,在SCK 的下降沿时被采样。即在 SCK 的下降沿时刻,MOSI 及 MISO 的数据有效,高电平时表示数据“1”,为低电平时表示数据“0”。
    CPOL/CPHA 及通讯模式:总的来说是根据CR寄存器中对CPOL/CPHA的配置来决定总线空闲时 SCK 的时钟状态以及数据采样时刻,一般使用模式0和3
    在这里插入图片描述

    编程要点

    (1) 初始化通讯使用的目标引脚及端口时钟;
    (2) 使能 SPI 外设的时钟;
    (3) 配置 SPI 外设的模式、地址、速率等参数并使能 SPI 外设;
    (4) 编写基本 SPI 按字节收发的函数;
    (5) 编写对 FLASH 擦除及读写操作的的函数;
    (6) 编写测试程序,对读写数据进行校验。

    配置GPIO复用

    //GPIO 配置
    GPIO_InitTypeDef GPIO_InitStructure;
    NSS片选引脚配置为普通GPIO
    MISO MOSI SLK引脚配置为复用推挽输出
    GPIO_Init(FLASH_SPI_MOSI_PORT, &GPIO_InitStructure);
    
    • 1
    • 2
    • 3
    • 4
    • 5

    配置SPI

    SPI_InitTypeDef SPI_InitStructure;
    RCC_APB2PeriphClockCmd (SPI1, ENABLE );
    
    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;
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
    SPI_InitStructure.SPI_CRCPolynomial = 7;
    SPI_Init(FLASH_SPIx, &SPI_InitStructure);
    
    SPI_Cmd(FLASH_SPIx, ENABLE);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    使用SPi 读写FLASH W25Q64

    使用 SPI 发送和接收一个字节的数据

     #define Dummy_Byte  0xFF
    u8 SPI_FLASH_SendByte(u8 byte)
    {
    	SPITimeout = SPIT_FLAG_TIMEOUT;
    	/* 等待发送缓冲区为空,TXE 事件 */
    	//读取SR寄存器 相关位
    	while (SPI_I2S_GetFlagStatus(FLASH_SPIx, SPI_I2S_FLAG_TXE) == RESET)
    	{
    		if ((SPITimeout--) == 0) return SPI_TIMEOUT_UserCallback(0);	
    	}
    	
    	/* 写入数据寄存器,把要写入的数据写入发送缓冲区 */
    	//与大多数写DR寄存器操作一致,写动作会自动清空DR寄存器
    	SPI_I2S_SendData(FLASH_SPIx, byte);
    
    	SPITimeout = SPIT_FLAG_TIMEOUT;
    	/* 等待接收缓冲区非空,RXNE 事件 */
    	while (SPI_I2S_GetFlagStatus(FLASH_SPIx, SPI_I2S_FLAG_RXNE) == RESET)
    	{
    		if ((SPITimeout--) == 0) return SPI_TIMEOUT_UserCallback(1);
    	}
    	/* 读取数据寄存器,获取接收缓冲区数据 */
    	//与大多数读DR寄存器操作一致,读动作会自动清空DR寄存器
    	return SPI_I2S_ReceiveData(FLASH_SPIx);
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    控制Flash的指令

    FLASH 芯片自定义了很多指令,我们通过控制 STM32 利用 SPI 总线向 FLASH 芯片发送指令,FLASH芯片收到后就会执行相应的操作。

  • 相关阅读:
    u盘制成系统盘之后如何让恢复普通盘
    haas506 2.0开发教程 - 阿里云ota - pac 固件升级(仅支持2.2以上版本)
    Leetcode 202 快乐数(HashSet,环形链表思想)
    uboot启动学习笔记三之启动镜像文件分析
    使用Hypothesis生成测试数据
    制作一个简单HTML大学生抗疫感动专题网页(HTML+CSS)
    SpringBoot 项目实战 ~ 11.接口(API)文档(完结啦)
    Java多线程 - 交替打印问题
    NGINX源码之:location
    json文件批量转为txt文件
  • 原文地址:https://blog.csdn.net/apythonlearner/article/details/132604162