找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机定时器与中断

[复制链接]
跳转到指定楼层
楼主
ID:424834 发表于 2019-11-17 21:45 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
51单片机共有两个16位可编程的定时器/计数器,即定时器T0和定时器T1。它们既有定时功能又有计数功能,通过设置一些相关的特殊功能寄存器就可以选择启用哪一个功能。定时器系统是单片机内部一个独立硬件部分,与CPU和晶振之间通过内部某些控制线连接并相互作用,CPU一旦启动定时功能,定时器便会在晶振的作用下自动计时,当定时器计数器积满之后就会产生中断,通知CPU接下来做什么。

定时器或计数器实质是加一计数器(16位)(其输入脉冲有两个来源,一是由系统时钟振荡器输出脉冲经过十二分频后送来;另外是T0或T1引脚输入的外部脉冲源,每来一个脉冲计数器加1,当加到计数器全为1时,在输入一个脉冲就可使计数器回零,计数器的溢出是的TCON寄存器中TF0或TF1置1,向CPU发出中断请求,如果定时或计数器工作于定时模式,则表示定时时间到了,如果是计数则表示计数值已满)由高八位和低八位两个寄存器组成。
TMOD:定时器/计数器模式控制寄存器(TIMER/COUNTER MODE CONTROL REGISTER) ,确定工作方式和功能
TCON:控制寄存器,控制T0,T1的启动和停止及设置溢出标志。

定时器/计数器模式控制寄存器TMOD是一个逐位定义的8位寄存器,但只能使用字节寻址,其字节地址为89H。其格式为:其中低四位定义定时器/计数器C/T0,高四位定义定时器/计数器C/T1,各位的说明:
GATE——门控制。
GATE=1时,由外部中断引脚INT0、INT1来启动定时器T0、T1。 当INT0引脚为高电平时TR0置位,启动定时器T0; 当INT1引脚为高电平时TR1置位,启动定时器T1。 GATE=0时,仅由TR0,TR1置位分别启动定时器T0、T1。
C/T——功能选择位
C/T=0时为定时功能,C/T=1时为计数功能。 置位时选择计数功能,清零时选择定时功能。
M0、M1——方式选择功能
由于有2位,因此有4种工作方式:
M1M0 工作方式计数器模式 TMOD(设置定时器模式)
0 0 方式0 13位计数器 TMOD=0x00
0 1 方式1 16位计数器 TMOD=0x01
1 0 方式2 自动重装8位计数器 TMOD=0x02
1 1 方式3 T0分为2个8位独立计数器,T1为无中断重装8位计数器 TMOD=0x03 单片机定时器0设置为工作方式1为TMOD=0x01

TCON: 定时器/计数器控制寄存器(TIMER/COUNTER CONTROL REGISTER)
TMOD分成2段,TCON控制更加精细,分成四段,在本文中只要用到高四段。 TF0(TF1)——计数溢出标志位,当计数器计数溢出时,该位置1。
TR0(TR1)——定时器运行控制位 当TR0(TR1)=0 停止定时器/计数器工作 当TR0(TR1)=1 启动定时器/计数器工作
IE0(IE1)——外中断请求标志位

IT0(IT1)——外中断请求信号方式控制位 当IT0(IT1)=1 脉冲方式(后沿负跳有效)
当IT0(IT1)=0 电平方式(低电平有效)此位由软件置1或清0。
TF0(TF1)——计数溢出标志位
当计数器产生计数溢出时,此位由硬件置1。当转向中断服务时,再有硬件自动清0。计数溢出的标志位的使用有两种情况:采用中断方式时,作中断请求标志位来使用;采用查询方式时,作查询状态位来使用。注意记忆方法,理解单词原形,就绝对不会把TF和TR搞混。TF的F也就是溢出Over Flow的F。TR的R就是运行Run。默认是0不运行,当然要置1才运行
//在写单片机定时器程序时候,在程序开始出需要对定时器及中断寄存器做初始化设置,通常初始化过程如下:对TMOD赋值,以确定T0和T1的工作方式; 计算初值,并将初值写入TH0,TL0或者TH1,TL1; 中断方式时,则对IE赋值,开放中断 使TR0或TR1置位,启动定时器/计数器定时或者计数。
//实现led灯一秒亮灭闪烁
//实现led灯一秒亮灭闪烁#define  uhar  unsinged char #define  uint  unsinged intuchar num;void main(){    TMOD=0x01;//设置定时器0为工作方式1(M1 M0为01)    TH0=(65536-45872)/256;//装初值11.0582晶振定时50ms数为45872    TL0=(65536-45872)%256;    EA=1;//开总中断    ET0=1;//开定时器0中断    TR0=1;//启动定时器0    while(1);//程序停止在这里等待中断发生}void T0_time() interrupt 1{    TMOD=0x01;//重装初值    TH0=(65536-45872)/256;    num++;//num每加一次判断一次是否到20次    if(num==20)//如果到了20次,说明1秒时间到        {            num=0;//num清0重新计数            led=~led1;        }}

