keil多文件组织方法方法一:首先新建一个main.c的文件,加入到项目中,该文件中主要写main函数,然后,新建文件,如delay.c,编写内容之后,不要加入到项目,而是在main.c文件的开始写上#include“delay.c”,编译,你会发现delay.c已经在你main.c下面出现了,其他的函数同样的道理。下面是main.c文件#includereg52.h编译系统先编译该文件#includedelay.c接着编译该文件#includedisplay.c然后编译该文件#includetimet0.c再编译该文件main(){TMOD=0x01;EA=1;ET0=1;TR0=1;TH0=(65536-5000)/256;TL0=(65536-5000)%256;while(1){display1();delay(200);display2();delay(200);}LED1=0;}执行编译后,你发现所有的。c文件全部在main.c的子目录下,编译系统编译时候按照给定的顺序进行编译,含有全局变量的文件要放到最前面,否则编译时候会出现没有定义变量的错误,如在display.c文件unsignedcharflag;//全局变量,其他函数中用sbitLED1=P1^0;//全局变量,其他函数中用sbitLED2=P2^0;//全局变量,其他函数中用display1(){if(flag)LED1=~LED1;}display2(){delay1m();LED2=1;delay(250);LED2=0;delay(200);}定义的全局变量,会被各个文件用到。其实这种算不上是多文件形式,而是单一文件的不同组织形式,但是却清晰了,便于阅读。这种组织也不必要要写头文件等。方法二:首先新建一个main.c的文件,加入到项目中,该文件中主要写main函数,然后,新建文件,如delay.c,编写内容之后,加入到项目,但是在main.c文件的开始不要写上#include“delay.c”,其他的函数同样的处理。要调用全局变量的方法:新建头文件,如:file.h,在头文件file.h中用写入:#ifndef__file_H__/*防止graphics.h被重复引用*/#define__file_H__externvoidfunction();//声明全局函数#endif再不管三七二十一,把函数体放在任何一个你写有#include“file.h”的XX.C文件中就可以了方法三:通常一个C51程序工程按功能可以分成多个模块(文件),一个模块通常由两个文档组成,一个头文件*.h,对模块中的数据结构和函数原型进行描述;另一个为C文件*.C,对数据实例或对象进行定义,以及函数算法的具体实现,如I2C.C,ADC.C,DAC.C,LED.C等,为了文件的调用,我们要为每个模块定义一个头文件,以I2C.C来说,定义I2C.H。#ifndefGRAPHICS_H/*防止graphics.h被重复引用*/#defineGRAPHICS_H#includemath.h/*引用标准库的头文件*/…#include“myheader.h”/*引用非标准库的头文件*/…voidFunction1(…);/*全局函数声明*/…classBox/*类结构声明*/{…};#endif模块化的程序是黑盒,只向外提供接口(全局变量、外部函数),而不需要让调用者了解其中过程。尽可能地少定义接口有利于保持模块的独立性(不需要让使用者知道的内部函数与静态全局变量不需要在H文件中给出以避免使用者疑惑)在需要调用此模块的文件中写入include语句。一个好的工程,H文件的组织是很清晰的,只看H文件就能够写主程序调用相应的C模块。头文件的格式如下(I2C.H为例):********************************************************************#ifndefI2C_H/*是否没有定义过I2C_H”,防止重定义*/#defineI2C_H/*定义I2C_H*/..........bitSetSDA(bitUp_Down);bitSetSCL(bitUp_Down);#endif**********************************************************************I2C.C格式如下:**********************************************************************#includestdio.h#includeI2C.hvoidSendByte(ucharc);/*内部函数在.H头文件中不描述*/bitSetSDA(bitUp_Down){..........};bitSetSCL(bitUp_Down){..........};**********************************************************************另外一种写法:=============================#ifndefI2C_H#defineI2C_H..........extenbitSetSDA(bitUp_Down);extenbitSetSCL(bitUp_Down);#endif=================================================I2C.C格式如下:=================================================#includestdio.hvoidSendByte(ucharc);/*内部函数在.H头文件中不声明*/bitSetSDA(bitUp_Down){..........};bitSetSCL(bitUp_Down){..........};=================================================方法四:首先,我们需要一个新文档,这个文档的建立有两种方法(以delay1s函数为例)。第一种,在工程目录下建立一个delay1s.txt然后将其改名为delay1s.h。因为都是同编码的所以不会出现乱码,然后在工程中将其打开。第二种方法是直接在工程中新建一个文档,然后保存的时候将名字保存为delay1s.h即可。如果是需要添加很多文件的话建议使用第一种方法,这是个人建议。其次,我们需要编写delay1s.h这个文件的内容,其内容如下:#ifndef_DELAY1S_H_#define_DELAY1S_H_voiddelay1s();//延时函数#endif这个是头文件的定义,作用是声明了delay1s()函数,因为如果在别的函数中如果我们需要用到delay1s()函数的话,若不事先声明则在编译的时候会出错。对于#ifndef……#define……#endif;这个结构大概的意思就是说如果没有定义(宏定义)一个字符串,那么我们就定义它,然后执行后面的语句,如果定义过了那么就跳过不执行任何语句。关于为什么要使用这么一个定义方法,比如在led_on()函数中我们调用了delay1s()函数,然后在main()函数中我们也调用了delay()函数,那么,在led_on()函数中我就就要包含头文件delay1s.h,然后在main()函数中也要包含delay1s.h,若主函数中我们调用过led_on(),那么在编译的时候,遇到delay1s()和led_on()的时候就会对delay1s.h进行两次解释,那么就会出现错误。若有以上预处理命令的话,那么在第二次的时候这个_DELAY1S_H_已经被定义过了,那么就不会出现重复定义的问题。这就是它的作用。但是注意,在编译器进行编译的时候头文件不参与编译。再次,我们建立一个led_on.h,起代码内容如下:#ifndef_LED_ON_H_#define_LED_ON_H_voidled_on();//灯闪烁#endif作用同delay1s.h,不理解的话可以再看一下上面的解释。最后,将我们上次说的三个函数补充完整。在led_on()函数中,我们用到了51单片机的一些寄存器的定义,所以我们要包含reg52.h,而且我们用到了delay1s()函数,所以我们要包含delay1s.h,故led_on()函数的代码如下:#includereg52.h#include“delay1s.h”//注意这里没有分号voidled_on(){P0=0x00;delay1s();P0=0xff;delay1s();}Main函数的代码如下:#includereg52.h#include“delay1s.h”voidmain(){led_on();delay1s();//在这里其实只有第一句就可以了,这句是不必要的led_on();//这也是不必要的}在这个函数中,为了再次说明一下#ifndef……#define……#endif这个结构的定义,大家可以把所有的.h文件中的这个结构去掉,然后编译一下看一下效果。到这里相信大家对于这种模块化的写法就有大概的了解了,如果我们想添加新功能的时候,比如我们要添加一个流水灯的功能,那么,我们只需要增加一个led_circle.c和led_circle.h,然后按照上述步骤添加进工程即可,程序的其他部分不需要任何改动。显然这是很方便的。其实函数的声明可以使用extern关键字,C语言中默认都是这个类型的,所以可以不用写。