51单片机 - 定时器

本文介绍了STC89C51RC/RD+单片机中的定时器工作原理及应用,包括3个定时器的不同工作模式。重点讲述了16位计数器模式,以及定时器中断的设置和程序设计。通过一个1S周期LED灯闪烁的实例展示了如何使用定时器0实现周期性任务。此外,还提及了定时器中断服务函数的实现细节,如计数器重载和中断标志位的处理。
摘要由CSDN通过智能技术生成



1> 概述(STC89C51RC/RD+)

1

STC89C51RC/RD+ 定时器数量: 3个;

T0模式:工作模式

模式0: 13位计数器;
模式1: 16位计数器;
模式2: 8位计数器 (带重装载功能);
模式3: 2个8位计数器;

T1模式:工作模式

模式0: 13位计数器;
模式1: 16位计数器;
模式2: 8位计数器 (带重装载功能);

T2模式:工作模式

模式0: 16位计数器 (带重装载功能);
模式1: 16位捕获功能;
模式2: 波特率发生器;


计数器对 单片机<内部>的时钟脉冲计数,叫定时器(Timer); // 因为内部时钟频率稳定;
计数器对单片机<外部> 的脉冲计数, 叫计数器(Counter);

2> 作用: CPU的 “闹钟”

CPU比作人, 人睡觉, 需要几点起床, 就设置个几点; 要是没这个闹钟, 上班估计要迟到了;

1

思考"闹钟"的神奇,
比如洗衣机上的, 洗23分钟,后"嘀 嘀"叫你, 这23分钟你就能干其他的;
比如学校的上下课铃声, 有了它, 整个有了秩序;


3> 工作原理 (16位计数器)

3

注意:
重点关注用到的,用不到的只做了解;
这样才能循序渐进的,掌握改技能;

🔗【数字电子技术基础】


3.1> control 逻辑

 control = ( (~(GATE ) | (INT0#) ) & TR0; 

3.2> [TL0 TH0]: 数据寄存器

2个寄存器, TH0,存高8位, TL0,存低8位;
比如: 55555,
转为 16进制 0xD953,
则TH0 = 0xD9; TL0 = 0x53;


3.3> TF: 定时器<溢出>标志位

置1: 计数器 计数结束, 由硬件电路将TF置1, 并产生中断;
清0: 产生中断后, 硬件自动清零;


滴水时钟
1.2

4> 定时器中断

4

定时器0为例, 使能ET0,和EA后, 在定时器产生中断标志位TF时,CUP就会被中断,去执行中断服务函数;

1

4.2


5> 程序设计

功能需求: 通过定时器0, 16位定时器模式, 实现LED灯 循环1S亮, 1S灭;
1

#include <reg52.h>

typedef unsigned char	uchar8_t;
typedef unsigned short	ushort16_t;


sbit LED0 = P3^0;
sbit LED7 = P3^7;

#define FOSC 12000000L

#define TIM_1MS (65536 - FOSC/12/1000)   // 1ms time in 12Tmode, 2^16 = 65536,  1s = 1000ms;


ushort16_t cnt = 0;

void Tim0_init_it(void);


/**
 *  main
 */
int main(void)
{
	uchar8_t i = 0;
	uchar8_t j = 0;

	Tim0_init_it();	//
	
	while (1) {
		for (i = 0; i<200; i++) {
			for (j = 0; j<200; j++)
				/* nothing */ ;
		}

		LED0 = ~LED0;		
	}
}


void Tim0_init_it(void)
{
	uchar8_t tmp = 0;

	/* Tim0 Mode1 */
	tmp = TMOD;		// read TMOD;
	tmp &= 0xF0;	// clean Tim0:[GATE, M1,M0];	 
	tmp |= 0x01;	// find value;
	TMOD = tmp;		// set Tim0 as mode1(16bit) 

	/* Tim0 initial value*/
	TL0 = TIM_1MS;			// Low Byte;
	TH0 = TIM_1MS >> 8;		// High	Byte;

	/* Start Tim0 */
	TR0 = 1;

	/* Enable interrupt*/
	IPH |= 0x02;	// PT0H = 1;
	PT0 = 1;   		// Tim0 Priority

	ET0 = 1;
	EA = 1;
}


void tim0_handle() interrupt 1
{
	/* Reload value */
  	TL0 = TIM_1MS;			// Low Byte;
	TH0 = TIM_1MS >> 8;		// High	Byte;

	if (cnt == 1000-1) {   // 结束条件:cnt 数1000-1个;1000 * 1ms = 1S;
		LED7 = ~LED7;
		cnt = 0; 
	} else {
		cnt++;   // 加一条件:TF0 == 1;
	}		
}										 



// end file

注意:
1> 时钟源选择
11

2> 进入中断后,初始值立马重载;

3> 自己实现的cnt这个计数器 - 3要素:

初始值:cnt == 0;
加一条件: TF == 1;
结束条件: cnt == 1000 - 1; // 为什么减1,因为是从0开始数数的;


6> 🔗视频链接

【B站🔗 视频讲解】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值