新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > STM32 SPI W25X16驅動

STM32 SPI W25X16驅動

作者: 時間:2016-11-25 來源:網(wǎng)絡 收藏

void User_SPI_W25X16_WaitForWriteEnd(void)
{
u8 ReceiveStatus;//用于存放W25X16返回的狀態(tài)非零就是操作結束

SPI_W25X16_CS_Select;

User_SPI_W25X16_SendByte(ReadStatusRegister);

do
{
ReceiveStatus=User_SPI_W25X16_SendByte(NoneCode);
}
while(ReceiveStatus & JudgeCode==SET);

SPI_W25X16_CS_DisSelect;
}

本文引用地址:http://butianyuan.cn/article/201611/321302.htm


void User_SPI_W25X16_SectorErase(vu32 SectorAddress)
{

User_SPI_W25X16_WriteEnable();

SPI_W25X16_CS_Select;


User_SPI_W25X16_SendByte(SectorErase);

User_SPI_W25X16_SendByte((SectorAddress & 0xff0000)>>16); //發(fā)送最高8位
User_SPI_W25X16_SendByte((SectorAddress & 0xff00)>>8); // 中間8位
User_SPI_W25X16_SendByte(SectorAddress & 0xff); //發(fā)送最低8位


SPI_W25X16_CS_DisSelect;


User_SPI_W25X16_WaitForWriteEnd();
}


void User_SPI_W25X16_BulkErase(void)
{

User_SPI_W25X16_WriteEnable();

SPI_W25X16_CS_Select;


User_SPI_W25X16_SendByte(ChipErase);


SPI_W25X16_CS_DisSelect;


User_SPI_W25X16_WaitForWriteEnd();
}


void User_SPI_W25X16_PageWrite(u8 *DataTable,vu32 WriteAddress,vu16 NumberOfWrite)
{

User_SPI_W25X16_WriteEnable();

SPI_W25X16_CS_Select;


User_SPI_W25X16_SendByte(PageProgram);


User_SPI_W25X16_SendByte((WriteAddress & 0xff0000)>>16); //最高8位地址
User_SPI_W25X16_SendByte((WriteAddress & 0xff00)>>8); //中間8位地址
User_SPI_W25X16_SendByte(WriteAddress & 0xff); //最低8位地址


if(NumberOfWrite > SPI_W25X16_PerPageWriteSize) //W25X16采用的是頁寫入方式,最多一次性寫入256個數(shù)據(jù),然后內部地址指針歸零
{
NumberOfWrite=SPI_W25X16_PerPageWriteSize;
printf("哦偶,一次性寫入的數(shù)據(jù)太多,不能超過256的啦,ARM將為你寫入前256個數(shù)據(jù)");
}


while(NumberOfWrite--)
{
User_SPI_W25X16_SendByte(*DataTable);
DataTable++; //數(shù)組指針 +1
}

SPI_W25X16_CS_DisSelect;


User_SPI_W25X16_WaitForWriteEnd();
}


