51单片机学习记录——定时器

前言

        今天由于处理一些问题花了较长的时间,所以今天的博客更新比较晚,今天学习了51单片机的定时器功能,并依据这个功能做了两个小小项目,一个是独立按键控制流水灯的的方向,一个是简易的计时器,接下来那我们记录一下今天的学习内容吧。

定时器介绍以及基本知识

        简介:51单片机的定时器属于单片机的内部资源,其电路的连接和运转均在单片机内部完成作用:1.用于及时系统,可以实现软件及时,或者让程序每隔一段时间进行一项操作;2.替代长时间的Delay,提高CPU的运行效率和处理速度等等。其实也有大佬将定时器有很好的总结,下面我贴上链接

51单片机定时器-CSDN博客文章浏览阅读5.6k次,点赞25次,收藏112次。下面来介绍学习51单片机第一个也是最常用的片上外设——定时器。该硬件是集成在单片机内部的,与板上外设不同的是,它不会受到外界的干扰,只会听从cpu的命令。在小编看来,51单片机上的外设虽没有stm32的复杂,但配置起来要比stm32难,stm32配置片上外设只需要调用函数库输入指定的参数即可,相比于51单片机来的更方便,而51单片机则更底层些,需要从配置寄存器开始,设置初值等等一步一步地打通通道。*ps:学习基础外设部分一定一定要学会查资料!_51单片机定时器https://blog.csdn.net/weixin_69561921/article/details/130030119?spm=1001.2014.3001.5502这篇文章将其工作原理有很棒的总结,但是我得纠正一些东西:普中科技的板子的晶振是11.0592MHz,配置代码有错误,其代码会有一定误差,11.0592MHz的配置代码如下:

#include <REGX52.H>
	void Timer0Init(void)		//1毫秒@11.0592MHz
{
	TMOD &= 0xF0;		//设置定时器模式
	TMOD |= 0x01;		//设置定时器模式
	TL0 = 0xCD;		//设置定时初值
	TH0 = 0xD4;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	ET0=1;
	EA=1;
	PT0=0;
}
/*定时器中断函数模板
void Timer0_Routine() interrupt 1
{
		static unsigned int T0Count;//保证在退出函数的时候不丢失其原本数值
		TL0 = 0x66;		//设置定时初值
		TH0 = 0xFC;		//设置定时初值
		T0Count++;
		if(T0Count>=1000)
		{
				T0Count=0;
				P2_0=~P2_0;
		}
}
*/

,注释里面是中断函数模板,T0count是时间,可以按需求修改,在if语句里面按需修改,其余代码可以由STC-ISP软件生成但是后面得配置通道。

独立按键控制流水灯

        独立按键使用的是K1,每一次按下K1将会变换流水灯的流水方向,是实现思路是先判断是否按下K1然后再在中断函数中实现流水灯的流动,其可以有头文件intrins.h中的_crol_()和cror_()快速实现,一个是循环左移,一个是循环右移。判断K1的时候模块化了独立按键按下的代码,以下是实现代码:

main函数:

#include <REGX52.H>
#include "Timer0.h"
#include "Key.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; // 使用static的原因就是在函数退出后能够保存之前的值
	TL0 = 0x66;					 // 设置定时初值
	TH0 = 0xFC;					 // 设置定时初值
	T0Count++;
	if (T0Count >= 500)
	{
		T0Count = 0;
		if (LEDMode == 0)
		{
			P2 = _crol_(P2, 1); // 循环左移
		}
		else if (LEDMode == 1)
		{
			P2 = _cror_(P2, 1); // 循环右移
		}
	}
}

独立按键的头文件以及c文件

#include <REGX52.H>
#include "Delay.h"
//获取独立按键建码 返回按键的按键
unsigned char Key()
{
	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;
}
#ifndef __KEY_H__
#define	__KEY_H__
unsigned char Key();
#endif

这个只要之前掌握的知识牢固,实现起来还是很容易的。

简易的计时器

        其实现的是一个计秒的计时器,最大可以实现23:59:59,主要是通过定时器来实现的,其中的逻辑实现相对容易,用几个if判断后就可以实现,只需要特别注意一下LCD1602的显示即可其实现代码如下,其余头文件可以访问我之前写的博客

#include <REGX52.H>
#include "Timer0.h"
#include <intrins.h>
#include "LCD1602.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; // 使用static的原因就是在函数退出后能够保存之前的值
	TL0 = 0x66;					 // 设置定时初值
	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;
				}
			}
		}
	}
}

问题:

1.今天的知识感觉好理论,特别是在讲解定时器的理论知识的时候,感觉有点难,后面肯定还需要花时间去深度学习一下

2.今天花了好长一段时间去解决初始化LCD后再初始化定时器之后LCD1602显示出的问题,最终结果发现,造成这样的原因是在新键文件的时候选错了芯片。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值