|
|||||||||||
| 技術交流 | 電路欣賞 | 工控天地 | 數(shù)字廣電 | 通信技術 | 電源技術 | 測控之家 | EMC技術 | ARM技術 | EDA技術 | PCB技術 | 嵌入式系統(tǒng) 驅動編程 | 集成電路 | 器件替換 | 模擬技術 | 新手園地 | 單 片 機 | DSP技術 | MCU技術 | IC 設計 | IC 產業(yè) | CAN-bus/DeviceNe |
暴力寫壞AVR的EEPROM,附測試程序,請評測指正 |
| 作者:雙龍 欄目:單片機 |
AVR的EEPROM可重復寫入次數(shù)是多少次?以前有人問,答是10萬次。 Non-volatile Program and Data Memories – 4/8/16K Bytes of In-System Self-Programmable FLASH (ATmega48/88/168) Endurance: 10,000 Write/Erase Cycles – Optional Boot Code Section with Independent LOCK Bits In-System PROGRAMMING by On-chip Boot Program True Read-While-Write Operation – 256/512/512 Bytes EEPROM (ATmega48/88/168) Endurance: 100,000 Write/Erase Cycles – 512/1K/1K Byte Internal SRAM (ATmega48/88/168) – PROGRAMMING LOCK for SOFTWARE Security 但EEPROM的壽命應該沒這么短。 于是利用我公司的SL-MEGA8實驗器,使用MEGA48芯片,讓我公司的一位新來的工程師做了個練手程序,沒怎么修改,請大家評測。程序如有不妥,也請指出。 實測,試了3個EEPROM地址段,認為AVR的EEPROM壽命應該有500萬次以上。 這個測試只是驗證下EEPROM的壽命,客戶實際設計,仍建議以ATMEL官方數(shù)據(jù)為準。 |
| 2樓: | >>參與討論 |
| 作者: 雙龍 于 2004/12/21 16:24:00 發(fā)布:
測試程序 /*****************************************************/ /* 廣州市天河雙龍電子公司北京分公司 */ /* http://www.sl.com.cn */ /* 測試EEPROM讀寫次數(shù) */ /* 作者:劉成利 */ /* E-mail:lcl@sl.com.cn */ /* 2004年12月21日 */ /* 目標MCU:MEGA48 晶振:內部RC(INT) 8MHZ */ /*****************************************************/ #include "iom48v.h" #include "macros.h" #define fosc 8000000 //內部8MHZ晶振 #define baud 19200 //波特率 unsigned CHAR eep_r;//EEPROM讀出的數(shù)據(jù) unsigned CHAR kk;//EEPROM讀寫次數(shù)第一部分 unsigned int count;//EEPROM讀寫次數(shù)第二部分 /*************************************** 串口輸出函數(shù),用于發(fā)送記數(shù)結果 ****************************************/ void putCHAR(unsigned CHAR c) { while (!(UCSR0A&(1<<UDRE0))); //置usart數(shù)據(jù)寄存器空,系統(tǒng)復位時,udre位置1,表示數(shù)據(jù)發(fā)送已準備好 UDR0=c;//數(shù)據(jù)寄存器 } /************************************** 串口初始化 ***************************************/ void uart_init(void) { UCSR0B=(1<<RXEN0)|(1<<TXEN0);//允許發(fā)送和接收 UBRR0L=(fosc/16/(baud+1))%256;//對波特率寄存器預置數(shù) UBRR0H=(fosc/16/(baud+1))/256; UCSR0C=(0<<UMSEL01)|(0<<UMSEL00)|(1<<UCSZ01)|(1<<UCSZ00);//8位數(shù)據(jù)+1位STOP位 } /*********************************** 主程序 ***********************************/ void main(void) { count = 0; //記數(shù)初值為0 PORTD=0xFF; //開放D口 DDRD=0xFF; PORTB=0xFF;//開放B口 DDRB=0xFF; uart_init(); CLI(); //關中斷,以免干涉EEPROM的寫入 while(1) { EEPROM_write(0x00FD,0X5A);//寫地址和數(shù)據(jù),可修改 eep_r=EEPROM_read(0x00FD); comp(); EEPROM_write(0x00FD,0XA5);//寫地址和數(shù)據(jù),可修改 eep_r=EEPROM_read(0x00FD); comp(); } } /******************************************************************* 對讀出的數(shù)據(jù)進行比較 正確……LED顯示R,并從串口發(fā)送數(shù)據(jù)kk 錯誤……LED顯示F,并從串口發(fā)送數(shù)據(jù)kk,count 讀寫總次數(shù)為:kk*4000+count ******************************************************************/ void comp(void) { unsigned CHAR eep_old; eep_old = eep_r&0x0f; //取EEPROM的低4位 eep_r = eep_r >> 4; //取EEPROM的高4位 if(eep_old+eep_r != 0x0f ) //低4位加高4位,結果和F比較 { putCHAR(kk); //輸出最終記數(shù)值 putCHAR(count); //輸出此時的已讀寫次數(shù),總數(shù)為:kk*4000+count(次) PORTB=0x8E; //點亮LED PORTD=0xEF; while(1); //讀取數(shù)據(jù),發(fā)生一次錯誤后,程序在此處掛起。 } else { count++; //每讀寫一次,count累加1 if(count>=4000) //每讀寫4000次,KK累加1 { //并從串口送出KK count=count-4000; kk++; putCHAR(kk); } //點亮LED PORTB=0x88; PORTD=0x7F; } } /********************************************* EEPROM寫操作 ********************************************/ void EEPROM_write(unsigned int uiAddress, unsigned CHAR ucData) { while(EECR & (1<<EEWE)); EEAR = uiAddress; EEDR = ucData; EECR |= (1<<EEMWE); EECR |= (1<<EEWE); } /******************************************** EEPROM讀操作 *******************************************/ unsigned CHAR EEPROM_read(unsigned int uiAddress) { while(EECR & (1<<EEWE)); EEAR = uiAddress; EECR |= (1<<EERE); return EEDR; } |
|
| 3樓: | >>參與討論 |
| 作者: AA55 于 2004/12/21 16:30:00 發(fā)布:
如果用作消費或者玩具類產品 大膽用到100萬次也無妨。 |
|
| 4樓: | >>參與討論 |
| 作者: 牧石.馬 于 2004/12/21 16:51:00 發(fā)布:
波特率計算公式 UBRR0L=(fosc/(16*baud)-1)%256; UBRR0H=(fosc/(16*baud)-1)/256; |
|
| 5樓: | >>參與討論 |
| 作者: qjy_dali 于 2004/12/21 20:46:00 發(fā)布:
請試試128的FLASH能寫多少次? |
|
| 6樓: | >>參與討論 |
| 作者: martin 于 2004/12/21 20:58:00 發(fā)布:
這種測試沒有意義 這個壽命值本來就是大量實驗的估計值,一般達到這個壽命時芯片不良率會增高,超出允許范圍,很多公司的不良允許范圍是小于萬分之一,甚至十萬分之一,想用這樣的實驗說明什么實在沒必要。 |
|
| 7樓: | >>參與討論 |
| 作者: 牧石.馬 于 2004/12/21 21:32:00 發(fā)布:
程序有多處不嚴謹?shù)牡胤?br>1 波特率計算公式 2 putchar(count); count可是int型的啊 3 500萬次不知是怎么得出的 用這個公式 kk*4000+count 最大計數(shù)也就100多萬 |
|
| 8樓: | >>參與討論 |
| 作者: americ 于 2004/12/22 11:37:00 發(fā)布:
程序運行了多長時間? 即將進行類似工作,嘻嘻。 |
|
| 9樓: | >>參與討論 |
| 作者: victorymay 于 2004/12/22 11:44:00 發(fā)布:
正需相關資料,值得借鑒 |
|
| 10樓: | >>參與討論 |
| 作者: NE5532 于 2004/12/22 20:55:00 發(fā)布:
我一直不喜歡那個PUTCHAR函數(shù)。 給人的感覺好像是只有這里能輸出一樣。并且這個函數(shù)也沒有進行串口數(shù)據(jù)打包工作吧? |
|
| 11樓: | >>參與討論 |
| 作者: 雙龍 于 2004/12/23 14:20:00 發(fā)布:
略作修改的程序,請再評測。 /*****************************************************/ /* 廣州天河雙龍電子公司北京分公司 */ /* http://www.sl.com.cn */ /* 測試EEPROM讀寫次數(shù) */ /* 作者:劉成利 */ /* E-mail:lcl@sl.com.cn */ /* 2004年12月21日 */ /* 目標MCU:MEGA48 晶振:內部RC(INT) 8MHZ */ /*****************************************************/ #include "iom48v.h" #include "macros.h" #define fosc 8000000 //內部8MHZ晶振 #define baud 19200 //波特率 unsigned CHAR eep_r;//EEPROM讀出的數(shù)據(jù) unsigned CHAR N;//EEPROM讀寫次數(shù)第一部分 unsigned CHAR kk;//EEPROM讀寫次數(shù)第二部分 unsigned int count;//EEPROM讀寫次數(shù)第三部分 /*************************************** 串口輸出函數(shù),用于發(fā)送記數(shù)結果 ****************************************/ void putCHAR(unsigned CHAR c) { while (!(UCSR0A&(1<<UDRE0))); //置usart數(shù)據(jù)寄存器空,系統(tǒng)復位時,udre位置1,表示數(shù)據(jù)發(fā)送已準備好 UDR0=c;//數(shù)據(jù)寄存器 } /************************************** 串口初始化 ***************************************/ void uart_init(void) { UCSR0B=(1<<RXEN0)|(1<<TXEN0);//允許發(fā)送和接收 UBRR0L=(fosc/(16*baud)-1)%256;//對波特率寄存器預置數(shù) UBRR0H=(fosc/(16*baud)-1)/256; UCSR0C=(0<<UMSEL01)|(0<<UMSEL00)|(1<<UCSZ01)|(1<<UCSZ00);//8位數(shù)據(jù)+1位STOP位 } /*********************************** 主程序 ***********************************/ void main(void) { PORTD=0xFF; //開放D口 DDRD=0xFF; PORTB=0xFF;//開放B口 DDRB=0xFF; uart_init(); CLI(); //關中斷,以免干涉EEPROM的寫入 while(1) { EEPROM_write(0x00FD,0X5A);//寫地址和數(shù)據(jù),可修改 eep_r=EEPROM_read(0x00FD); comp(); EEPROM_write(0x00FD,0XA5);//寫地址和數(shù)據(jù),可修改 eep_r=EEPROM_read(0x00FD); comp(); } } /******************************************************************* 對讀出的數(shù)據(jù)進行比較 正確……LED顯示R,并從串口發(fā)送數(shù)據(jù)kk 錯誤……LED顯示F,并從串口發(fā)送數(shù)據(jù)kk,count 讀寫總次數(shù)為:(N*256+kk)*4000+count ******************************************************************/ void comp(void) { unsigned CHAR eep_old,count_high,count_low; eep_old = eep_r&0x0f; //取EEPROM的低4位 eep_r = eep_r >> 4; //取EEPROM的高4位 if(eep_old+eep_r != 0x0f ) //低4位加高4位,結果和F比較 { count_high =count >> 8; count_low=count&0xff; putCHAR(N);//輸出最終記數(shù)值 putCHAR(kk); //輸出最終記數(shù)值 putCHAR(count_high); //輸出此時的已讀寫次數(shù),總數(shù)為:(N*256+kk)*4000+count(次) putCHAR(count_low); PORTB=0x8E; //點亮LED PORTD=0xEF; while(1); //讀取數(shù)據(jù),發(fā)生一次錯誤后,程序在此處掛起。 } else { count++; //每讀寫一次,count累加1 if(count>=4000) //每讀寫4000次,KK累加1 { //并從串口送出KK count=count-4000; kk++; if(kk>=255) { N++; } putCHAR(N); putCHAR(kk); } //點亮LED PORTB=0x88; PORTD=0x7F; } } /********************************************* EEPROM寫操作 ********************************************/ void EEPROM_write(unsigned int uiAddress, unsigned CHAR ucData) { while(EECR & (1<<EEWE)); EEAR = uiAddress; EEDR = ucData; EECR |= (1<<EEMWE); EECR |= (1<<EEWE); } /******************************************** EEPROM讀操作 *******************************************/ unsigned CHAR EEPROM_read(unsigned int uiAddress) { while(EECR & (1<<EEWE)); EEAR = uiAddress; EECR |= (1<<EERE); return EEDR; } |
|
| 12樓: | >>參與討論 |
| 作者: winsu 于 2004/12/23 15:20:00 發(fā)布:
為何不測試整片的? 而只測試某地址的? 這樣做是為了速度快? 不知道EEPROM的各位壽命是否相同,會不會某些位壞了,而某些壞好的。 那么這個測試只能證明該地址的壽命? |
|
| 13樓: | >>參與討論 |
| 作者: NE5532 于 2004/12/23 19:57:00 發(fā)布:
嗯,我喜歡寫自加數(shù)列。 |
|
|
|
| 免費注冊為維庫電子開發(fā)網(wǎng)會員,參與電子工程師社區(qū)討論,點此進入 |
Copyright © 1998-2006 m.58mhw.cn 浙ICP證030469號 |