这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » STC8G单片机的EEPROM读写不了,why?

共6条 1/1 1 跳转至

STC8G单片机的EEPROM读写不了,why?

工程师
2021-06-14 22:21:49     打赏

大家好! 我参考了官方的STC8G单片机的技术文档里面的例程,在带电状态下EEPROM是可以写,也可以读的。但就是断电后,在主程序里读同一个地址。数据就是空白。什么都没有。怎么办呀?

贴上例程

#include<STC8.h>                 //STC15W系列单片机。晶振12MHZ
#include <INTRINS.H>
#define uint unsigned int   //宏命令,声明uint替代unsignde int
#define uchar unsigned char

sfr        DATA1=0xC2;  //数据寄存器
sfr        ADDRH=0xC3; //地址寄存器高八位
sfr        ADDRL=0xC4; //地址寄存器低八位
sfr        CMD=0xC5;    //命令模式寄存器
sfr        TRIG=0xC6;    //命令触发寄存器
sfr        CONTR=0xC7;  //控制寄存器
sfr        TPS=0xF5;       //等待时间控制继存器


void iapoff()
{
    IAP_CONTR = 0;                              //关闭IAP功能
    IAP_CMD = 0;                                //清除命令寄存器
    IAP_TRIG = 0;                               //清除触发寄存器
    IAP_ADDRH = 0x80;                           //将地址设置到非IAP区域
    IAP_ADDRL = 0;
}


uchar read(uint add)//读EEPROM子函数,add为EEPROM读数地址
{
                uchar dat;
        CONTR=0x80;       //定义控制寄存器工作时间,打开控制寄存器,晶体为12M
        TPS=12;           //晶振为12MHZ
        CMD=1;            //选择读的方式
        ADDRH=add>>8;     //得到地址高八位
        ADDRL=add;        //得到地址低八位
        TRIG=0x5a;        //控制码
        TRIG=0xa5;        //控制码
         _nop_();         //延时
                 _nop_();
                 _nop_();
        dat=DATA1;
        return dat;//将值返回
        iapoff();
}


void iniap(uint add,uchar vale)//写EEPROM子函数,add为EEPROM要写数的地址, vale为要存的数变量
{

        CONTR=0x80;//定义控制寄存器工作时间,打开控制寄存器,晶体为12M
        TPS=12;//晶振为12MHZ
        CMD=0X02;//选择写的方式
        ADDRH=add>>8;//得到地址高八位
        ADDRL=add;//得到地址低八位
        DATA1=vale;//将要存的数放进存数寄存器DATA
        TRIG=0x5a;//控制码
        TRIG=0xa5;//控制码
         _nop_();//延时
         _nop_();
         _nop_();
        iapoff();
}


void del(uint add)//删除子函数
{
        CONTR=0x80;

        TPS=12;//晶振为12MHZ
        CMD=3;//选择寄存器方式
        ADDRH=add>>8;
        ADDRL=add;
        TRIG=0x5a;
        TRIG=0xa5;
         _nop_();
                 _nop_();
                 _nop_();
                 iapoff();
}


void key()
{   
     if(k1!=jat&num<=2){jat=k1,num++;}      
    if(jta==1)                                                //判断JTA是否为1
  {               
     if(num==2)                                          //如果NUM是2
     {        
       bled=1;rled=0;                                   //蓝灯灭,红灯亮
       del(0x0f00);bled=0;                             //清除0X0F00这个EEPROM地址。
       iniap(0x0f00,1);bled=1;rled=1;             //写入0X0F00这个地址。注数1;所有灯灭。
       if(jta==read(0x0f00)){num=3;rled=0;}    //读取一次0X0F00这个地址,判断读数是否JTA相等,直至相等就退出储存状态。
     }


  }
}

void main()
{  
   P0M0=0Xff;
   P0M1=0X00;
   P1M0=0X00;
   P1M1=0X00;
   P2M0=0X00;
   P2M1=0X00;
   P3M0=0X00;
   P3M1=0X00;
   P4M0=0X00;
   P4M1=0X00;
   P5M0=0X00;
   P5M1=0X00;
   P6M0=0X00;
   P6M1=0X00;
   P7M0=0X00;
   P7M1=0X00;

    shuxian=read(0x0f00);                    //如果是1,读取EEPROM发送到数显。
    while(1)   {
    key();
    }

}




关键词: STC8G     EEPROM     存储器    

工程师
2021-06-14 23:48:43     打赏
2楼

期待高手帮你看看


工程师
2021-06-15 08:32:01     打赏
3楼

这个是官方例程吗? 应该OK的吧?


工程师
2021-06-15 08:38:03     打赏
4楼
谢谢大家的答复。例子是官方的,只是我修改了一些。另外,我自己看了官方技术手册好像这个8G2K64S4这个是特殊型号,可以自定义EEPROM尺寸的.....所以可能储存地址有问题。不过现在回家了,只能明天早上再验证了。定义1K容量EEPROM的话,地址范围应该是0x0000~0x03ff.超出范围值无效。



工程师
2021-06-15 08:43:36     打赏
5楼

8G2K64S4的EEPROM没有固定地址,自定义地址放在用户程序占用空间剩余下的任意扇区。重要事说三遍:扇区,扇区,扇区。每个扇区512字节,各扇区首地址以200H递增,0x0000,0x0200,0x0400,......。
如同作业本,你写字用了3页半,EEPROM只能从第5页开始。

楼主这句可能错了if(k1!=jat & num<=2)
按题意应该是if(k1!=jat && num<=2)


工程师
2021-06-15 08:49:42     打赏
6楼

谢谢楼上!


刚刚我又试了一下。确实是地址问题。现在可以正常读写了。大佬,还有一个问题,串口中断导致了点阵的动态扫描索引时序不一致而引起爆点,就是有一行因为中断而亮灯时间长一点,视觉上会特别亮。这个怎么处理呢?而且位置随串口中断次数不停变换。看着像鬼影。但跟鬼影又不同。难道点阵要用定时器中断来扫描吗?我是直接用P0口接的点阵。


共6条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]