六、定时器和中断系统

定时器介绍:51单片机的定时器属于单片机的内部资源,其电路的连接和运转均在单片机内部完成 定时器作用: (1)用于计时系统,可实现软件计时,或者使程序每隔一固定时间完成一项操作 (2)替代长时间的Delay,提高CPU的运行效率和处理速度(Delay是占用cpu时间的)

定时器

一、STC89C52定时器资源
  • 定时器个数:3个(T0、T1、T2),T0和T1与传统的51单片机兼容,T2是此型号单片机增加的资源。

  • 注意:定时器的资源和单片机的型号是关联在一起的,不同的型号可能会有不同的定时器个数和操作方式,但一般来说,T0和T1的操作方式是所有51单片机所共有的。

定时器框图

  • 定时器在单片机内部就像一个小闹钟一样,根据时钟的输出信号,每隔“一秒”(时间段),计数单元的数值就增加一,当计数单元数值增加到“设定的闹钟提醒时间”时,计数单元就会向中断系统发出中断申请,产生“响铃提醒”,使程序跳转到中断服务函数中执行

暂时无法在飞书文档外展示此内容

二、定时器工作模式
  • STC89C52的T0和T1均有四种工作模式: 模式0:13位定时器/计数器 模式1:16位定时器/计数器(常用) 模式2:8位自动重装模式 模式3:两个8位计数器

  • 工作模式1框图:

  • 在这个模式一这个图形中我们可以将时钟、计数单元、中断系统划分出来:

工作原理:时钟系统每隔一段时间会向计数系统发送一段脉冲,当计数系统接受到脉冲时,计数(TL0和TH0)会加一,计数系统最大能显示2^16(65,535),如果超过了这个数字,计数器中的值就会变0(溢出),然后标志位TF0会加一,当有TF0不为零时,就会向中断系统申请中断

  • TL0:Time low 0:计数器低8位,0代表这是定时器0

  • TH0:Time hight :计数器高8位,0代表这是定时器0

  • TF0:Time flag :标志位,0代表这是定时器0

计数系统分为计数和控制,控制时钟是怎么过来的,包括一些定时器的启动和暂停,TR0就是用于控制定时器是启动还是暂停的。

  • SYSclk(system clock):系统时钟,即晶振周期,本开发板上的晶振为12MHz(表示每秒发生12 000 000次周期变化)(M:为百万级倍数)

51单片机的时钟信号来源有两种方式,一种是通过SYSclk来提供,一种是通过T0 Pin,T0 Pin为外部引脚,当使用外部引脚提供时钟脉冲时,定时器也相当于计数器。

如果选择配置为12T(MCU in 12T mode)模式的分频12/12,这时输出的频率为1MHZ,一个周期为1us,(1s = 1000ms,1ms = 1us)

公式:(2^16– X)× 12 ÷ 晶振频率 = 定时时间(默认单位us)

X = 2^16 - 定时时间(us) * 晶振频率 / 12

—————————————————————————————————

定时器计数初值为 X,X是未知量

—————————————————————————————————

216是根据方式选择的,可以自行选择,方式1为16位

方式0 :213 (少用)

方式1 :216 (最常用)

方式2 :28 (常用)

————————————————

x = 2^16-1000*12/12 = 64536

 

该寄存器如果给1,则代表着C这个功能(count:计数),给0就是Time。如果给1开关则连接下面(T0 Pin),如果给0开关则连接上面(SYSclk)

