IO模拟SPI FLASH W25Q64B [IO模拟SPI时序,使用FLASH W25Q64B]

#include "iospiflash.h"

/*******************************************
//
// This is a IOSPI (simulater by IO)
//
// Lib For Driver Flash W25Q64BV
//
*******************************************/
//sbit IOFLASHSPI_CS = P1^0;
//sbit IOFLASHSPI_DIN = P1^3;
//sbit IOFLASHSPI_DOUT = P1^4;
//sbit IOFLASHSPI_CLK = P1^5;

/*******************************************
//
// IOSPI base FUNC
// Data shifting at the --rising edge-- of the clk
// CLK need a hold time MyDelay(3)
//
// Shift
// Write u8
// Read u8
//
// 1
Time Series requires:
The W25Q64B Flash support the stantdard SPI , but the SPI Mode 0 or 3.
SPI Mode 0 required that:
when free:
the CLK need be low - 0 , while the /CS is high( when free );
when execute an instruction:
Fall the /CS that Enable the Flash.
0 - 1 - 0 - 1 the CLK,
when the rasing edge of CLK, the DOUT(0,1) will be send to the FLASH.
when a whole instruction completed.
need to! PULL up the /CS than Over an Instruction.

SPI Mode 3 required that:
..... /CS /CLK the reverse.

2
Other IO need!
/HOLD --- like a enable pin.
when /hold is Low,the FLASH ,can not excute any instructions.


//
*******************************************/
u8 IOSPI_Flash_Shift(u8 Data)
{
u8 DataRead = 0xFF;
u8 i = 0;
for(i = 0 ; i < 8 ; i++)
{
IOFLASHSPI_CLK = 0; //fall edge chage the out data bit
IOFLASHSPI_DOUT = ((Data & 0x80) == 0x80 )?1 : 0;
Data <<= 1;
DataRead <<= 1;

MyDelay(5);

IOFLASHSPI_CLK = 1; //rising edge
// the rising edge out the data bit and in the data bit
MyDelay(5);
if(IOFLASHSPI_DIN==1) //get bit
DataRead += 1;
}

return DataRead;

}
//rising edge of CLK
//!!!!!the CLK should be keep 0,while there is not excuting any instructions!
void IOSPI_Flash_u8_Write(u8 Data)
{
u8 i = 0;
for(i = 0 ; i < 8 ; i++)
{
IOFLASHSPI_CLK = 0;
IOFLASHSPI_DOUT = (Data & 0x80);
Data <<= 1;
MyDelay(5);
IOFLASHSPI_CLK = 1; //rising edge
MyDelay(5);
}

IOFLASHSPI_CLK = 0;
}

u8 IOSPI_Flash_u8_Read(void)
{
u8 Data = 0xFF;
u8 i = 0;
for(i = 0 ; i < 8 ; i++)
{
IOFLASHSPI_CLK = 0;
Data <<= 1;
MyDelay(5); //hold time
IOFLASHSPI_CLK = 1; //rising edge
MyDelay(5);
if(IOFLASHSPI_DIN==1) //get bits
Data += 1;
}
IOFLASHSPI_CLK = 0;
return Data;
}

//-----------------------------------
//
// IOSPI FLASH FUNC
//
//-----------------------------------
void IOSPI_Flash_CMD(u8 CMD)
{
IOSPI_Flash_u8_Write(CMD);
}

u8 IOSPI_Flash_RDSR(void)
{
u8 ReadStatus = 0;

IOSPI_FLASH_CS_ENABLE

IOSPI_Flash_CMD(CMD_RDSR); //time series need to be learn
ReadStatus = IOSPI_Flash_u8_Read();

IOSPI_FLASH_CS_DISABLE //cs over the instruction

return ReadStatus;
}

u32 IOSPI_Flash_RDJCID()
{
u8 i = 0;
u32 JCID = 0x00000000;
u8 *pData = &JCID;

IOSPI_FLASH_CS_ENABLE

IOSPI_Flash_CMD(CMD_RDJCID); //time series need to be learn
for(i = 0 ; i < 3 ; i++)
{
*(pData++) = IOSPI_Flash_u8_Read();
}

IOSPI_FLASH_CS_DISABLE //cs over the instruction

return JCID;
}

void IOSPI_Flash_WaitFree(void)
{
while((IOSPI_Flash_RDSR() & 0x01)==0x01) //check the busy = 0;
{
MyDelay(30);
}
}


