微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 51单片机基础剖析(基于C语言)

51单片机基础剖析(基于C语言)

时间:11-20 来源:互联网 点击:

extern int x;

void fun1( )

{

static int a=5; //静态变量只在第一次调用函数时赋值,退出函数时

//会保留上次的值,下次调用不再重新赋值。

int b=5;

printf(“%d %d %d |”,a,b,x);

a-=2;

b-=2

x-=2;

printf(“%d %d %d |”,a,b,x);

}

int fun2(int y)

{

return(35*x*y);

}

程序执行如果如下:

5 5 5 | 3 3 3

3 5 3 | 1 3 1

1 5 1 | -1 3 1

-1 35

注:C语言不允许在一个函数内嵌套定义另一个函数。为了能够访问不同文件中各个函数的变量,除了可以采用参数传递的方法外,还可以采用外部变量的方法,上面的例子就说了这一点。不过,尽管使用外部变量在不同函数之间传递数据有时比使用函数参数传递更为方便,不过当外部变量过多时,会增加程序的调试排错的困难。使得程序不便于维护。别外不通过参数传递直接在函数中改变全局变量的值,有时还会发生一些意想不到的副作用。因些最好还是使用函数参数来传递数据。

(3).寄存器变量(register)

为了提高程序的执行效率,C语言允许将一些频率最高的那些变量,定义为能够直接使用硬件寄存器的所谓的寄存器变量。定义一个变量时,在变量类型名前冠以“register” 即将该变量定义成为了寄存器变量。寄存器变量可以认为是一自动变量的一种。有效作用范围也自动变量相同。由于计算机寄存器中寄存器是有限的。不能将所有变量都定义成为寄存器变量,通常在程序中定义寄存器变量时,只是给编译器一个建议,该变量是否真正成为寄存器变量,要由编译器根据实际情况来确定。另一方面,C51编译器能够识别程序中使用频率最高的变量,在可能的情况下,即使程序中并未将该变量定义为寄存器变量,编译器也会自动将其作为寄存器变量处理。被定义的变量是否真正能成为寄存器变量,最终是由编译器决定的。

(4).静态变量(static)

使用存储种类说明符“static”定义的变量为静态变量,在上面模块2程序文件中使用了一个静态变量:static int a =5 ;由于这个变量是在函数fun1( )内部定义,因此称为内部静态变量或局部静态变量。局部静态变量始终都是存在的,但只有在定义它的函数内部进行访问,退出函数之后,变量的值仍然保持,但不能进行访问。

还有一种全局静态变量,它是在函数外部被定义的。作用范围从它的定义点开始,一直到程序结束,当一个C语言程序由若干个模块文件所组成时,全局静态变量始终存在,但它只能在被定义的模块文件中访问,其数据值可为该模块文件内的所有函数共享,退出该文件后,虽然变量的值仍然保持着,但不能被其它模块文件访问。在一个较大的程序中,这就方便了多人设计时,各自写的程序模块不会被别的模块文件所引用。全局静态变量和单纯的全局变量,在编译时就已经为期分配了固定的内存空间,只是他们的作用范围不同而已。局部静态变量是一种在两次函数调用之间仍能保持其值的局部变量。如下,局部变量的使用——计算度输出1~5的阶乘值。

#include

int fac( int n)

{

static int f=1;

f=f*n;

return(f);

}

main( )

{

int i;

for(i=1;i<=5;i++)

printf(“%d!=%d\n”,i,fac(i));

}

程序执行结果

1!=1

2!=2

3!=6

4!=24

5!=120

注:在这个程序中一共调用了5次计算阶乘的函数fac(i),每次调用后输出一个阶乘值i!,同时保留了这个i!值,以便下次再乘(i+1).由此可见,如果要保留函数上一次调用结束时的值,或是在初始化之后变量只被引用而不改变其值,则这时使用局部静态变量;较为方便,以免在每调用时都要重新进行赋值,但是,使用局部静态变量需要占用较多的内存空间,而且降低了程序的可读性,因此并不建议多用局部静态变量。

静态函数:

对于函数也可以定义成为具为静态存储种类的属性,定义函数时在函数名前冠以关键字static即将其定义为一个静态函数。例如static int func1(char x, y)函数是外部型的,使用静态函数可以使该函数只局限于当前定义它的模块文件中。其它模块文件是不能调用它的。换名话说,就是在其它模块文件中可以定义与静态函数完全同名的另一个函数。不会因为程序中存在相同的函数名而发生函数调用时的混乱。 这一点对于进行模块化程序设计是很有用的。

三、中断浅谈

0

外中断0

1

定时器0

2

外中断1

3

定时器1

4

串行口

定义中断函数如下

void timer1() interrupt 3

{

……

……

}

强烈建议:如上所述,定义中断函数时不要加using n选项。除非你对你的程序以及单片机的工作过程非常熟悉,否则会带来不必要的麻烦。具体原因由于篇幅的限制暂不讨论。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top