11085|5

75

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

keil全局变量初始化值改变的问题 [复制链接]

正在用keil for arm学习LPC2312,用proteus联调

我在main.c中定义了一个全局变量led_flag和led_taber[16]的数组,
我主要是要完成用LPC2312的p0.0-p0.6这7个口作为输出来控制7段数码管显示0 1 2 …E F十六个数字
用p0.7,p0.9作为外部中断输入,通过按键改变电平,然后触发中断,在中断中把数码管的数值显示加1或者减1
led_flag主要用来记录当前显示的数值,进入中断后都是以led_flag为基数来做加1或者减1,所以led_flag要设置为全局变量,而且程序运行的过程中要能够改变
led_tabel是数码管显示的对照表

现在就是有个问题:
当我在main.c文件的开头定义
long led_flag=0x0;
int led_taber[16]={   0x3F, 0x06 ,0x5B,  0x4F,
                      0x66, 0x6D ,0x7D,  0x07,
                      0x7F, 0x67,0x77,  0x7C,
                      0x39, 0x5E,0x79,  0x71,
                   }  ;
时,在调试的过程中发现led_flag这个数值并不是0,而是一个很奇怪的数字(好像是0xE00F……什么的,没有细看),led_taber数组中数据全部变成0xAAAAAAAA,为何数据会改变,

后来在led_tabel前加上const才解决led_tabel的值没有变化,但是led_flag数值在运行中需要改变,所以不能加const,只要在进入main()时先给led_flag赋值0,修正一下。

问题虽然是解决了,但是至于定义的全局变量的值为何会改变,到现在还是想不明白
希望高手解答,帮忙
谢谢


