找回密码
 立即注册

QQ登录

只需一步,快速开始

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

STC单片机内置EEPROM读取与保存 函数调用 .c和.h文件

[复制链接]
跳转到指定楼层
楼主
ID:278006 发表于 2020-2-15 22:23 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
10黑币
STC 内置EEPROM  读取与保存的 .c和.h文件

请教如何调用文件  掉电不丢失

1、读取3参数个数  改动后 保存到 EEPROM
我的用法是 :

unsigned int  Temp_Buf[3];                           //定义缓存:
Read_Flash_Message(ks_Addr,Temp_Buf, 3);//读取:函数是:void Read_Flash_Message(unsigned int Addr,unsigned char *Buf,unsigned int *Len);

Save_Flash_Message(ks_Addr,Temp_Buf, 3);//保存    函数是 :void Save_Flash_Message(unsigned int Addr,unsigned char *Buf,unsigned int Len);

现在是  无法保存  调取的也不对



//以下为.h文件
//使用单片机内部的Flash,模拟EEPROM使用
//STC15W4K48S4 单片机,可以使用IAP命令擦写内部Flash
//起始地址 0X0000 结束 0X27FF  其中,512Byte一个扇区
//一共20个扇区  一个扇区可以存储一组参数,这样就可以直接擦出整个扇区修改内容

#ifndef        __IAP_EEPROM__H_
#define        __IAP_EEPROM__H_
#include "STC15W.h"
#include "intrins.h"


#define        ks_Addr                                0X0000
#define        tz_Addr                                0X0200
#define        tm_Addr                                0X0400



//保存内容到Flash
void Save_Flash_Message(unsigned int Addr,unsigned char *Buf,unsigned int Len);
//从Flash读取内容
void Read_Flash_Message(unsigned int Addr,unsigned char *Buf,unsigned int *Len);
//读取某地址一个字节
unsigned char Read_One_Byte(unsigned int addr);
void Erase_IAP(unsigned int addr);
void Write_One_Byte(unsigned int addr,unsigned char dat);

#endif

以下为.c文件

  1. #include "IAP_EEPROM.h"
  2. //#include<Uart_1.h> //用来CLI交互
  3. //STC15W4K48S4 单片机,可以使用IAP命令擦写内部Flash
  4. //起始地址 0X0000 结束 0X27FF  其中,512Byte一个扇区

  5. //关闭IAP功能
  6. void Close_IAP(void)
  7. {
  8.         IAP_CONTR = 0;
  9.         IAP_CMD = 0;
  10.         IAP_TRIG = 0;
  11.         IAP_ADDRH = 0;
  12.         IAP_ADDRL = 0;
  13. }
  14. //擦除某地址所在的扇区
  15. void Erase_IAP(unsigned int addr)
  16. {
  17.                 IAP_CONTR = 0x82;//允许IAP操作,设置IAP操作速度         
  18.     IAP_CMD = 0x03;//扇区擦除命令            
  19.     IAP_ADDRL = addr;              
  20.     IAP_ADDRH = addr >> 8;//地址赋值         
  21.     IAP_TRIG = 0x5a;               
  22.     IAP_TRIG = 0xa5;//触发命令               
  23.     _nop_();_nop_();_nop_();            
  24.     Close_IAP();//清空IAP操作寄存器等
  25. }
  26. //在某地址写入一个字节
  27. void Write_One_Byte(unsigned int addr,unsigned char dat)
  28. {
  29.                 IAP_CONTR = 0x82;//允许IAP操作,设置IAP操作速度   
  30.     IAP_CMD = 0x02;//IAP写命令
  31.     IAP_ADDRL = addr;
  32.     IAP_ADDRH = addr >> 8;//地址赋值
  33.     IAP_DATA = dat;//更新写寄存器
  34.     IAP_TRIG = 0x5a;
  35.     IAP_TRIG = 0xa5;//触发
  36.     _nop_();
  37.     Close_IAP();//清空IAP操作寄存器等
  38. }
  39. //读取某地址一个字节
  40. unsigned char Read_One_Byte(unsigned int addr)
  41. {
  42.                 unsigned char dat=0;//定义一个待返回的数据
  43.     IAP_CONTR = 0x82;//允许IAP
  44.     IAP_CMD = 0x01;//IAP读命令
  45.     IAP_ADDRL = addr;
  46.     IAP_ADDRH = addr >> 8;//地址赋值
  47.     IAP_TRIG = 0x5a;
  48.     IAP_TRIG = 0xa5;//触发
  49.     _nop_();_nop_();_nop_();_nop_();
  50.     dat = IAP_DATA;
  51.                 Close_IAP();//清空IAP操作寄存器等
  52.     return dat;
  53. }
  54. //保存内容到Flash
  55. void Save_Flash_Message(unsigned int Addr,unsigned char *Buf,unsigned int Len)
  56. {
  57.         unsigned int i=0;
  58.         Erase_IAP(Addr);//擦除对应扇区
  59.         
  60.         if(Len >= 511)
  61.                 Len = 511;
  62.         
  63.         Write_One_Byte(Addr,Len>>8);//长度写入首地址
  64.         Write_One_Byte(Addr+1,(Len&0X00FF));//长度写入首地址
  65.         for(i=0;i<Len;i++) //顺序存储有效信息
  66.         {
  67.                 Write_One_Byte((Addr+2+i),Buf[i]);
  68.         }
  69. }
  70. //从Flash读取内容
  71. void Read_Flash_Message(unsigned int Addr,unsigned char *Buf,unsigned int *Len)
  72. {
  73.         unsigned int i=0;
  74.         *Len = Read_One_Byte(Addr); //首先读取长度信息
  75.         *Len <<= 8;
  76.         *Len += Read_One_Byte(Addr+1);
  77.         
  78.         if(*Len >= 511)
  79.                 *Len = 511;
  80.         
  81.         for(i=0;i<*Len;i++)
  82.         {
  83.                 Buf[i] = Read_One_Byte(Addr+2+i);
  84.         }
  85. }
  86. //
