w25q128fw 外部 spi 闪存不响应从 stm32 发送的命令

w25q128fw External spi flash not responding orders sent from stm32

我正在使用来自 Winbound 的名为 W25Q128FW 的外部闪存和 STM32L4 微控制器,我试图让它们通过 SPI 总线进行通信。

我的问题是,我的请求没有得到 w25q 的响应。例如,当我发送 "get_id" 协议时,它应该发回 ID(如数据表中所述),但我在闪存的 DO 引脚上没有任何内容(因此没有答案)。

我使用 STM32CubeMX 设置引脚(GPIO ans SPI),这是它们的配置:

SPI 引脚

 static 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_HIGH;
  hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;
  hspi1.Init.NSS = SPI_NSS_SOFT;
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256; //312.25 Kbit/s
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi1.Init.CRCPolynomial = 7;
  hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
  hspi1.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

}

和 GPIO 端口

static void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct;

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOC_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(FLASH_CS_GPIO_Port, FLASH_CS_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOC, SPI_HOLD_Pin|SPI_WP_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin : FLASH_CS_Pin */
  GPIO_InitStruct.Pin = FLASH_CS_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(FLASH_CS_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pins : SPI_HOLD_Pin SPI_WP_Pin */
  GPIO_InitStruct.Pin = SPI_HOLD_Pin|SPI_WP_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

}

然后我在我的主程序中使用了一些测试功能,我首先使用重置命令“0x66”初始化闪存以启用重置,并使用“0x99”重置设备。

  HAL_GPIO_WritePin(FLASH_CS_GPIO_Port, FLASH_CS_Pin, GPIO_PIN_RESET); //chipselect
  BufferSendFlash[0]=0x66;    //reset enable order
  HAL_SPI_Transmit(&hspi1, BufferSendFlash, 1, 1000);
  HAL_GPIO_WritePin(FLASH_CS_GPIO_Port, FLASH_CS_Pin, GPIO_PIN_SET); //chip desselect
  HAL_GPIO_WritePin(FLASH_CS_GPIO_Port, FLASH_CS_Pin, GPIO_PIN_RESET); //chipselect
  BufferSendFlash[0]=0x99;   //reset devise order
  HAL_SPI_Transmit(&hspi1, BufferSendFlash, 1, 1000);
  HAL_GPIO_WritePin(FLASH_CS_GPIO_Port, FLASH_CS_Pin, GPIO_PIN_SET); //chipdesselect

我的设计现在应该已经初始化了。然后我尝试通过发送“0x90”命令后跟 2 个虚拟字节和 0x00(如数据表中所述)来读取设备 ID,我应该立即收到制造商和 ID 的 2 个字节。 devise ID instruction datagram

HAL_GPIO_WritePin(FLASH_CS_GPIO_Port, FLASH_CS_Pin, GPIO_PIN_RESET);
BufferSendFlash[0]=0x90;  //ask for ID instruction
BufferSendFlash[1]=0x00;  //dummy
BufferSendFlash[2]=0x00;  //dummy
BufferSendFlash[3]=0x00;  //end of address
HAL_SPI_Transmit(&hspi1, BufferSendFlash, 4, 1000);  //send the order
HAL_SPI_Receive(&hspi1,BufferReceiveFlash, 2, 1000);  //read the flash answer
HAL_GPIO_WritePin(FLASH_CS_GPIO_Port, FLASH_CS_Pin, GPIO_PIN_SET);

这是我在示波器上看到的(我在 STM32 的 MOSI 和 MISO 引脚上使用了上拉电阻):
data input and output from flash

我们可以看到我有时钟和命令(从 stm32 的 MOSI 引脚发送到闪存的 DI 引脚)但是我们在 DO(数据输出)引脚上看到,我们什么都没有,但是时钟在这里。

我可能忘记了闪存初始化的一个步骤,但我无法理解,因为我遵循了数据表。我在网上找不到任何可以帮助我的东西,所以如果有人能解决这个问题,请帮助我,在这里非常欢迎你!谢谢。

正如@old_timer建议的那样,我检查了 HOLD 引脚,确实存在问题。 问题是 HOLD 引脚的硬件问题,保持一直很低,我们无法控制它。现在我们修复了硬件设置,我们可以将 HOLD 引脚设置为高电平,闪光灯监听并响应输入命令。

感谢@old_timer的帮助。