?? at45db081test.c
字號:
/***************************************************************
功能:實(shí)現(xiàn)存儲器EEPROM AT45db081的數(shù)據(jù)讀寫操作,同時了解硬件spi讀寫操作
作者:ZDP
時間:2005-11-30
版本:V1.0
***************************************************************/
#include <c8051f020.h>
#include <stdio.h>
#include <intrins.h>
unsigned int Count1msInc;
unsigned int AT450XXPageAddr;
void SYSCLK_Init (void);
void PORT_Init (void);
void SPI0_Init (void);
void Timer0_Init (void);
#define SYSCLK 11059200
#define DF_RESET P4&=~0x10; P4|=0x10; // AT45DB081復(fù)位
#define DF_RDY_BUSY P4|=0x20; while(!(P4&0x20)); // 等待AT45DB081準(zhǔn)備好
#define DF_CHIP_SELECT P4&=~0x4; // AT45DB081片選開
#define DF_CHIP_NOSELECT P4|=0x4; // AT45DB081片選關(guān)
#define RAM_CHIP_SELECT_BANK0 ES0=1;P4 = 0xF4;
#define RAM_CHIP_SELECT_BANK1 P4 = 0xF5;
#define BUFFER_1 0x00 // buffer 1
#define BUFFER_2 0x01 // buffer 2
#define BUFFER_1_WRITE 0x84 // buffer 1 write
#define BUFFER_2_WRITE 0x87 // buffer 2 write
#define BUFFER_1_READ 0x54 // buffer 1 read (change to 0xD4 for SPI mode 0,3)
#define BUFFER_2_READ 0x56 // buffer 2 read (change to 0xD6 for SPI mode 0,3)
#define B1_TO_PAGE_WITH_ERASE 0x83 // buffer 1 to main memory page program with built-in erase
#define B2_TO_PAGE_WITH_ERASE 0x86 // buffer 2 to main memory page program with built-in erase
#define B1_TO_PAGE_WITHOUT_ERASE 0x88 // buffer 1 to main memory page program without built-in erase
#define B2_TO_PAGE_WITHOUT_ERASE 0x89 // buffer 2 to main memory page program without built-in erase
#define PAGE_PROG_THROUGH_B1 0x82 // main memory page program through buffer 1
#define PAGE_PROG_THROUGH_B2 0x85 // main memory page program through buffer 2
#define AUTO_PAGE_REWRITE_THROUGH_B1 0x58 // auto page rewrite through buffer 1
#define AUTO_PAGE_REWRITE_THROUGH_B2 0x59 // auto page rewrite through buffer 2
#define PAGE_TO_B1_COMP 0x60 // main memory page compare to buffer 1
#define PAGE_TO_B2_COMP 0x61 // main memory page compare to buffer 2
#define PAGE_TO_B1_XFER 0x53 // main memory page to buffer 1 transfer
#define PAGE_TO_B2_XFER 0x55 // main memory page to buffer 2 transfer
#define STATUS_REGISTER 0x57
#define MAIN_MEMORY_PAGE_READ 0x52 // main memory page read (change to 0xD2 for SPI mode 0,3)
void SendSPIByte(unsigned char ch)
{
SPIF = 0;
SPI0DAT = ch;
while (SPIF == 0); // 等待寫結(jié)束
}
unsigned char GetSPIByte(void)
{
SPIF = 0;
SPI0DAT = 0;
while (SPIF == 0);
return SPI0DAT; // 等待讀結(jié)束
}
//啟用緩存1讀
void FlashBuffer1Read(unsigned int star_addr,unsigned int len, unsigned char *buffer) //從緩沖區(qū)1的指定位置(0-263)中讀入指定字節(jié)
{
unsigned int i;
DF_RDY_BUSY;//測芯片準(zhǔn)備好?
DF_CHIP_SELECT;//芯片選擇
SendSPIByte(BUFFER_1_READ); //緩沖區(qū)1為54H
SendSPIByte(0);
SendSPIByte((unsigned char)(star_addr>>8));
SendSPIByte((unsigned char)star_addr);
SendSPIByte(0);
for (i=0;i<len;i++)
{
buffer[i] = GetSPIByte(); // read data from SPI
}
DF_CHIP_NOSELECT;
}
//啟用緩存2讀
void FlashBuffer2Read(unsigned int star_addr,unsigned int len, unsigned char *buffer) //從緩沖區(qū)2的指定位置(0-263)中讀入指定字節(jié)
{
unsigned int i;
DF_RDY_BUSY;//測芯片準(zhǔn)備好?
DF_CHIP_SELECT;//芯片選擇
SendSPIByte(BUFFER_2_READ); //緩沖區(qū)2為56H
SendSPIByte(0);
SendSPIByte((unsigned char)(star_addr>>8));
SendSPIByte((unsigned char)star_addr);
SendSPIByte(0);
for (i=0;i<len;i++)
{
*buffer = GetSPIByte(); // read data from SPI
buffer++;
}
DF_CHIP_NOSELECT;
}
//啟用緩存1寫
void FlashBuffer1Write(unsigned int start_addr, unsigned int len,unsigned char *buffer) //向緩沖區(qū)1的指定位置(0-263)寫入指定字節(jié)
{
unsigned int i;
DF_RDY_BUSY;//測芯片準(zhǔn)備好?
DF_CHIP_SELECT;//芯片選擇
SendSPIByte(BUFFER_1_WRITE);//緩沖區(qū)1為84H
SendSPIByte(0x00);
SendSPIByte((unsigned char)(start_addr>>8));
SendSPIByte((unsigned char)start_addr);
for (i=0;i<len;i++)
SendSPIByte(buffer[i]);
DF_CHIP_NOSELECT;
}
//啟用緩存2寫
void FlashBuffer2Write(unsigned int start_addr, unsigned int len,unsigned char *buffer) //向緩沖區(qū)2的指定位置(0-263)寫入指定字節(jié)
{
unsigned int i;
DF_RDY_BUSY;//測芯片準(zhǔn)備好?
DF_CHIP_SELECT;//芯片選擇
SendSPIByte(BUFFER_2_WRITE);//緩沖區(qū)2為87H
SendSPIByte(0x00);
SendSPIByte((unsigned char)(start_addr>>8));
SendSPIByte((unsigned char)start_addr);
for (i=0;i<len;i++)
SendSPIByte(buffer[i]);
DF_CHIP_NOSELECT;
}
//讀取狀態(tài)
unsigned char GetFlashStatus() //讀Flash當(dāng)前狀態(tài)Bit7=1:空閑 0:忙 Bit6=1:比較結(jié)果不匹配 0:匹配 Bit5Bit3Bit2:芯片標(biāo)志 100:081
{
unsigned char idata ret;
DF_CHIP_SELECT;//芯片選擇
SendSPIByte(STATUS_REGISTER);
ret=GetSPIByte();
DF_CHIP_NOSELECT;
return ret;
}
//讀主存至緩存
void PageToBuffer1(void) //從Flash讀一頁至緩存1
{
DF_RDY_BUSY;//測芯片準(zhǔn)備好?
DF_CHIP_SELECT;//芯片選擇
SendSPIByte(PAGE_TO_B1_XFER);
SendSPIByte((unsigned char)(AT450XXPageAddr >> 7));
SendSPIByte((unsigned char)(AT450XXPageAddr << 1));
SendSPIByte(0);
DF_CHIP_NOSELECT;
}
//讀主存至緩存
void PageToBuffer2(void) //從Flash讀一頁至緩存2
{
DF_RDY_BUSY;//測芯片準(zhǔn)備好?
DF_CHIP_SELECT;//芯片選擇
SendSPIByte(PAGE_TO_B2_XFER);
SendSPIByte((unsigned char)(AT450XXPageAddr >> 7));
SendSPIByte((unsigned char)(AT450XXPageAddr << 1));
SendSPIByte(0);
DF_CHIP_NOSELECT;
}
//緩存1寫主存
void FlashBuffer1ProgNoErase(void) //直接將緩存1寫入Flash一頁(不擦除)
{
DF_RDY_BUSY;//測芯片準(zhǔn)備好?
DF_CHIP_SELECT;//芯片選擇
SendSPIByte(B1_TO_PAGE_WITHOUT_ERASE);
SendSPIByte((unsigned char)(AT450XXPageAddr >> 7));
SendSPIByte((unsigned char)(AT450XXPageAddr << 1));
SendSPIByte(0x00);
DF_CHIP_NOSELECT;
}
//緩存2寫主存
void FlashBuffer2ProgNoErase(void) //直接將緩存2寫入Flash一頁(不擦除)
{
DF_RDY_BUSY;//測芯片準(zhǔn)備好?
DF_CHIP_SELECT;//芯片選擇
SendSPIByte(B2_TO_PAGE_WITHOUT_ERASE);
SendSPIByte((unsigned char)(AT450XXPageAddr >> 7));
SendSPIByte((unsigned char)(AT450XXPageAddr << 1));
SendSPIByte(0x00);
DF_CHIP_NOSELECT;
}
//擦除+緩存1寫主存
void FlashBuffer1ProgAutoErase(void) //直接將緩存1寫入Flash一頁(先擦除)
{
DF_RDY_BUSY;//測芯片準(zhǔn)備好?
DF_CHIP_SELECT;//芯片選擇
SendSPIByte(B1_TO_PAGE_WITH_ERASE);
SendSPIByte((unsigned char)(AT450XXPageAddr >> 7));
SendSPIByte((unsigned char)(AT450XXPageAddr << 1));
SendSPIByte(0x00);
DF_CHIP_NOSELECT;
}
//擦除+緩存2寫主存
void FlashBuffer2ProgAutoErase(void) //直接將緩存2寫入Flash一頁(先擦除)
{
DF_RDY_BUSY;//測芯片準(zhǔn)備好?
DF_CHIP_SELECT;//芯片選擇
SendSPIByte(B2_TO_PAGE_WITH_ERASE);
SendSPIByte((unsigned char)(AT450XXPageAddr >> 7));
SendSPIByte((unsigned char)(AT450XXPageAddr << 1));
SendSPIByte(0x00);
DF_CHIP_NOSELECT;
}
//讀主存
//寫緩存+緩存寫主存
void FlashProgViaBuffer1(unsigned int start_addr, unsigned int len,unsigned char *buffer) //將指定數(shù)據(jù)通過緩存1寫入Flash指定位置(不擦除)
{
unsigned int i;
DF_RDY_BUSY;//測芯片準(zhǔn)備好?
DF_CHIP_SELECT;//芯片選擇
SendSPIByte(PAGE_PROG_THROUGH_B1);//緩沖區(qū)1為82H
SendSPIByte((unsigned char)(AT450XXPageAddr >> 7));
SendSPIByte((unsigned char)(AT450XXPageAddr << 1 + start_addr>>8));
SendSPIByte((unsigned char)start_addr);
for (i=0;i<len;i++)
SendSPIByte(buffer[i]);
DF_CHIP_NOSELECT;
}
//寫緩存+緩存寫主存
void FlashProgViaBuffer2(unsigned int start_addr, unsigned int len,unsigned char *buffer) //將指定數(shù)據(jù)通過緩存2寫入Flash指定位置(不擦除)
{
unsigned int i;
DF_RDY_BUSY;//測芯片準(zhǔn)備好?
DF_CHIP_SELECT;//芯片選擇
SendSPIByte(PAGE_PROG_THROUGH_B2);//緩沖區(qū)2為85H
SendSPIByte((unsigned char)(AT450XXPageAddr >> 7));
SendSPIByte((unsigned char)(AT450XXPageAddr << 1 + start_addr>>8));
SendSPIByte((unsigned char)start_addr);
for (i=0;i<len;i++)
SendSPIByte(buffer[i]);
DF_CHIP_NOSELECT;
}
//寫緩存+擦除+緩存寫主存
void FlashAutoProgViaBuffer1(unsigned int start_addr, unsigned int len,unsigned char *buffer) //將指定數(shù)據(jù)通過緩存1寫入Flash指定位置(先擦除)
{
unsigned int i;
DF_RDY_BUSY;//測芯片準(zhǔn)備好?
DF_CHIP_SELECT;//芯片選擇
SendSPIByte(AUTO_PAGE_REWRITE_THROUGH_B1);//緩沖區(qū)1為84H
SendSPIByte((unsigned char)(AT450XXPageAddr >> 7));
SendSPIByte((unsigned char)(AT450XXPageAddr << 1 + start_addr>>8));
SendSPIByte((unsigned char)start_addr);
for (i=0;i<len;i++)
SendSPIByte(buffer[i]);
DF_CHIP_NOSELECT;
}
//寫緩存+擦除+緩存寫主存
void FlashAutoProgViaBuffer2(unsigned int start_addr, unsigned int len,unsigned char *buffer) //將指定數(shù)據(jù)通過緩存2寫入Flash指定位置(先擦除)
{
unsigned int i;
DF_RDY_BUSY;//測芯片準(zhǔn)備好?
DF_CHIP_SELECT;//芯片選擇
SendSPIByte(AUTO_PAGE_REWRITE_THROUGH_B2);//緩沖區(qū)2為87H
SendSPIByte((unsigned char)(AT450XXPageAddr >> 7));
SendSPIByte((unsigned char)(AT450XXPageAddr << 1 + start_addr>>8));
SendSPIByte((unsigned char)start_addr);
for (i=0;i<len;i++)
SendSPIByte(buffer[i]);
DF_CHIP_NOSELECT;
}
void main (void) {
unsigned char xdata MyBuff[270];
unsigned char xdata MyBuff1[270];
unsigned char xdata *idata MyBuff11;
unsigned int i,j;
WDTCN = 0xde; // disable watchdog timer
WDTCN = 0xad;
SYSCLK_Init (); // initialize oscillator
Timer0_Init();
PORT_Init (); // initialize crossbar and GPIO
EA=1;
DF_RESET;
SPI0_Init (); // initialize SPI0
// RAM_CHIP_SELECT_BANK0;
// EMI0CF = 0x2F;
/*---------------------------------------------------------------------------
緩存讀寫測試
---------------------------------------------------------------------------*/
for(j=0;j<264;j++) //初始化數(shù)組數(shù)據(jù)為:0--264
{
MyBuff[j]=j;
}
FlashBuffer1Write(0,264,MyBuff); //寫數(shù)據(jù)至數(shù)據(jù)緩存區(qū)1
_nop_();
for(j=0;j<264;j++) //初始化數(shù)組數(shù)據(jù)全為:0
{
MyBuff[j]=0;
}
FlashBuffer1Read(0,264,MyBuff); //讀數(shù)據(jù)緩存區(qū)1數(shù)據(jù)至數(shù)組
_nop_();
/*---------------------------------------------------------------------------
FLASH讀寫測試
---------------------------------------------------------------------------*/
for(i=0;i<4096;i++)
{ MyBuff[0]=i>>8;
MyBuff[1]=i; //將頁地址寫入數(shù)組的前兩個字節(jié).
for(j=2;j<264;j++)
{
MyBuff[j]=i;
} //向數(shù)組寫數(shù)據(jù)共262個字節(jié)
AT450XXPageAddr=i; //指定待寫頁
FlashBuffer1Write(0,264,MyBuff);//將數(shù)組的內(nèi)容寫入緩存1
FlashBuffer1ProgAutoErase(); //將緩存的內(nèi)容寫入主存(帶擦除)
}
_nop_();
for(i=0;i<4096;i++)
{
AT450XXPageAddr=i; //指定待讀頁
MyBuff11=0x0+i*264; //指定數(shù)據(jù)放置的XRAM的地址(首地址為0x0).
PageToBuffer2(); //將主存內(nèi)容讀入緩存2
FlashBuffer2Read(0,264,MyBuff11); //將緩存2的內(nèi)容讀入XRAM
_nop_(); //在此設(shè)斷點(diǎn)觀察XRAM中的數(shù)據(jù)是否與寫入的數(shù)據(jù)相符.
}
_nop_(); //同時在此設(shè)一斷點(diǎn)在全部讀完主存后觀察XRAM中的內(nèi)容.
/*---------------------------------------------------------------------------
其它測試
---------------------------------------------------------------------------*/
AT450XXPageAddr=0;
FlashBuffer1Write(20,14,"1234567890UUAA");
FlashBuffer1Read(0,260,MyBuff1);
FlashBuffer1Write(20,14,"3234567890UUAA");
FlashBuffer1Read(20,14,MyBuff); //在此處設(shè)置斷點(diǎn),觀察MyBuff的內(nèi)容
FlashBuffer1ProgNoErase();
PageToBuffer2();
FlashBuffer2Read(20,14,MyBuff);
Count1msInc=0;
FlashBuffer2Read(100,14,MyBuff);
Count1msInc=0;
FlashBuffer1Write(20,14,"1234567890UUAA");
Count1msInc=0;
FlashBuffer1Read(100,14,MyBuff);
Count1msInc=0;
FlashBuffer1ProgNoErase();
Count1msInc=0;
PageToBuffer2();
Count1msInc=0;
FlashBuffer2Read(100,14,MyBuff);
FlashProgViaBuffer1(100,14,MyBuff);
//ErasingDataFlash();
//EraseFlashPage();
FlashBuffer1Read(1,1, MyBuff); //從緩沖區(qū)1的指定位置(0-263)中讀入指定字節(jié)
FlashBuffer2Read(1,1,MyBuff); //從緩沖區(qū)2的指定位置(0-263)中讀入指定字節(jié)
FlashBuffer1Write(1,1,"!");
FlashBuffer2Write(1,1,"1");
GetFlashStatus();
PageToBuffer1();
PageToBuffer2();
FlashBuffer1ProgNoErase();
FlashBuffer2ProgNoErase();
FlashBuffer1ProgAutoErase();
FlashBuffer2ProgAutoErase();
FlashProgViaBuffer1(1,1, MyBuff);
FlashProgViaBuffer2(1,1, MyBuff);
FlashAutoProgViaBuffer1(1,1, MyBuff);
FlashAutoProgViaBuffer2(1,1, MyBuff);
while(1);
}
void SYSCLK_Init (void)
{
int i; // delay counter
OSCXCN = 0x67; // start external oscillator with
// 11.0592MHz crystal
for (i=0; i < 256; i++) ; // Wait for osc. to start up
while (!(OSCXCN & 0x80)) ; // Wait for crystal osc. to settle
OSCICN = 0x88; // select external oscillator as SYSCLK
// source and enable missing clock
}
void PORT_Init (void)
{
XBR0 = 0x07; // Enable SMBus, SPI0, and UART0
XBR1 = 0x00;
XBR2 = 0x44; // Enable crossbar and weak pull-ups
// EMI0TC = 0x21;
P74OUT = 0x00;
P0MDOUT = 0x15;
}
void SPI0_Init (void)
{
SPI0CFG = 0x07; // data sampled on 1st SCK rising edge
// 8-bit data words
SPI0CFG|=0xC0;//CKPOL =1;
SPI0CN = 0x03; // Master mode; SPI enabled; flags
// cleared
SPI0CKR = SYSCLK/2/2000000-1; // SPI clock <= 8MHz (limited by
// EEPROM spec.)
}
void Timer0_Init (void)
{
CKCON|=0x8;
TMOD|=0x1; //16Bit
TR0 = 0; // STOP Timer0
TH0 = (-SYSCLK/1000) >> 8; // set Timer0 to overflow in 1ms
TL0 = -SYSCLK/1000;
TR0 = 1; // START Timer0
IE|= 0x2;
}
void Timer0_ISR (void) interrupt 1 //1ms
{
TH0 = (-SYSCLK/1000) >> 8;
TL0 = -SYSCLK/1000;
Count1msInc++;
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -