各位大佬先且看我的代码和log打印
#define CMD_IDLE 0 //空闲模式
#define CMD_READ 1 //IAP字节读命令
#define CMD_PROGRAM 2 //IAP字节编程命令
#define CMD_ERASE 3 //IAP扇区擦除命令
#define ENABLE_IAP 0x80 //if SYSCLK<30MHz
#define IAP_TPS_CONSTANT ((FOSC/1000000)+1)
static const unsigned long iapTps = IAP_TPS_CONSTANT;
//********************关闭IAP*******************************ok
static void IapIdle()
{
IAP_CONTR = 0; //关闭IAP功能
IAP_CMD = 0; //清除命令寄存器
IAP_TRIG = 0; //清除触发寄存器
IAP_ADDRH = 0x80; //将地址设置到非IAP区域
IAP_ADDRL = 0;
}
//************************从ISP/IAP/EEPROM区域读取一字节****************************ok
static BYTE IapReadByte(WORD addr)
{
BYTE dat; //数据缓冲区
IAP_CONTR = ENABLE_IAP; //使能IAP
IAP_TPS = iapTps; //设置等待参数 ********************************************STC8C2K64S2
IAP_CMD = CMD_READ; //设置IAP命令
IAP_ADDRL = addr; //设置IAP低地址
IAP_ADDRH = addr >> 8; //设置IAP高地址
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_nop_(); //等待ISP/IAP/EEPROM操作完成
dat = IAP_DATA; //读ISP/IAP/EEPROM数据
IapIdle(); //关闭IAP功能
return dat; //返回
}
//*********写一字节数据到ISP/IAP/EEPROM区域*************************************ok
static BYTE IapProgramByte(WORD addr, BYTE dat)
{
IAP_CONTR = ENABLE_IAP; //使能IAP
IAP_TPS = iapTps; //设置等待参数 ********************************************STC8C2K64S2
IAP_CMD = CMD_PROGRAM; //设置IAP命令
IAP_ADDRL = addr; //设置IAP低地址
IAP_ADDRH = addr >> 8; //设置IAP高地址
IAP_DATA = dat; //写ISP/IAP/EEPROM数据
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_nop_(); //等待ISP/IAP/EEPROM操作完成
IapIdle(); //关闭IAP功能
return FIND_BIT(IAP_CONTR, 4);
}
//**************************************扇区擦除************************************ok
static BYTE IapEraseSector(WORD addr)
{
IAP_CONTR = ENABLE_IAP; //使能IAP
IAP_CMD = CMD_ERASE; //设置IAP命令
IAP_ADDRL = addr; //设置IAP低地址
IAP_ADDRH = addr >> 8; //设置IAP高地址
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_nop_(); //等待ISP/IAP/EEPROM操作完成
IapIdle(); //关闭IAP功能
return FIND_BIT(IAP_CONTR, 4);
}
BYTE* eepRom_Read_DevAddr(void)
{
unsigned char cnt;
const unsigned char DevIdLen = EEPROM_DEVID_END_ADDR - EEPROM_DEVID_START_ADDR;
memset(eepRomBuffer, 0, sizeof(eepRomBuffer));
for ( cnt = 0; cnt < DevIdLen; cnt++ )
eepRomBuffer[cnt] = IapReadByte(EEPROM_DEVID_START_ADDR + cnt);
return eepRomBuffer;
}
int eepRom_Save_DeviceAddress(const char* DevId)
{
unsigned char cnt = 0;
BYTE Flag_QRcodeShow = 0;
const int DevIdLen = EEPROM_DEVID_END_ADDR - EEPROM_DEVID_START_ADDR;
if ( *(DevId + DevIdLen) != '\0' || DevId == NULL )
return EEPROM_ERR_ARG; // 没有结束符或参数为NULL
Flag_QRcodeShow = IapReadByte((WORD)EEPROM_QRCODE_FLAG_ADDR);
DebugPrint(TAG, "frist, save QRcode flag: %bu", Flag_QRcodeShow);
if ( IapEraseSector(IAP_ADDRESS2) )
goto _EEPROM_ERR;
DebugPrint(TAG, "erase successes... will write data: %s", DevId);
for ( cnt = 0; cnt < DevIdLen; cnt++ )
{
if ( IapProgramByte((WORD)(IAP_ADDRESS2 + cnt), (BYTE)(*(DevId + cnt))) )
{
DebugPrint(TAG, "write eepRom error");
goto _EEPROM_ERR;
}
}
IapProgramByte((WORD)EEPROM_QRCODE_FLAG_ADDR, Flag_QRcodeShow);
DebugPrint(TAG, "save data..");
DebugPrint(TAG, "write data: %s", eepRom_Read_DevAddr());
return (strcmp(DevId, eepRomBuffer) == 0) ? EEPROM_OK : EEPROM_FAIL;
_EEPROM_ERR:
CLEAR_BIT(IAP_CONTR, 4); // 清除IAP错误
return (int)IapEraseSector(IAP_ADDRESS2);
}
正是这么一段代码,但打印出了以下log
----bufAddr status (ok), len 108 from UART2:
id.a001...a001
----send to UART1
bufAddr:x:0689, bufferLen:0
[protocol]:funcString: id
[protocol]:into command 'ID'
[protocol]:print DevID
[eepRom]:frist, save QRcode flag: 0
[eepRom]:erase successes... will write data: a001
[eepRom]:save data..
[eepRom]:write data:
[protocol]:save DevId status: fail
我一开始以为是没接收到数据,但并不是接收不到数据。我怀疑是数据根本就没有写入,但为什么会出现这种情况呢?若写入有报错了,我的代码应当返回错误值而不是继续写。还有,根据手册上的描述, IAP_TPS
是一个等待时间控制寄存器,故此 _nop_()
函数是必要的吗?能否用自定义的定时器延时函数替代?