第六章(续)、定时器和中断系统实践

文章展示了如何使用STC89C52单片机通过定时器T0来控制LED流水灯模式,并实现时、分、秒的计时功能。通过独立按键K1切换LED流水灯模式,同时利用中断服务程序更新计时状态。

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

1、独立按键K1控制LED流水灯模式

按下独立按键K1时,LCD朝着相反方向移动

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

// Timer0,定时器0初始化
void Timer0Init()
{	
	// 第一步设置 定时器工作模式 模式1 :16位定时器
	TMOD &= 0xF0;    // TMOD寄存器高四位不变,低四位清零
	TMOD |= 0x01;   // TMOD寄存器高四位不变,低四位设置为 0001,即16位计数器模式
	
	// 因为16位计时器可以计0-65535次,按照+12模式,即1微秒计时一次
	// 为了每次计数都是一个整数,则要给寄存器赋初始值。
	// 例如:要想计算器溢满时正好时1毫秒,则设置初始值为64535;
	TL0 = 0x18 ; //低八位赋值: 64535%256+1 = 23
	TH0 = 0xFC ; //高八位赋值: 64535/256 = 252 
	
	//定时器T0溢出标志。当计数器溢出时,由硬件置1,
	//然后向CPU发送中断请求。CPU响应请求后,由硬件再次置为0
	TF0 = 0;
	// 计时器T0的控制位,为1时允许T0开始计数
	TR0 = 1;
	
	// EA=1,CPU开放中断
	EA = 1;
	//  ET0:定时器T0的溢出中断允许位。ET0=1,允许T0中断;
	ET0 = 1;
	// 设置定时器T0为最低优先级中断
	PT0 = 0;
}


/**
  * @brief  获取独立按键键码
  * @param  无
  * @retval 按下按键的键码,范围:0~4,无按键按下时返回值为0
  */
unsigned char getKey()
{	
	unsigned char KeyNumber=0;
	if(P3_1==0){Delay(20);while(P3_1==0);Delay(20);KeyNumber=1;}
	if(P3_0==0){Delay(20);while(P3_0==0);Delay(20);KeyNumber=2;}
	if(P3_2==0){Delay(20);while(P3_2==0);Delay(20);KeyNumber=3;}
	if(P3_3==0){Delay(20);while(P3_3==0);Delay(20);KeyNumber=4;}
	return KeyNumber;
}

unsigned char KeyNum,LEDMode;  
void main()
{
	P2=0xFE;   // 是第一个LED点亮
	Timer0Init(); // 初始化计时器T0
	
	while(1)
	{
		KeyNum=getKey();  //获取独立按键键码
		if(KeyNum)        //如果按键按下
		{            
			if(KeyNum==1)   //如果K1按键按下
			{
				LEDMode++;
				if(LEDMode>=2)LEDMode=0;
			}	
		}
	}
}


//  中断执行程序
void Timer0_Routine() interrupt 1
{
	static unsigned int T0Count;
	TL0 = 0x18;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	T0Count++;
	if(T0Count>=1000)     // 1000 * 1微秒 = 1毫毛
	{	
		T0Count=0;
		if(LEDMode==0)			//模式判断
			P2=_crol_(P2,1);	//LED输出
		if(LEDMode==1)
			P2=_cror_(P2,1);
	}
}

2、定时器时钟

使用STC89C52定时器T0实现 一个时、分、秒的计时器

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

// Timer0,定时器0初始化
void Timer0Init()
{	
	// 第一步设置 定时器工作模式 模式1 :16位定时器
	TMOD &= 0xF0;    // TMOD寄存器高四位不变,低四位清零
	TMOD |= 0x01;   // TMOD寄存器高四位不变,低四位设置为 0001,即16位计数器模式
	
	// 因为16位计时器可以计0-65535次,按照+12模式,即1微秒计时一次
	// 为了每次计数都是一个整数,则要给寄存器赋初始值。
	// 例如:要想计算器溢满时正好时1毫秒,则设置初始值为64535;
	TL0 = 0x18 ; //低八位赋值: 64535%256+1 = 23
	TH0 = 0xFC ; //高八位赋值: 64535/256 = 252 
	
	//定时器T0溢出标志。当计数器溢出时,由硬件置1,
	//然后向CPU发送中断请求。CPU响应请求后,由硬件再次置为0
	TF0 = 0;
	// 计时器T0的控制位,为1时允许T0开始计数
	TR0 = 1;
	
	// EA=1,CPU开放中断
	EA = 1;
	//  ET0:定时器T0的溢出中断允许位。ET0=1,允许T0中断;
	ET0 = 1;
	// 设置定时器T0为最低优先级中断
	PT0 = 0;
}


unsigned char Sec,Min,Hour;     // 秒、分、时
void main()
{
	Timer0Init(); // 初始化计时器T0
	LCD_Init();  // LCD1602 初始化
	
	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)     // 1000 * 1微秒 = 1毫毛
	{	
		T0Count = 0; 
		Sec ++;
		if(Sec>=60){
			Sec = 0;
			Min ++;
			if(Min>=60){
				Min = 0;
				Hour ++;
				if (Hour>=24){
					Hour=0;
				}
			}
		}
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值