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

w25q16Flash读写的问题

[复制链接]
watercici 提问时间:2018-5-16 10:19 /
现在我在用W25Q16这款FLASH芯片,现在出现了一个问题,就是我往一个地址中连着写两个0X55,然后再从这个地址中把他们读出来,可是我用逻辑分析仪抓取的结果是写时序正常,写的数据也正确,但是读的时序也是正常的,可是读出的数据却是两个0x00,读写的地址都是一样的,不知道这是怎么回事?涉及到的函数及变量:

        u8 Flash_Init_Value[2]={0x55,0x55};
        u8 Flash_Read_Init_Value[2] = {0};
        u8 Flash_Load_Init_Value[20] = {0};


       Flash_Read_Data(WriteInitValueAddr,0x02,Flash_Read_Init_Value);//判断读取的值是不是0x55,如果是则非首次用

      Flash_PagePro(Flash_Init_Value,WriteInitValueAddr,0x02); //如果不是,则将0x55,写入该地址
     Flash_Read_Data(WriteInitValueAddr,0x02,Flash_Read_Init_Value);//读取一下,判断是否写入成功


基本函数:
void Flash_PagePro(u8 *Pdat,u32 addr,u16 Len)
{
  u8 padr1,padr2,padr3;
        u8 i;
        padr1 = (addr & 0xff0000)>>16;
        padr2 = (addr & 0xff00)>>8;
        padr3 = addr & 0xff;
        
        while((Flash_Read_SR(0x05))&0x01);
        Flash_Write_EnorDis(ENABLE);
        
        SPI2_Flash_CS_LOW();
        SPI2_Flash_SendByte(PAGE_PROGRAM);
        SPI2_Flash_SendByte(padr1);
        SPI2_Flash_SendByte(padr2);
        SPI2_Flash_SendByte(padr3);
        
        for(i=0;i<Len;i++)
        {
                SPI2_Flash_SendByte(Pdat);
        }        
         SPI2_Flash_CS_HIGH();
}

void Flash_Read_Data(u32 addr, u32 len, u8* dst)
{
         u8 adr1,adr2,adr3;
         u32 i = 0;
        
//         SPI2_SetSpeed(SPI_BaudRatePrescaler_4);
         adr1 = (addr & 0xff0000)>>16;
         adr2 = (addr & 0xff00)>>8;
         adr3 =  addr & 0xff;
         SPI2_Flash_CS_LOW();
         //delay_us(2);
         SPI2_Flash_SendByte(READ_DATA);
         SPI2_Flash_SendByte(adr1);
         SPI2_Flash_SendByte(adr2);
         SPI2_Flash_SendByte(adr3);
         for(i=0;i<len;i++)
        {               
                dst = SPI2_Flash_ReceiveByte();
        }
         SPI2_Flash_CS_HIGH();
}



评分

参与人数 1 ST金币 -1 收起 理由
ouyang11111111 -1

查看全部评分

收藏 评论32 发布时间:2018-5-16 10:19

举报

32个回答
watercici 回答时间:2018-5-16 11:55:42
anobodykey 发表于 2018-5-16 11:50
就是软件的读写基本函数,此外你可以读取一下flash的id看下是否读取正确借此检验你的接线是否正确 ...

