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 每秒熄亮一次
	}
}

效果 与上面一样

相关推荐
小猪写代码1 小时前
STM32 FreeRTOS内存管理简介
stm32·单片机
电工小王(全国可飞)4 小时前
STM32F407 内部参考电压校准实现 HAL库
stm32·单片机·嵌入式硬件
gyeolhada4 小时前
计算机组成原理(计算机系统3)--实验七:新增指令实验
单片机·嵌入式硬件
嵌入式小强工作室5 小时前
STM32更新程序OTA
stm32·单片机·嵌入式硬件
gyeolhada7 小时前
计算机组成原理(计算机系统3)--实验八:处理器结构拓展实验
java·前端·数据库·嵌入式硬件
andylauren14 小时前
(5)STM32 USB设备开发-USB键盘
stm32·嵌入式硬件·计算机外设
Ronin-Lotus15 小时前
嵌入式硬件篇---ADC模拟-数字转换
笔记·stm32·单片机·嵌入式硬件·学习·低代码·模块测试
promising-w15 小时前
单片机基础模块学习——数码管
单片机·嵌入式硬件·学习
华清远见IT开放实验室16 小时前
嵌入式STM32创新教学:华清远见虚拟仿真实验平台与智能车项目师资培训
stm32·单片机·嵌入式硬件
andylauren16 小时前
(1)STM32 USB设备开发-基础知识
stm32·单片机·嵌入式硬件