51单片机STC89C52RC——6.2 定时器

一,定时器介绍

STC89C51RC/RD+系列单片机的定时器0和定时器1,与传统8051的定时器完全兼容,当在定时器1做波特率发生器时,定时器0可以当两个8位定时器用。

STC89C51RC/RD+系列单片机内部设置的两个16位定时器/计数器TO和T1都具有计数方式和定时方式两种工作方式。对每个定时器/计数器(TO和T1),在特殊功能寄存器TMOD中都有一控制位―CT来选择TO或T1为定时器还是计数器。定时器/计数器的核心部件是一个加法(也有减法)的计数器,其本质是对脉冲进行计数。只是计数脉冲来源不同:如果计数脉冲来自系统时钟,则为定时方式,此时定时器/计数器每12个时钟或者每6个时钟得到一个计数脉冲,计数值加1;如果计数脉冲来自单片机外部引脚(TO为P3.4,T1为P3.5),则为计数方式,每来一个脉冲加1。

当定时器/计数器工作在定时模式时,可在烧录用户程序时在STC-ISP编程器中设置(如下图所示)是系统时钟/12还是系统时钟/6后让TO和T1进行计数。当定时器/计数器工作在计数模式时,对外部脉冲计数不分频。

定时器在单片机内部就像一个小闹钟一样,根据时钟的输出信号,每隔"一秒",计数单元的数值就增加一,当计数单元数值增加到"设定的闹钟提醒时间"时,计数单元就会向中断系统发出中断申请,产生"响铃提醒",使程序跳转到中断服务函数中执行

二,四种工作模式

STC89C52的T0和T1均有四种工作模式:

模式0:13位定时器/计数器

模式1:16位定时器/计数器(常用)

模式2:8位自动重装模式

模式3:两个8位计数器

模式1:

此模式下,定时器配置为16位定时器/计数器,由TL0的8位和TH0的8位所构成。TL0的8位溢出向TH0进位,THO计数溢出置位TCON中的溢出标志位TF0。

SYSclk:系统时钟,即晶振周期,本开发板上的晶振为12MHz

那么1毫秒 溢出一次的晶振次数怎么计算呢?

STC89C51RC/RD+系列单片机的定时器有两种计数速率:一种是12T模式,每12个时钟加1,与传统8051单片机相同;另外一种是6T模式,每6个时钟加1,速度是传统8051单片机的2倍。TO的速率在烧录用户程序时在STC-ISP编程器中设置。

STC89C52RC 的时钟频率是12MHz。

12MHz就是 1秒钟 晶振次数 是 12000000次,

12000000/12/1000(毫秒)=1000 (次/毫秒)

也就是说我们 要让定时器没1毫秒溢出一次,就得让晶振震动1000次后溢出。而溢出的时候TH0和TL0 合并起来的值是65536

所以我们把 定时器的初始值TH0和TL0的合并值设置为TIMS=65536-1000=64536

赋值

TL0=64535%256;(TL0=TIMS; [TL0只有8位,所以高位不会赋值过去,只有地位有效])

