📄 timer.c
字号:
/******************************************************************************************
* 目的:定时器驱动
* 功能:提供基本的定时器操作接口
* 模块依赖:MCS51 定时器中断 硬件端口 及 操作方式
******************************************************************************************/
#include "io8052A.h"
#include "TIMER.h"
#define lFosc 24000000 //晶振频率24MZ
struct _tagtimer //定时器模块内部数据结构
{
unsigned int MsTimer0; //T0中断间隔毫秒
unsigned int MsTimer1; //T1中断间隔毫秒
unsigned char cTH0,cTL0; //TH0 TL0
unsigned char cTH1,cTL1; //TH1 TL1
volatile unsigned int ulTimeCount0; //计时器0
volatile unsigned int ulTimeCount1; //计时器1
pFnTime pfnTimer0; //定时回调函数指针0
pFnTime pfnTimer1; //定时回调函数指针1
} TIMER;
/*
**-------------------------------------------------------------------------------------
** 初始化定时器中断处理模块 C51timer
**-------------------------------------------------------------------------------------
*/
void Init_Timer()
{
TIMER.pfnTimer0 = (pFnTime)0;
TIMER.pfnTimer1 = (pFnTime)0;
}
/*
**-------------------------------------------------------------------------------------
** 初始化定时器使用定时方式1,最小可定时1毫秒
** ims: 硬件中断发生时间间隔 (ms)
** tag_id: 定时器ID (TIMER0~TIMER1)
** 当输入参数tag_id=0xff时定时器0被用做记数,当为记数器时需要用Timestart()开始记数
** 返回值1成功 0则失败
**-------------------------------------------------------------------------------------
*/
unsigned int TimeInit(unsigned char tag_id,unsigned int ims)
{
unsigned long lt;
IE_bit.EA = 0;
if(tag_id!=0xff) lt=ims*lFosc/(12*1000)-1; // 计算TH TL初始值
else // 定时器被用做记数器
{
TMOD = ( TMOD & 0XF1 ) | 0x01; //16位记数器
TH0 = 0; //ms
TL0 = 0;
TCON_bit.TF0 = 0;
IE_bit.EA = 1;
return 1; //此时还未开始记数
}
if ( 0xffff<lt ) //当大于最大时返回错误
{
return 0;
}
else if( tag_id==TIMER0 ) //T0
{
TMOD = ( TMOD & 0XF1 ) | 0x01; //16位记数器
lt = 0xffff-lt; //可按需要设计时间
TH0 = (unsigned char)(lt>>8); //ms
TIMER.cTH0 = TH0;
TL0 = (unsigned char)(lt&0xff);
TIMER.cTL0 = TL0;
TCON_bit.TF0 = 0;
TIMER.MsTimer0 = ims; //记录定时中断时间
}
else if( tag_id==TIMER1 ) //T1
{
TMOD = ( TMOD & 0XF1 ) | 0x10; //16位记数器
lt = 0xffff-lt; //可按需要设计时间
TH1 = (unsigned char)(lt>>8); //ms
TIMER.cTH1 = TH1;
TL1 = (unsigned char)(lt&0xff);
TIMER.cTL1 = TL1;
TCON_bit.TF1 = 0;
TIMER.MsTimer1 = ims; //记录定时中断时间
}
else
{
//NULL
}
//所有参数回0
TIMER.ulTimeCount0 = 0;
TIMER.ulTimeCount1 = 0;
IE_bit.EA = 1;
return 1;
}
/*
**-------------------------------------------------------------------------------------
** 定时器计时开始
** tag_id: 定时器ID (TIMER0~TIMER1)
**-------------------------------------------------------------------------------------
*/
void TimeStart(unsigned char tag_id)
{
if( tag_id==TIMER0 ) //T0
{
TCON_bit.TR0 = 1; // T0置工作位
IE_bit.ET0 = 1;
}
else if( tag_id==TIMER1 ) //T1
{
TCON_bit.TR1 = 1;
IE_bit.ET1 = 1;
}
}
/*
**-------------------------------------------------------------------------------------
** 定时器停止计时
** tag_id: 定时器ID (TIMER0~TIMER1)
**-------------------------------------------------------------------------------------
*/
void TimeStop(unsigned char tag_id)
{
if( tag_id==TIMER0 ) // T0
{
TCON_bit.TR0 = 0; // T0不作位
IE_bit.ET0 = 0;
}
else if( tag_id==TIMER1 ) //T1
{
TCON_bit.TR1 = 0;
IE_bit.ET1 = 0;
}
else
{
//NULL
}
}
/*
**-------------------------------------------------------------------------------------
** 判断当前定时记数是否溢出
** tag_id: 定时器ID (0~1)
**-------------------------------------------------------------------------------------
*/
char TimeFout(unsigned char tag_id)
{
if( tag_id==TIMER0 )
{
if( TCON_bit.TF0 ) return 1;
else return 0;
}
else if( tag_id==TIMER1 )
{
if( TCON_bit.TF1 ) return 1;
else return 0;
}
else
{
//NULL
}
return 0;
}
/*
**-------------------------------------------------------------------------------------
** 返回硬件记数状态(TH,TL)
** tag_id: 定时器ID (TIMER0~TIMER1)
**-------------------------------------------------------------------------------------
*/
unsigned int Timecount(unsigned char tag_id)
{
unsigned int time;
if( tag_id==TIMER0 )
{
time = TH0;
time <<= 8;
time |= TL0;
}
else if( tag_id==TIMER1 )
{
time = TH1;
time <<= 8;
time |= TL1;
}
else
{
//NULL
}
return time;
}
/*
**-------------------------------------------------------------------------------------
** 系统延时,占用定时器T1
** uiTime_ms: 延时时间 (ms)
**-------------------------------------------------------------------------------------
*/
void delay(unsigned int uiTime_ms)
{
unsigned char UiCount10;
unsigned char UiCount0;
// T1 准备延时
IE_bit.ET1 = 0;
TCON_bit.TR1 = 0;
// 计算延时次数
UiCount10 = ( unsigned char )( uiTime_ms / 10 );
UiCount0 = uiTime_ms % 10;
// 10MS 延时
while( UiCount10 )
{
TCON_bit.TF1 = 0;
TH1 = 0xB1; //10 ms
TL1 = 0xE2;
TCON_bit.TR1 = 1;
while( !TCON_bit.TF1 );
TCON_bit.TR1 = 0;
UiCount10--;
}
// 1 MS 延时
while( UiCount0 )
{
TCON_bit.TF1 = 0;
TH1 = 0xF8; //1 ms
TL1 = 0x32;
TCON_bit.TR1 = 1;
while( !TCON_bit.TF1 );
TCON_bit.TR1 = 0;
UiCount0--;
}
TH1 = 0x15; //30 ms
TL1 = 0xA0;
IE_bit.ET1 = 1;
TCON_bit.TR1 = 1;
}
/*
**-------------------------------------------------------------------------------------
** 改写定时器当前计数值
** tag_id: 定时器ID (TIMER0~TIMER1)
** setms: 将改变的计数值 (ms)
**-------------------------------------------------------------------------------------
*/
void TimeSet(unsigned char tag_id,unsigned long setms)
{
if( tag_id == TIMER0 )
{
TIMER.ulTimeCount0 = setms;
}
else if( tag_id == TIMER1 )
{
TIMER.ulTimeCount1 = setms;
}
else
{
//NULL
}
}
/*
**-------------------------------------------------------------------------------------
** 比较当前定时器记数值与输入值,当大于等于输入值输出1
** tag_id: 定时器ID (TIMER0~TIMER1)
** breakms: 输入值 (ms)
**-------------------------------------------------------------------------------------
*/
int TimeBreak(unsigned char tag_id,unsigned long breakms)
{
if( tag_id==TIMER0 )
{
if( TIMER.ulTimeCount0 >= breakms/(unsigned long)TIMER.MsTimer0 )
{
return 1;
}
else
{
return 0;
}
}
else if( tag_id==TIMER1 )
{
if( TIMER.ulTimeCount1 >= breakms/(unsigned long)TIMER.MsTimer1 )
{
return 1;
}
else
{
return 0;
}
}
else
{
//NULL
}
return 0;
}
/*
**-------------------------------------------------------------------------------------
** 创建定时中断
** tag_id: 定时器ID (TIMER0~TIMER1)
** pFn: 回调时间函数指针pFn (中断函数名)
**-------------------------------------------------------------------------------------
*/
unsigned int TimeLoad(unsigned char tag_id,pFnTime pFn)
{
if( tag_id==TIMER0 )
{
TIMER.pfnTimer0 = pFn; // 装入中断函数
}
else if( tag_id==TIMER1 )
{
TIMER.pfnTimer1 = pFn; // 装入中断函数
}
else
{
//NULL
}
return 1;
}
/*
**-------------------------------------------------------------------------------------
** 消毁第uiTimer个定时中断
** tag_id: 定时器ID (TIMER0~TIMER1)
**-------------------------------------------------------------------------------------
*/
unsigned int TimeDestroy(unsigned char tag_id)
{
if( tag_id==TIMER0 )
{
TIMER.pfnTimer0 = (pFnTime)0; // 对应中断无效
return 1;
}
else if( tag_id==TIMER1 )
{
TIMER.pfnTimer1 = (pFnTime)0; // 对应中断无效
return 1;
}
else
{
//NULL
}
return 0;
}
/*
**-------------------------------------------------------------------------------------
** 释放定时器资源
**-------------------------------------------------------------------------------------
*/
void TimeRelease()
{
TIMER.pfnTimer0 = (pFnTime)0; // T0中断无效
TMOD = ( TMOD & 0XF1 ) | 0x01; // 16位记数器
TH0 = 0; // TO
TL0 = 0;
TCON_bit.TR0 = 0; // T0不作位
IE_bit.ET0 = 0;
TCON_bit.TF0 = 0;
}
/*
**-------------------------------------------------------------------------------------
** 定时器0中断
**-------------------------------------------------------------------------------------
*/
#pragma vector=timer0
__interrupt void TimeINT0(void)
{
IE_bit.EA = 0; // 关闭所有中断
TH0 = TIMER.cTH0; //重装T0 应考虑本函数用时??
TL0 = TIMER.cTL0;
TIMER.ulTimeCount0++; //计时毫秒数
//pfnTimer非0
if( TIMER.pfnTimer0 )
{
( TIMER.pfnTimer0 )( ); //调用注册的回调函数
}
else
{
//NULL
}
IE_bit.EA = 1; // 开启所有中断
}
/*
**-------------------------------------------------------------------------------------
** 定时器1中断
**-------------------------------------------------------------------------------------
*/
#pragma vector=timer1
__interrupt void TimeINT1(void)
{
IE_bit.EA = 0; // 关闭所有中断
TH1 = TIMER.cTH1; //重装T1 应考虑本函数用时??
TL1 = TIMER.cTL1;
TIMER.ulTimeCount1++; //计时毫秒数
//pfnTimer非0
if( TIMER.pfnTimer1 )
{
( TIMER.pfnTimer1 )( ); //调用注册的回调函数
}
else
{
//NULL
}
IE_bit.EA = 1; // 开启所有中断
}
//----------------------------------------------------------------- End Of File --------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -