前些天淘宝购得30只w25q64fviq芯片,1.9元/只.直接替换掉原来红牛板上的SST25VF016B,花了些功夫终于成功了.
例子是将BMP图片写入SPI_Flash中,再读取SPI_Flash中的图片显示在LCD屏上,由于之前是2M_Byte,现在是8M_Byte,想测试一下8M空间,于是改写了测试程序.
方案是:
首先将Flash写入地址定义到0页的0x000000,擦除写入230454 Byte的图片,读出显示.
然后首地址按4KB增加,循环擦除写入230454 Byte的图片,读出显示.
擦除程序会根据写入数据的大小计算,采用最佳方式来擦除(64K,32K,4K).
由于BMP图片大小是: 230454 Byte,按最小4K擦除块方式,需要擦除228K的空间.
按最佳方案应该是:228K = 3次*64K擦除 + 1次*32K擦除 +1次*4K擦除.
结果现在问题来了:
图片第一次擦除写入读出显示没有问题,接着第二次以后的会出现图片花屏现象,而且多出现在后半屏花屏,
已经确定是没有正常擦除造成的,于是在擦除子程序中取消了64K,32K的擦除操作,只采用4K擦除方式.结果正常.
经反复验证,无论是64K+4K擦除方案或是32K+4K擦除方案,都不正常.
不知道有没有人遇到过这样的问题,特来请教一下是那里出了问题???
3.png (340.79 KB, 下载次数: 0)
下载附件
2016-4-22 04:23 上传
- /*******************************************************************************
- * Function Name : SSTF016B_WR
- * Description : SST25VF016B的写函数,可写1个和多个数据到指定地址
- * Input : - Dst: 目标地址,范围 0x0 - MAX_ADDR(MAX_ADDR = 0x1FFFFF)
- * - SndbufPt: 发送缓存区指针
- * - NByte: 要写的数据字节数
- * Output : None
- * Return : 操作成功则返回OK,失败则返回ERROR
- * Attention : 若某功能下,某一入口参数无效,可在该入口参数处填Invalid,该参数将被忽略
- *******************************************************************************/
- uint8_t SSTF016B_WR(uint32_t Dst, uint8_t* SndbufPt,uint32_t NByte)
- {
- // uint8_t temp = 0,temp1 = 0,StatRgVal = 0;//
- uint32_t i = 0;
- //------------------------------------------------------------------------------------------
- if (( (Dst+NByte-1 > MAX_ADDR)||(NByte == 0) ))
- {
- return (ERROR); /* 检查入口参数 */
- }
- //------------------------------------------------------------------------------------------
- #if 0 //--取消下面的读取状态寄存器操作
- SPI_FLASH_CS_LOW();
- Flash_ReadWriteByte(0x05); /* 发送读状态寄存器1命令 */
- temp = Flash_ReadWriteByte(0xFF); /* 保存读得的状态寄存器值 */
- SPI_FLASH_CS_HIGH();
- SPI_FLASH_CS_LOW();
- Flash_ReadWriteByte(0x35); /* 发送读状态寄存器2命令 */
- temp1 = Flash_ReadWriteByte(0xFF); /* 保存读得的状态寄存器值 */
- SPI_FLASH_CS_HIGH();
- SPI_FLASH_CS_LOW();
- Flash_ReadWriteByte(0x50); /* 使状态寄存器可写 */
- SPI_FLASH_CS_HIGH();
-
- SPI_FLASH_CS_LOW();
- Flash_ReadWriteByte(0x01); /* 发送写状态寄存器指令 */
- Flash_ReadWriteByte(0); /* 清0BPx位,使Flash芯片全区可写 */
- Flash_ReadWriteByte(temp1); /* 清0BPx位,使Flash芯片全区可写 */
- SPI_FLASH_CS_HIGH();
-
- SPI_FLASH_WaitForWriteEnd(); /* 一直等待,直到芯片空闲 */
- #endif
-
- //------------------------------------------------------------------------------------------
- for(i = 0; i < NByte; i++)
- {
- SPI_FLASH_CS_LOW();
- Flash_ReadWriteByte(0x06); /* 发送写使能命令 */
- SPI_FLASH_CS_HIGH();
- SPI_FLASH_CS_LOW();
- Flash_ReadWriteByte(0x02); /* 发送字节数据烧写命令 */
- Flash_ReadWriteByte((((Dst+i) & 0xFFFFFF) >> 16)); /* 发送3个字节的地址信息 */
- Flash_ReadWriteByte((((Dst+i) & 0xFFFF) >> 8));
- Flash_ReadWriteByte((Dst+i) & 0xFF);
- Flash_ReadWriteByte(SndbufPt[i]); /* 发送被烧写的数据 */
- SPI_FLASH_CS_HIGH();
- SPI_FLASH_WaitForWriteEnd(); /* 一直等待,直到芯片空闲 */
- }
- //------------------------------------------------------------------------------------------
- #if 0 //--取消下面的恢复状态寄存器操作
- SPI_FLASH_CS_LOW();
- Flash_ReadWriteByte(0x06); /* 发送写使能命令 */
- SPI_FLASH_CS_HIGH();
- SPI_FLASH_CS_LOW();
- Flash_ReadWriteByte(0x50); /* 使状态寄存器可写 */
- SPI_FLASH_CS_HIGH();
-
- SPI_FLASH_CS_LOW();
- Flash_ReadWriteByte(0x01); /* 发送写状态寄存器指令 */
- Flash_ReadWriteByte(temp); /* 恢复状态寄存器设置信息 */
- Flash_ReadWriteByte(temp1); /* 恢复状态寄存器设置信息 */
- SPI_FLASH_CS_HIGH();
- SPI_FLASH_WaitForWriteEnd(); /* 一直等待,直到芯片空闲 */
- #endif
- //------------------------------------------------------------------------------------------
- return (ENABLE);
- }
复制代码
- <p>/*******************************************************************************
- * Function Name : SSTF016B_Erase
- * Description : 根据指定的扇区号选取最高效的算法擦除
- * Input : - sec1: 起始扇区号,范围(0~511)
- * - sec2: 终止扇区号,范围(0~511)
- * Output : None
- * Return : 操作成功则返回OK,失败则返回ERROR
- * Attention : None
- *******************************************************************************/
- uint8_t SSTF016B_Erase(uint32_t sec1, uint32_t sec2)
- {
- uint8_t ErCount,temp2 = 0;
- // uint8_t temp0 = 0,temp1 = 0;//
- uint32_t sectorStartAddr = 0;
- uint32_t sectorNumber = 0; /* 要擦除的扇区数目 */
- uint32_t CurSecNumber = 0; /* 当前要擦除的扇区号 */
-
- /* 检查入口参数 */
- if ((sec1 > SEC_MAX)||(sec2 > SEC_MAX))
- {
- return (ERROR);
- }
- //------------------------------------------------------------------------------------------
- #if 0 //--取消下面的读取状态寄存器操作
- SPI_FLASH_CS_LOW();
- Flash_ReadWriteByte(0x05); /* 发送读状态寄存器1命令 */
- temp0 = Flash_ReadWriteByte(0xFF); /* 保存读得的状态寄存器值 */
- SPI_FLASH_CS_HIGH();
- SPI_FLASH_CS_LOW();
- Flash_ReadWriteByte(0x35); /* 发送读状态寄存器2命令 */
- temp1 = Flash_ReadWriteByte(0xFF); /* 保存读得的状态寄存器值 */
- SPI_FLASH_CS_HIGH();
- SPI_FLASH_CS_LOW();
- Flash_ReadWriteByte(0x50); /* 使状态寄存器可写 */
- SPI_FLASH_CS_HIGH();
- SPI_FLASH_CS_LOW();
- Flash_ReadWriteByte(0x01); /* 发送写状态寄存器指令 */
- Flash_ReadWriteByte(0); /* 清0BPx位,使Flash芯片全区可写 */
- Flash_ReadWriteByte(temp1); /* 清0BPx位,使Flash芯片全区可写 */
- SPI_FLASH_CS_HIGH();
-
- SPI_FLASH_CS_LOW();
- Flash_ReadWriteByte(0x06); /* 发送写使能命令 */
- SPI_FLASH_CS_HIGH();
- SPI_FLASH_WaitForWriteEnd(); /* 一直等待,直到芯片空闲 */
- #endif
- //------------------------------------------------------------------------------------------
- /* 如果用户输入的起始扇区号大于终止扇区号,则在内部作出调整 */
- if (sec1 > sec2)
- {
- temp2 = sec1;
- sec1 = sec2;
- sec2 = temp2;
- }
- /* 若起止扇区号相等则擦除单个扇区 */
- if (sec1 == sec2)
- {
- SPI_FLASH_CS_LOW();
- Flash_ReadWriteByte(0x06); /* 发送写使能命令 */
- SPI_FLASH_CS_HIGH();
- sectorStartAddr = SEC_SIZE * sec1; /* 计算扇区的起始地址 */
- SPI_FLASH_CS_LOW();
- Flash_ReadWriteByte(0x20); /* 发送扇区擦除指令 */
- Flash_ReadWriteByte(((sectorStartAddr & 0xFFFFFF) >> 16)); /* 发送3个字节的地址信息 */
- Flash_ReadWriteByte(((sectorStartAddr & 0xFFFF) >> 8));
- Flash_ReadWriteByte(sectorStartAddr & 0xFF);
- SPI_FLASH_CS_HIGH();
- SPI_FLASH_WaitForWriteEnd(); /* 一直等待,直到芯片空闲 */
- return (ENABLE);
- }
- //------------------------------------------------------------------------------------------
-
- /* 根据起始扇区和终止扇区间距调用最快速的擦除功能 */
-
- if (sec2 - sec1 == SEC_MAX)
- {
- SPI_FLASH_CS_LOW();
- Flash_ReadWriteByte(0x06); /* 发送写使能命令 */
- SPI_FLASH_CS_HIGH();
-
- SPI_FLASH_CS_LOW();
- Flash_ReadWriteByte(0xC7); /* 发送芯片擦除指令(60h or C7h) */
- SPI_FLASH_CS_HIGH();
- SPI_FLASH_WaitForWriteEnd(); /* 一直等待,直到芯片空闲 */
- return (ENABLE);
- }
-
- sectorNumber = sec2 - sec1 +1; /* 获取要擦除的扇区数目 */
- CurSecNumber = sec1; /* 从起始扇区开始擦除 */
- GUI_IntegerText(10,55,CurSecNumber);
- //------------------------------------------------------------------------------------------
- #if 1
- /* 若两个扇区之间的间隔够大,则采取8扇区擦除算法 */
- ErCount = 0;
- while (sectorNumber >= 16)
- {
- SPI_FLASH_CS_LOW();
- Flash_ReadWriteByte(0x06); /* 发送写使能命令 */
- SPI_FLASH_CS_HIGH();
- sectorStartAddr = SEC_SIZE * CurSecNumber; /* 计算扇区的起始地址 */
- SPI_FLASH_CS_LOW();
- Flash_ReadWriteByte(0xd8); /* 发送64KB擦除指令 */
- Flash_ReadWriteByte(((sectorStartAddr & 0xFFFFFF) >> 16)); /* 发送3个字节的地址信息 */
- Flash_ReadWriteByte(((sectorStartAddr & 0xFFFF) >> 8));
- Flash_ReadWriteByte(sectorStartAddr & 0xFF);
- SPI_FLASH_CS_HIGH();
- SPI_FLASH_WaitForWriteEnd(); /* 一直等待,直到芯片空闲 */
- CurSecNumber += 16;
- sectorNumber -= 16;
- GUI_IntegerText(59,55,++ErCount);
- }
- #endif
- //------------------------------------------------------------------------------------------
- #if 1
- /* 若两个扇区之间的间隔够大,则采取8扇区擦除算法 */
- ErCount = 0;
- while (sectorNumber >= 8)
- {
- SPI_FLASH_CS_LOW();
- Flash_ReadWriteByte(0x06); /* 发送写使能命令 */
- SPI_FLASH_CS_HIGH();
- sectorStartAddr = SEC_SIZE * CurSecNumber; /* 计算扇区的起始地址 */
- SPI_FLASH_CS_LOW();
- Flash_ReadWriteByte(0x52); /* 发送32KB擦除指令 */
- Flash_ReadWriteByte(((sectorStartAddr & 0xFFFFFF) >> 16)); /* 发送3个字节的地址信息 */
- Flash_ReadWriteByte(((sectorStartAddr & 0xFFFF) >> 8));
- Flash_ReadWriteByte(sectorStartAddr & 0xFF);
- SPI_FLASH_CS_HIGH();
- SPI_FLASH_WaitForWriteEnd(); /* 一直等待,直到芯片空闲 */
- CurSecNumber += 8;
- sectorNumber -= 8;
- GUI_IntegerText(114,55,++ErCount);
- }
- #endif
- //------------------------------------------------------------------------------------------
- /* 采用扇区擦除算法擦除剩余的扇区 */
- ErCount = 0;
- while (sectorNumber >= 1)
- {
- SPI_FLASH_CS_LOW();
- Flash_ReadWriteByte(0x06); /* 发送写使能命令 */
- SPI_FLASH_CS_HIGH();
- sectorStartAddr = SEC_SIZE * CurSecNumber; /* 计算扇区的起始地址 */
- SPI_FLASH_CS_LOW();
- Flash_ReadWriteByte(0x20); /* 发送4K扇区擦除指令 */
- Flash_ReadWriteByte(((sectorStartAddr & 0xFFFFFF) >> 16)); /* 发送3个字节的地址信息 */
- Flash_ReadWriteByte(((sectorStartAddr & 0xFFFF) >> 8));
- Flash_ReadWriteByte(sectorStartAddr & 0xFF);
- SPI_FLASH_CS_HIGH();
- SPI_FLASH_WaitForWriteEnd(); /* 一直等待,直到芯片空闲 */
- CurSecNumber += 1;
- sectorNumber -= 1;
- GUI_IntegerText(170,55,++ErCount);
- }
- //------------------------------------------------------------------------------------------
- #if 0 //--取消下面的恢复状态寄存器操作
-
- /* 擦除结束,恢复状态寄存器信息 */
- SPI_FLASH_CS_LOW();
- Flash_ReadWriteByte(0x06); /* 发送写使能命令 */
- SPI_FLASH_CS_HIGH();
- SPI_FLASH_CS_LOW();
- Flash_ReadWriteByte(0x50); /* 使状态寄存器可写 */
- SPI_FLASH_CS_HIGH();
-
- SPI_FLASH_CS_LOW();
- Flash_ReadWriteByte(0x01); /* 发送写状态寄存器指令 */
- Flash_ReadWriteByte(temp0); /* 恢复状态寄存器设置信息 */
- Flash_ReadWriteByte(temp1); /* 恢复状态寄存器设置信息 */
- SPI_FLASH_CS_HIGH();
- SPI_FLASH_WaitForWriteEnd(); /* 一直等待,直到芯片空闲 */
- #endif
- //------------------------------------------------------------------------------------------
- return (ENABLE);
- }</p><p>
- </p><p>
- </p><p>
- </p>
复制代码
不过,你的测试方案很好。
一周热门 更多>