c++定时器
- 格式:doc
- 大小:47.50 KB
- 文档页数:5
mcs-51单片机计数器定时器详解【1】80C51单片机内部设有两个16位的可编程定时器/计数器。
可编程的意思是指其功能(如工作方式、定时时间、量程、启动方式等)均可由指令来确定和改变。
在定时器/计数器中除了有两个16位的计数器之外,还有两个特殊功能寄存器(控制寄存器和方式寄存器)。
:从上面定时器/计数器的结构图中我们可以看出,16位的定时/计数器分别由两个8位专用寄存器组成,即:T0由TH0和TL0构成;T1由TH1和TL1构成。
其访问地址依次为8AH-8DH。
每个寄存器均可单独访问。
这些寄存器是用于存放定时或计数初值的。
此外,其内部还有一个8位的定时器方式寄存器TMOD和一个8位的定时控制寄存器TCON。
这些寄存器之间是通过内部总线和控制逻辑电路连接起来的。
TMOD主要是用于选定定时器的工作方式;TCON主要是用于控制定时器的启动停止,此外TCON还可以保存T0、T1的溢出和中断标志。
当定时器工作在计数方式时,外部事件通过引脚T0(P3.4)和T1(P3.5)输入。
定时计数器的原理:16位的定时器/计数器实质上就是一个加1计数器,其控制电路受软件控制、切换。
当定时器/计数器为定时工作方式时,计数器的加1信号由振荡器的12分频信号产生,即每过一个机器周期,计数器加1,直至计满溢出为止。
显然,定时器的定时时间与系统的振荡频率有关。
因一个机器周期等于12个振荡周期,所以计数频率fcount=1/12osc。
如果晶振为12MHz,则计数周期为:T=1/(12×106)Hz×1/12=1μs这是最短的定时周期。
若要延长定时时间,则需要改变定时器的初值,并要适当选择定时器的长度(如8位、13位、16位等)。
当定时器/计数器为计数工作方式时,通过引脚T0和T1对外部信号计数,外部脉冲的下降沿将触发计数。
计数器在每个机器周期的S5P2期间采样引脚输入电平。
若一个机器周期采样值为1,下一个机器周期采样值为0,则计数器加1。
c 标准库定时器C 标准库定时器。
在C语言中,定时器是一种非常重要的功能,它可以帮助我们在程序中实现定时执行某些操作的功能。
在C标准库中,定时器的使用可以通过一些函数来实现,本文将介绍C标准库中定时器的基本概念和使用方法。
首先,我们需要包含头文件<time.h>来使用C标准库中的定时器函数。
在<time.h>中,定义了一些与时间相关的函数和数据类型,其中包括了定时器的相关函数。
在使用定时器之前,我们需要了解一些与时间相关的数据类型和函数。
在C标准库中,时间的表示通常使用time_t类型来表示,它是一个长整型的数据类型,用来表示从某个固定时间点(通常是1970年1月1日)到当前时间的秒数。
而定时器的使用通常需要用到time_t类型来表示时间。
除了time_t类型之外,我们还需要了解tm结构体,它用来表示一个时间的各个组成部分,包括年、月、日、时、分、秒等。
在C标准库中,获取当前时间的函数是time(),它返回当前时间的秒数,可以用time_t类型来接收。
而将时间转换为tm结构体的函数是localtime(),它可以将time_t类型的时间转换为tm结构体类型的时间。
这些函数在使用定时器时非常重要,因为我们通常需要获取当前时间来进行定时器的设置和判断。
在C标准库中,实现定时器的函数是alarm(),它用来设置一个定时器,当定时器时间到达时,会向程序发送一个SIGALRM信号。
我们可以在程序中捕获这个信号,并在信号处理函数中实现定时器到达时需要执行的操作。
使用alarm()函数时,我们需要传入一个整数参数,表示定时器的时间间隔,单位为秒。
当程序运行到设置定时器的位置时,定时器就开始计时,当时间间隔到达时,程序就会收到SIGALRM信号。
除了alarm()函数之外,在C标准库中还提供了一些与定时器相关的函数,比如sleep()函数,它可以让程序休眠一段时间,单位也是秒。
另外,还有setitimer()函数,它可以设置一个精确的定时器,可以用来实现一些需要高精度定时的操作。
C标准库定时器函数==========在C标准库中,定时器函数提供了一种在特定时间间隔后触发事件或者在某个时间点执行特定任务的能力。
以下是一些主要的C标准库定时器函数及其功能:1. 创建/删除定时器-----------* `timer_create`:此函数用于创建一个新的定时器。
它需要一个`timer_t`类型的变量来存储定时器的标识符,一个`struct sigevent`结构体来指定定时器的回调函数和参数,以及一个`timer_attr_t`类型的变量来指定定时器的属性。
* `timer_delete`:此函数用于删除一个已创建的定时器。
它需要一个`timer_t`类型的变量来存储定时器的标识符。
2. 定时器控制--------* `timer_settime`:此函数用于设置定时器的运行参数,包括定时器的标识符、定时器类型(周期性或单次)、回调函数、回调函数的参数、初试时间、间隔时间等。
* `timer_gettime`:此函数用于获取定时器的当前状态,包括定时器的标识符、当前时间、剩余时间等。
3. 定时器回调--------* `timer_cb`:此函数是定时器的回调函数,它会在定时器触发时被调用。
在回调函数中,您可以执行任何需要在特定时间执行的任务。
4. 定时器状态获取----------* `timer_status`:此函数用于获取定时器的状态,包括定时器的标识符、当前时间、剩余时间、状态标志等。
这些函数的使用需要结合具体的程序设计和需求来进行。
使用这些函数时需要注意错误处理和异常情况的处理,以确保程序的稳定性和可靠性。
c语言定时器算法一、概述定时器算法是一种常用的计算机编程技术,用于在特定的时间间隔内执行特定的任务。
在C语言中,可以使用定时器算法来实现定时任务、倒计时、延时等功能。
本文档将介绍C语言中常用的定时器算法,包括定时器的基本概念、定时器的实现方式以及定时器的应用场景。
二、基本概念定时器是一种用于控制时间间隔的设备或技术。
在计算机编程中,定时器通常用于在特定的时间间隔内执行特定的任务。
定时器的精度和范围取决于所使用的硬件和软件实现。
三、实现方式C语言中实现定时器的方式有多种,其中常见的方法包括:1.查询式定时器:通过查询定时器标志位的方式来实现定时器功能。
这种方式简单易行,但是精度较低,不适合需要高精度的应用场景。
2.滴答定时器:操作系统通常会提供滴答定时器,可以自动计算时间间隔并执行相应的任务。
这种方式精度较高,但是需要操作系统支持。
3.循环延时:通过循环语句来实现延时功能,通过控制循环次数来控制时间间隔。
这种方式简单易行,但是延时精度和范围有限。
4.信号量+循环延时:使用信号量来控制定时器的执行次数,通过循环延时来实现定时功能。
这种方式精度较高,适用于需要精确控制时间间隔的应用场景。
四、应用场景定时器算法在许多应用场景中都有应用,例如:1.游戏计时器:在游戏中使用定时器算法可以精确控制游戏时间,实现倒计时、时间流逝等功能。
2.定时任务:通过定时器可以实现定时执行任务的功能,例如每天自动备份数据、定期清理过期文件等。
3.延时控制:在需要精确控制时间间隔的场合,如数字信号处理、通信协议等,可以使用定时器算法来实现。
4.程序调试:在调试程序时,可以使用定时器来控制程序的执行过程,观察程序的运行状态和结果。
五、代码示例以下是一个简单的C语言代码示例,使用循环延时来实现一个定时器:```c#include<stdio.h>#include<stdlib.h>#include<unistd.h>//用于循环延时函数sleep()intmain(){intcount=10;//定时时间间隔,单位为秒while(count>0){printf("Timer:%dsecondsremaining\n",count);sleep(1);//控制时间间隔为1秒的延时函数count--;}printf("Timerfinished\n");return0;}```六、总结C语言中的定时器算法是一种常用的计算机编程技术,可以用于实现定时任务、倒计时、延时等功能。
C语言使用定时器的方法控制LED灯以1S的速度闪亮最近因为赶不上提高班的进度,老师给的教程总是断断续续的,所以我打算跟11月1号通过考试的网友们一起学习,呵呵,这也是我一教训来着,在三维里学习要坚持一步一个脚印,坚持必有奇迹,但也要跟得上大家,以后再忙也要努力实现计划了,不能再像这次一样,因为所谓的考试落下了好几堂课,不过也没有关系,能够吸取点教训总是好的。
我可以先给自己点时间多学些其它的基础知识。
今天开始学单片机的计数器了,呵呵,可能是一直因为用C语言编程序我定时老是定不准的原因,当得知学会定时/计数器后可以让单片机C语言定时准确后,我感觉学它真的很有动力,虽然编一个简单的程序也花了我好长时间,但编出来的感觉却是那么的爽快,我觉得要学会定时/计数器,关键是要学会编程控制 TCOM,TMOD,及TH和TL吧。
主要是TH和TL的准确运算。
还有就是完时以后怎么样让其跟循环语句配合使用。
今天所编的程序是利用单片机定时器控制LED灯以1S 的速度闪烁,我的晶振是12MHZ的,首先是让计时器0.02S进行一次溢出,使TF1=1,其次是利用I++循环50次,加起来为1S。
程序如下: #include;sbit LED = P1^2;void main(){unsigned char i;TMOD |= 0x10;TMOD &= 0xdf;TH1 = 0xb1;TL1 = 0xdf;TCON |= 0x40;while(1){if(TF1==1){TF1 = 0;TH1 = 0xb1;TL1 = 0xdf;i++;if(i==50){i=0;LED=~LED;}}}}。
d d _E N 02/19IHP 1C/2CProduct information / menu descriptionCCT15440CCT15441CCT15442CCT15443d d _E N 02/19The IHP with weekly program controls lighting, air conditioning, flushing, etc.|The device must not control safety-relevant applications.G etting to know the timerDisplays and operating elementsA Time displayB Channel stateC Date displayD Programmed ON timesE Display of week daysF Display of active buttonsG OK buttonH Selection buttonsI MENU buttonOperationButton FunctionMENU button•Opens the menu•In menu mode: one step back:•In programming mode: cancel programming modeSelection buttons •Switch between menu items •Increase/decrease value OK button•In menu mode: select menu item •In programming mode: confirm settingMenu structurePROGRAM TIME/DATEMANUAL CONFIG ENDCHANNEL 1TIME CHANNEL 1LANGUAGENEW SET DATEPERM ON PIN CHECK SU-WI PERM OFF FACTORY SETTINGSMODIFY WEEK DAY OVERRI ONINFO DELETEFORM DATE HOLIDAYENDENDFORM TIMEENDd d _E N 02/19The basic settings, such as date, time, etc., must be carried out when starting for the first time or following a reset.The device starts in the settings menu with the item LANGUAGE .1Select the language.2Confirm the message FORM DATE .3Select the date format.4Set the year.5Set the month.6Set the day.7Confirm the message FORM TIME .8Select the time format.9Set the hours.0Set the minute.^Select summer time/winter time.A switching time always consists of one time at which the load is switched on and one time at which the load is switched off. Y ou can either set switching times for a specific day of the week or copy them for multiple week days. Copied week days are referred to as a block.T o set a switching time, perform the following steps once for ON and once for OFF :1Confirm message about free memory slots.2Select ON or OFF .3Set the hour.4Set the minute.5Set the day of the week.6If the switching time is only to be valid for one week day, select SAVE .The switching time is set.7If the switching time is to be copied as a block for multiple week days, select COPY .8Select further days of the week and confirm in each case.Week days contained in the block are indicated in the week days display.To remove a week day from the block, select the week day again using the selection buttons.9Once the desired week days have been set, select COPY .Initial setupSetting a switching timePROGRAMCHANNELC1CHANNELC2NEWNEWd d _E N 02/19Y ou can change the time for the switching times. In the case of switching times within a block, you can select whether the modification of the time is to apply to the whole block or only to a specific week day. This week day is then removed from the block.1Select the switching time.The display runs through all switching times in sequence. If no switching time is set for a week day, this is indicated in the display by --:--.If the selected switching time is part of a block, all days of the block are shown in the week day display. The selected week day flashes.2Set the hour.3Set the minute.4If the selected switching time is only set for one week day, only the option SAVE appears.5If the selected switching time is part of a block, select MODIFY BLOCK or MODIFY WEEK DAY .- MODIFY BLOCK changes the time for all switching times of the block.- MODIFY WEEK DAY changes the time for the selected switching time. The selected switching time is re-moved from the block.Y ou can delete switching times at any time. If a switching time is part of a block, you can delete the entire block or remove the switching time from the block. Y ou can also delete all switching times of a channel simultaneously.Deleting a switching time:1Select SINGLE .2Select the switching time.The display runs through all switching times in sequence. If no switching time is set for a week day, this is indicated in the display by --:--.If the selected switching time is part of a block, all days of the block are shown in the week day display. The selected week day flashes.3If the selected switching time is only valid for one week day, only the option DELETE WEEK DAY appears.4If the selected switching time is part of a block, select DELETE BLOCK or DELETE WEEK DAY .- DELETE BLOCK deletes all switching times of the block.- DELETE WEEK DAY removes the selected switching time from the block and deletes it.Deleting all switching times of a channel:1Select DELETE ALL .2Confirm with CONFIRM .Modifying a switching timePROGRAMCHANNELC1CHANNELC2MODIFYMODIFYDeleting a switching timePROGRAMCHANNELC1CHANNELC2DELETEDELETEd d _E N 02/19With the holiday function, you can switch a channel on or off completely for a longer period. The programmed switching times do not apply while the holiday function is active. Y ou can only set one holiday time per channel.1Select ON or OFF .2Confirm BEGIN HOLIDAY .3Set the year.4Set the month.5Set the day.6Set the hour.7Confirm END HOLIDAY .8Set the year.9Set the month.0Set the day.^Set the hour.A PIN protects against unauthorized use.If you have forgotten your PIN, contact the Customer Care centre in your country, stating the serial number of your device.1Select WITH PIN .NO PIN cancels the PIN protection function.2Confirm CURRENT PIN .3Set new PIN.|The PIN digits are set one after the other with +/- and confirmed with OK . A digit that has already been set can no longer be changed. When the last digit is confirmed with OK , the PIN is saved. If in any doubt, exit the PIN setting procedure with MENU .Setting the holiday functionMANUALCHANNELC1CHANNELC2HOLIDAYHOLIDAYSetting the PINCONFIGPINd d _E N 02/19Y ou can set override or permanent switching either via the MANUAL menu or using combinations of buttons on the device.Override switchingIf you wish to switch a channel briefly to the other switching state (e.g. from ON to OFF ), activate override. This state is only valid until the next switching time.If override is active, CHANNEL OVERRIDE appears briefly in the display.Permanent switchingIf you wish to switch a channel permanently, activate permanent switching. While permanent switching is activat-ed, switching times have no effect.If you want to select whether the channel is to be switched ON or OFF permanently, use the MANUAL menu.If you use the button combinations to activate permanent switching, the channel is switched to the other switching state (e.g. from ON to OFF ).If permanent switching is active, CHANNEL PERMANENT appears briefly in the display.Activating override and permanent switchingd d _E N 02/19Y ou can reset the basic settings, such as date, time, etc. and delete or keep all switching times.Y ou have two options: Y ou can either load the factory settings via the CONFIG menu or reset the device using combinations of buttons on the device.|Loading the factory settings will also delete all switching times. If you want to reset the basic settings and retain the switching times, use the reset function.Loading factory settings1Confirm the message LOAD FACTORY SETTINGS .2Set basic settings as described in chapter “Initial setup”.Resetting1Push all four buttons on the device simultaneously.2Select the language.3If you want to retain the switching times, select RETAIN PROGRAMS .4If you want to delete all switching times, select DELETE PROGRAMS .5Set basic settings as described in chapter “Initial setup”.If you have technical questions, please contact the Customer Care Centre in your /contactResetting basic settingsCONFIGFACTORY SET-TINGSSchneider Electric Industries SAS。
C语⾔实现简单的定时器本⽂实例为⼤家分享了C语⾔实现简单的定时器的具体代码,供⼤家参考,具体内容如下1.代码分析2.代码#include <stdio.h>#include <time.h>#include <conio.h>#ifndef CLOCKS_PER_SEC#define CLOCKS_PER_SEC 1000#endifint main( void ){clock_t start;long count = 1;start = clock();while(1){if((clock() - start) == CLOCKS_PER_SEC){printf("%ld\n",count++);start = clock();//break;}}getch();}3. 代码抽象出⼀个定时器函数 void timer(long time)void timer(long time){clock_t start;long count = 1;start = clock();while(1){if((clock() - start) != (time*CLOCKS_PER_SEC)) {//时间没有到,啥也不做,空循环}else {//时间到了退出循环// printf("%s","hello");break;}}}完整代码#include <stdio.h>#include <time.h>#include <conio.h>#ifndef CLOCKS_PER_SEC#define CLOCKS_PER_SEC 1000#endif/*** time 的单位为s*/void timer(long time){clock_t start;long count = 1;start = clock();while(1){if((clock() - start) != (time*CLOCKS_PER_SEC)) {//时间没有到,啥也不做,空循环}else {//时间到了退出循环// printf("%s","hello");break;}}}int main( void ){for(int i=0;i<10;i++){timer(1);printf("%d\n",i);}getch();}以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。
C单片机的C语言程序设计解读C单片机的C语言程序设计是指使用C语言编写单片机程序的过程。
C语言是一种通用编程语言,非常适合用于嵌入式系统开发,特别是单片机。
在单片机中,C语言用于控制和编程微处理器的功能,比如读写IO口、中断处理、定时器控制等。
1. 引入库函数:在C单片机程序设计中,首先需要引入相应的库函数。
库函数是封装了一系列常用功能的函数集合,通过调用库函数可以方便地实现各种功能。
例如,可以引入stdio.h库函数实现标准的输入输出功能,或者引入io.h库函数实现IO口控制功能。
2. 定义宏定义和常量:在C单片机程序中,可以使用宏定义和常量来定义一些固定的数值或者字符串。
宏定义使用#define指令,在程序中定义一个标识符,并将其替换为指定的文本。
常量使用const关键字定义,定义后数值不可更改。
宏定义和常量可以提高程序的可读性和可维护性。
3.变量的声明和定义:变量是C程序的基本组成元素之一,用于存储和表示数据。
在C单片机程序中,可以先声明变量的类型,然后再进行定义。
变量的类型可以是整型、浮点型、字符型等。
变量的作用范围和生命周期取决于其在程序中的声明位置。
4.函数的定义和调用:函数是C程序的另一个基本组成元素,用于封装一段独立的代码块,实现特定的功能。
在C单片机程序中,可以先定义函数的原型,然后再实现函数的具体功能。
函数的调用使用函数名和实参列表,可以将函数的返回值赋给一个变量或者作为一个表达式的值进行使用。
5. 控制语句:控制语句是用于控制程序执行流程的语句。
C单片机程序中常用的控制语句包括条件语句(if-else语句、switch语句)、循环语句(for循环、while循环、do-while循环)和跳转语句(break语句、continue语句、goto语句)。
通过控制语句可以根据不同的条件执行不同的操作,或者循环执行一些代码块,或者跳转到程序的其他位置。
6.中断处理:中断是单片机程序中常用的一种处理方式。
定时器今天我们来讨论下c++中的定时器(SetTimer)一些基础的知识和用法:你可以通过呼叫SetTimer函数为您的Windows程序分配一个定时器。
SetTimer有一个时间间隔范围为1毫秒到4,294,967,295毫秒(将近50天)的整数型态参数,这个值指示Windows每隔多久时间给您的程序发送WM_TIMER消息。
例如,如果间隔为1000毫秒,那么Windows将每秒给程序发送一个WM_TIMER消息。
当您的程序用完定时器时,它呼叫KillTimer函数来停止定时器消息。
在处理WM_TIMER 消息时,您可以通过呼叫KillTimer函数来编写一个「限用一次」的定时器。
KillTimer呼叫清除消息队列中尚未被处理的WM_TIMER消息,从而使程序在呼叫KillTimer之后就不会再接收到WM_TIMER消息。
系统和定时器Windows定时器是PC硬件和ROM BIOS架构下之定时器一种相对简单的扩充。
回到Windows 以前的MS-DOS程序写作环境下,应用程序能够通过拦截者称为timer tick的BIOS中断来实作时钟或定时器。
一些为MS-DOS编写的程序自己拦截这个硬件中断以实作时钟和定时器。
这些中断每54.915毫秒产生一次,或者大约每秒18.2次。
这是原始的IBM PC的微处理器时脉值4.772720 MHz 被218所除而得出的结果。
Windows应用程序不拦截BIOS中断,相反地,Windows本身处理硬件中断,这样应用程序就不必进行处理。
对于目前拥有定时器的每个程序,Windows储存一个每次硬件timer tick减少的计数。
当这个计数减到0时,Windows在应用程序消息队列中放置一个WM_TIMER消息,并将计数重置为其最初值。
因为Windows应用程序从正常的消息队列中取得WM_TIMER消息,所以您的程序在进行其它处理时不必担心WM_TIMER消息会意外中断了程序。
在这方面,定时器类似于键盘和鼠标。
驱动程序处理异步硬件中断事件,Windows把这些事件翻译为规律、结构化和顺序化的消息。
在Windows 98中,定时器与其下的PC定时器一样具有55毫秒的分辨率。
在Microsoft Windows NT中,定时器的分辨率为10毫秒。
Windows应用程序不能以高于这些分辨率的频率(在Windows 98下,每秒18.2次,在Windows NT下,每秒大约100次)接收WM_TIMER消息。
在SetTimer呼叫中指定的时间间隔总是截尾后tick数的整数倍。
例如,1000毫秒的间隔除以54.925毫秒,得到18.207个tick,截尾后是18个tick,它实际上是989毫秒。
对每个小于55毫秒的间隔,每个tick都会产生一个WM_TIMER消息。
定时器消息不是异步的因为定时器使用硬件定时器中断,程序写作者有时会误解,认为他们的程序会异步地被中断来处理WM_TIMER消息。
然而,WM_TIMER消息并不是异步的。
WM_TIMER消息放在正常的消息队列之中,和其它消息排列在一起,因此,如果在SetTimer呼叫中指定间隔为1000毫秒,那么不能保证程序每1000毫秒或者989毫秒就会收到一个WM_TIMER消息。
如果其它程序的执行事件超过一秒,在此期间内,您的程序将收不到任何WM_TIMER消息。
您可以使用本章的程序来展示这一点。
事实上,Windows 对WM_TIMER消息的处理非常类似于对WM_PAINT消息的处理,这两个消息都是低优先级的,程序只有在消息队列中没有其它消息时才接收它们。
WM_TIMER还在另一方面和WM_PAINT相似:Windows不能持续向消息队列中放入多个WM_TIMER消息,而是将多余的WM_TIMER消息组合成一个消息。
因此,应用程序不会一次收到多个这样的消息,尽管可能在短时间内得到两个WM_TIMER消息。
应用程序不能确定这种处理方式所导致的WM_TIMER消息「遗漏」的数目。
这样,WM_TIMER消息仅仅在需要更新时才提示程序,程序本身不能经由统计WM_TIMER 消息的数目来计时(在本章后面,我们将编写两个每秒更新一次的时钟程序,并可以看到如何做到这一点)。
为了方便起见,下面在讨论时钟时,我将使用「每秒得到一次WM_TIMER消息」这样的叙述,但是请记住,这些消息并非精确的tick中断。
定时器的使用:三种方法如果您需要在整个程序执行期间都使用定时器,那么您将得从WinMain函数中或者在处理WM_CREATE消息时呼叫SetTimer,并在退出WinMain或响应WM_DESTROY消息时呼叫KillTimer。
根据呼叫SetTimer时使用的参数,可以下列三种方法之一使用定时器。
方法举例这是最方便的一种方法,它让Windows把WM_TIMER消息发送到应用程序的正常窗口消息处理程序中,SetTimer呼叫如下所示:SetTimer (hwnd, 1, uiMsecInterval, NULL) ;第一个参数是其窗口消息处理程序将接收WM_TIMER消息的窗口句柄。
第二个参数是定时器ID,它是一个非0数值,在整个例子中假定为1。
第三个参数是一个32位无正负号整数,以毫秒为单位指定一个时间间隔,一个60,000的值将使Windows每分钟发送一次WM_TIMER消息。
您可以通过呼叫KillTimer (hwnd, 1) ;在任何时刻停止WM_TIMER消息(即使正在处理WM_TIMER消息)。
此函数的第二个参数是SetTimer呼叫中所用的同一个定时器ID。
在终止程序之前,您应该响应WM_DESTROY消息停止任何活动的定时器。
当您的窗口消息处理程序收到一个WM_TIMER消息时,wParam参数等于定时器的ID值(上述情形为1),lParam参数为0。
如果需要设定多个定时器,那么对每个定时器都使用不同的定时器ID。
wParam的值将随传递到窗口消息处理程序的WM_TIMER消息的不同而不同。
为了使程序更具有可读性,您可以使用#define叙述定义不同的定时器ID:#define TIMER_SEC 1#define TIMER_MIN 2然后您可以使用两个SetTimer呼叫来设定两个定时器:SetTimer (hwnd, TIMER_SEC, 1000, NULL) ;SetTimer (hwnd, TIMER_MIN, 60000, NULL) ;WM_TIMER的处理如下所示:caseWM_TIMER:switch (wParam){case TIMER_SEC://每秒一次的处理break ;case TIMER_MIN://每分钟一次的处理break ;}return 0 ;如果您想将一个已经存在的定时器设定为不同的时间间隔,您可以简单地用不同的时间值再次呼叫SetTimer。
在时钟程序里,如果显示秒或不显示秒是可以选择的,您就可以这样做,只需简单地将时间间隔在1000毫秒和60 000毫秒间切换就可以了。
程序8-1显示了一个使用定时器的简单程序,名为BEEPER1,定时器的时间间隔设定为1秒。
当它收到WM_TIMER消息时,它将显示区域的颜色由蓝色变为红色或由红色变为蓝色,并通过呼叫MessageBeep函数发出响声。
(虽然MessageBeep通常用于MessageBox,但它确实是一个全功能的鸣叫函数。
在有声卡的PC机上,一般可以使用不同的MB_ICON参数作为MessageBeep的一个参数以用于MessageBox,来播放使用者在「控制台」的「声音」程序中选择的不同声音)。
BEEPER1在窗口消息处理程序处理WM_CREATE消息时设定定时器。
在处理WM_TIMER消息处理期间,BEEPER1呼叫MessageBeep,翻转bFlipFlop的值并使窗口无效以产生WM_PAINT消息。
在处理WM_PAINT消息处理期间,BEEPER1通过呼叫GetClientRect获得窗口大小的RECT结构,并通过呼叫FillRect改变窗口的颜色。
代码#include <windows.h>#define ID_TIMER 1LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,PSTR szCmdLine, int iCmdShow){static TCHAR szAppName[] = TEXT ("Beeper1") ;HWND hwnd ;MSG msg ;WNDCLASS wndclass ;wndclass.style = CS_HREDRAW | CS_VREDRAW ;wndclass.lpfnWndProc = WndProc ;wndclass.cbClsExtra = 0 ;wndclass.cbWndExtra = 0 ;wndclass.hInstance = hInstance ;wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;wndclass.lpszMenuName = NULL ;wndclass.lpszClassName = szAppName ;if (!RegisterClass (&wndclass)){MessageBox ( NULL, TEXT ("Program requires Windows NT!"),szAppName, MB_ICONERROR) ;return 0 ;}hwnd = CreateWindow (szAppName, TEXT ("Beeper1 Timer Demo"),WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, CW_USEDEFAULT,CW_USEDEFAULT, CW_USEDEFAULT,NULL, NULL, hInstance, NULL) ;ShowWindow (hwnd, iCmdShow) ;UpdateWindow (hwnd) ;while (GetMessage (&msg, NULL, 0, 0)){TranslateMessage (&msg) ;DispatchMessage (&msg) ;}return msg.wParam ;}LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam) {static BOOL fFlipFlop = FALSE ;HBRUSH hBrush ;HDC hdc ;PAINTSTRUCT ps ;RECT rc ;switch (message){case WM_CREATE:SetTimer (hwnd, ID_TIMER, 1000, NULL) ;return 0 ;case WM_TIMER :MessageBeep (-1) ;fFlipFlop = !fFlipFlop ;InvalidateRect (hwnd, NULL, FALSE) ;return 0 ;case WM_PAINT :hdc = BeginPaint (hwnd, &ps) ;GetClientRect (hwnd, &rc) ;hBrush = CreateSolidBrush (fFlipFlop ? RGB(255,0,0) : RGB(0,0,255)) ;FillRect (hdc, &rc, hBrush) ;EndPaint (hwnd, &ps) ;DeleteObject (hBrush) ;return 0 ;case WM_DESTROY :KillTimer (hwnd, ID_TIMER) ;PostQuitMessage (0) ;return 0 ;}return DefWindowProc (hwnd, message, wParam, lParam) ;}因为BEEPER1每次收到WM_TIMER消息时,都用颜色的变换显示出来,所以您可以通过呼叫BEEPER1来查看WM_TIMER消息的性质,并完成Windows内部的一些其它操作。