1)函数的概念
函数是能够实现特定功能的代码段。一个C51程序通常由一个主函数和若干个子函数构成。其中,主函数即main()函数。C51程序的执行总是从main函数开始,完成对其他函数的调用后再返回到主函数,最后由main函数结束整个程序。一个C51源程序必须有且只有一个主函数main()。除了主函数外,C51程序还提供了极为丰富的库函数,并允许用户自定义函数。在C51程序中,由主函数调用其他函数,其他函数之间也可以相互调用。同一个函数可以被一个或多个函数调用任意次。
在使用C51函数时,需要注意的是:
①C51的源程序的函数数目是不限的。
②在一个函数的函数体内,不能再定义另一个函数,即不能嵌套定义。
③函数之间允许相互调用,也允许嵌套调用。
④函数还可以自己调用自己,称为递归调用。
2)函数的分类
(1)按用户使用的角度分类
从用户使用的角度来划分,C51语言的函数可分为库函数和用户自定义函数两种。库函数由C系统提供,用户不需要定义而直接使用它们,也不必在程序中作类型说明,只需在程序前注明包含该函数原型的头文件,便可以在程序中直接调用;用户自定义函数是由用户根据需要编写的函数,对于用户自定义函数,不仅要在程序中定义函数本身,而且在主调函数模块中还必须对被调用函数进行类型说明,然后才能使用(即必须先定义后使用)。
(2)按有无返回值的角度分类
按有无返回值的角度来划分,可把C51函数分为有返回值函数和无返回值函数两种。有返回值函数就是此类函数被调用执行完后,将向调用者返回一个执行结果,称函数返回值。库函数包含多个带有返回值的函数。另外,由用户定义的这种有返回函数值的函数,必须在函数定义和函数说明中明确返回值的类型。无返回值函数相当于其他高级语言中的过程,常用于完成某项特定的任务,执行完成后不向调用者返回函数值。库函数包含多个不带有返回值的函数。对于用户自定义的无返回值函数,可指定它的返回为“无值型”,其类型说明符为“void”。
(3)按主调函数和被调函数之间数据传送的角度分类
按主调函数和被调函数之间数据传送的角度划分,可把C51函数分为无参函数和有参函数两种。无参函数是指主调函数和被调函数之间不进行参数传送,因此,在函数定义、函数说明及函数调用中可以不带参数。此类函数通常用来完成一组指定的功能,可以带有返回值,也可以没有返回函数值。有参函数是指主调函数和被调函数之间存在参数传送,因此,在函数定义及函数说明时都需要有参数,称“形式参数”(简称“形参”)。在主调函数中进行函数调用时也必须给出参数,称“实际参数”(简称“实参”)。在函数调用时,主调函数将把实参的值传送给形参,供被调函数使用。有参函数可以带有返回值,也可以不带有返回值。
3)函数的定义
函数定义的一般格式如下:
前面部分是函数的首部,后面是函数体。
(1)函数首部
函数类型和函数名为函数首部。函数类型指明了本函数的类型,它实际上是函数返回值的类型。如果不要求函数有返回值,此时函数类型可以写为void。
(2)函数名
函数名是由用户定义的标识符,规定同变量名,应简洁好记。函数名后有一对圆括号,其中若无参数,括号也不可少,在C51语言中“()”一般是函数的标志。
(3)函数体
“{}”中的内容称为函数体。函数体由两部分组成:一是类型说明,即声明部分,是对函数体内部所用到的变量的类型说明;二是语句,即执行部分。
(4)reentrant修饰符
该修饰符用于把函数定义为可重入函数,就是允许被递归调用。函数的递归调用实际上是函数嵌套调用的一种特殊情况。一个函数直接或间接地调用了它本身,就被称为函数的递归调用。
(5)interrupt m修饰符
interrupt m修饰符是C51函数中非常重要的一个修饰符,这是因为中断函数必须通过它进行修饰。C51的中断过程通过使用interrupt关键字和中断m(0~31)来实现,中断号对应51单片机的入口地址见表3.6。
(6)using n修饰符
using n修饰符用于指定中断服务程序使用的工作寄存器组,其中n的值为1~3,表示寄存器号。对于using n的使用,要注意两点:一是加入using n后,所有被中断调用的过程必须使用同一个寄存器组;二是using n修饰符不能用于有返回值的函数,其原因是C51函数的返回值是放在寄存器中的。
4)函数调用与返回函数值
中断号与中断源的对应关系见表3.6。
表3.6 中断号与中断源的对应关系
(www.xing528.com)
(1)函数调用
函数的调用是指函数在主调函数中的调用形式。在C51语言中,函数调用的一般形式如下:
函数名(实参列表)
其中,函数名即被调用的函数,实参列表是主调函数传递给被调函数的数据。通常函数有以下3种调用方式。
①函数语句:把函数作为一个语句,主要用于无返回值的函数。例如:
delay();
②函数表达式:函数出现在表达式中,主要用于有返回值的函数,将返回值赋值给变量。例如:
c=min(x,y); //函数min求x、y中的最小值
③函数参数:函数作为另一个函数的实参,主要用于函数的嵌套调用。例如:
c=min(x,min(y,z));//函数min求x、y、z中的最小值
赋值调用与引用调用是C51语言中最常用的参数传递方式,下面分别进行介绍。
a.赋值调用(call by value):这种方法中函数的形参是数值变量,函数调用时把参数的值复制到函数的形式参数中,赋值调用不会影响主调函数中的变量的数值。
b.引用调用(call by reference):这种方法中函数的形参是指针,函数调用时把参数的地址复制给形式参数。在函数中,这个地址用来访问调用中所使用的实际参数,引用调用将会影响主调函数中变量的数值。
(2)返回函数值(return)
return语句一般放在函数的最后位置,用于终止函数的执行,并控制程序返回调用该函数时所处的位置。返回时还可以通过return语句带回返回值。return语句格式有两种:
①return;
②return(表达式);
如果return语句后面带有表达式,则要计算表达式的值,并将表达式的值作为函数的返回值;若不带表达式,则函数返回时将返回一个不确定的值。通常使用return语句可把调用函数取得的值返回给主调用函数。
知识拓展
一般循环延时,使用12 MHz的晶振要方便一些,如果是定时器,则用11.059 2 MHz的晶振更方便、精确。关于单片机C语言的精确延时,很多是估算的延时值,而非准确值,而51核给出的延时函数克服了以上缺点,能够精确计算出延时值且精确达到1 μs。例如:
i=100,j=250,T=1 μs时,延时时间=50.301 ms,通过示波器验证。
下面给出几种常见的C语言延时程序。
(1)10 ms延时子程序(12 MHz):
(2)1 s延时子程序(12 MHz):
(3)200 ms延时子程序(12 MHz):
(4)500 ms延时子程序(12 MHz):
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。