你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

请教下,qspi n25q512a 读取数据错误 ???

[复制链接]
hpdell 提问时间:2016-12-15 09:58 /
悬赏5ST金币未解决
本帖最后由 hpdell 于 2016-12-15 10:03 编辑

大侠们好,现在折腾 N25Q512 这个芯片,现在能够正常读取 芯片 ID 号了,而且也是正确的

芯片工作模式设置为 QUAD 与 4字节模式,读取标志寄存器查看是否设置成功,结果设置是正确的
读取到的芯片 ID 号:

ID.png

资料介绍的 芯片ID 号:

ID-m.png

读取到的id号与资料介绍的是完全一致的

现在就是读取数据错误,全部都为 0x88
read.png


测试读数据前先把读取的一个扇区已经擦除了,再直接读取数据全部都为 0x88,正常来说应该是0xff才对

测试擦除一个扇区大概需要240ms左右,这个擦除时间应该算是正常的了,现在问题就出在数据读取上了

有哪位知道请指点指点几下啊 ????????!!!!!

收藏 3 评论19 发布时间:2016-12-15 09:58

举报

19个回答
xhzheng 回答时间:2016-12-15 10:47:56
上代码看看吧;
回答时间:2016-12-15 14:18:06
楼主还是把代码发上来看看吧。可能是读取的时序问题。楼主用的是硬件SPI还是模拟的?
hpdell 回答时间:2016-12-15 14:28:34
本帖最后由 hpdell 于 2016-12-15 14:32 编辑
安 发表于 2016-12-15 14:18
楼主还是把代码发上来看看吧。可能是读取的时序问题。楼主用的是硬件SPI还是模拟的? ...

使用的硬件的 QSPI ,芯片是N25Q512A的,估计就是时钟频率与 Dummy
Clock Cycles 的周期没有搞对造成的,

再加上 芯片 N25Q512的资料也没有完全明白
static QSPI_StaticTypeDef QSPI_SendCmdData( uint8_t  __Instruction,       //  发送指令
                                             uint32_t __InstructionMode,   //  指令模式
                                             uint32_t __AddressMode,       //  地址模式
                                             uint32_t __AddressSize,       //  地址长度  
                                             uint32_t __DataMode,          //  数据模式
                                             uint32_t __NbData,            //  数据读写字节数
                                             uint32_t __DummyCycles,       //  设置空指令周期数
                                             uint32_t __Address,           //  发送到的目的地址
                                             uint8_t  *_pBuf,              //  待发送的数据
                                             __SEND_CMD_DATA_T  _SendCmdDat
                                           )
{
  QSPI_CommandTypeDef     sCommand;

  sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;      //每次都发送指令
  sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;     //无交替字节
  sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;         //关闭DDR模式
  sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;

  sCommand.Instruction       = __Instruction;                  //指令
  sCommand.DummyCycles       = __DummyCycles;                  //设置空指令周期数
  sCommand.Address           = __Address;                      //发送到的目的地址
//  sCommand.NbData            = __NbData;                     //这个地方不使用

  sCommand.InstructionMode   = __InstructionMode;              //指令模式
  sCommand.AddressMode       = __AddressMode;                  //地址模式
  sCommand.AddressSize       = __AddressSize;                  //地址长度  
  sCommand.DataMode          = __DataMode;                     //数据模式  

  if (HAL_QSPI_Command(&hqspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  {
    return QSPI_ERROR;
  }

  if( _SendCmdDat == QSPI_SEND_DAT)
  {
    if(QSPI_Transmit( ( uint8_t * )_pBuf, __NbData) != QSPI_OK)
    {
      return QSPI_ERROR;
    }
  }

  return QSPI_OK;
}






/**
  * @brief  This function configure the dummy cycles on memory side.
  * @param  hqspi: QSPI handle
  * @retval None
  */
QSPI_StaticTypeDef QSPI_DummyCyclesCfg(QSPI_HandleTypeDef *hqspi)
{
  QSPI_CommandTypeDef sCommand;
  uint8_t reg;

  if(W25QxxQpiMode)   // qpi
  {
    sCommand.InstructionMode   = QSPI_INSTRUCTION_4_LINES;
    sCommand.DataMode          = QSPI_DATA_4_LINES;
  }
  else
  {
    sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
    sCommand.DataMode          = QSPI_DATA_1_LINE;  
  }


  /* Read Volatile Configuration register --------------------------- */
//  sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
  sCommand.Instruction       = QSPI_READ_VOL_CFG_REG_CMD;
  sCommand.AddressMode       = QSPI_ADDRESS_NONE;
  sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
//  sCommand.DataMode          = QSPI_DATA_1_LINE;
  sCommand.DummyCycles       = 0;
  sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
  sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
  sCommand.SIOOMode         = QSPI_SIOO_INST_EVERY_CMD;
  sCommand.NbData            = 1;

  if (HAL_QSPI_Command( hqspi , &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  {
    return QSPI_ERROR;
  }

  if (HAL_QSPI_Receive( hqspi , &reg, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  {
    return QSPI_ERROR;
  }

  /* Enable write operations ---------------------------------------- */
  QSPI_WriteEnable( hqspi );

  /* Write Volatile Configuration register (with new dummy cycles) -- */  
  sCommand.Instruction = QSPI_WRITE_VOL_CFG_REG_CMD;
  MODIFY_REG(reg, 0xF0, (10<< POSITION_VAL(0xF0)));

  if (HAL_QSPI_Command(hqspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  {
    return QSPI_ERROR;
  }

  if (HAL_QSPI_Transmit(hqspi, &reg, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  {
    return QSPI_ERROR;
  }

  return QSPI_OK;
}




QSPI_StaticTypeDef QSPI_ReadBuff(uint8_t* data, uint32_t address, uint32_t size)
{
  uint8_t _RegVal = 0;

  QSPI_DummyCyclesCfg(&hqspi);      

  //QPI,快速读数据,地址为ReadAddr,4线传输数据_32位地址_4线传输地址_4线传输指令,8空周期,NumByteToRead个数据
  if(QSPI_SendCmdData(  QSPI_QUAD_INOUT_FAST_READ_CMD /*QSPI_QUAD_INOUT_FAST_READ_CMD*/  /*QSPI_QUAD_INOUT_FAST_READ_CMD*/ ,        // _Instruction,      发送指令
                        QSPI_INSTRUCTION_4_LINES,  // _InstructionMode,  指令模式
                        QSPI_ADDRESS_4_LINES,      // _AddressMode,      地址模式
                        QSPI_ADDRESS_32_BITS,      // _AddressSize,      地址长度  
                        QSPI_DATA_4_LINES,         // _DataMode,         数据模式
                        size,            // _NbData,           数据读写字节数
                        10 ,        // _DummyCycles,      设置空指令周期数 与 QSPI_SET_READ_PARAM 这个指令设置的值一致
                        address,                 // _Address,          发送到的目的地址
                        &_RegVal,                  //  *_pBuf,           待发送的数据
                        QSPI_SEND_CMD              // __SEND_CMD_DATA_T  _SendCmdDat
                     ) != QSPI_OK )
  {
    return QSPI_ERROR;
  }   

  if(QSPI_Receive(  data,  size) != QSPI_OK)
    return  QSPI_ERROR;  
  return  QSPI_OK;

}




hpdell 回答时间:2016-12-15 14:32:41

使用的硬件的 QSPI ,芯片是N25Q512A的,估计就是时钟频率与 Dummy
Clock Cycles 的周期没有搞对造成的,

再加上 芯片 N25Q512的资料也没有完全明白
static QSPI_StaticTypeDef QSPI_SendCmdData( uint8_t  __Instruction,       //  发送指令
                                             uint32_t __InstructionMode,   //  指令模式
                                             uint32_t __AddressMode,       //  地址模式
                                             uint32_t __AddressSize,       //  地址长度  
                                             uint32_t __DataMode,          //  数据模式
                                             uint32_t __NbData,            //  数据读写字节数
                                             uint32_t __DummyCycles,       //  设置空指令周期数
                                             uint32_t __Address,           //  发送到的目的地址
                                             uint8_t  *_pBuf,              //  待发送的数据
                                             __SEND_CMD_DATA_T  _SendCmdDat
                                           )
{
  QSPI_CommandTypeDef     sCommand;

  sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;      //每次都发送指令
  sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;     //无交替字节
  sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;         //关闭DDR模式
  sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;

  sCommand.Instruction       = __Instruction;                  //指令
  sCommand.DummyCycles       = __DummyCycles;                  //设置空指令周期数
  sCommand.Address           = __Address;                      //发送到的目的地址
//  sCommand.NbData            = __NbData;                     //这个地方不使用

  sCommand.InstructionMode   = __InstructionMode;              //指令模式
  sCommand.AddressMode       = __AddressMode;                  //地址模式
  sCommand.AddressSize       = __AddressSize;                  //地址长度  
  sCommand.DataMode          = __DataMode;                     //数据模式  

  if (HAL_QSPI_Command(&hqspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  {
    return QSPI_ERROR;
  }

  if( _SendCmdDat == QSPI_SEND_DAT)
  {
    if(QSPI_Transmit( ( uint8_t * )_pBuf, __NbData) != QSPI_OK)
    {
      return QSPI_ERROR;
    }
  }

  return QSPI_OK;
}






/**
  * @brief  This function configure the dummy cycles on memory side.
  * @param  hqspi: QSPI handle
  * @retval None
  */
QSPI_StaticTypeDef QSPI_DummyCyclesCfg(QSPI_HandleTypeDef *hqspi)
{
  QSPI_CommandTypeDef sCommand;
  uint8_t reg;

  if(W25QxxQpiMode)   // qpi
  {
    sCommand.InstructionMode   = QSPI_INSTRUCTION_4_LINES;
    sCommand.DataMode          = QSPI_DATA_4_LINES;
  }
  else
  {
    sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
    sCommand.DataMode          = QSPI_DATA_1_LINE;  
  }


  /* Read Volatile Configuration register --------------------------- */
//  sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
  sCommand.Instruction       = QSPI_READ_VOL_CFG_REG_CMD;
  sCommand.AddressMode       = QSPI_ADDRESS_NONE;
  sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
//  sCommand.DataMode          = QSPI_DATA_1_LINE;
  sCommand.DummyCycles       = 0;
  sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
  sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
  sCommand.SIOOMode         = QSPI_SIOO_INST_EVERY_CMD;
  sCommand.NbData            = 1;

  if (HAL_QSPI_Command( hqspi , &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  {
    return QSPI_ERROR;
  }

  if (HAL_QSPI_Receive( hqspi , &reg, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  {
    return QSPI_ERROR;
  }

  /* Enable write operations ---------------------------------------- */
  QSPI_WriteEnable( hqspi );

  /* Write Volatile Configuration register (with new dummy cycles) -- */  
  sCommand.Instruction = QSPI_WRITE_VOL_CFG_REG_CMD;
  MODIFY_REG(reg, 0xF0, (10<< POSITION_VAL(0xF0)));

  if (HAL_QSPI_Command(hqspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  {
    return QSPI_ERROR;
  }

  if (HAL_QSPI_Transmit(hqspi, &reg, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  {
    return QSPI_ERROR;
  }

  return QSPI_OK;
}




QSPI_StaticTypeDef QSPI_ReadBuff(uint8_t* data, uint32_t address, uint32_t size)
{
  uint8_t _RegVal = 0;

  QSPI_DummyCyclesCfg(&hqspi);      

  //QPI,快速读数据,地址为ReadAddr,4线传输数据_32位地址_4线传输地址_4线传输指令,8空周期,NumByteToRead个数据
  if(QSPI_SendCmdData(  QSPI_QUAD_INOUT_FAST_READ_CMD /*QSPI_QUAD_INOUT_FAST_READ_CMD*/  /*QSPI_QUAD_INOUT_FAST_READ_CMD*/ ,        // _Instruction,      发送指令
                        QSPI_INSTRUCTION_4_LINES,  // _InstructionMode,  指令模式
                        QSPI_ADDRESS_4_LINES,      // _AddressMode,      地址模式
                        QSPI_ADDRESS_32_BITS,      // _AddressSize,      地址长度  
                        QSPI_DATA_4_LINES,         // _DataMode,         数据模式
                        size,            // _NbData,           数据读写字节数
                        10 ,        // _DummyCycles,      设置空指令周期数 与 QSPI_SET_READ_PARAM 这个指令设置的值一致
                        address,                 // _Address,          发送到的目的地址
                        &_RegVal,                  //  *_pBuf,           待发送的数据
                        QSPI_SEND_CMD              // __SEND_CMD_DATA_T  _SendCmdDat
                     ) != QSPI_OK )
  {
    return QSPI_ERROR;
  }   

  if(QSPI_Receive(  data,  size) != QSPI_OK)
    return  QSPI_ERROR;  
  return  QSPI_OK;

}


回答时间:2016-12-16 09:13:56
楼主读取ID和其他数据的代码发一下。
hpdell 回答时间:2016-12-16 09:38:02
本帖最后由 hpdell 于 2016-12-16 14:29 编辑
安 发表于 2016-12-16 09:13
楼主读取ID和其他数据的代码发一下。

你好,我现在把 N25Q512的程序全部上传,包括进入 QUAD 及4字节模式

N25Q512A.rar (17.75 KB, 下载次数: 51)
回答时间:2016-12-16 15:00:48
QSPI_WriteBuffAutoEraseSector,调用这个,看看他开始读取的数据是否正确。

评分

参与人数 1ST金币 +2 收起 理由
zero99 + 2

查看全部评分

hpdell 回答时间:2016-12-17 10:44:35
本帖最后由 hpdell 于 2016-12-17 12:49 编辑
安 发表于 2016-12-16 15:00
QSPI_WriteBuffAutoEraseSector,调用这个,看看他开始读取的数据是否正确。

结果也还是一样的啊,
移植官网的 驱动 想测试一下,结果 程序死掉了,哎,

刚刚重新更换了一片 N25Q256A QSPI 芯片,结果神奇般的好了,怎么512的就不行,也不知道是不是512芯片搞到假货了【淘宝搞的,不过价格也不便宜啊,23大洋啊】

256的芯片一次读写32KByte 的数据也都没有问题

回答时间:2016-12-17 14:08:22
512的读取方式可能不一样,你看一下手册。
12下一页

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版