STC8G1K08 官方eeprom程序有问题?
前些天拿到了最新的STC8G1K08样品,今天我迫不及待地把手册上的代码粘到keil编译下载,结果显示FF,改起始位置,改ISP软件设置...试了半天一直是FF,无奈了,这是不是BUG?有谁和我一样的情况吗,告诉我如何解决这个头疼的问题吧下面是测试代码// 测试工作频率为 11.0592MHz
#include "reg51.h"
#include "intrins.h"
#defineFOSC11059200UL
#defineBRT(65536 - FOSC / 115200 / 4)
sfrP1M1=0x91;
sfrP1M0=0x92;
sfrP3M1=0xb1;
sfrP3M0=0xb2;
sfrP5M1=0xc9;
sfrP5M0=0xca;
sfrAUXR=0x8e;
sfrT2H=0xd6;
sfrT2L=0xd7;
sfrIAP_DATA=0xC2;
sfrIAP_ADDRH=0xC3;
sfrIAP_ADDRL=0xC4;
sfrIAP_CMD=0xC5;
sfrIAP_TRIG=0xC6;
sfrIAP_CONTR=0xC7;
sfrIAP_TPS=0xF5;
void UartInit()
{
SCON = 0x5a;
T2L = BRT;
T2H = BRT >> 8;
AUXR = 0x15;
}
void UartSend(char dat)
{
while (!TI);
TI = 0;
SBUF = dat;
}
void IapIdle()
{
IAP_CONTR = 0;// 关闭 IAP 功能
IAP_CMD = 0; // 清除命令寄存器
IAP_TRIG = 0; // 清除触发寄存器
IAP_ADDRH = 0x80; // 将地址设置到非 IAP 区域
IAP_ADDRL = 0;
}
char IapRead(int addr)
{
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 数据
IapIdle(); // 关闭 IAP 功能
return dat;
}
void IapProgram(int addr, char dat)
{
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_();
IapIdle(); // 关闭 IAP 功能
}
void IapErase(int addr)
{
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_();//
IapIdle(); // 关闭 IAP 功能
}
void main()
{
P1M0 = 0x00;
P1M1 = 0x00;
P3M0 = 0x00;
P3M1 = 0x00;
P5M0 = 0x00;
P5M1 = 0x00;
UartInit();
IapErase(0x0400);
UartSend(IapRead(0x0400));
IapProgram(0x0400, 0x12);
UartSend(IapRead(0x0400));
while (1);
}
对着文档检查下 你也知道是新出来的芯片,建议你找官方还快解决。 ayb_ice 发表于 2019-11-26 15:57
对着文档检查下
我是把官方的程序编译,我想不用检查了吧。 LKC134 发表于 2019-11-26 16:05
你也知道是新出来的芯片,建议你找官方还快解决。
官方也慢,坛友这么多,或许解决得快一些。这芯片蛮不错的,各项都还好,大佬帮我看看哪里出问题了呗
行知ing 发表于 2019-11-26 16:17
官方也慢,坛友这么多,或许解决得快一些。这芯片蛮不错的,各项都还好,大佬帮我看看哪里出问题了呗
...
你串口整个程序才发送两个数据,怎么会收到那么多数据
估计程序都没跑起来 本帖最后由 行知ing 于 2019-11-26 17:29 编辑
解决了,使用MOVC 读取EEPROM可以,IAP方式不行。
#include "reg51.h"
#include "intrins.h"
sfrP1M1=0x91;
sfrP1M0=0x92;
sfrP3M1=0xb1;
sfrP3M0=0xb2;
sfrP5M1=0xc9;
sfrP5M0=0xca;
sfrIAP_DATA=0xC2;
sfrIAP_ADDRH=0xC3;
sfrIAP_ADDRL=0xC4;
sfrIAP_CMD=0xC5;
sfrIAP_TRIG=0xC6;
sfrIAP_CONTR=0xC7;
sfrIAP_TPS=0xF5;
#defineIAP_OFFSET 0x2000//STC8G1K08
void IapIdle()
{
IAP_CONTR = 0;// 关闭 IAP 功能
IAP_CMD = 0; // 清除命令寄存器
IAP_TRIG = 0; // 清除触发寄存器
IAP_ADDRH = 0x80; // 将地址设置到非 IAP 区域
IAP_ADDRL = 0;
}
char IapRead(int addr)
{
addr += IAP_OFFSET; // 使用 MOVC 读取 EEPROM 需要加上相应的偏移
return *(char code *)(addr); // 使用 MOVC 读取数据
}
void IapProgram(int addr, char dat)
{
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_();
IapIdle(); // 关闭 IAP 功能
}
void IapErase(int addr)
{
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_();//
IapIdle(); // 关闭 IAP 功能
}
void main()
{
P1M0 = 0x00;
P1M1 = 0x00;
P3M0 = 0x00;
P3M1 = 0x00;
P5M0 = 0x00;
P5M1 = 0x00;
IapErase(0x0400);
P3 = IapRead(0x0400); //P3=0xff
IapProgram(0x0400, 0x12);
P1 = IapRead(0x0400); //P1=0x12
while (1);
} 使用MOVC方式读取eeprom,第一页首地址读出来了。不知道为啥IAP方式读不出来,后边在研究吧,反正现在能用了{:biggrin:}
ayb_ice 发表于 2019-11-26 16:39
你串口整个程序才发送两个数据,怎么会收到那么多数据
估计程序都没跑起来 ...
哈,断电重新上电几次就有了呀 行知ing 发表于 2019-11-26 18:02
哈,断电重新上电几次就有了呀
我解决了,IAP方式官方程序少了点步骤,正在研究。MOVC可以。 楼主您好 求救 我也遇到相同问题 但是使用MOVC效果并不好 掉电还是丢失数据您有研究出更多方案么? 本帖最后由 ayumi7 于 2020-12-12 16:59 编辑
我也遇到了这个问题 2020年12月了这个BUG 还在???你试试写入 数据之后 注释掉写入 然后重新上电 只读取呢?是不是写入进去了?
你后来是怎么解决的???好了吗?
已经解决
本帖最后由 qq986433936 于 2020-12-19 21:08 编辑
应该没啥问题啊。给你贴个我正常使用的测试程序。可以从串口观察读出的数值是否正确。
//艾瑞泽5自动大灯编程
//STC8G1K08A_SOP8,晶振频率11.0592mhz,串口波特率115200
//使用了STC的资料及程序
#include <STC8G.H>
#include "intrins.h"
#include <stdio.h>
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
uchar Mem1,Mem2,Mem3;
uchar EEPROM_READ(uint); //读指定地址的一个字节
voidEEPROM_IDLE(void); //关闭EEPROM操作
void EEPROM_WRITE(uint, uchar);//向指定地址写入一个字节
void EEPROM_ERASE(uint); //擦除指定地址的扇区
voidDelay100ms(void); //@11.0592MHZ
//_____________程序开始_____________________
void main(void)
{
_nop_();
_nop_();
SCON = 0x50; //8位数据,可变波特率
AUXR &= 0xBF; //定时器1时钟为Fosc/12,即12T
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //设定定时器1为16位自动重装方式
TL1 = 0xFE; //设定定时初值115200@11.0592MHZ
TH1 = 0xFF; //设定定时初值
ET1 = 0; //禁止定时器1中断
TR1 = 1; //启动定时器1
TI = 1; //允许串口中断,printf函数需要此条语句
EA= 1; //总中断开关打开
while(1) //EEPROM读写测试
{
EEPROM_ERASE(0x0); //擦除指定地址的扇区
EEPROM_WRITE(0x01,0x7F); //向指定地址写入0x7f
EEPROM_WRITE(0x02,0xAA); //向指定地址写入0xAA
EEPROM_WRITE(0x03,0x55); //向指定地址写入0x55
Mem1 =0;
Mem2 =0;
Mem3 =0;
Mem1 = EEPROM_READ(0x01); //读入存储的3个数值
Mem2 = EEPROM_READ(0x02);
Mem3 = EEPROM_READ(0x03);
printf("Mem1:%X ",(uint)Mem1);
printf("Mem2:%X ",(uint)Mem2);
printf("Mem3:%X ",(uint)Mem3);
printf("\n"); //回车换行
Delay100ms();
}
}
//******************************************
void Delay100ms() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();
i = 6;
j = 157;
k = 59;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
//********以下是EEPROM操作函数,全部通过,无需再改
//关闭ISP/IAP/EEPROM功能
void EEPROM_IDLE(void)
{
IAP_CONTR = 0; //关闭IAP功能
IAP_CMD = 0; //standby模式
IAP_TRIG= 0; //清触发寄存器
IAP_ADDRH = 0x80; //指向非EEPROM地址区,防止误操作
IAP_ADDRL = 0;
}
//从指定的EEPROM地址Eeprom_Addr读取一个字节
uchar EEPROM_READ(uint Eeprom_Addr)
{
uchar dat;
IAP_CONTR = 0x80; //使能IAP
IAP_TPS = 12; // 设置擦除等待参数 12MHz
IAP_CMD = 1; //读命令
IAP_ADDRL = Eeprom_Addr; //地址低8位
IAP_ADDRH = Eeprom_Addr>>8; //地址高8位
IAP_TRIG = 0x5a; //触发命令
IAP_TRIG = 0xa5;
_nop_();
dat = IAP_DATA; //读取EEPROM数据
EEPROM_IDLE(); //关闭IAP
return dat;
}
//说明:Eeprom_Addr写入一个字节
//注意,在此之前一定要先擦除扇区
void EEPROM_WRITE(uint Eeprom_Addr, uchar dat)
{
IAP_CONTR = 0x80; //使能IAP
IAP_TPS = 12; // 设置擦除等待参数 12MHz
IAP_CMD = 2; //编程命令
IAP_ADDRL = Eeprom_Addr; //地址低8位
IAP_ADDRH = Eeprom_Addr>>8; //地址高8位
IAP_DATA = dat; //写入数据
IAP_TRIG = 0x5a; //触发命令
IAP_TRIG = 0xa5;
_nop_();
EEPROM_IDLE(); //关闭IAP
}
//擦除扇区,Eeprom_Addr为扇区起始地址
void EEPROM_ERASE(uint Eeprom_Addr)
{
IAP_CONTR = 0x80;//使能IAP
IAP_TPS = 12; // 设置擦除等待参数 12MHz
IAP_CMD = 3; //擦除命令
IAP_ADDRL = Eeprom_Addr; //地址低8位
IAP_ADDRH = Eeprom_Addr>>8; //地址高8位
IAP_TRIG = 0x5a; //触发命令
IAP_TRIG = 0xa5;
_nop_();
EEPROM_IDLE(); //关闭IAP
}
根本就不对 你IAP 方式的时候,接收发送的波特率设置不对,单片机是115200,ISP是9600 最近;我也在学习STC8G1K08 eeprom程序;遇到和楼主一样的问题,百思不解在网上搜索见到了这个帖子,看到烧录烧录软件有个选项:下次下载用户程序擦除用户
eeprom区,这个选项打开默认是打勾的,即是下次下载用户程序擦除用户eeprom区,那么每次下载都是上次的下次,所以每次下载都把eeprom区删除,如果把这个选项的勾点掉,下载就不删除eeprom区了,好了一切正常。
页:
[1]