搜索
bottom↓
回复: 36

有关于模块化编程的一个疑问

[复制链接]

出165入0汤圆

发表于 2012-5-9 13:31:46 | 显示全部楼层 |阅读模式
今天有幸拜读了一位高人的博客,发现这篇文章写得非常好,模块化的编写方法与组织:
http://blog.csdn.net/zhzht19861011/article/details/5974945

其中不解的是:按例子中的各个功能模块,是怎样在main函数中组织的呢?主函数只有一个大循环啊,只有一个while(1),各个功能模块又能独立运行调试,百思不得其解。

主程序主要完成程序的初始化,LCD菜单显示,监视键盘程序并根据键值更新菜单。

步骤为:

1.新建工程。

2.点击File—New(或者点击快捷图标:),新建一个文档。

3.点击File—Save(或者点击快捷图标:),保存新建的文档,在文件名后填写LCD_device.c(液晶驱动模块: LCD_device,提供显示汉字、字符和图像的接口),点击确定。

在该文档内编写LCD驱动程序。

4. 点击File—New(或者点击快捷图标:),再新建一个文档。

5. 点击File—Save(或者点击快捷图标:),保存新建的文档,在文件名后填写LCD_device.h(液晶驱动模块的头文件,模块的接口和全局变量在这里定义)。点击确定。在该文档中整理全局变量和接口函数。以上步骤之后的效果见下图:



至此,液晶驱动模块书写完毕,可以对这个模块单独的调试。

6.重复以上步骤2~5,定义 红外键盘模块:key.c与key.h

菜单模块:menu.c与menu.h

串口通信模块:uart_.c与uart.h

计算器模块:counter.c与counter.h

频率测量模块:mea_fre.c与mea_fre.h

开机次数记忆模块:eepram.c与eepram.h

7.重复以上步骤2~3,定义主程序main.c

最终效果如下图所示:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出165入0汤圆

 楼主| 发表于 2012-5-9 13:34:46 | 显示全部楼层
很想知道这些功能模块是怎样各自独立运行的,最后在主函数的组织下实现各个功能的。望高手释疑。非常感谢。

出0入4汤圆

发表于 2012-5-9 15:15:07 | 显示全部楼层
主函数只有一个大循环啊,只有一个while(1),各个功能模块又能独立运行调试?

你没看仔细吧?

模块化编程就是将各种模块分类编写,然后在主函数中直接调用,这样有利于不同项目的开发
你可以理解为模块就是键盘 LCD等外围的底层驱动,以后要用到相同的功能直接将相关模块include,然后在主程序中调用,你可以不用了解这些模块是怎么实现的,按模块的说明直接调用相关函数就好了
你不调用函数怎么会运行?

出0入0汤圆

发表于 2012-5-9 16:15:13 | 显示全部楼层
作者写的确实不错!

出165入0汤圆

 楼主| 发表于 2012-5-9 19:28:49 | 显示全部楼层
我的意思其实是想了解这么多的功能是怎么组织起来的。我知道需在主程序内调用各相关函数,可是这么多模块,实现如此的多功能,觉得有点不可思议。希望有这方面经验的高手能解释一下,怎样有效地组织这些功能,最后实现这些功能。这其中每单个模块的独一功能实现很容易,但要把他们组织成一个程序整体,是如何实现(或者叫什么时候该调用哪个模块,“同时”实现这些所有的功能的。)

出0入4汤圆

发表于 2012-5-9 19:47:44 | 显示全部楼层
嗯 模块化读程序时感觉很舒服,写程序时各个模块写起来也不错。写main()时就晕了,组织不好,而且似乎感觉流程图比较重要,但有时候写着写着就要加东西,然后就糊涂了。写main()这还是有点问题。

出0入0汤圆

发表于 2012-5-9 20:43:58 | 显示全部楼层
我一直是这么理解的,模块化程序,就是将实现不同功能的函数进行封装,留出函数之间的数据接口,每一个.c文件对应一个.h文件,在c文件中编写功能函数,在h文件中存放宏定义,全局变量的声明,函数的声明等,在需要调用函数时,直接包含.h文件,就可以实现调用,单片机某一时刻只能实现某一功能,多个功能之间可以进行协调 调用,在完成当前功能后,在运行下一个要运行的功能,

出0入0汤圆

发表于 2012-5-9 20:44:12 | 显示全部楼层
模块化是个好东西!不过也太难写了,老是错误错误。。。。。。。。

出165入0汤圆

 楼主| 发表于 2012-5-9 20:52:54 | 显示全部楼层
