Purpose: Read and write data
The key part of the chip manual is the instruction module , especially the timing
How to read data: one instruction , one address , one variable buff , no protection
Pay attention to the number of bits in the address
How to write data: Write data must not remove write protection and obtain permission.
The following focuses on how to write:
u32 secpos;
u16 secoff;
u16 secremain; u16 i; u8 * W25QXX_BUF; W25QXX_BUF=W25QXX_BUFFER; secpos=WriteAddr/4096;//Sector address secoff=WriteAddr%4096;//Offset in sector secremain=4096- secoff;//Sector remaining space size //printf("ad:%X,nb:%X\r\n",WriteAddr,NumByteToWrite);//Test if(NumByteToWrite<=secremain)secremain=NumByteToWrite;/ / no larger than 4096 bytes
while(1)
{ W25QXX_Read(W25QXX_BUF,secpos*4096,4096); //Read the content of the entire sector for(i=0;i<secremain;i++) //Check data { if(W25QXX_BUF[secoff+i ]!=0XFF)break ; //Need to erase } if(i<secremain)//Need to erase { W25QXX_Erase_Sector(secpos); // Erase this sector for(i=0;i<secremain;i++) / /copy { W25QXX_BUF[ i+secoff ]=pBuffer[i]; //The purpose of this statement is to copy the data in buf smaller than scremain into the chip } W25QXX_Write_NoCheck(W25QXX_BUF, secpos*4096 , 4096 );// Write entire sector }else W25QXX_Write_NoCheck(pBuffer, WriteAddr
, secremain );//Write what has been erased, directly write to the remaining area of the sector. //Note the difference between writeadrr and secpos because the previous one is to erase a whole piece, so the address starts from the beginning and the latter does not need to be erased so The address remains unchanged; if(NumByteToWrite==secremain)break;//The writing is over else//The writing is not over { secpos++;//The sector address is increased by 1 secoff=0;//The offset position is 0 pBuffer+= secremain; //Pointer offset WriteAddr+=secremain; //Write address offset
NumByteToWrite-=secremain; //The number of bytes is decremented
else secremain=NumByteToWrite; //The next sector can be finished
}
};
Summarize:
Write data to the chip: divided into write sector and write the smallest unit, but the final write sector function has to call a small function because it is stipulated that only 256 bytes of data can be written at most
1. How big is the writing? where to write?
Answer: Define the size of NumByteToWrite by yourself, and define the address WriteAddr that does not exceed the size of falsh
2. What should I do before writing?
answer:
enable write;
The result is the number of sectors secpos= WriteAddr /4096 and secremain=4096- WriteAddr %4096 ( the remaining capacity of a sector )
Due to the limited amount of sector remaining, it can only be written less than or equal to secret at the beginning
if(NumByteToWrite<=secremain)
secret=NumByteToWrite ;//Not more than 4096 bytes
Check if the sector is empty i.e. 0xff if it is not empty it needs to be erased
3. How to check whether the sector is empty?
The data of the WriteAddr /4096 block must be read out and put into the readbuf[4096] buffer area, and then the data byte by byte is judged whether it is ==0xff
if(W25QXX_BUF[secoff+i]!=0XFF)break ; //Need to erase
4. How to erase?
Pass the block sector address to the sector erase function
i.e. secpos*= 4096
Note: The erased write data address is secpos*4096 and the write data size is also 4096
W25QXX_Write_NoCheck( W25QXX_BUF , secpos*4096,4096 );// Write the entire sector
If not erased then
else W25QXX_Write_NoCheck( pBuffer , WriteAddr , secremain ); Note the parameters passed by the upper and lower functions
5. The datanum may be larger than the remaining capacity of the sector. What should I do?
Fill up the remaining capacity first, and then write data to the next sector,
NOTE: At this point it should be
NumByteToWrite = NumByteToWrite -secremain (minus the remaining capacity, because the secret has been written, the next time it will not write NumByteToWrite data, but NumByteToWrite -secremain)
secret= NumByteToWrite (when datanum<4096) one sector is enough, otherwise secret=4096
The original number of sectors +1, because you want to continue to write data to the next sector
The offset address secoff =WriteAddr%4096 becomes (relative to the current sector) 0 because it is the beginning of the next sector
code show as below:
secpos++;//Increase sector address by 1
secoff=0;//Offset position is 0 pBuffer+=secremain; //Pointer offset WriteAddr+=secremain; //Write address offset NumByteToWrite-=secremain; //Decrease the number of bytes if(NumByteToWrite>4096)secremain=4096;//The next sector is still unfinished else secremain=NumByteToWrite; //The next sector can be written