您好,欢迎访问三七文档
当前位置:首页 > 办公文档 > 其它办公文档 > keil-C51模块化编程经验总结
模块化编程1模块化编程(keil)前言:看过小编前段时间上传的那份有关C51程序书写,介绍#include指令两种写法的区别和使用typedef声明新类型名等方面知识的文档,可能会对#include指令的两种写法不是很明白。比如,什么时候适合用“#include”,什么时候又适合用“#include”。本次小编将通过介绍如何在keil软件里面进行模块化编程来详细说明。为什么要进行模块化编程:一般而言,一个小程序只包含一个源程序文件,在这个源程序文件中又包含若干个函数(其中有一个是main函数)。刚开始写程序,很多读者在keil里面编程,几乎都是一个程序一个源程序文件(小编刚开始写程序也是一样滴)。当然,刚开始写的程序都是些小程序,所以进行模块化编程也没这个必要。不过随着编程者知识的积累,当尝试着去写大程序时就会发现,当程序规模较大时,所包含的函数的数量较多,如果把所有的函数都放在同一个源程序文件中,则此文件显得太大,不便于编译和调试。而且有时连自己都会被弄得稀里糊涂的,那就更不用说把程序拿个别人看了。所以为了便于调试和管理,可以使一个程序包含若干个源程序文件,每个源程序文件又包含若干个函数。(一个源程序文件就是一个程序模块,即将一个程序分成若干个程序模块。)接下来小编将通过介绍“数码管模拟时钟”这个程序来给大家详细的介绍三种模块化编程方法:(提示:此次小编介绍的这三种模块化编程方法相互之间是存在着一定的联系的,所以读者最好按照从前及后的顺序浏览,免得看到后面的内容时会很模糊。另外,虽然文章篇幅很长,但信息量不多,需要注意的知识点可能“藏在了”某些不起眼的地方。这点小编今后会逐渐完善。此外,keil版本为UV4,与UV5的不同文中会具体细节具体说明。)方法一:一个“.c”文件对应一个“.h”文件。步骤一:(建立源程序文件)新建一个工程后,我们新建一个源程序文件,保存时我们不能像往常那样直接保存在之前建的那个文件夹里面,而是在之前建的那个文件夹里再建一个文件夹。新建的这个文件夹是用来专门放“.c”“.h”文件的,所以我们就给它命名为“ch”(或其它合法文件名)。如下图复杂的事情要简单做。简单的事情要认真做。认真的事情要重复做。重复的事情要创造性地做。2图1然后进入刚新建的这个“ch”文件夹,把要保存的“.c”或者“.h”文件保存在这里面。如下图图2刚我们保存的是一个“.c”文件,然后我们按照“数码管模拟时钟”需要的几大模块(主函数、初始化函数、显示函数)再新建几个源程序文件,按照刚才的方法依次保存在“ch”文件夹里面。下图中小编又新建和保存了两个“.c”源程序文件,及其对应的“.h”文件。如下图模块化编程3图3图4其中“.h”文件与“.c”新建和保存方法一样,唯一不同就是把“.c”中的“c”改为“h”。这样我们就完成了第一步,接下来我们就开始第二步。(打字好累啊,还有那么多)步骤二:(对各类工程目录文件进行分类——UV5自动设置生成故不需要此步)首先,点击工具栏类似于一个魔法棒的按钮。如下图复杂的事情要简单做。简单的事情要认真做。认真的事情要重复做。重复的事情要创造性地做。4图5以前我们写程序都是在检查程序没错误后,才点击此按钮,把生成hex文件选项勾上。这里我们可以“顺便”提前把这个选项勾上,就可以避免写完程序后总是忘勾此选项了。之所以称为顺便,是因为我们点击这个按钮的主要目的不是为了去勾上hex文件生成选项,而是为了在编译的时候让各类工程目录文件进行自动分类。比如,输出类文件归类在一个文件夹里,清单类文件归类在一个文件夹里。具体操作如下:点击进入后,我们点击对话框里面“output”这个按钮。然后勾上hex文件生成选项。如下图图6【说明:以下两步在UV5版本不需要手动操作,软件会自动设置并生成分类文件。如图13】模块化编程5然后我们点击“SelectFolderforObjects”按钮。如下图图7出现一个对话框(图8)。我们点击新建文件按钮(或者在空白处单击右键新建一个文件夹),就在此对话框里新建了一个文件夹。由于我们开始点击的是“Output”,我么就给此文件夹命名为“Output”(或其他合法文件名)。重命名后一定要记得进入这个文件夹,单击“OK”自动退出才行(图9),否则工程目录文件中的输出类文件(这里就指出了,此文件夹是用来装输出类文件,比如说hex文件)在编译时是不会被自动分类到里面的。图8复杂的事情要简单做。简单的事情要认真做。认真的事情要重复做。重复的事情要创造性地做。6图9然后我们点击“Output”右边的“Listing”按钮,进入后点击“SelectFolderforListing”按钮。如下图图10接下来的操作和前面一样。只是要把新建的文件夹命名为“List”(或其他合法文件名),然后点进此文件夹,再单击“OK”按钮自动退出(此文件夹的作用就是将工程目录文件中的清单类文件归类到此文件夹里)。如下图模块化编程7图11以上操作做完后,此时我们一定要记得点击剩余窗口的“OK”按钮,否则我们之前勾的生成hex文件选项仍没被勾选上。如下图图12这样我们就完成了两步了。然而,在keil的UV5版本,以上关于文件分类的操作步骤,keil软件是会自动设置完成的,所以不需要人为的手动操作。生成的两个文件夹名分别为“Listings”和“Objects”(如图13),眼尖的读者应该会注意到这两个单词在哪里出现过——也即就在前面的两步操作中,我们分别点击“Output”和“Listing”按钮后,再点击“SelectFolderforObjects”和“SelectFolderforListing”按钮,看到这应该就知道那两个文件夹的文件名的来由咯。从此可见,keil软件升级后的变化其实不大,但至于升不升级,各有利弊,由读者们自行斟酌。复杂的事情要简单做。简单的事情要认真做。认真的事情要重复做。重复的事情要创造性地做。8官方网站:图13接下来我们就开始第三步。步骤三:(给整个工程进行重命名操作)首先,我们点击工具栏中有个用三种不同颜色的正方形叠加起来的按钮(就在上一步点击的那个类似魔法棒的按钮的右边)。如下图图14模块化编程9点击后弹出一个对话框,里面的排布有以下这些对应关系。如下图图15其实第一栏就是整个工程的工程名(系统默认为Target1),我们可以对它进行重命名(双击即可)。这里小编就给它重命名为“数码管模拟时钟”。在第一步中,我们建立了三个“.c”源程序文件,也即三个程序模块,而上图中的第二栏就相当于是此工程所包含的各个模块的名称。而第二栏中只有一个默认文件怎么办?其实很简单,我们用鼠标左键双击它下面的空白处即可(或者点击新建文件夹按钮)。如果我们建多了或者不想要某个了,而怎么去删除呢?我们只需要用鼠标左键单击一下要删除的文件名,然后点击删除按钮即可。如下图图16右边的那两个黑色箭头的功能是返回上一步操作和下一步操作。如果我们想按照自己的意愿来排布这几个文件,我们就用鼠标左键长时间单击住需要移动的文件,这样我们就可以移动该文件到我们想排布在哪的位置。复杂的事情要简单做。简单的事情要认真做。认真的事情要重复做。重复的事情要创造性地做。10第一栏和第二栏我们现在都知道代表的是什么,而且知道了怎么去操作。但第三栏代表的是什么呢?其实第三栏才是最重要的。以前我们添加“.c”文件都是在窗口的左侧,用鼠标右键单击后选择添加。这里小编给大家介绍另一种添加“.c”文件的方法。既然放在这里说,当然与第三栏是有关联的。的确,在这里我们想要给第二栏的哪个程序模块里添加“.c”文件,我们只需用鼠标左键单击下该模块(蓝色光标覆盖上),然后点击第三栏的“AddFiles”按钮,这时会弹出一个窗口。在第一步的时候我们把“.c”文件都是保存在“ch”文件夹里的,所以这里我们就打开“ch”文件夹,然后把对应的“.c”文件添加即可。如下图图17图18模块化编程11图19然后按照这个操作把其它两个程序模块对应的“.c”文件添加到各模块中。添加完各模块的“.c”文件后,同样的一定记住点击“OK”按钮(如下图),否则刚添加的“.c”文件也是没被添加到各模块的。图20经过以上操作,我们就做完了一个程序模块对应一个“.c”文件的准备工作,得到了下图中的效果。(看了是不是觉得一目了然)复杂的事情要简单做。简单的事情要认真做。认真的事情要重复做。重复的事情要创造性地做。12图21如果你嫌这样太麻烦,不想一个程序模块对应一个文件。那么小编在这里再向大家介绍一种“简便”方法——我们在第二栏不像之前那样一个程序模块对应一个文件,而就一个文件,小编给它重命名为“SourceGroup”(或其它合法文件名),然后将所有的“.c”文件都添加到这个文件里面。如下图图22模块化编程13图23至于今后编程时大家选哪种格式,这里没有硬性要求,读者可以结合自己的编程风格进行选择。(后面的例程小编均是以第一种格式,其它风格请自行补脑哟)。接下来我们就开始具体介绍如何模块化编程了。步骤四:(如何模块化编程)首先,我们将自建的头文件的基本框架搭起。如下图图24复杂的事情要简单做。简单的事情要认真做。认真的事情要重复做。重复的事情要创造性地做。14图25其中“#ifndef”和“#define”所在两行后面的字符串编程者是可以随便定义的,但必须保证是合法的C语言标识符,以及不能与其它文件重复。不过小编还是建议大家都写相应头文件的名称,比如说初始化函数的头文件名是“init.h”,所以我们就写“INIT_H”,显示函数类似就写“DISPLAY_H”。因为这样就可以避免有多个头文件时出现重复定义而出错。对于“#ifndef……#define……#endif”这个结构具体有什么作用,小编结合网友的说法以及小编自己查找到的资料来解释说明:C语言专门定义了两个预处理语句#ifdef与#ifndef,它们用来测试某个名字是否已经定义。故以上结构的大概意思就是说:如果没有定义(宏定义)一个字符串,我们就定义它,然后执行该条件语句中的内容;如果定义过了就跳过不执行任何内容。其目的也就是为了保证该头文件的内容只被包含一次(条件包含)。比如第一次包含头文件init.h时,将定义名字INIT_H;此后再次包含该头文件时,会发现该名字已经定义,这样将直接跳转到#endif处。更形象的解释如下:比如在keyscan()函数中我们调用了delay()函数,然后在main()函数中我们也调用了delay()函数。那么,在keyscan()函数中就要包含头文件“delay.h”,然后在main()函数中也要包含“delay.h”。若主函数中我们调用过keyscan(),那么在编译时,遇到delay()和keyscan()就会对“delay.h”进行两次解释,因此就会出现错误。若有以上预处理指令的话,在第二次的时候这个DELAY_H就已经被定义过了,所以就不会出现重复定义的问题。这就是它的作用。(有兴趣的读者也可以去查找相关资料加深自己的理解。)但是,“#ifndef……#define……#endif”结构并不是强制必须要包含在头文件里,可以不写。不过根据以上对此结构的解释说明,从一个程序的可移植性出发,小编建议大家此结构还是要有。其实究竟该如何进行模块化编程,最直接的方法是以视频的形式介绍。可刚开始的时候没想到这种方法(小编真的out了……),小编也就只好继续通过打字来介绍。如果有哪里介绍得不清楚,可以通过各种联系方式与小编交流。考模块化编程15虑到工作量,下面小编先将各模块的程序代码先展示如下(数码管、LED的锁存语句顺序待完善,但程序只是方便大家更好的理解):主函数模块:#includereg52.h#includeinit.h#includedisplay.hUchartt;intmain(void)/***主函数***/{Ucharhour=23;Ucharminute=59;Ucharsecond=50;//刚上电时时间是“23:59:50”(值可以
本文标题:keil-C51模块化编程经验总结
链接地址:https://www.777doc.com/doc-5696476 .html