1.static
static一般不用在主函数中,大多数在中断函数和封装好的子函数里运用,它的作用是保证在子函数或中断函数中定义的变量每次调用完之后都可以保持调用完时候的值,《手把手教你学51单片机》文档7.2节有这个知识点的讲解,不过我们还是用代码来解释这个static的作用吧。
2.举例
我们要实现像第四章第2讲的实验现象让数码管0从0到F循环显示。本次我们用的是函数封装,代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | #include <reg52.h> sbit ADDR2 = P1^2; sbit ADDR1 = P1^1; sbit ADDR0 = P1^0; sbit ENLED = P1^4; sbit ADDR3 = P1^3; unsigned char code LedChar[16]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E}; //数码管状态值初始化 void delay_ms(unsigned int x) { unsigned int i,j; if (x==1000) { for (i=0;i<19601;i++) //延时1s { for (j=5;j>0;j--); } } else while (x--) for (j=115;j>0;j--); } void SEG0_task() { unsigned char i=0; P0=LedChar[i]; i++; if (i>=16)i=0; //让i在0~15之间变化 } void main() { ADDR3 = 1; //使能三八译码器 ENLED = 0; // ADDR2 = 0; //************************** ADDR1 = 0; //只让数码管0显示 ADDR0 = 0; //************************** while (1) { SEG0_task(); delay_ms(1000); //延时1s } } |
我们看到的是数码管0一直显示0,这是因为主函数的死循环里每次调用“SEG0_task()”时开头i的值都被初始化为0了,虽然第一次调用完这个函数时,已经执行过“i++;”,但是第二次调用该函数时i又被初始化为0了,导致永远执行的是“P0= LedChar[0];”
而我们只要在SEG0_task()函数中加上static的关键字去定义i,就可以使i成为局部静态变量,从而实现变量在函数调用结束之后仍然保持着当前的值,第二次调用该函数时不会被再次初始化为0。
代码修改如下
1 | static unsigned char i=0; |
这样就可以实现我们想要的实验现象了。
3.回归按键
按键的执行任务也可以封装为函数,同样需要static去定义key_up,因为它需要跟着KEY4变化,而不是每次都被初始化为同一个值。
代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | #include <reg52.h> sbit ADDR2 = P1^2; sbit ADDR1 = P1^1; sbit ADDR0 = P1^0; sbit ENLED = P1^4; sbit ADDR3 = P1^3; sbit LED2 = P0^0; sbit KEY4 = P2^7; void delay_ms(unsigned int x) { unsigned int i,j; if (x==1000) { for (i=0;i<19601;i++) //延时1s { for (j=5;j>0;j--); } } else while (x--) for (j=115;j>0;j--); } void KEY_task() { static unsigned char key_up=1; if (key_up==0) { if (KEY4==1) //不支持连按 { LED2 = !LED2; } } key_up=KEY4; //如果不松手,key_up就会等于0 } void main() { ADDR3 = 1; //使能三八译码器 ENLED = 0; // ADDR2 = 1; //************ ADDR1 = 1; //只让小灯显示 ADDR0 = 0; //************ P2 = 0xF7; //让K4能具备有被拉低的条件先 while (1) { KEY_task(); //按键功能任务 delay_ms(2); //假设这部分是要执行的其他程序 } } |
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程