w25q64fv 读写程序怎么取消写

查看: 2413|回复: 4
W25Q64写数据的疑问,为什么要对全扇区?
主题帖子精华
初级会员, 积分 51, 距离下一级还需 149 积分
在线时间1 小时
原子哥看下代码:
&&& while(1)
&& &&& &SPI_Flash_Read(SPI_FLASH_BUF,secpos*);//读出整个扇区的内容
&& &&& &for(i=0;i&i++)//校验数据
&& &&& &&& &if(SPI_FLASH_BUF[secoff+i]!=0XFF)//需要擦除 &&& & &
&& &&& &if(i&secremain)//需要擦除
&& &&& &&& &SPI_Flash_Erase_Sector(secpos);//擦除这个扇区
&& &&& &&& &for(i=0;i&i++)&& &&& //复制
&& &&& &&& &{
&& &&& &&& &&& &SPI_FLASH_BUF[i+secoff]=pBuffer;&& & &
&& &&& &&& &}
红色字体部。为什么要读出整个扇区的内容,读一部分不可以么,比如只检测50字节的内容?
读出整个扇区不是使写速度变慢了么
因为要判断需不需要擦除。。。。
你也可以读只需要写的区域出来,这样确实会快一些。
主题帖子精华
在线时间485 小时
因为要判断需不需要擦除。。。。
你也可以读只需要写的区域出来,这样确实会快一些。
我是开源电子网站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺:
微信公众平台:正点原子
主题帖子精华
在线时间160 小时
flash擦除是整个扇区擦除的,如果你写入数据的小于4096,就会将之前保存有的数据全部擦除掉了,所以。。。你懂得
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
主题帖子精华
初级会员, 积分 51, 距离下一级还需 149 积分
在线时间1 小时
回复【3楼】Badu_Space:
---------------------------------
谢谢
主题帖子精华
初级会员, 积分 51, 距离下一级还需 149 积分
在线时间1 小时
回复【2楼】正点原子:
---------------------------------
谢谢
Powered by403 Forbidden
403 ForbiddenSTC12控制w25q64读写问题 - 单片机论坛 -
中国电子技术论坛 -
最好最受欢迎电子论坛!
后使用快捷导航没有帐号?
STC12控制w25q64读写问题
23:03:33  
我是新手,第一次接触flash存储器件,刚刚手里有一块W25Q64,不知道该如何下手,在网上搜索了一些资料,自己又研究了几天,一知半解的写了一个程序,请大家帮忙改改,最好能详细说明一下,让我好好学习一下,这个程序是要按键1(key1),写入数据,不知道我的这个连写两个程序是不是对,按键2(key2)读出两个地址数据,并让LED等点亮。W25Q64中文数据说明
************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
#include&reg52.h&
#include&intrins.h&
#define uint unsigned int
#define uchar unsigned char
#define uint8 unsigned char
#define uint16 unsigned int
#define uint32 unsigned long
#define W25P_writeenable 0x06& && &&&//写使能
#define W25P_writedisable 0x04& & & & & & & &&&//写禁能
#define W25P_readstatusreg 0x05& & & & & & & &&&//读状态寄存器
#define W25P_writestatusreg 0x01& & & & & & & &&&//写状态寄存器
#define W25P_readdata 0x03& & & & & & & & & & & &&&//读数据
#define W25P_fastreaddata 0x0b& & & & & & & &&&//快读
#define W25P_pageprogram 0x02& & & & & & & &&&//页编程
#define W25P_sectorerase 0x20& & & & & & & &&&//扇区擦除
#define W25P_chiperase 0xc7& & & & & & & & & & & &&&//芯片擦除
#define W25P_powerdown 0xb9& & & & & & & & & & & &&&//掉电
#define W25P_releasepowerdown 0xab& & & &&&//释放掉电
#define W25P_deviceID 0xab& & & & & & & & & & & &&&//器件ID
#define W25P_manufactdeviceID 0x90& & & &&&//制造器件ID
#define W25P_jedecdeviceID 0x9f& & & & & & & &&&//JEDEC ID
sbit key1=P2^0;
sbit key2=P2^1;
sbit key3=P2^2;
sbit key4=P2^3;
sbit led1=P1^0;
sbit led2=P1^1;
sbit led3=P1^2;
sbit led4=P1^3;
sbit HOLD=P3^0;
sbit WP=P3^1;
sbit CS=P3^2;
sbit DI=P3^3;
sbit DO=P3^4;
sbit CLK=P3^5;
void IO_send_byte(uchar out);
uchar IO_get_byte();
void IO_wait_busy();
void IO_init();
uchar IO_read_statusreg();
void IO_write_statusreg(byte);
void IO_write_enable();
void IO_powerdown();
void IO_releasepowerdown();
uchar IO_read_ID1();
uint IO_read_ID2(uchar ID_Addr);
uchar IO_read_byte(uint32 DST_Addr);
void IO_read_nbyte(uint32 DST_Addr,uchar nbyte_128);
uchar IO_fastread_byte(uint32 Dst_Addr);
void IO_fastread_nbyte(uint32 Dst_Addr,uchar nbyte_128);
void IO_write_byte(uint32 Dst_Addr,uchar byte);
void IO_write_byte(uint32 Dst_Addr,uchar nbyte_128);
void IO_erase_chip();
void IO_erase_sector(uint32 Dst_Addr);
void verify(uchar byte,uchar cor_byte);
void IO_write_disable();
void trace(uchar *str,uchar len);
uint IO_read_ID3();
uint8 tx_buff[16];
uint8 upper_128[16];
#define nop() _nop_()
void delay(uchar tt)
& & & & while(tt--);
void main()
& & & & uint32
& & & & IO_init();
& & & & for(;;)
& & & & & & & & if(key1==0)
& & & & & & & & {
& & & & & & & & & & & & IO_read_ID1();
& & & & & & & & & & & & IO_write_enable();
& & & & & & & & & & & &
& & & & & & & & & & & & IO_erase_chip();
& & & & & & & & & & & &
& & & & & & & & & & & & IO_write_byte(0xx01);& & & & & & & & //0x0000000地址写入0x01
& & & & & & & & & & & & IO_write_byte(0xx02);& & & && &&&//0x0000001地址写入0x02
& & & & & & & & & & & & & & & & & & & & & & & & & & & &
& & & & & & & & }
& & & & & & & & if(key2==0)
& & & & & & & & {
& & & & & & & & & & & & dizhi=0x0000000;
& & & & & & & & & & & & for(t=0;t&2;t++)
& & & & & & & & & & & & {
& & & & & & & & & & & & & & & & j=IO_read_byte(dizhi);
& & & & & & & & & & & & & & & & dizhi++;
& & & & & & & & & & & & & & & & if(j==0x01)
& & & & & & & & & & & & & & & & & & & & led1=0;
& & & & & & & & & & & & & & & & if(j==0x02)
& & & & & & & & & & & & & & & & & & & & led2=0;
& & & & & & & & & & & & }
& & & & & & & & }
/* ********************************
***********************************
& & & & & & & & & & & & & & & & 送出
***********************************
**********************************/
void IO_send_byte(uchar out)
& & & & uchar i=0;
& & & & CS=0;
& & & & for(i=0;i&8;i++)
& & & & & & & & if((out&0x80)==0x80)
& & & & & & & & & & & & DI=1;
& & & & & & & & else
& & & & & & & & & & & & DI=0;
& & & & & & & & CLK=1;
& & & & & & & & out=(out&&1);
& & & & & & & & nop();
& & & & & & & & nop();
& & & & & & & & nop();
& & & & & & & & nop();
& & & & & & & & CLK=0;
/* ********************************
***********************************
& & & & & & & & & & & & & & & & 得到数据
***********************************
**********************************/
uchar IO_get_byte()
& & & & uchar i=0,in=0,temp=0;
& & & & CS=0;
& & & & for(i=0;i&8;i++)
& & & & & & & & in=(in&&1);
& & & & & & & & temp=DO;
& & & & & & & & CLK=1;
& & & & & & & & if(temp==1);
& & & & & & & & in |=0x01;
& & & & & & & & CLK=0;
/* ********************************
***********************************
& & & & & & & & 等待忙结束
***********************************
**********************************/
void IO_Wait_Busy()
& & & & while(IO_read_statusreg()==0x03)
& & & & & & & & IO_read_statusreg();
/* ********************************
***********************************
& & & & & & & & SPI初始化
***********************************
**********************************/
void IO_init()
& & & & CLK=0;
& & & & WP=1;
& & & & CS=1;
& & & & IO_write_disable();&&//写禁能
/* ********************************
***********************************
& & & & & & & & 读状态寄存器
***********************************
**********************************/
uchar IO_read_statusreg()
& & & & uchar byte=0;
& & & & CS=0;
& & & & IO_send_byte(W25P_readstatusreg); //发送读状态寄存器命令 0x05
& & & & byte=IO_get_byte();& & & & & & & & & & & & & & & && &//接收读状态寄存器数据值
& & & & CS=1;
/* ********************************
***********************************
& & & & & & & & 写状态寄存器
***********************************
**********************************/
void IO_write_statusreg(byte)
& & & & CS=0;
& & & & IO_send_byte(W25P_writestatusreg);
& & & & IO_send_byte(byte);
& & & & CS=1;
/* ********************************
***********************************
& & & & & & & & 写使能
***********************************
**********************************/
void IO_write_enable()
& & & & CS=0;
& & & & IO_send_byte(W25P_writeenable);& &//发送写使能命令 0x01
& & & & CS=1;
/* ********************************
***********************************
& & & & & & & & 掉电
***********************************
**********************************/
void IO_powerdown()
& & & & CS=0;
& & & & IO_send_byte(W25P_powerdown);
& & & & CS=1;
& & & & delay(6);
/* ********************************
***********************************
& & & & & & & & 释放掉电
***********************************
**********************************/
void IO_releasepowerdown()
& & & & CS=0;
& & & & IO_send_byte(W25P_releasepowerdown);//发送释放掉电命令
& & & & CS=1;
& & & & delay(6);
/* ********************************
***********************************
& & & & & & & & 读取器件ID1
***********************************
**********************************/
uchar IO_read_ID1()
& & & & CS=0;
& & & & IO_send_byte(W25P_deviceID);
& & & & IO_send_byte(0);& && && && && && & //发送3个伪地址
& & & & IO_send_byte(0);
& & & & IO_send_byte(0);
& & & & byte=IO_get_byte();
& & & & CS=1;
& & & & delay(4);
/* ********************************
***********************************
& & & & & & & & 读取制造器件ID2
***********************************
**********************************/
uint IO_read_ID2(uchar ID_Addr)
& & & & uint IData16;
& & & & CS=0;
& & & & IO_send_byte(W25P_manufactdeviceID);
& & & & IO_send_byte(0x00);& && && && && && &
& & & & IO_send_byte(0x00);
& & & & IO_send_byte(ID_Addr);
& & & & IData16=IO_get_byte()&&8;
& & & & IData16|=IO_get_byte();
& & & & CS=1;
& & & & return IData16;
/* ********************************
***********************************
& & & & & & & && &读JEDEC ID
***********************************
**********************************/
uint IO_read_ID3()
& & & & uint IData16;
& & & & CS=0;
& & & & IO_send_byte(0x9f);
& & & & IData16=IO_get_byte()&&8;
& & & & IData16=IO_get_byte();
& & & & tx_buff[2]=IO_get_
& & & & CS=1;
& & & & return IData16;
/* ********************************
***********************************
& & & & & & & && &读数据地址
***********************************
**********************************/
uchar IO_read_byte(uint32 Dst_Addr)
& & & & uchar byte=0;
& & & & CS=0;
& & & & IO_send_byte(W25P_readdata);
& & & & IO_send_byte((uchar)((Dst_Addr&0xffffff)&&16));
& & & & IO_send_byte((uchar)((Dst_Addr&0xffff)&&8));
& & & & IO_send_byte((uchar)(Dst_Addr&0xff));
& & & & byte=IO_get_
& & & & CS=1;
/* ********************************
***********************************
& & & & & & & && &读数据起始128个字节以内的内容
***********************************
**********************************/
void IO_read_nbyte(uint32 Dst_Addr,uchar nbytes_128)
& & & & uchar i=0;
& & & & CS=0;
& & & & IO_send_byte(W25P_readdata);
& & & & IO_send_byte((uchar)((Dst_Addr&0xffffff)&&16));
& & & & IO_send_byte((uchar)((Dst_Addr&0xffff)&&8));
& & & & IO_send_byte((uchar)(Dst_Addr&0xff));
& & & & for(i=0;i&nbytes_128;i++)
& & & & & & & & upper_128=IO_get_byte();
& & & & CS=1;
/* ********************************
***********************************
& & & & & & & && &快读数据
***********************************
**********************************/
uchar IO_fastread_byte(uint32 Dst_Addr)
& & & & uchar byte=0;
& & & & CS=0;
& & & & IO_send_byte(W25P_fastreaddata);
& & & & IO_send_byte((uchar)((Dst_Addr&0xffffff)&&16));
& & & & IO_send_byte((uchar)((Dst_Addr&0xffff)&&8));
& & & & IO_send_byte((uchar)(Dst_Addr&0xff));
& & & & IO_send_byte(0xff);
& & & & byte=IO_get_byte();& & //发送8个虚拟字节
& & & & CS=1;
/* ********************************
***********************************
& & & & & & & && &快读数据起始128个字节以内的内容
***********************************
**********************************/
void IO_fastread_nbyte(uint32 Dst_Addr,uchar nbytes_128)
& & & & uchar i=0;
& & & & CS=0;
& & & & IO_send_byte(W25P_fastreaddata);
& & & & IO_send_byte((uchar)((Dst_Addr&0xffffff)&&16));
& & & & IO_send_byte((uchar)((Dst_Addr&0xffff)&&8));
& & & & IO_send_byte((uchar)(Dst_Addr&0xff));
& & & & IO_send_byte(0xff);
& & & & for(i=0;i&nbytes_128;i++)
& & & & & & & & upper_128=IO_get_byte();
& & & & CS=1;
/* ********************************
***********************************
& & & & & & & & 页编程
***********************************
**********************************/
void IO_write_byte(uint32 Dst_Addr,uchar byte)
& & & & CS=0;
& & & & IO_write_enable();
& & & & IO_wait_busy();
& & & & CS=0;
& & & & IO_send_byte(W25P_pageprogram);
& & & & IO_send_byte((uchar)((Dst_Addr&0xffffff)&&16));
& & & & IO_send_byte((uchar)((Dst_Addr&0xffff)&&8));
& & & & IO_send_byte((uchar)(Dst_Addr&0xff));
& & & & IO_send_byte(byte);
& & & & CS=1;
/* ********************************
***********************************
& & & & & & & & 页编程128字节内容
***********************************
**********************************/
void IO_write_nbyte(uint32 Dst_Addr,uchar nbyte_128)
& & & & uchar byte,i;
& & & & CS=0;
& & & & IO_write_enable();
& & & & CS=0;
& & & & IO_send_byte(W25P_pageprogram);
& & & & IO_send_byte((uchar)((Dst_Addr&0xffffff)&&16));
& & & & IO_send_byte((uchar)((Dst_Addr&0xffff)&&8));
& & & & IO_send_byte((uchar)(Dst_Addr&0xff));
& & & & for(i=0;i&nbyte_128;i++)
& & & & & & & & byte=upper_128;
& & & & & & & & IO_send_byte(byte);
& & & & CS=1;
/* ********************************
***********************************
& & & & & & & & 芯片擦除
***********************************
**********************************/
void IO_erase_chip()
& & & & CS=0;
& & & & IO_write_enable();
& & & & CS=0;
& & & & IO_wait_busy();
& & & & CS=0;
& & & & IO_send_byte(W25P_chiperase);
& & & & CS=1;
/* ********************************
***********************************
& & & & & & & & 扇区擦除
***********************************
**********************************/
void IO_erase_sector(uint32 Dst_Addr)
& & & & CS=0;
& & & & IO_write_enable();
& & & & CS=0;
& & & & IO_send_byte(W25P_sectorerase); //擦除扇区
& & & & IO_send_byte((uchar)((Dst_Addr & 0xFFFFFF)&&16));
& & & & IO_send_byte((uchar)((Dst_Addr & 0xFFFF)&&8));
& & & & IO_send_byte((uchar)(Dst_Addr & 0xFF));
& & & & CS=1;
/* ********************************
***********************************
& & & & & & & & 判断
***********************************
**********************************/
void verify(uchar byte,uchar cor_byte)
& & & & if(byte!=cor_byte)
& & & & & & & & while(1);
/* ********************************
***********************************
& & & & & & & & 写禁能
***********************************
**********************************/
void IO_write_disable()
& & & & CS=0;
& & & & IO_send_byte(W25P_writedisable);
& & & & CS=1;
/* ********************************
***********************************
& & & & & & & & 发送字符
***********************************
**********************************/
void myputchar(uchar c)
& & & & ES=0;
& & & & SBUF=c;
& & & & while(TI==0);
& & & & TI=0;
& & & & ES=1;
/* ********************************
***********************************
& & & & & & & & 查找指针
***********************************
**********************************/
void trace(uchar *str,uchar len)
& & & & & & & & for(i=0;i&i++)
& & & & & & & & {
& & & & & & & & & & & & myputchar(*str);
& & & & & & & & & & & & str++;
& & & & & & & & }
12:20:28  
自己顶一下,程序有太多的问题,希望大家能认真帮忙分析一下!
20:35:30  
没办法,只有自己在顶一下,谁让晚上人多呢
18:40:26  
恩,哥们弄出来了没??
18:42:06  
14:51:03  
想了解一下。& && && && && && && &&&
10:25:14  
顶下,最近可能也要用STC驱动W25Q64
Powered by查看: 1556|回复: 10
w25q64写数据有时候就一直卡在等待空闲那里了,有什么办法可以解决的么?
主题帖子精华
初级会员, 积分 65, 距离下一级还需 135 积分
在线时间2 小时
我做一个刷卡实验,每刷一次卡我都要记录一次数据到flash里面,八个字节的记录。要是我一直不停的刷有时候就死机了,经测试是在flash
等待空闲&这里卡住了,要是我等一段时间强行跳过发现
下一次刷卡也记录不了,请问各位大神有没有遇到相类似的问题啊,求大神们指导一下小弟。
整个flash的驱动代码都是源子哥的,在战舰板上做的实验,等待空闲&flash空闲源码:
void SPI_Flash_Wait_Busy(void) &&
while ((SPI_Flash_ReadSR()&0x01)==0x01); & // 等待BUSY位清空
主题帖子精华
初级会员, 积分 153, 距离下一级还需 47 积分
在线时间0 小时
板子的mpu与w25q64通讯有问题,无应答。也可能你软件问题,如你某个时钟开啊,GPIO未设置正确啊,反正告诉你就是不通的意思
主题帖子精华
在线时间485 小时
回复【楼主位】everymama:
---------------------------------
怀疑你程序配置的有问题,spi配置,是不是有改过?
我是开源电子网站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺:
微信公众平台:正点原子
主题帖子精华
初级会员, 积分 65, 距离下一级还需 135 积分
在线时间2 小时
回复【3楼】正点原子:
---------------------------------
没改,也说不定什么时候会卡在等待空闲这里的,在while&((SPI_Flash_ReadSR()&0x01)==0x01);里面加了喂狗就不会重启,就一直停在了等待空闲这里了(我加了指示),&如果while&((SPI_Flash_ReadSR()&0x01)==0x01);里面不加喂狗,其他的地方得不到喂狗连续刷卡测试两天两夜,记录了一下被重启了七次。
配置代码:
void&SPI2_Init(void)
& GPIO_InitTypeDef&GPIO_InitS
&& SPI_InitTypeDef&&SPI_InitS
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB,&ENABLE&);//PORTB时钟使能&
RCC_APB1PeriphClockCmd( RCC_APB1Periph_SPI2,&&ENABLE&);//SPI2时钟使能&
GPIO_InitStructure.GPIO_Pin&=&GPIO_Pin_13&|&GPIO_Pin_14&|&GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode&=&GPIO_Mode_AF_PP;&&//PB13/14/15复用推挽输出&
GPIO_InitStructure.GPIO_Speed&=&GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&&GPIO_InitStructure);//初始化GPIOB
& GPIO_SetBits(GPIOB,GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);&&//PB13/14/15上拉
SPI_InitStructure.SPI_Direction&=&SPI_Direction_2Lines_FullD&&//设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工
SPI_InitStructure.SPI_Mode&=&SPI_Mode_M
//设置SPI工作模式:设置为主SPI
SPI_InitStructure.SPI_DataSize&=&SPI_DataSize_8b;
//设置SPI的数据大小:SPI发送接收8位帧结构
SPI_InitStructure.SPI_CPOL&=&SPI_CPOL_H
//串行同步时钟的空闲状态为高电平
SPI_InitStructure.SPI_CPHA&=&SPI_CPHA_2E //串行同步时钟的第二个跳变沿(上升或下降)数据被采样
SPI_InitStructure.SPI_NSS&=&SPI_NSS_S
//NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
SPI_InitStructure.SPI_BaudRatePrescaler&=&SPI_BaudRatePrescaler_256;
//定义波特率预分频的值:波特率预分频值为256
SPI_InitStructure.SPI_FirstBit&=&SPI_FirstBit_MSB; //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
SPI_InitStructure.SPI_CRCPolynomial&=&7; //CRC值计算的多项式
SPI_Init(SPI2,&&SPI_InitStructure);&&//根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
SPI_Cmd(SPI2,&ENABLE);&//使能SPI外设
SPI2_ReadWriteByte(0xff);//启动传输
主题帖子精华
初级会员, 积分 65, 距离下一级还需 135 积分
在线时间2 小时
回复【2楼】lanny_cn:
---------------------------------
都检查过了的,要连续的记录好几个钟才会出现的,要是被卡死了重启后读之前写进去的记录是正确的。难道会是其他的配置干扰了,要一个一个好好检查下。
主题帖子精华
金牌会员, 积分 1490, 距离下一级还需 1510 积分
在线时间14 小时
while&((SPI_Flash_ReadSR()&0x01)==0x01); 这种写法学习还可以,产品代码这样写基本上都要死翘翘
主题帖子精华
初级会员, 积分 153, 距离下一级还需 47 积分
在线时间0 小时
回复【5楼】everymama:
---------------------------------
原子的循环里有个计数的,所以时间长了还是能跑出来的,但还是证明你mpu与w25q64不通的
主题帖子精华
初级会员, 积分 153, 距离下一级还需 47 积分
在线时间0 小时
回复【6楼】beyond696:
---------------------------------
能写嵌入式的都是高手,代码里如果中断级别高的还直接用汇编写呐,类似做法产品很常见
主题帖子精华
初级会员, 积分 65, 距离下一级还需 135 积分
在线时间2 小时
(STM32的SPI功能很强大,SPI时钟最多可以到18Mhz,)我现在把SPI时钟设低点,设为9M,加个计数,时间长了先初始SPI一次再跑出来。希望效果会好点,
主题帖子精华
初级会员, 积分 153, 距离下一级还需 47 积分
在线时间0 小时
回复【9楼】everymama:
---------------------------------
谁说SPI时钟最多可以到18Mhz,SP1明明是36MHz,我读w25q64的4KB数据能只用1.08ms完成,也就是速率4MB/S稍小一点
主题帖子精华
初级会员, 积分 65, 距离下一级还需 135 积分
在线时间2 小时
在STM32开发指南里面看到的。原子哥著的,
799f7a788ebdf_81.jpg (0 Bytes, 下载次数: 0)
22:54 上传
Powered by

我要回帖

更多关于 如何烧写字库w25q64 的文章

 

随机推荐