查看: 7688|回复: 8

[其他] 经验分享--Flash模拟EEPROM编程中的两个小问题

[复制链接]

该用户从未签到

8

主题

39

帖子

0

注册会员

Rank: 2

积分
121
最后登录
1970-1-1
发表于 2008-10-5 16:20:43 | 显示全部楼层 |阅读模式
情景:用Flash模拟EEPROM保存预设参数
问题:每次开机时程序并没有使用设置后的新值,而是仍然用初始值运行。
分析:读Flash,参数已经被写入了Flash。但是看来程序并没有使用Flash中的参数运行。
原来程序中相关的部分如下。目的是从Flash的F000~F003地址处取出参数,并放到变量“DRTU”和“DRTL”中。
 #define RTU         501               /* input pulse standard up value */
 #define RTL         251               /* input pulse standard low value */
 
 uint16 DRTU;
 uint16 DRTL;
 
 #pragma DATA_SEG EEE_DATA             /* 这是Flash中用来模拟EEPROM的地址空间 */
 const uint8 CRTUH      @0x0000F000 = (uint8)(RTU/256);
 const uint8 CRTUL      @0x0000F001 = (uint8)(RTU&0x00FF);
 const uint8 CRTLH      @0x0000F002 = (uint8)(RTL/256);
 const uint8 CRTLL      @0x0000F003 = (uint8)(RTL&0x00FF);
 #pragma DATA_SEG DEFAULT
  DRTU = CRTUH*256+CRTUL;
  DRTL = CRTLH*256+CRTLL;
反汇编代码如下。发现汇编代码并没有从Flash地址取数,而是直接用立即数给变量赋值。看来“聪明”的编译器找到了更“优化”的赋值方法。我们当然不能怪编译器,它只是按照人的指令去工作。 
 
  445:    DRTU = CRTUH*256+CRTUL;
  007c 4501f5   [3]             LDHX  #501
  007f 3500     [5]             STHX  DRTU
  446:    DRTL = CRTLH*256+CRTLL;
  0081 aefb     [2]             LDX   #-5
  0083 8c       [1]             CLRH 
  0084 3500     [5]             STHX  DRTL
 
解决方法:这里用到了这个貌似怪异的声明“const volatile”。没错,既“const”又“volatile”。“const”表示这个值为只读。“volatile”则告诉编译器每次用到这个值都要去老老实实的到相应的地址去读一下,不能“偷懒”。比较典型的应用是用来声明硬件相关的状态寄存器。我们这里Flash中存储的参数值对程序来说是只读的,而这块Flash是通过特殊的操作步骤模拟EEPROM使用的。修改后的声明如下。
 #pragma DATA_SEG EEE_DATA             /* 这是Flash中用来模拟EEPROM的地址空间 */
 const volatile uint8 CRTUH      @0x0000F000 = (uint8)(RTU/256);
 const volatile uint8 CRTUL      @0x0000F001 = (uint8)(RTU&0x00FF);
 const volatile uint8 CRTLH      @0x0000F002 = (uint8)(RTL/256);
 const volatile uint8 CRTLL      @0x0000F003 = (uint8)(RTL&0x00FF);
 #pragma DATA_SEG DEFAULT
反汇编,这回是我们想要的代码了。
  445:    DRTU = CRTUH*256+CRTUL;
  007c c60000   [4]             LDA   CRTUL
  007f b701     [3]             STA   DRTU:1
  0081 c60000   [4]             LDA   CRTUH
  0084 b700     [3]             STA   DRTU
  446:    DRTL = CRTLH*256+CRTLL;
  0086 c60000   [4]             LDA   CRTLL
  0089 b701     [3]             STA   DRTL:1
  008b c60000   [4]             LDA   CRTLH
  008e b700     [3]             STA   DRTL
**************************************************
情景:用Flash模拟EEPROM保存预设参数
问题:在DATA_SEG EEE_DATA段中声明的数组会被初始化为全零,而我的应用里想让它保持“FF”状态。
解决方法:将EEE_STORAGE的属性改为NO_INIT。注意,这样此段中声明的其他变量也不可以赋初值。下面是工程中.prm文件的内容。
SEGMENTS /* Here all RAM/ROM areas of the device are listed. Used in PLACEMENT below. */
    Z_RESERVE                =  READ_WRITE   0x0060 TO 0x0064;
    Z_RAM                    =  READ_WRITE   0x0065 TO 0x00FF;
    RAMFUNC                  =  READ_WRITE   0x0100 TO 0x011F;
    RAM                      =  READ_WRITE   0x0120 TO 0x015F;
    EEE_STORAGE              =  NO_INIT      0xF000 TO 0xF1FF;
    ROM                      =  READ_ONLY    0xF200 TO 0xFFA9;
    ROM1                     =  READ_ONLY    0xFFC0 TO 0xFFCF;
 /* INTVECTS                 =  READ_ONLY    0xFFD0 TO 0xFFFF; Reserved for Interrupt Vectors */
