找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6412|回复: 5
打印 上一主题 下一主题
收起左侧

STC8G单片机的片上EEPROM程序

  [复制链接]
跳转到指定楼层
楼主
ID:162691 发表于 2021-3-20 16:04 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 407871699 于 2021-3-20 16:40 编辑

最近研究了STC8G的片上EEPROM,比片外ROM方便多了。
但刚开始使用STC官网下载的例程时候老报错,还是不熟悉啊。
然后和官方的手册上的例程比较:手册提供了3个函数,写1个字节函数void IapProgramByte(WORD addr, BYTE dat),读1个字节函数BYTE IapReadByte(WORD addr),擦除扇区函数void IapEraseSector(WORD addr)。   手册上这3个函数不方便与主函数进行数据交换,还要在编数据交换函数;因此结合手册例程,把官网下载的EEPROM例程改动了一下,编成EEPROM.H,就可以直接调用
片上EEPROM写入时,重点是必须先用扇区擦除,否则写入的数值错误。

单片机源程序如下:
#include<STC8xxxx.h>      //建议到官网下载,则包含sfr IAP_TPS = 0xF5;
//sfr  IAP_TPS = 0xF5;         //这个是STC8新增的寄存器,按CPU频率计算等待时间
#define  EEPROM_ADD_0  0x0000           //EROM ADDRESS  起始地址,大家可以根据需要改存储位置,但是要符合MCU手册
#define  MAIN_Fosc                11059200L        //定义MCU频率;这句可以放在初始化配置中或主程序中
#define  IAP_EN          (1<<7)                   //启动IAP;等价于IAP_EN=0X80;
#define  IAP_ENABLE()        IAP_CONTR = IAP_EN; IAP_TPS = MAIN_Fosc / 1000000   //使能+等待


void        DisableEEPROM(void)                //禁止IAP操作
{
        IAP_CONTR = 0;                //禁止IAP操作
        IAP_CMD   = 0;                //去除IAP命令
        IAP_TRIG  = 0;                //防止IAP命令误触发
        IAP_ADDRH = 0xff;        //清0地址高字节
        IAP_ADDRL = 0xff;        //清0地址低字节,指向非EEPROM区,防止误操作
}


void EEPROM_Trig(void)   //触发EEPROM
{
        F0 = EA;    //保存全局中断
        EA = 0;     //禁止中断, 避免触发命令无效
        IAP_TRIG = 0x5A; //先送5AH,再送A5H到IAP触发寄存器,每次都需要如此
        IAP_TRIG = 0xA5; //送完A5H后,IAP命令立即被触发启动//CPU等待IAP完成后,才会继续执行程序。
        _nop_();        _nop_();     //2个空指令等待一下
        EA = F0;    //恢复全局中断
}

// 参数: EE_address:  读取EEPROM的首地址.
//       DataAddress: 读取数据后给到 数组首地址.
//       number:      读取的字节长度.
void EEPROM_read_n(unsigned int EE_address,unsigned char *DataAddress,unsigned int number)      
{
IAP_ENABLE();             //设置等待时间,允许IAP操作,送一次就够
IAP_CMD = 1;              //=1读;送字节读命令,命令不需改变时,不需重新送命令
do
  {
        IAP_ADDRH = EE_address / 256;  //送地址高字节(地址需要改变时才需重新送地址)
        IAP_ADDRL = EE_address % 256;       //送地址低字节
        EEPROM_Trig();                      //触发EEPROM操作
        *DataAddress = IAP_DATA;            //读出的数据送往
        EE_address++;
        DataAddress++;
  }while(--number);
DisableEEPROM();
}
void EEPROM_SectorErase(unsigned int EE_address)
{
        IAP_ENABLE();  //设置等待时间,允许IAP操作,送一次就够
        IAP_CMD = 3;   //宏调用, =3,送扇区擦除命令,命令不需改变时,不需重新送命令
                        //只有扇区擦除,没有字节擦除,512字节/扇区。
                        //扇区中任意一个字节地址都是扇区地址。
        IAP_ADDRH = EE_address / 256; //送扇区地址高字节(地址需要改变时才需重新送地址)
        IAP_ADDRL = EE_address % 256;  //送扇区地址低字节
        EEPROM_Trig();                 //触发EEPROM操作
        DisableEEPROM();               //禁止EEPROM操作
}

// 参数: EE_address:  写入EEPROM的首地址.
//       DataAddress: 写入源数据的缓冲的首地址. 就是从数组读取数据,
//       number:      写入的字节长度.

void EEPROM_write_n(unsigned int EE_address,unsigned char *DataAddress,unsigned int number)
{
        IAP_ENABLE();       //设置等待时间,允许IAP操作,送一次就够
        IAP_CMD = 2;        //宏调用, =2,送字节写命令
        do
        {
        IAP_ADDRH = EE_address / 256; //送地址高字节(地址需要改变时才需重新送地址)
        IAP_ADDRL = EE_address % 256;     //送地址低字节
        IAP_DATA  = *DataAddress;         //送数据到IAP_DATA,只有数据改变时才需重新送
        EEPROM_Trig();                    //触发EEPROM操作
        EE_address++;                     //下一个地址
        DataAddress++;                    //下一个数据
        }while(--number);                   //直到结束
        DisableEEPROM();
}

调用举例:(建议定义一个数组)
unsigned char ROM_num[6];        //存储数据的数组,最后与EEPROM进行数据交换

EEPROM_read_n(EEPROM_ADD_0,ROM_num,6);          //读取ROM信息到数组

void _write_ROM()      //编制专门的写入函数
{
EEPROM_SectorErase(EEPROM_ADD_0);           //必须先擦除数据(由MCU自动,512字节被擦除),之后再写入,才能写正确
ROM_num[0]=test_1/256;                           //将4个测试数值分别给到临时交换数组。
ROM_num[1]=test_1%256;
ROM_num[2]=test_2;                               //test_1、3是16位的数据(2个字节);
ROM_num[3]=test_3/256;
ROM_num[4]=test_3%256;
ROM_num[5]=test_4;                               //test_2、test_4是单字节数据(8位)
EEPROM_write_n(EEPROM_ADD_0,ROM_num,6);        //从数组写如到ROM中
}



评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏7 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:162691 发表于 2021-3-20 17:01 | 只看该作者
自己顶一个
回复

使用道具 举报

板凳
ID:250631 发表于 2021-3-23 23:39 | 只看该作者
我选用的是8h8k64u芯片,希望能用上。感谢楼主无私分享
回复

使用道具 举报

地板
ID:307493 发表于 2024-1-23 17:37 | 只看该作者
为啥我 照着写 没有把数据保存住
回复

使用道具 举报

5#
ID:771630 发表于 2024-1-24 22:34 | 只看该作者
qq378912453 发表于 2024-1-23 17:37
为啥我 照着写 没有把数据保存住

要加延时,靠他自动延时存不住数据
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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