|
- .C
- #include "eeprom.h"
- #include "STC15Fxxxx.H"
- //========================================================================
- // 函數(shù): void ISP_Disable(void)
- // 描述: 禁止訪問(wèn)ISP/IAP.
- // 參數(shù): non.
- // 返回: non.
- // 版本: V1.0, 2022-05-28
- //========================================================================
- void DisableEEPROM(void)
- {
- ISP_CONTR = 0; //禁止ISP/IAP操作
- ISP_CMD = 0; //去除ISP/IAP命令
- ISP_TRIG = 0; //防止ISP/IAP命令誤觸發(fā)
-
- ISP_ADDRH = 0xff; //清0地址高字節(jié)
- ISP_ADDRL = 0xff; //清0地址低字節(jié),指向非EEPROM區(qū),防止誤操作
- }
- //========================================================================
- // 函數(shù): void EEPROM_read_n(u16 EE_address,u8 *DataAddress,u16 number)
- // 描述: 從指定EEPROM首地址讀出n個(gè)字節(jié)放指定的緩沖.
- // 參數(shù): EE_address: 讀出EEPROM的首地址.
- // DataAddress: 讀出數(shù)據(jù)放緩沖的首地址.
- // number: 讀出的字節(jié)長(zhǎng)度.
- // 返回: non.
- // 版本: V1.0, 2022-05-28
- //========================================================================
- void EEPROM_read_n(u16 EE_address,u8 *DataAddress,u16 number)
- {
- ISP_CONTR = (ISP_EN + ISP_WAIT_FREQUENCY); //設(shè)置等待時(shí)間,允許ISP/IAP操作,送一次就夠
- ISP_READ(); //送字節(jié)讀命令,命令不需改變時(shí),不需重新送命令
-
- do
- {
- ISP_ADDRH = EE_address / 256; //送地址高字節(jié)(地址需要改變時(shí)才需重新送地址)
- ISP_ADDRL = EE_address % 256; //送地址低字節(jié)
- _ISP_TRIG(); //先送5AH,再送A5H到ISP/IAP觸發(fā)寄存器,每次都需要如此
- //送完A5H后,ISP/IAP命令立即被觸發(fā)啟動(dòng)
- //CPU等待IAP完成后,才會(huì)繼續(xù)執(zhí)行程序。
- _nop_();
-
- *DataAddress = ISP_DATA; //讀出的數(shù)據(jù)送往
-
- EE_address++;
- DataAddress++;
- }while(--number);
-
-
- DisableEEPROM();
- }
- /******************** 扇區(qū)擦除函數(shù) *****************/
- //========================================================================
- // 函數(shù): void EEPROM_SectorErase(u16 EE_address)
- // 描述: 把指定地址的EEPROM扇區(qū)擦除.
- // 參數(shù): EE_address: 要擦除的扇區(qū)EEPROM的地址.
- // 返回: non.
- // 版本: V1.0, 2022-05-28
- //========================================================================
- void EEPROM_SectorErase(u16 EE_address)
- {
- //只有扇區(qū)擦除,沒(méi)有字節(jié)擦除,512字節(jié)/扇區(qū)。
- //扇區(qū)中任意一個(gè)字節(jié)地址都是扇區(qū)地址。
- ISP_ADDRH = EE_address / 256; //送扇區(qū)地址高字節(jié)(地址需要改變時(shí)才需重新送地址)
- ISP_ADDRL = EE_address % 256; //送扇區(qū)地址低字節(jié)
-
- ISP_CONTR = (ISP_EN + ISP_WAIT_FREQUENCY); //設(shè)置等待時(shí)間,允許ISP/IAP操作,送一次就夠
-
- ISP_ERASE(); //送扇區(qū)擦除命令,命令不需改變時(shí),不需重新送命令
-
- _ISP_TRIG(); //先送5AH,再送A5H到ISP/IAP觸發(fā)寄存器,每次都需要如此
- //送完A5H后,ISP/IAP命令立即被觸發(fā)啟動(dòng)
-
- _nop_();
-
- DisableEEPROM();
- }
- //========================================================================
- // 函數(shù): void EEPROM_write_n(u16 EE_address,u8 *DataAddress,u16 number)
- // 描述: 把緩沖的n個(gè)字節(jié)寫(xiě)入指定首地址的EEPROM.
- // 參數(shù): EE_address: 寫(xiě)入EEPROM的首地址.
- // DataAddress: 寫(xiě)入源數(shù)據(jù)的緩沖的首地址.
- // number: 寫(xiě)入的字節(jié)長(zhǎng)度.
- // 返回: non.
- // 版本: V1.0, 2022-05-28
- //========================================================================
- void EEPROM_write_n(u16 EE_address,u8 *DataAddress,u16 number)
- {
- ISP_CONTR = (ISP_EN + ISP_WAIT_FREQUENCY); //設(shè)置等待時(shí)間,允許ISP/IAP操作,送一次就夠
-
- ISP_WRITE(); //送字節(jié)寫(xiě)命令,命令不需改變時(shí),不需重新送命令
-
- do
- {
- ISP_ADDRH = EE_address / 256; //送地址高字節(jié)(地址需要改變時(shí)才需重新送地址)
- ISP_ADDRL = EE_address % 256; //送地址低字節(jié)
-
- ISP_DATA = *DataAddress; //送數(shù)據(jù)到ISP_DATA,只有數(shù)據(jù)改變時(shí)才需重新送
-
- _ISP_TRIG(); //先送5AH,再送A5H到ISP/IAP觸發(fā)寄存器,每次都需要如此
- //送完A5H后,ISP/IAP命令立即被觸發(fā)啟動(dòng)
-
- _nop_();
-
- EE_address++;
- DataAddress++;
- }while(--number);
- DisableEEPROM();
- }
復(fù)制代碼
STC芯片的IAP版本:IAP15F2K61S2
使用官方IAP示例代碼測(cè)試,如代碼所示:
IAP15F2K61S2據(jù)說(shuō)整片F(xiàn)lash都可以模擬EEPROM,地址:0x0000-0xF3FF(測(cè)試時(shí)需要避開(kāi)程序空間,測(cè)試讀寫(xiě)地址:0xF200)使用官方IAP示例代碼測(cè)試
測(cè)試:部分代碼
unsigned char EPR1[20]={0x20,0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
寫(xiě):
EEPROM_SectorErase(0xF200); //擦除一個(gè)扇區(qū)
EEPROM_write_n(0xF200,EPR1,sizeof(EPR1)); //寫(xiě)
讀:
EEPROM_read_n(0xF200,EPR1,sizeof(EPR1)); //讀出n字節(jié),存放在EPR1數(shù)組內(nèi)
uartWrite(EPR1,sizeof(EPR1));//串口發(fā)送
測(cè)試結(jié)果如圖:
問(wèn)題:
1,代碼是使用IAP讀寫(xiě)官方Demo修改,有沒(méi)有問(wèn)題?
2,正常讀出來(lái)的數(shù)據(jù)為0x20,0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,但是芯片運(yùn)行一段時(shí)間后,F(xiàn)lash好像無(wú)法通過(guò)IAP程序再次讀寫(xiě)了,即讀出來(lái)都是0x00,目測(cè)壞了,更換新的同型號(hào)芯片又沒(méi)有問(wèn)題了(代碼均一致,只是換了新的芯片),但是或者有什么辦法修復(fù)一下?還是代碼哪里可以優(yōu)化一下?又感覺(jué)沒(méi)壞,因?yàn)槌绦蜻在正常運(yùn)行,只是沒(méi)辦法通過(guò)IAP讀寫(xiě)Flash,來(lái)模擬EEPROM了
PS:正常與非正常的芯片,代碼運(yùn)行均正常(因?yàn)榇诎l(fā)送0x15是用來(lái)測(cè)試IC的,由此得出芯片其實(shí)除了IAP,其他正常),讀寫(xiě)次數(shù)最多也沒(méi)超過(guò)100次,地址均為0xF200,且沒(méi)有與程序區(qū)沖突,就壞了
沒(méi)有遇到過(guò)類似無(wú)法IAP讀寫(xiě)的問(wèn)題,分享一下!
|
-
1正常.png
(15.48 KB, 下載次數(shù): 37)
下載附件
2022-10-5 11:33 上傳
-
2非正常.png
(10.77 KB, 下載次數(shù): 42)
下載附件
2022-10-5 11:33 上傳
|