使用stm32的模拟spi读取w25q128读取设备ID时一直出现0xFF

由于公司的电路是前辈画的,只能使用模拟spi中如图所示

 

上图是stm32所对应的引脚

 上图是w25q128的引脚

当读取的时候ID号一直是0xffff,在网上查了各种方法都试过了都不行,我这个情况稍微特殊,就是使用了PB3、PB4这两个引脚上电复位默认是作为调试端口使用的。所以得先关闭JTAG功能才行

GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);//关闭pb3、4,pa15的JTAG功能,打开sw调试功能

初始化时,PB3、PB4做普通io需打开复用功能

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);   //pb3,4做普通io需打开复用功能

#include "spi_flash.h"


#define W25Q32_PageSize 256
//指令表
#define W25X_PowerDown 0xb9					//休眠
#define W25X_ReleasePowerDown 0xab	//唤醒

#define W25X_ReadStatusReg 0x05			//读控制和状态寄存器
#define W25X_WriteStatusReg 0x01		//写控制与状态寄存器
#define W25X_WriteEnable 0x06        //写使能    
#define W25X_WriteDisable 0x04       //写禁用
#define W25X_ReadData 0x03					//读数据
#define W25X_PageProgram 0x02					//页编程
#define W25X_ChipErase 0x60					//整页擦除
#define W25X_SectorErase 0x20				//扇区擦除

#define DO_H() (GPIO_SetBits(GPIOB, GPIO_Pin_3))
#define DO_L() (GPIO_ResetBits(GPIOB, GPIO_Pin_3))

#define SCK_H() (GPIO_SetBits(GPIOD, GPIO_Pin_2))
#define SCK_L() (GPIO_ResetBits(GPIOD, GPIO_Pin_2))

#define DI_STATE() (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_5))

#define SPIFLASH_CS_LOW() (GPIO_ResetBits(GPIOB, GPIO_Pin_4))
#define SPIFLASH_CS_HIGH() (GPIO_SetBits(GPIOB, GPIO_Pin_4))


static void SpiWriteByte(uint8_t data)    //写字节
{

	register unsigned char i;

	SCK_L();
	for (i = 0; i < 8; i++)
	{
		delay_us(4);
		// MOSI
		if (data & 0x80)
			DO_H();
		else
			DO_L();
		delay_us(4);
		SCK_H();
		delay_us(4);
		data <<= 1;
		SCK_L();
		delay_us(4);
	}
	//delay_ms(1);
}

static uint8_t SpiReadByte(void)    //读字节
{

	register unsigned char i, out;

	out = 0;

	for (i = 0; i < 8; i++)
	{
		delay_us(4);
		SCK_H();
		out <<= 1;
		delay_us(4);
		if (DI_STATE())
			out |= 0x01;
		delay_us(4);
		SCK_L();
		delay_us(4);
	}
	return out;
}