这些是基本函数,读芯片的ID 没有问题,ID是0xEF 0x40 0x15

  1. void SPI2_Flash_SendByte(u8 dat)
  2. {
  3.         while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);//µÈ´ýÊý¾Ý¼Ä´æÆ÷¿Õ
  4.         SPI_I2S_SendData(SPI2,dat);//д1¸ö×Ö½ÚÊý¾Ý
  5.         while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);
  6.         SPI_I2S_ReceiveData(SPI2);
  7. }

  8. u8 SPI2_Flash_ReceiveByte(void)
  9. {
  10.                 u8 RDat;
  11.           while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET){};//µÈ´ýÊý¾Ý¼Ä´æÆ÷¿Õ
  12.           SPI_I2S_SendData(SPI2,0xFF);
  13.        
  14.                 while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET){};//µÈ´ý½ÓÊÕ»º³åÇø·Ç¿Õ£¬Ôò½ÓÊÕÊý¾Ý
  15.           RDat = SPI_I2S_ReceiveData(SPI2);       
  16.           return RDat;
  17. }

  18. //---- Write Enalbe or Write Disable-----------------------
  19. void Flash_Write_EnorDis(FunctionalState sta)
  20. {
  21.         if(sta == ENABLE)
  22.         {
  23.                 SPI2_Flash_CS_LOW();

  24.                 SPI2_Flash_SendByte(WRITE_ENABLE);

  25.                 SPI2_Flash_CS_HIGH();
  26.         }
  27.         else
  28.         {
  29.                 SPI2_Flash_CS_LOW();

  30.                 SPI2_Flash_SendByte(WRTTE_DISABLE);
  31.        
  32.                 SPI2_Flash_CS_HIGH();
  33.         }
  34.         //delay_ms(10);
  35. }
  36. //----Read status register-------------------------------------
  37. u8 Flash_Read_SR(u8 regaddr)
  38. {
  39.           u8  t;
  40. //                SPI2_SetSpeed(SPI_BaudRatePrescaler_4);
  41.           SPI2_Flash_CS_LOW();
  42.                 //delay_us(2);
  43.                 SPI2_Flash_SendByte(regaddr);
  44.                
  45.                 t = SPI2_Flash_ReceiveByte();
  46.                
  47.                 SPI2_Flash_CS_HIGH();       
  48.          // delay_ms(10);
  49.        
  50.           return t;
  51. }
  52. //----Write register status------------------------------
  53. void Flash_Write_SR(u16 Set_Dat)
  54. {
  55.          u8 dat1,dat2;
  56.          dat1 = Set_Dat & 0xff; //µÍ8λ
  57.          dat2 = (Set_Dat>>8) & 0xff;//¸ß8λ
  58.        
  59.          while((Flash_Read_SR(0x05))&0x01);//¼ì²éÊÇ·ñæ
  60.          Flash_Write_EnorDis(ENABLE);//²»Ã¦£¬ÔòдʹÄÜ
  61.        
  62.    SPI2_Flash_CS_LOW();
  63.         // delay_us(10);
  64.          SPI2_Flash_SendByte(WRITE_STATUS_REGISTER);
  65.          SPI2_Flash_SendByte(dat1);
  66.          SPI2_Flash_SendByte(dat2);
  67.    SPI2_Flash_CS_HIGH();
  68.          //delay_ms(10);
  69. }
  70. //----Flash Read Data---------------------------------
  71. void Flash_Read_Data(u32 addr, u32 len, u8* dst)
  72. {
  73.          u8 adr1,adr2,adr3;
  74.          u32 i = 0;
  75.        
  76. //         SPI2_SetSpeed(SPI_BaudRatePrescaler_4);
  77.          adr1 = (addr & 0xff0000)>>16;
  78.          adr2 = (addr & 0xff00)>>8;
  79.          adr3 =  addr & 0xff;
  80.          SPI2_Flash_CS_LOW();
  81.          //delay_us(2);
  82.          SPI2_Flash_SendByte(READ_DATA);//¶ÁÊý¾ÝÖ¸Áî
  83.          SPI2_Flash_SendByte(adr1);
  84.          SPI2_Flash_SendByte(adr2);
  85.          SPI2_Flash_SendByte(adr3);
  86.          for(i=0;i<len;i++)
  87.         {               
  88.                 dst[i] = SPI2_Flash_ReceiveByte();
  89.         }
  90.          SPI2_Flash_CS_HIGH();
  91.         //delay_ms(10);
  92.         //return Rdat;
  93. }
  94. //----Load Default Data--------------------------------------------
  95. void Flash_Load_Data(void)
  96. {
  97.   Flash_Read_Data(HeadAddr,sizeof(LastRecordStruct),(u8*)LoadSaveData);
  98.   a;
  99. }

  100. //----Page Program-------------------------------------
  101. void Flash_PagePro(u8 *Pdat,u32 addr,u16 Len)
  102. {
  103.   u8 padr1,padr2,padr3;
  104.         u8 i;
  105.         padr1 = (addr & 0xff0000)>>16;
  106.         padr2 = (addr & 0xff00)>>8;
  107.         padr3 = addr & 0xff;
  108.        
  109.         while((Flash_Read_SR(0x05))&0x01);//¼ì²éÊÇ·ñæ
  110.         Flash_Write_EnorDis(ENABLE);
  111.        
  112.         SPI2_Flash_CS_LOW();
  113.         SPI2_Flash_SendByte(PAGE_PROGRAM);//Ò³±à³Ì0x02
  114.         SPI2_Flash_SendByte(padr1);
  115.         SPI2_Flash_SendByte(padr2);
  116.         SPI2_Flash_SendByte(padr3);
  117.        
  118.         for(i=0;i<Len;i++)
  119.         {
  120.                 SPI2_Flash_SendByte(Pdat[i]);
  121.         }       
  122.          SPI2_Flash_CS_HIGH();
  123.          //delay_ms(10);
  124. }
