两个函数可以调用同一个定时器吗?

STM32定时器包含基本定时器、通用定时器和高级定时器,其中TIM6和TIM7是STM32当中的基本定时器,作为初学者,先从最基本的学起最容易,下面我们用这个定时器实现毫秒延时函数来入门STM32定时器的应用。

学习单片机,就是学习使用它的寄存器。即便你用库函数,寄存器也是必须要学习的。

先略览一下寄存器,CR1和CR1是控制寄存器,SR是状态寄存器,ARR就是溢出值寄存器,CNT就是计数器的当前值,PSC是预分频寄存器。预分频寄存器?听的傻眼了吧,前面几个个寄存器听的还能理解,一听到预分频寄存器,好像不知道是干嘛用的。瑞生来给你解释一下吧,你可以给预分频寄存器里面写一个从0~65535的值,这个值+1,就是定时器运行的时钟。举个例子,比如单片机工作在主频72MHz,预分频寄存器写0,预分频系数就是0+1=1,定时器的时钟就是72MHz/1=72MHz;再举个例子,比如单片机还是工作在主频72MHz,预分频寄存器写71,预分频系数就是71+1=72,定时器的时钟就是72MHz/72=1MHz。知道定时器的时钟有什么用?相信很多初学者不清楚,定时器的时钟关乎定时器计数器CNT递增的时间间隔,根据频率和周期的公式f=1/T,定时器计数器递增的时间间隔就是1/定时器的时钟,例如当定时器时钟为1MHz时,定时器计数器递增的时间间隔就是1/1MHz=1微秒,这时,如果你把溢出值设置为1000,就是1000*1us=1ms溢出。

下面,我们先用直接操作寄存器的方式,写一个毫秒延时函数:

第一条语句,设置预分频系数为00,所以定时器的时钟为00=2000Hz,那么定时时间间隔就是1/5秒,即0.5毫秒。

第二条语句,设置溢出值为ms乘以2,假如要延时1秒,函数的参数ms就是1000,溢出值就是0,毫秒=1000毫秒,即1秒。这时候,有人会说,为什么不干脆把预分频值PSC设置为71999,即预分频系数为72000,定时器的时钟就是00=1000Hz,定时时间就是1毫秒,那么直接把函数的参数ms给了溢出值寄存器ARR就可以了,就不必乘以2了。想法是可以,但是你得知道,定时器都是16位的,所以PSC的值最大到65535,到不了71999。这下你明白了吧?

第三条语句,CR1寄存器bit3写1,由寄存器定义得知,这是把定时器设置为一旦发生溢出,就停止定时器,因为我们做的是延时函数,延时到了以后,就没有必要让定时器再不断递增了,所以要这样设置。

第四条语句,CR1寄存器bit0写1,打开定时器,定时器计数器开始从0递增。

第五条语句,检测状态寄存器SR中的bit0UIF是否置1,置1的时候,定时值就达到溢出值了,说明定时时间到了。

第六条语句,清除状态寄存器SR中刚才溢出造成的UIF位。

下面,我们看看怎么使用库函数实现毫秒延时函数:

/* 定义一个定时器基本定时初始化结构体变量 */ /* 自动重装载寄存器值 */ /* 把上面的值配置到寄存器 */ /* 设置定时时间到了以后停止定时器计数 */ /* 检测定时时间是否到来 */ /* 软件清除更新标志 */

你可以细细观察一下上面的库函数,实际上,和直接操作寄存器是一样的。比如说,我们看打开定时器的库函数TIM_Cmd(TIM6,ENABLE),我们打开这个函数,如下所示:

上面两个方式虽能达到普通定时器制作延时函数的目的,但是却不能us级别延时函数,让人很是头疼!所以不得已不用软件延时来实现,代码如下:

单线程容易被阻塞 / 同步 会很耗时
异步 后续的任务无需等待

