|
- .C
- #include "eeprom.h"
- #include "STC15Fxxxx.H"
- //========================================================================
- // 函數(shù): void ISP_Disable(void)
- // 描述: 禁止訪問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é)長度.
- // 返回: 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ū)擦除,沒有字節(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é)寫入指定首地址的EEPROM.
- // 參數(shù): EE_address: 寫入EEPROM的首地址.
- // DataAddress: 寫入源數(shù)據(jù)的緩沖的首地址.
- // number: 寫入的字節(jié)長度.
- // 返回: 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é)寫命令,命令不需改變時(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ù)說整片F(xiàn)lash都可以模擬EEPROM,地址:0x0000-0xF3FF(測(cè)試時(shí)需要避開程序空間,測(cè)試讀寫地址: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};
寫:
EEPROM_SectorErase(0xF200); //擦除一個(gè)扇區(qū)
EEPROM_write_n(0xF200,EPR1,sizeof(EPR1)); //寫
讀:
EEPROM_read_n(0xF200,EPR1,sizeof(EPR1)); //讀出n字節(jié),存放在EPR1數(shù)組內(nèi)
uartWrite(EPR1,sizeof(EPR1));//串口發(fā)送
測(cè)試結(jié)果如圖:
問題:
1,代碼是使用IAP讀寫官方Demo修改,有沒有問題?
2,正常讀出來的數(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好像無法通過IAP程序再次讀寫了,即讀出來都是0x00,目測(cè)壞了,更換新的同型號(hào)芯片又沒有問題了(代碼均一致,只是換了新的芯片),但是或者有什么辦法修復(fù)一下?還是代碼哪里可以優(yōu)化一下?又感覺沒壞,因?yàn)槌绦蜻在正常運(yùn)行,只是沒辦法通過IAP讀寫Flash,來模擬EEPROM了
PS:正常與非正常的芯片,代碼運(yùn)行均正常(因?yàn)榇诎l(fā)送0x15是用來測(cè)試IC的,由此得出芯片其實(shí)除了IAP,其他正常),讀寫次數(shù)最多也沒超過100次,地址均為0xF200,且沒有與程序區(qū)沖突,就壞了
沒有遇到過類似無法IAP讀寫的問題,分享一下!
|
-
-
|