IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 51单片机定时器及其应用(1)(时钟功能) -> 正文阅读

[嵌入式]51单片机定时器及其应用(1)(时钟功能)

51单片机定时器及其应用(1)(时钟功能)

??STC89C51单片机有2个定时器,叫做定时器0和定时器1,可以用作普通定时器,计数器。普通定时器可以用来进行中断定时,波特率发生等,计数器可以用来对脉冲宽度进行测量,从而实现测频功能。其工作模式由定时器/计数器控制寄存器TMOD控制,TMOD寄存器各位如下:
在这里插入图片描述
?TMOD是一个8位寄存器,两边对称,分别控制着定时器0和定时器1,。GATE位,简单理解就是门位,为0就是关门,此时定时器的开启与停止仅由内部控制位决定,这个内部控制位就是TR1,后面会讲。当GATE=1时,相当于把门打开,定时器的开启与停止由外部和内部一起控制,对于定时器1来说,当GATE=1时,是有当INT1引脚为高且TR1=1时才能开启定时器。 C / T ˉ C/\bar{T} C/Tˉ位很好理解,C就是count,T就是timer,为0工作在定时器模式,为1工作在定时器模式。M1和M0用于选择定时器/计数器的计数模式,因为定时器其实也是按脉冲进行计数,计数到一定值后溢出,产生中断,所有这里统一称为计数模式。当 M1和M0取值不同即为不同模式,如下图所示:
在这里插入图片描述
THx(x=0,1),TLx(x=0,1)为两个8位寄存器,用来存放计数的值,写入不同的控制字可以实现不同功能,当M1=0,M0=0时,是一个13位定时器,这个功能比较鸡肋,也不常用,M1=0,M0=1时是一个16位定时器,这是比较常用的,16位最多可以存放的计数值为2^{16}=65536,51单片机每计数一个值的时间是一个机器周期,也就是12个时钟周期,T_{机器}=12T_{时钟}=12(1/12000000)=1us,从而得出最大计时时间为65.536ms,如何想要产生更大的计时时间,可以设置一个中间计数变量count,在中断程序中进行count++,则可以得到count*定时器计时时间的最终计时时间。M1=1,M0=0时,是一个8位具有重载初值功能的定时器,自动重载初值就是在计数器里面的值计满后,单片机会产生一个溢出中断,自动将计数值清0,因此每次在中断服务程中都需要进行重新赋计数值,而这种模式就省去了重新幅值这一步,由单片机自动进行赋值。M1=1,M0=1这个功能只有定时器0具有,是两片区域同时进行工作,其实就是两个定时器,我反正没用过。具体可以参见STC89C51单片机的芯片手册。
?到这里基本知道单片机定时器配置了,但上面一直提到中断,这里解释一下,就好比请假要写请假条申请一样,单片机中断相当于一段时间出去干其他的事情,这要向上级申请,因此也就有了中断控制寄存器:
在这里插入图片描述
也就是请假条的格式,TF1为定时器1的溢出中断,TR1为定时器1的运行控制位,TF0和TR0为定时器0的相关位。IE1、IT1、IE0、IT0为外部中断位,以后会用到,这里只用到前4位。这相当于申请书的格式,那么批准的领导呢?因此会有个中断允许寄存器IE
在这里插入图片描述
EA为总的领导,当EA=1时开启总中断,后面的ET2、ET1、ES等为分领导,用于开启后面的小中断。ET1和ET0也就是定时器1和定时器0的中断使能位。
到此我们就可以进行定时器中断配置了:

void InitTimer1(void)
{
    TMOD = 0x10;
    TH1 = 0xFC;
    TL1 = 0x18;
    EA = 1;
    ET1 = 1;
    TR1 = 1;
}

下面分享一个小项目,也就是常见的电子时钟,可以进行按键控制

#include <reg52.h>
sbit LED=P1^0;
sbit LED1=P1^1;
sbit Wei_Select=P2^6;//数码管位选择
sbit Duan_Select=P2^5;//7段数码管段选择
sbit KEY1=P3^7;
sbit KEY2=P3^6;
sbit KEY3=P3^5;
sbit KEY4=P3^4;
char Display_Code[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};//共阳极段码
char Wei[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};//数码管位码
unsigned int second=0;
unsigned int minute=0;
unsigned int hour=0;
unsigned int count=0;
unsigned int second_flag=0;
unsigned int minute_flag=0;
unsigned int hour_flag=0;
unsigned int Key_Flag=0;
void delay_ms(unsigned int Xms)
{
	unsigned int i=0,j=0;
	for(i=Xms;i>0;i--)
		for(j=110;j>0;j--);

}
void InitTimer1(void)
{
    TMOD = 0x10;
    TH1 = 0xFC;
    TL1 = 0x18;
    EA = 1;
    ET1 = 1;
    TR1 = 1;
}
void display(unsigned int position,unsigned int number)
{
	Duan_Select=0;
	Wei_Select=1;
	P0=Wei[position-1];
	Wei_Select=0;
	Duan_Select=1;
	P0=Display_Code[number];
	delay_ms(2);
}
void timer1() interrupt 3 
{
		TH1 = 0xFC;
    TL1 = 0x18;
		count++;
	if(count==1000)
	{
		second++;
		if(second==60)
		{
			minute++;
			if(minute==60)
			{
				hour++;
				minute=0;
				if(hour==24)
				{
					hour=0;
				}
			}
			second=0;
		}
		count=0;
	}		
}
void main()
{
	InitTimer1();
	while(1)
	{
		display(8,second%10);
		display(7,second/10);

		display(5,minute%10);
		display(4,minute/10);
		
		display(2,hour%10);
		display(1,hour/10);
		if(KEY1==0)
		{
			delay_ms(20);
				if(KEY1==0)
				{
					ET1=0;
					Key_Flag++;
				}
				switch(Key_Flag)
				{
					case 1: second_flag=1;hour_flag=0;minute_flag=0;break;
					case 2:	minute_flag=1;second_flag=0;hour_flag=0;break;
					case 3:	hour_flag=1;second_flag=0;minute_flag=0;Key_Flag=0;break;
					default:break;
				}
				while(KEY1==0);
		}
		if(KEY2==0)
		{
			delay_ms(20);
			if(KEY2==0)
			{
				if(second_flag==1)
					second++;
				if(minute_flag==1)
					minute++;
				if(hour_flag==1)
					hour++;
			}
			while(KEY2==0);
		}
		if(KEY3==0)
		{
			delay_ms(20);
			if(KEY3==0)
			{
				if(second_flag==1)
					second--;
				if(minute_flag==1)
					minute--;
				if(hour_flag==1)
					hour--;
			}
			while(KEY3==0);
		}
		if(KEY4==0)
		{
			delay_ms(20);
			if(KEY4==0)
			{
				ET1=1;
			}
		}
	}
}
  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-08-09 10:23:46  更:2021-08-09 10:25:30 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/28 2:37:00-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计