代码如下:

  1. #include "lpc21xx.h"
  2. long led_flag;   //在这里初始化没用,编译后发现值改变了
  3. const int led_taber[16]={   0x3F, 0x06 ,0x5B,  0x4F,   //加上const才解决问题
  4.                       0x66, 0x6D ,0x7D,  0x07,
  5.                       0x7F, 0x67,0x77,  0x7C,
  6.                       0x39, 0x5E,0x79,  0x71,
  7.                    }  ;


  8. void Led_Add()
  9. {
  10.         Ext->INT=0x04;
  11.         led_flag++;
  12.         led_flag%=16;
  13.         Gpio->PIN= led_taber[led_flag];
  14.                        
  15. }
  16. void Led_Sub()
  17. {
  18.         Ext->INT=0x08;
  19.         led_flag--;
  20.         led_flag=(led_flag+16)%16;
  21.         Gpio->PIN= led_taber[led_flag];
  22. }

  23. void Init()
  24. {
  25.         Pin->SEL0=0x000cc000;//P0.7 P0.9设为EINT2,3

  26.         Gpio->DIR=0x7F;//P0.0-P0.6设置为输出

  27.         Ext->MODE=ExtMode2|ExtMode3;
  28.         Ext->POLAR=ExtPolar2|ExtPolar3;
  29.            Vic->IntEnable=(1<
  30.         Vic->VectCntl[0]=0x20|VicEint2;
  31.         Vic->VectAddr[0]=(u32)Led_Add;  //递增
  32.         Vic->VectCntl[1]=0x20|VicEint3;
  33.         Vic->VectAddr[1]=(u32)Led_Sub;  //递减
  34.                        

  35. }


  36. int main()
  37. {
  38.         Init();
  39.         led_flag=0; //在这里重新赋值,修正一下
  40.         Gpio->PIN= led_taber[led_flag];
  41.         while(1);
  42.         return 1;
  43. }

复制代码


下面是自己写的lpc21xx.h头文件

  1. typedef         unsigned long        u32;
  2. typedef                unsigned short        u16;
  3. typedef                unsigned char        u8;        

  4. typedef         struct
  5. {
  6.         u32                SEL0;
  7.         u32                SEL1;
  8.         u32                SEL2;
  9. }PIN;

  10. #define Pin                ((PIN*)0xe002c000)        //管脚选择寄存器

  11. typedef         struct
  12. {
  13.         u32                PIN;
  14.         u32                SET;
  15.         u32                DIR;
  16.         u32                CLR;
  17. }GPIO;

  18. #define Gpio        ((GPIO*)0xe0028000)

  19. typedef         struct
  20. {
  21.         u32                INT;
  22.         u32                WAKE;
  23.         u32                MODE;
  24.         u32                POLAR;
  25. }EXT;

  26. #define Ext                        ((EXT*)0xe01fc140)
  27. #define ExtInt0          0x1
  28. #define ExtInt1                0x2
  29. #define ExtInt2                0x4
  30. #define ExtInt3                0x8

  31. #define ExtWake0        0x1
  32. #define ExtWake1        0x2
  33. #define ExtWake2        0x4
  34. #define ExtWake3        0x8
  35. #define BodWake                (0x1<<14)
  36. #define RtcWake                (0x1<<15)

  37. #define ExtMode0        0x1
  38. #define ExtMode1        0x2
  39. #define ExtMode2        0x4
  40. #define ExtMode3        0x8

  41. #define ExtPolar0        0x1
  42. #define ExtPolar1        0x2
  43. #define ExtPolar2        0x4
  44. #define ExtPolar3        0x8               

  45. typedef         struct
  46. {
  47.         u32                IrqStatus;
  48.         u32                FiqStatus;
  49.         u32                RawIntr;
  50.         u32                IntSelect;
  51.         u32                IntEnable;
  52.         u32                IntEnClr;
  53.         u32                SoftInt;
  54.         u32                SoftIntClear;
  55.         u32                Protection;
  56.         u32                rsv1[3];
  57.         u32                CurVectAddr;
  58.         u32                DefVectAddr;
  59.         u32                rsv2[50];
  60.         u32                VectAddr[16];
  61.         u32                rsv3[48];
  62.         u32                VectCntl[16];
  63. }VIC;

  64. #define Vic                ((VIC*)0xfffff000)

  65. #define VicWdt                        0
  66. #define VicSwi                        1
  67. #define VicDbgCommRx        2
  68. #define VicDbgCommTx        3
  69. #define VicTmr0                        4
  70. #define VicTmr1                        5
  71. #define VicUart0                6
  72. #define VicUart1                7
  73. #define VicPwm0                        8
  74. #define VicI2c0                        9
  75. #define VicSpi0                        10
  76. #define VicSpi1                        11
  77. #define VicPll                        12
  78. #define VicRtc                        13
  79. #define VicEint0                14
  80. #define VicEint1                15
  81. #define VicEint2                16
  82. #define VicEint3                17
  83. #define VicAd0                        18
  84. #define VicI2c1                        19
  85. #define VicBod                        20
  86. #define VicAd1                        21
复制代码

最新回复

MDK4.7 也遇到了这个问题!! 而且变量放到另外一个文件就正常了。 ???  详情 回复 发表于 2014-12-5 15:45
点赞 关注

回复
举报

72

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
简单的讲一下原理。在嵌入式系统中,全局变量的初始化是在系统启动的过程中来做的。做法其实很简单,就是把外存(ROM或Flash等存放CODE的介质)中的全局变量空间拷贝到内存中的全局变量空间映像中。如果没有这一步正确的从外存到内存的拷贝工作,你的全局变量是没有初始化值的。

编译器如果没有生成这步代码,那你的全局变量就都是没有办法初始化的。

用const为啥能解决问题呢?因为const型的变量被Keil直接放到了外存中,也就是放到了代码段中。以后使用const实际不是访问内存而是外存!

现在说你的全局变量初始化的问题解决方案:
1. 研究编译结果,看全局变量的初值被放在了code段的哪个位置,以及全局变量在内存中的位置定义,然后在初始化过程中——进入main函数之前,把这些值拷贝过来。因为编译器是按照段来处理全局变量的,所以所有全局变量的相对位置都是一一对应的,用memcpy就可以了。
2. 不要在全局变量中这样初始化,而是通过函数来初始化,在main函数的开头用init函数来初始化所有的全局变量。

 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
RVMDK没这个问题哦~
 
 
 

回复

96

帖子

0

TA的资源

一粒金砂(初级)

4
 
QQ:530405158
我也遇到了这样的问题
谢谢!
 
 
 

回复

69

帖子

0

TA的资源

一粒金砂(初级)

5
 
碰到同样的问题
 
 
 

回复

15

帖子

3

TA的资源

一粒金砂(初级)

6
 
MDK4.7 也遇到了这个问题!!
而且变量放到另外一个文件就正常了。
???
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表