似乎不太好弄,按这位牛人的文章,如果我要执行计算器功能,输入一串数字,按+什么的,程序就好像必须停在这个计算器程序当中,如何每次主循环过来从头执行计算程序,那些数字还保持不动...只到我退到这个程序为止.真是没有头绪.真想知道他是怎样组织这些模块化的功能的.

出0入0汤圆

发表于 2012-5-10 10:23:48 | 显示全部楼层
261854681 发表于 2012-5-9 20:52
似乎不太好弄,按这位牛人的文章,如果我要执行计算器功能,输入一串数字,按+什么的,程序就好像必须停在 ...

应该要加分时思想吧:http://www.ourdev.cn/forum.php?m ... D%E5%AD%A6%E8%80%85

出0入4汤圆

发表于 2012-5-11 01:01:14 | 显示全部楼层
261854681 发表于 2012-5-9 20:52
似乎不太好弄,按这位牛人的文章,如果我要执行计算器功能,输入一串数字,按+什么的,程序就好像必须停在 ...

别把模块化编程想得太高深了,其实模块化编程和非模块化编程差别不是很多。
使用模块化编程主要是为了通用函数在不同项目中可以直接调用或修改部分代码就可以直接使用,特别是在较大的项目中都是分工合作的,不同的人编写不同的功能代码,然后整合,你不需要清楚的知道别人完成该功能的函数是怎么写的,你只需按他提供的函数说明直接调用就好了。

在非模块化编程中,我们通常是将所有的子函数放在一个.C文件中,然后在main函数中调用。
而在模块化编程中,通常的做法是将子函数按功能分类放在不同的.C文件中,然后在.h中将对应.C中需要对外公开的函数进行申明,在main函数中通过include引用后再调用。

简单的说就是模块化编程就是将一个.C文件按子函数功能分割为多个.C文件。你一个.C文件该怎么调用子函数的的,多个.C文件也一样调用。

出0入0汤圆

发表于 2012-5-11 01:24:21 | 显示全部楼层
sniper.q 发表于 2012-5-11 01:01
别把模块化编程想得太高深了,其实模块化编程和非模块化编程差别不是很多。
使用模块化编程主要是为了通 ...

表面看起来是你理解的这样,但设计思路却不是简单的把一个分成多个。

面向过程的思路:程序是一个操作流水线,有起始、分支判断(循环)和结束。

模块化或者对象化的思路:首先定义和实现各个模块的属性和行为,使之有明确的功能和接口,然后整个程序的运行过程就是各个模块的通信过程,main方法(函数)仅仅作为程序运行的一个总入口。
在高度模块化的项目中,你是不会看到main方法的大循环的,取而代之的是一个调度系统。

出0入4汤圆

发表于 2012-5-11 09:06:40 | 显示全部楼层
crtfor 发表于 2012-5-11 01:24
表面看起来是你理解的这样,但设计思路却不是简单的把一个分成多个。

面向过程的思路:程序是一个操作流 ...

可实际上模块化编程最主要是为了分布式开发和代码的重复利用缩短开发周期。

模块化不是面向对象,按我的认知模块化是编程方法或者说一种编程规范,面向对象或面向过程是编程思想目的实现的不同方式。

出0入0汤圆

发表于 2012-5-11 10:38:21 | 显示全部楼层
sniper.q 发表于 2012-5-11 09:06
可实际上模块化编程最主要是为了分布式开发和代码的重复利用缩短开发周期。

模块化不是面向对象,按我的 ...

但是在逻辑复杂的项目中,简单的“分开”所带来的弊端绝对不会比它带来的益处少多少。其实分与不分没什么必然的好与坏,项目组完全可以让不同的人写不同的函数,然后都粘贴到一个文件中,按名字划好区域,开发效率不会降低多少,而且会减少很多隐含的问题,你说呢?

其实说起设计模式,大部分的设计模式只在干一件事,就是解耦。比如由于需求的变化,屏幕要换了,当然屏幕的驱动也要换,而怎么换就要看当初的设计了。最理想的情况是:
排除硬件连接的变化,只需要改变显示部分的C文件,连头文件都不用动。

也就是说系统只要关心显示什么,完全不关心显示模块是怎么实现的。这就是解耦,这才是真正意义上的模块化。跟你说的“你不需要清楚的知道别人完成该功能的函数是怎么写的,你只需按他提供的函数说明直接调用就好了”有着很大的区别。

试想,你因为把独立键盘换成了矩阵键盘而不得不把一半的模块调整一遍,在一堆文件中各种调试——为什么不放在一起呢?

出0入442汤圆

