keil 多文件组织方法

方法一:
首先新建一个 main.c 的文件,加入到项目中,该文件中主要写 main 函数,然后,新建文件,如 delay.c,
编写内容之后,不要加入到项目,而是在 main.c 文件的开始写上#include“delay.c”,编译,你会发现 delay.c

已经在你 main.c 下面出现了,其他的函数同样的道理。下面是 main.c 文件

#include <reg52.h>编译系统先编译该文件
#include"delay.c" 接着编译该文件
#include"display.c"然后编译该文件

#include"timet0.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 文件
unsigned char flag;//全局变量,其他函数中用
sbit LED1=P1^0;//全局变量,其他函数中用
sbit LED2=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__
extern void function();//声明全局函数
#endif
再不管三七二十一,把函数体放在任何一个你写有#include“file.h”的 XX.C 文件中就可以了

方法三:
通常一个 C51 程序工程按功能可以分成多个模块(文件) , 一个模块通常由两个文档组成,一个头文件 *.h,
对模块中的数据结构和函数原型进行描述;另一个为 C 文件*.C , 对数据实例或对象进行定义,以及函数
算法的具体实现,如 I2C.C, ADC.C, DAC.C, LED.C 等,为了文件的调用,我们要为每个模块定义一个头
文件,以 I2C.C 来说,定义 I2C.H。
#ifndef GRAPHICS_H /*防止 graphics.h 被重复引用*/
#define GRAPHICS_H
#include <math.h > /*引用标准库的头文件*/

#include “myheader.h” /* 引用非标准库的头文件*/
… v
oid Function1(…); /*全局函数声明*/

class Box /*类结构声明*/
{

};
#endif
模块化的程序是黑盒,只向外提供接口(全局变量、外部函数) ,而不需要让调用者了解其中过程。尽可能
地少定义接口有利于保持模块的独立性(不需要让使用者知道的内部函数与静态全局变量不需要在 H 文件
中给出以避免使用者疑惑)在需要调用此模块的文件中写入 include 语句。一个好的工程,H 文件的组织是
很清晰的,只看 H 文件就能够写主程序调用相应的 C 模块。
头文件的格式如下(I2C.H 为例):
********************************************************************
#ifndef I2C_H /*是否没有定义过 "I2C_H”, 防止重定义*/
#define I2C_H /*定义"I2C_H" */
..........
bit SetSDA ( bit Up_Down );
bit SetSCL ( bit Up_Down);
#endif
**********************************************************************
I2C.C 格式如下:
**********************************************************************
#include < stdio.h >
#include "I2C.h"
void SendByte ( uchar c ); /*内部函数在.H 头文件中不描述*/
bit SetSDA ( bit Up_Down ) { .......... };
bit SetSCL ( bit Up_Down) { .......... };
**********************************************************************
另外一种写法:
=============================
#ifndef I2C_H
#define I2C_H
..........
exten bit SetSDA ( bit Up_Down );
exten bit SetSCL ( bit Up_Down);
#endif
=================================================
I2C.C 格式如下:
=================================================
#include < stdio.h >
void SendByte ( uchar c ); /*内部函数在.H 头文件中不声明*/
bit SetSDA ( bit Up_Down ) { .......... };
bit SetSCL ( bit Up_Down) { .......... };
=================================================

方法四:
首先,我们需要一个新文档,这个文档的建立有两种方法(以 delay1s 函数为例) 。第一种,在工程目录下建立一个 delay1s.txt 然后将其改名为 delay1s.h。因为都是同编码的所以不会出现乱码,然后在工程中将其打开。第二种方法是直接在工程中新建一个文档,然后保存的时候将名字保存为 delay1s.h 即可。如果是需要添加很多文件的话建议使用第一种方法,这是个人建议。其次,我们需要编写 delay1s.h 这个文件的内容,其内容如下:

#ifndef _DELAY1S_H_
#define _DELAY1S_H_
void delay1s();//延时函数
#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_
void led_on();//灯闪烁
#endif
作用同 delay1s.h,不理解的话可以再看一下上面的解释。
最后,将我们上次说的三个函数补充完整。
在 led_on()函数中,我们用到了 51 单片机的一些寄存器的定义,所以我们要包含 reg52.h,而且我们用到了
delay1s()函数,所以我们要包含 delay1s.h,故 led_on()函数的代码如下:
#include <reg52.h>
#include “delay1s.h” //注意这里没有分号
void led_on()
{
P0=0x00;
delay1s();
P0=0xff;
delay1s();
}
Main 函数的代码如下:
#include <reg52.h>
#include “delay1s.h”
void main()
{
led_on();
delay1s();//在这里其实只有第一句就可以了,这句是不必要的
led_on();//这也是不必要的
}
在这个函数中,为了再次说明一下#ifndef……#define……#endif 这个结构的定义,大家可以把所有的.h 文
件中的这个结构去掉,然后编译一下看一下效果。
到这里相信大家对于这种模块化的写法就有大概的了解了,如果我们想添加新功能的时候,比如我们要添
加一个流水灯的功能,那么,我们只需要增加一个 led_circle.c 和 led_circle.h,然后按照上述步骤添加进
工程即可,程序的其他部分不需要任何改动。显然这是很方便的。其实函数的声明可以使用 extern 关键字,
C 语言中默认都是这个类型的,所以可以不用写。

