×
嵌入式开发 > 详情

单片机C51编程几个有用的模块

发布时间:2020-07-03 发布时间:
|

KeilC51常用功能模块使用说明

说明
本文档包括单片机系统中常用到的时钟中断、通讯及键盘扫描等模块(见所附源程序)的说明。这些模块使用前后台系统模型。为达到最大的灵活性,需要在用户工程中定义config.h文件,在其中定义各模块可选参数的设置,而不是直接更改源代码。
这些可选内容大部分为宏定义,如果不定义宏相应的功能在编译时被屏蔽,不会增加代码长度。具体可选内容见各模块中的说明。
在Config.h文件中还要包含一个单片机硬件的资源头文件。
各模块使用了定义在Common.h中的一些数据类型。如:BIT(bit)BYTE(unsignedchar)等,具体请参见源程序。

时钟模块
单片机软件设计中,时钟是重要资源,为了充分利用时钟资源,故设计本时钟模块。本模块使用定时器0,在完成用户指定功能的同时,还能够自动处理一些其它模块中与时钟相关的信息。
时钟模块由声明文件Timer.h以及实现文件Timer.c组成。
用户应该在Config.h中定义宏TIMER_RELOAD来设定定时器0的重装载初值。推荐的定时器0的中断时间大于1毫秒。

在程序的初始化阶段调用时钟模块的初始化函数InitTimerModule()之后,就可以使用时钟模块所以支持的各种功能。具体描述如下:
延时:当用户需要进行一定时间的延时时,可以通过调用Delay()来进行,参数为时钟中断的次数。如时钟中断周期为1ms,想进行100ms的延时,则可以调用Delay(100)。
注意:
如果延时的绝对时间小于时钟中断的周期,则不能够用本方法做到延时。

定时:当程序中需要使用定时功能时,如等待某外部事件,如果在一定时间内发生则继续执行,如果在这段时间内发生,则认为出现错误,转向错误处理机制。
在此推荐一种编程模式,但用户可以用自己认为更合理的方式处理此类问题。
这里简单说明一下关于阻塞式函数及非阻塞式函数。简单说,阻塞式函数就是当检测完成条件,如果不能够完成则等待,如:
voidCheckSomething()
{
//gbitSuccessFlagisaglobalvariable
while(gbitSuccessFlag==FALSE)
{
//donothingbutwaiting
}
}
可以看到,当bitSuccessFlag没有被设置为TRUE时,函数保持等待状态不返回,这样就是阻塞式的函数。
另外一种情况:
BITCheckSomething()
{
if(gbitSuccessFlag==TRUE)
{
//…
returnTRUE;
}
returnFALSE;
}
在这里,如果所检测的事件有没有完成,函数进行检测之后,立刻返回,通过返回值报告完成情况,如果没有完成,则等待调用者分配再次执行的机会。这样的函数就是非阻塞函数。
在应用定时功能时,首先要将检测函数定义成非阻塞函数。如上面的第二个版本的CheckSomething。
然后下面模式:
BITbitDone=FALSE;
ResetClock();//cleartimerinterrupttimescounter
while(GetClock()MAX_WAITINGTIME)
{
if(CheckSomething()==TRUE)
{
bitDone=TRUE;
break;
}
}
if(bitDone==FALSE)
{
//processtimeout
}

或者简单写成:
BITbitDone=FALSE;
ResetClock();
while(GetClock()MAX_WAITINGTIME(bitDone=CheckSomething));
if(bitDone==FLASE)
{
//…
}

软件看门狗:实现具有局限性的看门狗功能。在程序中合适的地方加入对软件看门狗的复位函数ResetWatchDog(),在Config.h中加入宏TIMER_WATCHDOGTIMEOUT。当程序运行时,如果在发生TIMER_WATCHDOGTIMEOUT次时钟中断之内没有复位软件看门狗,则系统复位。
注意:
如果没有加入TIMER_WATCHDOGTIMEOUT宏,程序中的ResetWatchDog没有任何用处,不用删除。
如果系统不能实现时钟中断,则软件看门狗也同时失去功能。
目前版本的的时钟模块的复位功能并不是完全复位,主要表现在当复位之后,系统将不再响应任何中断。所以软件看门狗只是一个程序的调试功能,不应该将它用于正式工作的程序,此时应该使用硬件看门狗。

用户自定义任务:如果想在时钟中断内执行一些耗时较短的任务,可以定义回调函数OnTimerInterrupt。函数原形为:voidOnTimerInterrupt();
如果想在发生时钟中断时执行一些功能,而这些功能又耗时相对较长,不合适放在中断响应函数内部,则可以在程序中的主循环中的任意地方添加:ImpTimerService(),同时提供原形为voidOnTimerEvent()的回调函数。具体的程序如下所示:
voidmain()
{
Initialize();
while(TRUE)
{
//…working
ImpTimerService();
//…working
}
}

voidOnTimerEvent()
{
//dosometask
}

对通讯模块提供支持:如通讯中的各种超时等,见通讯模块中的详细说明。
对键盘扫描模块提供支持:可以自动调用键盘扫描模块,见键盘扫描模块中的详细说明。
对程序调试提供支持:在程序开发过程中,有时为了判断程序是不是在工作,常用利用单片机系统的某一空闲引脚通过一个限流电阻接一个发光二极管,在程序中间隔固定时间交替控制发光管的明暗。实现这个功能只要在Config.h文件中定义TIMER_FLASHLED宏,如:
#defineTIMER_FLASHLEDP1_0
则当时钟中断发生256次之后,改变发光管的状态。



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
单片机汇编语言 如何实现点亮熄灭二极管