编写单片机定时器程序的步骤:

1.对TMOD赋值,以确定T0和T1的工作方式。
2.计算初值,并将初值写入TH0,TL0或TH1,TL1。
3.中断方式时,对IE赋值,开放中断。
4.使TR0或TR1置位,启动定时器/计数器定时或计数。
1.定时器使用方法
1.时间的计算
要实现定时50ms,(65536-T0)x12/12000000=0.05s得T0=15536即0x3c要实现定时tms,可以利用(65536-t)x12/12000000= txE-3;求出t,即可。
2.对TMOD赋值,以确定T0和T1的工作方式
//例子TMOD=0x01;    //0b00000001  用的是定时器0,工作在方式1(16位寄存器)TMOD:定时器/计数器模式控制寄存器GATE=1时,由外部中断引脚INT0、INT1来启动定时器T0、T1。   当INT0引脚为高电平时TR0置位,启动定时器T0;   当INT1引脚为高电平时TR1置位,启动定时器T1。   GATE=0时,仅由TR0,TR1置位分别启动定时器T0、T1。   Ⅱ,C/T——功能选择位   C/T=0时为定时功能,C/T=1时为计数功能。   置位时选择计数功能,清零时选择定时功能。   Ⅲ,M0、M1——方式选择功能   由于有2位,因此有4种工作方式     M1  M0 工作方式 计数器模式 TMOD(设置定时器模式)    0 0 方式0 13位计数器 TMOD=0x00   0 1 方式1 16位计数器 TMOD=0x01   1 0 方式2 自动重装8位计数器 TMOD=0x02   1 1 方式3 T0分为2个8位独立计数器,T1为无中断重装8位计数器 TMOD=0x03
/**********************************************************************************************定时器1的初始化函数************************************************************************************************/void timer1_init()   //这里是定时器1初始化函数{     TMOD |= 0x10;          //TMOD里 MO 置1     TMOD &= 0xdf;        //TOOD里  M1 清零 定时器选择为 16位定时模式     TH1   = 0xFC;          //下面2句是 定时器的初值 也就是你定时器需要定时的时间     TL1   = 0x67;    TR1   = 1;               //启动定时器 }

