新聞中心

EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 51單片機(jī)EEPROM(E2PROM)測(cè)試程序

51單片機(jī)EEPROM(E2PROM)測(cè)試程序

作者: 時(shí)間:2016-11-19 來(lái)源:網(wǎng)絡(luò) 收藏
/
** 文件名稱: eeprom.c * 摘 要:    對(duì)EEPROM某個(gè)扇區(qū)進(jìn)行讀、寫(xiě)和擦除,并發(fā)送到串口UART=9600 8位數(shù)據(jù) CRYSTAL=18.432 TIMER_MODE=12T(EEPROM就是DATA FLASH,擦除只能按扇區(qū),讀寫(xiě)可以按字節(jié),字節(jié)為0XFF時(shí)才可以寫(xiě))* CPU芯片:  STC12C5A16S2	  instruction mode:1T* 作 者:	 XCY* 修改日期: 2012年3月27日**/
#include #include typedef unsigned char 	BYTE;typedef unsigned int 	WORD;sfr AUXR = 0x8e;sfr S2CON = 0x9a;sfr S2BUF = 0x9b;sfr BRT = 0x9c;sfr IAP_DATA = 0XC2;sfr IAP_ADDRH = 0XC3;sfr IAP_ADDRL = 0XC4;sfr IAP_CMD = 0XC5;sfr IAP_TRIG = 0XC6;sfr IAP_CONTR = 0XC7;#define CMD_IDLE 	0#define CMD_READ 	1#define CMD_PROGRAM 2#define CMD_ERASE 	3#define BAUDBRT 0#define TIMER1 1#define S2RI 0X01#define S2TI 0x02//config#define IAP_ADDRESS 0x0000//const float code CRYSTAL = 18.432;#define CRYSTAL	18.432#define BAUDRATE_GENERATOR BAUDBRT#define UART 2#define ENABLE_IAP 0X82//sysclk<20mvoid InitUART1(void);	//串口1初始化 使用定時(shí)器1作為波特率發(fā)生器void InitUART1BRT(void);//串口1初始化 使用獨(dú)立波特率發(fā)生器void InitUART2(void);	//串口2初始化 必須使用獨(dú)立波特率發(fā)生器void Uart1Sendbyte(BYTE c);void Uart2Sendbyte(BYTE c);void IapIdle();BYTE IapReadByte(WORD addr);void IapProgramByte(WORD addr, BYTE dat);void IapEraseSector(WORD addr);BYTE data global_c,global_d;void delay10ms(void)   //誤差 -0.054253472222us{unsigned char a,b,c;for(c=4;c>0;c--)for(b=52;b>0;b--)for(a=220;a>0;a--);_nop_();  //if Keil,require use intrins.h}void main(){WORD data i;BYTE data c;#if UART == 1 && BAUDRATE_GENERATOR == TIMER1 	//串口1 定時(shí)器1InitUART1();#elif UART == 1 && BAUDRATE_GENERATOR == BAUDBRT 	//串口1 獨(dú)立波特率InitUART1BRT();#elif UART == 2								 //串口2 只能使用獨(dú)立波特率InitUART2();#endif//IapEraseSector(IAP_ADDRESS);	  //erase//for(i = 0; i < 512; i++)  //check all byte is 0xff//if(IapReadByte(IAP_ADDRESS+i) != 0xff)//	goto Error;//	for(i = 0; i < 512; i++)  //write//	IapProgramByte(IAP_ADDRESS+i,(BYTE)i);for(i = 0; i < 512; i++)  //read{c = IapReadByte(IAP_ADDRESS+i);Uart2Sendbyte(c);		  //sendif(c != (BYTE)i)goto Error;}P2 = 0xfe;while(1);Error:P1 = 0xdf;while(1);}void InitUART1(void)	//串口1初始化 使用定時(shí)器1作為波特率發(fā)生器{//9600bps timer mode:12T 8位數(shù)據(jù)PCON &= 0x7f;TMOD = TMOD & 0x0f;TMOD = TMOD | 0x20;SCON = 0x50;#if CRYSTAL == 18.432TH1 = 0xFB;	#elif CRYSTAL == 11.0592TH1 = 0xFD;#endifTL1 = TH1;AUXR &= 0xbf;AUXR &= 0xfe;ET1 = 0;EA = 1;ES = 1;TR1 = 1;}void InitUART1BRT()		{	//9600bps	timer mode:12T 8位數(shù)據(jù)PCON &= 0x7f;		//波特率不倍速SCON = 0x50;		//8位數(shù)據(jù),可變波特率#if CRYSTAL == 18.432BRT = 0xFB;		//設(shè)定獨(dú)立波特率發(fā)生器重裝值#elif CRYSTAL == 11.0592BRT = 0xFD;#endifAUXR &= 0xfb;		//獨(dú)立波特率發(fā)生器時(shí)鐘為Fosc/12,即12TAUXR |= 0x01;		//串口1選擇獨(dú)立波特率發(fā)生器為波特率發(fā)生器AUXR |= 0x10;		//啟動(dòng)獨(dú)立波特率發(fā)生器EA = 1;ES = 1;}void InitUART2()	//串口2初始化 必須使用獨(dú)立波特率發(fā)生器  {//9600bps	timer mode:12T	8位數(shù)據(jù)AUXR &= 0xf7;		//波特率不倍速S2CON = 0x50;		//8位數(shù)據(jù),可變波特率#if CRYSTAL == 18.432BRT = 0xfb;		   //設(shè)定獨(dú)立波特率發(fā)生器重裝值#elif CRYSTAL == 11.0592BRT = 0Xfd;		   //設(shè)定獨(dú)立波特率發(fā)生器重裝值#endifAUXR &= 0xfb;		//獨(dú)立波特率發(fā)生器時(shí)鐘為Fosc/12,即12TAUXR |= 0x10;		//啟動(dòng)獨(dú)立波特率發(fā)生器EA = 1;ES = 1;}void Uart1Sendbyte(BYTE c){SBUF = c;while(!TI);TI = 0;}void Uart2Sendbyte(BYTE c){S2BUF = c;while(!(S2CON & S2TI));S2CON &= 0XFD;}void Uart1_Int() interrupt 4 using 1 //using 1:使用第一組寄存器//(對(duì)于同級(jí)中斷,用同樣的寄存器組,因?yàn)椴粫?huì)中斷嵌套,就不會(huì)出問(wèn)題;//對(duì)于不同級(jí)別的中斷,一定不能使用同組寄存器,嵌套可能改變寄存器的值,引起錯(cuò)誤){if(RI)	//串口每接收完1幀,硬件置1 RI,請(qǐng)求中斷。{	 	//(其實(shí)就是請(qǐng)求把RI置0并且取走數(shù)據(jù),不然還能干什么呢?//當(dāng)然你可以加入自己想要的功能在里面)global_c = SBUF;SBUF = global_c;RI = 0;			}else TI = 0; 		}void Uart2_Int() interrupt 8 using 1{if(S2CON&S2RI){S2CON &= 0XFE;global_d = S2BUF;SBUF  = global_d; }else S2CON &= 0XFD;}void IapIdle(){IAP_CONTR &= 0X7F;  //DISABLE IAP FUNCTIONIAP_CMD = 0;IAP_TRIG = 0;		//CLEAR TRIG REGESTERIAP_ADDRH = 0X2000;IAP_ADDRL = 0;}BYTE IapReadByte(WORD addr){BYTE dat;IAP_CONTR = ENABLE_IAP;	//使能IAP功能IAP_CMD = CMD_READ;		//說(shuō)明是讀還是寫(xiě)還是擦除IAP_ADDRL = addr;		//給定要操作的扇區(qū)地址IAP_ADDRH = addr>>8;IAP_TRIG = 0X5A;        //IAP觸發(fā)開(kāi)關(guān) 先送5A后送A5才能觸發(fā),IAP命令才能生效 每次讀寫(xiě)都要重新送值IAP_TRIG = 0XA5;_nop_();				//延時(shí),等待讀取dat = IAP_DATA;			//將讀取的數(shù)據(jù)賦值給datIapIdle();				//將IAP功能設(shè)置成空閑return dat;}void IapProgramByte(WORD addr, BYTE dat){IAP_CONTR = ENABLE_IAP;IAP_CMD = CMD_PROGRAM;IAP_ADDRL = addr;IAP_ADDRH = addr>>8;IAP_DATA = dat;IAP_TRIG = 0X5A;IAP_TRIG = 0XA5;_nop_();IapIdle();}void IapEraseSector(WORD addr){IAP_CONTR = ENABLE_IAP;IAP_CMD = CMD_ERASE;IAP_ADDRL = addr;IAP_ADDRH = addr>>8;IAP_TRIG = 0X5A;IAP_TRIG = 0XA5;_nop_();IapIdle();}


評(píng)論


技術(shù)專區(qū)

關(guān)閉