求助:IAP15W4K58s读写EEPROM失效
大神们,我用STC15库函数写IAP15W4K58s的EEPROM,好像写不进去.请各位大神帮我看下.另外库函数STC15FXXXX.H里的#define ISP_TRIG() ISP_TRIG = 0x5A, ISP_TRIG = 0xA5 其中的逗号是不是应该为分号?
//========================================================================
void ReadParaFromEprom(void)
{
EEPROM_read_n(EPROMSetParatAdd,EpromRecordData,SizeOfRecord);
SetParaStructure.Unit=(((EpromRecordData>=Unit_gf)&&(EpromRecordData<=Unit_N ))?EpromRecordData:SetParaInit.Unit);
SetParaStructure.WireFactor=(((EpromRecordData>=0)&&(EpromRecordData<=20 ))?EpromRecordData:SetParaInit.WireFactor);
SetParaStructure.CloseTime=(((((u16)EpromRecordData<<8|(u16)EpromRecordData)>=0)&&(((u16)EpromRecordData<<8|(u16)EpromRecordData)<=3600))?((u16)EpromRecordData<<8|(u16)EpromRecordData):SetParaInit.CloseTime);
SetParaStructure.Sensitive=(((((u16)EpromRecordData<<8|(u16)EpromRecordData)>=100)&&(((u16)EpromRecordData<<8|(u16)EpromRecordData)<=2000))?((u16)EpromRecordData<<8|(u16)EpromRecordData):SetParaInit.Sensitive);
SetParaStructure.FlashSpeed=(((((u16)EpromRecordData<<8|(u16)EpromRecordData)>=500)&&(((u16)EpromRecordData<<8|(u16)EpromRecordData)<=5000))?((u16)EpromRecordData<<8|(u16)EpromRecordData):SetParaInit.FlashSpeed);
SetParaStructure.LastSaveNum=(((((u16)EpromRecordData<<8|(u16)EpromRecordData)>=0)&&(((u16)EpromRecordData<<8|(u16)EpromRecordData)<=127))?((u16)EpromRecordData<<8|(u16)EpromRecordData):SetParaInit.LastSaveNum);
}
//========================================================================
void WritePara2Eprom(void)
{
EEPROM_read_n(EPROMStartAdd ,EpromSectionData,SizeOfSection);
EEPROM_SectorErase(EPROMStartAdd);
EpromSectionData=SetParaStructure.Unit;
EpromSectionData=SetParaStructure.WireFactor;
EpromSectionData=SetParaStructure.CloseTime>>8;
EpromSectionData=SetParaStructure.CloseTime;
EpromSectionData=SetParaStructure.Sensitive>>8;
EpromSectionData=SetParaStructure.Sensitive;
EpromSectionData=SetParaStructure.FlashSpeed>>8;
EpromSectionData=SetParaStructure.FlashSpeed;
EpromSectionData=SetParaStructure.LastSaveNum>>8;
EpromSectionData=SetParaStructure.LastSaveNum;
EEPROM_write_n(EPROMStartAdd,EpromSectionData,SizeOfSection);
}
相关的库函数如下:
//========================================================================
void EEPROM_write_n(u16 EE_address,u8 *DataAddress,u16 number)
{
EA = 0; //½ûÖ¹ÖжÏ
ISP_CONTR = (ISP_EN + ISP_WAIT_FREQUENCY); //ÉèÖõȴýʱ¼ä£¬ÔÊÐíISP/IAP²Ù×÷£¬ËÍÒ»´Î¾Í¹»
ISP_WRITE(); //ËÍ×Ö½ÚдÃüÁÃüÁî²»Ðè¸Ä±äʱ£¬²»ÐèÖØÐÂËÍÃüÁî
do
{
ISP_ADDRH = EE_address / 256; //Ë͵ØÖ·¸ß×Ö½Ú£¨µØÖ·ÐèÒª¸Ä±äʱ²ÅÐèÖØÐÂË͵ØÖ·£©
ISP_ADDRL = EE_address % 256; //Ë͵ØÖ·µÍ×Ö½Ú
ISP_DATA= *DataAddress; //ËÍÊý¾Ýµ½ISP_DATA£¬Ö»ÓÐÊý¾Ý¸Ä±äʱ²ÅÐèÖØÐÂËÍ
//ISP_TRIG();
ISP_TRIG = 0x5A;
ISP_TRIG = 0xA5;
_nop_();
_nop_();
_nop_();
_nop_();
EE_address++;
DataAddress++;
}while(--number);
DisableEEPROM();
EA = 1; //ÖØÐÂÔÊÐíÖжÏ
}
//========================================================================
void EEPROM_SectorErase(u16 EE_address)
{
EA = 0; //½ûÖ¹ÖжÏ
//Ö»ÓÐÉÈÇø²Á³ý£¬Ã»ÓÐ×Ö½Ú²Á³ý£¬512×Ö½Ú/ÉÈÇø¡£
//ÉÈÇøÖÐÈÎÒâÒ»¸ö×Ö½ÚµØÖ·¶¼ÊÇÉÈÇøµØÖ·¡£
ISP_ADDRH = EE_address / 256; //ËÍÉÈÇøµØÖ·¸ß×Ö½Ú£¨µØÖ·ÐèÒª¸Ä±äʱ²ÅÐèÖØÐÂË͵ØÖ·£©
ISP_ADDRL = EE_address % 256; //ËÍÉÈÇøµØÖ·µÍ×Ö½Ú
ISP_CONTR = (ISP_EN + ISP_WAIT_FREQUENCY); //ÉèÖõȴýʱ¼ä£¬ÔÊÐíISP/IAP²Ù×÷£¬ËÍÒ»´Î¾Í¹»
ISP_ERASE(); //ËÍÉÈÇø²Á³ýÃüÁÃüÁî²»Ðè¸Ä±äʱ£¬²»ÐèÖØÐÂËÍÃüÁî
//ISP_TRIG();
ISP_TRIG = 0x5A;
ISP_TRIG = 0xA5;
_nop_();
_nop_();
_nop_();
_nop_();
DisableEEPROM();
EA = 1; //ÖØÐÂÔÊÐíÖжÏ
}
//========================================================================
void EEPROM_read_n(u16 EE_address,u8 *DataAddress,u16 number)
{
EA = 0; //½ûÖ¹ÖжÏ
ISP_CONTR = (ISP_EN + ISP_WAIT_FREQUENCY); //ÉèÖõȴýʱ¼ä£¬ÔÊÐíISP/IAP²Ù×÷£¬ËÍÒ»´Î¾Í¹»
ISP_READ(); //ËÍ×Ö½Ú¶ÁÃüÁÃüÁî²»Ðè¸Ä±äʱ£¬²»ÐèÖØÐÂËÍÃüÁî
do
{
ISP_ADDRH = EE_address / 256; //Ë͵ØÖ·¸ß×Ö½Ú£¨µØÖ·ÐèÒª¸Ä±äʱ²ÅÐèÖØÐÂË͵ØÖ·£©
ISP_ADDRL = EE_address % 256; //Ë͵ØÖ·µÍ×Ö½Ú
// ISP_TRIG(); //ÏÈËÍ5AH£¬ÔÙËÍA5Hµ½ISP/IAP´¥·¢¼Ä´æÆ÷£¬Ã¿´Î¶¼ÐèÒªÈç´Ë
// //ËÍÍêA5Hºó£¬ISP/IAPÃüÁîÁ¢¼´±»´¥·¢Æô¶¯
// //CPUµÈ´ýIAPÍê³Éºó£¬²Å»á¼ÌÐøÖ´ÐгÌÐò¡£
ISP_TRIG = 0x5A;
ISP_TRIG = 0xA5;
_nop_();
_nop_();
_nop_();
_nop_();
*DataAddress = ISP_DATA; //¶Á³öµÄÊý¾ÝËÍÍù
EE_address++;
DataAddress++;
}while(--number);
DisableEEPROM();
EA = 1; //ÖØÐÂÔÊÐíÖжÏ
}
//========================================================================
void DisableEEPROM(void)
{
ISP_CONTR = 0; //½ûÖ¹ISP/IAP²Ù×÷
ISP_CMD = 0; //È¥³ýISP/IAPÃüÁî
ISP_TRIG= 0; //·ÀÖ¹ISP/IAPÃüÁîÎó´¥·¢
ISP_ADDRH = 0xff; //Çå0µØÖ·¸ß×Ö½Ú
ISP_ADDRL = 0xff; //Çå0µØÖ·µÍ×Ö½Ú£¬Ö¸Ïò·ÇEEPROMÇø£¬·ÀÖ¹Îó²Ù×÷
}
EEPRO读写地址如下:
#define EPROMStartAdd 0xE000
#define EPROMSetParatAdd 0xE000
#define SizeOfSection 512
#define SizeOfRecord 16 您好,您回复的:
1.需确认EPROMSetParatAdd是有效的EEPROM地址(通常为0x0000~0x07FF),且SizeOfRecord不超过单次写入限制(一般为16字节)。IAP15W4K58S有效的EEPROM地址应该为:0x0000~0xE7FF吧.另外单次写入限制为什么只有16个字节?
2.建议使用轮询方式等待ISPFLAG标志位:IAP15W4K58S有ISPFLAG标志位吗?
EEPROM程序供参考:
void Iap_Idle(void)
{
IAP_CONTR&=~IAPEN;
IAP_CMD=IAP_IDL;
IAP_TRIG=0x00;
IAP_ADDRH=0x80;
IAP_ADDRL=0x00;
}
//unsigned char Iap_Read_Byte(unsigned char sector,unsigned int addr)
{
unsigned char dat;
unsigned int add;
add=sector*0x0200+addr;
IAP_CONTR|=IAPEN;
IAP_TPS=IAP_TPS_;
IAP_CMD=IAP_READ;
IAP_ADDRL=add;
IAP_ADDRH=add>>8;
IAP_TRIG=0x5A;
IAP_TRIG=0xA5;
_nop_();
dat=IAP_DATA;
Iap_Idle();
return dat;
}
void Iap_Program_Byte(unsigned char sector,unsigned int addr,unsigned char dat)
{
unsigned int add;
add=sector*0x0200+addr;
IAP_CONTR|=IAPEN;
IAP_TPS=IAP_TPS_;
IAP_CMD=IAP_WRITE;
IAP_ADDRL=add;
IAP_ADDRH=add>>8;
IAP_DATA=dat;
IAP_TRIG=0x5A;
IAP_TRIG=0xA5;
_nop_();
Iap_Idle();
}
void Iap_Erase_Sector(unsigned char sector)
{
unsigned int add;
add=sector*0x0200;
IAP_CONTR|=IAPEN;
IAP_TPS=IAP_TPS_;
IAP_CMD=IAP_ERASE;
IAP_ADDRL=add;
IAP_ADDRH=add>>8;
IAP_TRIG=0x5A;
IAP_TRIG=0xA5;
_nop_();
Iap_Idle();
}
应该是分号
IAP_TRIG=0x5A;
IAP_TRIG=0xA5; sindge 发表于 2025-7-18 16:19
EEPRO读写地址如下:
#define EPROMStartAdd 0xE000
#define EPROMSetParatAdd 0xE00 ...
总大小0xE800,0xE000也没有超出范围,使用的是倒数第4个扇区,地址没有问题 测试时发现,仿真时读EEPROM可以,但是写EEPROM时序好像就乱了
页:
[1]