TH0=64536/256;(TH0=TIMS>>8;TH0也只有8位,TIMS右移8位后然低位溢出,高位就自动在低位了

每次中断发生后,都需要重新将TH0和TL0重新初始化。(在中断函数中重新赋值TH0和TL0)

三,如何开启定时器/计数器中断

3.1 开启中断 interrupt 1 (定时器Timer0/计数器 触发中断 实现LED闪烁)

如下图。要开启标红的这一路。配置还是比较多。不要嫌麻烦。挨着来。走一遍后,你会觉得像是打开了任督二脉。

按照图,还是从下往从右往左一次配置。

PX0: 优先级系统默认是最高级,不管

EA:全局中断开关合上 EA=1

ET0:允许Timer0/TF0 的中断进入。ET0=1;

我们再单独分析定时器器/计数器,

TR0:定时器开始运行;TR0=1;

TMOD:采用模式1(16位)

cpp 复制代码
#include <REGX52.H> 
/*宏定义定时器的初始值*/
#define TIMS (65536-12000000/12/1000)
unsigned int count=1000;//计数器  默认1000
void main()
{
	TMOD=0x01;	//设置模式1
	TL0=TIMS;	//设置定时器的低8位
	TH0=TIMS>>8;//设置定时器的高8位
	TR0=1;		//让定时器开始运行
	ET0=1;		//允许定时器发生中断溢出
	EA=1;		//打开全局中断
	while(1);	//主程序停止在此
}

/**
 * 函    数:定时器中断函数
 * 参    数:无
 * 返 回 值:无
 */
void timer0_interrupt() interrupt 1
{
	TL0=TIMS;		//重新初始化低位
	TH0=TIMS>>8;	//重新初始化高位
	if(count--==0)	//1毫秒*1000=1秒
	{	
		count=1000;	//重置计数
		P2_0=!P2_0;	//第一个LED 每秒熄亮一次
	}
}

效果

3.2 开启中断 interrupt 3 (定时器Time1/计数器 触发中断 实现LED闪烁)

还是模式1,同样的,只是几个开关的名字变了

PX0: 优先级系统默认是最高级,不管

EA:全局中断开关合上 EA=1

ET1:允许Timer0/TF0 的中断进入。ET1=1;

TR1:定时器开始运行;TR1=1;

TMOD:采用模式1(16位)不过这里和上面有区别,要设置为0x10

cpp 复制代码
#include <REGX52.H> 
/*宏定义定时器的初始值*/
#define TIMS (65536-12000000/12/1000)
unsigned int count=1000;//计数器  默认1000
void main()
{
	TMOD=0x10;	//设置模式1
	TL1=TIMS;	//设置定时器的低8位
	TH1=TIMS>>8;//设置定时器的高8位
	TR1=1;		//让定时器开始运行
	ET1=1;		//允许定时器发生中断溢出
	EA=1;		//打开全局中断
	while(1);	//主程序停止在此
}

/**
 * 函    数:定时器中断函数
 * 参    数:无
 * 返 回 值:无
 */
void timer1_interrupt() interrupt 3
{
	TL1=TIMS;		//重新初始化低位
	TH1=TIMS>>8;	//重新初始化高位
	if(count--==0)	//1毫秒*1000=1秒
	{	
		count=1000;	//重置计数
		P2_0=!P2_0;	//第一个LED 每秒熄亮一次
	}
}

效果 与上面一样

相关推荐
网易独家音乐人Mike Zhou3 小时前
【卡尔曼滤波】数据预测Prediction观测器的理论推导及应用 C语言、Python实现(Kalman Filter)
c语言·python·单片机·物联网·算法·嵌入式·iot
zy张起灵3 小时前
48v72v-100v转12v 10A大功率转换电源方案CSM3100SK
经验分享·嵌入式硬件·硬件工程
lantiandianzi10 小时前
基于单片机的多功能跑步机控制系统
单片机·嵌入式硬件
哔哥哔特商务网10 小时前
高集成的MCU方案已成电机应用趋势?
单片机·嵌入式硬件
跟着杰哥学嵌入式10 小时前
单片机进阶硬件部分_day2_项目实践
单片机·嵌入式硬件
电子科技圈11 小时前
IAR与鸿轩科技共同推进汽车未来
科技·嵌入式硬件·mcu·汽车
东芝、铠侠总代1361006839312 小时前
浅谈TLP184小型平面光耦
单片机·嵌入式硬件·物联网·平面
lantiandianzi12 小时前
基于单片机中医药柜管理系统的设计
单片机·嵌入式硬件
嵌入式知识大讲堂12 小时前
HDMI数据传输三种使用场景
单片机
黑客呀13 小时前
[系统安全]Rootkit基础
stm32·单片机·系统安全