- 打卡等级:初来乍到
- 打卡总天数:5
- 最近打卡:2024-05-02 21:48:56
高级会员
- 积分
- 614
|
本帖最后由 qq603599910 于 2024-6-11 10:30 编辑
2024-06-11 最终确认修复结果:之前没有确认准确原因一直在尝试,然后太多不稳定因素干扰导致一直没有找到准确原因,然后前辈回复让我尝试增加延时,我把延时增加在外部步骤代码上没有作用,需要增加在Flash_Read函数代码内部,如图.
char Flash_Read(int addr)
{
char dat;
EA = 0; //禁止中断
IAP_CONTR = 0x80; //使能IAP
IAP_TPS = 12; //设置等待参数12MHz
IAP_CMD = 1; //设置IAP读命令
IAP_ADDRL = addr; //设置IAP低地址
IAP_ADDRH = addr >> 8; //设置IAP高地址
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_nop_(); ====================================== 这里增加2个延时即输出正常.
_nop_(); ======================================
_nop_();
dat = IAP_DATA; //读IAP数据
Flash_Idle(); //关闭IAP功能
EA = 1; //重新允许中断
return dat;
}
=============原文 =======================
各位前辈,最近新拿STC8H2K08U开始做基础代码调试,在IAP_EEPROM验证时不能正常写入读取多个数据,单个地址没有发现异常,基础代码是从范例复制,偶尔烧录一次又能正常读取但没有找到规律.
1: 开始从0x0001开始擦除,然后for循环读取已擦除的5个地址原始值,理论上0x0001-0x0005擦除后应该都是0xffff,但异常是0x0001地址不能被擦除.
2: 从0x0001-0x0005一次写入"0,1,2,3,4"个数值,然后读取已写入值变成"4,0,1,2,3" .我试过N种方法,例如改数据量,用数组,改初始地址,改地址排列都不能找到规律.
3: 调试偶尔烧录后能正常写入读取数据顺序不会变所有地址擦除也正常.但可能第二次烧录后又是读取顺序异常,第一个地址不能被擦除.
以下是验证代码:========================================================
void IAP_Test(void) //EEPROM验证.
{
IAP_Erase(0x0001); //从0x0001起始擦除
for (i=0; i<5; i++)
{
printf("IAP_Erase,%01u:%01u\r\n",(u16)(i),(u16)IAP_Read(0x0001+i)); //读取并发送擦除的5个地址(0xFFFF)
}
for (i=0; i<5; i++)
{
IAP_Program(0x0001+i,i); //写入5个地址数据
}
for (i=0; i<5; i++)
{
printf("IAP_Program,%01u:%01u\r\n",(u16)(i),(u16)IAP_Read(0x0001+i));//读取并发送写入5个地址的数据
}
}
以下是打印输出:======================================
时间 数据描述,顺序号:数据
[15:54:44.632]接收:IAP_Erase,0:0 <<<0x0001地址这个应该是65535(0xFFFF)
IAP_Erase,1:65535
IAP_Erase,2:65535
IAP_Erase,3:65535
IAP_Erase,4:65535
IAP_Program,0:4 <<<0x0001地址这个应该是0,被占了一个地址,一次后排.
IAP_Program,1:0
IAP_Program,2:1
IAP_Program,3:2
IAP_Program,4:3
[15:54:46.612]接收:IAP_Erase,0:4 <<< 0x0001地址这次数据"4"上一次写入的值.不能被擦除
IAP_Erase,1:65535
IAP_Erase,2:65535
IAP_Erase,3:65535
IAP_Erase,4:65535
IAP_Program,0:4
IAP_Program,1:0
IAP_Program,2:1
IAP_Program,3:2
IAP_Program,4:3
基础代码是从范例复制==================
#include "inc\eeprom.h"
void IAP_Idle() //IAP关闭
{
IAP_CONTR = 0; //关闭IAP功能
IAP_CMD = 0; //清除命令寄存器
IAP_TRIG = 0; //清除触发寄存器
IAP_ADDRH = 0x80; //将地址设置到非IAP区域
IAP_ADDRL = 0;
}
char IAP_Read(int addr) //读取IAP
{
char dat;
IAP_CONTR = 0x80; //使能IAP
IAP_TPS = 12; //设置等待参数12MHz
IAP_CMD = 1; //设置IAP读命令
IAP_ADDRL = addr; //设置IAP低地址
IAP_ADDRH = addr >> 8; //设置IAP高地址
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_nop_();
dat = IAP_DATA; //读IAP数据
IAP_Idle(); //关闭IAP功能
return dat;
}
void IAP_Program(int addr, char dat) //写IAP
{
IAP_CONTR = 0x80; //使能IAP
IAP_TPS = 12; //设置等待参数12MHz
IAP_CMD = 2; //设置IAP写命令
IAP_ADDRL = addr; //设置IAP低地址
IAP_ADDRH = addr >> 8; //设置IAP高地址
IAP_DATA = dat; //写IAP数据
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_nop_();
IAP_Idle(); //关闭IAP功能
}
void IAP_Erase(int addr) //清除IAP地址
{
IAP_CONTR = 0x80; //使能IAP
IAP_TPS = 12; //设置等待参数12MHz
IAP_CMD = 3; //设置IAP擦除命令
IAP_ADDRL = addr; //设置IAP低地址
IAP_ADDRH = addr >> 8; //设置IAP高地址
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_nop_(); //
IAP_Idle(); //关闭IAP功能
}
|
|