STM32F103ZET CubeMX W25Q64不完全操作

在cubemx下操作flash

使用最小系统板,最小系统板的flash为SPI2,具体管脚对应如下:
PB15–>SPI2_MOSI
PB14–>SPI2_MISO
PB13–>SPI2_SCK
PB12–>GPIO_Output(片选)
在cube中设置SPI2模式为全双工模式,禁止硬件NSS片选,如果使用NSS片选可能会出现问题(没有详细试验过)。SPI速率采用18.0MBits/s,SPI设置为模式0,模式3也行。
SPI管脚配置
在这里插入图片描述
在这里插入图片描述
至此,对SPI的配置完成。

读取厂家及ID信息

首先对于W25Q64的操作可以从时序图入手,以对Manufacturer / Device ID的操作为例。
在这里插入图片描述

由上图可知,要读取设备信息先要在CS为低电平期间向flash通过IO0发送指令0x90,然后发送24bits地址0x00,在时钟不间断的情况下IO1返回Manufacturer / Device ID。

void W25Qx_Read_ID(uint16_t *ID)
{
   
	uint8_t idt[2];	
	uint8_t cmd[4] = {
   READ_ID_CMD,0x00,0x00,0x00};	
	W25Qx_Enable();
	/* Send the read ID command */
	HAL_SPI_Transmit(&hspi2, cmd, 4, W25QXXXX_TIMEOUT_VALUE);	
	/* Reception of the data */
	HAL_SPI_Receive(&hspi2,idt, 2, W25QXXXX_TIMEOUT_VALUE);	
	*ID = (idt[0] << 8) + idt[1]; 	
	W25Qx_Disable();	
}

对于读写等操作类似。

具体编程思路

flash在读写等操作时可能需要较长时间才能完成,在操作进行期间,设备处于忙的状态,该状态可以通过对状态寄存器中位的读取进行判断。当设备忙时,等待,超出等待时间,拉高CS,结束操作。

	/* Wait the end of Flash writing */
	while(W25Qx_GetStatus() == W25Qx_BUSY)
	{
   
		/* Check for the Timeout */
    if((get_tick() - tickstart) > W25QXXXX_TIMEOUT_VALUE)
    {
           
			return W25Qx_TIMEOUT;
    }
	  delay(1);
	}	
	return W25Qx_OK;

读操作

在这里插入图片描述
和读ID一样,先发送指令,再发送地址,接着返回数据,不同的是,只要CS一直处于低电平期间,只要时钟一直有,则数据会一直往下读出。

uint8_t W25Qx_Read(uint8_t* pData, uint32_t ReadAddr, uint32_t Size)
{
   
	uint8_t cmd[4];
	/* Configure the command */
	cmd[0] = READ_CMD;
	cmd[1] = (uint8_t)(ReadAddr >> 16);
	cmd[2] = (uint8_t)(ReadAddr >> 8);
	cmd[3] = (uint8_t)(ReadAddr);	
	W25Qx_Enable();
	/* Send the read ID command */
	HAL_SPI_Transmit(&hspi2, cmd, 4, W25QXXXX_TIMEOUT_VALUE);	
	/* Reception of the data */
	if (HAL_SPI_Receive(&hspi2, pData,Size,W25QXXXX_TIMEOUT_VALUE) != HAL_OK)
  {
   
    return W25Qx_ERROR;
  }
	W25Qx_Disable();
	return W25Qx_OK;
}

写操作

在写操作开始之前先要写入write enable指令,然后再开始写。首先需要根据要写的起始地址判断该地址处于哪一个page、sector和block。然后再根据要写入的数据大小判断需要对哪些区域进行擦除(flash写入之前必须处于擦除状态,写入只能将单元中的内容从1编程0,不能逆向操作)。擦除完后进行写入,每次最多写入1个page,即256bytes。

uint8_t W25Qx_Write(uint8_t* pData, uint32_t WriteAddr, uint32_t Size)
{
   
	uint8_t cmd[4];
	uint32_t end_addr, current_size, current_addr;
	uint32_t tickstart = get_tick();	
	/* Calculation of the size between the write address and the end of the page */
  current_addr = 0;
  while (current_addr <= WriteAddr)
  {
   
    current_addr += W25QXXXX_PAGE_SIZE;
  }
  current_size = current_addr - WriteAddr;
  /* Check if the size of the data is less than the remaining place in the page */
  if (current_size > Size)
  {
   
    current_size = Size;
  }
  /* Initialize the adress variables */
  current_addr = WriteAddr;
  end_addr = WriteAddr + Size;	
  /* Perform the write page by page */
  do
  {
   
		/* Configure the command */
		cmd[0] = PAGE_PROG_CMD;
		cmd[1] = (uint8_t)(current_addr >> 16);
		cmd[2] = (uint8_t)(current_addr >> 8);
		cmd[3] = (uint8_t)(current_addr);
		/* Enable write operations */
		W25Qx_WriteEnable();	
		W25Qx_Enable();
    /* Send the command */
    if (HAL_SPI_Transmit(&hspi2,cmd, 4
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值