定时器是异步的,同步代码和异步代码同时存在的时候,同步代码会先执行,然后异步代码再执行

使用定时器一定要注意离开页面的时候要清除,回到页面再继续启动

定时任务:隔固定时间做某件事(一次性)、无限次的循环做

定时器调用这个函数不用传参,直接写函数名即可,
定时器调用这个函数要传参,必须接受一个回调

第二参数是时间,表示1秒(1000毫秒)后调用一次,然后每隔1秒调用一次,第一个参数

(2)、 第一个参数fn 与 fn() 区别,fn()会不等延迟,直接调用,后面不在调用

定时器是事件执行的时候,最好在前面先清除定时器一次,因为每点击一次都是生成一个新的定时器

第二参数是时间,表示1秒(1000毫秒)后调用一次,然后不再调用

5、当我们的定时器第一个参数为一个函数的时候,这个函数又是一个立即执行的函数,可以把第一个参数用单引号引起来,它会视作一个需要定时器来调用的函数

6、定时器的 this 指向问题

setTimeout() 调用的代码运行在与所在函数完全分离的执行环境上。这会导致,这些代码中包含的 this 关键字在非严格模式会指向 window (或全局)对象,严格模式下为 undefined,这和所期望的 this 的值是不一样的

解决这个问题可以使用 bind 来修改函数的 this 指向问题

Math对象用于执行数学任务 Math对象 无需new,直接调用Math方法就行

封装 随机 X至Y之间的数

方法会将数字的小数部分去掉,只保留整数部分。
传入该方法的参数会被隐式转换成数字类型。

案例3:随机色卡(随机颜色讲解)

”的定义是,“两条射线从圆心向圆周射出,形成一个夹角和夹角正对的一段弧。当这段弧长正好等于圆周长的360分之一时,两条射线的夹角的大小为1度。(如图1)
弧度的定义是:两条射线从圆心向圆周射出,形成一个夹角和夹角正对的一段弧。当这段弧长正好等于圆的半径时,两条射线的夹角大小为1弧度。(如图2)

角所对的弧长是半径的几倍那么角的大小就是几弧度
它们的关系可用下式表示和计算:
圆的周长是半径的 2π倍,所以一个周角(360度)是 2π弧度


三、度跟弧度之间的换算

据上所述,一个平角是 π 弧度。


1、Math.sin(弧度 正弦 对边比斜边 一个以弧度表示的角



Math.PIπ 是圆的周长和它的直径之比。这个值近似为 3.793


案例4:圆周运动(三角函数讲解)

setInterval()方法可按照指定的周期(以毫秒计)来调用函数或计算表达式,setTimeout()方法用于在指定的毫秒数后调用函数或计算表达式,详细使用方法可以参考下本文

必需,要调用的函数或要执行的代码串。
必需,周期性执行或调用 code 之间的时间间隔,以毫秒计。
必需,要调用的函数后要执行的 JavaScript 代码串。
必需,在执行代码前需等待的毫秒数。

执行上面代码,页面不会延迟3秒调用test(a),而是会立即执行test(a),IE、FF、Chrome下都会出现这个问题,如果你经常用到定时器,这个问题应该应该经常会碰到,那么要怎样去解决呢?
笔者在这里归纳两种常用的解决方法,当然应该也还有其他的解决方法,在这里就不一一赘述。
方法1:用匿名函数包裹

方法2:用引号包裹需调用的函数

  • 这篇文章主要介绍了JS数组splice操作,结合实例形式分析了javascript使用splice方法删除数组元素相关操作技巧,需要的朋友可以参考下

  • 这篇文章主要介绍了jQuery及JS实现循环中暂停的方法,以实例形式分析了循环中暂停的原理及实现技巧,非常具有实用价值,需要的朋友可以参考下

  • 这篇文章主要介绍了微信小程序 扭蛋抽奖机css3动画实现详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

我要回帖

更多关于 js在一定时间内设置定时器 的文章

 

随机推荐