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

请教下,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, 下载次数: 55)
废鱼 回答时间: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的读取方式可能不一样,你看一下手册。
hpdell 回答时间:2016-12-17 15:46:14
安 发表于 2016-12-17 14:08
512的读取方式可能不一样,你看一下手册。

手册看了半天也没有看明白,跟256的手册对比看,貌似也都差不多啊
zbber 回答时间:2016-12-18 12:03:54
我只是路过打酱油的
hpdell 回答时间:2016-12-21 10:28:43
安 发表于 2016-12-17 14:08
512的读取方式可能不一样,你看一下手册。

你好,在手册上也没有找到啊,同样的程序,在 N25Q256A qspi 的芯片上使用的挺好的,
hpdell 回答时间:2016-12-21 10:45:24
安 发表于 2016-12-17 14:08
512的读取方式可能不一样,你看一下手册。

你好,在手册上也没有找到有什么不同啊,另外我吧 官网提供的 HAL 移植过来也不行
xhzheng 回答时间:2016-12-21 14:25:44
啊哦,我也只是使用SPI单线,数据OK的,没有使用QSPI读取命令;

评分

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

查看全部评分

12下一页

所属标签

相似问题

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版