分享

单片机之定时器篇_定时器t0,t1各种工作方式最长时间

 和生k7zm98l2kv 2023-06-06 发布于广东

学习单片机这门课的时候我们肯定会学习到中断这节,然后就会了解到什么是外部中断和内部中断还有串行口中断,外部中断包括:外部中断0(INT0),外部中断1(INT1);内部中断包括:定时器/计数器0,定时器/计数器1;我们这里只讲关于定时器T0/T1的知识及使用方法,后面关于其他的知识我们会陆续讲解。

标准的51里边只有定时器0和定时器1这两个定时器,现在很多单片机也有多个定时器的,在这里我们先讲定时器0和1。那么我前边提到过,对于单片机的每一个功能模块, 都是由他的SFR,也就是特殊功能寄存器来控制。而和定时器有关的特殊功能寄存器,有以下几个,大家不需要去记忆这些寄存器的名字和作用,你只要大概知道就行,用的时候,随时可以查手册,找到每个寄存器的名字和每个寄存器所起到的作用。

T0有4种工作方式,T1有3种工作方式,每种工作方式都有定时和计数2种方式,故共有14种组合关系。见下表:
在这里插入图片描述

定时/计数器控制寄存器 TCON (可位寻址)
在这里插入图片描述
关于定时器控制位的描述如下:
在这里插入图片描述
*TF0/TF1使用中断方式时,作为中断标志位,中断响应后由硬件自动清零;
*TF0/TF1使用查询方式时,作为状态供查询,查询有效后应用软件将该位自动清零。

工作方式控制寄存器 TMOD (不可位寻址)
在这里插入图片描述
关于工作方式寄存器的描述如下:
在这里插入图片描述
这个地方的意细心的同学会发现,TCON那个地方标注的是“可位寻址”,TMOD这里标注的是“不可位寻址”。这个地方的意思就是比如TCON有一位TR1,我们可以在程序中直接进行TR1 = 1;这样操作。但是(T1)M1 = 1;这样的操作就是错误的。我们要操作就必须一次操作一个字节, 就是必须一次性对TMOD所有位操作,不能对其中某一位单独进行操作。

接下来介绍一下关于定时器工作方式,以及计算公式和计数范围。

工作方式
T1只有3种工作方式(T0的方式3中占用了T1的部分资源)
T0
在这里插入图片描述
T1
在这里插入图片描述
计算公式
定时计数初值 a = 2^x- t×fosc/12
(t ≤2^x us, fosc=12MHz时)

各工作方式的计数范围
工作方式0
N=2^13-计数初值
即 计数初值=2^13-N,计数范围即位1~8192
定时时间 t=(2^13-计数初值)(振荡周期12)
假设晶振频率位12MHz,则最大计数个数为8192,最大定时时间则为8.192ms。

由此可知
工作方式1的最大计数个数为65536,最大定时时间为65.536ms。
工作方式2的最大计数个数为256,最大定时时间为0.256ms。

工作方式3
当T0置成工作方式3时,TL0、TH0为两个独立的计数器
(1)TL0的功能和操作与方式0、1完全相同(定时/计数),使用T0的所有控制位。
(2)TH0只能用作定时功能,并占用了T1的控制位TR1和中断标志位TF1,其启动仅受TR1的控制。

利用定时器做一个延时1s的流水灯设计

程序代码如下:

#include"reg52.h"  //头文件
#define LED P1    //端口单片机P1端口名称为LED
unsigned char i;  //定义一个无符号字符型变量 i

void Delay_50ms(unsigned char Times) //定义一个50ms的子函数
{
  while(Times--)
  {
/*这里用的是定时器0,工作方式1,工作方式1的计数最大值是65536us,
1s的话是1000000us,显然想要达到1s的效果,已经超出了工作方式一的
最大计数值,所以我们采用0.05s,让它重复执行20次,依次来达到1s的效果,
0.05s也就是50000us,我们根据根据公式可以计算出它的计数初值为16536,
转换后换成16进制就是3cb0H*/
		
    TH0  = 0x3C;  //计数初值的高8位赋值给TH0
		TL0  = 0xB0;  //计数初值的低8位赋值给TH0
		TR0 = 1;   //启动定时器0
		while(!TF0);   //判断T0是否溢出,如果没有则继续计数
		TF0 = 0;    //溢出后清0
  }
}

void main(void)  //主函数 
{
   TMOD = 0x01;  //设置TMOD的值,表示用的是定时器0,工作方式1
	 EA=1;      //开中断
	 ET0=1;     //开定时器0中断
   while(1)  //死循环
   {
		 for(i=0;i<8;i++)  //利用for循环,达到8个灯的流水效果
		{
			LED=~(0x01<<i);	 //LED向左循环一位
			Delay_50ms(20);  //延时1s
		}	
   }
}

仿真电路图如下:
在这里插入图片描述
本次分享就到这里,喜欢的话可以关注我,一起玩转单片机,希望我们都可以在这条路上走得越来越远,路越来越宽❤~

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多