利用定时器0工作方式1——独立按键控制流水灯模式

发布于:2023-01-04 ⋅ 阅读:(211) ⋅ 点赞:(0)

目录

1.前言

1.1 项目资源

1.2 实验现象

2.定时器/计数器

2.1定时器/计数器0&1的相关寄存器

2.2定时器的工作方式(总结)

3.中断系统

3.1中断概念

3.2中断流程:

3.3中断资源:

3.4 定时器和中断系统

3.5 中断寄存器

4.源码

4.1 main.c

4.2key.c

4.3key.h

4.4 Timer0.c


1.前言

1.1 项目资源

https://download.csdn.net/download/YLG_lin/86501743

1.2 实验现象

按下K1按键LED向左移,按下K2按键LED向右移;

2.定时器/计数器

STC89C52系列单片机的定时器0和定时器1,与传统8051的定时器完全兼容,当在定时器1做波特率发生器时,定时器0可以当两个8位定时器用。

定时器个数:3个(T0、T1、T2),T0和T1与传统的51单片机兼容,T2是此型号单片机增加的资源

注意:定时器的资源和单片机的型号是关联在一起的,不同的型号可能会有不同的定时器个数和操作方式,但一般来说,T0和T1的操作方式是所有51单片机所共有的

定时器在单片机内部就像一个小闹钟一样,根据时钟的输出信号,每隔一定时间,计数单元的数值就增加一,当计数单元数值增加到“设定的闹钟提醒时间”时,计数单元就会向中断系统发出中断申请,产生“响铃提醒”,使程序跳转到中断服务函数中执行

2.1定时器/计数器0&1的相关寄存器

 定时器计数器的结构框图

两个 16 位定时 / 计数器
存放初值的 SFR
T0: TH0 TL0
T1: TH1 TL1
其它相关的 SFR
TMOD (工作方式控制寄存器)
TCON (控制寄存器)
定时功能时,每个机器周期定时器加 1
计数功能时,在外部相应输入脚( T0 T1 )产生
下降沿,计数器加 1
工作方式控制寄存器 TMOD(89H)
GATE C/T M1 M0 GATE C/T M1 M0
注意: TMOD 不能位寻址
控制寄存器 TCON (88H)
TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0
复位后两个寄存器的状态均为 00H
GATE :门控位
GATE 1 T0 T1 是否工作受外部引脚输入电平的控制, INT0
引脚控制 T0 运行, INT1 引脚控制 T1 运行。 可用于测量在 INT0
INT1 引脚出现的正脉冲的宽度。
GATE=0 ,定时 / 计数器的运行不受外部引脚 INT0 INT1 的控制。
C/T 位:计数器模式和定时器模式的选择位
C/T=0 ,为定时器模式。内部计数器对晶振频率 12 分频后的脉冲
计数(该脉冲的周期等于机器周期),每个周期计数值加 1
选择 12MHz 晶振,则计数频率为 1MHz 从计数值便可求得计数
的时间,所以称为定时器模式;
C/T=1 ,设置为计数器模式,计数器对由引脚 T0 P3.4 脚)或 T1
P3.5 脚)输入的外部脉冲(负跳变)计数, 允许最高计数频率
为晶振频率的 1/24

TF1 位: T1 计数溢出标志位。当 T1 计数溢出时,由硬件置
1 ,申请中断。 进入中断服务程序后被硬件自动清 0
TR1 位: T1 计数运行控制位。由软件置 1 或清 0 。当 GATE
位( TMOD.7 )= 0 时,若 TR1=1 ,允许 T1 计数;
TR1=0 时,禁止 T1 计数。当 GATE =1 时, TR1 1
INT1=1 时,允许 T1 计数。
TF0 位: T0 计数溢出标志位,功能同 TF1
TR0 位: T0 计数运行控制位,由软件置 1 或清 0 。当 GATE
位( TMOD.3 )= 0 时,若 TR0=1 ,允许 T0 计数;
TR0=0 时,禁止 T0 计数。当 GATE =1 时, TR0 1
INT0=1 时,允许 T0 计数。
 

2.2定时器的工作方式(总结)

方式 0 13 位定时计数器
注意: TLx 的低 5 位和 THx 共同组成
方式 1 16位定时计数器 (常用)
方式 2 : 自动重装入的 8 位定时计数器
溢出后 TFx=1 ,同时由 THx TLx
方式 3 T0 成为两个独立的 8 位计数器
TL0 作为定时计数器; TH0 仅作定时器用
TL0 的控制用原 T0 的, TH0 占用原 T1 的控制位 TR1 TF1 ,同
时占用定时器 T1 的中断源
此时, T1 可工作于方式 0 2 ,溢出时送串行口,经常作为串
行口波特率发生器

 

