#include<reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
sbit SCLK =P0^1;//SCK
sbit MISO =P0^4;
sbit MISI =P0^2;
sbit CE =P0^5;//CE
sbit rw =P0^3;//WP
sbit HOLD =P0^0;//RET/HOLD
uchar dat[10]={1,2,3,4,5,6,7,8,9,1};
uchar add[3]={1,0,1};
uchar R_dat[10];
uint num;
void Flash_init() ; /* 程序功能: 用来将时钟线初始化为低. 必须在将设备设置为模式0之前调用*/
void Flash_WRSR(uchar byte) ;//写状态寄存器
uchar Flash_Read_Status_Register(void); //读状态寄存器的值
void Flash_WREN_Check(void) ; /* 功能: 检查擦写操作前WEL位是否为1 */
void Flash_WREN(void) ; //写使能命令
void Flash_Wait_Busy(void) ;//等待 FLASH空闲
void Flash_Chip_Erase(void) ; /* 功能: 擦除整个芯片 */
void Flash_EWSR(void) ; //;使能改写状态寄存器
void Flash_WRDI(void) ;// 禁止写使能
void Flash_Send_Byte(uchar dat) ;//发送一个数据char 型 的 从51到FLASH
uchar Flash_Get_Byte(void);// 接收一个char型的数据 51接收
void Flash_Read_data(uchar add[],uchar R_dat[],uchar size);//向从flash 内的一个基地址 add, 内读出size个数据。 放到dat[]中
ulong ReadID(uint ID_addr);
ulong JedecIDRead() ;
void Flash_EHLD();
void ProgSID(uint *psecurityid);
void ReadSID(uint Dst, uint *psave, uint security_length) ;
void LockSID() ;
void ExternFlashChipErase();
void ExternFlashSectorErase(ulong Dst);
void ExternFlashBlockErase_64K(ulong Dst);
void ExternFlashBlockErase_32K(ulong Dst);
void ExternFlash_Init();
void ExternFlashHighSpeedRead(ulong Dst, uint *psave,ulong no_bytes);
void Flash_Write_data(uchar add[],uchar *pupper,ulong amount);
/**********************************************
//函数名称:
//功能描述:
//输入参数:
//返回参数:
//说明:Flash初始化 不完善需要添加
***********************************************/
void Flash_init() /* 程序功能: 用来将时钟线初始化为低. 必须在将设备设置为模式0之前调用*/
{
uchar i;
SCLK=0;
for(i=255;i>0;i--);
SCLK=1;
}
/**********************************************
//函数名称:void ExternFlash_Init()
//功能描述:SST25VF064管脚,寄存器,SPI方式初始化
//输入参数:
//返回参数:
//说明:
***********************************************/
void ExternFlash_Init()
{
Flash_init();
Flash_EHLD(); //配置RES/HOLD管脚的功能为HOLD
Flash_EWSR(); //使能写寄存器
Flash_WRSR(0x00);//BPL=0,BP0~3=0000,NO Protect
}
/**********************************************
//函数名称:
//功能描述:
//输入参数:
//返回参数:
//说明:从单片机到SST25VF064 发送一个字节
***********************************************/
void Flash_Send_Byte(uchar dat)
{
uchar i;
SCLK=0;
CE=0;
for(i=0;i<8;i++)
{
if(dat & 0x80)
{
MISI=1;
}
else
MISI=0;
dat<<=1;
SCLK=1; //信号拉高读进数据
_nop_();
SCLK=0; //将信号拉低
_nop_();
}
SCLK=0;
}
/**********************************************
//函数名称:
//功能描述:
//输入参数:
//返回参数:
//说明:从flash到单片机,接收一个字节
***********************************************/
uchar Flash_Get_Byte(void) //接收一个char型的数据
{
uchar i;
uchar one_data=0;
CE = 0;
// SCLK=1;
for(i=0;i<8;i++)
{
one_data=one_data<<1;
SCLK=0;
_nop_();
_nop_();
if(MISO==1)
{
one_data=one_data | 0x01;
}
SCLK=1;
_nop_();
}
SCLK=0;
//CS=1;
return one_data;
}
/**********************************************
//函数名称:
//功能描述:
//输入参数:
//返回参数:
//说明:读状态寄存器的值
***********************************************/
uchar Flash_Read_Status_Register(void)
{
uchar byte = 0;
CE =0; /* 使能设备 */
Flash_Send_Byte(0x05); /* 发送读状态寄存器的命令 */
byte = Flash_Get_Byte(); /* 读取状态寄存器 */
CE =1; /* 禁止设备 */
return byte;
}
/**********************************************
//函数名称:
//功能描述:
//输入参数:
//返回参数:
//说明:使能改写状态寄存器,执行后允许写
***********************************************/
void Flash_EWSR(void)
{
CE =0; /* 使能设备*/
Flash_Send_Byte(0x50); /* 发送使能写寄存器的命令 */
CE =1; /* 禁止设备*/
}
/**********************************************
//函数名称:
//功能描述:
//输入参数:
//返回参数:
//说明: 写状态寄存器
***********************************************/
void Flash_WRSR(uchar byte)
{
CE =0; /* 使能设备 */
Flash_Send_Byte(0x01); /* 发送写状态寄存器 */
Flash_Send_Byte(byte); ///* 改变寄存器里BPx或者BPL (只有2,3,4,5,7位可以改写) */ ???
CE =1; /* 禁止设备 */
}
/**********************************************
//函数名称:
//功能描述:
//输入参数:
//返回参数:
//说明:在执行任何写(编程/擦除)操作之前,都必须先执行WREN 指令。
WREN 指令也可用于允许执行写状态寄存器(WRSR)指令;但是,状态寄存器中的写使能锁存器位将在WRSR 指令的CE# 上升沿被清零。
在执行WREN 指令之前, CE# 必须驱动为高电平。
***********************************************/
void Flash_WREN(void)
{
CE =0;
Flash_Send_Byte(0x06); /* 发送WREN命令 */
CE =1;
}
/**********************************************
//函数名称:
//功能描述:
//输入参数:
//返回参数:
//说明:禁止写使能WRDI 指令不会终止任何正在进行的编程或擦除操作。
执行WRDI 指令之后,所有正在进行的编程或擦除操作都将继续进行。
在执行WRDI 指令之前, CE# 必须驱动为高电平。
***********************************************/
void Flash_WRDI(void)
{
CE =0;
Flash_Send_Byte(0x04); /* 发送WRDI命令*/
CE =1;
}
/**********************************************
//函数名称:
//功能描述:
//输入参数:
//返回参数:
//说明:读ID 指令(RDID)将器件标识为SST25VF064C,将制造商标识为SST。
通过执行8 位命令90H 或ABH(后面紧跟地址位A23-A0)可读取器件信息。
执行读ID 指令之后,制造商ID 位于地址00000H,器件ID位于地址00001H。
器件处于读ID 模式之后,制造商ID 和器件ID 输出数据在地址00000H 和00001H 之间翻转,
直到被CE# 上低电平到高电平的转换终止。CE# 驱动为高电平之后,器件进入待机模式。
***********************************************/
ulong ReadID(uint ID_addr)
{
ulong byte;
byte=0;
CE = 0; // enable device
Flash_Send_Byte(0x90); // send read ID command (90h or ABh)
Flash_Send_Byte(0x00); // send address
Flash_Send_Byte(0x00); // send address
Flash_Send_Byte(ID_addr); // send address - either 00H or 01H
byte = (byte|Flash_Get_Byte())<<8;// receive byte 返回制造商ID
byte = (byte|Flash_Get_Byte());// receive byte 返回器件ID
CE = 1; // disable device
return byte;
}
/**********************************************
//函数名称:
//功能描述:
//输入参数:
//返回参数:
//说明:JEDEC 读ID 指令将器件标识为SST25VF064C,将制造商标识为SST。
可通过执行8 位命令9FH 来读取器件信息。执
行JEDEC 读ID 指令之后,将从器件输出8 位制造商ID (BFH)。
然后, 24 位器件ID 在SO 引脚上移出。
字节1 (BFH)将制造商标识为SST。
字节2 (25H)将存储器类型标识为SPI串行闪存。
字节3 (4BH)将器件标识为SST25VF064C。
***********************************************/
ulong JedecIDRead()
{
ulong temp=0;
CE = 0; // enable device
Flash_Send_Byte(0x9F); // send JEDEC ID command (9Fh)
temp = (temp | Flash_Get_Byte()) << 8; //
temp = (temp | Flash_Get_Byte()) << 8;
temp = (temp | Flash_Get_Byte()); // temp value = 0xBF254B
CE =1; // disable device
return temp;
}
/************************************************************************/
//* 名称: Read */
//* 功能: 读取一个地址内一个字节的数据.返回读取的数据*/
//* 输入: Dst: Destination Address 000000H - 1FFFFFH */
//* 返回: