找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1718|回复: 13
收起左侧

STC8F单片机eeprom可以连继读写int数据吗?拆分再写还是怎么样

[复制链接]
ID:734017 发表于 2021-11-12 11:08 | 显示全部楼层 |阅读模式
有一个int 数据190~280
拆分再写还是怎么样
请教有没好方法
回复

使用道具 举报

ID:624769 发表于 2021-11-12 13:53 | 显示全部楼层
首先,STC8 是8位机, 所以,即使在C代码表面上看你是读写一个16位数据,实际操作时候,还是分开读写2个8位的。
然后,写得时候,一个萝卜一个坑, 一个 IAP_ADDRH + IAP_ADDRL 对应一个地址 写入一个8位数据。你可以做一个子函数,不牵涉到跨页的前提下,函数里通过直接 IAP_ADDRL++; 然后 IAP_DATA = xx 可以比较快速的写入下一个。
读的时候相对简单一些,可以用 unsigned short code 指针直接读出来,(至少代码上看,是这样)
回复

使用道具 举报

ID:879348 发表于 2021-11-12 13:56 | 显示全部楼层
STC的是假EEPROM,本质是一块flash,可以允许连续写入一页数据,但是写入前必须整块擦除
回复

使用道具 举报

ID:734017 发表于 2021-11-12 14:42 | 显示全部楼层
188610329 发表于 2021-11-12 13:53
首先,STC8 是8位机, 所以,即使在C代码表面上看你是读写一个16位数据,实际操作时候,还是分开读写2个8位 ...

void IapProgram(int addr, unsigned char dat)       
{
    IAP_CONTR = WT_24M;                
    IAP_CMD = 2;                                
    IAP_ADDRL = addr;              
    IAP_ADDRH = addr >> 8;         
    IAP_DATA = dat;               
    IAP_TRIG = 0x5a;               
    IAP_TRIG = 0xa5;               
    _nop_();                        
    IapIdle();      
}

void IapIdle()
{
        IAP_CONTR        =0;                       
        IAP_CMD                =0;                       
        IAP_TRIG         =0;                       
        IAP_ADDRH        =0x80;               
        IAP_ADDRL        =0;                       
}
IapErase(0x0000); //擦除
IapProgram(0x0000,XXX);               
IapProgram(0x0001,XXX);
IapProgram(0x0002,XXX);

连续写可以这样干吧,IapIdle();   是不是要从写函数拿出来放在最后


回复

使用道具 举报

ID:624769 发表于 2021-11-12 14:56 | 显示全部楼层
void IapIdle() 没有任何实际意义,完全不需要用。

把一个 16位 变量存入 Eeprom:
void WriteWord(unsigned short addr, unsigned short dat)        
{
    IAP_CONTR = WT_24M;                 
    IAP_CMD = 2;                                 
    IAP_ADDRL = addr;              
    IAP_ADDRH = addr >> 8;         
    IAP_DATA = dat >>8 ;               
    IAP_TRIG = 0x5a;               
    IAP_TRIG = 0xa5;               
    _nop_();
    if(++IAP_ADDRL == 0)   IAP_ADDRH++
    IAP_DATA = dat;               
    IAP_TRIG = 0x5a;               
    IAP_TRIG = 0xa5;               
}
回复

使用道具 举报

ID:734017 发表于 2021-11-12 15:14 | 显示全部楼层
188610329 发表于 2021-11-12 14:56
void IapIdle() 没有任何实际意义,完全不需要用。

把一个 16位 变量存入 Eeprom:

if(++IAP_ADDRL == 0)   IAP_ADDRH++
地址不是0x0000,0x0001........
加高位吗??
上次那个比较器,我弄好了,谢谢你
回复

使用道具 举报

ID:624769 发表于 2021-11-12 15:24 | 显示全部楼层
如果,你给的地址,正好是  0x00FF 的话, 那么, ADDRL+1 之后,需要进位,这句IF主要是判断,是否ADDRL +1 之后 为0,是的话 就 给ADDRH +1 不是的话 ADDRH 维持原状
回复

使用道具 举报

ID:57657 发表于 2021-11-12 15:27 | 显示全部楼层
16位变量请移位拆分储存,32位、浮点数请用union结构转换。
回复

使用道具 举报

ID:734017 发表于 2021-11-12 17:04 | 显示全部楼层
188610329 发表于 2021-11-12 15:24
如果,你给的地址,正好是  0x00FF 的话, 那么, ADDRL+1 之后,需要进位,这句IF主要是判断,是否ADDRL + ...

地址是硬件自动加的吗,还是程序加ADDRL +1
回复

使用道具 举报

ID:624769 发表于 2021-11-12 17:33 来自手机 | 显示全部楼层
happy2058 发表于 2021-11-12 17:04
地址是硬件自动加的吗,还是程序加ADDRL +1

当然手动加啊,没看到++IAP_ADDRL 么?
回复

使用道具 举报

ID:734017 发表于 2021-11-12 18:15 | 显示全部楼层
188610329 发表于 2021-11-12 17:33
当然手动加啊,没看到++IAP_ADDRL 么?

unsigned int IapRead_two(unsigned int addr)
{
    unsigned int dat;

    IAP_CONTR = WT_24M;
    IAP_CMD = 1;  
    IAP_ADDRL = addr;
    IAP_ADDRH = addr >> 8;
    IAP_TRIG = 0x5a;  
    IAP_TRIG = 0xa5;
    _nop_();   
    dat = IAP_DATA;  
        dat=dat<<8;
        if(++IAP_ADDRL == 0)  
                IAP_ADDRH++;
    IAP_TRIG = 0x5a;               
    IAP_TRIG = 0xa5;
        _nop_();        
        dat |= IAP_DATA;  
   // IapIdle();   
    return dat;   
}

读两个可以这个干吗
下面这个程序,烧录后第一次上电,读了一个521,不知道为什么,还没写数据

SK_Data_KHz_switch        =        IapRead(0x0000);    //读频率8位
SK_Data_KHz        =        IapRead_two(0x0100);    //读强度 16位
if(SK_Data_KHz!=0)                                          
{
SK_HZ_satar(SK_PWM[SK_Data_KHz_switch]);          //加载频率                                                               
}
else
{
        SK_Data_KHz_switch=50;                    //eerporm 为什么,加载默认初值
        SK_Data_KHz=250;
}

回复

使用道具 举报

ID:624769 发表于 2021-11-12 21:39 | 显示全部楼层
确认一下,SK_Data_KHz  是unsigned short 么?

另外,你的 Eeprom 0x0100 处存的数据,你能确认么? 一般,为了安全起见,会在烧录的时候,烧入指定的Eeprom数据,下载其那里可以直接输入16进制烧录,来确保,“读”这个动作,是否正常的检验没有其他因素干扰。
回复

使用道具 举报

ID:734017 发表于 2021-11-12 21:52 | 显示全部楼层
188610329 发表于 2021-11-12 21:39
确认一下,SK_Data_KHz  是unsigned short 么?

另外,你的 Eeprom 0x0100 处存的数据,你能确认么? 一 ...

unsigned short和unsigned int 是不是都是16位,我找了很多资文章都是16位。
我试一下在烧录那个先写入
回复

使用道具 举报

ID:734017 发表于 2021-11-13 01:22 | 显示全部楼层
188610329 发表于 2021-11-12 21:39
确认一下,SK_Data_KHz  是unsigned short 么?

另外,你的 Eeprom 0x0100 处存的数据,你能确认么? 一 ...

原因找到了 eeprom第一次上电时未写入时。里部是0xff  ,我以为是0x00;
读出来16位 存在char 数据显示523
现在已经读写正常,今天非常感谢谢你。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表