定时/计数器的初始化与计数初值的计算

一. 定时/计数器的初始化

初始化程序应完成如下工作:
1). 对TMOD赋值, 以确定T0和T1的工作方式.
2). 计算初值, 并将其写入 TH0, TL0 或者 TH1, TL1.
3). 使用中断方式时, 则对IE赋值, 开放中断.
4). 使 TR0 或 TR1 置位, 启动定时/计数器的定时或计数.

二. 初值的计算

假设定时器工作在方式1, 则位数是16位. 定时器一旦启动, 便在原来的数值上开始加1计数. 如果程序开始时, 我们没有设置TH.x和TL.x, 则它们的默认值为0. 假设时钟频率为12MHz, 12个时钟周期为一个机器周期, 那么此时机器周期就是1us, 计满TH.x 和TL.x 就需要: 计数最大值-1; 再来一个脉冲, 计数器就会溢出, 随即向CPU申请中断. 因此溢出共需要65536us, 约等于65.5ms.

例如要定时50ms, 那么就要先给TH.x和TL.x装初值. TH.x和TL.x 中应该装入的总数是65536 - 50000 = 15536; TH.x = 15536 / 256 = 60; TL.x = 15536 % 256 = 176; 在这个初值的基础上级50000个数后就溢出, 此时刚好就是50ms中断一次.

例如要定时1s, 但是定时/计数器的最大定时时长为65536us, 不够. 那么我们可以设定定时50ms, 重复20次, 就刚好是1s了.(20次50ms就刚好是1s).


三. 例子代码

// P1口大约1s置反一次

#include<reg52.h>	// 包含特殊功能寄存器的定义
#define LED P1		// 宏定义LED代表P1

unsigned char ucCount = 0;

// 定时器初始化子程序
void Init_Timer0(void)		  
{
	TMOD = 0x01;		// 不影响定时计数器T1
						// 使用定时计数器T0(GATE 0, C/T 0, M1 0, M0 1)
						// 使用模式1, 16位定时器.
	TH0 = (65536 - 50000) / 256;	      	// 计数器计数初值, 这里使用定时器最大值从0开始计数一直到65535溢出
	TL0 = (65536 - 50000) % 256;

	EA = 1;            // 总中断打开
	ET0 = 1;           // 定时器中断打开
	TR0 = 1;           // 定时器开关打开
}

void main()
{
	Init_Timer0();

	P1 = 0xFF;
	while(1);
}


// 中断函数
void Timer0_isr(void) interrupt 1 using 1
{
	TH0 = (65536 - 50000) / 256;	      	// 计数器计数初值, 这里使用定时器最大值从0开始计数一直到65535溢出
	TL0 = (65536 - 50000) % 256;

	++ucCount;
	if(19 == ucCount)
	{
		LED = ~LED;		// 指示灯反相,可以看到闪烁
		ucCount = 0;	
	}
	
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值