keil全局变量初始化值改变的问题

时间:2022-08-04 19:41:09
正在用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,修正一下。

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


代码如下:

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


void Led_Add()
{
Ext->INT=0x04;
led_flag++;
led_flag%=16;
Gpio->PIN= led_taber[led_flag];

}
void Led_Sub()
{
Ext->INT=0x08;
led_flag--;
led_flag=(led_flag+16)%16;
Gpio->PIN= led_taber[led_flag];
}

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

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

Ext->MODE=ExtMode2|ExtMode3;
Ext->POLAR=ExtPolar2|ExtPolar3;
    Vic->IntEnable=(1<<VicEint2)|(1<<VicEint3);
Vic->VectCntl[0]=0x20|VicEint2;
Vic->VectAddr[0]=(u32)Led_Add;  //递增
Vic->VectCntl[1]=0x20|VicEint3;
Vic->VectAddr[1]=(u32)Led_Sub;  //递减


}
 

int main()
{
Init();
led_flag=0; //在这里重新赋值,修正一下
Gpio->PIN= led_taber[led_flag];
while(1);
return 1;
}



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

typedef  unsigned long u32;
typedef unsigned short u16;
typedef unsigned char u8; 

typedef  struct
{
u32 SEL0;
u32 SEL1;
u32 SEL2;
}PIN;

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

typedef  struct
{
u32 PIN;
u32 SET;
u32 DIR;
u32 CLR;
}GPIO;

#define Gpio ((GPIO*)0xe0028000)

typedef  struct
{
u32 INT;
u32 WAKE;
u32 MODE;
u32 POLAR;
}EXT;

#define Ext ((EXT*)0xe01fc140)
#define ExtInt0   0x1
#define ExtInt1 0x2
#define ExtInt2 0x4
#define ExtInt3 0x8

#define ExtWake0 0x1
#define ExtWake1 0x2
#define ExtWake2 0x4
#define ExtWake3 0x8
#define BodWake (0x1<<14)
#define RtcWake (0x1<<15)

#define ExtMode0 0x1
#define ExtMode1 0x2
#define ExtMode2 0x4
#define ExtMode3 0x8

#define ExtPolar0 0x1
#define ExtPolar1 0x2
#define ExtPolar2 0x4
#define ExtPolar3 0x8

typedef  struct
{
u32 IrqStatus;
u32 FiqStatus;
u32 RawIntr;
u32 IntSelect;
u32 IntEnable;
u32 IntEnClr;
u32 SoftInt;
u32 SoftIntClear;
u32 Protection;
u32 rsv1[3];
u32 CurVectAddr;
u32 DefVectAddr;
u32 rsv2[50];
u32 VectAddr[16];
u32 rsv3[48];
u32 VectCntl[16];
}VIC;

#define Vic ((VIC*)0xfffff000)

#define VicWdt 0
#define VicSwi 1
#define VicDbgCommRx 2
#define VicDbgCommTx 3
#define VicTmr0 4
#define VicTmr1 5
#define VicUart0 6
#define VicUart1 7
#define VicPwm0 8
#define VicI2c0 9
#define VicSpi0 10
#define VicSpi1 11
#define VicPll 12
#define VicRtc 13
#define VicEint0 14
#define VicEint1 15
#define VicEint2 16
#define VicEint3 17
#define VicAd0 18
#define VicI2c1 19
#define VicBod 20
#define VicAd1 21

4 个解决方案

#1


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

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

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

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

#2


RVMDK没这个问题哦~

#3


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

#4


碰到同样的问题

#1


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

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

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

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

#2


RVMDK没这个问题哦~

#3


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

#4


碰到同样的问题