STM32-HAL-SPI-读写W25Q128FV-JEDEC ID(1)
文章目录
- 一、SPI串行通信协议
- 1.1 SPI通信协议简介
- 1.2 SPI工作原理
- 1.3 SPI特性
- 二、W25Q128FV芯片介绍
- 2.1 芯片基本参数介绍
- 2.2 芯片管脚介绍
- 2.3 技术手册等更多信息
- 三、开发板的板载Flash的连接电路
- 四、测试准备
- 五、初始化片上外设SPI1
- 5.1 初始化SPI1
- 5.2 设置片选引脚PB14
- 5.3 配置串口打印模式
- 5.4 设置生成Keil- MDK代码文件
- 六、读写芯片JEDEC ID
- 6.1 芯片技术手册和读JEDEC ID流程
- 6.2 编写读芯片JEDEC ID代码
一、SPI串行通信协议
1.1 SPI通信协议简介
SPI是串行外设接口,是Motorola首先在其MC68HCxx系列处理器上定义的。SPI是一种高速的、全双工,同步的通信总线,并且在芯片的管教上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便。
1.2 SPI工作原理
SPI的通信原理很简单,它以主从的方式工作,这种模式通常有一个主设备和一个或者多个从设备,至少需要4根线,事实上3根也可以(片选信号可以直接接地,默认选中)。SPI的4根线是MOSI主设备输出从设备输入),MISO主设备输入从设备输出),CK(时钟信号),CS(片选信号,低电平有效)。
1.3 SPI特性
- 三线全双工同步传输
- 8位或16位传输帧格式选择
- 主或从操作
- 8个主模式波特率预分频系数
- 可编程的时钟极性和相位
- 可编程的数据顺序,MSB在前或者LSB在前
- 可触发的中断的专用发送和接收标志
- SPI总线忙状态标志
- 支持DMA功能的1字节发送和接收缓冲器,产生发送和接收请求
二、W25Q128FV芯片介绍
2.1 芯片基本参数介绍
W25QXX系列存储芯片是基于SPI接口的串行Flash存储器,主要有W25Q64、W25Q128等。芯片支持工作电压在2.7~3.6V之间,在正常工作时电流小于5mA,掉电时低于1uA。最大支持104MHz的编程速度。支持SPI和QSPI读写方式。
- W25Q128每页256个字节。页是最小的可读、可写单元,也是编程和擦除的最小单位。
- W25Q128的块大小为64KB。块是由多个页组成的一个较大的存储单元,每个块通常包含256个页面。
- 如果需要更改或者擦除某个页、块中的某个数据,那么就要将整个页或者块全部写入或者擦除。
- W25Q128的扇区大小为4KB。扇区是块的子单元,每个块包含16个扇区。更改或者擦除一个扇区的数据不会影响其他的扇区的数据。
- 字节是最小的可寻址单元,一个字节是由8个二进制位组成,可以存储一个字符或者数字。
2.2 芯片管脚介绍
- 芯片管脚图
- 管脚的名称
管脚编号 | 管脚名称 | 功能描述 |
---|---|---|
1 | /CS | 片选输入,为低电平时选中,高电平时未选中 |
2 | DO(IO1) | 数据输出(数据输入输出1) |
3 | /WP(IO2) | 写保护输入(数据输入输出2),低电平写保护 |
4 | GND | 地 |
5 | DI(IO0) | 输入输入(数据输入输出0) |
6 | CLK | 串行时钟 |
7 | /HOLD(IO3) | 数据保持(数据输入输出3)低电平有效 |
8 | VCC | 电源正 |
- 不同的SPI模式的引脚作用
标准SPI模式下管脚功能 | CS | DI | DP | WP | HOLD |
---|---|---|---|---|---|
双倍SPI模式下管脚功能 | CS | IO0 | IO1 | WP | HOLD |
四倍SPI模式下管脚功能 | CS | IO0 | IO1 | IO2 | IO3 |
2.3 技术手册等更多信息
点击访问官网
三、开发板的板载Flash的连接电路
1、从电路图中可以看出,芯片的供电电压为3.3V
2、芯片的数据线为4线,接在SPI1
总线上
3、芯片读写使能用的是软件片选
- 芯片和MCU引脚对应表
SPI1_SCK | 时钟线 PB3 |
---|---|
F_CS | 片选(低电平选中)PB14 |
SPI1_MISO | 主机输入从机输出 PB4 |
SPI1_MOSI | 主机输出从机输入PB5 |
四、测试准备
- 基于
STM32F407ZET6
的正点原子开发板(Flash芯片在左上角W25Q128FV
)
- 安装
windows
系统并安装Cubemx
和Keil MDK
的电脑
五、初始化片上外设SPI1
由于硬件原因需要修改成对应硬件的引脚
5.1 初始化SPI1
初始化为全双工模式(因为要进行读写操作)
直接无视软件自动配置的引脚,手动设置硬件对应的引脚为
SPI1
对应的引脚
- 时钟源设置为外部高速时钟
【重要】
查看开发板的板载晶振的频率(根据自己的开发板的晶振频率设置),因此设置输入的时钟的频率为8Hz,经过分频后最后设置频率为最大168MHz
- 时钟树设置,经过分频、倍频后
- 针对
SPI1
总线进行参数设置
- 配置参数说明
Mode | Full-Duplex Mater 全双工模式主模式 |
---|---|
Frame Format | Motorola(摩托罗拉) |
Data Size | 8 Bit( 查看芯片的技术手册可得) |
First Bit | 高位在前:MSB First ( 查看芯片的技术手册可得) |
Prescaler(For BaudRate) | 可设置为最高速率:2分频 42.0MBts/s ( 查看芯片的技术手册可得) |
Clock Polarity | 时钟极性为上升沿 : Low ( 查看芯片的技术手册可得) |
Clock Phase | 时钟相位为0 : 1 Edge( 查看芯片的技术手册可得) |
CRC Calucation | 不设置CRC校验:Disable |
NSS Signal Type | 设置软件片选:SoftWare |
MSB | MSB代表“Most Significant Bit”,即最高有效位,是二进制数中权值最高的位,通常位于左侧。在多字节数据传输时,MSB通常是首先传输的字节。 |
---|---|
LSB | LSB代表“Least Significant Bit”,即最低有效位,是二进制数中权值最低的位,通常位于右侧。在多字节数据传输时,LSB通常是最后传输的字节。 |
Clock Polarity和Clock Phase
的具体设置方式需要依照设备和应用场景进行调整的
在本次测试中,由于W25Q128
芯片的读写模式支持Mode 0(0,0)
和Mode3(1,1)
选择了模式0作为读写模式
芯片的数据手册第6.1章节
模式 | CPOL(极性) | CPHA(相位) | 空闲时SCK时钟 | 采样时刻 |
---|---|---|---|---|
模式0 | 0 | 0 | 低电平 | 奇数边沿 |
模式1 | 0 | 1 | 低电平 | 偶数边沿 |
模式2 | 1 | 0 | 高电平 | 奇数边沿 |
模式3 | 1 | 1 | 高电平 | 偶数边沿 |
一般经常用的就是模式0和模式3。经过测试,设置为模式0或者模式3均可进行正确的读写。
5.2 设置片选引脚PB14
5.3 配置串口打印模式
参考以前的配置文章进行设置
5.4 设置生成Keil- MDK代码文件
六、读写芯片JEDEC ID
6.1 芯片技术手册和读JEDEC ID流程
在SPI总线上接收三个字节的数据,分别表示制造商ID、设备类型、容量
芯片的Jedec ID指令
芯片的Jedec ID介绍
- 常见的存储芯片的类型和它的Jedec ID
芯片类型 | Jedec ID |
---|---|
SST25VF016B_ID | 0xBF2541 |
MX25L1606E_ID | 0xC22015 |
W25Q64BV_ID(BV JV FV) | 0xEF4017 |
W25Q128_ID | 0xEF4018 |
通过SPI总线读取W25Q128的JEDEC ID,并将JEDEC ID整合为一个32位的数值。具体流程如下:
- 通过调用
sf_SetCS
函数使能W25Q128芯片的片选信号。 - 将读取
ID命令(0x9F)
放入发送缓冲区g_spiTxBuf
,并将发送缓冲区长度g_spiLen
设置为4(包括一个读取ID命令和3个地址字节)。 - 调用
bsp_spiTransfer
函数发送读取ID命令,并从DO引脚接收3个字节的ID数据,并将接收到的数据存储在g_spiRxBuf
接收缓冲区中。 - 从
g_spiRxBuf
接收缓冲区中读取3个字节的ID数据,并分别存储在id1、id2和id3
变量中。 - 通过调用
sf_SetCS
函数禁用W25Q128芯片的片选信号。 - 将3个字节的ID数据整合成一个32位的数值uiID,其中id1占据高16位,id2占据中8位,id3占据低8位。
- 将整合后的32位ID数值返回。
6.2 编写读芯片JEDEC ID代码
代码来自安富莱电子
[bsp_flash.c]#include "bsp_flash.h"
SFLASH_T g_tSF; //定义结构体/*
*********************************************************************************************************
* 函 数 名: sf_SetCS
* 功能说明: 串行FALSH片选控制函数
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
void sf_SetCS(uint8_t _Level)
{if (_Level == 0){bsp_SpiBusEnter(); SF_CS_0();}else{ SF_CS_1(); bsp_SpiBusExit(); }
}/*
*********************************************************************************************************
* 函 数 名: sf_ReadInfo
* 功能说明: 读取器件ID,并填充器件参数
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
void sf_ReadInfo(void)
{/* 自动识别串行Flash型号 */{g_tSF.ChipID = sf_ReadID(); /* 芯片ID */switch (g_tSF.ChipID){case SST25VF016B_ID:strcpy(g_tSF.ChipName, "SST25VF016B");g_tSF.TotalSize = 2 * 1024 * 1024; /* 总容量 = 2M */g_tSF.SectorSize = 4 * 1024; /* 扇区大小 = 4K */break;case MX25L1606E_ID:strcpy(g_tSF.ChipName, "MX25L1606E");g_tSF.TotalSize = 2 * 1024 * 1024; /* 总容量 = 2M */g_tSF.SectorSize = 4 * 1024; /* 扇区大小 = 4K */break;case W25Q64BV_ID:strcpy(g_tSF.ChipName, "W25Q64");g_tSF.TotalSize = 8 * 1024 * 1024; /* 总容量 = 8M */g_tSF.SectorSize = 4 * 1024; /* 扇区大小 = 4K */break;case W25Q128_ID:strcpy(g_tSF.ChipName, "W25Q128");g_tSF.TotalSize = 16 * 1024 * 1024; /* 总容量 = 8M */g_tSF.SectorSize = 4 * 1024; /* 扇区大小 = 4K */break; default:strcpy(g_tSF.ChipName, "Unknow Flash");g_tSF.TotalSize = 2 * 1024 * 1024;g_tSF.SectorSize = 4 * 1024;break;}}
}/*
*********************************************************************************************************
* 函 数 名: sf_ReadID
* 功能说明: 读取器件ID
* 形 参: 无
* 返 回 值: 32bit的器件ID (最高8bit填0,有效ID位数为24bit)
*********************************************************************************************************
*/
uint32_t sf_ReadID(void)
{uint32_t uiID;uint8_t id1, id2, id3;sf_SetCS(0); /* 使能片选 */g_spiLen = 0;g_spiTxBuf[0] = (CMD_RDID); /* 发送读ID命令 0x9F */g_spiLen = 4;bsp_spiTransfer();id1 = g_spiRxBuf[1]; /* 读ID的第1个字节 */id2 = g_spiRxBuf[2]; /* 读ID的第2个字节 */id3 = g_spiRxBuf[3]; /* 读ID的第3个字节 */sf_SetCS(1); /* 禁能片选 */uiID = ((uint32_t)id1 << 16) | ((uint32_t)id2 << 8) | id3; /*ID整合*/return uiID;
}
[bsp_flash.h]
#ifndef __BSP_FLASH_H_
#define __BSP_FLASH_H_#include "stm32f4xx_hal.h"
#include "main.h"
#include "spi.h"
#include "string.h"#define SF_CS_0() F_CS_GPIO_Port->BSRR = ((uint32_t)F_CS_Pin << 16U)
#define SF_CS_1() F_CS_GPIO_Port->BSRR = F_CS_Pin#define CMD_AAI 0xAD /* AAI 连续编程指令(FOR SST25VF016B) */
#define CMD_DISWR 0x04 /* 禁止写, 退出AAI状态 */
#define CMD_EWRSR 0x50 /* 允许写状态寄存器的命令 */
#define CMD_WRSR 0x01 /* 写状态寄存器命令 */
#define CMD_WREN 0x06 /* 写使能命令 */
#define CMD_READ 0x03 /* 读数据区命令 */
#define CMD_RDSR 0x05 /* 读状态寄存器命令 */
#define CMD_RDID 0x9F /* 读器件ID命令 */
#define CMD_SE 0x20 /* 擦除扇区命令 */
#define CMD_BE 0xC7 /* 批量擦除命令 */
#define DUMMY_BYTE 0xA5 /* 哑命令,可以为任意值,用于读操作 */#define WIP_FLAG 0x01 /* 状态寄存器中的正在编程标志(WIP) */typedef struct
{uint32_t ChipID; /* 芯片ID */char ChipName[16]; /* 芯片型号字符串,主要用于显示 */uint32_t TotalSize; /* 总容量 */uint16_t SectorSize; /* 扇区大小 */
}SFLASH_T;/* 定义串行Flash ID */
enum
{SST25VF016B_ID = 0xBF2541,MX25L1606E_ID = 0xC22015,W25Q64BV_ID = 0xEF4017, /* BV, JV, FV */W25Q128_ID = 0xEF4018
};void bsp_InitSFlash(void);
void sf_ReadInfo(void);
uint32_t sf_ReadID(void);
void sf_SetCS(uint8_t _Level);extern SFLASH_T g_tSF;#endif
[spi.c]
/* USER CODE BEGIN Header */
/********************************************************************************* @file spi.c* @brief This file provides code for the configuration* of the SPI instances.******************************************************************************* @attention** Copyright (c) 2023 STMicroelectronics.* All rights reserved.** This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS.********************************************************************************/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "spi.h"/* USER CODE BEGIN 0 */
enum {TRANSFER_WAIT,TRANSFER_COMPLETE,TRANSFER_ERROR
};uint32_t g_spiLen;
uint8_t g_spi_busy; /* SPI忙状态,0表示不忙,1表示忙 */
__IO uint32_t wTransferState = TRANSFER_WAIT;uint8_t g_spiTxBuf[SPI_BUFFER_SIZE];
uint8_t g_spiRxBuf[SPI_BUFFER_SIZE];/*
*********************************************************************************************************
* 选择DMA,中断或者查询方式
*********************************************************************************************************
*/
//#define USE_SPI_DMA /* DMA方式 */
//#define USE_SPI_INT /* 中断方式 */
#define USE_SPI_POLL /* 查询方式 *//* USER CODE END 0 */SPI_HandleTypeDef hspi1;/* SPI1 init function */
void MX_SPI1_Init(void)
{/* USER CODE BEGIN SPI1_Init 0 *//* USER CODE END SPI1_Init 0 *//* USER CODE BEGIN SPI1_Init 1 *//* USER CODE END SPI1_Init 1 */hspi1.Instance = SPI1;hspi1.Init.Mode = SPI_MODE_MASTER;hspi1.Init.Direction = SPI_DIRECTION_2LINES;hspi1.Init.DataSize = SPI_DATASIZE_8BIT;hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;hspi1.Init.NSS = SPI_NSS_SOFT;hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;hspi1.Init.TIMode = SPI_TIMODE_DISABLE;hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;hspi1.Init.CRCPolynomial = 10;if (HAL_SPI_Init(&hspi1) != HAL_OK){Error_Handler();}/* USER CODE BEGIN SPI1_Init 2 *//* USER CODE END SPI1_Init 2 */}void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle)
{GPIO_InitTypeDef GPIO_InitStruct = {0};if(spiHandle->Instance==SPI1){/* USER CODE BEGIN SPI1_MspInit 0 *//* USER CODE END SPI1_MspInit 0 *//* SPI1 clock enable */__HAL_RCC_SPI1_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();/**SPI1 GPIO ConfigurationPB3 ------> SPI1_SCKPB4 ------> SPI1_MISOPB5 ------> SPI1_MOSI*/GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);/* USER CODE BEGIN SPI1_MspInit 1 *//* USER CODE END SPI1_MspInit 1 */}
}void HAL_SPI_MspDeInit(SPI_HandleTypeDef* spiHandle)
{if(spiHandle->Instance==SPI1){/* USER CODE BEGIN SPI1_MspDeInit 0 *//* USER CODE END SPI1_MspDeInit 0 *//* Peripheral clock disable */__HAL_RCC_SPI1_CLK_DISABLE();/**SPI1 GPIO ConfigurationPB3 ------> SPI1_SCKPB4 ------> SPI1_MISOPB5 ------> SPI1_MOSI*/HAL_GPIO_DeInit(GPIOB, GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5);/* USER CODE BEGIN SPI1_MspDeInit 1 *//* USER CODE END SPI1_MspDeInit 1 */}
}/* USER CODE BEGIN 1 */
/*
*********************************************************************************************************
* 函 数 名: HAL_SPI_TxRxCpltCallback,HAL_SPI_ErrorCallback
* 功能说明: SPI数据传输完成回调和传输错误回调
* 形 参: SPI_HandleTypeDef 类型指针变量
* 返 回 值: 无
*********************************************************************************************************
*/
void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
{wTransferState = TRANSFER_COMPLETE;
}void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi)
{wTransferState = TRANSFER_ERROR;
}/*
*********************************************************************************************************
* 函 数 名: bsp_SpiBusEnter
* 功能说明: 占用SPI总线
* 形 参: 无
* 返 回 值: 0 表示不忙 1表示忙
*********************************************************************************************************
*/
void bsp_SpiBusEnter(void)
{g_spi_busy = 1;
}/*
*********************************************************************************************************
* 函 数 名: bsp_SpiBusExit
* 功能说明: 释放占用的SPI总线
* 形 参: 无
* 返 回 值: 0 表示不忙 1表示忙
*********************************************************************************************************
*/
void bsp_SpiBusExit(void)
{g_spi_busy = 0;
}/*
*********************************************************************************************************
* 函 数 名: bsp_SpiBusBusy
* 功能说明: 判断SPI总线忙,方法是检测其他SPI芯片的片选信号是否为1
* 形 参: 无
* 返 回 值: 0 表示不忙 1表示忙
*********************************************************************************************************
*/
uint8_t bsp_SpiBusBusy(void)
{return g_spi_busy;
}/*
*********************************************************************************************************
* 函 数 名: bsp_spiTransfer
* 功能说明: 启动数据传输
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
void bsp_spiTransfer(void)
{if (g_spiLen > SPI_BUFFER_SIZE){return;}/* DMA方式传输 */
#ifdef USE_SPI_DMAwTransferState = TRANSFER_WAIT;if(HAL_SPI_TransmitReceive_DMA(&hspi, (uint8_t*)g_spiTxBuf, (uint8_t *)g_spiRxBuf, g_spiLen) != HAL_OK) {Error_Handler();}while (wTransferState == TRANSFER_WAIT){;}
#endif/* 中断方式传输 */
#ifdef USE_SPI_INTwTransferState = TRANSFER_WAIT;if(HAL_SPI_TransmitReceive_IT(&hspi, (uint8_t*)g_spiTxBuf, (uint8_t *)g_spiRxBuf, g_spiLen) != HAL_OK) {Error_Handler();}while (wTransferState == TRANSFER_WAIT){;}
#endif/* 查询方式传输 */
#ifdef USE_SPI_POLLif(HAL_SPI_TransmitReceive(&hspi1, (uint8_t*)g_spiTxBuf, (uint8_t *)g_spiRxBuf, g_spiLen, 1000000) != HAL_OK) {Error_Handler();}
#endif
}/* USER CODE END 1 */
[spi.h]
/* USER CODE BEGIN Header */
/********************************************************************************* @file spi.h* @brief This file contains all the function prototypes for* the spi.c file******************************************************************************* @attention** Copyright (c) 2023 STMicroelectronics.* All rights reserved.** This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS.********************************************************************************/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __SPI_H__
#define __SPI_H__#ifdef __cplusplus
extern "C" {#endif/* Includes ------------------------------------------------------------------*/
#include "main.h"/* USER CODE BEGIN Includes */
#define SPI_BUFFER_SIZE (4 * 1024)
extern uint8_t g_spiTxBuf[SPI_BUFFER_SIZE];
extern uint8_t g_spiRxBuf[SPI_BUFFER_SIZE];
extern uint32_t g_spiLen;
extern uint8_t g_spi_busy;/* USER CODE END Includes */extern SPI_HandleTypeDef hspi1;/* USER CODE BEGIN Private defines *//* USER CODE END Private defines */void MX_SPI1_Init(void);/* USER CODE BEGIN Prototypes */
void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi);
void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi);
void bsp_SpiBusEnter(void);
void bsp_SpiBusExit(void);
uint8_t bsp_SpiBusBusy(void);
void bsp_spiTransfer(void);/* USER CODE END Prototypes */#ifdef __cplusplus
}
#endif#endif /* __SPI_H__ */
[main.c]/* USER CODE BEGIN Includes */
#include "stdio.h"
#include "bsp_flash.h"
/* USER CODE END Includes *//* USER CODE BEGIN 2 */
sf_ReadInfo();//读取芯片的ID
/* 检测串行Flash OK */
printf("检测到串行Flash, ID = %08X, 型号: %s \r\n", g_tSF.ChipID , g_tSF.ChipName);
printf(" 容量 : %dM字节, 扇区大小 : %d字节\r\n", g_tSF.TotalSize/(1024*1024), g_tSF.SectorSize);
/* USER CODE END 2 */[result]检测到串行Flash, ID = 00EF4018, 型号: W25Q128
容量 : 16M字节, 扇区大小 : 4096字节
STM32-HAL-SPI-读写W25Q128FV-JEDEC ID(1)相关推荐
- STM32利用SPI读写SD卡的程序详解
STM32利用SPI读写SD卡的一些程序详解 关于SD卡的基础知识这里不做过多陈述,如果有对这方面感兴趣的朋友可以直接百度一下,有很多讲SD卡的文章,这里主要是针对SD卡的读写程序实现做一些详细说明. ...
- stm32中spi可以随便接吗_STM32的SPI模式读写FLASH芯片全面讲解
例程完整代码: SPI协议简介 SPI协议,即串行外围设备接口,是一种告诉全双工的通信总线,它被广泛地使用在ADC,LCD等设备与MCU间通信的场合. SPI信号线 SPI包含4条总线,分别为SS,S ...
- STM32的SPI模式读写FLASH芯片全面讲解
SPI协议简介 SPI协议,即串行外围设备接口,是一种告诉全双工的通信总线,它被广泛地使用在ADC,LCD等设备与MCU间通信的场合. SPI信号线 SPI包含4条总线,分别为SS,SCK,MOSI, ...
- STM32笔记(十二)---SPI读写FLASH
SPI读写FLASH 文章目录 SPI读写FLASH 一.SPI协议简介 1.1 SPI 物理层 1.2 协议层 1.2.1 SPI 基本通讯过程 1.2.2 通讯的起始和停止信号 1.2.3 数据有 ...
- STM32 SPI读写FLASH
文章目录 一.SPI协议 1.物理层 2.协议层 总体讲解 具体讲解 二.STM32 SPI外设 1.通讯引脚 2.时钟控制逻辑 3.数据控制 4.整体控制逻辑 三.通信过程 四.固件库编程 1.结构 ...
- [学习笔记]STM32F1硬件SPI读写W25Qx(寄存器、标准库、HAL库)
目录 10. 硬件SPI读写W25Qx 0. 博主调侃: 1. 实验内容及步骤: 2. 硬件说明 3. 步骤详细讲解 3.1 RCC 3.2 配置GPIO 3.3 硬件SPI配置 3.4 发送和接收过 ...
- STM32学习笔记之硬件SPI读写与极性设置
废话不多说讲重点!!! [软件中如何设置SPI的极性和相位] SPI分主设备和从设备,两者通过SPI协议通讯. 而设置SPI的模式,是从设备的模式,决定了主设备的模式. 所以要先去搞懂从设备的SP ...
- 《STM32从零开始学习历程》——SPI读写FLASH
<STM32从零开始学习历程>@EnzoReventon SPI读写FLASH 相关链接: SPI物理层及FLASH芯片介绍 SPI协议层 SPI特性及架构 参考资料: [野火EmbedF ...
- stm32 SPI读写储存卡(MicroSD TF卡)
stm32 SPI读写储存卡(MicroSD TF卡) 简述 操作分析及实现 0.整个流程 1.上电以后储存卡的初始化 2.如何进行读写 3.下面是具体的过程 博客原址:http://www.code ...
- [学习笔记]STM32F1软件SPI读写W25Qx(寄存器、标准库、HAL库)
目录 9. 软件SPI读写W25Qx 0. 博主调侃: 1. 实验内容及步骤: 2. 硬件说明 3. 步骤详细讲解 3.1 配置GPIO 3.2 软件SPI读写Byte(模式0或模式3) 3.3 读取 ...
最新文章
- 轻松破解NewzCrawler时间限制
- Thinkpad SL400 issue
- The Singleton of Design Pattern单态模式
- SpringBoot - 统一格式封装及高阶全局异常处理
- 简单java socket_基于Java Socket实现一个简易在线聊天功能(一)
- 20应用统计考研复试要点(part34)--简答题
- Linux 环境下 jdk1.8 maven3.2.3 Git2.8.0 安装脚本
- junit规则_JUnit规则
- python里面的函数
- 2018生活消费趋势:越来越多95后开始泡枸杞
- pdftk — PDF万用命令行工具
- Debug学习资源汇总
- 如何将两个php超链接,php超链接跳转
- 重走JAVA之路(四):ThreadLocal源码解析
- UVA - 10129 Play on Words(欧拉回路)
- 个人技术博客的选择:CSDN、博客园、简书、知乎专栏、Github、新浪、个人建站等?
- 初识C语言及开始跨考计算机的心路历程
- 弱网条件下基于阻抗小扰动稳定性分析,小信号模型,阻抗扫描(电容电流反馈有源阻尼),单逆变器SRF-PLL
- 静态网站和动态网站的区别
- 俞敏洪:度过有意义的生命