[51单片机]

STC8G1K08 官方eeprom程序有问题?

[复制链接]
4278|16
手机看帖
扫描二维码
随时随地手机跟帖
行知ing|  楼主 | 2019-11-26 14:56 | 显示全部楼层 |阅读模式
前些天拿到了最新的STC8G1K08样品,今天我迫不及待地把手册上的代码粘到keil编译下载,结果显示FF,改起始位置,改ISP软件设置...试了半天一直是FF,无奈了,这是不是BUG?有谁和我一样的情况吗,告诉我如何解决这个头疼的问题吧下面是测试代码
// 测试工作频率为 11.0592MHz
#include "reg51.h"
#include "intrins.h"
#define  FOSC  11059200UL
#define  BRT  (65536 - FOSC / 115200 / 4)
sfr  P1M1  =  0x91;
sfr  P1M0  =  0x92;
sfr  P3M1  =  0xb1;
sfr  P3M0  =  0xb2;
sfr  P5M1  =  0xc9;
sfr  P5M0  =  0xca;
sfr  AUXR  =  0x8e;
sfr  T2H  =  0xd6;
sfr  T2L  =  0xd7;
sfr  IAP_DATA  =  0xC2;
sfr  IAP_ADDRH  =  0xC3;
sfr  IAP_ADDRL  =  0xC4;
sfr  IAP_CMD  =  0xC5;
sfr  IAP_TRIG  =  0xC6;
sfr  IAP_CONTR  =  0xC7;
sfr  IAP_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);
}

417215ddccb1e4d851.png

934945ddccc691fd07.png







使用特权

评论回复

相关帖子

ayb_ice| | 2019-11-26 15:57 | 显示全部楼层
对着文档检查下

使用特权

评论回复
LKC134| | 2019-11-26 16:05 | 显示全部楼层
你也知道是新出来的芯片,建议你找官方还快解决。

使用特权

评论回复
行知ing|  楼主 | 2019-11-26 16:14 | 显示全部楼层

我是把官方的程序编译,我想不用检查了吧。

使用特权

评论回复
行知ing|  楼主 | 2019-11-26 16:17 | 显示全部楼层
LKC134 发表于 2019-11-26 16:05
你也知道是新出来的芯片,建议你找官方还快解决。

官方也慢,坛友这么多,或许解决得快一些。这芯片蛮不错的,各项都还好,大佬帮我看看哪里出问题了呗

使用特权

评论回复
ayb_ice| | 2019-11-26 16:39 | 显示全部楼层
行知ing 发表于 2019-11-26 16:17
官方也慢,坛友这么多,或许解决得快一些。这芯片蛮不错的,各项都还好,大佬帮我看看哪里出问题了呗
...

你串口整个程序才发送两个数据,怎么会收到那么多数据

估计程序都没跑起来

使用特权

评论回复
行知ing|  楼主 | 2019-11-26 17:23 | 显示全部楼层
本帖最后由 行知ing 于 2019-11-26 17:29 编辑

解决了,使用MOVC 读取EEPROM可以,IAP方式不行。
672505ddceedc7631c.png
#include "reg51.h"
#include "intrins.h"
sfr  P1M1  =  0x91;
sfr  P1M0  =  0x92;
sfr  P3M1  =  0xb1;
sfr  P3M0  =  0xb2;
sfr  P5M1  =  0xc9;
sfr  P5M0  =  0xca;
sfr  IAP_DATA  =  0xC2;
sfr  IAP_ADDRH  =  0xC3;
sfr  IAP_ADDRL  =  0xC4;
sfr  IAP_CMD  =  0xC5;
sfr  IAP_TRIG  =  0xC6;
sfr  IAP_CONTR  =  0xC7;
sfr  IAP_TPS  =  0xF5;
#define  IAP_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);
}

使用特权

评论回复
行知ing|  楼主 | 2019-11-26 17:37 | 显示全部楼层
使用MOVC方式读取eeprom,第一页首地址读出来了。不知道为啥IAP方式读不出来,后边在研究吧,反正现在能用了
130405ddcf1c1d0f68.png

使用特权

评论回复
行知ing|  楼主 | 2019-11-26 18:02 | 显示全部楼层
ayb_ice 发表于 2019-11-26 16:39
你串口整个程序才发送两个数据,怎么会收到那么多数据

估计程序都没跑起来 ...

哈,断电重新上电几次就有了呀

使用特权

评论回复
行知ing|  楼主 | 2019-11-26 18:04 | 显示全部楼层
行知ing 发表于 2019-11-26 18:02
哈,断电重新上电几次就有了呀

我解决了,IAP方式官方程序少了点步骤,正在研究。MOVC可以。

使用特权

评论回复
评论
849928055 2019-11-27 17:25 回复TA
楼主加个qq849928055,我也遇到同样的问题,交流下 
蒙蒙plus| | 2020-5-6 09:57 | 显示全部楼层
楼主您好 求救   我也遇到相同问题 但是使用MOVC效果并不好 掉电还是丢失数据  您有研究出更多方案么?

使用特权

评论回复
ayumi7| | 2020-12-12 15:14 | 显示全部楼层
本帖最后由 ayumi7 于 2020-12-12 16:59 编辑

  我也遇到了这个问题   2020年12月了  这个BUG 还在???  你试试  写入 数据之后    注释掉写入      然后重新上电    只读取呢?是不是写入进去了?

你后来是怎么解决的???好了吗?


已经解决   

使用特权

评论回复
qq986433936| | 2020-12-19 21:04 | 显示全部楼层
本帖最后由 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);     //读指定地址的一个字节
void  EEPROM_IDLE(void);     //关闭EEPROM操作
void EEPROM_WRITE(uint, uchar);  //向指定地址写入一个字节
void EEPROM_ERASE(uint);         //擦除指定地址的扇区
void  Delay100ms(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
}


使用特权

评论回复
中国微电脑网| | 2021-1-25 16:54 | 显示全部楼层
根本就不对

使用特权

评论回复
zhxzhxzzhhxx| | 2022-6-23 21:25 | 显示全部楼层
你IAP 方式的时候,接收发送的波特率设置不对,单片机是115200,ISP是9600

使用特权

评论回复
taihang258| | 2022-8-16 13:30 | 显示全部楼层
最近;我也在学习STC8G1K08 eeprom程序;遇到和楼主一样的问题,百思不解在网上搜索见到了这个帖子,看到烧录烧录软件有个选项:下次下载用户程序擦除用户
eeprom区,这个选项打开默认是打勾的,即是下次下载用户程序擦除用户eeprom区,那么每次下载都是上次的下次,所以每次下载都把eeprom区删除,如果把这个选项的勾点掉,下载就不删除eeprom区了,好了一切正常。
756CB5DD-DE1A-4D6B-B552-B6BC4819705C.jpeg

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

13

帖子

0

粉丝