打印
[学习资料]

浅析PIC单片机定时器

[复制链接]
1478|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wiba|  楼主 | 2019-7-25 13:48 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

什么是定时器?

定时器顾名思义就是用来定时的。在单片机应用中常常用于各种各样的定时。比如让LED灯每隔 1S 亮一次。 这个1S 就是由定时器做到的。

指令周期

指令周期就是单片机执行一个指令所花费的时间。这也是定时器定时的最小时间单位。时钟频率/4=指令频率。1/指令频率=指令周期。

假设现在的时钟是4MHZ ,4MHz的时钟经过4分频后变成了 1MHz 其周期为0.0000001s也就是1us,这个1us就是指令周期,这1us也就是定时器定时的最小单位。

定时器与预分频器

假设在没有预分频器情况下。开启定时器 每隔一个指令周期定时器就加一。假设时钟是4MHz 也就是每隔 1us 定时器加一。

如果有了预分频器假设预分频器设置成2分频,定时器就 每隔2个指令周期定时器加一。如果预分频器设置成4分频,定时器就 每隔4个指令周期定时器加一,以此类推。


使用特权

评论回复
沙发
wiba|  楼主 | 2019-7-25 13:51 | 只看该作者

定时器中断标志位

如: TMR0 这个是8位的定时器,也就是8位的寄存器。8位的寄存器能代表的数值为0~255.也就是说定时器可以从0开始加一直加到255.到255后再加一就又变成0。此时TMR0定时器中断标志位 (TMR0IF)变成 1.(如果中断没有开启,并不执行中断程序。)

到底从时钟频率一直到定时器中断溢出之间是什么关系呢?

下面我画了一个流程图我们用频率的方式来理解这一切。假设时钟频率是4MHz ,定时器预分频值为2,定时器初始值为0.

1。首先4MHz 的时钟 4分频后变成 1MHz的指令频率;

2。然后预分频器 2 分频后变成 0.5MHz的频率供给定时器;

3。定时器经过256分频后变成约1952Hz的频率溢出中断;



使用特权

评论回复
板凳
wiba|  楼主 | 2019-7-25 13:51 | 只看该作者

然后我们再用周期的方式来理解这一切。

1。首先0.25us时钟周期4分频后变成 1us指令周期;

2。然后预分频器 2 分频后变成 2us周期 供给定时器;

3。定时器每隔2us加一 ,加到256次 256X2us=512us溢出中断 ;



希望上面的流程图能帮你梳理一下概念。

使用特权

评论回复
地板
wiba|  楼主 | 2019-7-25 13:51 | 只看该作者

实例说明:

假设时钟周期为4MHZ,每隔50MS点亮LED,每隔50MS灭掉LED。这样的程序要如何做到呢。

这50ms如何做到.

1,得到指令周期

4MHz/4=1MHz

1/1MHz=0.0000001s=1us

2,得到预分频

定时器定时的最大时间要超过这50mS,所以预分频器要选择256

预分频X256=最大的定时时间。256X256=65536us=65.536ms 大于50ms

3, 计算定时器初始值

(定时器最大值+1)- (定时时间/预分频)=定时器的初始值。

255+1=256

50000/256=195.3125

256-195.3125=60.6875 四舍五入 定时器初始值为61.

设置相关的寄存器。

OPTION_REG寄存器中我们一般需要设置三处。

PS<2:0>设置用来设置预分频预分频范围从2 ~256

PSA设置成0 讲预分频器分配给Timer0模块

TMR0CS设置成0 内部指令周期时钟。



使用特权

评论回复
5
wiba|  楼主 | 2019-7-25 13:52 | 只看该作者

实例程序:

/*开发环境 MPLAB X IDE 型号PIC16LF1823*/

#include

__CONFIG(FOSC_INTOSC&WDTE_OFF&PWRTE_ON&MCLRE_OFF&CP_ON&CPD_OFF&BOREN_ON&CLKOUTEN_OFF&IESO_ON&FCMEN_ON);

__CONFIG(PLLEN_OFF&LVP_OFF) ;

