玄学的eeprom保存
<p>我写了个数据保存函数,用以保存ASCⅡ码,读与写却是不匹配。。。以下是我的代码</p><pre><code class="language-c">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 = 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);
//***********写入eeprom************
if ( IapEraseSector(IAP_ADDRESS2) )
goto _EEPROM_ERR;
DebugPrint(TAG, "erase successes... will write data: %s", DevId);
Delay_100ms();
for ( cnt = 0; cnt < DevIdLen; cnt++ )
{
if ( IapProgramByte((EEPROM_DEVID_START_ADDR + cnt), (*(DevId + cnt))) )
{
DebugPrint(TAG, "write eepRom error");
goto _EEPROM_ERR;
}
Delay_10ms();
DebugPrint(TAG, "write byte: %bu, read: %bu", *(DevId + cnt), IapReadByte(EEPROM_DEVID_START_ADDR + cnt));
}
IapProgramByte((WORD)EEPROM_QRCODE_FLAG_ADDR, Flag_QRcodeShow);//保存地址二维码显示否
DebugPrint(TAG, "devId writting successes...");
return (strcmp(DevId, eepRom_Read_DevAddr()) == 0) ? EEPROM_OK : EEPROM_FAIL;
_EEPROM_ERR:
CLEAR_BIT(IAP_CONTR, 4); // 清除IAP错误
return (int)IapEraseSector(IAP_ADDRESS2);
}
</code></pre>
<p>代码中,eeprom的读写是这样实现的( Soc设置的频率为33.1776MHz )</p>
<pre><code class="language-c">//********************关闭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);
}
</code></pre>
<p>按照正常来说,我那保存字符串到eeprom的函数应该是正常生效的。但实际上却出错了,打印了以下的log</p>
<pre><code class="language-text">:frist, save QRcode flag: 255
:erase successes... will write data: BCDE
:write byte: 66, read: 0
:write byte: 67, read: 1
:write byte: 68, read: 0
:write byte: 69, read: 65
:devId writting successes...
:save DevId status: fail
</code></pre>
<p>而我的另一个同样也是保存数据到eeprom的函数,读与写对比却是没有问题的</p>
<pre><code class="language-c">BYTE* eepRom_Read_Name(const int index)
{
BYTE MaxCnt = 0, cnt = 0;
memset(eepRomBuffer, 0, sizeof(eepRomBuffer));
switch ( index )
{
case 1:
{
MaxCnt = IapReadByte(EEPROM_NAME1_CNT_ADDR);
for ( cnt = 0; cnt < MaxCnt; cnt++ )
{
eepRomBuffer = IapReadByte(EEPROM_NAME1STR_ADDR + cnt);
}
}break;
case 2:
{
MaxCnt = IapReadByte(EEPROM_NAME2_CNT_ADDR);
for ( cnt = 0; cnt < MaxCnt; cnt++ )
{
eepRomBuffer = IapReadByte(EEPROM_NAME2STR_ADDR + cnt);
}
}break;
case 3:
{
MaxCnt = IapReadByte(EEPROM_NAME3_CNT_ADDR);
for ( cnt = 0; cnt < MaxCnt; cnt++ )
{
eepRomBuffer = IapReadByte(EEPROM_NAME3STR_ADDR + cnt);
}
}break;
case 4:
{
MaxCnt = IapReadByte(EEPROM_NAME4_CNT_ADDR);
for ( cnt = 0; cnt < MaxCnt; cnt++ )
{
eepRomBuffer = IapReadByte(EEPROM_NAME4STR_ADDR + cnt);
}
}break;
default:
DebugPrint(TAG, "ReadName index fail");
return NULL;
}
return eepRomBuffer;
}
BYTE eepRom_Read_NameLen(const int index)
{
BYTE len = 0;
switch ( index )
{
case 1:
len = IapReadByte(EEPROM_NAME1_CNT_ADDR);
break;
case 2:
len = IapReadByte(EEPROM_NAME2_CNT_ADDR);
break;
case 3:
len = IapReadByte(EEPROM_NAME3_CNT_ADDR);
break;
case 4:
len = IapReadByte(EEPROM_NAME4_CNT_ADDR);
break;
default:
DebugPrint(TAG, "ReadNameLen index fail");
break;
}
return len;
}
int eepRom_Save_Name(const char* Name, const unsigned int len, const unsigned int index)
{
unsigned int cnt = 0;
const unsigned int MaxCnt = EEPROM_NAME_END_ADDR - EEPROM_NAME_START_ADDR;
const unsigned char DataHead = EEPROM_NAME1STR_ADDR - EEPROM_NAME_START_ADDR;
//BYTE tmpSave = {0};
if ( Name == NULL || len == 0 )
return EEPROM_ERR_ARG;
memset(eepRomBuffer, 0, sizeof(eepRomBuffer));
// 先读出数据
for ( cnt = 0; cnt < MaxCnt; cnt++ )
{
eepRomBuffer = IapReadByte(EEPROM_NAME_START_ADDR);
}
switch ( index )
{
case 1:
{
eepRomBuffer = len;
memcpy(eepRomBuffer + DataHead, Name, len);
}break;
case 2:
{
eepRomBuffer = len;
memcpy(eepRomBuffer + DataHead + (EEPROM_NAME_MAX_LEN * 1), Name, len);
}break;
case 3:
{
eepRomBuffer = len;
memcpy(eepRomBuffer + DataHead + (EEPROM_NAME_MAX_LEN * 2), Name, len);
}break;
case 4:
{
eepRomBuffer = len;
memcpy(eepRomBuffer + DataHead + (EEPROM_NAME_MAX_LEN * 3), Name, len);
}break;
default:
DebugPrint(TAG, "SaveName index fail");
return EEPROM_ERR_ARG;
}
if ( IapEraseSector(EEPROM_NAME_START_ADDR) )
goto _EEPROM_ERROR;
for ( cnt = 0; cnt < MaxCnt; cnt++ )
{
if ( IapProgramByte(EEPROM_NAME_START_ADDR + cnt, eepRomBuffer) )
goto _EEPROM_ERROR;
}
DebugPrint(TAG, "SaveName successes");
return (memcmp(eepRom_Read_Name(index), Name, len) == 0) ? EEPROM_OK : EEPROM_FAIL;
_EEPROM_ERROR:
DebugPrint(TAG, "erase or write error");
return IapEraseSector(EEPROM_NAME_START_ADDR);
}
</code></pre>
<pre><code class="language-text">:SaveName successes
:1-Save name status: ok
:Show string
:parse fail
:2-Display GB2312 status: FAIL, cnt: 0
:parse fail
:2-Display GB2312 status: FAIL, cnt: 0
:parse status: ok
:recv data ok
</code></pre>
<p>这么看起来,两个函数的保存与读取其实并没有什么区别。但函数 <code>eepRom_Save_DeviceAddress()</code>就是返回了错误值。希望大佬能指导我该如何分析🙏🙏🙏</p>
根据您的描述,EEPROM读写的ASCII码数据不匹配,可能涉及以下几个问题:首先,检查EEPROM的起始地址和结束地址是否正确,确保读写范围一致。其次,确认`eepRomBuffer`的大小是否足够存储读取的数据,避免溢出或截断。此外,EEPROM的读写时序和延迟可能影响数据一致性,建议在读写操作后增加适当的延时或检查EEPROM的状态寄存器。最后,确保硬件连接稳定,避免因信号干扰导致数据错误。建议逐步调试,验证每个环节的正确性,以定位问题根源。
[本文内容由国芯人工智能辅助生成,仅供参考] 在您的代码中,可能存在以下问题导致EEPROM读取与写入的ASCII码不匹配:
1. **地址范围确认**:确保`EEPROM_DEVID_START_ADDR`和`EEPROM_DEVID_END_ADDR`定义正确,且不会超出EEPROM的物理地址范围。
2. **缓冲区大小**:`eepRomBuffer`的大小应至少为`DevIdLen`,以确保能存储所有读取的数据。
3. **读取函数实现**:确认EEPROM读取函数是否正确实现,每次读取一个字节并存入`eepRomBuffer`。
4. **写入函数检查**:检查写入函数是否正确将ASCII码写入EEPROM,确保写入的数据与预期一致。
5. **数据校验**:建议在写入后立即读取并进行校验,以确保数据一致性。
建议您逐步排查上述问题,必要时增加调试信息,以便定位具体原因。
[本文内容由国芯人工智能辅助生成,仅供参考] <p>我尝试上电就对eeprom进行写入,首次写入成功,但后面的写入都没有成功</p>
<pre><code class="language-text">:UART buffer memory reset
:frist, save QRcode flag: 255
:erase successes... will write data: 010A
:write byte: 48, read: 48
:write byte: 49, read: 49
:write byte: 48, read: 48
:write byte: 65, read: 65
:devId writting successes...
:save address ok
:frist, save QRcode flag: 255
:erase successes... will write data: 9999
:write byte: 57, read: 48
:write byte: 57, read: 49
:write byte: 57, read: 48
:write byte: 57, read: 1
:devId writting successes...
:save address fail
:frist, save QRcode flag: 255
:erase successes... will write data: 010A
:write byte: 48, read: 48
:write byte: 49, read: 49
:write byte: 48, read: 48
:write byte: 65, read: 1
:devId writting successes...
:save address fail
</code></pre>
<p>我在写入eeprom前也是有擦除的,但是写不进去寄存器也没有返回错误值</p>
操作EEPROM之前关闭中断试试
国芯人工智能 发表于 2025-3-3 11:23
在您的代码中,可能存在以下问题导致EEPROM读取与写入的ASCII码不匹配:
1. **地址范围确认**:确保`EEPRO ...
1234都正常,到了第5步的时候就有问题了。请分析 DebugLab 发表于 2025-3-3 11:46
操作EEPROM之前关闭中断试试
大意了,没关中断 王锦平 发表于 2025-3-3 11:52
大意了,没关中断
主程序和中断中都操作EEPROM才需要关中断避免重入问题 DebugLab 发表于 2025-3-3 11:46
操作EEPROM之前关闭中断试试
<h3>刚刚为IAP函数添加了中断</h3>
<pre><code class="language-c">//********************关闭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; //数据缓冲区
GLOBAL_INTERRUPT(DISABLE);
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功能
GLOBAL_INTERRUPT(ENABLE);
return dat; //返回
}
//*********写一字节数据到ISP/IAP/EEPROM区域*************************************ok
static BYTE IapProgramByte(WORD addr, BYTE dat)
{
GLOBAL_INTERRUPT(DISABLE);
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功能
GLOBAL_INTERRUPT(ENABLE);
return FIND_BIT(IAP_CONTR, 4);
}
//**************************************扇区擦除************************************ok
static BYTE IapEraseSector(WORD addr)
{
GLOBAL_INTERRUPT(DISABLE);
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功能
GLOBAL_INTERRUPT(ENABLE);
return FIND_BIT(IAP_CONTR, 4);
}
</code></pre>
<p>不过没有效果。。。</p>
<pre><code class="language-text">:UART buffer memory reset
:frist, save QRcode flag: 255
:erase successes... will write data: 010A
:write byte: 48, read: 48, addr: 0
:write byte: 49, read: 49, addr: 1
:write byte: 48, read: 48, addr: 2
:write byte: 65, read: 65, addr: 3
:devId writting successes...
:save address ok
:frist, save QRcode flag: 255
:erase successes... will write data: 9999
:write byte: 57, read: 48, addr: 0
:write byte: 57, read: 49, addr: 1
:write byte: 57, read: 48, addr: 2
:write byte: 57, read: 1, addr: 3
:devId writting successes...
:save address fail
:frist, save QRcode flag: 255
:erase successes... will write data: 010A
:write byte: 48, read: 48, addr: 0
:write byte: 49, read: 49, addr: 1
:write byte: 48, read: 48, addr: 2
:write byte: 65, read: 1, addr: 3
:devId writting successes...
:save address fail
</code></pre>
<p>如果只是关闭中断就可以的话,那么从一开始就不应该写入成功才对🤔</p>
这里写之前擦的地址正确吗?建议贴完整可复现的工程上来方便大家帮你分析
页:
[1]
2