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

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管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版