標題:
STC單片機的EEPROM問題
[打印本頁]
作者:
danq
時間:
2022-10-5 11:44
標題:
STC單片機的EEPROM問題
.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個字節(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è)置等待時間,允許ISP/IAP操作,送一次就夠
ISP_READ(); //送字節(jié)讀命令,命令不需改變時,不需重新送命令
do
{
ISP_ADDRH = EE_address / 256; //送地址高字節(jié)(地址需要改變時才需重新送地址)
ISP_ADDRL = EE_address % 256; //送地址低字節(jié)
_ISP_TRIG(); //先送5AH,再送A5H到ISP/IAP觸發(fā)寄存器,每次都需要如此
//送完A5H后,ISP/IAP命令立即被觸發(fā)啟動
//CPU等待IAP完成后,才會繼續(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ū)中任意一個字節(jié)地址都是扇區(qū)地址。
ISP_ADDRH = EE_address / 256; //送扇區(qū)地址高字節(jié)(地址需要改變時才需重新送地址)
ISP_ADDRL = EE_address % 256; //送扇區(qū)地址低字節(jié)
ISP_CONTR = (ISP_EN + ISP_WAIT_FREQUENCY); //設(shè)置等待時間,允許ISP/IAP操作,送一次就夠
ISP_ERASE(); //送扇區(qū)擦除命令,命令不需改變時,不需重新送命令
_ISP_TRIG(); //先送5AH,再送A5H到ISP/IAP觸發(fā)寄存器,每次都需要如此
//送完A5H后,ISP/IAP命令立即被觸發(fā)啟動
_nop_();
DisableEEPROM();
}
//========================================================================
// 函數(shù): void EEPROM_write_n(u16 EE_address,u8 *DataAddress,u16 number)
// 描述: 把緩沖的n個字節(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è)置等待時間,允許ISP/IAP操作,送一次就夠
ISP_WRITE(); //送字節(jié)寫命令,命令不需改變時,不需重新送命令
do
{
ISP_ADDRH = EE_address / 256; //送地址高字節(jié)(地址需要改變時才需重新送地址)
ISP_ADDRL = EE_address % 256; //送地址低字節(jié)
ISP_DATA = *DataAddress; //送數(shù)據(jù)到ISP_DATA,只有數(shù)據(jù)改變時才需重新送
_ISP_TRIG(); //先送5AH,再送A5H到ISP/IAP觸發(fā)寄存器,每次都需要如此
//送完A5H后,ISP/IAP命令立即被觸發(fā)啟動
_nop_();
EE_address++;
DataAddress++;
}while(--number);
DisableEEPROM();
}
復制代碼
STC芯片的IAP版本:IAP15F2K61S2
使用官方IAP示例代碼測試,如代碼所示:
IAP15F2K61S2據(jù)說整片F(xiàn)lash都可以模擬EEPROM,地址:0x0000-0xF3FF(測試時需要避開程序空間,測試讀寫地址:0xF200)使用官方IAP示例代碼測試
測試:部分代碼
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); //擦除一個扇區(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ā)送
測試結(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,但是芯片運行一段時間后,F(xiàn)lash好像無法通過IAP程序再次讀寫了,即讀出來都是0x00,目測壞了,更換新的同型號芯片又沒有問題了(代碼均一致,只是換了新的芯片),但是或者有什么辦法修復一下?還是代碼哪里可以優(yōu)化一下?又感覺沒壞,因為程序還在正常運行,只是沒辦法通過IAP讀寫Flash,來模擬EEPROM了
PS:正常與非正常的芯片,代碼運行均正常(因為串口發(fā)送0x15是用來測試IC的,由此得出芯片其實除了IAP,其他正常),讀寫次數(shù)最多也沒超過100次,地址均為0xF200,且沒有與程序區(qū)沖突,就壞了
沒有遇到過類似無法IAP讀寫的問題,分享一下!
1正常.png
(15.48 KB, 下載次數(shù): 37)
下載附件
2022-10-5 11:33 上傳
2非正常.png
(10.77 KB, 下載次數(shù): 42)
下載附件
2022-10-5 11:33 上傳
作者:
624353765
時間:
2022-10-5 15:47
http://www.torrancerestoration.com/bbs/dpj-223265-1.html
用這軟件生成通用型EEPROM函數(shù),簡單明了
作者:
wulin
時間:
2022-10-5 16:56
所有端口初始化為準雙向口試試,以前用IAP15F4K58S4吃過苦頭。
P0M0 = 0x00;
P0M1 = 0x00;
P1M0 = 0x00;
P1M1 = 0x00;
P2M0 = 0x00;
P2M1 = 0x00;
P3M0 = 0x00;
P3M1 = 0x00;
P4M0 = 0x00;
P4M1 = 0x00;
P5M0 = 0x00;
P5M1 = 0x00;
P6M0 = 0x00;
P6M1 = 0x00;
P7M0 = 0x00;
P7M1 = 0x00;
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1