/* Deselect the FLASH: Chip Select high */ SPI_FLASH_CS_HIGH();
return (Temp0 << 8) | Temp1; }
/******************************************************************************* * Function Name : SPI_FLASH_ReadByte * Description : Reads a byte from the SPI Flash. * This function must be used only if the Start_Read_Sequence * function has been previously called. * Input : None * Output : None * Return : Byte Read from the SPI Flash. *******************************************************************************/ u8 SPI_FLASH_ReadByte(void) { return (SPI_FLASH_SendByte(0x5A)); }
/******************************************************************************* * Function Name : SPI_FLASH_SendByte * Description : Sends a byte through the SPI interface and return the byte * received from the SPI bus. * Input : byte : byte to send. * Output : None * Return : The value of the received byte. *******************************************************************************/ u8 SPI_FLASH_SendByte(u8 byte) { /* Loop while DR register in not emplty */ while(SPI_GetFlagStatus(SPI1, SPI_FLAG_TXE) == RESET);
/* Send byte through the SPI1 peripheral */ SPI_SendData(SPI1, byte);
/* Wait to receive a byte */ while(SPI_GetFlagStatus(SPI1, SPI_FLAG_RXNE) == RESET);
/* Return the byte read from the SPI bus */ return SPI_ReceiveData(SPI1); }
/************************************************************************/ /* PROCEDURE: WRSR */ /* */ /* This procedure writes a byte to the Status Register. */ /* */ /* Input: */ /* byte */ /* */ /* Returns: */ /* Nothing */ /************************************************************************/ void CMD_WRSR(u8 byte) { SPI_FLASH_CS_LOW(); /* enable device */ SPI_FLASH_SendByte(0x01); /* select write to status register */ SPI_FLASH_SendByte(byte); /* data that will change the status of BPx or BPL (only bits 2,3,7 can be written) */ SPI_FLASH_CS_HIGH(); /* disable the device */ }
//************************************************************************ // This procedure reads one address of the device. It will return the // byte read in variable byte. //************************************************************************ u8 SST25_ReadByte(u32 Dst) { unsigned char byte = 0;
//*************************************************************************************** // This procedure reads multiple addresses of the device and stores data into buffer. //*************************************************************************************** void SST25_ReadBuffer(u32 nAddr, u32 nSize, u8* pBuf) { u32 i = 0; SPI_FLASH_CS_LOW(); // enable device SPI_FLASH_SendByte(0x03); //read command */ SPI_FLASH_SendByte((u8)(nAddr>>16)); // send 3 address bytes SPI_FLASH_SendByte((u8)(nAddr>>8 )); SPI_FLASH_SendByte((u8)nAddr); for (i = 0; i < nSize; i++) // read until no_bytes is reached { pBuf = SPI_FLASH_ReadByte(); // receive byte and store to buffer } SPI_FLASH_CS_HIGH(); /* disable device */ }
void SST25_WriteEnable(u8 bEn) { if(bEn) { CMD_EWSR(); CMD_WRSR(0); } else { CMD_EWSR(); CMD_WRSR(0x0C); } } //************************************************************************/ // This procedure programs one address of the device. // Assumption: Address being programmed is already erased and is NOT block protected. //************************************************************************/ void SST25_WriteByte(u32 Dst, u8 byte) { SPI_FLASH_CS_LOW(); /* enable device */ SPI_FLASH_SendByte(0x02); /* send Byte Program command */ SPI_FLASH_SendByte(((Dst & 0xFFFFFF) >> 16)); /* send 3 address bytes */ SPI_FLASH_SendByte(((Dst & 0xFFFF) >> 8)); SPI_FLASH_SendByte(Dst & 0xFF); SPI_FLASH_SendByte(byte); /* send byte to be programmed */ SPI_FLASH_CS_HIGH(); /* disable device */
SPI_FLASH_WaitReady(); }
//*************************************************************************************** // This procedure write multiple data from buffer to the device. //*************************************************************************************** void SST25_WriteBuffer(u32 nAddr, u32 nSize, u8* pBuf) { u32 i = 0;
//************************************************************************ // This procedure waits until device is no longer busy (can be used by // Byte-Program, Sector-Erase, Block-Erase, Chip-Erase). //************************************************************************ void SPI_FLASH_WaitReady() { while (Read_Status_Register() & 0x01); }
//************************************************************************ // This procedure waits until device is no longer busy for AAI mode. //************************************************************************ void Wait_Busy_AAI() { while (Read_Status_Register() == 0x43) /* waste time until not busy */ Read_Status_Register(); }
//************************************************************************ // This procedure checks to see if WEL bit set before program/erase. //************************************************************************ void WREN_Check() { unsigned char byte; byte = Read_Status_Register(); /* read the status register */ if (byte != 0x02) /* verify that WEL bit is set */ { // while(1) /* option: insert a display to view error on LED? */ } }
//************************************************************************ // This procedure checks for AAI and WEL bit once in AAI mode. //************************************************************************ void WREN_AAI_Check() { unsigned char byte; byte = Read_Status_Register(); /* read the status register */ if (byte != 0x42) /* verify that AAI and WEL bit is set */ { // while(1) /* option: insert a display to view error on LED? */ } }
因为SPI_I2S_ReceiveData(SPI1);只从接收缓冲区中取数,而W25X20仍需要发送时钟信号才能读出数据.而且SPI_I2S_SendData(SPI1,0x05);也需要读出数据才能保证后续读出数据正确.所以你无论是送数还是取数,都应该完成这四个语句: u8 SPI_FLASH_SendByte(u8 byte) { /* Loop while DR register in not emplty */ while(SPI_GetFlagStatus(SPI1, SPI_FLAG_TXE) == RESET);
/* Send byte through the SPI1 peripheral */ SPI_SendData(SPI1, byte);
/* Wait to receive a byte */ while(SPI_GetFlagStatus(SPI1, SPI_FLAG_RXNE) == RESET);
/* Return the byte read from the SPI bus */ return SPI_ReceiveData(SPI1); }