51读写nandflash例程
时间:01-09
来源:21IC中国电子网
点击:
51读写flash
下面是CYPRESS 68013上的一个读写samsung K9F1G的例子程序。
说明:程序针对mcu:cypress 68013,flash:samsung k9f1g08u,MCU运行于48M,对于其它频率,一些时序常数可能需要修改.程序实现了FLASH的CLEAR,WRITE,READ基本操作.
/******************************************************************/
/*AC Timing Characteristics define for Command / Address / Data Input
/*for cpu frequency 48MHZ,
/******************************************************************/
#define TDS 130
#define TDH 125
#define TWHR 300
/******************************************************************/
//IO PORT MAP
#define POW_LED PD1
#define RUN_LED PD2
//flash control line map
#define SIG_CEn PA4 //o
#define SIG_WEn PA1 //o
#define SIG_REn PA5 //o
#define SIG_CLEp PA3 //o
#define SIG_ALEp PA2 //o
#define SIG_RB PA6 //i
#define SIG_WP PA0 //o
#define SIG_DATA IOB //data bus
#define SIG_DATA_DIR OEB
#define SIG_CON_DIR OEA
#define SIG_LED_DIR OED
#define init_con_io() {SIG_CON_DIR=0xbf;SIG_WP=0x1;SIG_LED_DIR=0XFF;}
/*some macro define
#define LATCH_DATA(LATCH,dataa) {if(LATCH){SIG_DATA_DIR=0xff;SIG_DATA=dataa;}
else {SIG_DATA_DIR=0x00;dataa=SIG_DATA;}}
#define SIG_INVALIDATE() {SIG_CEn=SIG_WEn=SIG_REn=HIGH;
SIG_CLEp=SIG_ALEp=LOW; }
#define SIGNAL_SETUP(x) {unsigned char i;for(i=x;i>0;i--)_nop_( );}
#define SIGNAL_HOLD(x) {unsigned char i;for(i=x;i>0;i--)_nop_( );}
/******************************************************************/
/*function: a Command Latch Cycle
/*input: comm: commamd no.
/******************************************************************/
void ss_comm_latch(unsigned char comm,unsigned char wait)
{
SIG_ALEp=SIG_CEn=SIG_WEn=LOW;
SIG_CLEp=HIGH;
SIG_REn=HIGH;
LATCH_DATA(1,comm);
SIGNAL_SETUP(TDS); //tds
SIG_WEn=HIGH;
if(wait)while(SIG_RB);
SIGNAL_HOLD(TDH); //tdh
SIG_INVALIDATE();
}
/******************************************************************/
/*function: Address Latch Cycle
/*input: addr: addr no.
/******************************************************************/
void ss_addr_latch(unsigned char addr)
{
SIG_CLEp=SIG_CEn=SIG_WEn=LOW;
SIG_ALEp=SIG_REn=HIGH;
LATCH_DATA(1,addr);
SIGNAL_SETUP(TDS); //tals
SIG_WEn=HIGH;
SIGNAL_HOLD(TDH); //twh
SIG_INVALIDATE();
}
/******************************************************************/
/*function: Input Data Latch Cycle
/*input: dat: input DATA
/******************************************************************/
void ss_data_latch(unsigned char dat)
{
SIG_ALEp=SIG_CLEp=SIG_CEn=SIG_WEn=LOW;
SIG_REn=HIGH;
LATCH_DATA(1,dat);
SIGNAL_SETUP(TDS); //tds tcs
SIG_WEn=HIGH;
SIGNAL_HOLD(TDH); //tdh,tch
SIG_INVALIDATE();
}
/******************************************************************/
/*function: Serial Access Cycle after Read
/*input: wait: if wait R/B pin
/******************************************************************/
unsigned char ss_serial_acess(unsigned char wait)
{
unsigned char rddata;
if(wait)
while(!SIG_RB); //trr
SIG_CLEp=SIG_ALEp=SIG_REn=SIG_CEn=LOW;
SIG_WEn=HIGH;
SIGNAL_SETUP(TDS); //trea
LATCH_DATA(0,rddata);
SIG_REn=HIGH;
SIGNAL_HOLD(TDH); //treh
SIG_INVALIDATE();
return rddata;
}
/******************************************************************/
/*function: Status Read Cycle
/*input: wait: if wait R/B pin
/******************************************************************/
unsigned char ss_status_read(unsigned char wait)
{
unsigned char rddata;
if(wait)
while(!SIG_RB);
ss_comm_latch(0x70,0);
SIG_CLEp=SIG_CEn=LOW;
SIGNAL_SETUP(TDS); //tclr
SIG_REn=LOW;
SIGNAL_SETUP(TDS); //trea
LATCH_DATA(0,rddata);
SIG_REn=HIGH;
SIGNAL_HOLD(TDH); //trhz
SIG_INVALIDATE();
return rddata;
}
/******************************************************************/
/*function: erase flash
/*input: addrH: flash row address,16 bit width refer to datasheet
/*return: I/O status
/* I/O No. Page Program Block Erase Cache Prorgam Read Definition
/* I/O 0 Pass/Fail Pass/Fail Pass/Fail(N) Not use Pass : "0" Fail : "1"
/* I/O 1 Not use Not use Pass/Fail(N-1) Not use Pass : "0" Fail : "1"
/* I/O 2 Not use Not use Not use Not use "0"
/* I/O 3 Not Use Not Use Not Use Not Use "0"
/* I/O 4 Not Use Not Use Not Use Not Use "0"
/* I/O 5 Ready/Busy Ready/Busy True Ready/Busy Ready/Busy Busy : "0" Ready : "1"
/* I/O 6 Ready/Busy Ready/Busy Ready/Busy Ready/Busy Busy : "0" Ready : "1"
/* I/O 7 Write Protect Write Protect Write Protect Write Protect Protected: "0" Not Protected:"1"
/******************************************************************/
unsigned char flash_erase(unsigned int addrH)
{
ss_comm_latch(0x60,0);
ss_addr_latch(LOWBYTE(addrH));
ss_addr_latch(HIGHBYTE(addrH));
ss_comm_latch(0xd0,1); //twb
return ss_status_read(1); //status is 0x60h(write protect is set)/0xe0h(non wp) is good
}
/******************************************************************/
/*function: read flash
/*input: addrH: flash row address,16 bit width refer to datasheet
/* addrL: flash column address,12 bit width
/* databuf: out data buffer pointer
/* buflen: unsigned char num from flash
/******************************************************************/
unsigned char flash_read_PAG(unsigned int addrH,
unsigned int addrL,
unsigned char *databuf,
unsigned int buflen)
{
ss_comm_latch(0x00,0);
ss_addr_latch(LOWBYTE(addrL));
ss_addr_latch(HIGHBYTE(addrL));
ss_addr_latch(LOWBYTE(addrH));
ss_addr_latch(HIGHBYTE(addrH));
ss_comm_latch(0x30,1); //twb+tr
for(;buflen>0;buflen--,databuf++)
*databuf=ss_serial_acess(1);
return TRUE;
}
/******************************************************************/
/*function: write flash
/*input: addrH: flash row address,16 bit width refer to datasheet
/* addrL: flash column address,12 bit width
/* databuf: data buffer pointer
/* buflen: unsigned char num to flash
/******************************************************************/
unsigned char flash_write_PAG(unsigned int addrH,
unsigned int addrL,
unsigned char* databuf,
unsigned int buflen,
{
ss_comm_latch(0x80,0);
ss_addr_latch(LOWBYTE(addrL));
ss_addr_latch(HIGHBYTE(addrL));
ss_addr_latch(LOWBYTE(addrH));
ss_addr_latch(HIGHBYTE(addrH));
for(;buflen>0;buflen--,databuf++)
ss_data_latch(*databuf);
ss_comm_latch(0x10,1); //twb+tprog
return ss_status_read(1);
}
io MAP已经补充,
SIGNAL_HOLD,//确保信号保持时间
SIGNAL_SETUP,//确保信号建立时间
SIG_INVALIDATE(); //System Interface Using CE don’t-care.
下面是CYPRESS 68013上的一个读写samsung K9F1G的例子程序。
说明:程序针对mcu:cypress 68013,flash:samsung k9f1g08u,MCU运行于48M,对于其它频率,一些时序常数可能需要修改.程序实现了FLASH的CLEAR,WRITE,READ基本操作.
/******************************************************************/
/*AC Timing Characteristics define for Command / Address / Data Input
/*for cpu frequency 48MHZ,
/******************************************************************/
#define TDS 130
#define TDH 125
#define TWHR 300
/******************************************************************/
//IO PORT MAP
#define POW_LED PD1
#define RUN_LED PD2
//flash control line map
#define SIG_CEn PA4 //o
#define SIG_WEn PA1 //o
#define SIG_REn PA5 //o
#define SIG_CLEp PA3 //o
#define SIG_ALEp PA2 //o
#define SIG_RB PA6 //i
#define SIG_WP PA0 //o
#define SIG_DATA IOB //data bus
#define SIG_DATA_DIR OEB
#define SIG_CON_DIR OEA
#define SIG_LED_DIR OED
#define init_con_io() {SIG_CON_DIR=0xbf;SIG_WP=0x1;SIG_LED_DIR=0XFF;}
/*some macro define
#define LATCH_DATA(LATCH,dataa) {if(LATCH){SIG_DATA_DIR=0xff;SIG_DATA=dataa;}
else {SIG_DATA_DIR=0x00;dataa=SIG_DATA;}}
#define SIG_INVALIDATE() {SIG_CEn=SIG_WEn=SIG_REn=HIGH;
SIG_CLEp=SIG_ALEp=LOW; }
#define SIGNAL_SETUP(x) {unsigned char i;for(i=x;i>0;i--)_nop_( );}
#define SIGNAL_HOLD(x) {unsigned char i;for(i=x;i>0;i--)_nop_( );}
/******************************************************************/
/*function: a Command Latch Cycle
/*input: comm: commamd no.
/******************************************************************/
void ss_comm_latch(unsigned char comm,unsigned char wait)
{
SIG_ALEp=SIG_CEn=SIG_WEn=LOW;
SIG_CLEp=HIGH;
SIG_REn=HIGH;
LATCH_DATA(1,comm);
SIGNAL_SETUP(TDS); //tds
SIG_WEn=HIGH;
if(wait)while(SIG_RB);
SIGNAL_HOLD(TDH); //tdh
SIG_INVALIDATE();
}
/******************************************************************/
/*function: Address Latch Cycle
/*input: addr: addr no.
/******************************************************************/
void ss_addr_latch(unsigned char addr)
{
SIG_CLEp=SIG_CEn=SIG_WEn=LOW;
SIG_ALEp=SIG_REn=HIGH;
LATCH_DATA(1,addr);
SIGNAL_SETUP(TDS); //tals
SIG_WEn=HIGH;
SIGNAL_HOLD(TDH); //twh
SIG_INVALIDATE();
}
/******************************************************************/
/*function: Input Data Latch Cycle
/*input: dat: input DATA
/******************************************************************/
void ss_data_latch(unsigned char dat)
{
SIG_ALEp=SIG_CLEp=SIG_CEn=SIG_WEn=LOW;
SIG_REn=HIGH;
LATCH_DATA(1,dat);
SIGNAL_SETUP(TDS); //tds tcs
SIG_WEn=HIGH;
SIGNAL_HOLD(TDH); //tdh,tch
SIG_INVALIDATE();
}
/******************************************************************/
/*function: Serial Access Cycle after Read
/*input: wait: if wait R/B pin
/******************************************************************/
unsigned char ss_serial_acess(unsigned char wait)
{
unsigned char rddata;
if(wait)
while(!SIG_RB); //trr
SIG_CLEp=SIG_ALEp=SIG_REn=SIG_CEn=LOW;
SIG_WEn=HIGH;
SIGNAL_SETUP(TDS); //trea
LATCH_DATA(0,rddata);
SIG_REn=HIGH;
SIGNAL_HOLD(TDH); //treh
SIG_INVALIDATE();
return rddata;
}
/******************************************************************/
/*function: Status Read Cycle
/*input: wait: if wait R/B pin
/******************************************************************/
unsigned char ss_status_read(unsigned char wait)
{
unsigned char rddata;
if(wait)
while(!SIG_RB);
ss_comm_latch(0x70,0);
SIG_CLEp=SIG_CEn=LOW;
SIGNAL_SETUP(TDS); //tclr
SIG_REn=LOW;
SIGNAL_SETUP(TDS); //trea
LATCH_DATA(0,rddata);
SIG_REn=HIGH;
SIGNAL_HOLD(TDH); //trhz
SIG_INVALIDATE();
return rddata;
}
/******************************************************************/
/*function: erase flash
/*input: addrH: flash row address,16 bit width refer to datasheet
/*return: I/O status
/* I/O No. Page Program Block Erase Cache Prorgam Read Definition
/* I/O 0 Pass/Fail Pass/Fail Pass/Fail(N) Not use Pass : "0" Fail : "1"
/* I/O 1 Not use Not use Pass/Fail(N-1) Not use Pass : "0" Fail : "1"
/* I/O 2 Not use Not use Not use Not use "0"
/* I/O 3 Not Use Not Use Not Use Not Use "0"
/* I/O 4 Not Use Not Use Not Use Not Use "0"
/* I/O 5 Ready/Busy Ready/Busy True Ready/Busy Ready/Busy Busy : "0" Ready : "1"
/* I/O 6 Ready/Busy Ready/Busy Ready/Busy Ready/Busy Busy : "0" Ready : "1"
/* I/O 7 Write Protect Write Protect Write Protect Write Protect Protected: "0" Not Protected:"1"
/******************************************************************/
unsigned char flash_erase(unsigned int addrH)
{
ss_comm_latch(0x60,0);
ss_addr_latch(LOWBYTE(addrH));
ss_addr_latch(HIGHBYTE(addrH));
ss_comm_latch(0xd0,1); //twb
return ss_status_read(1); //status is 0x60h(write protect is set)/0xe0h(non wp) is good
}
/******************************************************************/
/*function: read flash
/*input: addrH: flash row address,16 bit width refer to datasheet
/* addrL: flash column address,12 bit width
/* databuf: out data buffer pointer
/* buflen: unsigned char num from flash
/******************************************************************/
unsigned char flash_read_PAG(unsigned int addrH,
unsigned int addrL,
unsigned char *databuf,
unsigned int buflen)
{
ss_comm_latch(0x00,0);
ss_addr_latch(LOWBYTE(addrL));
ss_addr_latch(HIGHBYTE(addrL));
ss_addr_latch(LOWBYTE(addrH));
ss_addr_latch(HIGHBYTE(addrH));
ss_comm_latch(0x30,1); //twb+tr
for(;buflen>0;buflen--,databuf++)
*databuf=ss_serial_acess(1);
return TRUE;
}
/******************************************************************/
/*function: write flash
/*input: addrH: flash row address,16 bit width refer to datasheet
/* addrL: flash column address,12 bit width
/* databuf: data buffer pointer
/* buflen: unsigned char num to flash
/******************************************************************/
unsigned char flash_write_PAG(unsigned int addrH,
unsigned int addrL,
unsigned char* databuf,
unsigned int buflen,
{
ss_comm_latch(0x80,0);
ss_addr_latch(LOWBYTE(addrL));
ss_addr_latch(HIGHBYTE(addrL));
ss_addr_latch(LOWBYTE(addrH));
ss_addr_latch(HIGHBYTE(addrH));
for(;buflen>0;buflen--,databuf++)
ss_data_latch(*databuf);
ss_comm_latch(0x10,1); //twb+tprog
return ss_status_read(1);
}
io MAP已经补充,
SIGNAL_HOLD,//确保信号保持时间
SIGNAL_SETUP,//确保信号建立时间
SIG_INVALIDATE(); //System Interface Using CE don’t-care.
- 无线充电技术的未来发展方向(08-13)
- Vishay新款大电流电感器的额定电流达到100A(03-05)
- 凌力尔特新LED驱动器满足大电流LED应用(11-12)
- 德州仪器针对中国市场推出两款新型高性能11位ADC(11-17)
- 意法半导体数字功放系列单片音频解决方案新增数字功率放大器STA510F(01-24)
- TI发布新款电池电量监测计,面向智能电话及移动互联网设备(01-18)