首页 理论教育 如何进行模块化编程及模块之间的交流?

如何进行模块化编程及模块之间的交流?

时间:2023-06-28 理论教育 版权反馈
【摘要】:表5-5 任务模块划分5.3.2.1 变量定义把一个任务分解成不同的功能模块,模块之间往往需要进行“交流”。

如何进行模块化编程及模块之间的交流?

我们将任务分解为如下几个模块,并分别加以实现,见表5-5。

表5-5 任务模块划分

978-7-111-55685-5-Chapter05-20.jpg

5.3.2.1 变量定义

把一个任务分解成不同的功能模块,模块之间往往需要进行“交流”。比如数码管显示模块,需要根据不同的时间值,显示不同的数码;而这个不同的时间值又是在定时器中断服务函数中修改。这里我们定义一个全局变量SecVal(中文意思,可理解成“秒值”),并初始化为9,以实现一通电就从9开始倒计时。

978-7-111-55685-5-Chapter05-21.jpg

变量SecVal被不同模块调用,我们称这种变量为“全局变量”。“全局变量”一般定义在函数外部,从定义或声明它的地方开始,任何一个函数都可以访问它。可见,从某种意义上,全局变量使用起来似乎十分方便,“随处”“随时”可以使用它。但正是这种随意的“方便”,有时让人“追悔莫及”。试想:若变量SecVal被100个函数使用和修改,而其中某个函数对它执行了错误的操作,你能很容易找出这个函数吗?所以,记住一句话:全局变量猛于虎,一般情况下,我们尽量少用,甚至不用全局变量。

与全局变量对应的是局部变量,顾名思义,它是“局部”的,一般是指定义在某个函数内部的变量,因此它只能被定义它的函数所使用。在前几章我们多次定义并使用了“延时函数”,在函数内部定义的变量就是局部变量,它只在这个延时函数中有效。这样,在不同函数中,可以定义名字相同的变量,而不会相互冲突。比如,我们定义了三个延时函数,分别是Delay1、Delay2、Delay3,在这三个函数都定义了一个无符号整形变量i。这样的做法是允许的。

978-7-111-55685-5-Chapter05-22.jpg

5.3.2.2 定时器初始化

STC15F2K60S2有三个定时器T0、T1和T2,用户可以根据需要灵活选用。这里我们使用T0。

定时器的初始化需要设置好工作方式TMOD、设定初值(TH0、TL0)、是否开放中断(T0本身ET0,总开关EA)及其优先级(PT0)等相关设置。如图5-7所示,为T0初始化函数,程序中已给出详细注释,这里不再赘述。

978-7-111-55685-5-Chapter05-23.jpg

图5-7 T0初始化函数

想一想

1.我们要实现10s循环倒计时,为什么图5-7中让T0每隔50ms中断一次,而不是每隔1s中断一次。提示:对十六位定时器而言,其最大定时时间是有限的。

2.既然图5-7只是50ms中断一次,那我们如何实现1s的计时呢?

5.3.2.3 定时器中断服务函数

如果在初始化时,还开放了相应的中断功能,则用户还必须给出相应的中断服务函数。当我们使用C语言进行编程时,使用关键字“interruptn”形式来表示该函数为“中断服务函数”,其中n的取值非常重要。那么请读者回顾一下,不同的n值对应不同功能部件的中断,请完成表5-6。

表5-6 n的取值与功能模块中断的对应关系

978-7-111-55685-5-Chapter05-24.jpg(www.xing528.com)

对应图5-7给出的初始化函数,前文我们已经定义了全局变量Sec_Val,我们要在定时器中断服务函数中实现对变量Sec_Val的修改。毫无疑问,Sec_Val只能每隔1s变化一次,而定时器T0是每隔50ms中断一次,怎么办?请读者仔细阅读图5-8中断服务函数。

可见,我们在中断服务函数中仅使用一个变量Cnt_1s来计数:每中断一次,变量Cnt_1s执行一次加1操作。由于中断是每隔50ms发生一次的,这意味着每计一个数相当于50ms,当Cnt_1s加到20时,说明1s时间到,我们可以修改秒值变量Sec_Val了。

978-7-111-55685-5-Chapter05-25.jpg

图5-8 T0的中断服务函数

想一想

1.变量Cnt Is是全局变量还是局部变量?为什么?

2.变量Cnt Is定义时,还出现一个关键词“static”,是否可以将它去掉呢?提示:静态局部变量的数值不会自动复位,你给它写什么,它就保留该值;而自动变量则每次被调函数执行完毕后,这个变量都会自动复位为初始值。

5.3.2.4 数码管显示模块

前面我们已讲过,对数码管显示而言,一般通过数组查表法实现会比较简洁。首先定义一个对应特性数码管的一维数组,然后根据需要显示的内容,查询数组元素即可。请读者阅读图5-9数码管显示函数。

978-7-111-55685-5-Chapter05-26.jpg

图5-9 数码管显示函数

可见,由于秒值变量SecVal被限制在0~9之间,通过Table[Sec_Val]操作就实现了对应数码的数码管显示了。

5.3.2.5 主函数

一个程序有且只能有一个主函数main。主函数main是统帅,它实现对各个功能模块的有序调配,从而最终实现控制目标。具体函数如图5-10所示。

978-7-111-55685-5-Chapter05-27.jpg

图5-10 主函数

请读者编写完整的控制程序,并调试验证。

动一动

请把图5-8定时器中断服务函数中的static去掉,再重新编译程序,观察运行结果,结合实验现象再次解释static的用处。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