51单片机定时器/计数器
定时(定时控制、测量、延时。。。)和计数(对外部事件统计数目)。
软件定时
机器执行一个程序,这个程序没有其他用处,只是为了延时!以达到定时的目的。
数字电路硬件定时
555之类的器件,完成定时可编程定时/计数器
硬件定时,但是是可编程的,可以通过软件初始化设置定时的要求。
1.结构
定时/计数器实质上是一个加一计数器,可以工作在两种方式里,实际上都是对脉冲计数,只是说脉冲的来源不一样而已!
1. 定时
1. 加一计数。
2. 脉冲来自振荡器的12分频后的脉冲(Fosc/12),简单的说就是对机器周期计数。
3. 需要预设定时初值(TH、TL)。
4. 初值设置需要是补码,加一计数(补码的加,原值的减)加到溢出(原值减到0了)则发生溢出中断。
2. 计数
1. 加一计数。
2. 需要预设计数初值(TH、TL)。
2. 脉冲来源于T0或T1引脚。
2. 上图的控制开关合上(控制=1)计数器对外部脉冲产生的下降沿开始计数
3. 知道计满,初始值变为0,产生溢出中断。
4. 计数脉冲的最高频率不可超过Fosc/24
2.定时计数器有关寄存器
中断我们需要考虑几个方面
- 中断打开没
- 怎么触发中断
- 中断的启停
- 多个中断触发后如何响应
(1)TMOD 定时计数方式寄存器(地址89h)
GATE1 | C/T1 | M1 | M0 | GATE0 | C/T0 | M1 | M0 |
---|---|---|---|---|---|---|---|
T1门控开关 | T1计数/定时 | T1方式选择 | T1方式选择 | T0门控开关 | T0计数/定时 | T0方式选择 | T0方式选择 |
GATE:
1. 门控信号 ,GATE=0,TRx=1 自启动的方式
2. GATE=1,TRx=1,INTx=1 启动定时/计数器工作(一种以INTx作为外界启动条件的方式)
C/-T:
定时、计数选择 —– 1定时0计数
M1M0:
定时计数器的四种工作方式选择
工作方式 | M1 | M0 |
---|---|---|
方式零 | 0 | 0 |
方式一 | 0 | 1 |
方式二 | 1 | 0 |
方式三 | 1 | 1 |
(2)TCON 中断的请求与外部中断的选择(地址88h)
TF1 | TR1 | TF0 | TR0 | IE1 | IT1 | IE0 | IT0 |
---|---|---|---|---|---|---|---|
T1中断请求 | T1工作启停 | T0中断请求 | T0工作启停 | int1中断请求 | int1中断触发方式 | int0中断请求 | int0中断触发方式 |
1请求0无请求 | 1启动0停止 | 1请求0无请求 | 1启动0停止 | 1请求0无请求 | 1下降沿0低电平 | 1请求0无请求 | 1下降沿0低电平 |
3.定时计数器工作方式
方式0:
定时器/计数器T0工作在方式0时,16位计数器只用了13位,即TH0的高8位和TL0的低5位,组成一个13位定时器/计数器(最大计数值8192)。
方式1:
定时器T0工作方式1与工作方式0类同,差别在于其中的计数器的位数。工作方式0以13位计数器参与计数,工作方式1则以16位计数器参与计数(最大计数值65536)。
工作方式1是16位计数器。这是工作方式1与工作方式0在计数方式时唯一差别。
方式2:
自动再装入预置数的工作方式。此时M1M0=10。
自动重装THx存放初值(预置数) ,TLx用于计数,计数完毕则自动将THx的值赋给TLx。(除了重装初值和最大计数值以外,其他同方式0)
方式3:(只适用于T0)
这种式作方式之下,定时/计数器0被拆成2个独立的定时/计数器来用。其中,TL0可以构成8位的定时器或计数器的工作方式,而TH0则只能作为定时器来用。我们知道作定时、计数器来用,需要控制,计满后溢出需要有溢出标记,T0被分成两个来用,那就要两套控制及、溢出标记了,从何而来呢?TL0还是用原来的T0的标记,而TH0则借用T1的标记。
一般情况下,只有在T1以工作方式2运行(当波特率发生器用)时,才让T0工作于方式3。
3.定时计数器计数初值和初始化
计数初值的计算:
- 计数方式:初值C = 模 - X(要计算的脉冲个数)
- 定时方式:初值C = [t /MC]补 = 模 - [t /MC](t定时的时间、MC机器周期,MC = 12/fosc)
- 计数初值示例:
方式0:初值C = (64H)补 = 2000H - 64H = 1F9CH
方式1: 初值C = (64H)补 = 10000H - 64H = FF9CH
方式2: 初值C = (64H)补 = 100H - 64H = 9CH
初始化:
- 计算初值
- TMOD设置
- 写入计数初值THx、TLx
- 启动定时器,TRx = 1
- EA = 1(打开中断总开关)
- ETx = 1 允许中断
- 编写中断子程序
#include<reg51.h>
unsigned char i=0;
int0() interrupt 1//定时器0 中断函数
{
i++;//计算中断次数
}
main()//主函数
{
//计算初值
TMOD = 0x01;//TMOD设置
TH0 = 0x3c;
TL0 = 0xb0;//初值
TR0 = 1//启动定时器,TRx = 1
EA=1;//中断总开关
ET0=1//定时器0 允许中断
}
ORG 0000H
AJMP MAIN
ORG 000bH ;中断子程序入口
AJMP COUNTING ;中断函数名
ORG 0030H
MAIN:
MOV TMOD,#01H ;TMOD设置
MOV TH0 ,#3cH;
TL0 = #0b0H; ;初值
SETB TR0 ;启动定时器,TRx = 1
SETB EA ;中断总开关
SETB ET0 ;定时器0 允许中断
HERE:AJMP HERE
COUNTING:
INC A ;a++
RETI
END
如有错误!请多多包含,方便的话留个言!我好马上修改。