发表于 2012-5-11 10:54:24 | 显示全部楼层
你可以这样考虑:
它使用类似于Windows事件的方式来循环,即处理完当前事件,就回到主循环中,执行下一个函数。所以当没有事件发生,事件立刻返回,否则进入事件处理。
比如你有10个数字需要通过I2C接口发出,那么在事件处理循环中,注册(即加入)一个函数,则每次循环如果发现I2C控制器为空闲,则输出一个字符,否则直接返回。当缓冲全部输出,就不用再去发送了。

出0入0汤圆

发表于 2012-5-11 11:17:42 | 显示全部楼层
再看一些资料吧

出0入0汤圆

发表于 2012-5-11 11:21:37 | 显示全部楼层
用面向对象的方法去设计系统的每一个模块

出0入4汤圆

发表于 2012-5-11 11:56:18 | 显示全部楼层
crtfor 发表于 2012-5-11 10:38
但是在逻辑复杂的项目中,简单的“分开”所带来的弊端绝对不会比它带来的益处少多少。其实分与不分没什么 ...

也就是说系统只要关心显示什么,完全不关心显示模块是怎么实现的。这就是解耦,这才是真正意义上的模块化。跟你说的“你不需要清楚的知道别人完成该功能的函数是怎么写的,你只需按他提供的函数说明直接调用就好了”有着很大的区别。

不关心显示模块是怎么实现的和不需要清楚的知道别人完成该功能的函数是怎么写的有区别吗?都是只要知道应该怎么用,需要传递什么参数,返回什么结果,至于怎么实现可以不管。也就是所谓的黑盒。要LCD显示一个字符,我只要调用显示函数,传递显示坐标,显示字符,就好,至于与LCD是怎么通讯的,需要什么时序我可以不管。

项目组完全可以让不同的人写不同的函数,然后都粘贴到一个文件中,按名字划好区域,开发效率不会降低多少,而且会减少很多隐含的问题,你说呢?
的确你要这样做也可以,但是你没注意我说的吗?“模块化编程最主要是为了分布式开发和代码的重复利用缩短开发周期。”
比如两个项目都是用同一种LCD显示,你是去一个很庞大的源代码中找出相关显示驱动代码复制过来,还是直接复制相应的.C.H?必然是后一种方便而且不容易出错。

出165入0汤圆

 楼主| 发表于 2012-5-11 12:39:43 | 显示全部楼层
我想我该去看看面向对面的程序设计方法了.看看能否找到原作者的那种思路.

出0入0汤圆

发表于 2012-5-11 13:26:12 | 显示全部楼层
sniper.q 发表于 2012-5-11 11:56
也就是说系统只要关心显示什么,完全不关心显示模块是怎么实现的。这就是解耦,这才是真正意义上的模块化 ...

很明显的一个问题:资源冲突呢?


不关心显示模块是怎么实现的和不需要清楚的知道别人完成该功能的函数是怎么写的有区别吗?都是只要知道应该怎么用,需要传递什么参数,返回什么结果,至于怎么实现可以不管。也就是所谓的黑盒。要LCD显示一个字符,我只要调用显示函数,传递显示坐标,显示字符,就好,至于与LCD是怎么通讯的,需要什么时序我可以不管。

区别非常大,首先出发点就不一样,我说的不关心是完全不关心,也就是说我的程序是固定的,随便你驱动怎么改,模块是为系统服务的。而你说的拿人家的代码用就是说你的程序根本没有这个功能,复制进来才有,你的程序总是随着别人的代码而改变。一个倾向于设计,一个倾向于编码。
比如IIS需要精确的定时,人家用的全都是延时函数,而你很多地方又用了个定时中断,你是改你的程序还是该人家的程序。如果你改自己的,你要改多少?改人家的就不是代码重用了。拿来就用和拿来改改再用完全不是一个概念。
如果没有统一的接口,你试试换一个任何一个驱动,你能保证你不用动主函数?


比如两个项目都是用同一种LCD显示,你是去一个很庞大的源代码中找出相关显示驱动代码复制过来,还是直接复制相应的.C.H?必然是后一种方便而且不容易出错。
我还是问,如果遇见冲突,你是改什么?Debug时两种方式有什么区别?

模块化的根本目的在于将功能和底层实现抽象和隔离开,添加或者删除任何模块都不会破坏整个功能的完整性。而调用人家的代码这种形式上的模块化根本没有脱离过程化编程。当然,任何接口化和对象化的代码都可以用过程化的编程来完成,甚至过程化编程总能带来更好的性能。我只能说拿2/3时间设计、1/3时间写代码,和拿1/2时间写代码、1/2时间修改代码的感觉完全不同。

出165入0汤圆

 楼主| 发表于 2012-5-14 14:06:38 | 显示全部楼层
面向对象的编程方法似乎是抽象啊,不好捉摸.

出0入0汤圆

