微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 关于51单片机定时器的灵活使用

关于51单片机定时器的灵活使用

时间:11-20 来源:互联网 点击:
前段时间,做一个项目,有串口收发指令判断,按键类型判断,长短按之类,power的定时关电,事件的轮询扫描更新和display的定时扫描。这些要求就对定时器提出了要求,但是我的51单片机只有两个定时器,其中一个又有debug口的波特率产生之用。于是乎我可以用的定时器就只剩下了一个。怎么办?可能大家都只能用变量在定时中断函数去做多了任务就行了,但是我总是感觉这样会导致代码看起来太不具有条理性,而且对于日后的管理不是很容易。思来想去,就想到了linux内核中对于定时器的封装,那种面向对象的思想。

想法有了,我觉得实现就是很简单了。下面给大家贴上我的代码:

.h 文件:

#ifndef __SC_TIMER_H#define __SC_TIMER_H/* SC_Common.h文件中包含了对数据类型的定义和包含对应的单片机的配置头文件,这里就没有列出,根据个人所使用情况而定 */#include "SC_Common.h"#ifdef MODE1T#define T0TIMES	(65536-FOSC/1000)#define T1TIMES	(65536-10*FOSC/1000)#else#define T0TIMES	(65536-FOSC/12/1000)			// 0.1ms#define T1TIMES	(65536-10*FOSC/12/1000)			// 10ms#endif /*MODE1T*/#define TIMER_SIZE	4typedef struct{U8 timerId;			/* 定时器的id,实则指明了起所在数组中的位置 */S8 isRuning;			/* 表明当前timer是否正在运行 */U16 curTimes;			/* 当前timer时间 */U16 expireTimes;		/* 当前timer的溢出时间 */U8 existInArry;		        /* 当前的timer是否存在于数组之中 */TimerFunc timerFunc;	        /* 当前timer的指定运行函数 */} Timer;void InitTimer(void);S8 AddTimer(Timer *timer);S8 DelTimer(Timer *timer);S8 StartTimer(Timer *timer);S8 ModifyTimer(Timer *timer);S8 StopTimer(Timer *timer);S8 IsRunningTimer(Timer *timer);#endif	/*__SC_TIMER_H*/

下面是这部分思想的重点实现,无非就是向timerArray数组中添加删除定时器,简言之,即所谓的增删改查,还有就是启动停止定时器,考虑到51单片机的性能,没有像linux内核中那样用链表实现,同时定时器的总数也是有上限要求的。

.c文件:

#include "SC_Timer.h"#include #include /* 这里采用数组的方式管理各个timer结构体 */Timer timerArray[TIMER_SIZE];U8 timerUsed = 0;void InitTimer(void){TMOD |= 0x01;TL0 = T0TIMES;TH0 = T0TIMES >> 8;ET0 = 1;TR0 = 1;timerUsed = 0;memset(timerArray, 0, sizeof(timerArray));}S8 AddTimer(Timer *timer){if(timerUsed >= TIMER_SIZE)timerUsed = 0;/*×Ô¶šÒåtimerIdµÄÉú³É·œÊœ¬Œ??ú±íÆäÔÚÊý×éÖеÄλÖÃ*/timer->timerId = timerUsed;timerArray[timerUsed] = *timer;timerUsed++;timer->existInArry = 1;timer->isRuning = 0;printf("%bu\n", timer->timerId);return 0;}static void Del_Timer(Timer *timerArray, U8 *timerUsed, U8 pos){U8  i = 0;U8 len = *timerUsed;for(i=pos; itimerId >= TIMER_SIZE || timer->timerId < 0 || timer->existInArry == 0)return -1;if(timerUsed <= 0)return -1;Del_Timer(timerArray, &timerUsed, timer->timerId);timer->existInArry = 0;return 0;}S8 StartTimer(Timer *timer){if(timer->timerId >= TIMER_SIZE || timer->timerId < 0 || timer->existInArry == 0)return -1;timerArray[timer->timerId].isRuning = 1;return 0;}S8 ModifyTimer(Timer *timer){if(timer->timerId >= TIMER_SIZE || timer->timerId < 0 || timer->existInArry == 0)return -1;timerArray[timer->timerId].curTimes = timer->curTimes;timerArray[timer->timerId].expireTimes = timer->expireTimes;timerArray[timer->timerId].timerFunc = timer->timerFunc;return 0;	}S8 StopTimer(Timer *timer){if(timer->timerId >= TIMER_SIZE || timer->timerId < 0  || timer->existInArry == 0)return -1;timerArray[timer->timerId].isRuning = 0;return 0;}S8 IsRunningTimer(Timer *timer){S8 ret = -1;if(timer->timerId >= TIMER_SIZE || timer->timerId < 0 || timer->existInArry == 0)return ret;ret = timerArray[timer->timerId].isRuning;return ret;}/* *  定时器的中断函数负责判断各个事件的时间是否到达,如果到达调用相应的相应函数进行运行*  由于51单片机的函数指针是没有堆栈保护的,所以这里加入了            

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top