目录
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的相关寄存器
定时器计数器的结构框图:



2.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