void User_SPI_W25X16_ChipWrite(u8 *DataTable,vu32 WriteAddress,vu16 NumberOfWrite)
{
u8 AddressRemainder =0;
u8 NumberOfPage =0;
u8 Count =0; //存放地址所在頁需要寫入的最多數(shù)據(jù)
u8 NumberOfSingle =0; //寫入數(shù)據(jù)的最后一些需要寫入的數(shù)據(jù)個數(shù)
u8 Buffer =0; //保留

AddressRemainder =WriteAddress % SPI_W25X16_PageSize;
Count =SPI_W25X16_PageSize - AddressRemainder;
NumberOfPage =NumberOfWrite / SPI_W25X16_PageSize;
NumberOfSingle =NumberOfWrite % SPI_W25X16_PageSize;


if(AddressRemainder==0)
{

if(NumberOfPage==0) //NumberOfWrite < SPI_W25X16_PageSize
{
User_SPI_W25X16_PageWrite(DataTable,WriteAddress,NumberOfWrite);
}

else
{

while(NumberOfPage--)
{
User_SPI_W25X16_PageWrite(DataTable,WriteAddress,SPI_W25X16_PageSize); //一次性寫入256個
DataTable+=SPI_W25X16_PageSize; //接著寫下一個256數(shù)據(jù)
WriteAddress+=SPI_W25X16_PageSize; //地址就移到下一頁(256為單位)
}

User_SPI_W25X16_PageWrite(DataTable,WriteAddress,NumberOfSingle);
}
}

else
{

if(NumberOfPage==0)
{

if(NumberOfWrite < Count)
{
User_SPI_W25X16_PageWrite(DataTable,WriteAddress,NumberOfWrite);
}

else
{

User_SPI_W25X16_PageWrite(DataTable,WriteAddress,Count); //起始地址所在頁只需要寫入Count個
Buffer=NumberOfWrite-Count; //計算出下一頁要寫入的數(shù)據(jù)數(shù)量
DataTable+=Count;
WriteAddress+=Count;


User_SPI_W25X16_PageWrite(DataTable,WriteAddress,Buffer);
}
}

else
{

User_SPI_W25X16_PageWrite(DataTable,WriteAddress,Count);

//之后需要重新計算以下參數(shù) 原因:數(shù)據(jù)量超過一頁分兩種情況:1、數(shù)據(jù)量不會覆蓋完起始地址下一頁;2、數(shù)據(jù)量會完全覆蓋起始地址下一頁
//重新計算就是看是否會覆蓋掉下一頁,如果會就進入while()循環(huán),否則就不進入
DataTable+=Count;
WriteAddress+=Count;
NumberOfWrite-=Count;
NumberOfPage=NumberOfWrite / SPI_W25X16_PageSize;
NumberOfSingle=NumberOfWrite % SPI_W25X16_PageSize;


while(NumberOfPage--)
{
User_SPI_W25X16_PageWrite(DataTable,WriteAddress,SPI_W25X16_PageSize);
DataTable+=SPI_W25X16_PageSize;
WriteAddress+=SPI_W25X16_PageSize;
}


if(NumberOfSingle != 0)
{
User_SPI_W25X16_PageWrite(DataTable,WriteAddress,NumberOfSingle);
}
}
}
}


void User_SPI_W25X16_ChipRead(u8 *DataTable,vu32 ReadAddress,vu16 NumberOfRead)
{
//雖然要發(fā)送地址,但是不需要說明有個寫操作(I2C才是這樣的時序)
SPI_W25X16_CS_Select;


User_SPI_W25X16_SendByte(ReadData);


User_SPI_W25X16_SendByte((ReadAddress & 0xff0000) >> 16); //最高8位地址
User_SPI_W25X16_SendByte((ReadAddress & 0xff00) >> 8); //中間8位
User_SPI_W25X16_SendByte(ReadAddress & 0xff); //最低8位


while(NumberOfRead--)
{
*DataTable = User_SPI_W25X16_SendByte(NoneCode);
DataTable++;
}


SPI_W25X16_CS_DisSelect;
}


vu32 User_SPI_W25X16_ReadID(void)
{
vu32 ID =0;
vu32 IDBuffer1=0;
vu32 IDBuffer2=0;
vu32 IDBuffer3=0;

SPI_W25X16_CS_Select;

User_SPI_W25X16_SendByte(JedecID);


IDBuffer1=User_SPI_W25X16_SendByte(NoneCode);//讀取高位
IDBuffer2=User_SPI_W25X16_SendByte(NoneCode);//讀取中位
IDBuffer3=User_SPI_W25X16_SendByte(NoneCode);//讀取低位

SPI_W25X16_CS_DisSelect;

ID=(IDBuffer1<<16)|(IDBuffer2<<8)|IDBuffer3;

return ID;
}


vu32 User_SPI_W25X16_ReadDeviceID(void)
{
vu32 ID =0;
vu32 IDBuffer1=0;
vu32 IDBuffer2=0;
vu32 IDBuffer3=0;

SPI_W25X16_CS_Select;

User_SPI_W25X16_SendByte(ManufatureID);


IDBuffer1=User_SPI_W25X16_SendByte(NoneCode);//讀取高位
IDBuffer2=User_SPI_W25X16_SendByte(NoneCode);//讀取中位
IDBuffer3=User_SPI_W25X16_SendByte(NoneCode);//讀取低位

SPI_W25X16_CS_DisSelect;

ID=(IDBuffer1<<16)|(IDBuffer2<<8)|IDBuffer3;

return ID;
}


void User_SPI_W25X16_StartReadSequence(vu32 ReadAddress)
{
SPI_W25X16_CS_Select;

User_SPI_W25X16_SendByte(ReadData);

User_SPI_W25X16_SendByte((ReadAddress & 0xff0000) >> 16); //最高8位地址
User_SPI_W25X16_SendByte((ReadAddress & 0xff00) >> 8); //中間8位
User_SPI_W25X16_SendByte(ReadAddress & 0xff); //最低8位

//SPI_W25X16_DisSelect;
}