复制代码
watercici 回答时间:2018-5-16 11:47:52
本帖最后由 watercici 于 2018-5-16 11:49 编辑
anobodykey 发表于 2018-5-16 11:37
哦,这样的话你可以更改一下排版,发帖时代码不要跟内容用一样的格式,发帖时上面有个的选项,是用来插入 ...
这部分代码,前几行是执行函数,后面的是执行函数中用到的基本函数
  1.         u8 Flash_Init_Value[2]={0x55,0x55};
  2.         u8 Flash_Read_Init_Value[2] = {0};
  3.         u8 Flash_Load_Init_Value[20] = {0};

  4. Flash_Read_Data(WriteInitValueAddr,0x02,Flash_Read_Init_Value);
  5.         if((0x55 == Flash_Read_Init_Value[0]) && (0x55 == Flash_Read_Init_Value[1]))
  6.         {
  7.                         Flash_Load_Data();        
  8.         }
  9.         else
  10.         {
  11.                 Flash_PagePro(Flash_Load_Init_Value,HeadAddr, 0x10);
  12.                 Flash_Load_Data();
  13.                 delay_us(5);
  14.                 Flash_PagePro(Flash_Init_Value,WriteInitValueAddr,0x02);
  15.                 Flash_Read_Data(WriteInitValueAddr,0x02,Flash_Read_Init_Value);
  16.         }
复制代码
anobodykey 回答时间:2018-5-16 15:13:05
本帖最后由 anobodykey 于 2018-5-16 15:14 编辑
watercici 发表于 2018-5-16 14:01
WP和HOLD硬件连接都是接的高电平,写使能就是单片机给flash发送一个0X06的指令,从机应该是没有回复的,但 ...

的确看你第二个波形是不对,那你试下这个代码
  1. void Flash_PagePro(u8 *Pdat,u32 addr,u16 Len)
  2. {
  3.     u8 padr1,padr2,padr3;
  4.     u8 i;
  5.     padr1 = (addr & 0xff0000)>>16;
  6.     padr2 = (addr & 0xff00)>>8;
  7.     padr3 = addr & 0xff;

  8.     while((Flash_Read_SR(0x05)&0x01) == 0x01);
  9.     Flash_Write_EnorDis(ENABLE);

  10.     SPI2_Flash_CS_LOW();
  11.     SPI2_Flash_SendByte(PAGE_PROGRAM);
  12.     SPI2_Flash_SendByte(padr1);
  13.     SPI2_Flash_SendByte(padr2);
  14.     SPI2_Flash_SendByte(padr3);

  15.     for(i=0;i<Len;i++)
  16.     {
  17.             SPI2_Flash_SendByte(Pdat[i]);
  18.     }   
  19.      
  20.     SPI2_Flash_CS_HIGH();
  21.     while((Flash_Read_SR(0x05)&0x01) == 0x01);//等待写入完成
  22. }
复制代码

看下这个波形是否正确,如果还不行的话,实在想不出哪里出问题了就,你也对比下st自带的flash读写示例,看下是否正常
anobodykey 回答时间:2018-5-16 10:46:53
你有没有发现你读取的函数有问题呢?
  1. for(i=0;i<len;i++)
  2. {                 
  3.     dst = SPI2_Flash_ReceiveByte();
  4. }
复制代码
其中dst是你传递进来的数据指针,你不觉得你这个赋值语句有问题吗?,按我的理解应该是这么写
  1. for(i=0;i<len;i++)
  2. {               
  3.     dst[i] = SPI2_Flash_ReceiveByte();
  4. }
复制代码


评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

xiajintaord 回答时间:2018-5-16 11:02:35
anobodykey 说得对!

另外,Flash_Read_Data() 的参数 Flash_Read_Init_Value 在一开始被你初始化为0了:
u8 Flash_Read_Init_Value[2] = {0};
所以你每次读取肯定是0啊

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

watercici 回答时间:2018-5-16 11:20:04
本帖最后由 watercici 于 2018-5-16 11:22 编辑
anobodykey 发表于 2018-5-16 10:46
你有没有发现你读取的函数有问题呢?其中dst是你传递进来的数据指针,你不觉得你这个赋值语句有问题吗?,按 ...

