定时器
概述:
- 定时器介绍:51单片机的定时器属于单片机的内部资源,其电路的连接和运转均在单片机内部完成
- •定时器在单片机内部就像一个小闹钟一样,根据时钟的输出信号,每隔“一秒”,计数单元的数值就增加一,当计数单元数值增加到“设定的闹钟提醒时间”时,计数单元就会向中断系统发出中断申请,产生“响铃提醒”,使程序跳转到中断服务函数中执行
- STC89C52定时器资源:
- 定时器个数:3个(T0、T1、T2),T0和T1与传统的51单片机兼容,T2是此型号单片机增加的资源
- 注意:定时器的资源和单片机的型号是关联在一起的,不同的型号可能会有不同的定时器个数和操作方式,但一般来说,T0和T1的操作方式是所有51单片机所共有的
作用:
- 用于计时系统,可实现软件计时,或者使程序每隔一固定时间完成一项操作
- 替代长时间的Delay,提高CPU的运行效率和处理速度
- 计数器(TH0(高八位),TL0(低八位))一共能计时0~65535 ,一次1us,一共65535us,若计时1ms,赋初始值为64535,离结束1ms
中断系统
概述:
-
中断源个数:8个(外部中断0、定时器0中断、外部中断1、定时器1中断、串口中断、定时器2中断、外部中断2、外部中断3)
-
中断优先级个数:4个
-
中断号:
-
注意:中断的资源和单片机的型号是关联在一起的,不同的型号可能会有不同的中断资源,例如中断源个数不同、中断优先级个数不同等等
使用
自动生成定时器初始化:
void Timer0Init() //1毫秒@12.000MHz
{
//AUXR &= 0x7F; //定时器时钟12T模式,这个删除不要
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x18; //设置定时初始值
TH0 = 0xFC; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
//中断,这几个后面自己添加
ET0=1;
EA=1;
PT0=0; //中断优先级 0:低优先级; 1:高优先级
}
定时器应用:
#ifndef __TIMER0_H__
#define __TIMER0_H__
void Timer0Init();
#endif
#include <REGX52.H>
/**
* @brief 定时器0初始化 1毫秒@12.000MHz
* @param 无
* @retval 无
*/
void Timer0Init() //1毫秒@12.000MHz
{
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x18; //设置定时初始值
TH0 = 0xFC; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
//中断
ET0=1;
EA=1;
PT0=0; //中断优先级 0:低优先级; 1:高优先级
}
/**
//定时器函数模板(1s)
void Timer0_Routine() interrupt 1
{
static unsigned int T0Count;
TL0 = 0x18;
TH0 = 0xFC;
T0Count++;
if(T0Count >= 1000){
T0Count=0;
}
}
**/
#include <REGX52.H>
#include "Timer0.h"
void main(){
Timer0Init();
while (1)
{
}
}
void Timer0_Routine() interrupt 1
{
static unsigned int T0Count;
TL0 = 0x18;
TH0 = 0xFC;
T0Count++;
if(T0Count >= 1000){
T0Count=0;
P2_0 =~ P2_0;
}
}
流水灯(按键控制LED流水灯左右移动)
#include "INTRINS.H" //数学函数
extern unsigned char _crol_ (unsigned char, unsigned char);//左移一位
extern unsigned char _cror_ (unsigned char, unsigned char);//右移一位
特殊之处:比如a = 0x01; a = _cror_(a,1); 他到a = 0x80 之后直接变成 a = 0x01;
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 != 0)
{
if(KeyNum == 1)
{
LEDMode++;
if(LEDMode > 1)LEDMode=0;
}
}
}
}
void Timer0_Routine() interrupt 1
{
static unsigned int T0Count;
TL0 = 0x18;
TH0 = 0xFC;
T0Count++;
if(T0Count >= 5000){
T0Count=0;
if(LEDMode==0)P2=_crol_(P2,1);
if(LEDMode==1)P2=_cror_(P2,1);
}
}
按键
#ifndef __KEY_H__
#define __KEY_H__
unsigned char Key();
#endif
#include <REGX52.H>
#include "Delay.h"
/**
* @brief 获取独立按键键码
* @param 无
* @retval 按下按键的键码,范围1~4,无按下为0
*/
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;
}
= 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;
}