1、什么是定时器与计数器
(1)定时器与计数器都是soc当中的一个内部外设。计数器顾名思义是用来计数的,就和我们的秒表一样。假如定时20秒,当我们按下秒表开始计数时,数秒的过程就是计数(计时器).当秒表数到20时(定时器),就自动暂停。
2、工作模式图
3、 定时器/计数器结构(只需掌握红色字体)
TMOD:定时器/计数器模式控制寄存器。属于不可寻址,但只能使用字节寻址。
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
GATE | C/T | M1 | M0 | GATE | C/T | M1 | M0 |
选择哪个定时器看下面(T0 和 T1这两个定时器)
注 意:D0~D3为 T0 定时/计数器的设置,D4~D7为 T1 定时/计数器的设置 。
GATE :门控位,GATE=0时,只要在编写程序时,使TCON中的TRO或TR1为1,就可以启动定时器/计数器工作。
GATE=1时,不仅要在编写程序时,使TCON中的TRO或TR1为1,且需要外部引脚也为高电平,才能工作。
M1,M0:用来选择定时计/计数器的工作方式,一般使用都是采用16位的计时计数器。
M1 | M0 | 工作模式 | 说明 |
0 | 0 | 0 | 13位计时计数器 (8192) |
0 | 1 | 1 | 16位计时计数器 (65536) (本次讲解使用此模式) |
1 | 0 | 2 | 8位计时计数器,可自动重新载入计数值 (256) |
1 | 1 | 3 | 当成两组独立的8位计时器(256,T0和T1不能同时用) |
TCON:控制寄存器,作用是控制定时器的启、停,标志定时器溢出和中断情况。
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
TF1 | TR1 | TF0 | TR0 | IE1 | IT1 | IE0 | IT0 |
TF1 :TF1=1表示T1有中断产生。(Timer Flag,定时器标志位)
TR1 :TR1=1表示T1开始计数。
TF0 :TF0=1表示T0有中断产生。
TR0 :TR0=1表示T0开始运行。
IE1 :IE1=1表示INT1有中断产生。
IT1 :IT1=1表示INT1为下降沿触发,IT1=0表示INT1为低电平触发。
IE0 :IE0=1表示INT0有中断产生。
IT0 :IT0=1表示INT0为下降沿(负跳变)触发,IT0=0表示INT0为低电平触发。
4、定时器/计数器初始流程
第 1 步:选择定时器工作模式(一共有4种工作模式);常用的是工作模式1
即 M1=0 ; M0 =1 ;
第 2 步:选择哪个定时器( T0定时器 和 T1定时器 )
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
GATE | C/T | M1 | M0 | GATE | C/T | M1 | M0 |
比如:选择TO定时器;(只需要把上图最右边两个位置M1 和M0,设置为 0 1,即为定时器T0)
TMOD = 0X01;
但上式子有弊端,它把其它位置都设置为0,最好的方法改为:
TMOD = TMOD & 0XFC (只把最右边两个位值置0)
TMOD= TMOD | 0x01 (只把最右边两位设置为0 1,即TO定时器)
第 3 步:设置定时器初始值(看第4节)
第 4 步:启动定时器TR ,即TR =1
4、设置定时器初始值(图解)
4.1、先看下面的一个例子:
上图有个错误,“设晶振震动x次,震动一次,放一个球”不是震动一次,放一次球。是一个机器周期放一个球。
修改: 设需要 x 次机器周期,用时为20ms。
5、如何让箱子已经表示装了45536
TL0低8位,最多可装 2^8 = 256
TH0高8位 每一个数据:只有当低八位装满256时,进1给THO高8位.(跟我们数学上满10进1一个道理)
5.1 举一例子:
15有几个10. 是不是 15/10 = 1余5, 即十位为 1,个位为 5
从此例子可知,十位上对应的是 整除数1, 个位上对应的是 余数5.
我们不妨把十位(满10 进1),个位 类比 TH0(满256进1),TL0。
THO = 45536 / 256 = 177 (在我们计算机中,除法只取整除数,省略余数)
TLO=45536 % 256 = 244 (在我们计算机中,%是 求余数)
单片机通常赋值使用的是十六进制,因此需要把177,244十进制 转换成 十六进制
十进制: 177(D)--------- 二进制: 10110001 (B)-------------------- 十六进制 :0xB1
十进制:244 (D)-------------二进制:11110100 (B)--------------------- 十六进制:0xF4
5.2、代码实现
#include<reg51.h>
sbit LED =P0^4;
void main()
{
unsigned char cnt =0;
TMOD = TMOD & 0xFC; //选择定时器0。 51有两种定时器,定时器0和定时器1
TMOD = TMOD | 0x01;
TH0 = 0xB1; //定时了20ms
TL0 = 0xF4;
TR0 = 1; //开始启动计时器
}
while(1)
{
if(1==TF0) //当TF0=1时,说明装满箱子一次
{
TF0=0; //重新计数
TH0 = 0xB1; //重新再设置初值
TL0 = 0xF4;
cnt++; //cnt用来计数,装满了多少次箱子
if(cnt>=50) //20ms x50 = 1s ,装满箱子一次用时0.02秒,1秒 需要装满50次。
{
cnt=0; //1秒时间到,重新赋值为0,开始计数装满箱子多次
LED=~LED; // LED每隔一秒亮一次,灭一次
}
}
}