void SPI_Flash_Init(void)
{

	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOD, ENABLE);	//使能USART1,GPIOA时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);   //pb3,4做普通io需打开复用功能
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(GPIOB, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(GPIOD, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	SPIFLASH_CS_HIGH();
	SPI_Flash_WAKEUP();    //唤醒
//W25QXX_Flash_ReadID(); //读ID
	
}



//读取W25QXX的状态寄存器
//BIT7  6   5   4   3   2   1   0
//SPR   RV  TB BP2 BP1 BP0 WEL BUSY
//SPR:默认0,状态寄存器保护位,配合WP使用
//TB,BP2,BP1,BP0:FLASH区域写保护设置
//WEL:写使能锁定
//BUSY:忙标记位(1,忙;0,空闲)
//默认:0x00
uint8_t W25QXX_Flash_ReadSR(void)     //读控制和状态寄存器
{
	uint8_t byte = 0;
	SPIFLASH_CS_LOW();				  //
	SpiWriteByte(W25X_ReadStatusReg); //
	byte = SpiReadByte();			  //
	SPIFLASH_CS_HIGH();				  //
	return byte;
}

/*static void SPI_FLASH_Write_SR(uint8_t sr)
{
	SPIFLASH_CS_LOW();// 
	SpiWriteByte(W25X_WriteStatusReg);// 
	SpiWriteByte(sr);// 
	SPIFLASH_CS_HIGH();// 
}*/


//写W25QXX状态寄存器
//只有SPR,TB,BP2,BP1,BP0(bit 7,5,4,3,2)可以写!!!
static void SPI_FLASH_Write_Enable(void)
{
	SPIFLASH_CS_LOW();				//
	SpiWriteByte(W25X_WriteEnable); //
	SPIFLASH_CS_HIGH();				//
}

/*static void SPI_FLASH_Write_Disable(void)
{
	SPIFLASH_CS_LOW();// 
	SpiWriteByte(W25X_WriteDisable);//
	SPIFLASH_CS_HIGH();//
}*/


//读取芯片ID
//返回值如下:				   
//0XEF13,表示芯片型号为W25Q80  
//0XEF14,表示芯片型号为W25Q16    
//0XEF15,表示芯片型号为W25Q32  
//0XEF16,表示芯片型号为W25Q64 
//0XEF17,表示芯片型号为W25Q128

uint16_t W25QXX_Flash_ReadID(void)
{
	uint16_t Temp = 0;
	SPIFLASH_CS_LOW();
	SpiWriteByte(0x90);
	SpiWriteByte(0x00);
	SpiWriteByte(0x00);
	SpiWriteByte(0x00);
	
	Temp |= SpiReadByte() << 8;
	Temp |= SpiReadByte();
	SPIFLASH_CS_HIGH();
	return Temp;
}
//读取SPI FLASH  
//在指定地址开始读取指定长度的数据
//pBuffer:数据存储区
//ReadAddr:开始读取的地址(24bit)
//NumByteToRead:要读取的字节数(最大65535)
void SPI_Flash_Read(uint32_t ReadAddr, uint16_t *pBuffer, uint16_t NumByteToRead)
{
	uint16_t i;
	SPIFLASH_CS_LOW();						   //
	SpiWriteByte(W25X_ReadData);			   //
	SpiWriteByte((uint8_t)((ReadAddr) >> 16)); //
	SpiWriteByte((uint8_t)((ReadAddr) >> 8));
	SpiWriteByte((uint8_t)ReadAddr);
	for (i = 0; i < NumByteToRead; i++)
	{
		pBuffer[i] = (SpiReadByte() << 8) & 0xff00; //
		pBuffer[i] |= (SpiReadByte() & 0xff);
	}
	SPIFLASH_CS_HIGH();
}
//SPI在一页(0~65535)内写入少于256个字节的数据
//在指定地址开始写入最大256字节的数据
//pBuffer:数据存储区
//WriteAddr:开始写入的地址(24bit)
//NumByteToWrite:要写入的字节数(最大256),该数不应该超过该页的剩余字节数!!!	
void SPI_Flash_Write_Page(uint16_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite)
{
	uint16_t i;
	SPI_FLASH_Write_Enable();					//SET WEL
	SPIFLASH_CS_LOW();							//
	SpiWriteByte(W25X_PageProgram);				//
	SpiWriteByte((uint8_t)((WriteAddr) >> 16)); //
	SpiWriteByte((uint8_t)((WriteAddr) >> 8));
	SpiWriteByte((uint8_t)WriteAddr);
	for (i = 0; i < NumByteToWrite; i++)
	{
		SpiWriteByte((pBuffer[i] >> 8) & 0xff); //
		SpiWriteByte(pBuffer[i] & 0xff);		//
	}
	SPIFLASH_CS_HIGH();	   //
	SPI_Flash_Wait_Busy(); //
}


//无检验写SPI FLASH 
//必须确保所写的地址范围内的数据全部为0XFF,否则在非0XFF处写入的数据将失败!
//具有自动换页功能 
//在指定地址开始写入指定长度的数据,但是要确保地址不越界!
//pBuffer:数据存储区
//WriteAddr:开始写入的地址(24bit)
//NumByteToWrite:要写入的字节数(最大65535)
//CHECK OK
 void SPI_Flash_Write_NoCheck(uint16_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite)
{
	uint16_t pageremain;
	pageremain = 128 - (WriteAddr % 256) / 2;
	if (NumByteToWrite <= pageremain)
		pageremain = NumByteToWrite; //
	while (1)
	{
		SPI_Flash_Write_Page(pBuffer, WriteAddr, pageremain);
		if (NumByteToWrite == pageremain)
			break; //
		else	   //NumByteToWrite>pageremain
		{
			pBuffer += pageremain;
			WriteAddr += pageremain * 2;

			NumByteToWrite -= pageremain; //
			if (NumByteToWrite > 128)
				pageremain = 128; //
			else
				pageremain = NumByteToWrite; //
		}
	};
}



//写SPI FLASH  
//在指定地址开始写入指定长度的数据
//该函数带擦除操作!
//pBuffer:数据存储区
//WriteAddr:开始写入的地址(24bit)						
//NumByteToWrite:要写入的字节数(最大65535) 
#define SPIFLASH_SEC_SIZE (4096)
#define SPIFLASH_BASE (0)
#define SPIFLASH_SIZE (128 / 8 * 1024 * 1024) //16MBytes
uint16_t SPI_FLASH_BUFFER[SPIFLASH_SEC_SIZE / 2];
void SPI_Flash_Write(uint32_t WriteAddr, uint16_t *pBuffer, uint16_t NumByteToWrite)
{
	uint32_t secpos;
	uint16_t secoff;
	uint16_t secremain;
	uint16_t i;
	uint32_t offaddr;

	

	if (WriteAddr >= SPIFLASH_SIZE)
		return;
	offaddr = WriteAddr - SPIFLASH_BASE;
	secpos = offaddr / SPIFLASH_SEC_SIZE;			//扇区地址 
	secoff = (offaddr % SPIFLASH_SEC_SIZE) / 2;//在扇区内的偏移
	secremain = SPIFLASH_SEC_SIZE / 2 - secoff;//扇区剩余空间大小
	if (NumByteToWrite <= secremain)  //不大于4096个字节
		secremain = NumByteToWrite;
	while (1)
	{
//		IWDG_ReloadCounter();
		SPI_Flash_Read(secpos * SPIFLASH_SEC_SIZE + SPIFLASH_BASE, SPI_FLASH_BUFFER, SPIFLASH_SEC_SIZE / 2);//读出整个扇区的内容
		for (i = 0; i < secremain; i++)//校验数据
		{
			if (SPI_FLASH_BUFFER[secoff + i] != 0XFFFF)
				break;
		}
		if (i < secremain)
		{
			SPI_Flash_Erase_Sector_addr((secpos * SPIFLASH_SEC_SIZE + SPIFLASH_BASE) / SPIFLASH_SEC_SIZE);

			for (i = 0; i < secremain; i++)
			{
				SPI_FLASH_BUFFER[i + secoff] = pBuffer[i];
			}
			SPI_Flash_Write_NoCheck(SPI_FLASH_BUFFER, secpos * SPIFLASH_SEC_SIZE + SPIFLASH_BASE, SPIFLASH_SEC_SIZE / 2);
		}
		else
			SPI_Flash_Write_NoCheck(pBuffer, WriteAddr, secremain);

		if (NumByteToWrite == secremain)
			break;
		else
		{
			secpos++;
			secoff = 0;
			pBuffer += secremain;
			WriteAddr += secremain;
			NumByteToWrite -= secremain;
			if (NumByteToWrite > (SPIFLASH_SEC_SIZE / 2))
				secremain = SPIFLASH_SEC_SIZE / 2;
			else
				secremain = SPIFLASH_SEC_SIZE;
		}
	};
}
//擦除整个芯片		  
//等待时间超长...
void SPI_Flash_Erase_Chip(void)  //擦除芯片
{
	SPI_FLASH_Write_Enable(); //SET WEL
	SPI_Flash_Wait_Busy();
	SPIFLASH_CS_LOW();			  //
	SpiWriteByte(W25X_ChipErase); //
	SPIFLASH_CS_HIGH();			  //
	SPI_Flash_Wait_Busy();		  //
}

//擦除一个扇区
//Dst_Addr:扇区地址 根据实际容量设置
//擦除一个扇区的最少时间:150ms
void SPI_Flash_Erase_Sector_addr(uint32_t Dst_Addr)    //擦除扇区地址
{
	Dst_Addr *= 4096;
	SPI_FLASH_Write_Enable(); //SET WEL
	SPI_Flash_Wait_Busy();
	SPIFLASH_CS_LOW();						   //
	SpiWriteByte(W25X_SectorErase);			   //
	SpiWriteByte((uint8_t)((Dst_Addr) >> 16)); //
	SpiWriteByte((uint8_t)((Dst_Addr) >> 8));
	SpiWriteByte((uint8_t)Dst_Addr);
	SPIFLASH_CS_HIGH();	//
	SPI_Flash_Wait_Busy(); //
}

FLASH_Status SPI_Flash_Erase_Sector(uint32_t Dst_Addr)//擦除扇区
{
	//Dst_Addr *= 4096;
	SPI_FLASH_Write_Enable(); //SET WEL
	SPI_Flash_Wait_Busy();
	SPIFLASH_CS_LOW();						   //
	SpiWriteByte(W25X_SectorErase);			   //
	SpiWriteByte((uint8_t)((Dst_Addr) >> 16)); //
	SpiWriteByte((uint8_t)((Dst_Addr) >> 8));
	SpiWriteByte((uint8_t)Dst_Addr);
	SPIFLASH_CS_HIGH();	   //
	SPI_Flash_Wait_Busy(); //
	return FLASH_COMPLETE;
}
//等待空闲
void SPI_Flash_Wait_Busy(void)
{
	uint16_t ii = 0;
	while ((W25QXX_Flash_ReadSR() & 0x01) == 0x01)
	{
		ii++; //
		if (ii > 10000)
		{
			ii = 10001;
		}
		else
		{
			delay_ms(1);
//			IWDG_ReloadCounter();
		}
	}
}
//进入掉电模式
void SPI_Flash_PowerDown(void)
{
	SPIFLASH_CS_LOW();			  //
	SpiWriteByte(W25X_PowerDown); //
	SPIFLASH_CS_HIGH();			  //
	delay_us(3);				  //
}
//唤醒
void SPI_Flash_WAKEUP(void)
{
	SPIFLASH_CS_LOW();					 //
	SpiWriteByte(W25X_ReleasePowerDown); //
	SPIFLASH_CS_HIGH();					 //
	delay_us(3);						 //
}

详细配置看这位大佬:STM32F10××× PB3,PB4,PA13,PA14,PA15的使用_RZA的博客-CSDN博客

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是使用STM32F4 HAL库进行SPI读写W25Q32的示例代码: ```c #include "stm32f4xx_hal.h" #include <string.h> /* 定义SPI接口 */ SPI_HandleTypeDef hspi1; /* 定义W25Q32的命令码 */ #define W25Q32_CMD_WRITE_ENABLE 0x06 #define W25Q32_CMD_WRITE_DISABLE 0x04 #define W25Q32_CMD_READ_STATUS_REG1 0x05 #define W25Q32_CMD_READ_STATUS_REG2 0x35 #define W25Q32_CMD_READ_DATA 0x03 #define W25Q32_CMD_PAGE_PROGRAM 0x02 #define W25Q32_CMD_ERASE_SECTOR 0x20 #define W25Q32_CMD_ERASE_CHIP 0xC7 /* 定义W25Q32的状态寄存器 */ typedef struct { uint8_t busy:1; uint8_t write_enable_latch:1; uint8_t block_protection:3; uint8_t reserved:1; uint8_t page_size:2; } w25q32_status_reg1_t; /* 初始化SPI接口 */ void MX_SPI1_Init(void) { /* SPI1 parameter configuration */ 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_256; 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(); } } /* 读取W25Q32的状态寄存器1 */ void w25q32_read_status_reg1(w25q32_status_reg1_t *status_reg) { uint8_t cmd = W25Q32_CMD_READ_STATUS_REG1; uint8_t data[2]; HAL_GPIO_WritePin(SPI_CS_GPIO_Port, SPI_CS_Pin, GPIO_PIN_RESET); HAL_SPI_Transmit(&hspi1, &cmd, 1, HAL_MAX_DELAY); HAL_SPI_Receive(&hspi1, data, sizeof(data), HAL_MAX_DELAY); HAL_GPIO_WritePin(SPI_CS_GPIO_Port, SPI_CS_Pin, GPIO_PIN_SET); status_reg->busy = (data[0] & 0x01); status_reg->write_enable_latch = ((data[0] >> 1) & 0x01); status_reg->block_protection = ((data[0] >> 2) & 0x07); status_reg->reserved = ((data[0] >> 5) & 0x01); status_reg->page_size = ((data[1] >> 6) & 0x03); } /* 写入W25Q32的状态寄存器1 */ void w25q32_write_status_reg1(w25q32_status_reg1_t *status_reg) { uint8_t cmd = W25Q32_CMD_WRITE_ENABLE; HAL_GPIO_WritePin(SPI_CS_GPIO_Port, SPI_CS_Pin, GPIO_PIN_RESET); HAL_SPI_Transmit(&hspi1, &cmd, 1, HAL_MAX_DELAY); HAL_GPIO_WritePin(SPI_CS_GPIO_Port, SPI_CS_Pin, GPIO_PIN_SET); cmd = W25Q32_CMD_PAGE_PROGRAM; uint8_t data[2] = {0}; data[0] |= (status_reg->busy & 0x01); data[0] |= (status_reg->write_enable_latch & 0x01) << 1; data[0] |= (status_reg->block_protection & 0x07) << 2; data[0] |= (status_reg->reserved & 0x01) << 5; data[1] |= (status_reg->page_size & 0x03) << 6; HAL_GPIO_WritePin(SPI_CS_GPIO_Port, SPI_CS_Pin, GPIO_PIN_RESET); HAL_SPI_Transmit(&hspi1, &cmd, 1, HAL_MAX_DELAY); HAL_SPI_Transmit(&hspi1, data, sizeof(data), HAL_MAX_DELAY); HAL_GPIO_WritePin(SPI_CS_GPIO_Port, SPI_CS_Pin, GPIO_PIN_SET); } /* 写入W25Q32的一页数据 */ void w25q32_write_page(uint32_t addr, uint8_t *data, uint32_t len) { uint8_t cmd = W25Q32_CMD_WRITE_ENABLE; HAL_GPIO_WritePin(SPI_CS_GPIO_Port, SPI_CS_Pin, GPIO_PIN_RESET); HAL_SPI_Transmit(&hspi1, &cmd, 1, HAL_MAX_DELAY); HAL_GPIO_WritePin(SPI_CS_GPIO_Port, SPI_CS_Pin, GPIO_PIN_SET); cmd = W25Q32_CMD_PAGE_PROGRAM; uint8_t addr_buf[3]; addr_buf[0] = (addr >> 16) & 0xFF; addr_buf[1] = (addr >> 8) & 0xFF; addr_buf[2] = addr & 0xFF; HAL_GPIO_WritePin(SPI_CS_GPIO_Port, SPI_CS_Pin, GPIO_PIN_RESET); HAL_SPI_Transmit(&hspi1, &cmd, 1, HAL_MAX_DELAY); HAL_SPI_Transmit(&hspi1, addr_buf, sizeof(addr_buf), HAL_MAX_DELAY); HAL_SPI_Transmit(&hspi1, data, len, HAL_MAX_DELAY); HAL_GPIO_WritePin(SPI_CS_GPIO_Port, SPI_CS_Pin, GPIO_PIN_SET); } /* 读取W25Q32的一页数据 */ void w25q32_read_page(uint32_t addr, uint8_t *data, uint32_t len) { uint8_t cmd = W25Q32_CMD_READ_DATA; uint8_t addr_buf[3]; addr_buf[0] = (addr >> 16) & 0xFF; addr_buf[1] = (addr >> 8) & 0xFF; addr_buf[2] = addr & 0xFF; HAL_GPIO_WritePin(SPI_CS_GPIO_Port, SPI_CS_Pin, GPIO_PIN_RESET); HAL_SPI_Transmit(&hspi1, &cmd, 1, HAL_MAX_DELAY); HAL_SPI_Transmit(&hspi1, addr_buf, sizeof(addr_buf), HAL_MAX_DELAY); HAL_SPI_Receive(&hspi1, data, len, HAL_MAX_DELAY); HAL_GPIO_WritePin(SPI_CS_GPIO_Port, SPI_CS_Pin, GPIO_PIN_SET); } /* 擦除W25Q32的一个扇区 */ void w25q32_erase_sector(uint32_t addr) { uint8_t cmd = W25Q32_CMD_WRITE_ENABLE; HAL_GPIO_WritePin(SPI_CS_GPIO_Port, SPI_CS_Pin, GPIO_PIN_RESET); HAL_SPI_Transmit(&hspi1, &cmd, 1, HAL_MAX_DELAY); HAL_GPIO_WritePin(SPI_CS_GPIO_Port, SPI_CS_Pin, GPIO_PIN_SET); cmd = W25Q32_CMD_ERASE_SECTOR; uint8_t addr_buf[3]; addr_buf[0] = (addr >> 16) & 0xFF; addr_buf[1] = (addr >> 8) & 0xFF; addr_buf[2] = addr & 0xFF; HAL_GPIO_WritePin(SPI_CS_GPIO_Port, SPI_CS_Pin, GPIO_PIN_RESET); HAL_SPI_Transmit(&hspi1, &cmd, 1, HAL_MAX_DELAY); HAL_SPI_Transmit(&hspi1, addr_buf, sizeof(addr_buf), HAL_MAX_DELAY); HAL_GPIO_WritePin(SPI_CS_GPIO_Port, SPI_CS_Pin, GPIO_PIN_SET); } /* 擦除W25Q32的整个芯片 */ void w25q32_erase_chip(void) { uint8_t cmd = W25Q32_CMD_WRITE_ENABLE; HAL_GPIO_WritePin(SPI_CS_GPIO_Port, SPI_CS_Pin, GPIO_PIN_RESET); HAL_SPI_Transmit(&hspi1, &cmd, 1, HAL_MAX_DELAY); HAL_GPIO_WritePin(SPI_CS_GPIO_Port, SPI_CS_Pin, GPIO_PIN_SET); cmd = W25Q32_CMD_ERASE_CHIP; HAL_GPIO_WritePin(SPI_CS_GPIO_Port, SPI_CS_Pin, GPIO_PIN_RESET); HAL_SPI_Transmit(&hspi1, &cmd, 1, HAL_MAX_DELAY); HAL_GPIO_WritePin(SPI_CS_GPIO_Port, SPI_CS_Pin, GPIO_PIN_SET); } int main(void) { /* 初始化HAL库 */ HAL_Init(); /* 初始化SPI接口 */ MX_SPI1_Init(); /* 定义状态寄存器并读取 */ w25q32_status_reg1_t status_reg; w25q32_read_status_reg1(&status_reg); /* 写入一页数据 */ uint8_t data[256]; memset(data, 0xFF, sizeof(data)); w25q32_write_page(0x000000, data, sizeof(data)); /* 读取一页数据 */ uint8_t read_data[256]; w25q32_read_page(0x000000, read_data, sizeof(read_data)); /* 擦除一个扇区 */ w25q32_erase_sector(0x000000); /* 擦除整个芯片 */ w25q32_erase_chip(); while (1) { } } ``` 需要注意的是,上述代码中的W25Q32的命令码和状态寄存器的定义仅适用于W25Q32型号的Flash芯片,如果需要使用其他型号的Flash芯片,需要根据数据手册自行修改。同,还需要根据实际硬件连接情况修改SPI接口的初始化代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值