大佬们来看一下,
单片机源程序如下:
#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);
}
|