14第十四课 C51函数

合集下载

C51的函数

C51的函数
/* ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
此程序用于说明函数的简单调用 ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ */
void delay(unsigned int time) {
while(time­­); }
d++;
6
return d; }
unsigned char get_value2(unsigned char *pd)*pd; }
void main() {
unsigned char a=100,b; b=get_value1(a); /*a 为参数,通过 get_value1 函数的形式参数传入函数中 这里要指出的是 get_value1 函数的形式参数 d,是定义在 函数内的,变量 a 传进来时是将变量 a 的值赋给了 d,实际 参与运算的是 d,可以说 d 是 a 的一个副本,对 d 的操作与 a 无关。所以 b 的值为 101,而 a 的值仍然为 100,这种传递方 式称为参数的值传递。 */式称为值传递。 b=get_value2(&a); /*get_value2 函数的参数为指针型,&a 作为参数传入,是
/* ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
此程序用于说明通过函数指针的用法 ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ */
void delay(unsigned int time) {
while(time­­); }
函数类型 函数名(数据类型 形式参数,数据类型 形式参数........) {

C51库函数详解

C51库函数详解

_chkfloat_:函数定义:unsigned char _chkfloat_ ( float val); /* number to check */函数功能:_chkfloat_函数检查浮点数val 的类型。

返回值:_chkfloat_函数返回浮点数val 的类型。

返回值意义0 标准浮点数1 浮点02 +INF 正溢出3 -INF 负溢出4 NaN 非数函数测试:#include <reg51.h>#include <intrins.h>/*本实验测试本征库中的_chkfloat_函数函数定义:unsigned char _chkfloat_(float val);返回值:Return Value Meaning0 Standard floating-point number.1 Floating-point value 0.2 +INF (positive overflow).3 -INF (negative overflow).4 NaN (Not a Number) error status.用P1指示返回值*/unsigned char f[4]={0xff,0xff,0xff,0xff};void delay(unsigned int time){while(time--);}void main(){P2=~_chkfloat_(1.2455); //Standard floating-point number.delay(50000);P2=~_chkfloat_(0.00); //Floating-point value 0.delay(50000);P2=~_chkfloat_(1000000000000000000000000000000000000000000000000000000000000000.0000 000000); //+INF (positive overflow).delay(50000);P2=~_chkfloat_(-1000000000000000000000000000000000000000000000000000000000000000.000 0000000); //-INF (negative overflow).delay(50000);P2=~_chkfloat_(*((float *)f)); //NaN (Not a Number) error status.while(1);_crol_:函数定义:unsigned char _crol_ ( unsigned char c, /* character to rotate left */unsigned char b); /* bit positions to rotate */ 函数功能:_crol_函数将一个字节c循环左移b位。

第11章C51的函数

第11章C51的函数
• 无参函数:主调函数和被调函数之间不进行参数传送,因 此在函数定义、函数说明及函数调用中也就可以不带参数。 此类函数通常用来完成一组指定的功能,可以带有返回值, 也可以没有返回函数值。
• 有参函数:主调函数和被调函数之间存在参数传送,因此 在函数定义及函数说明时都需要有参数,称为“形式参数” (简称为“形参”)。在主调函数中进行函数调用时也必 须给出参数,称为“实际参数”(简称为“实参”)。在 函数调用时,主调函数将把实参的值传送给形参,供被调 函数使用。有参函数可以带有返回值,也可以没有返回函 数值。
• 函数的值只能通过return语句返回主调函数。 return 语句的一般形式为:
• return 表达式; • 或者为: • return (表达式);
11.5 函数的调用
• 函数的调用是指函数在主调函数中的调用形式。在前面的 实例中其实已经用到了函数的调用。在C51语言中,函数的 调用的一般形式如下:
• 示例如下: • int f(int x)
//函数定义 •{ • int y; • z=f(y);
//递归调用 • return z; •}
11.5.3 嵌套调用
• 嵌套调用即在被调函数中又调用了其他函数的调用形式。 C51语言中不允许作嵌套的函数定义。但是允许调用其他的 函数,因为除了主函数外,各个函数都是平行的。这与其 他高级语言的子程序嵌套的情形是类似的。示例如下:
• 除了主函数外,C51还提供了极为丰富的库函数,而且还允许用户 自定义函数。在C51程序中,由主函数调用其他函数,其他函数之 间也可以相互调用。同一个函数可以被一个或多个函数调用任意 次。
• 在使用C51函数时,需要注意如下几点: • C51的源程序的函数数目是不限的。 • 在一个函数的函数体内,不能再定义另一个函数,即不能嵌套定

c51调用函数的各种格式

c51调用函数的各种格式

c51调用函数的各种格式(实用版)目录1.C51 函数调用的基本概念2.C51 函数调用的格式3.C51 函数调用的参数传递方式4.C51 函数调用的返回值5.C51 函数调用的注意事项正文【1.C51 函数调用的基本概念】在 C51 编程语言中,函数是一种可以实现特定功能的代码块。

函数调用则是指在程序中使用函数的过程。

通过函数调用,可以实现代码的模块化和重用,提高程序的可读性和可维护性。

【2.C51 函数调用的格式】在 C51 中,函数调用的格式包括以下要素:- 函数名:用于标识要调用的函数的唯一名称。

- 参数列表:用于传递给函数的实际参数,可以包含多个参数,参数之间用逗号分隔。

- 函数返回值:函数执行完成后返回给调用者的结果。

【3.C51 函数调用的参数传递方式】C51 函数调用的参数传递方式有两种:- 值传递:将实参的值传递给形参。

这种方式下,形参和实参是两个独立的变量,互不影响。

函数中的形参修改不会影响到实参的值。

- 指针传递:将实参的地址传递给形参。

这种方式下,形参和实参共享同一内存空间,函数中的形参修改会影响到实参的值。

【4.C51 函数调用的返回值】函数调用后,函数需要返回一个结果给调用者。

返回值的类型应与函数定义时指定的返回类型匹配。

如果函数不需要返回值,可以使用 void 类型作为返回类型。

【5.C51 函数调用的注意事项】- 函数调用时,应确保函数定义在前,调用在后。

否则,编译器无法识别函数。

- 函数调用时,应确保实参的类型与形参的类型匹配,否则会导致编译错误。

- 函数调用时,应避免使用未定义的函数。

否则,编译器会报错。

通过以上介绍,相信大家对 C51 函数调用的格式有了更清晰的认识。

c51 nop函数

c51 nop函数

c51 nop函数【1.什么是C51 NOP函数】C51 NOP函数,全称“C51 No Operation Function”,是在嵌入式系统编程中常用的一种编程技巧。

它被称为“空操作函数”,简写为NOP。

在C51单片机中,NOP函数是一个无条件的空操作,它不会执行任何有效指令,而是在指令周期内闲置。

【2.C51 NOP函数的作用】C51 NOP函数的主要作用有以下几点:1.填补代码:在某些情况下,程序中可能存在一些空闲的指令周期,通过使用NOP函数,可以填补这些空白,使程序更加紧凑。

2.延时:NOP函数可以在一定程度上实现延时的功能。

虽然它的延时效果不如专门的发延时函数,但在某些简单场景下,可以满足需求。

3.调试:在程序开发过程中,NOP函数可以作为一种调试工具,帮助开发者检查程序的执行流程。

4.降低功耗:在某些特定场景下,通过在循环中插入NOP函数,可以降低部分硬件的工作频率,从而降低功耗。

【3.如何使用C51 NOP函数】在使用C51 NOP函数时,只需在代码中调用即可。

以下是一个简单的示例:```c#include <reg52.h>void main(){while (1){// 插入NOP函数_nop_();// 其它代码语句}}```需要注意的是,虽然NOP函数可以实现简单的延时,但它的延时效果并不稳定,因为它与编译器、单片机型号和晶振频率等因素有关。

在需要精确延时的情况下,建议使用专门的延时函数。

【4.C51 NOP函数的注意事项】1.避免在关键路径上使用NOP函数,以免影响程序的执行效率。

2.使用NOP函数填补代码时,应注意确保总线宽度和时序兼容性。

3.在循环中使用NOP函数时,要注意防止无限循环导致的系统瘫痪。

可以适时添加计数器或标志位来控制循环次数。

4.虽然NOP函数在大多数情况下不会引起问题,但在某些特定条件下,可能会导致意外的结果。

因此,在使用NOP函数时,要充分了解其工作原理和可能的影响。

C51 函数

C51 函数

4.2.2.3 用全程变量实现参数互传 如果将所要传递的参数定义为全程变量, 可使变量在整个程序中对所有函数都可见。 全程变量的数目受到限制, 特别对于较大的 数组更是如此。
例4-2-4 以下示例程序中m[10]数组是全程变量,数据元素的值在disp()函 数中被改变后,回到主函数中得到的依然是被改变后的值。
4.1.1 函数说明 形式为:
函数名(数据类型 形式参数, 形式参数, 函数类型 函数名 数据类型 形式参数 数据类型 形式参数 ......);
其中: 函数类型是该函数返回值的数据类型, 可以是以前介绍的整型(int),长整型(long), 字符型(char), 单浮点型(float), 双浮点型 (double)以及无值型 (void), 也可以是指针, 包括结构指针。无值型表示函数没有返回值。
单片机接口技术(C51版)
第四章 函数
内容概述
函数是C51程序的基本组成部分, 程序的基本组成部分, 函数是 程序的基本组成部分 C51程序的全部工作都是由各式各 程序的全部工作都是由各式各 样的函数完成的。本章主要介绍函 样的函数完成的。 数的定义、调用、参数的传递、变 数的定义、调用、参数的传递、 量的作用域等。 量的作用域等。
4.2.2.2 被调用函数向调用函数返回值 一般使用return语句由被调用函数向调 用函数返回值, 该语句有下列用途: 1) 它能立即从所在的函数中退出, 返回到调 用它的程序中去。 2) 返回一个值给调用它的函数。
1. 2.
有两种方法可以终止子函数运行并返回到调用它 的函数中: 一是执行到函数的最后一条语句后返回; 一是执行到语句return时返回。 前者当子函数执行完后仅返回给调用函数一个0。 若要返回一个值, 就必须用return语句。只需在 return 语句中指定返回的值即可。 return语句可以向调用函数返回值, 但这种方法 只能返回一个参数