中断系统

  • 中断系统是为使CPU具有对外界紧急事件的实时处理能力而设置的.

  • 当中央处理机CPU正在处理某件事的时候外界发生了紧急事件请求,要求CPU暂停当前的工作,转而去处理这个紧急事件,处理完以后,再回到原来被中断的地方,继续原来的工作,这样的过程称为中断。实现这种功能的部件称为中断系统,请示CPU中断的请求源称为中断源。微型机的中断系统一般允许多人中断源,当几个中断源同时向CPU请求中断,要求为它服务的时候,这就存在CPU优先响应哪一个中断源请求的问题。通常根据中断源的轻重缓急排队,优先处理最紧急事件的中断请求源,即规定每一个中断源有一个优先级别。CPU总是先响应优先级别最高的中断请求。

  • 当CPU正在处理一个中断源请求的时候(执行相应的中断服务程序),发生了另外一个优先级比它还高的中断源请求。如果CPU能够暂停对原来中断源的服务程序,转而去处理优先级更高的中断请求源,处理完以后,再回到原低级中断服务程序,这样的过程称为中断嵌套。这样的中断系统称为多级中断系统,没有中断嵌套功能的中断系统称为单级中断系统。

一、中断程序流程

二、STC89C52中断资源
  • 中断源个数:8个(外部中断0、定时器0中断、外部中断1、定时器1中断、串口中断、定时器2中断、外部中断2、外部中断3)

  • 中断优先级个数:4个

  • 中断号:

  • 注意:中断的资源和单片机的型号是关联在一起的,不同的型号可能会有不同的中断资源,例如中断源个数不同、中断优先级个数不同等等

三、定时器和中断系统

这条红线就相当于第一种定时器的整个流程。

四、定时器相关寄存器

  • 寄存器是连接软硬件的媒介

  • 在单片机中寄存器就是一段特殊的RAM存储器,一方面,寄存器可以存储和读取数据,另一方面,每一个寄存器背后都连接了一根导线,控制着电路的连接方式

  • 寄存器相当于一个复杂机器的“操作按钮”

TCON :time control

TF:time flag

TR:time run

按键控制LED流水灯模式

#include <REGX52.H>
#include "Timer0.h"
#include "Key.h"
#include <INTRINS.H>
unsigned char KeyNum,LEDMode;
void main()
{
        P2=0xFE;
        Timer0Init();
        while(1)
        {
                KeyNum=Key();                //获取独立按键键码
                if(KeyNum)                   //如果按键按下
                {
                        if(KeyNum==1)        //如果K1按键按下
                        {
                                LEDMode++;   //模式切换
                                if(LEDMode>=2)LEDMode=0;
                        }
                }
        }
}
void Timer0_Routine() interrupt 1
{
        static unsigned int T0Count;
        TL0 = 0x18;                   //设置定时初值
        TH0 = 0xFC;                   //设置定时初值
        T0Count++;                    //T0Count计次,对中断频率进行分频
        if(T0Count>=500)              //分频500次,500ms
        {
                T0Count=0;
                if(LEDMode==0)           //模式判断
                        P2=_crol_(P2,1); //LED输出
                if(LEDMode==1)
                        P2=_cror_(P2,1);
        }
}

  • GATE:结合电路图可知,当GATE置0时通过非门(取反),他的值就会变成1,GATE连接着非门和INT0连接着或门(有1为1),但是当GATE给0时,无论INT0给什么最终的结果都是1,这一部分和TR0连接着与门(有0为0),所以此时计时器的开关由TR0决定。当GATE置1时,此时计时器的开关则由TR0和INT0决定

  • C/T:该寄存器如果给1,则代表着C这个功能(count:计数),给0就是Time。如果给1开关则连接下面(T0 Pin:计数器功能),如果给0开关则连接上面(SYSclk:定时器,内部时钟)

  • M1、M0(定时器/计数器0模式选择):

0 0 13位定时器/计数器,兼容8048定时模式,TL1只用低5位参与分频,TL1整个8位全用。

0 1 16位定时器/计数器,TL1、TH1全用。

1 0 8位自动重装裁定时器,当溢出时将TH1存放的值自动重装入TL1。

1 1 定时器/计数器1此时无效(停止计数)。

由于使用T0定时器,所以TMOD寄存器的值为0x0001;

