8.计时器

1.计时器定义

windows计时器是一种输入设备,每到一个指定的时间间隔,它就会周期性地通知应用程序。windows会反复地向程序发送WM_TIMER消息,以表示改时间间隔已经过去。


2.计时器功能

多任务进行。在抢占式多任务系统中,如果程序必须完成大量的处理,可以把一个任务分成许多小块,每当收到一个WM_TIMER消息时,就处理一小块任务。达到充分利用cpu的效果。

保持更新进度报告。应用程序可以利用计时器实时的显示不断变化的信息,例如时钟程序,也可以每隔一段时间更新显示不断变化的信息。

实现自动存储的功能。计时器可以提醒windows程序每隔一个指定时间间隔就把用户的工作自动保存到磁盘上。

终止程序的演示版。适用于一定演示时间的程序。

控制运动速度。游戏中的图形对象或者计算机辅助指令程序的连续显示也许需要以一定的速度进行。利用计时器可以消除因微处理器速度不同而造成的不均匀性。

多媒体。音乐程序常常在后台播放音频数据,一个程序可以利用计时器周期性地确定有多少音频符号已经播放,以协调屏幕视觉信息。



3.计时器工作原理

windows计时器只是简单地扩展了pc硬件和ROM BIOS中的计时逻辑。应用程序中的时钟或计时器功能是通过截获一个叫“时钟滴答”的BIOS中断而实现的,这个中断每54.925毫秒出现一次,windows应用程序并不截获BIOS中断,windows本身会处理硬件中断。对于当前设定的每个计时器,windows都会保持一个计数值,硬件时钟滴答每出现一次,这个值就会减1,当计数值减为0,windows就会把一个WM_TIMER消息适当的放在应用程序消息队列中,同时把计数值重新设置回它的原始值。


由于windows应用程序是是通过正常的消息队列来接收WM_TIMER消息,所以绝对不用担心程序在处理其他任务时会被突入而来WM_TIMER消息所中断。因此计时器与键盘和鼠标相似:驱动程序会处理异步硬件中断事件,windows则将这些事件转换成有序的,有组织和序列化的消息。


4.计时器的三种使用方式


设置定时器,一般在WM_CREATE消息处理中


hWnd:窗口句柄

nIDEvent:计时器ID

uElapse:时间间隔

lpTimeFuc:计时器回调函数地址,也就是函数名


终止定时器,务必在程序终止之前完成,也就是WM_DESTROY消息处理中

KillTimer(hWnd,nIDEvent)


第一种使用方法:

不使用回调计时器函数,直接在WM_TIMER中处理。

设定计时器:

SetTime(hWnd,nIDEvent,uElapse,NULL)

处理计时器:

case WM_TIMER:

                 //处理逻辑

                 ......

                 break;

杀死计时器:

KillTimer(hWnd,nIDEvent)


第二种使用方法:

使用计时器回调函数,windows发送的WM_TIMER消息将直接在该回调函数中处理,不在由窗口过程处理。

其实窗口过程也是一个窗口的回调函数,windows发送给窗口的所有消息,将自动调用窗口过程来处理。


定义计时器回调函数:

void CALLBACK TimerProc(HWND hwnd,UINT message,UINT iTimerID,DWORD dwTime)


设置定时器:

SetTimer(hWnd,nIDEvent,uElapse,lpTimeFuc)


杀死计时器:

KillTimer(hWnd,nIDEvent)


第三种使用方法:

该方法和第二种类似,只不过SetTimer的hwnd的参数被设置为NULL,而且第二个参数(正常情况下是计时器的ID)被忽略了,此外这个函数会反悔计时器ID:

设定计时器:

iTimerID=SetTimer(NULL,0,uElapse,lpTimeFuc)

杀死计时器:

KillTimer(NULL,iTimerID)


个人觉得这样使用的计时器很乱。


示例代码:

#include <windows.h>

#define ID_TIMER    1

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
void CALLBACK TimerProc(HWND,UINT,UINT,DWORD);

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 fFileFlop=FALSE;
	HBRUSH		hBrush;
	HDC			hdc;
	PAINTSTRUCT ps;
	RECT		rect;*/

	switch(message)
	{
	case WM_CREATE:
		SetTimer(hwnd,ID_TIMER,1000,TimerProc);        //交给计时器的回调函数完成
		return 0;

	/*case WM_TIMER:
		MessageBeep(-1);                //the fuction ?
		fFileFlop=!fFileFlop;
		InvalidateRect(hwnd,NULL,FALSE);
		return 0;

	case WM_PAINT:
		hdc=BeginPaint(hwnd,&ps);

		GetClientRect(hwnd,&rect);
		hBrush=CreateSolidBrush(fFileFlop ? RGB(255,0,0) :RGB(0,0,255));
		FillRect(hdc,&rect,hBrush);

		EndPaint(hwnd,&ps);
		DeleteObject(hBrush);       //free the hBrush
		return 0;*/

	case WM_DESTROY:
		KillTimer(hwnd,ID_TIMER);
		PostQuitMessage(0);
		return 0;
	}

	return DefWindowProc(hwnd,message,wParam,lParam);
}