C51的函数

C51的函数
空操作函数的格式如下: void _nop_ (void) 该函数产生一个汇编指令NOP,执行它没有任何实质性操作,仅仅延时一 个机器周期。 3)位测试函数 位测试函数的格式如下: bit _testbit_ (bit x) 该函数的参数和返回值必须是位变量。该函数产生汇编指令JBC x,即判 断位x的值是0还是1,并将其值通过Cy标志返回。
函数
C51的函数
函数是C51语言的重要组成部分,是从标准C语言中继承 而来的。C51语言不限制程序中的函数个数。任何一个完整的 C51程序都必须有且仅有一个主函数(main函数),主函数是 C51程序的入口,所有的C51程序都是从主函数开始执行的。 为了有利于程序的模块化,促进资源的共享,C51语言允许用 户使用自定义函数。同时,C51提供了大量的功能强大的库函 数。这些库函数都是编译系统自带的已定义好的函数,用户 可以在程序中直接调用,而无须再自定义。合理使用库函数 可以简化程序设计、加快程序执行速度。
被调函数在主调函数中,以程序语句的方式出现。通常只完成一种 操作,不带函数会返回值。 该函数调用非常简单,即在main函数内调用函数func,用于输出一串字 符。 2.函数表达式
调用函数后,取得函数的返回值,用于其他操作。
1.3 C51的库函数
C51可以使用大量标准C语言的库函数,在用预处理器命令#include 包含相应的头文件后,程序员就可以在程序中使用这些函数。
unsigned int _lrol_ (unsigned int val, unsigned char n); /*左移无符号长整型*/
这些函数的第一个参数表示要进行位移的变量,第二个参数表示要移 动的位数。
右移函数与左移函数形式一致,只是函数名不同,它们分别是: unsigned char _cror_ (unsigned char val, unsigned char n);/*

C51的常用库函数精品课件

C51的常用库函数精品课件
• char _toupper (char c); • 其中,c为待转换的小写字符。这其实是一个由宏
定义完成的操作,其功能是将字符参数c与常数 0xdf逐位进行与运算,从而将小写字符转换为大 写字符。
第19页,共85页。
12.2 字符串函数
• 字符串函数的原型声明包含在头文件STRING.H中。 在C51语言中,字符串应包括2个或多个字符,字 符串的结尾以空字符来表示。字符串函数通过接 受指针串来对字符串进行处理。常用的字符串函 数介绍如下。
• 十六进制数字检查函数用于转换形参字符为十六 进制数字,其函数原型如下:
• char toint (char c); • 其中,c为待转换字符。该函数将形参字符0~9、
a~f(大小写无关)转换为16进制数字。其中, 对于字符0~9,返回值为0H~9H,对于ASCII字符 a~f(大小写无关),返回值为0AH~0FH。
第28页,共85页。
12.2.9 字符串比较函数
• 字符串比较函数用于比较两个字符串的大小,其 函数原型如下:
• char strcmp(char *s1,char *s2); • 其中,s1和s2为待比较的字符串。该函数的功能
是比较字符串s1和s2,如果两者相等则返回0;如 果s1<s2,则返回一个负数;如果s1>s2,则返回 一个正数。
第21页,共85页。
12.2.2 指定长度的字符串比较函数
• 指定长度的字符串比较函数用于按照指定的长度 比较两个字符串的大小,其函数原型如下:
• char memcmp(void*s1, void*s2,int len); • 其中,s1和s2为输入字符串,len为比较的长度。
该函数的功能是逐个比较字符串sl和s2的前len个 字符,如果相等则返回0,如果字符串s1大于s2, 则返回一个正数,如果字符串s1小于s2,则返回 一个负数。如果两个字符串的长度小于len,该函 数仍将一直比较len个字符,这种情况下,有可能 结果是错误的。因此应该保证len不能超过最短字 符串的长度。
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

上一篇的最后一个例子中有用到函数,其实一直出现在例子中的 main()也算是一个函数,只不过它比较特殊,编译时以它做为程序的开始段。

有了函数C 语言就有了模块化的优点,一般功能较多的程序,会在编写程序时把每项单独的功能分成数个子程序模块,每个子程序就能用函数来实现。

函数还能被反复的调用,因此一些常用的函数能做成函数库以供在编写程序时直接调用,从而更好的实现模块化的设计,大大提高编程工作的效率。

一.函数定义通常C 语言的编译器会自带标准的函数库,这些都是一些常用的函数,Keil uv 中也不例外。

标准函数已由编译器软件商编写定义,使用者直接调用就能了,而无需定义。

但是标准的函数不足以满足使用者的特殊要求,因此C 语言允许使用者根据需要编写特定功能的函数,要调用它必须要先对其进行定义。

定义的模式如下:函数类型函数名称(形式参数表){函数体}函数类型是说明所定义函数返回值的类型。

返回值其实就是一个变量,只要按变量类型来定义函数类型就行了。

如函数不需要返回值函数类型能写作“void”表示该函数没有返回值。

注意的是函数体返回值的类型一定要和函数类型一致,不然会造成错误。

函数名称的定义在遵循C 语言变量命名规则的同时,不能在同一程序中定义同名的函数这将会造成编译错误(同一程序中是允许有同名变量的,因为变量有全局和局部变量之分)。

形式参数是指调用函数时要传入到函数体内参与运算的变量,它能有一个、几个或没有,当不需要形式参数也就是无参函数,括号内能为空或写入“void”表示,但括号不能少。

函数体中能包含有局部变量的定义和程序语句,如函数要返回运算值则要使用return 语句进行返回。

在函数的{}号中也能什么也不写,这就成了空函数,在一个程序项目中能写一些空函数,在以后的修改和升级中能方便的在这些空函数中进行功能扩充。

二.函数的调用函数定义好以后,要被其它函数调用了才能被执行。

C 语言的函数是能相互调用的,但在调用函数前,必须对函数的类型进行说明,就算是标准库函数也不例外。

标准库函数的说明会被按功能分别写在不一样的头文件中,使用时只要在文件最前面用#include 预处理语句引入相应的头文件。

如前面一直有使用的printf 函数说明就是放在文件名为stdio.h 的头文件中。

调用就是指一个函数体中引用另一个已定义的函数来实现所需要的功能,这个时候函数体称为主调用函数,函数体中所引用的函数称为被调用函数。

一个函数体中能调用数个其它的函数,这些被调用的函数同样也能调用其它函数,也能嵌套调用。

笔者本人认为主函数只是相对于被调用函数而言。

在c51 语言中有一个函数是不能被其它函数所调用的,它就是main 主函数。

调用函数的一般形式如下:函数名 (实际参数表) “函数名”就是指被调用的函数。

实际参数表能为零或多个参数,多个参数时要用逗号隔开,每个参数的类型、位置应与函数定义时所的形式参数一一对应,它的作用就是把参数传到被调用函数中的形式参数,如果类型不对应就会产生一些错误。

调用的函数是无参函数时不写参数,但不能省后面的括号。

在以前的一些例子我们也能看不一样的调用方式:1.函数语句如 printf ("Hello World!\n"); 这是在我们的第一个程序中出现的,它以"HelloWorld!\n"为参数调用printf 这个库函数。

在这里函数调用被看作了一条语句。

2.函数参数“函数参数”这种方式是指被调用函数的返回值当作另一个被调用函数的实际参数,如temp=StrToInt(CharB(16));CharB 的返回值作为StrToInt 函数的实际参数传递。

3.函数表达式而在上一篇的例子中有temp = Count();这样一句,这个时候函数的调用作为一个运算对象出现在表达式中,能称为函数表达式。

例子中Count()返回一个int 类型的返回值直接赋值给temp。

注意的是这种调用方式要求被调用的函数能返回一个同类型的值,不然会出现不可预料的错误。

前面说到调用函数前要对被调用的函数进行说明。

标准库函数只要用#include 引入已写好说明的头文件,在程序就能直接调用函数了。

如调用的是自定义的函数则要用如下形式编写函数类型说明类型标识符函数的名称(形式参数表); 这样的说明方式是用在被调函数定义和主调函数是在同一文件中。

你也能把这些写到文件名.h 的文件中用#include "文件名.h"引入。

如果被调函数的定义和主调函数不是在同一文件中的,则要用如下的方式进行说明,说明被调函数的定义在同一项目的不一样文件之上,其实库函数的头文件也是如此说明库函数的,如果说明的函数也能称为外部函数。

extern 类型标识符函数的名称(形式参数表); 函数的定义和说明是完全不一样的,在编译的角度上看函数的定义是把函数编译存放在ROM 的某一段地址上,而函数说明是告诉编译器要在程序中使用那些函数并确定函数的地址。

如果在同一文件中被调函数的定义在主调函数之前,这个时候能不用说明函数类型。

也就是说在main 函数之前定义的函数,在程序中就能不用写函数类型说明了。

能在一个函数体调用另一个函数(嵌套调用),但不允许在一个函数定义中定义另一个函数。

还要注意的是函数定义和说明中的“类型、形参表、名称”等都要相一致。

三.中断函数中断服务函数是编写单片机应用程序不可缺少的。

中断服务函数只有在中断源请求响应中断时才会被执行,这在处理突发事件和实时控制是十分有效的。

例如:电路中一个按钮,要求按钮后LED 点亮,这个按钮何时会被按下是不可预知的,为了要捕获这个按钮的事件,通常会有三种方法,一是用循环语句不断的对按钮进行查询,二是用定时中断在间隔时间内扫描按钮,三是用外部中断服务函数对按钮进行捕获。

在这个应用中只有单一的按钮功能,那么第一种方式就能胜任了,程序也很简单,但是它会不停的在对按钮进行查询浪费了CPU 的时间。

实际应用中一般都会还有其它的功能要求同时实现,这个时候能根据需要选用第二或第三种方式,第三种方式占用的CPU 时间最少,只有在有按钮事件发生时,中断服务函数才会被执行,其余的时间则是执行其它的任务。

如果你学习过汇编语言的话,刚开始写汇编的中断应用程序时,你一定会为出入堆栈的问题而困扰过。

单片机c语言语言扩展了函数的定义使它能直接编写中断服务函数,你能不必考虑出入堆栈的问题,从而提高了工作的效率。

扩展的关键字是interrupt,它是函数定义时的一个选项,只要在一个函数定义后面加上这个选项,那么这个函数就变成了中断服务函数。

在后面还能加上一个选项using,这个选项是指定选用51 芯片内部4 组工作寄存器中的那个组。

开始学习者能不必去做工作寄存器设定,而由编译器自动选择,避免产生不必要的错误。

定义中断服务函数时能用如下的形式。

函数类型函数名 (形式参数) interrupt n [using n]interrupt 关键字是不可缺少的,由它告诉编译器该函数是中断服务函数,并由后面的n 指明所使用的中断号。

n 的取值范围为0-31,但具体的中断号要取决于芯片的型号,像AT89c51 实际上就使用0-4 号中断。

每个中断号都对应一个中断向量,具体地址为8n+ 3, 中断源响应后处理器会跳转到中断向量所处的地址执行程序,编译器会在这地址上产生一个无条件跳转语句,转到中断服务函数所在的地址执行程序。

下表是51 芯片的中断向量和中断号。

表9-1 AT89c51 芯片中断号和中断向量使用中断服务函数时应注意:中断函数不能直接调用中断函数;不能通过形参传速参数; 在中断函数中调用其它函数,两者所使用的寄存器组应相同。

限于篇幅其它与函数相关的知识这里不能一一加以说明,如变量的传递、存储,局部变量、全部变量等,有兴趣的朋友可以访问笔者的网站阅读更多相关文章。

下面是简单的例子。

首先要在前面做好的实验电路中加多一个按钮,接在P3.2(12 引脚外部中断INT0)和地线之间。

把编译好后的程序烧录到芯片后,当接在P3.2 引脚的按钮接下时,中断服务函数Int0Demo 就会被执行,把P3 当前的状态反映到P1,如按钮接下后P3.7(之前有在这脚装过一按钮)为低,这个时候P1.7 上的LED 就会熄灭。

放开P3.2 上的按钮后,P1LED 状态保持先前按下P3.2 时P3 的状态。

#include <at89x51.h>unsigned char P3State(void); //函数的说明,中断函数不用说明void main(void){IT0 = 0; //设外部中断0 为低电平触发EX0 = 1; //允许响应外部中断0EA = 1; //总中断开关while(1);}//外部中断0 演示,使用2 号寄存器组void Int0Demo(void) interrupt 0 using 2{unsigned int Temp; //定义局部变量P1 = ~P3State(); //调用函数取得p2 的状态反相后并赋给P1for (Temp=0; Temp<50; Temp++); //延时这里只是演示局部变量的使用}//用于返回P3 的状态,演示函数的使用unsigned char P3State(void){unsigned char Temp;Temp = P3; //读取P3 的引脚状态并保存在变量Temp 中//这样只有一句语句实在没必要做成函数,这里只是学习函数的基本使用方法return Temp;}。

相关文档
最新文档