keil 多文件组织方法相关推荐

  1. STM32Cube工程转为Keil工程的方法介绍

    本文介绍STM32Cube工程转为Keil工程的方法.使用的windows10系统, STM32CubeMX 6.6.1,Keil uVision5.22. 1 准备 安装好软件STM32CubeMX ...

  2. 在实际项目开发中keil的调试方法

    转载2015-06-14 20:23:04 一.在keilc的调试状态下,如何观察各个片内外设的运行状态?如何修改它们的设置?​ 在调试状态下,点击Peripherals菜单下的不同外设选项命令,就会 ...

  3. proteus与keil的安装方法合集

    1.proteus安装方法:https://blog.csdn.net/qq_38101569/article/details/107014640 2.keil安装方法: https://blog.c ...

  4. 关于keil常见问题解决方法记录error: #268: declaration may not appear after executable statement in block

    error: #268: declaration may not appear after executable statement in block 因为keil 默认编译标准是C89,解决方法:

  5. Keil插件使用方法汇总

    文章目录 代码格式化 CoolFormat 添加脚本 一.pandas是什么? 二.使用步骤 参考文档 代码格式化 CoolFormat 添加脚本 在Keil中,!E表示当前文件 一.pandas是什 ...

  6. mysql临时表创建_MySQL临时表创建

    和SQL SERVER 创建临时表不同 不能直接写 Create table #Test_Table 而是需要在 Create 和 table 之间 加入 TEMPORARY(temporary) 关 ...

  7. KEIL编译stdarg处理机制遇到incorrect use之类的问题

    文章转自:https://blog.csdn.net/chengdong1314/article/details/74625528 SYD8801是一款低功耗高性能蓝牙低功耗SOC,集成了高性能2.4 ...

  8. keil uvision2 c语言调试,keil uvision2

    keil uvision2是款优秀的单片机开发工具,采用接近于c语言的语法来开发,功能全面,提供了源代码.功能导航器.模板编辑等功能,为开发者们提高了工作效率和项目开发周期,软件还能嵌入汇编,用户可在 ...

  9. 软件工程结构化建模的方法和工具_软件工程系列-结构化设计方法2

    本系列文章为笔记,内容根据北京大学<软件工程>MOOC 初始化模块结构图精化的启发式规则 常见的启发式规则 什么叫做"启发式" 根据设计准则,从长期的软件开发实践中,总 ...

最新文章

  1. IT公司100题-10-翻转句子中单词的顺序
  2. 主流浏览器内核介绍(前端开发值得了解的浏览器内核历史)
  3. 没学过编程可以自学python吗-我以前从没学过编程,学Python看什么书?
  4. 神奇的HyperLogLog算法
  5. 专科 java转go 翱翔之路(一)基础语法:变量声明,匿名函数,结构体,函数,map
  6. 【剑指offer】面试题57 - II:和为s的连续正数序列(Java)
  7. 4.线性和卷积——边界问题、解决边界方法和Matlab实战_3
  8. 小米组织架构再调整:手机部成立参谋部 朱磊出任参谋长
  9. py2neo 数据类型
  10. 【已解决】SyntaxError: Non-UTF-8 code starting with ‘\xe4‘ in file
  11. android之Fragment(官网资料翻译)
  12. linux修改对外访问ip_linux 同一个ip 绑定两个不同的域名 访问两个不同的项目
  13. AI人工智能的5种绝佳编程语言
  14. PowerDesigner设计数据库表操作
  15. 计算机开机反复启动,电脑开机后反复重启原因 电脑开机后反复重启解决方法【详解】...
  16. 两年数据对比柱形图_办公小技巧:让Excel图表对比更轻松
  17. jenkins发送邮件添加附件
  18. 密码学归约证明——选择明文攻击下的不可区分性
  19. 大闹天竺里的机器人_王宝强的电影《大闹天竺》都植入了哪些品牌?
  20. 主题:“芙蓉姐姐”荣登05年十大令人作呕女人榜首…… [荐]

热门文章

  1. common.logging和log4j比较
  2. struts2处理请求流程详解
  3. Hibernate映射配置方法
  4. indent 的格式
  5. software enginer1
  6. UA MATH563 概率论的数学基础 鞅论初步7 停时与Upcrossing不等式
  7. 首次使用Windbg调试dNet程序
  8. 各种Oracle常见操作
  9. 中文分词工具的初步使用图解
  10. 很多优秀的软件公司和开发者为什么愿意开源和共享?