找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 11322|回复: 1
打印 上一主题 下一主题
收起左侧

pic16f887 TMR0计时器讲解及准确定时程序

[复制链接]
跳转到指定楼层
楼主
前言
TMR0 计时器
实际上 TMR0 计时器的应用很广。很少程式不用到它。它非常方便,而且很容易用来撰写产生任意期 间的脉冲的程式或副程式(subroutine)、测量时间,或是计数外部脉冲 (事件),几乎没有什么限制。
TMR0 计时器模组是 8 位元的计时器/计数器,具有下列特性:
● 8 位元计时器/计数器;
● 8 位元 prescaler (与 Watchdog timer 共享);
● 可程式的内部或外部时脉来源 (Programmable internal or external clock sources);
● 溢位中断 (Interrupt on overflow); 及
● 可程式选择的外部时脉边缘 (Programmable external clock edge selection)。

原理与暂存器设定说明
原理:
OPTION_REG 暂存器

可以看出,PSA 位元的逻辑状态决定 prescaler 指派给 TMR0 或是 watchdog timer。
另外,值得一提的是:
● 当 prescaler 指派给 TMR0 时,任何对 TMR0 暂存器的写入动作将会清除 prescaler;
● 当 prescaler 指派给 watchdog timer 时,CLRWDT 指令将同时清除 prescaler 与 WDT;
● 当 TMR0 作为计时器用时,对 TMR0 的写入动作不会让脉冲计数立即开始,而会有两个指令周期 的延迟。因此,有必要调整写到TMR0 的值;
● 当微控制器被设成睡眠模式时,振荡器便会关闭。因为没得计数脉冲,所以就不会发生溢位 (overflow)。这就是为什么 TMR0 溢位不能将微控制器从睡眠模式中唤醒的原因;
● 当用作不含 prescaler 的外部时脉计数器时 (external clock counter),最小的脉冲长度或两个脉 冲之间的间歇必须是 2 Tosc + 20 nS. Tosc 是振荡讯号周期 (oscillator signal period);
● 当用作含 presacler 的外部计数器时,最小的脉冲长度或两个脉冲之间的间歇必须是 10nS;
● 8 位元 prescaler 暂存器不提供给使用者,这表示不能直接读写 prescaler 暂存器;
当从 TMR0 将 prescaler 指派给 watchdog timer 时,必须按下列指令次序执行以免发生重置 (reset):
view source    print?
01 BANKSEL TMR0   02 CLRWDT ;CLEAR WDT   03 CLRF TMR0 ;CLEAR TMR0 AND PRESCALER    04 BANKSEL OPTION_REG   05 BSF OPTION_REG,PSA ;PRESCALER IS ASSIGNED TO THE WDT        06 CLRWDT ;CLEAR WDT   07 MOVLW b’11111000’ ;SELECT BITS PS2,PS1,PS0 AND CLEAR      08 ANDWF OPTION_REG,W ;THEM BY INSTRUCTION “LOGICAL AND”  09 IORLW b’00000101’ ;BITS PS2, PS1, AND PS0 SET        10 MOVWF OPTION_REG ;PRESCALER RATE TO 1:32
● 同样的,当从 WDT 将 prescaler 指派给 TMR0 时,必须按下列指令次序执行以免发生重置:
view source    print?     1 BANKSEL TMR0   2 CLRWDT ;CLEAR WDT AND PRESCALER      3 BANKSEL OPTION_REG
4 MOVLW b’11110000’ ;SELECT ONLY BITS PSA,PS2,PS1,PS0               5 ANDWF OPTION_REG,W ;CLEAR THEM AFTERWARDS BY INSTRUCTION 6 ;“LOGICAL AND”         7 IORLW b’00000011’ ;PRESCALER RATE IS 1:16    8 MOVWF OPTION_REG
暂存器设定说明
为了恰当地使用 TMR0,必须:
1、要选择模式:
● 计时器模式是借由 OPTION_REG 暂存器的 T0CS 来选择。 (T0CS: 0=timer, 1=counter);
● 使用的时候,必须借由清除 OPTION_REG 暂存器的 PSA 位元将 prescaler 指派给 TMR0。 prescaler 比率 (Prescaler rate) 的设定是透过OPTION_REG 暂存器的 PS2-PS0 位元,及
● 使用中断时,必须设定 INTCON 暂存器的 GIE 与 TMR0IE 位元。
2、要测量时间:
● 重设 TMR0 暂存器或写入已知的值到 TMR0;
● 经过时间 (单位是毫秒,当使用 4 MHz 石英晶体时) 的获得方式是透过读取 TMR0 暂存器
● 每当 TMR0 暂存器溢位时,INTCON 暂存器的 TMR0IF 旗号便会自动竖起来,如果中断有启用, 会引发中断。
3、要计数脉冲:
● 位于 RA4 脚位,要计数的脉冲极性 (polarity) 的选择是透过设定 OPTION_REG 暂存器的 T0SE 位元 (T0SE: 0=负向缘, 1=正向缘); 及
● 脉冲数可从 TMR0 暂存器中取得。如同计时器模式,presacler 和中断的用法是一样的。

三、程式与电路图
程式:
// FOSC=16MHz  Fcy=4Mhz  Tcy=1/Fcy
#include
__CONFIG ( FOSC_HS & WDTE_OFF & PWRTE_OFF & MCLRE_ON & CP_OFF & CPD_OFF &  BOREN_OFF &     IESO_OFF  &  FCMEN_OFF & LVP_OFF ); //配置位元设置为外接晶振
__CONFIG ( BOR4V_BOR40V & WRT_OFF );
unsigned char data=0;//定义变数data并赋值为0
main()
{  
unsigned  int i=0;//定义i为无符号整形并赋值为0
   T0CS=0;   // 选通Fosc/4
   PSA=0;    //设定为TIMER0,而不是WDT
   PS2=0; //1:16 预除4倍,数完250=4MHz/1*250=1ms
   PS1=1;//PS2,PS1,PS0除频设置
PS0=1;
   T0IF=0;//设置溢位初始值为0
   TMR0=6; //预设TMR0=6,运行250次会进位
TRISD=0;// 埠初始化D0--D7设置为输出
PORTD=0; //D输出低电频,8LED全灭掉
data=0b00000001;//data赋值为1
   while(1)       // 主回圈必须是闭环
{
      if(T0IF==1)//如果溢位为1则执行if下语句
{
           T0IF=0;    //if成立将溢位再次置0
           i++;         //i=i+1
            if(i==1000)   //i=1000时执行下面语句
{
                    i=0;    //i重新置0,进行下一轮计时
data=data<<1;   //data左移1
if(data==0)   //如果data=0时执行下面语句
data=0b00000001;   //data重新置为1
                       PORTD=data;  //D埠输出资料为data
                       TMR0=6;//使TMR0等于6
              }
         }
   }
}



电路图

结论





程序打包下载:http://www.51hei.com/bbs/dpj-50261-1.html

评分

参与人数 1黑币 +10 收起 理由
YJGG + 10 很给力!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:23606 发表于 2016-5-17 07:06 | 只看该作者
谢谢楼主分享!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表