单片机C语言C51的函数
函 数
1. 函数的定义
函数定义的一般格式如下:
函数类型 函数名(形式参数表) [reentrant][interrupt m][using n]
形式参数说明
{
局部变量定义
函数体
}
前面部件称为函数的首部,后面称为函数的尾部,格式说明:
1).函数类型
函数类型说明了函数返回值的类型。
2).函数名
函数名是用户为自定义函数取的名字以便调用函数时使用。
3).形式参数表
形式参数表用于列录在主调函数与被调用函数之间进行数据传递的形式参数。
【例】定义一个返回两个整数的最大值的函数max()。
int max(int x,int y)
{ int z;
z=x>y?x:y;
return(z);
}
也可以用成这样:
int max(x,y)
int x,y;
{ int z;
z=x>y?x:y;
return(z);
}
4).reentrant修饰符
这个修饰符用于把函数定义为可重入函数。所谓可重入函数就是允许被递归调用的函数。函数的递归调用是指当一个函数正被调用尚未返回时,又直接或间接调用函数本身。一般的函数不能做到这样,只有重入函数才允许递归调用。
关于重入函数,注意以下几点:
(1)用reentrant修饰的重入函数被调用时,实参表内不允许使用bit类型的参数。函数体内也不允许存在任何关于位变量的操作,更不能返回bit类型的值。
(2)编译时,系统为重入函数在内部或外部存储器中建立一个模拟堆栈区,称为重入栈。重入函数的局部变量及参数被放在重入栈中,使重入函数可以实现递归调用。
(3)在参数的传递上,实际参数可以传递给间接调用的重入函数。无重入属性的间接调用函数不能包含调用参数,但是可以使用定义的全局变量来进行参数传递。
5).interrupt m修饰符
interrupt m是C51函数中非常重要的一个修饰符,这是因为中断函数必须通过它进行修饰。在C51程序设计中,当函数定义时用了interrupt m修饰符,系统编译时把对应函数转化为中断函数,自动加上程序头段和尾段,并按51系统中断的处理方式自动把它安排在程序存储器中的相应位置。
在该修饰符中,m的取值为0~31,对应的中断情况如下:
0——外部中断0
1——定时/计数器T0
2——外部中断1
3——定时/计数器T1
4——串行口中断
5——定时/计数器T2
其它值预留。
编写51中断函数注意如下:
(1)中断函数不能进行参数传递,如果中断函数中包含任何参数声明都将导致编译出错。
(2)中断函数没有返回值,如果企图定义一个返回值将得不到正确的结果,建议在定义中断函数时将其定义为void类型,以明确说明没有返回值。
(3)在任何情况下都不能直接调用中断函数,否则会产生编译错误。因为中断函数的返回是由8051单片机的RETI指令完成的,RETI指令影响8051单片机的硬件中断系统。如果在没有实际中断情况下直接调用中断函数,RETI指令的操作结果会产生一个致命的错误。
(4)如果在中断函数中调用了其它函数,则被调用函数所使用的寄存器必须与中断函数相同。否则会产生不正确的结果。
(5)C51编译器对中断函数编译时会自动在程序开始和结束处加上相应的内容,具体如下:在程序开始处对ACC、B、DPH、DPL和PSW入栈,结束时出栈。中断函数未加using n修饰符的,开始时还要将R0~R1入栈,结束时出栈。如中断函数加using n修饰符,则在开始将PSW入栈后还要修改PSW中的工作寄存器组选择位。
(6)C51编译器从绝对地址8m+3处产生一个中断向量,其中m为中断号,也即interrupt后面的数字。该向量包含一个到中断函数入口地址的绝对跳转。
(7)中断函数最好写在文件的尾部,并且禁止使用extern存储类型说明。防止其它程序调用。
【例】编写一个用于统计外中断0的中断次数的中断服务程序
extern int x;
void int0() interrupt 0 using 1
{
x++;
}
6).using n修饰符
修饰符using n用于指定本函数内部使用的工作寄存器组,其中n的取值为0~3,表示寄存器组号。
对于using n修饰符的使用,注意以下几点:
(1)加入using n后,C51在编译时自动的在函数的开始处和结束处加入以下指令。
{
PUSH PSW ;标志寄存器入栈
MOV PSW,#与寄存器组号相关的常量
……
POP PSW ;标志寄存器出栈
}
(2)using n修饰符不能用于有返回值的函数,因为C51函数的返回值是放在寄存器中的。如寄存器组改变了,返回值就会出错。
2. 函数的调用与声明
一.函数的调用
函数调用的一般形式如下:
函数名(实参列表);
对于有参数的函数调用,若实参列表包含多个实参,则各个实参之间用逗号隔开。
按照函数调用在主调函数中出现的位置,函数调用方式有以下三种:
(1)函数语句。把被调用函数作为主调用函数的一个语句。
(2)函数表达式。函数被放在一个表达式中,以一个运算对象的方式出现。这时的被调用函数要求带有返回语句,以返回一个明确的数值参加表达式的运算。
(3)函数参数。被调用函数作为另一个函数的参数。
二.自定义函数的声明
在C51中,函数原型一般形式如下:
[extern] 函数类型 函数名(形式参数表);
函数的声明是把函数的名字、函数类型以及形参的类型、个数和顺序通知编译系统,以便调用函数时系统进行对照检查。函数的声明后面要加分号。
如果声明的函数在文件内部,则声明时不用extern,如果声明的函数不在文件内部,而在另一个文件中,声明时须带extern,指明使用的函数在另一个文件中。
【例】函数的使用
#include <reg52.h> //包含特殊功能寄存器库
#include <stdio.h> //包含I/O函数库
int max(int x,int y); //对max函数进行声明
void main(void) //主函数
{
int a,b;
SCON=0x52; //串口初始化
TMOD=0x20;
TH1=0XF3;
TR1=1;
scanf(“please input a,b:%d,%d”,&a,&b);
printf(“\n”);
printf(“max is:%d\n”,max(a,b));
while(1);
}
int max(int x,int y)
{ int z;
z=(x>=y?x:y);
return(z);
}
【例24】 外部函数的使用
程序serial_initial.c
#include <reg52.h> //包含特殊功能寄存器库
#include <stdio.h> //包含I/O函数库
void serial_initial(void) //主函数
{
SCON=0x52; //串口初始化
TMOD=0x20;
TH1=0XF3;
TR1=1;
}
程序y1.c
#include <reg52.h> //包含特殊功能寄存器库
#include <stdio.h> //包含I/O函数库
extern serial_initial();
void main(void)
{
int a,b;
serial_initial();
scanf(“please input a,b:%d,%d”,&a,&b);
printf(“\n”);
printf(“max is:%d\n”,a>=b?a:b);
while(1);
}
3. 函数的嵌套与递归
一.函数的嵌套
在一个函数的调用过程中调用另一个函数。C51编译器通常依靠堆栈来进行参数传递,堆栈设在片内RAM中,而片内RAM的空间有限,因而嵌套的深度比较有限,一般在几层以内。如果层数过多,就会导致堆栈空间不够而出错。
【例】 函数的嵌套调用
#include <reg52.h> //包含特殊功能寄存器库
#include <stdio.h> //包含I/O函数库
extern serial_initial();
int max(int a,int b)
{
int z;
z=a>=b?a:b;
return(z);
}
int add(int c,int d,int e,int f)
{
int result;
result=max(c,d)+max(e,f); //调用函数max
return(result);
}
main()
{
int final;
serial_initial();
final=add(7,5,2,8);
printf(“%d”,final);
while(1);
}
二.函数的递归
递归调用是嵌套调用的一个特殊情况。如果在调用一个函数过程中又出现了直接或间接调用该函数本身,则称为函数的递归调用。
在函数的递归调用中要避免出现无终止的自身调用,应通过条件控制结束递归调用,使得递归的次数有限。
下面是一个利用递归调用求n!的例子。
【例】递归求数的阶乘n!。
在数学计算中,一个数n的阶乘等于该数本身乘以数n-1的阶乘,即n!=n´(n-1)!,用n-1的阶乘来表示n的阶乘就是一种递归表示方法。在程序设计中通过函数递归调用来实现。
程序如下:
#include <reg52.h> //包含特殊功能寄存器库
#include <stdio.h> //包含I/O函数库
extern serial_initial();
int fac(int n) reentrant
{
int result;
if (n= =0)
result=1;
else
result=n*fac(n-1);
return(result);
}
main()
{
int fac_result;
serial_initial();
fac_result=fac(11);
printf(“%d\n”,fac_result);
}
单片机C语言C51的函数相关推荐
- 单片机c语言中延时函数的作用,单片机中C语言延时函数
单片机C语言延时程序计算2009-11-02 22:15单片机C语言延时程序用C语言写出来程序非常的简练,它是一种模块化的语言,一种比汇编更高级的语言,但是就是这样一种语言也还是有它不足之处:它的延时 ...
- 单片机c语言常用指令,单片机C语言(C51)的常用库函数.doc
C51的常用库函数详解 C51语言的编译器中包含有丰富的库函数,使用库函数可以大大简化用户程序设计的工作量,提高编程效率.每个库函数都在相应的头文件中给出了函数原型声明,在使用时,必须在源程序的开始处 ...
- 单片机C语言C51的输入输出
在C51语言中,它本身不提供输入和输出语句,输入和输出操作是由函数来实现的.在C51的标准函数库中提供了一个名为"stdio.h"的一般I/O函数库,它当中定义了C51中的输入和输 ...
- 单片机C语言C51的数据类型
C51的数据类型分为基本数据类型和组合数据类型,情况与标准C中的数据类型基本相同,但其中char型与short型相同,float型与double型相同,另外,C51中还有专门针对于51单片机的特殊功能 ...
- 万年历单片机c语言,c51单片机万年历的c程序
求一个单片机可以显示阳历的年.月.日.星期.小时.分.秒.阴历也能显示,标明是否为闰年. 用LCD液晶显示,可以调整时间..... 这有个数码管显示的程序 以前做的,.. 你可以在我这个程序上修改修 ...
- 单片机c语言字符发送函数,求1602显示自定义字符 ℃ 的C语言程序,在写入和读函数多点说明,因为是初学者,...
#include __CONFIG(0X1832); //芯片配置字,看门狗关,上电延时开,掉电检测关,低压编程关,加密,4M晶体HS振荡 #define rs RA1 #define rw RA2 ...
- 51单片机c语言编程函数,单片机C语言教程:C51函数
其实一直出现在例子中的 main()也算是一个函数,只不过它比较特殊,编译时以它做为程序的开始段.有了函数C 语言就有了模块化的优点,一般功能较多的程序,会在编写程序时把每项单独的功能分成数个子程序模 ...
- c语言单片机常用函数,C51单片机C语言函数编辑 -单片机-电子工程世界网
其实一直出现在例子中的 main()也算是一个函数,只不过它比较特殊,编译时以它做为程序的开始段.有了函数C 语言就有了模块化的优点,一般功能较多的程序,会在编写程序时把每项单独的功能分成数个子程序模 ...
- 用c语言编辑单片机,C51单片机C语言函数编辑
三.中断函数 中断服务函数是编写 中断时才会被执行,这在处理突发事件和实时控制是十分有效的.例如:电路中一个按钮, 要求按钮后 LED 点亮,这个按钮何时会被按下是不可预知的,为了要捕获这个按钮的事件 ...
最新文章
- python【蓝桥杯vip练习题库】ADV-9 递归倒置字符数组
- 拼数pascal程序
- php页面代码简化,代码求简化
- Leetcode1512. 好数对的数目 抽出本质原型 利用范围条件
- Sybase用户登录以后的自动运行脚本
- linux系统中 库分为静态库和,Linux系统中“动态库”和“静态库”那点事儿-【经典好文】...
- MATLAB调用C/C++函数的方法
- mysql复杂查询sql_mysql – 复杂的SQL查询,很多很多
- VMware vSphere5.0 HA高可用性原理
- python 蒙特卡罗_蒙特卡洛模拟(Python)深入教程
- java 数据库连接池配置方式
- 快速了解babel工作原理
- WayOS路由器企业应用方案
- mysql数据库限流方案_用于对MySQL数据库的并发操作进行控制的方法及装置的制造方法_3...
- WinForm与WPF下跨线程调用控件
- 阿里这份Java程序性能优化指南,让你的程序快上200%
- 如何快速删除某几页的页眉页脚
- 序列周期性与魔术(一)——数学里的函数周期性
- cocos creator切换场景闪退_#Cocos Creator# 为什么音乐音效在场景切换的时候自动停止了?...
- 实践练习二(必选):手动部署 OceanBase 单副本集群
热门文章
- 这是基于HTML+CSS+JQ做的一款炫酷的旋转时钟网页代码
- 层净高怎么算_房屋的层高和净高怎么算?你知道相关标准吗
- Python kmp算法部分匹配表(pmt)和next
- Dialect needs to be explicitly supplied as of v4.0.0
- 在生活当中过得不如意也就算了
- yolov5部署android教程
- 马蜂窝推荐排序算法模型是如何实现快速迭代的
- 燃料电池压缩机系统学习
- 模式识别学习笔记(5)——最大似然和贝叶斯参数估计
- VMwear workstations下载及安装