完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
大侠们好,现在折腾 N25Q512 这个芯片,现在能够正常读取 芯片 ID 号了,而且也是正确的 芯片工作模式设置为 QUAD 与 4字节模式,读取标志寄存器查看是否设置成功,结果设置是正确的 读取到的芯片 ID 号: 资料介绍的 芯片ID 号: 读取到的id号与资料介绍的是完全一致的 现在就是读取数据错误,全部都为 0x88 测试读数据前先把读取的一个扇区已经擦除了,再直接读取数据全部都为 0x88,正常来说应该是0xff才对 测试擦除一个扇区大概需要240ms左右,这个擦除时间应该算是正常的了,现在问题就出在数据读取上了 有哪位知道请指点指点几下啊 ????????!!!!! |
|
相关推荐
19个回答
|
|
上代码看看吧;
|
|
|
|
楼主还是把代码发上来看看吧。可能是读取的时序问题。楼主用的是硬件SPI还是模拟的?
|
|
|
|
本帖最后由 hpdell 于 2016-12-15 14:32 编辑 使用的硬件的 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 , ®, 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, ®, 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; } |
|
|
|
使用的硬件的 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 , ®, 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, ®, 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; } |
|
|
|
楼主读取ID和其他数据的代码发一下。
|
|
|
|
本帖最后由 hpdell 于 2016-12-16 14:29 编辑 你好,我现在把 N25Q512的程序全部上传,包括进入 QUAD 及4字节模式 但是没有找到他们之间的对应关系具体该如何设置 ?? 下面的这个图片对应的是 MX25L51245G 这个芯片的,别人的貌似写得的比较详细,一看就明白了 // 读写测试函数 void QSPI_ReadWriteDemo(void) { static uint8_t qspi_tx_buff[256], qspi_rx_buff[256]; uint32_t RWDataSize = 256; // uint8_t * qspi_tx_buff = (uint8_t *)mymalloc(SRAMEX, RWDataSize ); // uint8_t * qspi_rx_buff = (uint8_t *)mymalloc(SRAMEX, RWDataSize ); uint8_t i = 0; uint32_t cc = 0; uint32_t QspiAddr_RW; uint32_t TimeBegin, TimeEnd; // if(( !qspi_tx_buff) || ( !qspi_rx_buff )) // 内存申请失败 // printf("QSPI SDRAM mymalloc Error ... ... rn"); for(cc=0;cc < ( RWDataSize );cc++) { qspi_tx_buff[cc] = i * 1 ; qspi_rx_buff[cc] = 0 ; i ++; } { TimeBegin = HAL_GetTick(); if(QSPI_EraseSector(0) != QSPI_OK) //擦除这个扇区 return ; TimeEnd = HAL_GetTick(); printf("QSPI QSPI Erase Sector ... ... %dms, %drn" , TimeEnd - TimeBegin, cc); // 擦除一个扇区大概是240ms左右 } QspiAddr_RW = (0 * 4096) + 0; QSPI_ReadBuff( &qspi_rx_buff[0], (uint32_t)(QspiAddr_RW ), RWDataSize); // 擦除完成后就直接读取,但是读回来的数据全部都是 0x88 ??? TimeBegin = HAL_GetTick(); QSPI_WritePageByte( &qspi_tx_buff[0], (uint32_t)(QspiAddr_RW ), RWDataSize); TimeEnd = HAL_GetTick(); printf("QSPI Write 8192 * 4 End ... ... %dmsrnrn" , TimeEnd - TimeBegin); TimeBegin = HAL_GetTick(); QSPI_ReadBuff( &qspi_rx_buff[0], (uint32_t)(QspiAddr_RW ), RWDataSize); TimeEnd = HAL_GetTick(); printf("QSPI Read 8192 * 4 End ... ... %dmsrnrn" , TimeEnd - TimeBegin); if( Buffercmp_8(&qspi_tx_buff[0], &qspi_rx_buff[0], RWDataSize) == 0) printf("QSPI Data Read Write 8192 * 4 Test OK ... DD rnrn"); else printf("QSPI Data Read Write 8192 * 4 Test Error ... EE rnrn"); // myfree(SRAMEX, qspi_tx_buff); // myfree(SRAMEX, qspi_rx_buff); } |
|
|
|
QSPI_WriteBuffAutoEraseSector,调用这个,看看他开始读取的数据是否正确。
|
|
|
|
本帖最后由 hpdell 于 2016-12-17 12:49 编辑 结果也还是一样的啊, 移植官网的 驱动 想测试一下,结果 程序死掉了,哎, 刚刚重新更换了一片 N25Q256A QSPI 芯片,结果神奇般的好了,怎么512的就不行,也不知道是不是512芯片搞到假货了【淘宝搞的,不过价格也不便宜啊,23大洋啊】 256的芯片一次读写32KByte 的数据也都没有问题 |
|
|
|
512的读取方式可能不一样,你看一下手册。
|
|
|
|
|
|
|
|
我只是路过打酱油的
|
|
|
|
你好,在手册上也没有找到啊,同样的程序,在 N25Q256A qspi 的芯片上使用的挺好的, |
|
|
|
|
|
|
|
啊哦,我也只是使用SPI单线,数据OK的,没有使用QSPI读取命令;
|
|
|
|
|
|
|
|
|
|
|
|
要看一下页地址,发送命令那。
|
|
|
|
本帖最后由 hpdell 于 2016-12-28 11:46 编辑 你好,我对照过命令,都是一样的,但是 N25Q256A QSPI 的程序就是不能在 N25Q512A QSPI 的芯片上使用,哎,悲催呀 看他们的控制寄存器等定义也都一样, N25Q256A QSPI的程序,读写寄存器完全可以在 N25Q512 QSPI 的芯片上使用,但是读写数据就不行了 |
|
|
|
谢谢分享
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
2255 浏览 1 评论
AD7686芯片不传输数据给STM32,但是手按住就会有数据。
2071 浏览 3 评论
4687 浏览 0 评论
如何解决MPU-9250与STM32通讯时,出现HAL_ERROR = 0x01U
2215 浏览 1 评论
hal库中i2c卡死在HAL_I2C_Master_Transmit
2757 浏览 1 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-27 02:36 , Processed in 0.914492 second(s), Total 79, Slave 73 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号