七、51单片机之定时器编程实践_16位定时器/计数器

本文介绍如何使用51单片机的定时器0实现LED灯的定时闪烁,包括定时器的工作原理、计算定时初始值的方法及具体代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、实验目的

(1)使用定时器来完成LED闪烁。

(2)使用定时器来定一个时间(比如0.5S),在这个定时器定时时间内CPU还可以去做主任务(main函数中的循环体),定时时间到产生中断,在中断处理程序中让LED闪烁。

2、定时器最多定时时长

(1)当外部晶振位12MHz,工作在12T模式下,也就是内部进行12分频。这时CPU的工作频率为1MHz(CPU实际工作频率为时钟周期)。

(2)51单片机中定时器工作频率等于CPU工作频率。

(3)时钟周期为:1/12M秒 = 1uS。16位定时器最多计数65535,也就是说最大定时时间为:

65535*1uS = 65535uS = 65.353mS。

(4)如果要定一个比较长的时间(譬如2S),定时器是不能直接满足的,解决办法是多次定时后加起来构成一个长时间。

3、计算TL0、TH0

(1)确定自己定时时长,例如50mS。

(2)确定时钟周期。因为外部晶振12MHz,12T模式,所以为1uS。

(3)定时器计数个数是:50mS / 1uS = 50 000

(5)51单片机是加法定时器,也就是从初始值加到超过65535(16位定时器)就产生中断。

(6)十进制:6 5535  - 50 000 + 1(溢出才产生中断)  =  15536

        15536转换为16进制为: 0x3CB0

        TL0 = 15536 & 0x00ff = 0xB0;        //设置定时初始值
        TH0 = 15536  >> 8 =  0x3C;           //设置定时初始值

4、实验代码

/*
 *功能:使用定时器让LED闪烁
 *定时器:使用定时器0
 *单片机型号:STC89C516
 */
#include <reg52.h>


sbit LED = P0^0;
unsigned int count;   


/*函数声明*/
void Timer0Init(void);   /*定时器0初始化,50mS*/


void main()
{ 
	count = 0;
	Timer0Init();
	ET0 = 1;    //打开T0溢出中断
	EA = 1;     //打开总中断     
	
	while(1)
	{
	
	}
}


/*
 *功能: 定时器0初始化,50mS
 */
void Timer0Init(void)		//50毫秒@12.000MHz
{
	TMOD &= 0xF0;		//设置定时器模式,16位定时器/计数器,TL0、TH0全用,工作在定时器模式下
	TMOD |= 0x01;		//设置定时器模式
	TL0 = 0xB0;		    //设置定时初始值
	TH0 = 0x3C;		    //设置定时初始值
	TF0 = 0;		    //定时器溢出标志,清除TF0标志,
	TR0 = 1;		    //定时器运行控制位,定时器0开始计数
}


/*
 *功能:定时器0中断处理函数
 */
void tm0_isr() interrupt 1 using 1
{
	TL0 = 0xB0;		   /*手工重载计数值*/ 
	TH0 = 0x3C;		 
	count++;
	if(count == 10)   /*500mS到了*/
	{
		LED = !LED;
		count = 0;
	}
}

5、补充

5.1、加法定时器和减法定时器

(1)定时器的原理就是计数器,加法定时器计数方法是从我们给定的值开始计数,直到溢出(譬如16位定时器最大值是0xffff,也就是65535,计数值超过这个值就溢出了)。减法定时器是从我们给定的值开始减1,减到小于0就溢出了。

(2)实例来看,譬如16位定时器,需要的计数个数为1000。

如果是减法定时器那么计数寄存器初始值就是1000 - 1;

如果是加法定时器那么计数寄存器初始值就是65535-1000 + 1=64535 + 1。

(3)51单片机就是典型的加法定时器。

(4)现代的单片机或者嵌入式soc,一般常用的都是减法定时器了。虽然加法定时器和减法定时器都能实现功能,但是明显减法定时器更加直观。

(5)51单片机可以用STC-ISP软件来辅助计算定时时间。

 

5.2、中断处理程序中using关键字

(1)在写中断处理函数时候,有时候会发现关键字using 。

例如: void Timer0Rountine(void)    interrupt 1 using 1

(2)using 1 可有可无。

(3)51单片机中using使用在C51编程中,用来在中断函数中指定工作寄存器区,工作寄存器共有4个区,分别代表R0~R7地址是:

第0工作区:00H~07H

第1工作区:08H~0FH

第2工作区:10H~17H

第3工作区:18H~1FH

using n,那么n就是第几区,使用方法如下:

void exterint0() interrupt 0 using 1

这表示外部中断0使用第1工作区地址。 

详细理解可能需要学习汇编

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

代码织梦师小猪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值