1、优化《51单片机——启用定时及使用1.0》里的代码。
2、主要是一些小改动。
3、主要包括:定时器0,8位自动重装、16位手动重装;定时器1,8位自动重装、16位手动重装;定时器2,16位自动重装。
备注:你想使用哪个就初始化配置哪个,注意time0、time1、time2、time00、time11是局部全局变量,如果外部要使用请去掉static,在.h里使用extern进行修饰一下。
如果觉的好,麻烦点赞一下哈。
#ifndef __TIME_H__
#define __TIME_H__
//时间不能大于71ms,如需更大的定时,需要在定时中断函数里累加71ms
//定时时间是ms毫秒
//建议定时为5ms\10ms\15ms\20ms\25ms\30ms\35ms\40ms\...70ms
//对于us微妙
//建议定时10us\20us\30us\40us\50us\60us\75us\86us\97us\119us
//定时器0初始化,并设定ms毫秒且工作方式1,16位模式
extern void Timer0_16bit(unsigned char time0_16_ms);
//定时器1初始化,并设定ms毫秒且工作方式1,16位模式
extern void Timer1_16bit(unsigned char time1_16_ms);
//定时器2初始化,并设定ms毫秒且工作方式1,16位自动重装模式
extern void Timer2(unsigned char time2_16_ms);
//定时器0初始化,并设定us微妙且工作方式2,8位自动重装模式
extern void Time0_8bit(unsigned char time0_8_us);
//定时器1初始化,并设定us微妙且工作方式2,8位自动重装模式
extern void Time1_8bit(unsigned char time1_8_us);
#endif // !__TIME_H__
#include"REG52.h"
sfr T2MOD = 0xC9;
//时间不能大于71ms,如需更大的定时,需要在定时中断函数里累加71ms
//定时时间是ms毫秒
//建议定时为5ms\10ms\15ms\20ms\25ms\30ms\35ms\40ms\...70ms
//对于us微妙
//建议定时10us\20us\30us\40us\50us\60us\75us\86us\97us\119us
//先计算1ms内震荡多少个机器周期
//TH1=(65536-ms*晶振频率hz/12/1000)/256;
//=(65536-ms*(11059200/12/1000))/256;
//=(65536-ms*921.6)/256;
//TL1=(65536-ms*晶振频率/12/1000)%256;//16位自动重装
//TH1=TL1=(256-ms*晶振频率hz/12/1000);//8位自动重装
//或者//先计算震荡1个机器周期多少秒
//TH1=(65536-ms/1000/(1/晶振频率hz*12))/256;
//=(65536-ms/(1/921.6))/256=(65536-ms*921.6)/256;
static unsigned char H0 = 0, L0 = 0;
static unsigned char time0 = 0;//定时器0,16位手动重装
static unsigned char H1 = 0, L1 = 0;
static unsigned char time1 = 0;//定时器1,16位手动重装
static unsigned char time2 = 0;//定时器2,16位自动重装
static unsigned char time00 = 0;//定时器0,8位自动重装
static unsigned char time11 = 0;//定时器1,8位自动重装
//定时器0初始化,设定ms毫秒且工作方式1,16位模式
void Timer0_16bit(unsigned char time0_16_ms)
{
TMOD |= 0x01;
TH0 =(65536 - (unsigned int)(time0_16_ms * 921.6)) / 256;//需将计算的小数转换整形
TL0 =(65536 - (unsigned int)(time0_16_ms * 921.6)) % 256;//需将计算的小数转换整形
H0 = TH0;
L0 = TL0;
EA = 1;//开启总中断
ET0 = 1;//允许定时器0溢出进入中断
TR0 = 1;//启动定时器
}
void Timer0Interrupt(void) interrupt 1
{
TH0 = H0;
TL0 = L0;
time0++;
/*
if (time0 == 20)//如果time0_16_ms=50,则定时1000ms
{
time0 = 0;
P1 = ~P1;//LED灯亮和灭
}*/
}
//定时器1初始化,设定ms毫秒且工作方式1,16位模式
void Timer1_16bit(unsigned char time1_16_ms)
{
TMOD |= 0x10;
TH1 = (65536 - (unsigned int)(time1_16_ms * 921.6)) / 256;//需将计算的小数转换整形
TL1 = (65536 - (unsigned int)(time1_16_ms * 921.6)) % 256;//需将计算的小数转换整形
H1 = TH1;
L1 = TL1;
EA = 1;
ET1 = 1;//允许定时器1溢出进入中断
TR1 = 1;
}
void Timer1Interrupt(void) interrupt 3
{
TH1 = H1;
TL1 = L1;
time1++;
if (time1 == 20)//如果time1_16_ms=50,则定时1000ms
{
time1 = 0;
P1 = ~P1;//LED灯亮和灭
}
}
//定时器2初始化,设定ms毫秒且工作方式1,16位自动重装模式
void Timer2(unsigned char time2_16_ms)
{
T2CON = 0x00;//用于定时器16位自动重装
T2MOD = 0x00;//T2输出允许位,当T2OE=1的时候,允许时钟输出到P1.0(仅对80C54/80C58有效)
RCAP2H = (65536 - (unsigned int)(time2_16_ms * 921.6)) / 256;//需将计算的小数转换整形
RCAP2L = (65536 - (unsigned int)(time2_16_ms * 921.6)) % 256;//需将计算的小数转换整形
TH2 = RCAP2H;
TL2 = RCAP2L;
EA = 1;//开启总中断允许
ET2 = 1;//允许定时器2溢出进入中断
TR2 = 1;//启动定时器2开始计时
}
void Timer2Interrupt(void) interrupt 5
{
TF2 = 0;//定时器2溢出标志,需要软件清零
time2++;
if (time2 == 20)//如果time2_16_ms=50,则定时1000ms
{
time2 = 0;
P1 = ~P1;//LED灯亮和灭
}
}
//定时器0初始化,设定us微妙且工作方式2,8位自动重装模式
void Time0_8bit(unsigned char time0_8_us)
{
TMOD |= 0x02;
TH0 = TL0 = 256 - time0_8_us * 9216 / 10000;
EA = 1;
ET0 = 1;//允许定时器0溢出进入中断
TR0 = 1;//启动定时器
}
/*
void Timer0Interrupt(void) interrupt 1
{
//待定,他和16位定时模式有冲突
}
*/
//定时器1初始化,设定us微妙且工作方式2,8位自动重装模式
void Time1_8bit(unsigned char time1_8_us)
{
TMOD |= 0x20;
TH1 = TL1 = 256 - time1_8_us * 9216 / 10000;
EA = 1;
ET1 = 1;//允许定时器1溢出进入中断
TR1 = 1;//启动定时器
}
/*void Timer1Interrupt(void) interrupt 3
{
//待定,他和16位定时模式有冲突
}
*/