標題:
C語言源代碼W25M02驅(qū)動使用
[打印本頁]
作者:
panfeng881112
時間:
2021-6-9 11:32
標題:
C語言源代碼W25M02驅(qū)動使用
本案例使用的是新唐M451的SPI1驅(qū)動W25M02的.
//W25 IC復(fù)位
void SpiFlash_Rest(void)
{
unsigned int au32SourceData;
unsigned int au32DestinationData;
SPI_SET_SS_LOW(SPI1);
//有些地方使用了 16 24 32 位模式 所以這里會重新設(shè)置一遍
SPI_SET_DATA_WIDTH(SPI1, 8);//設(shè)置SPI為8位模式
au32SourceData = 0xFF;//復(fù)位指令
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
}
//選擇模具 IChange == 0 或 1
void SpiFlash_IC_Change(u8 IChange)
{
unsigned int au32SourceData;
unsigned int au32DestinationData;
SPI_SET_SS_LOW(SPI1);
SPI_SET_DATA_WIDTH(SPI1, 8);//設(shè)置SPI為8位模式
//選擇模具指令 選擇W25M02GV內(nèi)的兩片W25N01GV中的其中一片 然后進行操作
au32SourceData = 0xC2;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32SourceData = IChange;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
}
//讀取IC ID值 一共24位
unsigned int SpiFlash_ReadMidDid(void)
{
unsigned int au32SourceData;
unsigned int au32DestinationData;
SPI_SET_SS_LOW(SPI1);
SPI_SET_DATA_WIDTH(SPI1, 8);
au32SourceData = 0x9F;//讀取ID指令 9F 00
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32SourceData = 0x0;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
//如果不想更改SPI設(shè)置 也可以拆成3個8位來操作
SPI_SET_DATA_WIDTH(SPI1, 24);//設(shè)置SPI為24位模式
I2S_CLR_RX_FIFO(SPI1);//清除SPI緩存
// 接收
au32SourceData = 0x0;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
//導(dǎo)出SPI緩存數(shù)據(jù)
au32DestinationData = SPI_READ_RX(SPI1);
return (au32DestinationData & 0xffffff);
}
//寫寄存器1
void SpiFlash_WriteStatusReg1(u8 SRData)
{ unsigned int au32SourceData;
unsigned int au32DestinationData;
SPI_SET_SS_LOW(SPI1);
SPI_SET_DATA_WIDTH(SPI1, 8);
au32SourceData = 0x01;//寫寄存器1指令: 01 A0
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32SourceData = 0xA0;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32SourceData = SRData;;//寫寄存器1:數(shù)據(jù)
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
}
//寫狀態(tài)寄存器2
void SpiFlash_WriteStatusReg2(u8 SRData)
{
unsigned int au32SourceData;
unsigned int au32DestinationData;
SPI_SET_SS_LOW(SPI1);
SPI_SET_DATA_WIDTH(SPI1, 8);
au32SourceData = 0x01;//寫寄存器2指令: 01 B0
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32SourceData = 0xB0;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32SourceData = SRData;//寫寄存器2:數(shù)據(jù)
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
}
//讀寄存器1
unsigned int SpiFlash_ReadStatusReg1(void)
{
unsigned int au32SourceData;
unsigned int au32DestinationData;
SPI_SET_SS_LOW(SPI1);
SPI_SET_DATA_WIDTH(SPI1, 8);
au32SourceData = 0x05;//讀寄存器1指令: 05 A0
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32SourceData = 0xA0;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
I2S_CLR_RX_FIFO(SPI1);
au32SourceData = 0X0;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32DestinationData = SPI_READ_RX(SPI1);//導(dǎo)致寄存器1數(shù)據(jù)
SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
return (au32DestinationData & 0xFF);
}
//讀寄存器2
unsigned int SpiFlash_ReadStatusReg2(void)
{
unsigned int au32SourceData;
unsigned int au32DestinationData;
SPI_SET_SS_LOW(SPI1); SPI_SET_DATA_WIDTH(SPI1, 8);
au32SourceData = 0x05;//讀寄存器2指令: 05 B0
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32SourceData = 0xB0;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
I2S_CLR_RX_FIFO(SPI1);
au32SourceData = 0X0;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32DestinationData = SPI_READ_RX(SPI1);
SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
return (au32DestinationData & 0xFF);
}
//讀寄存器3
unsigned int SpiFlash_ReadStatusReg3(void)
{
unsigned int au32SourceData;
unsigned int au32DestinationData;
SPI_SET_SS_LOW(SPI1);
SPI_SET_DATA_WIDTH(SPI1, 8);
au32SourceData = 0x05;//讀寄存器2指令: 05 C0
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32SourceData = 0xC0;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
I2S_CLR_RX_FIFO(SPI1);
au32SourceData = 0X0;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32DestinationData = SPI_READ_RX(SPI1);
SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
return (au32DestinationData & 0xFF);
}
//等待ic空閑
void SpiFlash_WaitReady(void)
{
unsigned int ReturnValue;
do
{ ReturnValue = SpiFlash_ReadStatusReg3();
ReturnValue = ReturnValue & 1;
}while(ReturnValue != 0);
}
//判斷是否正在寫入IC
void SpiFlash_WaitWEL_1(void)
{
unsigned int ReturnValue;
do
{ ReturnValue = SpiFlash_ReadStatusReg3();
ReturnValue = ReturnValue | 0XFD;
}while(ReturnValue != 0XFF);
}
//擦除一塊數(shù)據(jù) 64頁 :64*2048=128k 字節(jié)
void SpiFlash_PageErase(u32 StartAddress)
{ unsigned int au32SourceData;
SPI_SET_SS_LOW(SPI1);
SPI_SET_DATA_WIDTH(SPI1, 8);
au32SourceData = 0x06;//寫啟用指令 06
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
SpiFlash_WaitReady();//等閑
SpiFlash_WaitWEL_1();
SPI_SET_SS_LOW(SPI1);
au32SourceData = 0xD8;//擦除塊 指令 D8 00
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32SourceData = 0x0;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_DATA_WIDTH(SPI1, 16);
//改塊64頁中任意一頁地址
au32SourceData=ADDR_Row_PA15_PA0(StartAddress);
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
SpiFlash_WaitReady();//等閑
}
//擦除功能函數(shù)
void SpiFlash_ChipErase(u32 StartAddress)
{
SpiFlash_PageErase(StartAddress);
W25M_STR3=SpiFlash_ReadStatusReg3();//判斷是否成功
if(W25M_STR3 & 0x04)//擦除失敗
{
//printf("\r\nErase_Error\r\n");
SpiFlash_PageErase(StartAddress);
}
SpiFlash_WaitReady();
}
//寫入數(shù)據(jù)功能函數(shù)
//StartAddress1 12~27位: 頁地址
//StartAddress1 0~11位:頁內(nèi)數(shù)據(jù)位置
//ByteCount字節(jié)個數(shù)
void SpiFlash_WriteData(u8 *DataBuffer, u32 StartAddress1, unsigned int ByteCount)
{
u32 au32SourceData;
unsigned int Counter;
SPI_SET_SS_LOW(SPI1);
SPI_SET_DATA_WIDTH(SPI1, 8);
au32SourceData = 0x06;//寫啟用指令 06
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
SpiFlash_WaitReady();//等閑
SpiFlash_WaitWEL_1();
SPI_SET_SS_LOW(SPI1);
au32SourceData = 0x02;//數(shù)據(jù)寫入IC緩沖區(qū)指令 02
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_DATA_WIDTH(SPI1, 16); au32SourceData=StartAddress1;
au32SourceData = (u16)(au32SourceData&0x7ff);//頁內(nèi)位置
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_DATA_WIDTH(SPI1, 8);
for(Counter = 0; Counter < ByteCount; Counter++)//數(shù)據(jù)寫入IC換沖執(zhí)行過程
{
au32SourceData = DataBuffer[Counter];
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
}
SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
SpiFlash_WaitReady();//等閑
SPI_SET_SS_LOW(SPI1);
au32SourceData = 0x10;//換沖導(dǎo)入存儲區(qū)指令 10 00
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32SourceData = 0x0;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_DATA_WIDTH(SPI1, 16);
au32SourceData=StartAddress1;
au32SourceData = (u16)(au32SourceData>>12);//頁地址
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
SpiFlash_WaitReady();//等閑
W25M_STR3=SpiFlash_ReadStatusReg3();//判斷是否成功
if(W25M_STR3 & 0x08)//寫入失敗
{
//printf("\r\nWrite_Error\r\n");
}
SpiFlash_WaitReady();
}
//一頁數(shù)據(jù)導(dǎo)出到IC緩沖區(qū)
void SpiFlash_LoadData(u32 StartAddress1)
{
u32 au32SourceData;
SPI_SET_SS_LOW(SPI1);
SPI_SET_DATA_WIDTH(SPI1, 8);
au32SourceData = 0x13;//頁數(shù)據(jù)讀取到緩存指令 13 00
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32SourceData = 0x0;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_DATA_WIDTH(SPI1, 16);
au32SourceData=(u16)(StartAddress1>>12);//頁地址
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_SS_HIGH(SPI1);
sys_delayms(2);
SpiFlash_WaitReady();//等閑
}
//讀出數(shù)據(jù)功能函數(shù)
//StartAddress1 12~27位: 頁地址
//StartAddress1 0~11位:頁內(nèi)數(shù)據(jù)位置
//ByteCount字節(jié)個數(shù)void SpiFlash_ReadData(u8 *DataBuffer, u32 StartAddress1, unsigned int ByteCount)
{
u32 au32SourceData;
unsigned int au32DestinationData;
unsigned int Counter;
SpiFlash_LoadData(StartAddress1);
W25M_STR3=SpiFlash_ReadStatusReg3();//判斷是否成功
if(W25M_STR3 & 0x20)//讀取失敗
{
//printf("\r\nRead_Load_Error\r\n");
SpiFlash_LoadData(StartAddress1);
W25M_STR3=SpiFlash_ReadStatusReg3();//判斷是否成功
if(W25M_STR3 & 0x20)//讀取失敗
{
//UART1_PUTS(":讀取失敗\r\n");
}
}
SPI_SET_SS_LOW(SPI1);
SPI_SET_DATA_WIDTH(SPI1, 8);
au32SourceData = 0x03;//讀取IC緩沖區(qū)數(shù)據(jù)指令 03
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_DATA_WIDTH(SPI1, 16);
au32SourceData=StartAddress1;
au32SourceData = (u16)(au32SourceData&0x7ff);//頁內(nèi)位置
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_DATA_WIDTH(SPI1, 8);
au32SourceData = 0x0;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
I2S_CLR_RX_FIFO(SPI1);//清空SPI緩沖區(qū) 準備接收IC緩沖區(qū)數(shù)據(jù)
for(Counter = 0; Counter < ByteCount; Counter++)
{
au32SourceData = 0x0;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32DestinationData = SPI_READ_RX(SPI1);
DataBuffer[Counter] = (u8) au32DestinationData;
}
SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
SpiFlash_WaitReady();
}
//以下是工程函數(shù)的案例
#defineW25PAGE(n)( 4096 * n )
//0 <= n < { 1024(塊)*64(頁)}
//注意:擦除操作時是擦除整塊 SpiFlash_ChipErase(W25PAGE(n))
//拿第一塊為例:n=0或n=63都是擦除第一塊64個頁的存儲區(qū)
//參數(shù)寫0并保存
void W25M_write_0(void)
{
u16 i=0;
for(i=0;i<2048;i++)
{W25M_temp[i]=0;}
SpiFlash_ChipErase(W25PAGE(0));SpiFlash_WriteData(W25M_temp, W25PAGE(0),2048);
}
//保存工程參數(shù)
void W25M_write_GongChen(void)
{
SpiFlash_ChipErase(W25PAGE(0));
SpiFlash_WriteData(W25M_temp, W25PAGE(0),500);
}
//讀取工程參數(shù)
void W25M_read_GongChen(void)
{
SpiFlash_ReadData(W25M_temp,W25PAGE(0),500);
}
復(fù)制代碼
作者:
bobo21
時間:
2023-7-26 10:47
學(xué)習(xí)中,感謝
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1