3.中断系统

3.1中断概念

中断系统是为使CPU具有对外界紧急事件的实时处理能力而设置的。当中央处理机CPU正在处理某件事的时候外界发生了紧急事件请求,要求CPU暂停当前的工作,转而去处理这个紧急事件,处理完以后,再回到原来被中断的地方,继续原来的工作,这样的过程称为中断。实现这种功能的部件称为中断系统,请示CPU中断的请求源称为中断源。微型机的中断系统一般允许多个中断源,当几个中断源同时向CPU请求中断,要求为它服务的时候,这就存在CPU优先响应哪一个中断源请求的问题。通常根据中断源的轻重缓急排队,优先处理最紧急事件的中断请求源,即规定每一个中断源有一个优先级别。CPU总是先响应优先级别最高的中断请求。当CPU正在处理一个中断源请求的时候(执行相应的中断服务程序),发生了另外一个优先级比它还高的中断源请求。如果CPU能够暂停对原来中断源的服务程序,转而去处理优先级更高的中断请求源,处理完以后,再回到原低级中断服务程序,这样的过程称为中断嵌套。这样的中断系统称为多级中断系统,没有中断嵌套功能的中断系统称为单级中断系统。

3.2中断流程:

3.3中断资源:

中断源个数:8个(外部中断0、定时器0中断、外部中断1、定时器1中断、串口中断、定时器2中断、外部中断2、外部中断3)
中断优先级个数:4个
中断号:

注意:中断的资源和单片机的型号是关联在一起的,不同的型号可能会有不同的中断资源,例如中断源个数不同、中断优先级个数不同等等

3.4 定时器和中断系统

SYSclk:系统时钟,即晶振周期;

3.5 中断寄存器

寄存器是连接软硬件的媒介,在单片机中寄存器就是一段特殊的RAM存储器,一方面,寄存器可以存储和读取数据,另一方面,每一个寄存器背后都连接了一根导线,控制着电路的连接方式
寄存器相当于一个复杂机器的“操作按钮”。

4.源码

4.1 main.c

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

unsigned char KeyNum,LEDMode;

void main()
{
	P2=0XFE;
	Timer0Init();//定时器0的初始化
	while(1)
	{
		KeyNum=Key();		
		if(KeyNum)	//返回的不是0即为真
		{
			if(KeyNum==1)	//判断K1是否按下
			{
				LEDMode=0;				
			}
			if(KeyNum==2)  //判断K2是否按下
			{
				LEDMode=1;
			}
		}
	}
}

void Timer0_Routine() interrupt 1
{
	static unsigned int T0Count;
	TL0 = 0x18;		//重装初值
	TH0 = 0xFC;		
	T0Count++;		//每过1ms,T0Count加1;
	if(T0Count>=500) //500ms(0.5s);
	{
		T0Count=0; //清零,等待下一个500ms
		if(LEDMode==0)			
			P2=_crol_(P2,1);	//往左移
		if(LEDMode==1)
			P2=_cror_(P2,1);  //往右移
	}
}

4.2key.c

#include <REGX52.H>
void Delay(unsigned int xms) //延时函数
{
	unsigned char i, j;
	while(xms--)
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
	}
}



unsigned char Key()//获取独立按键键码
{				   //无按键按下时返回0
	unsigned char KeyNumber=0; //局部变量
	
	if(P3_1==0){Delay(20);while(P3_1==0);Delay(20);KeyNumber=1;}//P3_1为K1
	if(P3_0==0){Delay(20);while(P3_0==0);Delay(20);KeyNumber=2;}//P3_0为K2
	
	return KeyNumber;
}

4.3key.h

#include <REGX52.H>
#ifndef __KEY_H__
#define __KEY_H__

unsigned char Key();
void Delay(unsigned int xms);

#endif

4.4 Timer0.c

#include <REGX52.H>

void Timer0Init(void)
{
	TMOD &= 0xF0;		
	TMOD |= 0x01;	//设置定时器0为工作方式1
	TL0 = 0x18;		//设置定时初值
	TH0 = 0xFC;	   //设置定时初值,初值的设置决定了定时的时间
	TF0 = 0;	   //TF0位:T0计数溢出标志位,不设问题也不大
	TR0 = 1;	   //允许T0计数
	ET0=1;        //3.4图看看就明白了
	EA=1;      //开总中断
	PT0=0;     //3.4图看看就明白了
}

4.5 Timer0.h

#ifndef __TIMET0_H__
#define __TIMET0_H__

void Timer0Init(void);

#endif

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到