#define LED LATA5/*也可用 #define LED RA5,只是PIC16LF1823 输出电平的时候,直接控制LATA5执行速度更快,因为传给RA5的数据最终也是传给LATA5才执行的*/

void init_fosc(void)

{

OSCCON= 0x68;//时钟设置为4MHz

}

void init_gpio(void)

{

PORTA = 0;

LATA = 0;

ANSELA = 0;

TRISAbits.TRISA5=0; //RA5口设置成输出 用来控制LED

}

void init_timer0(void)

{

OPTION_REG=0x87; //预分频为256

}

int main(int argc, char** argv)

{

init_fosc();

init_gpio();

init_timer0();

TMR0IF=0;//清除TMR0中断标志位

TMR0=61;//设置中断初始值61

while(1)

{

if(TMR0IF==1)//定时时间到了吗??

{

LED = ~LED;//改变LED的状态

TMR0IF=0;//清除TMR0中断标志位

TMR0=61;//设置中断初始值61为下次50ms定时做准备

}

}

}



使用特权

评论回复
6
wiba|  楼主 | 2019-7-25 13:52 | 只看该作者
所谓定时功能就是通过来自单片机内部的时钟脉冲作计数脉冲,使计数器计数,即每个机器周期计数器加1 ,计数值达到予置值后,定时/计数模块产生溢出。

所谓计数是指对外部事件进行计数。外部事件的发生以输入脉冲表示,因此计数功能的实质就是对外来脉冲进行计数。

定时器/ 计数器TMR0 模块的定时工作方式

  对8 位定时器TMR0 来说,不使用分频器时,定时时间的计算公式为:(28 -计数初值)×指令周期

  使用分频器时,定时时间的计算公式为:分频比×(28-计数初值) ×指令周期;分频比取值为2 、4 、8…256。

使用特权

评论回复
7
wiba|  楼主 | 2019-7-25 13:52 | 只看该作者
首先强调的是TMR1可以被禁止工作,以降低能耗。要关闭定时/计数模块T M R 1只要将 T M R 1使能位 TMR1ON清0 ,“ 与” 门G1的一个引脚被低电平封锁,就使得累加计数器保持静止状态。对16位定时器TMR1 来说,如选择内部时钟源,则定时时间的计算公式为:

         分频比×(216– 计数初值)  ×指令周期。分频比取值为1 、2 、4、8 。

定时器TMR2模块只有一种工作方式,即定时器工作方式.时钟信
号由内部系统时钟4分频后获取,即取自指令周期信号.
(1)用作周期可调的时基发生器:如指令周期为T,分频比为P1,周期寄存器预赋值为PR2 ,则该周期的计算式为:TTMR2=T×P1×(PR2+1)。

(2)用作延时可调的周期性定时器:如指令周期为T,预分频比为P ,周期寄存器预赋值为PR2 ,后分频比为P2,则该超时溢出周期为:TTMR2IF=T×P1×(PR2+1)×P2
(3)用作普通定时器:如指令周期为T,预分频比为P1,则定时时间为P1×(28-X)×T   (以PIC16F877A为例进行的说明)

使用特权

评论回复
8
deepblueyqw| | 2019-9-2 10:37 | 只看该作者
时间在mcc中直接 就能配置好吧
还用去计算?

使用特权

评论回复
9
deepblueyqw| | 2019-9-2 10:38 | 只看该作者
这是查询方式
中断怎么做?

使用特权

评论回复
10
奔波儿熊| | 2019-9-2 17:13 | 只看该作者
这么详细啊,赞一个

使用特权

评论回复
11
wiba|  楼主 | 2019-9-9 16:07 | 只看该作者
感谢各位支持

使用特权

评论回复
12
mjs0528| | 2019-10-6 18:00 | 只看该作者
感谢分享,感谢楼主!!!

使用特权

评论回复
13
yiy| | 2019-10-7 14:56 | 只看该作者
看结构图,更容易理解

使用特权

评论回复
14
xixi2017| | 2019-10-9 20:50 | 只看该作者
现在好多了,图形化配置可以很清楚每个环节的时钟。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

77

主题

3312

帖子

3

粉丝