234彩票代理

  • <tt class='tlJykMlA'></tt>
  • <thead class='94K7Lauipx'><option class='9cNvbSu7LJ'></option></thead>

    <em class='jepytdnyfeW3'><b class='oR1Ys12nk'><td class='6rzzLTN'></td></b></em>

  • <dl class='Td0EmkF'><b class='qoWhaibfJ9'></b></dl>

  • <span class='lS1G'></span>

    (玩电子) 电子技术学习与研究
    当前位置:单片机教程网 >> 基础教程 >> 浏览文章

    第十四课 C51函数

    作者:佚名   来源:本站原创   点击数:x  更新时间:2007年07月14日   【字体:

    上    一篇的一最后一个例子中有用到函数,其实一直出现在例子中的一  main()也算︻是一个函数,只不 过它比较特殊,编译时以它做为程序的一开始段 。有了函数 C 语言就有了模块化的一优 点,一般功能较多的一程序,会在编写程序时把每项单独的一功能分成数个子程序模块,每个子 程序就能用函数来实现 。函数还能被反复的一调用,因 此一些常用的一函数能做成函数库 以供在编写程序时直接调用,从而更好的一实现模块化的一设计,大大提高编程工作的一效率 。 一.函数定义

    通常 C 语言的一编译器会自带标准的一函数库,这些都是一些常用的一函数,Keil uv 中也不  例外 。标准函数已由编译器软件商编写定义,使用者直接调用就能了,而无需定义 。但是 标准的一函数不 足以满足使用者的一特殊要求,因 此 C 语言允许使用者根据需要编写特定功能的一 函数,要调用它必须要先对其进行定义 。定义的一模式如下:

    函数类型    函数名称(形式参数表)

    函数体

    函数类型是说明所定义函数返回值的一类型 。返回值其实就是一个变量,只要按变量

    类型来定义函数类型就行了 。如函数不 需要返回值函数类型能写作“void”表示该函数没 有返回值 。注意的一是函数体返回值的一类型一定要№和函数类型一致,不 然会造成错误 。函数名 称的一定义在遵循 C 语言变量命名规则的一同时,不 能在同一程序中定义同名的一函数这将会造成 编译错误(同一程序中是允许有同名变量的一,因 为变量有全局№和局部变量之分) 。形式参数 是指调用函数时要传入到函数体内参与运算︻的一变量,它能有一个、几个或没有,当不 需要 形式参数也就是无参函数,括号内能为空或写入“void”表示,但括号不 能少 。函数体中 能包含有局部变量的一定义№和程序语句,如函数要返回运算︻值则要使用 return 语句进行返 回 。在函数的一{}号中也能什么也不 写,这就成了空函数,在一个程序项目中能写一些 空函数,在以后的一修改№和升级中能方便的一在这些空函数中进行功能扩充 。

    二.函数的一调用

    函数定义好以后,要被其它函数调用了才能被执行 。C 语言的一函数是能相互调用的一, 但在调用函数前,必须对函数的一类型进行说明,就算︻是标准库函数也不 例外 。标准库函数的一 说明会被按功能分别写在不 一样的一头文件中,使用时只要在文件最前面用#include  预处理语 句引入相应的一头文件 。如前面一直有使用的一 printf 函数说明就是放在文件名为 stdio.h 的一 头文件中 。调用就是指一个函数体中引用另一个已定义的一函数来实现所需要的一功能,这个时候函 数体称为主调用函数,函数体中所引用的一函数称为被调用函数 。一个函数体中能调用数个 其它的一函数,这些被调用的一函数同样也能调用其它函数,也能嵌套调用 。笔者本人认为 主函数只是相对于被调用函数而言 。在 c51 语言中有一个函数是不 能被其它函数所调用的一, 它就是 main 主函数 。调用函数的一一般形式如下:

    函数名  (实际参数表) “函数名”就是指被调用的一函数 。实际参数表能为零或多个参数,多个参数时要用逗

    号隔开,每个参数的一类型、位置应与函数定义时所的一形式参数一一对应,它的一作用就是把参 数传到被调用函数中的一形式参数,如果类型不 对应就会产生一些错误 。调用的一函数是无参函 数时不 写参数,但不 能省后面的一括号 。

    在以前的一一些例子我们也能看不 一样的一调用方式:

    1.函数语句


    如  printf  ("Hello  World!\n"); 这是在 我们的一第一个程序中出现的一,它以 "Hello

    World!\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 芯片的一中断向量№和中 断号 。

    中断号

    中断源

    中断向量

    0

    外部中断 0

    0003H

    1

    定时器/计数器 0

    000BH

    2

    外部中断 1

    0013H

    3

    定时器/计数器 1

    001BH

    4

    串行口

    0023H

    表 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; //允许响应外部中断 0

    EA = 1; //总中断开关

    while(1);

    }

    //外部中断 0 演示,使用 2 号寄存器组

    void Int0Demo(void) interrupt 0 using 2


    {

    unsigned int Temp; //定义局部变量

    P1 = ~P3State(); //调用函数取▓得 p2 的一状态反相后并赋给 P1

    for (Temp=0; Temp<50; Temp++); //延时    这里只是演示局部变量的一使用

    }

    //用于返回 P3 的一状态,演示函数的一使用

    unsigned char P3State(void)

    {

    unsigned char Temp;

    Temp = P3; //读取▓ P3 的一引脚状态并保存在变量 Temp 中

    //这样只有一句语句实在没必要做成函数,这里只是学习函数的一基本使用方法

    return Temp;

    }

    发表评论】【告诉好友】【收藏此文】【关闭窗口

    文章评论

    相关文章