大佬們來看一下,
單片機源程序如下:
#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;
}
/************************************************
檢測Flash是否準備就緒
入口參數: 無
出口參數:
0 : 沒有檢測到正確的Flash
1 : Flash準備就緒
************************************************/
void FlashCheckID(void)
{
u16 ID,ID1,ID2;
SPI_CE_Low();
SPI_WriteByte(SFC_RDID); //發送讀取ID命令
SPI_WriteByte(0x00); //空讀3個字節
SPI_WriteByte(0x00);
SPI_WriteByte(0x00);
ID = SPI_ReadByte(); //讀取制造商ID1
ID1 = SPI_ReadByte(); //讀取設備ID
ID2 = SPI_ReadByte(); //讀取制造商ID2
SPI_CE_High();
printf("ID:%x,ID1:%x,ID2:%x\r\n",ID,ID1,ID2);
}
/************************************************
檢測Flash的忙狀態
入口參數: 無
出口參數:
0 : Flash處于空閑狀態
1 : Flash處于忙狀態
************************************************/
u8 CheckFlashBusy(void)
{
u8 dat;
SPI_CE_Low();
SPI_WriteByte(SFC_RDSR); //發送讀取狀態命令
dat = SPI_ReadByte(); //讀取狀態
SPI_CE_High();
return (dat); //狀態值的Bit0即為忙標志
}
/************************************************
使能Flash寫命令
入口參數: 無
出口參數: 無
************************************************/
void FlashWriteEnable(void)
{
while(CheckFlashBusy() > 0); //Flash忙檢測
SPI_CE_Low();
SPI_WriteByte(SFC_WREN); //發送寫使能命令
SPI_CE_High();
}
/************************************************
禁止Flash寫使能命令
入口參數: 無
出口參數: 無
************************************************/
void FlashWriteDisable(void)
{
while(CheckFlashBusy() > 0); //Flash忙檢測
SPI_CE_Low();
SPI_WriteByte(SFC_WRDI); //發送寫使能命令
SPI_CE_High();
}
/************************************************
擦除扇區, 一個扇區4KB
入口參數: 無
出口參數: 無
************************************************/
void FlashSectorErase(u32 addr)
{
FlashWriteEnable(); //使能Flash寫命令
SPI_CE_Low();
SPI_WriteByte(SFC_SECTORER2); //發送扇區擦除命令
SPI_WriteByte(((u8 *)&addr)[1]); //設置起始地址
SPI_WriteByte(((u8 *)&addr)[2]);
SPI_WriteByte(((u8 *)&addr)[3]);
SPI_CE_High();
while(CheckFlashBusy() > 0);
FlashWriteDisable();
}
/************************************************
從Flash中讀取數據
入口參數:
addr : 地址參數
buffer : 緩沖從Flash中讀取的數據
len : 數據塊大小
出口參數:
無
************************************************/
void SPI_Read_Nbytes(u32 addr, u8 *buffer, u16 len)
{
u16 i;
while(CheckFlashBusy() > 0); //Flash忙檢測
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個字節,跟指定的數據進行比較, 錯誤返回1,正確返回0
************************************************************************/
u8 SPI_Read_Compare(u32 addr, u8 *buffer, u16 len)
{
u8 j;
if(len == 0) return 2;
while(CheckFlashBusy() > 0); //Flash忙檢測
j = 0;
SPI_CE_Low(); //enable device
SPI_WriteByte(SFC_READ); //read command
SPI_WriteByte(((u8 *)&addr)[1]); //設置起始地址
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;
}
/************************************************
寫數據到Flash中
入口參數:
addr : 地址參數
buffer : 緩沖需要寫入Flash的數據
len : 數據塊大小
出口參數: 無
************************************************/
void SPI_Write_Nbytes(u32 addr, u8 *buffer, u8 len)
{
u16 i;
while(CheckFlashBusy() > 0); //Flash忙檢測
FlashWriteEnable(); //使能Flash寫命令
SPI_CE_Low(); // enable device
SPI_WriteByte(SFC_PAGEPROG); // 發送頁編程命令
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();
}
//////////////////////////////////主函數//////////////
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); //每次可以擦除一個扇區。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);
}
|