END
PLACEMENT /* Here all predefined and user segments are placed into the SEGMENTS defined above. */
    DEFAULT_RAM                         /* non-zero page variables */
                                        INTO  RAM;
    _PRESTART,                          /* startup code */
    STARTUP,                            /* startup data structures */
    ROM_VAR,                            /* constant variables */
    STRINGS,                            /* string literals */
    VIRTUAL_TABLE_SEGMENT,              /* C++ virtual table segment */
    DEFAULT_ROM,
    COPY                                /* copy down information: how to initialize variables */
                                        INTO  ROM; /* ,ROM1: To use "ROM1" as well, pass the option -OnB=b to the compiler */
    EEE_DATA
                                        INTO  EEE_STORAGE;
    _DATA_ZEROPAGE,                     /* zero page variables */
    MY_ZEROPAGE                         INTO  Z_RAM;
    CODE_IN_RAM                         INTO  RAMFUNC;
    PASS_IN_RAM                         INTO  Z_RESERVE;
END
我知道答案 目前已有8人回答
回复

使用道具 举报

该用户从未签到

6

主题

48

帖子

0

新手上路

Rank: 1

积分
51
最后登录
1970-1-1
发表于 2011-3-25 08:15:43 | 显示全部楼层

RE:经验分享--Flash模拟EEPROM编程中的两个小问题

不错!不错!

该用户从未签到

0

主题

25

帖子

0

新手上路

Rank: 1

积分
11
最后登录
1970-1-1
发表于 2011-7-5 15:15:07 | 显示全部楼层

RE:经验分享--Flash模拟EEPROM编程中的两个小问题

学习学习,看看学习
  • TA的每日心情
    开心
    2018-9-14 09:26
  • 签到天数: 2 天

    连续签到: 1 天

    [LV.1]初来乍到

    70

    主题

    329

    帖子

    0

    高级会员

    Rank: 4

    积分
    952
    最后登录
    2021-1-4
    发表于 2011-7-5 16:10:19 | 显示全部楼层

    回复:经验分享--Flash模拟EEPROM编程中的两个小问题

    1.volatile的意思是提醒编译器,变量有可能会在程序没有对它进行修改,但是它的值有可能变化,一般是对SFR声明,比如PORT口的输入值。你的变量用volative来声明,不是很合适。我觉得你的现象应该是优化级别太高造成的。
     
    2、你用两个变量对常量进行初始化,你把编译器搞胡度了。 从结果来看, 它把常量当变量初始化了。
    最好常量EEPROM的值自己初始化,FF无所谓,要有初始化函数,这样便于调试和测试

    该用户从未签到

    6

    主题

    48

    帖子

    0

    新手上路

    Rank: 1

    积分
    51
    最后登录
    1970-1-1
    发表于 2012-11-3 20:54:54 | 显示全部楼层

    回复:经验分享--Flash模拟EEPROM编程中的两个小问题

    mark
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    3

    主题

    151

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    396
    最后登录
    2020-6-22
    发表于 2012-11-7 11:31:53 | 显示全部楼层

    RE:经验分享--Flash模拟EEPROM编程中的两个小问题


    .volatile的意思是提醒编译器,变量有可能会在程序没有对它进行修改,但是它的值有可能变化,一般是对SFR声明,比如PORT口的输入值。你的变量用volative来声明,不是很合适。我觉得你的现象应该是优化级别太高造成的。

    2、你用两个变量对常量进行初始化,你把编译器搞胡度了。 从结果来看, 它把常量当变量初始化了。
    最好常量EEPROM的值自己初始化,FF无所谓,要有初始化函数,这样便于调试和测试
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    0

    主题

    15

    帖子

    0

    新手上路

    Rank: 1

    积分
    19
    最后登录
    1970-1-1
    发表于 2012-11-8 15:28:20 | 显示全部楼层

    回复:经验分享--Flash模拟EEPROM编程中的两个小问题

    回复第 4 楼 于2011-07-05 16:10:19发表:
    1.volatile的意思是提醒编译器,变量有可能会在程序没有对它进行修改,但是它的值有可能变化,一般是对SFR声明,比如PORT口的输入值。你的变量用volative来声明,不是很合适。我觉得你的现象应该是优化级别太高造成的。
     
    2、你用两个变量对常量进行初始化,你把编译器搞胡度了。 从结果来看, 它把常量当变量初始化了。
    最好常量EEPROM的值自己初始化,FF无所谓,要有初始化函数,这样便于调试和测试
     

    大牛
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    8

    主题

    39

    帖子

    0

    注册会员

    Rank: 2

    积分
    121
    最后登录
    1970-1-1
     楼主| 发表于 2014-2-28 14:56:45 | 显示全部楼层

    回复:经验分享--Flash模拟EEPROM编程中的两个小问题

    回复第 4 楼 于2011-07-05 16:10:19发表:
    1.volatile的意思是提醒编译器,变量有可能会在程序没有对它进行修改,但是它的值有可能变化,一般是对SFR声明,比如PORT口的输入值。你的变量用volative来声明,不是很合适。我觉得你的现象应该是优化级别太高造成的。
     
    2、你用两个变量对常量进行初始化,你把编译器搞胡度了。 从结果来看, 它把常量当变量初始化了。
    最好常量EEPROM的值自己初始化,FF无所谓,要有初始化函数,这样便于调试和测试
     

    不懂别乱说行么
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    0

    主题

    318

    帖子

    0

    高级会员

    Rank: 4

    积分
    880
    最后登录
    2018-2-27
    发表于 2016-8-6 22:12:53 | 显示全部楼层

    学习学习,看看学习
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-7-22 01:01 , Processed in 0.103005 second(s), 30 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

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