void User_SPI_W25X16_PowerDown(void)
{
SPI_W25X16_CS_Select;

User_SPI_W25X16_SendByte(PowerDown);

SPI_W25X16_CS_DisSelect;
}


void User_SPI_W25X16_WakeUp(void)
{
SPI_W25X16_CS_Select;

User_SPI_W25X16_SendByte(WakeUp);

SPI_W25X16_CS_DisSelect;
}

user_spi_w25x16.h

//SPI FLASH chip W25X16 頭文件

#ifndef _USER_SPI_W25X16_H
#define _USER_SPI_W25X16_H

#include"stm32f10x.h"

typedef enum{Failed=0,Successed=!Failed}TestStatus; //聲明定義枚舉型變量 用于表示測試失敗與成功

#define SPI_W25X16_SectorSize4096
#define SPI_W25X16_PageSize256//W25X16每頁數(shù)據(jù)長度
#define SPI_W25X16_PerPageWriteSize256//每頁最多寫入的數(shù)據(jù)個數(shù)


#define SPI_W25X16SPI1
#define SPI_W25X16_ClockRCC_APB2Periph_SPI1


#define SPI_W25X16_CS_ClockRCC_APB2Periph_GPIOC
#define SPI_W25X16_CS_PortGPIOC
#define SPI_W25X16_CS_PinGPIO_Pin_4


#define SPI_W25X16_SCK_ClockRCC_APB2Periph_GPIOA
#define SPI_W25X16_SCK_PortGPIOA
#define SPI_W25X16_SCK_PinGPIO_Pin_5


#define SPI_W25X16_MISO_Clock RCC_APB2Periph_GPIOA
#define SPI_W25X16_MISO_PortGPIOA
#define SPI_W25X16_MISO_PinGPIO_Pin_6


#define SPI_W25X16_MOSI_ClockRCC_APB2Periph_GPIOA
#define SPI_W25X16_MOSI_PortGPIOA
#define SPI_W25X16_MOSI_PinGPIO_Pin_7


#define SPI_24G_CS_ClockRCC_APB2Periph_GPIOB
#define SPI_24G_CS_PortGPIOB
#define SPI_24G_CS_PinGPIO_Pin_2


#define SPI_VS1003B_CS_ClockRCC_APB2Periph_GPIOB
#define SPI_VS1003B_CS_PortGPIOB
#define SPI_VS1003B_CS_PinGPIO_Pin_0


#define SPI_W25X16_CS_SelectGPIO_ResetBits(SPI_W25X16_CS_Port,SPI_W25X16_CS_Pin)

#define SPI_W25X16_CS_DisSelectGPIO_SetBits(SPI_W25X16_CS_Port,SPI_W25X16_CS_Pin)



u8 User_SPI_W25X16_SendByte(u8 SendByteData) ;//send data that is byte
u8 User_SPI_W25X16_ReadByte(void); //Read ByteData from chip W25X16
vu16 User_SPI_W25X16_SendHalfWord(u16 HalfWord) ;//send data ,is halfword
void User_SPI_W25X16_WriteEnable(void); //write enable for W25X16
void User_SPI_W25X16_WaitForWriteEnd(void); //wait the end about write for chip W25X16


void User_SPI_Config(void); //SPI1 init configuration
void User_SPI_W25X16_SectorErase(vu32 SectorAddress);
void User_SPI_W25X16_BulkErase(void);//erase the W25X16
void User_SPI_W25X16_PageWrite(u8 *DataTable,vu32 WriteAddress,vu16 NumberOfWrite);
void User_SPI_W25X16_ChipWrite(u8 *DataTable,vu32 WriteAddress,vu16 NumberOfWrite);
void User_SPI_W25X16_ChipRead(u8 *DataTable,vu32 ReadAddress,vu16 NumberOfRead);
vu32 User_SPI_W25X16_ReadID(void);//read chip ID
vu32 User_SPI_W25X16_ReadDeviceID(void);//read manufacture device ID
void User_SPI_W25X16_StartReadSequence(vu32 ReadAddress);
void User_SPI_W25X16_PowerDown(void);
void User_SPI_W25X16_WakeUp(void);


#endif

以上,結束。


上一頁 1 2 下一頁

關鍵詞: STM32SPIW25X16驅

評論


技術專區(qū)

關閉