下面是W25X16的驱动程序,发现写数据,读数据没有问题,但是在用SPI_FLASH_ReadID读器件ID的时候总是返回0x00,哪里出了问题了?谢谢了
/******************************
* | PA4-SPI1-NSS : W25X16-CS |
* | PA5-SPI1-SCK : W25X16-CLK |
* | PA6-SPI1-MISO : W25X16-DO |
* | PA7-SPI1-MOSI : W25X16-DIO |
* ----------------------------
******************************/
#include "SPI_W25X16.h"
#define SPI_FLASH_PerWritePageSize 256 //每一页256个字节
#define W25X16_WriteEnable 0x06
#define W25X16_WriteDisable 0x04
#define W25X16_ReadStatusReg 0x05
#define W25X16_WriteStatusReg 0x01
#define W25X16_ReadData 0x03
#define W25X16_FastReadData 0x0B
#define W25X16_FastReadDual 0x3B
#define W25X16_PageProgram 0x02
#define W25X16_BlockErase 0xD8
#define W25X16_SectorErase 0x20
#define W25X16_ChipErase 0xC7
#define W25X16_PowerDown 0xB9
#define W25X16_ReleasePowerDown 0xAB
#define W25X16_DeviceID 0xAB
#define W25X16_ManufactDeviceID 0x90
#define W25X16_JedecDeviceID 0x9F
#define WIP_Flag 0x01
#define Dummy_Byte 0xff //随意的字节
void SPI_FLASH_Init(void)
{
SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
//使能GPIOA SPI时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_SPI1,ENABLE);
//四个引脚都设置为了复用推挽输出
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_4;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_Init(GPIOA,&GPIO_InitStructure);
//不选择FLASH
SPI_FLASH_CS_HIGH();
//配置SPI
SPI_InitStructure.SPI_Direction=SPI_Direction_2Lines_FullDuplex;//双向全双工
SPI_InitStructure.SPI_Mode=SPI_Mode_Master ;
SPI_InitStructure.SPI_DataSize=SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL=SPI_CPOL_High;
SPI_InitStructure.SPI_CPHA=SPI_CPHA_2Edge;
SPI_InitStructure.SPI_NSS=SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_4;
SPI_InitStructure.SPI_FirstBit=SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial=7;
SPI_Init(SPI1,&SPI_InitStructure);
SPI_Cmd(SPI1,ENABLE);
}
//send a byte through the spi interface and return the byte receive from the SPI bus
u8 SPI_FLASH_SendByte(u8 byte)
{
//等待DR为空
while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)==RESET);
SPI_I2S_SendData(SPI1,byte);
//等待接收数据
while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE)==RESET);
return SPI_I2S_ReceiveData(SPI1);
}
//Enable the Write access to the FALSH
void SPI_FLASH_WriteEnable(void)
{
SPI_FLASH_CS_LOW();
//使能 写
SPI_FLASH_SendByte(W25X16_WriteEnable);
SPI_FLASH_CS_HIGH();
}
//wait for write complete
void SPI_FLASH_WaitForWriteEnd(void)
{
u8 FLASH_Status=0;
SPI_FLASH_CS_LOW();
//读状态寄存器
SPI_FLASH_SendByte(W25X16_ReadStatusReg);
do
{
//send a dummy byte to generate the clock needed by the flash
//and return the value of the status register
FLASH_Status=SPI_FLASH_SendByte(Dummy_Byte);
} while((FLASH_Status&WIP_Flag)==SET);
SPI_FLASH_CS_HIGH();
}
// 扇区擦除4KB SectorAddr为起始地址
void SPI_FLASH_SectorErase(u32 SectorAddr)
{
SPI_FLASH_WriteEnable();
SPI_FLASH_WaitForWriteEnd();
//sector erase
SPI_FLASH_CS_LOW();
SPI_FLASH_SendByte(W25X16_SectorErase);
//send sectorAddr high address byte
SPI_FLASH_SendByte((SectorAddr&0xFF0000)>>16);
SPI_FLASH_SendByte((SectorAddr&0xFF00)>>8);
SPI_FLASH_SendByte(SectorAddr&0xFF);
SPI_FLASH_CS_HIGH();
SPI_FLASH_WaitForWriteEnd();
}
// Erase the entire FLASH
void SPI_FLASH_BulkErase(void)
{
SPI_FLASH_WriteEnable();
SPI_FLASH_WaitForWriteEnd();
SPI_FLASH_CS_LOW();
SPI_FLASH_SendByte(W25X16_ChipErase);
SPI_FLASH_CS_HIGH();
SPI_FLASH_WaitForWriteEnd();
}
//Writes more than one bytes to the flash, the number of the byte can not
// exceed the FLASH page size (256)
//此函数只能写入小于等于256个字节
void SPI_FLASH_PageWrite(u8 *pBuffer,u32 WriteAddr,u16 NumByteToWrite)
{
SPI_FLASH_WriteEnable();
SPI_FLASH_WaitForWriteEnd();
SPI_FLASH_CS_LOW();
SPI_FLASH_SendByte(W25X16_PageProgram);
SPI_FLASH_SendByte((WriteAddr&0xFF0000)>>16);
SPI_FLASH_SendByte((WriteAddr&0xFF00)>>8);
SPI_FLASH_SendByte(WriteAddr&0xFF);
if(NumByteToWrite>SPI_FLASH_PerWritePageSize)
{
NumByteToWrite=SPI_FLASH_PerWritePageSize;
}
while(NumByteToWrite--)
{
SPI_FLASH_SendByte(*pBuffer);
pBuffer++;
}
SPI_FLASH_CS_HIGH();
SPI_FLASH_WaitForWriteEnd();
}
//将缓冲区的数据写入flash中,字节数不要大于整个芯片的字节数
void SPI_FLASH_BufferWrite(u8 *pBuffer,u32 WriteAddr,u16 NumByteToWrite)
{
u8 NumOfPage=0,NumOfSingle=0,Addr=0,count=0,temp=0;
Addr=WriteAddr%SPI_FLASH_PerWritePageSize;
count=SPI_FLASH_PerWritePageSize-Addr;
NumOfPage=NumByteToWrite/SPI_FLASH_PerWritePageSize;
NumOfSingle=NumByteToWrite%SPI_FLASH_PerWritePageSize;
if(Addr==0) //起始地址是256的整数倍
{
if(NumOfPage==0) //小于256个字节
{
SPI_FLASH_PageWrite(pBuffer,WriteAddr,NumByteToWrite);
}
else //多于256个字节
{
while(NumOfPage--)
{
SPI_FLASH_PageWrite(pBuffer,WriteAddr,SPI_FLASH_PerWritePageSize);
WriteAddr+=SPI_FLASH_PerWritePageSize;
pBuffer+=SPI_FLASH_PerWritePageSize;
}
SPI_FLASH_PageWrite(pBuffer,WriteAddr,NumOfSingle);
}
}
else
{
if(NumOfPage==0) //
{
if(NumOfSingle>count)
{
temp=NumOfSingle-count;
SPI_FLASH_PageWrite(pBuffer,WriteAddr,count);
WriteAddr+=count;
pBuffer+=count;
SPI_FLASH_PageWrite(pBuffer,WriteAddr,temp);
}
else
{
SPI_FLASH_PageWrite(pBuffer,WriteAddr,NumByteToWrite);
}
}
else //多于256个字节
{
NumByteToWrite-=count;
NumOfPage=NumByteToWrite/SPI_FLASH_PerWritePageSize;
NumOfSingle=NumByteToWrite%SPI_FLASH_PerWritePageSize;
SPI_FLASH_PageWrite(pBuffer,WriteAddr,count);
WriteAddr+=count;
pBuffer+=count;
while(NumOfPage--)
{
SPI_FLASH_PageWrite(pBuffer,WriteAddr,SPI_FLASH_PerWritePageSize);
WriteAddr+=SPI_FLASH_PerWritePageSize;
pBuffer+=SPI_FLASH_PerWritePageSize;
}
if(NumOfSingle!=0)
{
SPI_FLASH_PageWrite(pBuffer,WriteAddr,NumOfSingle);
}
}
}
}
// read a block of data from the FLASH
void SPI_FLASH_BufferRead(u8 *pBuffer,u32 ReadAddr,u16 NumByteToRead)
{
SPI_FLASH_CS_LOW();
SPI_FLASH_SendByte(W25X16_ReadData);
SPI_FLASH_SendByte((ReadAddr&0xFF0000)>>16);
SPI_FLASH_SendByte((ReadAddr&0xFF00)>>8);
SPI_FLASH_SendByte(ReadAddr&0xFF);
while(NumByteToRead--)
{
*pBuffer=SPI_FLASH_SendByte(Dummy_Byte);
pBuffer++;
}
SPI_FLASH_CS_HIGH();
}
// Read FLASH identification
u32 SPI_FLASH_ReadID(void)
{
u32 temp=0,temp0=0,temp1=0,temp2=0;
SPI_FLASH_CS_LOW();
SPI_FLASH_SendByte(W25X16_JedecDeviceID);
temp0=SPI_FLASH_SendByte(Dummy_Byte);
temp1=SPI_FLASH_SendByte(Dummy_Byte);
temp2=SPI_FLASH_SendByte(Dummy_Byte);
SPI_FLASH_CS_HIGH();
temp=(temp0<<16)|(temp1<<8)|temp2;
return temp;
}
/*******************************************************************************
* Function Name : SPI_FLASH_ReadID
* Description : Reads FLASH identification.
* Input : None
* Output : None
* Return : FLASH identification
*******************************************************************************/
u32 SPI_FLASH_ReadDeviceID(void)
{
u32 Temp = 0;
/* Select the FLASH: Chip Select low */
SPI_FLASH_CS_LOW();
/* Send "RDID " instruction */
SPI_FLASH_SendByte(W25X16_DeviceID);
SPI_FLASH_SendByte(Dummy_Byte);
SPI_FLASH_SendByte(Dummy_Byte);
SPI_FLASH_SendByte(Dummy_Byte);
/* Read a byte from the FLASH */
Temp = SPI_FLASH_SendByte(Dummy_Byte);
/* Deselect the FLASH: Chip Select high */
SPI_FLASH_CS_HIGH();
return Temp;
}
//进入掉电模式
void SPI_FLASH_PowerDown(void)
{
SPI_FLASH_CS_LOW();
SPI_FLASH_SendByte(W25X16_PowerDown);
SPI_FLASH_CS_HIGH();
}
//唤醒
void SPI_FLASH_WAKEUP(void)
{
SPI_FLASH_CS_LOW();
SPI_FLASH_SendByte(W25X16_ReleasePowerDown);
SPI_FLASH_CS_HIGH();
}
转载
|