当前位置:   article > 正文

手把手教你学51单片机-变量进阶与点阵LED_51单片机中局部变量怎么表示

51单片机中局部变量怎么表示

变量的作用域

所谓的作用域就是指变量起作用的范围,也是变量的有效范围。变量按他的作用域可以 分为局部变量和全局变量。

局部变量

在一个函数内部声明的变量是内部变量,它只在本函数内有效,在本函数以外是不能使 用的,这样的变量就是局部变量。

全局变量

在函数外声明的变量就是全局变量。一个源程序文件可以包含一个或者多个函数,全局 变量的作用范围是从它开始声明的位置一直到程序结束。

定义全局变量会永久占用单片机的内存单元,而局部变量只有进入定义局部变量的 函数时才会占用内存单元,函数退出后会自动释放所占用的内存。所以大量的全局变量会额 外增加内存消耗。

全局变量的应用会降低函数的通用性,函数在执行的时候过多依赖于全局变量,不 利于函数的重复利用。

全局变量可以被作用域内所有的函数直接引用,可以增加函数间数据联系的途径, 但同时加强了函数模块之间的数据联系,使这些函数的独立性降低,对其中任何一个函数的 修改都可能会影响到其它函数的执行结果,函数之间过于紧密的联系不利于程序的维护的。

变量的存储类别

变量的存储类别分为自动、静态、寄存器和外部这四种。

函数中的局部变量,如果不加 static 这个关键字来修饰,都属于自动变量,也叫做动态 存储变量。这种存储类别的变量,在调用该函数的时候系统会给他们分配存储空间,在函数 调用结束后会自动释放这些存储空间。动态存储变量的关键字是 auto,但是这个关键字是可 以省略的

那么与动态变量对应的就是静态变量首先,全局变量均是静态变量,此外,还有一种 特殊的局部变量也是静态变量。即我们在定义局部变量时前边加上 static 这个关键字,加上 这个关键字的变量就称之为静态局部变量,它的特点是,在整个生存期中只赋一次初值,在 第一次执行该函数时,它的值就是给定的那个初值而之后在该函数所有的执行次数中,它 的值都是上一次函数执行结束后的值,即它可以保持前次的执行结果。

  1. #include <reg52.h>
  2. sbit ADDR0 = P1^0;
  3. sbit ADDR1 = P1^1;
  4. sbit ADDR2 = P1^2;
  5. sbit ADDR3 = P1^3;
  6. sbit ENLED = P1^4;
  7. unsigned char code LedChar[] = { //数码管显示字符转换表
  8. 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
  9. 0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
  10. };
  11. unsigned char LedBuff[6] = { //数码管显示缓冲区,初值0xFF确保启动时都不亮
  12. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
  13. };
  14. unsigned char flag1s = 0; //1秒定时标志
  15. void main()
  16. {
  17. unsigned long sec = 0; //记录经过的秒数
  18. EA = 1; //使能总中断
  19. ENLED = 0; //使能U3,选择控制数码管
  20. ADDR3 = 1; //因为需要动态改变ADDR0-2的值,所以不需要再初始化了
  21. TMOD = 0x01; //设置T0为模式1
  22. TH0 = 0xFC; //为T0赋初值0xFC67,定时1ms
  23. TL0 = 0x67;
  24. ET0 = 1; //使能T0中断
  25. TR0 = 1; //启动T0
  26. while (1)
  27. {
  28. if (flag1s == 1) //判断1秒定时标志
  29. {
  30. flag1s = 0; //1秒定时标志清零
  31. sec++; //秒计数自加1
  32. //以下代码将sec按十进制位从低到高依次提取并转为数码管显示字符
  33. LedBuff[0] = LedChar[sec%10];
  34. LedBuff[1] = LedChar[sec/10%10];
  35. LedBuff[2] = LedChar[sec/100%10];
  36. LedBuff[3] = LedChar[sec/1000%10];
  37. LedBuff[4] = LedChar[sec/10000%10];
  38. LedBuff[5] = LedChar[sec/100000%10];
  39. }
  40. }
  41. }
  42. /* 定时器0中断服务函数 */
  43. void InterruptTimer0() interrupt 1
  44. {
  45. static unsigned char i = 0; //动态扫描的索引,定义为局部静态变量
  46. static unsigned int cnt = 0; //记录T0中断次数,定义为局部静态变量
  47. TH0 = 0xFC; //重新加载初值
  48. TL0 = 0x67;
  49. cnt++; //中断次数计数值加1
  50. if (cnt >= 1000) //中断1000次即1秒
  51. {
  52. cnt = 0; //清零计数值以重新开始下1秒计时
  53. flag1s = 1; //设置1秒定时标志为1
  54. }
  55. //以下代码完成数码管动态扫描刷新
  56. P0 = 0xFF; //显示消隐
  57. switch (i)
  58. {
  59. case 0: ADDR2=0; ADDR1=0; ADDR0=0; i++; P0=LedBuff[0]; break;
  60. case 1: ADDR2=0; ADDR1=0; ADDR0=1; i++; P0=LedBuff[1]; break;
  61. case 2: ADDR2=0; ADDR1=1; ADDR0=0; i++; P0=LedBuff[2]; break;
  62. case 3: ADDR2=0; ADDR1=1; ADDR0=1; i++; P0=LedBuff[3]; break;
  63. case 4: ADDR2=1; ADDR1=0; ADDR0=0; i++; P0=LedBuff[4]; break;
  64. case 5: ADDR2=1; ADDR1=0; ADDR0=1; i=0; P0=LedBuff[5]; break;
  65. default: break;
  66. }
  67. }

 LED点阵 

 在图中大方框外侧的就是 点阵 LED 的引脚号,左侧的 8 个引脚是接的内部 LED 的阳极,上侧的 8 个引脚接的是内部 LED 的阴极。那么如果我们把 9 脚置成高电平、13 脚置成低电平的话,左上角的那个 LED 小灯就会亮了。

  1. #include <reg52.h>
  2. sbit LED = P0^0;
  3. sbit ADDR0 = P1^0;
  4. sbit ADDR1 = P1^1;
  5. sbit ADDR2 = P1^2;
  6. sbit ADDR3 = P1^3;
  7. sbit ENLED = P1^4;
  8. void main()
  9. {
  10. ENLED = 0; //U3、U4两片74HC138总使能
  11. ADDR3 = 0; //使能U4使之正常输出
  12. ADDR2 = 0; //经U4的Y0输出开启三极管Q10
  13. ADDR1 = 0;
  14. ADDR0 = 0;
  15. LED = 0; //向P0.0写入0来点亮左上角的一个点
  16. while(1); //程序停止在这里
  17. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/408700
推荐阅读
相关标签
  

闽ICP备14008679号