一个写的比较牛逼的51定时器中断
来源:互联网 发布:木地板性价比 知乎 编辑:程序博客网 时间:2024/04/29 18:39
来源:https://wenku.baidu.com/view/de230f2bcc7931b765ce1591.html
主要思想是将定时器的任务放到链表里面,通过注册,初始化定时器任务,通过遍历完成事件查询。简化了程序代码。
#ifndef _TIMER_CONFIG_H_
#define _TIMER_CONFIG_H_#include "const.h"
#include "oscfrequencydef.h"
#ifndef OSC_FREQUENCY
#error undefined OSC_FREQUENCY
#endif
//#warning must be used in AT89C52 or later version because of "idata"
#warning **********************************************************************************
#warning !! make sure MAX_TIMER_EVENT_NUM and TI
MER0_BASE_INTERVAL has appropriate value!!
#warning **********************************************************************************
#define MAX_TIMER_EVENT_NUM 5 //可设置不同定时事件的最大个数(至少为2)
#define TIMER0_BASE_INTERVAL 20 //单位:毫秒
typedef void (*TIMERPROC)(BYTE nID);
void InitTimer0();
BOOL SetTimerCallback(TIMERPROC lpTimerFunc); //必须在SetTimer0之前调用
BOOL SetTimer0(BYTE nID, WORD wInterval); //通过nID(nID>0)来区分
//BOOL KillTimer0(BYTE nID);
/////////////////////////////////////////////////
//以下为内部使用
typedef struct tagTIMERINFO{
BYTE nID; //定时器ID
WORD wInterval; //此定时器的设定间隔时间
WORD wElapse; //剩余的时间
}TIMERINFO;
static BOOL AddTail(const TIMERINFO* pTimerInfo);
static BOOL Remove(BYTE nID);
static BYTE FindID(BYTE nID);
#endif
#ifndef _CONST_H_
#define _CONST_H_
#include
#define TRUE 1
#define FALSE 0
typedef unsigned char BYTE;
typedef unsigned int WORD;
typedef unsigned long DWORD;
typedef float FLOAT;
typedef char CHAR;
typedef unsigned char UCHAR;
typedef int INT;
typedef unsigned int UINT;
typedef unsigned long ULONG;
typedef UINT WPARAM;
typedef ULONG LPARAM;
typedef ULONG LRESULT;
typedef void VOID;
typedef const CONST;
typedef void *PVOID;
typedef bit BOOL;
#define MAKEWORD(lo, hi) ((WORD)(((BYTE)(lo)) | ((WORD)((BYTE)(hi))) << 8))
#define MAKEDWORD(lo, hi) ((DWORD)(((WORD)(lo)) | ((DWORD)((WORD)(hi))) << 16))
#define LOWORD(l) ((WORD)(l))
#define HIWORD(l) ((WORD)(((DWORD)(l) >> 16) & 0xFFFF))
#define LOBYTE(w) ((BYTE)(w))
#define HIBYTE(w) ((BYTE)(((WORD)(w) >> 8) & 0xFF))
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#define SET_STATE_FLAG(state, mask) ((state) |= (mask))
#define RESET_STATE_FLAG(state, mask) ((state) &= ~(mask))
#define TEST_STATE_FLAG(state, mask) ((state) & (mask))
#define TEST_BIT(b, offset) (1 & ((b) >> (offset)))
#define SET_BIT(b, offset) ((b) |= (1 << (offset)))
#define RESET_BIT(b, offset) ((b) &= (~(1 << (offset))))
//将BCD码变为十进制,如将0x23变为23
//注意:高四位和低四位均不能大于9
#define BCD_TO_DECIMAL(bcd) ((BYTE)((((BYTE)(bcd)) >> 4) * 10 + (((BYTE)(bcd)) & 0x0f)))
#define DECIMAL_TO_BCD(decimal) ((BYTE)(((((BYTE)(decimal)) / 10) << 4) | ((BYTE)(decimal)) % 10))
#define NOP() _nop_()
#define BYTE_ROTATE_LEFT(b, n) _crol_(b, n)
#define BYTE_ROTATE_RIGHT(b, n) _cror_(b, n)
#define WORD_ROTATE_LEFT(w, n) _irol_(w, n)
#define WORD_ROTATE_RIGHT(w, n) _iror_(w, n)
#define DWORD_ROTATE_LEFT(dw, n) _lrol_(dw, n)
#define DWORD_ROTATE_RIGHT(dw, n) _lror_(dw, n)
#define ENABLE_ALL_INTERRUPTS() (EA = 1)
#define DISABLE_ALL_INTERRUPTS() (EA = 0)
#endif
#include "timerconfig.h"
#include "chiptypedef.h"
#include
#include
code const WORD TIMER0_INIT_VALUE = UINT_MAX - ((WORD)((float)OSC_FREQUENCY * 1.0f / 12 * 1000)) * TIMER0_BASE_INTERVAL;
idata TIMERINFO TimerInfoArray[MAX_TIMER_EVENT_NUM] = {0};
TIMERPROC g_pfnTimerFunc = NULL;
BYTE g_nTimerInfoNum = 0; //当前队列的元素个数
void InitTimer0(){
TMOD |= T0_M0_; //定时器0,工作方式1
TH0 = HIBYTE(TIMER0_INIT_VALUE);
TL0 = LOBYTE(TIMER0_INIT_VALUE);
TR0 = 0; //停止定时器0
ET0 = 0; //关定时器0中断
EA = 1;
}
BOOL SetTimerCallback(TIMERPROC lpTimerFunc){
if(lpTimerFunc == NULL)
return FALSE;
g_pfnTimerFunc = lpTimerFunc;
return TRUE;
}
BOOL SetTimer0(BYTE nID, WORD wInterval){
TIMERINFO ti;
if(g_pfnTimerFunc == NULL || nID == 0 || wInterval == 0)
return FALSE;
if(wInterval % TIMER0_BASE_INTERVAL != 0) //定时间隔必须是TIMER0_BASE_INTERVAL的整数倍
return FALSE;
if(FindID(nID) != MAX_TIMER_EVENT_NUM) //若已经有相同的ID存在
return FALSE;
ti.nID = nID;
ti.wInterval = wInterval;
ti.wElapse = wInterval;
if(!AddTail(&ti))
return FALSE;
TR0 = 1; //启动定时器0
ET0 = 1; //开定时器0中断
return TRUE;
}
static BYTE FindID(BYTE nID){
BYTE i = 0;
for(i = 0; i < MAX_TIMER_EVENT_NUM; i++){
if(TimerInfoArray[i].nID == nID)
return i;
}
return MAX_TIMER_EVENT_NUM;
}
static BOOL AddTail(const TIMERINFO* pTimerInfo){
if(g_nTimerInfoNum == MAX_TIMER_EVENT_NUM || pTimerInfo == NULL)
return FALSE;
memcpy(&TimerInfoArray[g_nTimerInfoNum], pTimerInfo, sizeof(TIMERINFO));
g_nTimerInfoNum++;
return TRUE;
}
void Timer0ISR() interrupt TF0_VECTOR
{
BYTE i = 0;
TF0 = 0;
TH0 = HIBYTE(TIMER0_INIT_VALUE);
TL0 = LOBYTE(TIMER0_INIT_VALUE);
for(i = 0; i < g_nTimerInfoNum; i++){
TimerInfoArray[i].wElapse -= TIMER0_BASE_INTERVAL;
if(TimerInfoArray[i].wElapse == 0){
(*g_pfnTimerFunc)(TimerInfoArray[i].nID);
TimerInfoArray[i].wElapse = TimerInfoArray[i].wInterval;
}
}
}
阅读全文
0 0
- 一个写的比较牛逼的51定时器中断
- 写定时器中断遇到的问题
- 比较牛逼的css
- 写一个逼格的冒泡排序
- JavaScript写的一个定时器
- JavaScript写的一个定时器
- 我写的一个定时器
- 一个牛逼的男人
- 比较牛逼的正则表达式替换
- 分享给大家一个比较装逼的小代码
- dm642的中断定时器
- STM32的定时器中断
- 一个苦逼程序猿的牛逼选择
- 封装一个使用比较方便快捷的定时器
- 关于字符编码(1)[据说是一个牛逼的人写的]
- 关于字符编码(1)[据说是一个牛逼的人写的]
- 多线程学习--写一个简单的定时器
- 自己写的一个定时器 timer
- webots自学笔记(七)通过定义顶点构件3D形状(IndexedFaceSet节点)
- Unity读取.csv文件
- android ANR实例分析
- LuaFramework框架启动详细流程图
- webots自学笔记(八)麦克纳母轮移动机器人平台,可控制摄像头视角
- 一个写的比较牛逼的51定时器中断
- 五分钟学GIS | 快速认识 MapBox GL
- 文章标题
- 【swagger】前后端分离联调利器——swagger安装和使用
- Server Tomcat v8.0 Server at localhost failed to start.
- java基础--坦克大战(一)
- webots自学笔记(九)弹簧与阻尼添加
- 第一次构建maven项目出现的问题
- myeclipse配置多个tomcat