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

liuwei84 2008-07-09 02:04:46
正在用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

...全文
1848 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
pyjsp 2009-07-29
  • 打赏
  • 举报
回复
碰到同样的问题
eric821115 2009-02-16
  • 打赏
  • 举报
回复
QQ:530405158
我也遇到了这样的问题
谢谢!
ly_liuyang 2008-07-11
  • 打赏
  • 举报
回复
RVMDK没这个问题哦~
fouryu 2008-07-09
  • 打赏
  • 举报
回复 2
简单的讲一下原理。在嵌入式系统中,全局变量的初始化是在系统启动的过程中来做的。做法其实很简单,就是把外存(ROM或Flash等存放CODE的介质)中的全局变量空间拷贝到内存中的全局变量空间映像中。如果没有这一步正确的从外存到内存的拷贝工作,你的全局变量是没有初始化值的。

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

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

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

实验一 搭建实验环境 一.实验简介 搭建嵌入式系统开发环境,建立第一个工程,流水灯实验 二.实验目的 掌握STM32开发环境,掌握从无到有的构建工程。 三.实验内容 熟悉MDK KEIL开发环境,构建基于固件库的工程,编写代码实现流水灯工程。通过ISP下载代码到 实验板,查看运行结果。下载代码到目标板,查看运行结果。 四.实验设备 硬件部分:PC计算机(宿主机)、STM32实验板。 软件部分:PC机WINDOWS系统、MDK KEIL软件、ISP软件。 五.实验步骤 1. 熟悉MDK KEIL开发环境 2. 熟悉串口编程软件ISP 3. 查看固件库结构和文件 4. 建立工程目录,复制库文件 5. 建立和配置工程 6. 编写代码 7. 编译代码 8. 使用ISP下载到实验板 9. 测试运行结果 10. 记录实验过程,撰写实验报告 六.实验结果及测试 七.实验总结 实验二 按键实验(查询方式) 一.实验简介 在实验一的基础上,使用按键控制流水灯速度,及使用按键控制流水灯流水方向。 二.实验目的 熟练使用库函数操作GPIO,掌握利用查询方式控制按键的程序编写方法。 三.实验内容 实现初始化GPIO,并配置中断,在中断服务程序中通过修改全局变量,达到控制流水 灯速度及方向。 四.实验设备 硬件部分:PC计算机(宿主机)、STM32实验板。 软件部分:PC机WINDOWS系统、MDK KEIL软件、ISP软件。 五.实验步骤 1在实验一代码的基础上,编写按键控制部分代码 2编写完成主程序 4编译代码,下载到实验板 5.单步调试 6记录实验过程,撰写实验报告 六.实验结果及测试 七.实验总结 实验三 按键实验(中断方式) 一.实验简介 在实验一的基础上,使用按键控制流水灯。 二.实验目的 熟练使用库函数操作GPIO,掌握中断配置和中断服务程序编写方法,掌握通过全局变 量在中断服务程序和主程序间通信的方法。 三.实验内容 实现初始化GPIO,并配置中断,在中断服务程序中通过修改全局变量,达到控制流水 灯速度及方向。 下载代码到目标板,查看运行结果。 四.实验设备 硬件部分:PC计算机(宿主机)、STM32实验板。 软件部分:PC机WINDOWS系统、MDK KEIL软件、ISP软件。 五.实验步骤 1在实验一代码的基础上,编写中断初始化代码 2在主程序中声明全局变量,用于和中断服务程序通信,编写完成主程序 3编写中断服务程序 4编译代码,下载到实验板 5.单步调试 6记录实验过程,撰写实验报告 六.实验结果及测试 七.实验总结 实验四 串口发送和接收实验 一.实验简介 编写代码实现串口发送和接收,将通过串口发送来的数据回送回去。 二.实验目的 掌握STM32基本串口编程,进一步学习中断处理。 三.实验内容 编写主程序,初始化串口1,设置波特率为115200,无校验,数据位8位,停止位1位。 编写中断服务程序代码实现将发送过来的数据回送。 四.实验设备 硬件部分:PC计算机(宿主机)、STM32实验板。 软件部分:PC机WINDOWS系统、MDK KEIL软件、ISP软件、串口调试助手。 五.实验步骤 1编写串口初始化代码 2编写中断服务程序代码 3编译代码,使用ISP下载到实验板 4记录实验过程,撰写实验报告 六.实验结果及测试 七.实验总结 实验五 ADC实验 一.实验简介 通过ADC将STM32系统将模拟量转换为数字量。 二.实验目的 掌握ADC编程。 三.实验内容 重新实现C库中的printf()函数到串口1。 四.实验设备 硬件部分:PC计算机(宿主机)、STM32实验板。 软件部分:PC机WINDOWS系统、MDK KEIL软件、ISP软件、串口调试助手。 五.实验步骤 1编写主程序 2编译代码,使用ISP下载到实验板,使用串口调试助手观察数据 3记录实验过程,撰写实验报告 六.实验结果及测试 七.实验总结 ----------------------- STM32实验报告全文共6页,当前为第1页。 STM32实验报告全文共6页,当前为第2页。 STM32实验报告全文共6页,当前为第3页。 STM32实验报告全文共6页,当前为第4页。 STM32实验报告全文共6页,当前为第5页。 STM32实验报告全文共6页,当前为第6页。

21,597

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 驱动开发/核心开发
社区管理员
  • 驱动开发/核心开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