void CALLBACK TimerProc(HWND hwnd,UINT message,UINT iTimerID,DWORD dwTime)
{
	static BOOL fFilpFlop=FALSE;
	HBRUSH		hBrush;
	HDC			hdc;
	RECT		rect;

	MessageBeep(MB_OK);        //系统默认的发声
	fFilpFlop=!fFilpFlop;

	GetClientRect(hwnd,&rect);

	hdc=GetDC(hwnd);

	hBrush=CreateSolidBrush(fFilpFlop? RGB(255,0,0): RGB(0,0,255));
	FillRect(hdc,&rect,hBrush);

	ReleaseDC(hwnd,hdc);
	DeleteObject(hBrush);
}








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: STM32F103C8T6是一款高性能、低功耗的单片机,它具备丰富的外设,包括多个计时器。下面我将介绍一下STM32F103C8T6的计时器功能及使用方法。 STM32F103C8T6内部集成了高级定器(TIM1和TIM8)、波形生成器(TIM2、TIM3、TIM4、TIM5和TIM9)、通用定器(TIM6和TIM7)以及基本定器(TIM15和TIM16)。这些定器可以用于测量间间隔、产生PWM信号、定中断等应用。 在使用STM32F103C8T6的计时器之前,首先需要对其进行初始化配置。一般情况下,需要设置计数模式、时钟分频因子、自动重装载值、预分频系数等参数。 配置完成后,可以通过编程方式启动计时器的运行。根据具体的应用需求,可以选择定中断模式或PWM模式。在定中断模式下,可以设置定器的周期,并在每个周期结束产生一个中断。此,可以根据需要处理中断事件,比如更新数码管显示、控制外设等。在PWM模式下,可以通过调整计时器的占空比和频率,产生具有一定占空比和频率的PWM信号,用于控制马达、灯光等。 在使用计时器过程中,我们还可以通过读取计数器的当前值来实现间测量或精确的计时功能。此外,STM32F103C8T6还提供了方便的计时器输入捕获和输出比较功能,通过这些功能可以更灵活地应对各种应用需求。 总而言之,STM32F103C8T6的计时器功能非常强大,可以广泛应用于各种定计时和PWM控制场景。通过合理的配置和编程,可以实现精确、稳定的计时功能,并且充分发挥单片机的高性能和低功耗特点。 ### 回答2: STM32F103C8T6是一款基于ARM Cortex-M3内核的32位微控制器,具有多个计时器功能。以下是关于STM32F103C8T6计时器的一些基本知识: 首先,STM32F103C8T6微控制器具有三个基本定器(TIM2、TIM3和TIM4)和一个高级定器(TIM1)。这些定器可用于生成定中断、PWM波形输出以及其他计时测量和控制功能。 基本定器具有简化的功能和配置选项,适用于较简单的应用。高级定器则具有更多功能和灵活性,适用于更复杂的应用。 每个定器都由一个16位或32位的计数器和多个输入捕获通道和输出比较通道组成。计数器用于计算间,而输入捕获通道用于捕获外部事件(例如脉冲信号)的间戳。输出比较通道可以用于产生PWM波形或产生定中断。 编程上,可以使用STM32CubeMX或STM32CubeIDE等开发工具来配置和初始化定器。通过设置寄存器的值,可以选择计时器的模式、时钟源、预分频器、自动重载值等参数。还可以配置输入捕获和输出比较通道的工作模式和触发条件。 定中断是使用定器的主要功能之一。可以通过配置定器的预分频和自动重载值来实现所需的中断频率。当计数器达到自动重载值,将触发中断,可以在中断服务程序中执行所需的操作。 除了定功能外,STM32F103C8T6还可以通过其他外设(如GPIO、UART、SPI等)与外部设备进行通信和控制。这使得它成为许多嵌入式应用的理想选择。 总而言之,STM32F103C8T6计时器具有多种功能和灵活性,适用于各种计时和控制应用。合理的配置和编程可以实现所需的定和测量要求。 ### 回答3: STM32F103C8T6是一款基于ARM Cortex-M3内核的高性能微控制器。它内置了多个计时器,用于实现各种定和计数功能。 STM32F103C8T6的计时器包括基本定器(TIM2和TIM3),通用定器(TIM1、TIM4、TIM5、TIM8),高级定器(TIM1和TIM8)和看门狗定器(IWDG和WWDG)。 基本定器是一个用于生成周期性中断的简单计数器。它具有16位计数器和一个自动重载寄存器,可以设置计数器的时钟源和分频系数,实现不同的定功能。 通用定器是一个功能强大的定器/计数器,可以用于多种应用,如PWM输出、脉宽测量、输入捕获等。它具有16位或32位计数器、自动重载寄存器、输入捕获寄存器和输出比较寄存器等功能。 高级定器是通用定器的扩展,具有更复杂的功能,如高级PWM输出、编码器接口、递减计数等。它具有16位或32位计数器和更多的输入捕获和输出比较通道。 看门狗定器是为了防止系统在异常情况下出现死锁而设计的。IWDG用于软件监视,WWDG用于硬件监视。它们可以设置超间,如果系统在超间内没有喂狗,将会触发复位操作。 在编程上,我们可以使用STM32CubeMX工具和STM32Cube HAL库来配置和操作这些计时器。通过设置寄存器的值和中断处理函数,我们可以实现精准的定和计数功能,满足各种应用需求。 总之,STM32F103C8T6的计时器具有丰富的功能和灵活的配置选项,可以广泛应用于各种领域,如工业自动化、通信设备、家用电器等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值