完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
本帖最后由 默默地努力 于 2014-1-19 21:50 编辑
如果哪里没看懂,请直接回帖,24小时之内必回!!! KEil C 中模块化程序的编写 前言: 在我们学习C语言的时候,我们习惯上把自己要写的东西按顺序写在一个.c文件中。这对初学者来说是比较容易接受的写法,看上去也比较清晰。当程序比较短的时候,是没有什么问题的。但是当程序很长的时候,程序就变得难以看懂了。 举个例子,用51单片机做一个带测温功能的电子时钟,时钟芯片用DS1302,用1602做显示,用DS18B20测温度。1602的操作涉及好几个函数(读、写……),18B20又有几个函数,1302也有还几个函数,这样下来的话,代码应该有几百行了。对于自己写的程序可能在自己的脑海中比较清晰,不会太乱,但是当把自己写的程序交给别人来看的时候,别人往往会看的云里雾里,经常会看着看着就不知道你写的是什么了。 此时我们就需要一种模块化的写法,每个模块单独写成一个.c文件,最后在合并到一起,非常实用。下面我们举个例子来手把手教大家如何在Keil C中写出自己的模块化程序。 【例1】 让学习板上的第一个LED以1S的频率闪烁 电路图如下: 我们先把按照之前的方法(即只有一个.c文件的方法)写一下程序: #include #define uint unsigned int //宏定义 ***it led=P1^0; //变量定义 void delay(uint); //函数声明 void main() //主函数 { while(1) { led=0; //由电路图可知,当IO口为低电平的时候,led点亮 delay(1000); //粗略延时,让led亮一会 led=1; //熄灭led delay(1000); } } void delay(uint xms) //延时函数,时间为xms { uint i,j; for(i=xms;i>0;i--) for(j=110;j>0;j--); } 下面我们分模块化来写: 首先我们需要将程序分模块,此处我们分为三个模块,分别是主函数、延时函数、闪烁函数,我们先建立三个.c的文件,分别命名为main.c、delay.c和led.c,过程如下: 新建工程,然后新建三个.c文件,并且保存,然后将三个.c文件添加到该工程里(右击source group 1,选择“add files to group source group 1”进行添加) 然后我们开始逐个加入代码 (1) delay.c中写入: #include #include"delay.h" (后面会解释) #define uint unsigned int void delay(uint xms) { uinti,j; for(i=xms;i>0;i--) for(j=110;j>0;j--); } (2) led.c中写入: #include #include"led.h" #include"delay.h" ***it led=P1^0; void led_shan() { led=0; delay(1000); led=1; delay(1000); } (3) 然后在main.c函数中我们添加如下代码: #include #include"led.h" void main() { while(1) { led_shan(); } } 下面问题来了,就是如何将这三个C文件关联起来。 其实在单个.c文件的程序中,我们在写程序的时候第一件事就是写上#include ,如果你是一个好学者,你一定问过为什么要这样写一句话,老师一定跟你讲reg52.h是头文件,这句话的作用的把头文件包含进来。当然这是很正确的,你可以打开reg52.h ,看一下里面的内容,里面包含了关于51单片机的一些定义。进一步想一下,一个包含命令可以把一个文件包含进来,那么用不同的头文件包含不就可以把更多的文件包含进来了吗?是不是有点思路了? 我们现在讨论一下如何将三个c文件关联起来,在单文档的程序中我们使用#include这个命令将单片机的头文件与我们的程序关联起来。同理我们也将以头文件的形式把我们建立的源程序关联起来。 首先,我们需要一个新的头文件,建立有两种方法(以delay函数为例)。 第一种,在工程目录下新建一个txt文档将其改名为delay.h,然后在工程中将其打开。第二种,直接在工程中新建一个文档(ctrl+n),然后保存的时候将名字保存为delay.h即可(此方法跟建立.c文件的方法一样,知识在保存的时候后缀不是.c,而是.h)。 .h文件的基本结构如下: #ifndef_DELAY_H_ #define_DELAY_H_ ……. #endif 然后,我们需要编写delay.h这个文件的内容,其内容如下: #ifndef_DELAY_H_ #define_DELAY_H_ #defineuint unsigned int externvoid delay(uint);//延时函数 #endif 这个是头文件的定义,作用是声明了delay()函数,因为如果在别的函数中如果我们需要用到delay()函数的话,若不事先声明则在编译的时候会出错。 对于#ifndef……#define……#endif;这个结构大概的意思就是说如果没有定义(宏定义)一个字符串,那么我们就定义它,然后执行后面的语句,如果定义过了那么就跳过不执行任何语句。关于为什么要使用这么一个定义方法,比如在led()函数中我们调用了delay()函数,然后在main()函数中我们也调用了delay()函数,那么,在led()函数中我就要包含头文件delay.h,然后在main()函数中也要包含delay1s.h,若主函数中我们调用过led(),那么在编译的时候,遇到delay()和led()的时候就会对delay.h进行两次解释,那么就会出现错误。若有以上预处理命令的话,那么在第二次的时候这个_DELAY_H_已经被定义过了,那么就不会出现重复定义的问题。这就是它的作用。但是注意,在编译器进行编译的时候头文件不参与编译。 再次,我们建立一个led.h,起代码内容如下: #ifndef_LED_H_ #define_LED_H_ voidled_shan(); #endif 下面我们对上面的.c文件予以说明: (1) 在led()函数中,我们用到了51单片机的一些寄存器的定义(P1),所以我们要包含reg52.h,而且我们用到了delay()函数,所以我们要包含delay.h, (2) 在main.c 中,我们用到了led.c 中的函数,所以我们要写上led.h (3) 对于头文件reg52.h,如果不知道该不该写的时候,都写上。 (4) 除了主函数之外的.c文件,都要在开始的地方包含自己的.h文件 评分 |
|
相关推荐
23 个讨论
|
|
只有小组成员才能发言,加入小组>>
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 10:56 , Processed in 0.756442 second(s), Total 56, Slave 45 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号