89C52RC定时器控制流水灯(复习自用)

本文详细介绍了如何在STC89c52RC单片机上配置定时器/计数器0,包括TMOD、TCON、TH0/TL0设置,以及定时器0的中断系统配置,同时展示了独立按键模块和流水灯控制的应用。
摘要由CSDN通过智能技术生成

一、定时器寄存器配置

为了理解寄存器的配置,在这里先记录自己配置的方法,记录完后会说简便方法。

这是定时器/计数器0和1的相关寄存器,对以下寄存器进行配置,达到自己想要的效果。

1、先配置TMOD(模式)因为TMOD是不可位寻址,就是说只能整体赋值。

根据数据手册,当前只用一个定时器0所以高4位都为0,GATE都设置为0(不用到),c/t为0时用作定时器,M1M0的配置根据表中设置为01(16位定时器)

所以TMOD=0x01;//0000 0001,在此处对TMOD配置低四位时会影响到高四位,因为此时只用一个定时器所以没有影响,若要用两个定时器时,应该这样配置

TMOD=TMOD&0xF0;//把TMOD低四位清0,高四位不变
TMOD=TMOD|0x01;//把TMOD最低位置1,高位不变
    

2、配置TCON是可位寻址,所以可以进行每一位单独赋值。

因为此时只用定时器0,TF0=0,TR0=1;IE0,IT0由于我们对GATE已经赋值为0是用不到的所以可以不用配置。

3、对TH0和TL0配置

因为是16位,所以可以计0-65535,因为脉冲16分频分频后,每个周期1us计数加一所以总共定时是65535us,我们给寄存器赋初值64535,距离溢出差值是1000,计时1ms。

TH0=64535/256;TL0=64535%256;取出高低位。

4、简便方法

运用stc进行配置,因为使用的是STC89c52RC,晶振是12Mhz,定时器0,定时长度1ms,模式的话只有16位没有16位重组,定时器时钟选择12T,生成代码。因为AUXR这个寄存器并没有,所以这一句可以删除,我们已经是12T模式并不需要配置。

二、中断系统配置

2.1配置开关和优先级

由上一篇文章介绍所说,传统的51单片机中断系统是向下兼容的,所以可以按照传统51的单片机中断系统图进行配置会简单许多。这里使用的是定时器0,因为只用一个定时器中断,这里的优先级可以默认为0。

ET0=1;EA=1;PT0=0;

2.2中断标志位

根据标志位的图设置。

在此设置void Timer0_Rountine(void) interrupt 12.3

2.3配置代码

定义Time0.c,对定时器0进行模块化编程,代码如图,之后运行定时器0,只需添加头文件即可。

#include <REGX52.H>
#include "Time0.h"
/**
  * @brief  定时器0初始化//1毫秒@12.000MHz
  * @parm  无 
  * @retval  无

  */
void 	Timer0_Init()		//1毫秒@12.000MHz
{
	TMOD &= 0xF0;		//设置定时器模式
	TMOD |= 0x01;		//设置定时器模式
	TL0 = 0x18;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	ET0=1;
	EA=1;
	PT0=0;
}
/*定时器中断函数模板

void Timer0_Routine()  interrupt 1
{
	static unsigned int T0Count;
	TL0 = 0x18;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	T0Count++;
	if(T0Count>=1000)
	{
		
		T0Count=0;
		P2=~P2;
	}
}
*/

三、独立按键模块

编辑独立按键模块返回键码,这样就可以在按下不同按键时在main中写出不同的功能。

#include <REGX52.H>
#include "Delay.h"
/**
  * @brief  获取独立按键键码
  * @parm   无
  * @retval  按下按键的键码,0~4

  */
unsigned char Key()
{
	unsigned char KeyNumber=0;//局部变量初值不确定
	if(P3_1==0)
		
	{
		Delay1ms(20);//消抖
		while(P3_1==0);//检测松手
		Delay1ms(20);
		KeyNumber=1;
		
	}
	if(P3_0==0)
		
	{
		Delay1ms(20);//消抖
		while(P3_0==0);//检测松手
		Delay1ms(20);
		KeyNumber=2;
		
	}
	if(P3_2==0)
		
	{
		Delay1ms(20);//消抖
		while(P3_2==0);//检测松手
		Delay1ms(20);
		KeyNumber=3;
	}
	if(P3_3==0)
		
	{
		Delay1ms(20);//消抖
		while(P3_3==0);//检测松手
		Delay1ms(20);
		KeyNumber=4;
	}
	return KeyNumber;
}

四、流水灯主函数

不设置按键也可以运行,就单纯定时器控制流水灯,这里设置按键的目的就是让流水灯移动的方向进行改变。这里用到了两个函数(必须得加头文件<INTRINS.H>才能使用):

 _cror_    (unsigned char, unsigned char); _crol_    (unsigned char, unsigned char);

可以快速的实现左移右移并且可以循环,而不是用单纯的>> ,<<再加if增到最大值返回最小值。

#include <REGX52.H>
#include "Time0.h"
#include "Key.h"
#include <INTRINS.H>
unsigned char Keynum,LedMode;//LedMode 控制模式

void main()
{
	P2=0xFE;//赋予初值点亮一个灯
	Timer0_Init();//定时器初始化
	while(1)
	{
		Keynum=Key();//获取按键码
		if(Keynum)//如果按下按键
		{
			
				if(Keynum==1)//如果按下按键模式+1
				{
					LedMode++;
					if(LedMode>=2)//模式只有01两种
					{
						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);//左移1位
		}
		else if(LedMode==1)
		{
			P2=_cror_(P2,1);//右移1位
		}
		
	}
}


  • 45
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值