赞
踩
所谓的作用域就是指变量起作用的范围,也是变量的有效范围。变量按他的作用域可以 分为局部变量和全局变量。
在一个函数内部声明的变量是内部变量,它只在本函数内有效,在本函数以外是不能使 用的,这样的变量就是局部变量。
在函数外声明的变量就是全局变量。一个源程序文件可以包含一个或者多个函数,全局 变量的作用范围是从它开始声明的位置一直到程序结束。
定义全局变量会永久占用单片机的内存单元,而局部变量只有进入定义局部变量的 函数时才会占用内存单元,函数退出后会自动释放所占用的内存。所以大量的全局变量会额 外增加内存消耗。
全局变量的应用会降低函数的通用性,函数在执行的时候过多依赖于全局变量,不 利于函数的重复利用。
全局变量可以被作用域内所有的函数直接引用,可以增加函数间数据联系的途径, 但同时加强了函数模块之间的数据联系,使这些函数的独立性降低,对其中任何一个函数的 修改都可能会影响到其它函数的执行结果,函数之间过于紧密的联系不利于程序的维护的。
变量的存储类别分为自动、静态、寄存器和外部这四种。
函数中的局部变量,如果不加 static 这个关键字来修饰,都属于自动变量,也叫做动态 存储变量。这种存储类别的变量,在调用该函数的时候系统会给他们分配存储空间,在函数 调用结束后会自动释放这些存储空间。动态存储变量的关键字是 auto,但是这个关键字是可 以省略的
那么与动态变量对应的就是静态变量。首先,全局变量均是静态变量,此外,还有一种 特殊的局部变量也是静态变量。即我们在定义局部变量时前边加上 static 这个关键字,加上 这个关键字的变量就称之为静态局部变量,它的特点是,在整个生存期中只赋一次初值,在 第一次执行该函数时,它的值就是给定的那个初值,而之后在该函数所有的执行次数中,它 的值都是上一次函数执行结束后的值,即它可以保持前次的执行结果。
- #include <reg52.h>
-
- sbit ADDR0 = P1^0;
- sbit ADDR1 = P1^1;
- sbit ADDR2 = P1^2;
- sbit ADDR3 = P1^3;
- sbit ENLED = P1^4;
-
- unsigned char code LedChar[] = { //数码管显示字符转换表
- 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
- 0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
- };
- unsigned char LedBuff[6] = { //数码管显示缓冲区,初值0xFF确保启动时都不亮
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
- };
- unsigned char flag1s = 0; //1秒定时标志
-
- void main()
- {
- unsigned long sec = 0; //记录经过的秒数
-
- EA = 1; //使能总中断
- ENLED = 0; //使能U3,选择控制数码管
- ADDR3 = 1; //因为需要动态改变ADDR0-2的值,所以不需要再初始化了
- TMOD = 0x01; //设置T0为模式1
- TH0 = 0xFC; //为T0赋初值0xFC67,定时1ms
- TL0 = 0x67;
- ET0 = 1; //使能T0中断
- TR0 = 1; //启动T0
-
- while (1)
- {
- if (flag1s == 1) //判断1秒定时标志
- {
- flag1s = 0; //1秒定时标志清零
- sec++; //秒计数自加1
- //以下代码将sec按十进制位从低到高依次提取并转为数码管显示字符
- LedBuff[0] = LedChar[sec%10];
- LedBuff[1] = LedChar[sec/10%10];
- LedBuff[2] = LedChar[sec/100%10];
- LedBuff[3] = LedChar[sec/1000%10];
- LedBuff[4] = LedChar[sec/10000%10];
- LedBuff[5] = LedChar[sec/100000%10];
- }
- }
- }
- /* 定时器0中断服务函数 */
- void InterruptTimer0() interrupt 1
- {
- static unsigned char i = 0; //动态扫描的索引,定义为局部静态变量
- static unsigned int cnt = 0; //记录T0中断次数,定义为局部静态变量
-
- TH0 = 0xFC; //重新加载初值
- TL0 = 0x67;
- cnt++; //中断次数计数值加1
- if (cnt >= 1000) //中断1000次即1秒
- {
- cnt = 0; //清零计数值以重新开始下1秒计时
- flag1s = 1; //设置1秒定时标志为1
- }
- //以下代码完成数码管动态扫描刷新
- P0 = 0xFF; //显示消隐
- switch (i)
- {
- case 0: ADDR2=0; ADDR1=0; ADDR0=0; i++; P0=LedBuff[0]; break;
- case 1: ADDR2=0; ADDR1=0; ADDR0=1; i++; P0=LedBuff[1]; break;
- case 2: ADDR2=0; ADDR1=1; ADDR0=0; i++; P0=LedBuff[2]; break;
- case 3: ADDR2=0; ADDR1=1; ADDR0=1; i++; P0=LedBuff[3]; break;
- case 4: ADDR2=1; ADDR1=0; ADDR0=0; i++; P0=LedBuff[4]; break;
- case 5: ADDR2=1; ADDR1=0; ADDR0=1; i=0; P0=LedBuff[5]; break;
- default: break;
- }
- }
在图中大方框外侧的就是 点阵 LED 的引脚号,左侧的 8 个引脚是接的内部 LED 的阳极,上侧的 8 个引脚接的是内部 LED 的阴极。那么如果我们把 9 脚置成高电平、13 脚置成低电平的话,左上角的那个 LED 小灯就会亮了。
- #include <reg52.h>
-
- sbit LED = P0^0;
- sbit ADDR0 = P1^0;
- sbit ADDR1 = P1^1;
- sbit ADDR2 = P1^2;
- sbit ADDR3 = P1^3;
- sbit ENLED = P1^4;
-
- void main()
- {
- ENLED = 0; //U3、U4两片74HC138总使能
- ADDR3 = 0; //使能U4使之正常输出
- ADDR2 = 0; //经U4的Y0输出开启三极管Q10
- ADDR1 = 0;
- ADDR0 = 0;
- LED = 0; //向P0.0写入0来点亮左上角的一个点
- while(1); //程序停止在这里
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。