51单片机定时器学习笔记

中断系统

介绍

中断系统的目的是为了使CPU具有对外界紧急事件的实时处理能力。当外界发出紧急事件的请求,可要求CPU暂停当前的工作,转而去处理这个紧急事件,处理完成后,再回到原来被中断的地方,继续原来的工作。通俗来讲就是,相当于假如你在家写作业,然后呢,要到煮饭的时间了,对人来讲,这时候吃饭是紧急的事件,毕竟人是铁,饭是钢,一顿不吃饿得慌,因此,你就不得不停下手头的作业,去完成煮饭吃饭的工作,等吃完后,你又会回到当时被中断作业上,继续完成作业。

其中,请示CPU中断的请求源称中断源。一般存在多个中断源,每个中断源有优先级别。因此可以实现中断嵌套,而51单片机有8个中断,如下图,Int是外部中断,Timer是定时器中断,UART是串口中断

 中断系统的结构图如下

结合上图,定时器0和1的中断请求标志位是TF0和TF1。当定时器寄存器THx/TLx(x=0/1)溢出时,溢出标志位TFx(x=0/1)会被置位,定时器中断发生。当执行定时器中断时,TFx(x=0/1)会被硬件清除。

串行口接收中断请求的标志位RI和串行口1发送中断请求标志位TI中的任何一个被置为1后,串行口中断都会发生。

中断寄存器

 这51单片机与中断相关的所有寄存器,其中,定时器需要用到的寄存器有两个,分别是TCON和SCON。

TCON的具体说明

 SCON的具体说明

定时器

定时器控制寄存

 

不可位寻址:即此地址只可用十六进制一次性赋值,不能一个一个的去赋值,如:单独的P2_1是无法赋值的。可位寻址就与之相反。

 

定时器一般用较多的模式是模式0。

上图,如果会看电路图的话,这张图的原理理解起来应该不是什么问题。

用定时器做流水灯

主函数代码:

#include <REGX52.H>
#include "Timer0.h"
#include "Key.h"
#include "Delay.h"
#include <INTRINS.H>


unsigned char KeyNum,LEDMode;

void main()
{
	
	P2=0xFE;
	Timer0Init();//中断函数只有在主函数先初始化才可以启动定时器
	while(1)
	{
		KeyNum=Key();
		if(KeyNum)
		{
				if(KeyNum==1)
				{
					LEDMode++;
					if(LEDMode>=2)LEDMode=0;
				}
		}
		
	}
}


void Timer0_Routine()  interrupt 1
{
	static unsigned int T0Count;
	TL0 = 0x18;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	T0Count++;
	if(T0Count>=500)
	{
		T0Count=0;
		if(LEDMode==0)
		{
			P2=_crol_(P2,1);
			
		}
		if(LEDMode==1)
		{
			P2=_cror_(P2,1);
		}
	}
	
}

定时器模块的代码:

#include <REGX52.H>

/**
  *@brief  定时器0初始化,1毫秒@12.000MHz
  *@param  无
  *@retval 无
  */

void Timer0Init(void)		
{
	TMOD &= 0xF0;		//设置定时器模式
	TMOD |= 0x01;		//设置定时器模式
	TL0 = 0x18;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	ET0=1;          //允许中断系统的开启
	EA=1;           //打开中断系统寄存器
	PT0=0;          //中断的优先级位低级
}

一般,我们习惯与将中断函数放在主函数的页面中,不会放在定时器模块中。

用定时器做简易时钟

在知道定时器的代码怎么写的基础上,我们可以用定时器去做一个简易的时钟,

主函数的代码如下:

#include <REGX52.H>
#include "Delay.h"
#include "LCD1602.h"
#include "Timer0.h"



unsigned char Sec,Min,Hour;

void main()
{
	LCD_Init();
	Timer0Init();
	LCD_ShowString(1,1,"Clock");
	LCD_ShowString(2,1,"  :  :");
	while(1)
	{
		LCD_ShowNum(2,1,Hour,2);
		LCD_ShowNum(2,4,Min,2);
		LCD_ShowNum(2,7,Sec,2);
		
	}
}

void Timer0_Routine()  interrupt 1
{
	static unsigned int T0Count;
	TL0 = 0x18;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	T0Count++;
	if(T0Count>=1000)
	{
		T0Count=0;
		Sec++;
		if(Sec>=60)
		{
			Sec=0;
			Min++;
			if(Min>=60)
			{
				Min=0;
				Hour++;
				if(Hour>=24)
				{
					Hour=0;
				}
			}
		}
	}
	
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

夜雨星辰487

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

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

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

打赏作者

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

抵扣说明:

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

余额充值