|
大佬們來看一下,
單片機(jī)源程序如下:
#include "w25q128.h"
/************************************************************************/
void SPI_init(void)
{
SPI_CE_High();
CLK_FLASH = 0; // set clock to low initial state
DI_FLASH = 1;
}
/************************************************************************/
void SPI_WriteByte(u8 out)
{
u8 i;
i = 8;
do{
out <<= 1;
DI_FLASH = CY;
CLK_FLASH = 1;
CLK_FLASH = 0;
}while(--i);
DI_FLASH = 1;
}
/************************************************************************/
u8 SPI_ReadByte(void)
{
u8 i, in;
i = 8;
do{
in <<= 1;
if (DO_FLASH) in++;
CLK_FLASH = 1;
CLK_FLASH = 0;
}while(--i);
return in;
}
/************************************************
檢測(cè)Flash是否準(zhǔn)備就緒
入口參數(shù): 無
出口參數(shù):
0 : 沒有檢測(cè)到正確的Flash
1 : Flash準(zhǔn)備就緒
************************************************/
void FlashCheckID(void)
{
u16 ID,ID1,ID2;
SPI_CE_Low();
SPI_WriteByte(SFC_RDID); //發(fā)送讀取ID命令
SPI_WriteByte(0x00); //空讀3個(gè)字節(jié)
SPI_WriteByte(0x00);
SPI_WriteByte(0x00);
ID = SPI_ReadByte(); //讀取制造商ID1
ID1 = SPI_ReadByte(); //讀取設(shè)備ID
ID2 = SPI_ReadByte(); //讀取制造商ID2
SPI_CE_High();
printf("ID:%x,ID1:%x,ID2:%x\r\n",ID,ID1,ID2);
}
/************************************************
檢測(cè)Flash的忙狀態(tài)
入口參數(shù): 無
出口參數(shù):
0 : Flash處于空閑狀態(tài)
1 : Flash處于忙狀態(tài)
************************************************/
u8 CheckFlashBusy(void)
{
u8 dat;
SPI_CE_Low();
SPI_WriteByte(SFC_RDSR); //發(fā)送讀取狀態(tài)命令
dat = SPI_ReadByte(); //讀取狀態(tài)
SPI_CE_High();
return (dat); //狀態(tài)值的Bit0即為忙標(biāo)志
}
/************************************************
使能Flash寫命令
入口參數(shù): 無
出口參數(shù): 無
************************************************/
void FlashWriteEnable(void)
{
while(CheckFlashBusy() > 0); //Flash忙檢測(cè)
SPI_CE_Low();
SPI_WriteByte(SFC_WREN); //發(fā)送寫使能命令
SPI_CE_High();
}
/************************************************
禁止Flash寫使能命令
入口參數(shù): 無
出口參數(shù): 無
************************************************/
void FlashWriteDisable(void)
{
while(CheckFlashBusy() > 0); //Flash忙檢測(cè)
SPI_CE_Low();
SPI_WriteByte(SFC_WRDI); //發(fā)送寫使能命令
SPI_CE_High();
}
/************************************************
擦除扇區(qū), 一個(gè)扇區(qū)4KB
入口參數(shù): 無
出口參數(shù): 無
************************************************/
void FlashSectorErase(u32 addr)
{
FlashWriteEnable(); //使能Flash寫命令
SPI_CE_Low();
SPI_WriteByte(SFC_SECTORER2); //發(fā)送扇區(qū)擦除命令
SPI_WriteByte(((u8 *)&addr)[1]); //設(shè)置起始地址
SPI_WriteByte(((u8 *)&addr)[2]);
SPI_WriteByte(((u8 *)&addr)[3]);
SPI_CE_High();
while(CheckFlashBusy() > 0);
FlashWriteDisable();
}
/************************************************
從Flash中讀取數(shù)據(jù)
入口參數(shù):
addr : 地址參數(shù)
buffer : 緩沖從Flash中讀取的數(shù)據(jù)
len : 數(shù)據(jù)塊大小
出口參數(shù):
無
************************************************/
void SPI_Read_Nbytes(u32 addr, u8 *buffer, u16 len)
{
u16 i;
while(CheckFlashBusy() > 0); //Flash忙檢測(cè)
SPI_CE_Low(); //enable device
SPI_WriteByte(SFC_READ); //read command
SPI_WriteByte((addr & 0xFF0000) >> 16);
SPI_WriteByte((addr & 0xFF00) >> 8);
SPI_WriteByte(addr & 0xFF);
for (i = 0; i < len; i++)
{
buffer[ i]= SPI_ReadByte();
}
SPI_CE_High(); //disable device
}
/************************************************************************
讀出n個(gè)字節(jié),跟指定的數(shù)據(jù)進(jìn)行比較, 錯(cuò)誤返回1,正確返回0
************************************************************************/
u8 SPI_Read_Compare(u32 addr, u8 *buffer, u16 len)
{
u8 j;
if(len == 0) return 2;
while(CheckFlashBusy() > 0); //Flash忙檢測(cè)
j = 0;
SPI_CE_Low(); //enable device
SPI_WriteByte(SFC_READ); //read command
SPI_WriteByte(((u8 *)&addr)[1]); //設(shè)置起始地址
SPI_WriteByte(((u8 *)&addr)[2]);
SPI_WriteByte(((u8 *)&addr)[3]);
do
{
if(*buffer != SPI_ReadByte()) //receive byte and store at buffer
{
j = 1;
break;
}
buffer++;
}while(--len); //read until no_bytes is reached
SPI_CE_High(); //disable device
return j;
}
/************************************************
寫數(shù)據(jù)到Flash中
入口參數(shù):
addr : 地址參數(shù)
buffer : 緩沖需要寫入Flash的數(shù)據(jù)
len : 數(shù)據(jù)塊大小
出口參數(shù): 無
************************************************/
void SPI_Write_Nbytes(u32 addr, u8 *buffer, u8 len)
{
u16 i;
while(CheckFlashBusy() > 0); //Flash忙檢測(cè)
FlashWriteEnable(); //使能Flash寫命令
SPI_CE_Low(); // enable device
SPI_WriteByte(SFC_PAGEPROG); // 發(fā)送頁編程命令
SPI_WriteByte((addr & 0xFF0000) >> 16);
SPI_WriteByte((addr & 0xFF00) >> 8);
SPI_WriteByte(addr & 0xFF);
for (i = 0; i < len; i++)
{
SPI_WriteByte(buffer[ i]);
}
SPI_CE_High(); // disable device
while(CheckFlashBusy() > 0);
FlashWriteDisable();
}
//////////////////////////////////主函數(shù)//////////////
code const unsigned char arr[200] = {
0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00,
0X00, 0X04, 0X00, 0X00, 0X00, 0X04, 0X00, 0X70, 0X00, 0X40,
0X04, 0X00, 0X04, 0X00, 0X04, 0X00, 0X07, 0X00, 0X00, 0X00,
0X00, 0X04, 0X00, 0X00, 0X70, 0X00, 0X07, 0X00, 0X00, 0X00,
0X00, 0X00, 0X00, 0X07, 0X70, 0X00, 0X77, 0X00, 0X00, 0X00,
0X00, 0X00, 0X70, 0X07, 0X77, 0X77, 0X77, 0X77, 0X00, 0X00,
0X00, 0X00, 0X07, 0X77, 0X77, 0X77, 0X77, 0X70, 0X70, 0X00,
0X00, 0X77, 0X77, 0X00, 0X00, 0X77, 0X77, 0X00, 0X00, 0X00,
0X00, 0X00, 0X70, 0X70, 0X00, 0X77, 0X77, 0X00, 0X00, 0X00,
0X00, 0X07, 0X70, 0X70, 0X00, 0X07, 0X77, 0X00, 0X07, 0X00,
0X07, 0X77, 0X00, 0X00, 0X00, 0X07, 0X77, 0X70, 0X70, 0X00,
0X00, 0X70, 0X00, 0X40, 0X00, 0X07, 0X77, 0X77, 0X00, 0X00,
0X00, 0X00, 0X00, 0X00, 0X40, 0X07, 0X77, 0X77, 0X00, 0X00,
0X00, 0X40, 0X00, 0X00, 0X00, 0X07, 0X77, 0X77, 0X00, 0X00,
0X00, 0X00, 0X00, 0X00, 0X00, 0X07, 0X70, 0X77, 0X70, 0X00,
0X00, 0X00, 0X00, 0X40, 0X00, 0X07, 0X00, 0X00, 0X07, 0X00,
0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00,
0X00, 0X00, 0X40, 0X00, 0X40, 0X00, 0X00, 0X00, 0X00, 0X00,
0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X40, 0X00, 0X00,
0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00,
};
void main(void)
{
xdata unsigned char read_dat[256];
// EA = 1;
UartInit();
io_init();
SPI_init();
FlashCheckID();
FlashSectorErase(0x011000); //每次可以擦除一個(gè)扇區(qū)。4KB
delay_ms(500);
SPI_Write_Nbytes(0x011000,arr,200);
delay_ms(100);
SPI_Read_Nbytes(0x011000, read_dat,200);
delay_ms(100);
UartSend(read_dat,200);
P03=0;
while(1);
}
|
|