//---------------------------------------------------------
//
// 4K byte Erase 16 pages
//
//---------------------------------------------------------
void IOSPI_Flash_SectorErase(u32 Addr)
{
u8* pAddr = &Addr;
IOSPI_Flash_WaitFree();

IOSPI_FLASH_CS_ENABLE
IOSPI_Flash_CMD(CMD_ENABLEWRITE);
IOSPI_FLASH_CS_DISABLE

MyDelay(5);

IOSPI_FLASH_CS_ENABLE
IOSPI_Flash_CMD(CMD_SECERASE);
IOSPI_Flash_u8_Write(*pAddr++);
IOSPI_Flash_u8_Write(*pAddr++);
IOSPI_Flash_u8_Write(*pAddr);
IOSPI_FLASH_CS_DISABLE
}
//void IOSPI_Flash_BlockErase(u8* Addr);


//-----------------------------------------------------------------
//
// Page Programe
// the data to be programe must less than 256bytes,
// otherwise the page will be wrap by the bytes lengther than the 256 bytes;
//
//-----------------------------------------------------------------
void IOSPI_Flash_Write(u32 Addr , char* Data , u16 length)
{
u16 i = 0;
u8 pData = 0x00;
u8* pAddr = &Addr;
if(length > 256)
return ;

IOSPI_Flash_WaitFree();

IOSPI_FLASH_CS_ENABLE
IOSPI_Flash_CMD(CMD_ENABLEWRITE);
IOSPI_FLASH_CS_DISABLE

MyDelay(5);

IOSPI_FLASH_CS_ENABLE
IOSPI_Flash_CMD(CMD_PAGEWRITE);
IOSPI_Flash_u8_Write(*pAddr++);
IOSPI_Flash_u8_Write(*pAddr++);
IOSPI_Flash_u8_Write(*pAddr);

for(i = 0 ; i < length ; i++)
{
IOSPI_Flash_u8_Write(*(Data+i));
}
IOSPI_FLASH_CS_DISABLE

}

//-----------------------------------------------------
//
// Standard Flash Read.
// Can Read 256 bytes once at most.
//
//-----------------------------------------------------
void IOSPI_Flash_Read(u32 Addr , char* Data , u16 length)
{
u16 i = 0;
u8* pAddr = &Addr;
IOSPI_Flash_WaitFree();

IOSPI_FLASH_CS_ENABLE
IOSPI_Flash_CMD(CMD_READ);
IOSPI_Flash_u8_Write(*pAddr++);
IOSPI_Flash_u8_Write(*pAddr++);
IOSPI_Flash_u8_Write(*pAddr);

for(i = 0 ; i < length ; i++)
{
*(Data+i) = IOSPI_Flash_u8_Read();
}
IOSPI_FLASH_CS_DISABLE

}

void IOSPI_Flash_FastRead(u32 Addr , char* Data , u16 length)
{
u16 i = 0;
u8* pAddr = &Addr;
if(length > 256)
return ;
IOSPI_Flash_WaitFree();

IOSPI_FLASH_CS_ENABLE
IOSPI_Flash_CMD(CMD_FASTREAD);
IOSPI_Flash_u8_Write(*pAddr++);
IOSPI_Flash_u8_Write(*pAddr++);
IOSPI_Flash_u8_Write(*pAddr);
IOSPI_Flash_u8_Write(0x00);

for(i = 0 ; i < length ; i++)
{
*(Data+i) = IOSPI_Flash_u8_Read();
}
IOSPI_FLASH_CS_DISABLE
}

===========================================================================================================

===========================================================================================================

=========================================================================================================== 

#ifndef __IOSPIFLASH_H
#define __IOSPIFLASH_H
#include "Common.h"
/**************************************************************
//
// W25Q64BVSFIG FLASH
//
//
*************************************************************/
#define CMD_RDSR 0x05
#define CMD_ENABLEWRITE 0x06
#define CMD_DISABLEWRITE 0x04
#define CMD_WDSR 0x01
#define CMD_READ 0x03
#define CMD_FASTREAD 0x0B
#define CMD_PAGEWRITE 0x02
#define CMD_SECERASE 0x20
#define CMD_BLOCKERASE 0x52
#define CMD_RDJCID 0x9F


#define IOSPI_FLASH_CS_ENABLE {IOFLASHSPI_CS = 0;}
#define IOSPI_FLASH_CS_DISABLE {IOFLASHSPI_CS = 1;}


u8 IOSPI_Flash_Shift(u8 Data);
void IOSPI_Flash_u8_Write(u8 Data);
u8 IOSPI_Flash_u8_Read(void);

void IOSPI_Flash_CMD(u8 CMD);
u8 IOSPI_Flash_RDSR(void);
void IOSPI_Flash_WaitFree(void);
void IOSPI_Flash_SectorErase(u32 Addr);
//void IOSPI_Flash_BlockErase(u2 Addr);
void IOSPI_Flash_Write(u32 Addr , char* Data , u16 length);
void IOSPI_Flash_Read(u32 Addr , char* Data , u16 length);
void IOSPI_Flash_FastRead(u32 Addr , char* Data , u16 length);

u32 IOSPI_Flash_RDJCID(void);


#endif

原文地址:https://www.cnblogs.com/hisoka/p/4794649.html