3.计算初值,并将初值写入TH0,TL0或TH1,TL1。
TH0=(65536-50000)/256; //装定时器初值高8位TL0=(65536-50000)%256; //装定时器初值低8位        TH0=(65536-T0)/256 ;//装定时器初值高8位TL0=(65536-T0)%256 ;//装定时器初值低8位//其中T0是需要计算的时间//一般编程过程并直接计算T0的值,直接写让单片机自己去计算
4.中断方式时,对IE赋值,开放中断。
EA=1;   //开 总中断ET0=1; //开 定时器0中断 EA=1;开 总中断         EA=0;关闭 总中断 ET0=1;开 定时器0中断    ET0=0;关闭 定时器0中断 EA=1;开 总中断         EA=0;关闭 总中断 ET1=1;开 定时器1中断    ET1=0;关闭 定时器1中断 /*********** //TR0=1;//启动定时器0   TR0=1;//关闭定时器0 ************/
5.//定时器初始化
/************************************定时器初始化案例******************************************/void timer0Init(){        TMOD=0x01;            //0b00000001  用的是定时器0,工作在方式1(16位寄存器)        TH0=(65536-50000)/256;   //装定时器初值高8位        TL0=(65536-50000)%256;    //装定时器初值低8位                EA=1;//开总中断        ET0=1; //开定时器0中断   //TR0=1;//启动定时器0   TR0=1;//关闭定时器0}
6..一般使用定时器的代码步骤
//实现led灯一秒亮灭闪烁#define  uhar  unsinged char #define  uint  unsinged intuchar num;void main(){    TMOD=0x01;//设置定时器0为工作方式1(M1 M0为01)    TH0=(65536-45872)/256;//装初值11.0582晶振定时50ms数为45872    TL0=(65536-45872)%256;    EA=1;//开总中断    ET0=1;//开定时器0中断    TR0=1;//启动定时器0    while(1);//程序停止在这里等待中断发生}void T0_time() interrupt 1{    TMOD=0x01;//重装初值    TH0=(65536-45872)/256;    num++;//num每加一次判断一次是否到20次    if(num==20)//如果到了20次,说明1秒时间到        {            num=0;//num清0重新计数            led=~led1;        }}

/定时器0中断函数#define  uhar  unsinged char void T0/T1_time() interrupt 1//使用定时器中断1{        TMOD=0X01;//选择了定时器0 方式1    //可以设置TMOD=0x00;0x01;0x10;0x11;共四组方式        TH0=(65536-T0)/256;   //装定时器初值高8位        TL0=(65536-T0)%256;    //装定时器初值低8位    //T0是需要计算的时间    uchar count=0;    if(count==X)        {        count=0; //清0重新计数        执行程序代码    }    //其中X是需要计算次数,比如让定时器定时个1s;    //则需要定时器一个50ms的时间;    //如果要达成1s则需要执行20次;    //让定时器定时个50ms时间,需要这样去写    //TH0=(65536-50000)/256;    //TL0=(65536-50000)%256;    //让定时器定时个T0时间,需要这样去写    //     //TH0=(65536-T0乘10的3次方)/256;    //TL0=(65536-T0乘10的3次方)%256;            }void main(){     timer0Init();//初始化     //执行程序代码,完成相应的功能;     while(1)     {        //执行程序代码,完成相应的功能;     }}void T0_time() interrupt 1{    TMOD=0x01;//重装初值    TH0=(65536-45872)/256;    num++;//num每加一次判断一次是否到20次    if(num==20)//如果到了20次,说明1秒时间到        {            num=0;//num清0重新计数            led=~led1;        }}
/*************************网上程序******************************/
/*************************网上程序******************************/#include"reg51.h"sbit led=P1^1;#define uchar unsigned char//#define uint unsigned intuchar num;//定义全局变量void t0Iint()//定时器0的初始化函数{       TMOD=0x01;//设置定时器0为工作方式1(M1 M0为01)    TH0=(65536-50000)/256;//装初值11.0582晶振定时50ms数为45872    TL0=(65536-50000)%256;    EA=1;//开总中断    ET0=1;//开定时器0中断}void main(){     t0Iint();     //TMOD=0x01;//设置定时器0为工作方式1(M1 M0为01)     // TH0=(65536-50000)/256;//装初值11.0582晶振定时50ms数为45872    //TL0=(65536-50000)%256;    //EA=1;//开总中断    //ET0=1;//开定时器0中断    TR0=1;//启动定时器0    while(1);//程序停止在这里等待中断发生}void T0_time() interrupt 1{    //TMOD=0x01;//重装初值    //TH0=(65536-50000)/256;       num++;//num每加一次判断一次是否到20次    if(num==20)//如果到了20次,说明1秒时间到        {            num=0;//num清0重新计数            led=~led;        }}


模板


/**********该程序经过处理更容易懂和套模板利用********************************************/#include"reg51.h"sbit led=P1^1;//定义一个LED灯为1.1引脚#define uchar unsigned char//#define uint unsigned intuchar num;//定义全局变量void timer0Iint()//定时器0的初始化函数{       TMOD=0x01;//设置定时器0为工作方式1(M1 M0为01)    TH0=(65536-50000)/256;//装初值11.0582晶振定时50ms数为45872    TL0=(65536-50000)%256;    EA=1;//开总中断    ET0=1;//开定时器0中断}void T0_time() interrupt 1{       num++;//num每加一次判断一次是否到20次      if(num==20)//如果到了20次,说明1秒时间到        {            num=0;//num清0重新计数            led=~led;        }}void main(){     timer0Iint();     TR0=1;//启动定时器0//该步骤也可在初始化写    while(1)    {    }//程序停止在这里等待中断发生   


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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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