不好意思,可能是我粘贴过程中,不小心删掉了,我的也是dst  ,还有其他的问题吗?诶????为什么我的括号和字母i显示不出来呢?那应该不是我删掉了,而是他没有显示,反正我和你说的是一样的。
watercici 回答时间:2018-5-16 11:26:52
xiajintaord 发表于 2018-5-16 11:02
anobodykey 说得对!

另外,Flash_Read_Data() 的参数 Flash_Read_Init_Value 在一开始被你初始化为0了:

是这样的Flash_Read_Init_value我只是在变量定义的时候初始化了,然后我用Flash_Read_Data()这个函数来读取指定地址中的数据,并把它存在Flash_Read_Init_value中,是这样的,如果读取的数值为0,就将0X55写入到这个地址中去
watercici 回答时间:2018-5-16 11:28:16
本帖最后由 watercici 于 2018-5-16 11:32 编辑
xiajintaord 发表于 2018-5-16 11:02
anobodykey 说得对!

另外,Flash_Read_Data() 的参数 Flash_Read_Init_Value 在一开始被你初始化为0了:

现在的问题是,我往WriteInitValueAddr这个地址中写两个0X55,然后在读出来是0第一个是写数据图,第二个是读数据图:
图片a.jpg
图片1b.jpg
butterflyspring 回答时间:2018-5-16 11:33:21
就是之前说的,你在接收弄个断点,看看接收寄存器呀,这很直接...
anobodykey 回答时间:2018-5-16 11:37:18
watercici 发表于 2018-5-16 11:20
不好意思,可能是我粘贴过程中,不小心删掉了,我的也是dst  ,还有其他的问题吗?诶????为什么我的括 ...

哦,这样的话你可以更改一下排版,发帖时代码不要跟内容用一样的格式,发帖时上面有个<>的选项,是用来插入代码的,这样看起来更清晰,你可以试下,另外把你的读写接口也都放上来,只放一个Flash_Read_Data看不出问题的
watercici 回答时间:2018-5-16 11:39:04
butterflyspring 发表于 2018-5-16 11:33
就是之前说的,你在接收弄个断点,看看接收寄存器呀,这很直接...

您能说的具体点吗,是看单片机的SPI状态寄存器中的RXNE还是SPI的数据寄存器DR?
watercici 回答时间:2018-5-16 11:41:41
anobodykey 发表于 2018-5-16 11:37
哦,这样的话你可以更改一下排版,发帖时代码不要跟内容用一样的格式,发帖时上面有个的选项,是用来插入 ...

不好意思,问一下,您说的这个读写接口指什么,是硬件的引脚,还是软件的读写基本函数?
anobodykey 回答时间:2018-5-16 11:50:05
watercici 发表于 2018-5-16 11:41
不好意思,问一下,您说的这个读写接口指什么,是硬件的引脚,还是软件的读写基本函数? ...

就是软件的读写基本函数,此外你可以读取一下flash的id看下是否读取正确借此检验你的接线是否正确
anobodykey 回答时间:2018-5-16 13:48:17
watercici 发表于 2018-5-16 11:55
这些是基本函数,读芯片的ID 没有问题,ID是0xEF 0x40 0x15

看起来是没啥问题的,如果读id正确的话,说明读取接口是对的,那可能是没写进去,看下写使能是否打开以及写保护引脚是否配置正确

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

watercici 回答时间:2018-5-16 14:01:02
本帖最后由 watercici 于 2018-5-16 14:03 编辑
anobodykey 发表于 2018-5-16 13:48
看起来是没啥问题的,如果读id正确的话,说明读取接口是对的,那可能是没写进去,看下写使能是否打开以及 ...

WP和HOLD硬件连接都是接的高电平,写使能就是单片机给flash发送一个0X06的指令,从机应该是没有回复的,但不知道为什么有的时候,MISO上会收到一堆脉冲,但不知道是不是这个影响,还有就是在写使能前会读取状态寄存器,来检查总线是否忙,这里用的是while,程序中您也能看到,正常情况下,读取的值的最低位应该是0,那么说明总线不忙,可以写使能;可是,我读取的值是0x03什么的,反正最低位不是0,按理说这种情况下是不能发送写使能命令0X06的,可是时序上发送了,当我用逻辑分析仪单抓这段是他读取的却总是正常的。


我给你贴个图看看第一个是正常的,第二个是不正常的;0X05:读状态寄存器;0X06写使能;0X02页编程
图片11.jpg
图片12.jpg
123下一页

所属标签

相似问题

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