TCON为定时器/计数器T0、T1的控制寄存器,同时也锁存T0、T1溢出中断源和外部请求中断源等,TCON格式如下

  • TF(time flag):定时器/计数器T1溢出标志。T1被允许计数以后,从初值开始加1计数。当最高位产生溢 出时由硬件置“1”TF1,向CPU请求中断,一直保持到CPU响应中断时,才由硬件清 “0”TF1(TF1也可由程序查询清“0”)。

  • TR(time run):定时器的运行控制位。该位由软件置位和清零。当GATE(TMOD.7)=0,TR1=1时就 允许T1开始计数,TR1=0时禁止T1计数。当GATE(TMOD.7)=1,TR1=1且INT1输入高电平时,才允许T1计数

  • EA : CPU的总中断允许控制位,EA=1,CPU开放中断,EA=0,CPU屏蔽所有的中断申请。EA的作用是使中断允许形成两级控制。即各中断源首先受EA控制;其次还受各中断源自己的中断允许控制位控制。

  • ET0 : T0的溢出中断允许位。ET0=1,允许T0中断;ET0=0禁止T0中断。

#include <REGX52.H>
/**
  * @brief  定时器0初始化,1毫秒@12.000MHz
  * @param  无
  * @retval 无
  */
void Timer0Init(void)
{
        TMOD &= 0xF0;                //设置定时器模式
        TMOD |= 0x01;                //设置定时器模式
        TL0 = 0x18;                //设置定时初值
        TH0 = 0xFC;                //设置定时初值
        TF0 = 0;                //清除TF0标志
        TR0 = 1;                //定时器0开始计时
        ET0=1;
        EA=1;
        PT0=0;
}
/*定时器中断函数模板
void Timer0_Routine() interrupt 1
{
        static unsigned int T0Count;
        TL0 = 0x18;                //设置定时初值
        TH0 = 0xFC;                //设置定时初值
        T0Count++;
        if(T0Count>=1000)
        {
                T0Count=0;     
        }
}
*/
#include <REGX52.H>
#include "Delay.h"
/**
  * @brief  获取独立按键键码
  * @param  无
  * @retval 按下按键的键码,范围:0~4,无按键按下时返回值为0
  */
unsigned char Key()
{
        unsigned char KeyNumber=0;
        if(P3_1==0){Delay(20);while(P3_1==0);Delay(20);KeyNumber=1;}
        if(P3_0==0){Delay(20);while(P3_0==0);Delay(20);KeyNumber=2;}
        if(P3_2==0){Delay(20);while(P3_2==0);Delay(20);KeyNumber=3;}
        if(P3_3==0){Delay(20);while(P3_3==0);Delay(20);KeyNumber=4;}
        return KeyNumber;
}

定时器时钟

#include <REGX52.H>
#include "Delay.h"
#include "LCD1602.h"
#include "Timer0.h"
unsigned char Sec=55,Min=59,Hour=23;
void main()
{
        LCD_Init();
        Timer0Init();
        
        LCD_ShowString(1,1,"Clock:");          //上电显示静态字符串
        LCD_ShowString(2,1,"  :  :");
        
        while(1)
        {
                LCD_ShowNum(2,1,Hour,2);        //显示时分秒
                LCD_ShowNum(2,4,Min,2);
                LCD_ShowNum(2,7,Sec,2);
        }
}
void Timer0_Routine() interrupt 1
{
        static unsigned int T0Count;
        TL0 = 0x18;                     //设置定时初值
        TH0 = 0xFC;                     //设置定时初值
        T0Count++;
        if(T0Count>=1000)               //定时器分频,1s
        {
                T0Count=0;
                Sec++;                  //1秒到,Sec自增
                if(Sec>=60)
                {
                        Sec=0;          //60秒到,Sec清0,Min自增
                        Min++;
                        if(Min>=60)
                        {
                                Min=0;                //60分钟到,Min清0,Hour自增
                                Hour++;
                                if(Hour>=24)
                                {
                                        Hour=0;        //24小时到,Hour清0
                                }
                        }
                }
        }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值