复制代码




IAP.zip

1.63 KB, 下载次数: 21, 下载积分: 黑币 -5

最佳答案

查看完整内容

//关闭IAP功能 void Close_IAP(void) { IAP_CONTR = 0; IAP_CMD = 0; IAP_TRIG = 0; IAP_ADDRH = 0; IAP_ADDRL = 0; } 中 IAP_ADDRH = 0;改为IAP_ADDRH = 0x80;

评分

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

查看全部评分

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

使用道具 举报

沙发
ID:45334 发表于 2020-2-15 22:23 | 只看该作者
//关闭IAP功能
void Close_IAP(void)
{
        IAP_CONTR = 0;
        IAP_CMD = 0;
        IAP_TRIG = 0;
        IAP_ADDRH = 0;
        IAP_ADDRL = 0;
}
中 IAP_ADDRH = 0;改为IAP_ADDRH = 0x80;
回复

使用道具 举报

板凳
ID:278006 发表于 2020-2-16 17:57 | 只看该作者
qsgang 发表于 2020-2-16 09:58
//关闭IAP功能
void Close_IAP(void)
{

1、读取3参数个数  改动后 保存到 EEPROM
我的用法是 :

unsigned int  Temp_Buf[3];                           //定义缓存:
Read_Flash_Message(ks_Addr,Temp_Buf, 3);//读取:函数原型是:void Read_Flash_Message(unsigned int Addr,unsigned char *Buf,unsigned int *Len);

Save_Flash_Message(ks_Addr,Temp_Buf, 3);//保存    函数原型是 :void Save_Flash_Message(unsigned int Addr,unsigned char *Buf,unsigned int Len);
我对于 调用 带指针参数的 函数有点迷糊  请教一下  我调用的方法对吗?  一个是 len对应的3好像是对的  *len也对应3  对吗?
回复

使用道具 举报

地板
ID:45334 发表于 2020-2-16 21:16 | 只看该作者
读错误,写正确,长度用整形,不用指针
回复

使用道具 举报

5#
ID:278006 发表于 2020-2-17 10:54 | 只看该作者
qsgang 发表于 2020-2-16 21:16
读错误,写正确,长度用整形,不用指针

读错误?您是说 这个函数本身就是错误 还是 我调用的错误呀

//从Flash读取内容
void Read_Flash_Message(unsigned int Addr,unsigned char *Buf,unsigned int *Len)
{
        unsigned int i=0;
        *Len = Read_One_Byte(Addr); //首先读取长度信息
        *Len <<= 8;
        *Len += Read_One_Byte(Addr+1);
        
        if(*Len >= 511)
                *Len = 511;
        
        for(i=0;i<*Len;i++)
        {
                Buf = Read_One_Byte(Addr+2+i);
        }
}
回复

使用道具 举报

6#
ID:91162 发表于 2020-3-8 08:39 | 只看该作者
单片机初始化后要加几百毫秒延时,再进主函数,否则读不出来
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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