编程思路漫谈
一、前言
长久以来,都想写一篇关于编程思想的文章,但是一直没敢下笔。因为这实在是一个比较难以用文字表达清楚的话题。vb采用什么的编程机制
思想是什么呢?
思想是隐藏在灵魂深处的东西。它对外的展现,也许是种观点,也许是种方法,也许是种技巧。
但更多时候,思想也许只是个一闪即逝的灵感,划过脑际不留痕迹。思想是活的精灵,就像流水,千回百转,奔流不息。而当我们想去捧起,那水却又悄悄从指尖缝隙里流走。
思想就是这么得不可捕捉,没有常形。而一旦被捕捉到了,那思想便也就从那一刻开始定格、僵化、失去活力,成为一潭死水。这样的思想又有何用呢?
语言文字,由于它的局限性,它也许可以表述编程的思路,却很难传递编程的思想。编程思想有时只能意会却不能言传。
因此,匠人只能退而求其次,就写一篇关于编程思路的手记吧。二、程序的基本结构
对于新手来说,背熟了指令集并不代表你就会写程序了。就像我们普通人,即使认识了所有的汉字,但并不代表就会写文章了。
如何把那一条条指令汇集成程序,并顺利实现预期的要求呢?或者说,如何根据具体的要求构建程序的框架呢?这往往成为新手上路后遇到的第一个“坎”。
那好,就随着匠人娓娓的叙说,从最简单的程序结构开始,进行一场进阶之旅吧……
单片机的程序都是为了实现某个特定的功能而定制的。因此每个程序的流程也不可能完全相同。但是写得多了,总还是有些规律可循。事实上,大多数程序都可以套用这样一个基本流程结构(参见图 3.1:基本程序结构)。
图 3.1:基本程序结构
这是一种比较完美的基本结构(完美的标准就是“简单有效”)。在这个程序结构中包含了两部分:
1、初始化程序
单片机上电复位后,从复位入口处开始运行程序。这个时候,应该先对系统进行自检和初始化动作。系统的初始化动作包括对IO口、RAM (变量)、堆栈、定时器、中断、显示、ADC、以及其它功能模块的初始化。初始化动作一般只需要执行一遍。
如果有必要,还可以在这段程序里建立分支结构,如热启动和冷启动分支。程序可以根据系统复位类型、系统自检的结果或其它条件,选择性地执行初始化动作。
2、主程序循环体
初始化程序结束后,系统的工作环境已经建立起来了,这时就可以进入主程序。
主程序一般是个循环体。在这里执行的是程序要实现的具体功能。如
输入检测、输出控制及人机界面等等。这些功能语句可以直接写在主程序里,也可以写成子程序形式,由主程序进行调用。
三、模块化的程序结构
原则上来说,匠人是不会在主程序里直接写功能语句的(喂狗指令除外)。一个好的主程序结构应该通过子程序去调用具体功能模块,这是程序模块化的要求。那种“脚踩西瓜皮,滑到哪里算哪里”可不是我们的风格哦。
在这种模块化的程序结构中,主程序仅仅是执行调度功能,负责轮流调用功能模块程序。主程序每循环一圈,所有的功能模块都被调用一次(参见图 3.2:模块化程序结构)。
图 3.2:模块化程序结构
显然,采用了这种结构后,各个模块之间相互独立性较强。我们可以象搭积木一样,很方便地增加或减少主程序调用的模块。
四、模块的事件驱动机制
由于主程序是按顺序依次调用各个功能模块的,而有些模块可能在本轮循环中不具备执行的条件。那么如何避免这些模块也被执行呢?一个比较好的解决办法是采取事件驱动机制,来加快了主程序的循环速度,提升整个系统的实时性。
所谓的事件驱动机制,就是给每个模块安排“使能标志”,通过使能标志来触发该模块代表的事件。也就是说,在每次进入功能模块(子程序)时,先判断该模块是否满足执行条件(功能模块使能标志=1),
如果满足则执行(同时将使能标志清零);否则直接返回即可(参见图 3.3:功能模块的程序结构)。
图 3.3:功能模块的程序结构
让我们举例说明。比如说,有一个显示功能模块,用于控制液晶的显示。实际上,我们没有必要在主程序的每次循环中都去刷新显示内容。我们只要为该显示模块定义一个显示刷新使能标志。在计时程序中
定期(比如说是0.5秒)把该标志设置为“1”。然后在显示程序开始处先判断一下这个标志。如果时间没到,则不必进行刷新显示。
某个功能模块的使能标志,可以由其它模块进行设置。就像前面说到的显示刷新使能标志一样。其显示功能由显示程序模块实现,而标志却是由计时程序或定时程序来进行设置。也就是说,虽然显示程序的执行与否受到计时程序的控制,但这两个模块之间并不存在互相调用的情况。它们之间仅仅是通过标志位进行联系。
这个显示使能标志就是一个显示刷新事件的触发条件。同时也相当于其它程序对显示模块的控制条件。在整个系统的任何其他程序模块中,当我们觉得有必要刷新一次显示时,都可以通过这个标志去通知显示模块。比如,在按键处理程序中,当用户通过按键设置,修改了显示内容。按键程序可以将显示使能标志设置为“1”,通知显示程序立即刷新显示,而不必等到0.5秒计时完成。
有时,可能一个标志不足以传递所有的控制信息,我们可以用更多的标志或寄存器来实现命令和参数的传递。
五、顺序调度机制与优先调度机制
前面讲的是在进入功能模块时,先查询该功能模块的使能标志。我们也可以把这种查询的动作放在主程序中。并因此延伸出两种不同的主程序调度机制:
1、顺序调度机制
如果各个模块之间没有优先级区别,我们可以采取顺序调度机制。(参见图 3.4:顺序调度)。
这种调度机制的特征是,主程序按照一定的顺序,轮流查询各个功能模块的使能标志。如果标志有效,就执行相应的模块,并清除该标志。一个模块查询或执行结束后,继续对下一个模块进行操作。全部模块操作结束后,回到主程序开始初,如此循环不止,周而复始。
采取顺序调度机制的程序结构的优点,是可以保证所有的功能模块都得到执行的机会,并且这种机会是均等的。(排排座,吃果果,你一个,我一个。呵呵!)
顺序调度机制的缺点是,某些重要的模块无法得到及时的响应。
图 3.4:顺序调度机制
2、优先调度机制
如果各个功能模块有优先级的区别,我们可以采取优先调度机制。(参见图 3.5:优先调度)。
这种调度机制的特征是,主程序按照一定的优先级次序,去查询各个标志。如果高优先级功能模块的使能标志有效,则在执行完该模块(并
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论