历史上的今天
今天是:2025年04月18日(星期五)
2020年04月18日 | 单片机学习(三)定时器篇
2020-04-18 来源:eefocus
一、定时器介绍
定时/计数器T0和T1分别是由两个8位的专用寄存器组成,即定时/计数器T0由TH0和TL0组成,T1由TH1和TL1组成。此外,其内部还有2个8位的特殊功能寄存器TMOD和TCON,TMOD负责控制和确定T0和T1的功能和工作模式,TCON用来控制T0和T1启动或停止计数,同时包含定时/计数器的状态。 [1]
TF1:定时器1溢出标志。定时/计数器溢出时由硬件置位。中断处理时由硬件清除。或用软件清除。
TF0:定时器0溢出标志。定时/计数器溢出时由硬件置位。中断处理时由硬件清除,或用软件清除。
二、单片机的内部框图与定时器工作原理分析

从上面的图中红线可以看出由TMOD选择由那个定时器工作,工作于什么方式;
从上面的图中蓝线可以看出由TCON决定定时器是否启动;
从上面的图中黄线可以看出外部技术输入由TH和TL进行累计;
从上面的图中紫线可以看出当TH和TL计数溢出时会向TCON进行申请报告;
从上面的图中绿线可以看出所有的定时中断都由TCON向CPU进行中断申请;
从上面的图中黑线可以看出外部中断直接向CPU进行中断申请;
三、寄存器介绍

TCON:
TF0和TF1:定时器/计数器溢出标志位。
当定时器/计数器0(或定时器/计数器1)溢出时,由硬件自动使TF0(或TF1)置1,并向CPU申请中断。
CPU响应中断后,自动对TF1清零。TF1也可以用软件清零。
TR0和TR1:定时器/计数起运行控制位。
TR0(或TR1)=0,停止定时器/计数器0(或定时器/计数器1)工作。
TR0(或TR1)=1,启动定时器/计数器0(或定时器/计数器1)工作。
TMOD:
GATE:门控位。
GATE=0,只要用软件使TR0(或TR1)置1就能启动定时器/计数器0(或定时器/计数器1);
GATE=1,只有在(或)引脚为高电平的情况下,且由软件使TR0(或TR1)置1时,才能启动定时器/计数器0(或定时器/计数器1)工作。不管GATE处于什么状态,只要TR0(或TR1)=0定时器/计数器便停止工作。
C/T: 定时器/计数器工作方式选择位。
C/T =0,为定时工作方式;
C/T=1,为计数工作方式。
M0、M1:工作方式选择位,确定4种工作方式。

IE:
EA = 1,CPU开放总中断;
ET0 = 1,允许T0中断;
TR TL:定时器寄存器
注意:由于reg52.h的库定义了大部分的寄存器所以可以直接给TCON TMOD IE赋值操作或者是单独寄存器操作。
四、中断程序执行方法和定时计数公式
中断程序执行方法有直接中断和查询两种方法,查询即查询TF位是否置位为1
定时初值计算公式为:
定时时间=(计数最大值 – 计数初值)×机器周期
机器周期T = 12/晶振频率
或者是用取模的方式
TH0=(计数最大值 – 定时时间)/256;
TL0=(计数最大值 – 定时时间)%256;
首先解析为什么要设定初值?
当设定定时器为16为计数器时,则计数最大值为2^16 = 65536;
TH和TL分别为8位,即TL每逢256进一位,所以除掉256就能看出TH进了多少位,取模则是余下多少位
举个例子,2位计数器最大计数为4,要将初值6分到两个2位计数器,由于低位逢四进1所以剩下2
即TL = 2然后高位是1即TH=1,按照上面的方法:2^4 = 16,2^2 = 4; TH = (16-(16-6))/4=1(整型不算小数);
TL = (16-(16-6))%4=2;可见结果是一样的。
一般的我们选取初值 TH0 = 0x3c,TLO = 0xb0,这时寄存器跑满时的时间为50ms,可以使这个过程进行20次,间隔也就是1s。
五、程序设计
//通过定时器中断实现数码管显示从0~59,间隔为1s
#include sbit LED1 = P1^0; #define DataPort P1 //宏定义,如果换接口,需要修改这里 sbit Seg_Latch = P2^2; //段锁存 sbit Bit_Latch = P2^3; //位锁存 unsigned char code Seg_Code[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //段码从0~9 unsigned char code Bit_Code[] = {0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //位码,控制8个LED灯 void delayls(void); void Display(unsigned char m,unsigned char num,unsigned int n); static unsigned int n = 0; int main(void) { unsigned char i; TMOD = 0x01; TH0 = 0x3c; TL0 = 0xb0; EA = 1; //开中断 ET0 = 1; //因为只有一个中断,所以IP不用设置 TR0 = 1; //开启定时器0,等待中断到来 while(1) { Display(1,2,n); } } void T0_ISR(void) interrupt 1 { unsigned char i; EA = 0; //屏蔽其他中断 TH0 = 0x3c; //重新赋值,保证每次都是 50ms TL0 = 0xb0; i++; if(i == 20) { i = 0; if(n < 60) { n++; } else { n = 0; } } EA = 1; } void Display(unsigned char m,unsigned char num,unsigned int n) //m表示从第几个数码管开始控制,num表示到第几个数码管,n表示要显示的数字 { unsigned char i,j,a[5],l; a[0] = n / 10; a[1] = n % 10; for(j = m-1;j < num;j++) { DataPort = 0; //初始化 Seg_Latch = 1; Seg_Latch = 0; DataPort = Bit_Code[j]; //送位码 Bit_Latch = 1; //位开门 Bit_Latch = 0; //关门 DataPort = Seg_Code[a[j]]; //送段码 Seg_Latch = 1; //段开门 Seg_Latch = 0; //关门 } }
上一篇:51单片机之计时器与计数器
下一篇:51单片机 时钟
史海拾趣
|
贴片式的MAX1898芯片在无PCB板的情况下如何焊接和调试呢? 想先用线搭个板子调试,单片机有管脚座,但是没想到MAX1898电源管理芯片那么小,放在2根牙签粗细的一个塑料管里,这要是我的焊接技术,所有管脚直接短接....有没有大虾介绍下经验阿.... [ 本帖最后由 zxpla 于 2010-4-15 12:54 编辑 ]… 查看全部问答> |
|
如以下语句: SELECT id,name FROM 表A WHERE id = (SELECT MAX(id) FROM 表A) 这样的语句在2000里运行OK,但是在SQLSERVER CE里却报错。 是SQLSERVER CE不支持吗?有什么解决方案?… 查看全部问答> |
|
将Altium.Designer09器件库中IC部分索引到一个pdf文件中,可以利用PDF阅读器的搜索功能搜索。 不知道有没有用途,反正我自己在用。 分卷压缩: https://download.eeworld.com.cn/detail/wangfuchong/13082 https://download.eeworld.com.cn/det ...… 查看全部问答> |
|
三极管有三个工作区:截止区、放大区和饱和区,而MOSFET对应的是关断区、饱和区和线性区。MOSFET线性区也叫三极区或可变电阻区,在这个区域,MOSFET基本上完全导通。 漏源间的导通电阻RDS(on) MOSFET在导通时漏源之间 ...… 查看全部问答> |




