定时器用法_西门子博图定时器用法 - CSDN
精华内容
参与话题
  • STM32通用定时器使用详解

    万次阅读 多人点赞 2018-08-12 09:45:57
    1.通用定时器基本介绍 通用定时器包括TIM2、TIM3、TIM4和TIM5 STM32通用定时器是一个通过可编程预分频器驱动的16位自动装载计数器构成。 每个定时器都是完全独立的,没有互相共享任何资源。它们可以一起同步操作。...

    1.通用定时器基本介绍

    • 通用定时器包括TIM2、TIM3、TIM4和TIM5
    • STM32通用定时器是一个通过可编程预分频器驱动的16位自动装载计数器构成。
    • 每个定时器都是完全独立的,没有互相共享任何资源。它们可以一起同步操作。
    • 定时器可以进行定时器基本定时输出4路PWM输入捕获
    • 本文详细介绍这三个功能并且利用定时器3并且示例代码使用

    2.开发环境

    开发平台:keil5
    单片机:STM32F103ZET6


    #3.基本定时功能

    ## 3.1定时器时钟来源分析
    STM32部分时钟树:
    定时器部分时钟树
      3.1.1 首先我们我们的系统时钟(SYSCLK 72MHz) 经过AHB分频器给APB1外设,但是APB1外设最大的只能到36Mhz,所以必须要系统时钟的二分频。下面又规定了如果APB1预分频系数为1则频率不变,否则频率X2至定时器27**,**所以定时器27的时钟频率为还是72MHz

      3.1.2 分配给我们定时器的时钟是72MHz,我们可以根据自己的需求再设置定时器的分频,设置它的定时值

    /*
    	* 初始化定时器的时候指定我们分频系数psc,这里是将我们的系统时钟(72MHz)进行分频
    	* 然后指定重装载值arr,这个重装载值的意思就是当 我们的定时器的计数值 达到这个arr时,定时器就会重新装载其他值.
    		例如当我们设置定时器为向上计数时,定时器计数的值等于arr之后就会被清0重新计数
    	* 定时器计数的值被重装载一次被就是一个更新(Update)
    	* 计算Update时间公式
    	Tout = ((arr+1)*(psc+1))/Tclk
    	公式推导详解:
    		Tclk是定时器时钟源,在这里就是72Mhz 
    		我们将分配的时钟进行分频,指定分频值为psc,就将我们的Tclk分了psc+1,我们定时器的最终频率就是Tclk/(psc+1) MHz
    		这里的频率的意思就是1s中记 Tclk/(psc+1)M个数 (1M=10的6次方) ,每记一个数的时间为(psc+1)/Tclk ,很好理解频率的倒数是周期,这里每一个数的周期就是(psc+1)/Tclk 秒
    		然后我们从0记到arr 就是 (arr+1)*(psc+1)/Tclk
    	举例:比如我们设置arr=7199,psc=9999
    	我们将72MHz (1M等于10的6次方) 分成了(9999+1)等于 7200Hz
    	就是一秒钟记录9000数,每记录一个数就是1/7200秒
    	我们这里记录9000个数进入定时器更新(7199+1)*(1/7200)=1s,也就是1s进入一次更新Update
    */
    //简单进行定时器初始化,设置 预装载值 和 分频系数
    void MY_TIM3_Init(u16 arr,u16 psc){
    	
    	//初始化结构体
    	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    	
    	//1.分配时钟
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
    	
    	//2.初始化定时器相关配置
    	TIM_TimeBaseStructure.TIM_Period = arr;
    	TIM_TimeBaseStructure.TIM_Prescaler = psc;
    	
    	/*在这里说一下这个TIM_ClockDivision 是设置与进行输入捕获相关的分频
    		设置的这个值不会影响定时器的时钟频率,我们一般设置为TIM_CKD_DIV1,也就是不分频*/
    	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数
    	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);
    	
    	//3.打开定时器
    	TIM_Cmd(TIM3,ENABLE);
    }
    
    /****************** 主函数 ********************/
    //在主函数中我们可以调用初始化
    int main(){
    	//定时器初始化
    	MY_TIM3_Init(7199,9999);
    	while(1){
    		
    		//检测更新标志位
    		if(TIM_GetFlagStatus(TIM3,TIM_IT_Update)){
    			//清除标志位
    			TIM_ClearFlag(TIM3,TIM_IT_Update);
    			//....(每隔一秒执行任务)
    		}
    		
    	}
    }
    

    #4.定时器输出PWM # 4.1基本介绍   **4.1.1** **PWM**是脉冲宽度调制,我们是通过改变**脉冲的宽度**来达到改变**输出电压**的效果,本质上就是调节**占空比**实现的,STM32除了**基本定时器(TIM6,TIM7)不能输出PWM**以外,其它的定时器都具有输出PWM,其中**高级定时器(TIM1和TIM8)**还能输出**7**路PWM,**基本定时器(TIM2,TIM3,TIM4,TIM5)**也可以输出**4**路PWM > 输出**PWM**是很有用的,比如我们可以通过**控制电机**来玩小车,或者通过输出PWM改变LED的亮度,制造**呼吸灯**等等

      4.1.2 我们通用定时器能输出PWM的IO口是固定的,虽然我们可以通过重映射可以改变引脚,具体是哪一些IO口我们要通过查阅STM32的参考手册

    这里涉及到一个重映射的概念,重映射就是管脚的外设功能映射到另一个管脚,但是不是可以随便映射的,具体对应关系参考手册上的管脚说明。这样优点是可以优化电路设计;扩展功能,减少外设芯片资源

    /**
    	定时器3,可产生四路的PWM输出,四个通道分别对应的引脚情况如下
    	TIM3_CH1,TIM3_CH2,TIM3_CH3,TIM3_CH4
    	没有重映像的对应情况:
    	PA6,PA7,PB0,PB1
    	部分重映像:
    	PB4,PB5,PB0,PB1
    	完全重映像:
    	PC6,PC7,PC8,PC9	
    
    	当我们的IO口不仅仅是做普通的输入输出使用的时候,作为别的外设(AD,串口,定时器等)的特定功能引脚,就需要开启外设.
    	这里我们还需要开启APB2外设上的复用时钟AFIO,同时IO口采用的是复用输出!
    
    	我们这里是没有使用重映射功能.
    */
    // 宏定义
    //判断当前是处于哪一种模式,以便于我们初始化IO口
    #define NO_REAMP   0
    #define PART_REAMP 1
    #define FULL_REAMP 2
    
    // ---> 这里是需要制定的参数
    
    //指定这里的 当前的模式,我们给她默认指定是 没有重映射
    #define CURRENT_MODE NO_REAMP 
    
    //*************根据当前模式初始化IO口 函数
    void MY_TIM3_GPIO_Init(void){
    	
    	GPIO_InitTypeDef 	GPIO_InitStructure;
    	
    	//1.开启AFIO时钟
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
    	
    	//2. 根据当前的重映像的模式 配置时钟 和 初始化相关引脚
    	switch(CURRENT_MODE){
    		
    		//2.1 如果没有重映射
    		case NO_REAMP:{
    			
    			// 时钟分配
    			RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB,ENABLE);
    			// 初始化IO口
    			GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    			GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    			GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
    			GPIO_Init(GPIOA,&GPIO_InitStructure);
    			GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;
    			GPIO_Init(GPIOB,&GPIO_InitStructure);
    			
    			break;
    		}
    		//2.2 部分重映射
    		case PART_REAMP:{
    			
    			// 时钟分配
    			RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
    			// 初始化IO口
    			GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    			GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    			GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_4|GPIO_Pin_5;
    			GPIO_Init(GPIOB,&GPIO_InitStructure);
    			
    			break;
    		}
    		//2.3 全映射
    		case FULL_REAMP:{
    			
    			// 时钟分配
    			RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
    			// 初始化IO口
    			GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    			GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    			GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9;
    			GPIO_Init(GPIOB,&GPIO_InitStructure);
    			
    			break;
    		}
    		default:break;
    	}	
    }
    
    //***************** 定时器PWM输出初始化函数
    void MY_TIM3_PWM_Init(u16 arr,u16 psc){
    	
    	//初始化结构体
    	TIM_OCInitTypeDef TIM_OCInitstrcuture;
    	
    	//1.初始化定时器 和 相关的IO口
    	MY_TIM3_Init(arr,psc); 
    	MY_TIM3_GPIO_Init();
    	
    	//2.初始化PWM的模式
    	
    	/**
    	选择PWM模式:
    		PWM1模式:
    			向上计数时,当我们 当前的 计数值 小于我们的设置阈值为有效电平,否则为无效电平,向下计数时与向上计数时相反
    		PWM2模式:
    			与PWM1模式向上向下计数时完全相反
    	*/
    	TIM_OCInitstrcuture.TIM_OCMode = TIM_OCMode_PWM1;
    	TIM_OCInitstrcuture.TIM_OutputState = TIM_OutputState_Enable;
    	TIM_OCInitstrcuture.TIM_OCPolarity = TIM_OCPolarity_High;   //输出电平为高,也就是有效电平为高
    	TIM_OC1Init(TIM3,&TIM_OCInitstrcuture);						//这里是设置利用通道1输出
    	
    	//这里只初始化通道1,我们可以根据自己需求初始化其它通道
    	
    //	TIM_OC2Init(TIM3,&TIM_OCInitstrcuture);
    //	TIM_OC3Init(TIM3,&TIM_OCInitstrcuture);
    //	TIM_OC4Init(TIM3,&TIM_OCInitstrcuture);
    
    	TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能预装载寄存器
    }
    
    //*********************主函数调用
    int main(){
    	
    	//因为我们单片机引脚输出电压3.3V左右,我们设置预装载值为330
    	MY_TIM3_PWM_Init(330,0);
    	
    	//我们初始化的时候选择的是PWM1模式,当计数值小于我们的设定值100时为有效电平,这里是高电平
    	//所以对于的1通道(PA6)电压是大概就是 3.3 * (100/330) = 1V 左右,我们可以用万用表测量
    	TIM_SetCompare1(TIM3,100);
    	
    	while(1);
    }
    
    

    #5.定时器输入捕获
    ## 5.1基本介绍

    • 上面介绍了定时器的四路通道可以输出PWM,同样的我们也可以捕获该定时器这四路通道上的边沿状态(上升沿,下降沿)

    • 由此可见基本定时器也不能进行输入捕获,没有思路通道

    我们可以通过输入捕获的来测量高电平脉宽时间,首先捕获到高电平,记录下改时间,然后切换为捕获低电平,得到时间
    ## 5.2开发步骤
    ###   输入捕获 (捕获边沿信号,上升沿和下降沿)
       首先我们需要以一定的频率检测电平的跳变,然后对部分跳变(也就是部分输入的波形)进行过滤
          ------ 这就是定时器里面的滤波器的任务

    1. 指定输入滤波器时钟频率,首先是系统时钟分给定时器72Mhz,我们首先初始化定时器的时候指定了TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; 没有分频,输入给滤波器的时钟频率还是72MHz,TIM_ClockDivision也可以指定为2分频或者4分频
    2. 波形过滤(TIM_ICFilter),这里有一个指定过滤器的参数(参考芯片手册),例如我们设置参数为0101(二进制),采样频率(fsampling)为 滤波器频率/2 = 36Mhz,N=8.当检测到一个上升沿的时候,再以fsampling频率连续8次检测到高电平才确认是一个有效的上升沿,这样可以滤除那些高电平脉宽低于8个采样周期的脉冲信号,从而达到滤高频波的效果。
      这里写图片描述
    3. 配置输入分频(TIM_ICPrescaler),如果我们设置不分频,一个边沿(上升沿或者下降沿)就触发一次捕获,二分频就是两次边沿触发捕获,这里这个分频可以为1,2,4,8
    //定时器输入捕获初始化
    void MY_TIM3_Cap_Init(u16 arr,u16 psc){
    
    	//初始化结构体
    	TIM_ICInitTypeDef TIM_ICInitStructure;
    	
    	//1.初始化定时器 和 相关的IO口
    	MY_TIM3_Init(arr,psc); 
    
    	//这里的IO口根据自己需求改成输入,我这改成下拉输入,具体代码就不展现了
    	MY_TIM3_GPIO_Init();
    	
    	//2.初始化定时器输入捕获
    	TIM_ICInitStructure.TIM_Channel = TIM_Channel_1 ; // 设置输入捕获的通道
    	
    	//不使用过滤器,假设我们想使用,例如上述举例使用0101
    	//我们就给TIM_ICFilter  = 0x05 ,(0000 0101),根据上表可以知道这个值范围(0x00~0x0F)
    	TIM_ICInitStructure.TIM_ICFilter = 0x00;
    	
    	TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕获
    	TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;		//配置输入分频,这里不分频,1次检测到边沿信号就发生捕获
    
    	/*
    		这里说一下定时器通道可以进行交叉捕获,通道1捕获通道2引脚上的边沿信号,通道2捕获通道1引脚,通道3可以捕获通道4对应引脚,... 
    		但是只能相邻一对可以相互捕获,例如通道2不能捕获通道3引脚边沿信号
    		TIM_ICSelection_DirectTI 表示直接捕获,通道1对应通道1引脚,通道2对应通道2引脚
    		TIM_ICSelection_IndirectTI 表示进行交叉捕获
    	*/
    	TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射捕获对应通道的引脚
    	TIM_ICInit(TIM3,&TIM_ICInitStructure);													
    	
    }
    //****************主函数
    int main(){
    	//初始化输入捕获
    	MY_TIM3_Cap_Init(1000,0);
    	
    	while(1){
    		//检测是否捕获到上升沿
    		if(TIM_GetFlagStatus(TIM3,TIM_IT_CC1)){
    			TIM_ClearFlag(TIM3,TIM_IT_CC1);
    			//捕获到上升沿之后的任务...
    			//一般测量高电平脉宽,我们可以先捕获上升沿再捕获下降沿
    			//TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Falling); 修改为下降沿捕获
    		}
    		
    	}
    }
    
    

    #6.定时器中断
     1.谈及到中断,我们就必须涉及到NVIC,具体关于NVIC请参考我的另外一篇,这里是直接使用,我们使能定时器3中断并且配置完抢占优先级和响应优先级之后,再在主函数中使能其更新中断和输入捕获中断

    //使能更新中断和输入捕获通道1的中断
    TIM_ITConfig(TIM3,TIM_IT_Update|TIM_IT_CC1,ENABLE);
    

     2.我们使用中断的一个主要目的就是能够及时处理信息,不用在主函数的while循环里面等待

    //定时器3的中断处理函数
    void TIM3_IRQHandler(void){
    	
    	//1.判断是什么中断
    	
    	// 1.1定时器更新中断
    	if(TIM_GetITStatus(TIM3,TIM_IT_Update)){
    		//...处理定时器更新之后任务
    	}
    	// 1.2如果是定时器 通道1的捕获中断
    	else if( TIM_GetITStatus(TIM3,TIM_IT_CC1) ){
    			//处理输入捕获之后的任务
    			//TIM_OC1PolarityConfig(TIM3,TIM_ICPolarity_Falling);更改为下降沿捕获
    	}
    	
    	//2.最后将中断标志位都清理掉
    	TIM_ClearITPendingBit(TIM3,TIM_IT_Update|TIM_IT_CC1);
    }
    
    展开全文
  • 简述js定时器用法

    千次阅读 2018-09-25 17:01:00
    js常用的定时器方法有三个 setTimeout(“js语句”,定时时间) setInterval(“js语句”,定时时间) clearTimeout(需要停止的对象) 注意:这里的定时时间单位都为毫秒 下面我们来看一下它们的用法: ...

    js常用的定时器方法有四个

    • setTimeout(“js语句”,定时时间)
    • setInterval(“js语句”,定时时间)
    • clearTimeout(需要停止的对象)
    • clearInterval(需要停止的对象)
      注意:这里的定时时间单位都为毫秒

    下面我们来看一下它们的用法:
    setTimeout()
    单次定时,即setTimeout的第一个参数的js语句只会定时实现一次。
    比如:

    word = setTimeout("showWord()", 2000)
    

    那么浏览器就会只在你调用setTimeout方法2秒后实现showWord方法,只实现一次不循环。将setTimeout赋值给word是为了方便清除,下面我们会提到。
    我们来看一下效果:
    在这里插入图片描述
    当然你还可以把函数方法写到setTimeout的参数中去。
    比如:

    var word = setTimeout(function() {
    	s.innerHTML = "<p>我喜欢javacript</p>"
    }, 3000)
    

    setInterval()
    循环定时,即setInterval的第一个参数的js语句只会定时实现无数次。
    比如:

    word = setInterval("showWord()", 2000)
    

    浏览器会在你调用setInterval后每间隔2秒就会调用一次showWorld方法
    在这里插入图片描述
    同理如果你喜欢的话,也可以将函数写到参数中去

    clearTimeout()clearInterval()
    两者用法一样,清除定时器对象,不过从名字可以看出,清除的定时器是与上面对应的,但其实是可以互用的,你们可以试试。现在我们来说说它们的用法。
    比如前面的word:

    clearInterval(word)
    

    clearInterval就只有一个参数,即你要清除的定时器对象,当然clearTimeout的参数也是只有一个
    效果在演示setInterval时已显示

    补上showWord代码:

    var showWord = () => {
    		r = Math.random() * 254 + 1
    		g = Math.random() * 254 + 1
    		b = Math.random() * 254 + 1
    		var s = document.getElementById("show")
    		s.style.background = "rgb(" + r + "," + g + "," + b + ")"
    		s.innerHTML = "<p>我喜欢javacript</p>"
    }
    
    展开全文
  • &lt;!DOCTYPE html&gt; &lt;html&gt; &lt;head&gt; &lt;meta charset="utf-8" /&gt; &lt;title&gt;&lt;/title&gt;...text/javas
    <!DOCTYPE html>
    <html>
    
    	<head>
    		<meta charset="utf-8" />
    		<title></title>
    	</head>
    
    	<body>
    		<script type="text/javascript">
    			//			window.onload=function(){
    			//				
    			//			}
    			function Msg(msg) {
    				this.msg = msg;
    				this.shout = function() {
    					//console.log(_this.msg);
    					console.log(this.msg);
    				}
    				this.waitAndShout = function() {
    					//隔五秒钟后执行上面的shout方法
    					var that = this;
    					setTimeout(that.shout, 2000);
    				}
    			}
    			var Obj = function(msg) {
    				this.msg = msg;
    				this.shout = function() {
    					console.log(this.msg);
    				}
    				this.waitAndShout = function() {
    					//隔五秒钟后执行上面的shout方法
    					var that = this;
    					setTimeout(that.shout, 1000);
    				}
    				return this;
    			}
    
    			function NewMsg(msg) {
    				this.msg = msg;
    				this.shout = function() {
    					//console.log(_this.msg);
    					console.log(this.msg);
    				}
    				this.waitAndShout = function() {
    					//隔五秒钟后执行上面的shout方法
    					var that = this;
    					setTimeout(that.shout.bind(that), 2000); //bind=>var that=this;
    				}
    			}
    			var obj1 = new Msg('woshimsg');
    			obj1.waitAndShout(); //this指向window
    			var obj2 = Obj("woshimsg");
    			obj2.waitAndShout(); //this指向obj
    			var obj3 = new NewMsg('woshimsg');
    			obj3.waitAndShout(); //this指向obj,通过bind重新指向this=>obj
    			/**
    			 * 注意:
    			 * 
    			 * 当我们使用定时器
    			 * setTimeout('fun()',1000)//一秒以后执行
    			 * setTimeout(fun,1000);//一秒以后执行
    			 * setTimeout(function(){fun()},1000);//一秒以后执行
    			 * setTimeout(fun(),1000);//立即执行
    			 * 
    			 * **/
    		</script>
    	</body>
    
    </html>

    项目中,经常会用到定时器来实现数据实时更新、时间等,简单总结一下:

    Javascript中的定时器有两种,setInterval和setTimeout,而定时器的作用就是延迟执行。

    一、定时器的写法

     

    setInterval(expression,milliseconds);

     

     

    setTimeout(expression,milliseconds);
    上式中,expression既可以是字符串,也可以是匿名函数,或者也可以是一个函数名。但是,函数名中不能传参。第二个参数为延迟要执行的时间。
    具体写法如下:
    (1)函数名,不带参数
    
     
    setInterval(test,1000);           //1秒后执行
    (2)字符串,可以执行的代码
    
     
    setInterval('test()',1000);       //1秒后执行
    (3)匿名函数
    
     
    setInterval(function(){},1000);   //1秒后执行
    (4)调用函数
    
     
    setInterval(test,1000);           //立即执行
    如果想要传参数,可以自己定义一个函数,如下:
    function test (str){
       console.log(str);
    }
    
     
    setInterval(test(str),1000);      //立即执行
    注:setTimeout的用法一样
    二、定时器的清除
    由于定时器在调用时,都会返回一个整形的数字,该数字代表定时器的序号,即第多少个定时器,所以定时器的清除要借助于这个返回的数字。
    定时器清除的方法:clearInterval(str)和clearTimeout(str)。
    要清除定时器,就必须在用定时器的时候,定义一个变量来记录定时器的返回值。如下:
    var str = setInterval(test,1000);
    setTimeout的用法也一样。
    注:有时候在写的时候,还会习惯将清空的定时器的变量置空,这样写既可以释放内存,也可以便于后边代码的判断。
    三、定时器的执行机理
    在工作或面试中,经常会遇到将‘定时器和JS的执行机制’结合起来的题。下面简单介绍下:
    定时器:延迟执行。
    Javascript:单线程执行。
    所以,在代码中遇到定时器时,定时器中要执行的代码,都要排在JS执行代码的后面,有如下几种情况:
    (1)第一种情况
    代码:
    
     
    打印结果:


    (2)第二种情况

    代码:

    
     
    打印结果:
    
     
    (3)第三种情况
    代码:
    
     
    打印结果:
    
     
    由上述几种情况可以断定,代码执行顺序:先执行完JS主线程代码后,再执行定时器延迟执行的代码。


     

    展开全文
  • 概述 在.NET Framework里面提供了三种Timer(只考虑Winform) ① System.Windows.Forms.Timer ② System.Timers.Timer ③ System.Threading.Timer 现分述如下: 1.System.Windows.Forms.Timer 介绍 ...

    概述

    在.NET Framework里面提供了三种Timer(只考虑Winform)

    ① System.Windows.Forms.Timer

    ② System.Timers.Timer

    ③ System.Threading.Timer

    现分述如下:

    1.System.Windows.Forms.Timer

    介绍

      System.Windows.Forms.Timer基于Windows消息循环,用事件方式触发,在界面线程执行;是使用得比较多的Timer,Timer Start之后定时(按设定的Interval)调用挂接在Tick事件上的EvnetHandler。在这种Timer的EventHandler中可 以直接获取和修改UI元素而不会出现问题–因为这种Timer实际上就是在UI线程自身上进行调用的。

    • 它是一个基于Form的计时器
    • 创建之后,你可以使用Interval设置Tick之间的跨度,用委托(delegate)hook Tick事件
    • 调用Start和Stop方法,开始和停止
    • 完全基于UI线程,因此部分UI相关的操作会在这个计时器内进行
    • 长时间的UI操作可能导致部分Tick丢失

    用法

            #region Timer控件定时操作
            private void TimerInit()
            {
                timer_Name.Enabled = true;
                timer_Name.Interval = 200;//200毫秒1次
                timer_Name.Tick += new EventHandler(timer_Name_Tick);
                timer_Name.Start();
            }
    
            private void timer_Name_Tick(object sender, EventArgs e)
            {
                //关闭定时器防止多次触发
                timer_Name_Monitor.Enabled = false;
                //要定时执行的方法 
                TimerNameWorking();
                //启动定时器
                timer_Name_Monitor.Enabled = true;
            }
           #endregion
    

      Windows计时器是为单线程环境设计的,其中,UI 线程用于执行处理。它要求用户代码有一个可用的 UI 消息泵,而且总是在同一个线程中操作,或者将调用封送到另一个线程。
      当定时器触发时,Windows把一个定时器消息插入到线程消息队列中。调用线程执行一个消息泵提取消息,然后发送到回调方法中(这里的timer_Name_Tick方法)。而这些都是单线程进行了,所以在执行回调方法时UI会假死。所以使用这个控件不宜执行计算受限或IO受限的代码,因为这样容易导致界面假死,而应该使用多线程调用的Timer。另外要注意的是这个控件时间精度不高,精度限定为 55 毫秒。

    2.System.Timers.Timer

    介绍

      System.Timers.Timer类:定义一个System.Timers.Timer对象,然后绑定Elapsed事件,通过Start()方法来启动计时,通过Stop()方法或者Enable=false停止计时。AutoReset属性设置是否重复计时(设置为false只执行一次,设置为true可以多次执行)。Elapsed事件绑定相当于另开了一个线程,也就是说在Elapsed绑定的事件里不能访问其它线程里的控件(需要定义委托,通过Invoke调用委托访问其它线程里面的控件)。

    用法

    长时间任务必须防止重复调用,否则定时器会在上次任务未执行完就再次开线程执行任务

            System.Timers.Timer timerName= new System.Timers.Timer();
            private void  timerNameInit() 
            {
                timerName.Enabled = true;
                timerName.Interval = 1000;//执行间隔时间,单位为毫秒    
                timerName.Start();
                timerName.Elapsed += new System.Timers.ElapsedEventHandler(timerName_Elapsed);
            }
            private void timerName_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
            {
                //关闭定时器防止多次触发
                timerName.Stop(); 
                //要定时执行的方法          
                TimerNameWorking();
                //启动定时器
                timerName.Start();
            }
    

    3.System.Threading.Timer

    介绍

      System.Threading.Timer类:定义该类时通过构造函数进行初始化,执行的方法也是新开一个线程。

    用法(正确用法)

    System.Threading.Timer的正确用法如下:

           //定义Timer类
            System.Threading.Timer timerName;
            /// <summary>
            /// 初始化Timer类
            /// </summary>
            private void timerNameInit()
            {
                //定时器在时间间隔过后仅打勾一次,然后在回调函数中工作完成后更改计时器,不需要锁定机制,没有并发性。
                timerName = new Timer( Callback, null, TIME_INTERVAL_IN_MILLISECONDS, Timeout.Infinite );
            }
    
            /// <summary>
            /// 定时到点执行的事件
            /// </summary>
            /// <param name="value"></param>
            private void TimerCall(object value)
            {
                 // Long running operation
                 //定时器将在下一个时间间隔+长时间运行时间后触发下一个回调
                 timerName.Change( TIME_INTERVAL_IN_MILLISECONDS, Timeout.Infinite );
            }
            //如果需要在N毫秒的时间内运行计时器,那么建议使用秒表来测量长时间运行的操作时间,然后适当调用Change方法:
            private void TimerCall(Object state)
            {
                Stopwatch watch = new Stopwatch();
    
                watch.Start();
                // Long running operation
    
                 timerName.Change(Math.Max(0, TIME_INTERVAL_IN_MILLISECONDS - watch.ElapsedMilliseconds), Timeout.Infinite);
            }
        }
    }
    
    

    总结

    • System.Windows.Forms.Timer基于Windows消息机制,在UI线程执行,不适合执行长时间任务,建议在与界面控件操作相关的任务中使用
    • System.Timers.Timer基于事件,在线程池中执行,上次任务的是否执行完毕不影响下次任务的开始执行,不建议单个任务而且也有一些bug
    • System.Threading.Timer基于回调函数,只能定时执行单个任务。
    展开全文
  • 西门子300PLC的定时器用法

    万次阅读 2017-06-01 14:09:25
    定时器的分类及用法
  • Windows定时器使用方法

    千次阅读 2016-01-25 16:28:24
    范围本文只讨论MFC环境下使用定时器的例子,用纯Win32 SDK是类似的。
  • window c++ 定时器使用方法

    千次阅读 2018-09-24 20:09:53
    使用定时器ID方式的使用方法 //定时器使用方式一 //每1秒,3秒开始执行 DWORD WINAPI mytimernull(LPVOID args) { BOOL bRet = FALSE; MSG msg = { 0 }; //步骤一:创建定时器 //如果hWnd为NULL,返回值为新...
  • MFC 定时器用法

    千次阅读 2017-05-23 11:32:47
    MFC定时器使用    1.在头文件定义一个afx_msg void OnTimer(UINT_PTR nIDEvent)函数  定义一个定时器ID #define SysTimeTimer 1   2.实现该函数  void CMiniGateTestNNDlg::OnTimer(UINT_PTR nIDEvent...
  • package com.myapp.sss; import java.util.Timer; import java.util.TimerTask; public class Test_001 { public static int i = 0; public static void main(String[] args) { timer1();......
  • C#.NET定时器使用方法 超简单

    千次阅读 2018-11-22 17:19:18
    首先在我们的aspx中加入下面代码:  &lt;asp:ScriptManager ID="ScriptManager1" runat="server"&gt;&lt;/asp:ScriptManager&gt; &lt;asp:Timer ID="...Timer1
  • 编写一个程序(库),实现定时器(计时器)的功能,它能为用户提供在同一进程中多次使用定时器。这里要求用信号来实现。 示例代码如下: #include<stdio.h> #include<time.h> #include<sys/time.h...
  • MFC中OnTimer定时器用法

    千次阅读 2017-11-16 18:37:06
    一、 单个定时器用法 定时器工作主要流程:设置定时器SetTimer,时间到后调用OnTimer函数,关闭定时器KillTimer。可以在程序初始化用SetTimer函数弄成多个线程类似,并行进行多个函数功能。 1.1 SetTimer(H,nID,...
  • STM32定时器用法

    千次阅读 2012-08-03 11:07:46
    最近在做STM32的PT2262解码,网上查到一些用单片机解码的程序,想对应地修改成STM32的程序,在定时器这里遇到了困难。目前的方案是打算用定时器计时,用示波器测量到接收到的信号的窄脉冲时间和宽脉冲时间,设置200...
  • 在VC编程中,用SetTimer可以定义一个定时器,到时间了,就响应OnTimer消息,但这种定时器精度太低了。如果需要精度更高一些的定时器(精确到1...vc高精度多媒体定时器使用方法如下: 复制内容到剪贴板 程序代码
  • C#多媒体定时器使用方法

    千次阅读 2014-08-19 11:52:14
    C#多媒体定时器使用方法 2012-09-26 10:50 936人阅读 评论(4) 收藏 举报 c#timerobjectdll工具 多媒体定时器下载地址:点击打开链接 使用方法 (1) 添加dll文件到项目中 (2) 使用命名空间 using ...
  • Timer定时器用法详解

    万次阅读 2019-07-06 17:30:20
    先看API和结论: /** timer总结: Timer timer = new Timer(); //其中会调用this(..., 即它以Timer+序列号为该定时器的名字 Timer timer = new Timer(String name); //以name作为该定时器的名字 Timer time...
  • 记录篇-tp5-定时器用法

    千次阅读 2019-06-12 17:20:43
    来源:“https://www.cnblogs.com/ordinaryk/p/9105351.html”
  • Qt中两种定时器用法

    万次阅读 多人点赞 2013-07-12 14:19:03
    在Qt中使用定时器有两种方法,一种是使用QObiect类的定时器;一种是使用QTimer类。定时器的精确性依赖于操作系统和硬件,大多数平台支持20ms的精确度。 1.QObject类的定时器  QObject是所有Qt对象的基类,它...
  • 这里面涉及到了三个函数方法:setInterval()、setTimeout()、clearInterval(),本文将围绕这三种函数的用法,来实现定时器的功能,需要的朋友可以过来参考下,喜欢的可以点波赞,或者关注一下本人,希望对大家有所...
  • Timer定时器简单的两种用法

    千次阅读 2016-05-13 10:42:19
    Timer定时器简单的两种用法,好用方便易懂
1 2 3 4 5 ... 20
收藏数 135,241
精华内容 54,096
关键字:

定时器用法