发表于 2012-5-14 14:31:28 | 显示全部楼层
261854681 发表于 2012-5-14 14:06
面向对象的编程方法似乎是抽象啊,不好捉摸.

其实先进的编程思想还有“面向接口”和“面向切面”等等。前者用于统一行为和易于更换组件,而后主要者用于分级和统一控制。

出165入0汤圆

 楼主| 发表于 2012-5-14 19:02:17 | 显示全部楼层
请教楼上,关于面向接口的编程思想在哪本教材里面有介绍,若是要学习该从哪些方面入手啊.现在总感觉学习基本处于停滞状态:有关单片机的各个单元功能(单一功能)已能熟练运用了,比如使用串口中断,定时器中断,DA,AD驱动在单片机上独立操作均没有问题,问题是一处于综合运用状态就觉得难啊,难于合理将各个单元模块合理地搭配起来.就像如题这样的项目上,需将各个小功能"组合"起来,形成一个整体的功能产品.迈过这一关可能才算学习单片机真正入门了啊.

出0入0汤圆

发表于 2012-5-14 19:34:27 | 显示全部楼层
261854681 发表于 2012-5-14 19:02
请教楼上,关于面向接口的编程思想在哪本教材里面有介绍,若是要学习该从哪些方面入手啊.现在总感觉学习基本 ...

论坛里不是有很多程序吗,看看了解就行,比如:万年历
不也是多个模块组合:显示、按键检测、红外控制、响铃检测、播放乐曲、公历转农历、温度更新(读DS18B20)、时间更新(读DS1302)……


读上面这篇文章,对以下3点有个大概的了解
1、普通的单任务顺序执行
2、状态机
3、多任务并行执行

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出165入0汤圆

 楼主| 发表于 2012-5-14 21:03:36 | 显示全部楼层
感谢,似乎有点想法了.

出165入0汤圆

 楼主| 发表于 2012-5-14 21:12:07 | 显示全部楼层
那些程序也已读了很多了,没有发现章法可循,然后看到如题原作者的文章,对他的这个程序规划很感冒,所以啊,希望弄清原作者的思路,如果每个程序都可以这样规划,则不再怕有很多功能的单片机程序的编写了,也就能把CPU的资源利用得干净合理的.该多好.

出0入0汤圆

发表于 2012-5-14 21:21:31 | 显示全部楼层
简单来说,作为一个高层指派不同的人干不同的事,自己不需要知道事情怎么做,只需要明确什么事情需要什么人来做就行了。

出165入0汤圆

 楼主| 发表于 2012-5-14 21:44:47 | 显示全部楼层
这个可以明白,根本是在于有N个人(功能):第一个人什么时候做什么事,然后又第二个什么时候做什么事...第N个人什么时候做什么事?合理搭配,分别实现,最后把整个工程要求给做完了.

出0入0汤圆

发表于 2012-5-14 21:48:09 | 显示全部楼层
261854681 发表于 2012-5-14 21:44
这个可以明白,根本是在于有N个人(功能):第一个人什么时候做什么事,然后又第二个什么时候做什么事...第N个人 ...

恩,说明你也是懂得。。。然后就要具体问题具体分析了。。。

另外,楼主会用中断不?会用的话就很好解决了。

出0入0汤圆

发表于 2012-5-14 22:50:37 | 显示全部楼层
爬了上述那么多楼,貌似有点感觉,但是又说不清楚

出165入0汤圆

 楼主| 发表于 2012-5-15 13:19:36 | 显示全部楼层
是啊,良好合理的程序规划应该是入门与入深的分水岭.一定要将这个模块化的思路搞明白.

出0入0汤圆

发表于 2012-5-15 17:36:36 来自手机 | 显示全部楼层
看从单片机初学者到单片机工程师,坛子里有

出0入0汤圆

发表于 2012-5-15 17:37:50 | 显示全部楼层
看从单片机初学者到单片机工程师,坛子里有

出0入0汤圆

发表于 2012-5-15 17:39:00 | 显示全部楼层
玩下操作系统 就会有概念啦

出0入0汤圆

发表于 2012-5-15 17:40:04 | 显示全部楼层
http://www.ourdev.cn/forum.php?m ... D%E5%AD%A6%E8%80%85

出0入0汤圆

发表于 2012-5-15 22:10:55 | 显示全部楼层
做下标志,下次再好好看。

出0入0汤圆

发表于 2012-9-4 10:12:02 | 显示全部楼层
261854681 发表于 2012-5-9 20:52
似乎不太好弄,按这位牛人的文章,如果我要执行计算器功能,输入一串数字,按+什么的,程序就好像必须停在 ...

这个需要状态机的方法。专门写一个状态机的模块,在内部保存状态变量
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-26 18:17

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表