51单片机毕设-系统定时器os_timer.c

os_timer.c

  • 1> 系统定时器概述
  • 2> 系统定时器-数据类型
  • 3> 系统定时器-启动
  • 4> 系统定时器-任务函数
  • 5> 系统定时器-停止函数


1> 系统定时器概述

为了解决51单片机内部定时器不足,基于SysTick系统嘀嗒的基础上,模拟出多路定时器;

51单片机内部定时器通常有3路:
Timer1:用于串口时钟;
Timer2:用于系统嘀嗒时钟SysTick;
Timer0:用于其他;


2> 系统定时器-数据类型


typedef void (*function)(void);
#define Function(address)   (*((function)address)) ()


typedef struct 
{
    ushort16_t  Times;
    function Function;
}TimerStruct;

#define TimerSum 0x4                            	// 定时器数量,不超过8

static uchar8_t idata State = 0;                    // 工作标记寄存器,共8路,置1使能


static TimerStruct idata TimerBlock[TimerSum];  	// 注册函数及次数存储数组

4路定时器;
51单片机毕设-系统定时器os_timer.c_第1张图片


3> 系统定时器-启动


typedef enum 
{
    TimerSystick            = 0,        // 系统节拍中处理
    TimerMessage            = 1	        // while(1)循环中消息处理
}TimerModeEnum;	

static TimerModeEnum idata Mode;                	// 工作模式 


/**
 * @brief 软件定时器
 * @mode 2种处理方式:
 *					1> 直接在节拍中断中处理,适合费用低的
 *					2> 在消息中处理,适合处理费用高的
 * @times 延时节拍数,以系统节拍为但我 times*100ms
 * @registerFunction 回调执行函数;
 * @retval 返回ID号,从0开始,失败则返回invalid(-1)
 */ 
uchar8_t TimerStart(TimerModeEnum mode, ushort16_t times, function registerFunction)
{
    uchar8_t i;

    EnterCritical();
    for(i = 0; i < TimerSum; i++) 
    {
        if(!GET_BIT(State, i)) 
        {			
            TimerBlock[i].Times = times;                        // 注册节拍次数 
            TimerBlock[i].Function = registerFunction;          // 注册回调函数
            if(mode)                                            // 工作模式
                SET_BIT(Mode, i);
            else 
                CLEAR_BIT(Mode, i);
			
            SET_BIT(State, i);                                   // 置位开启 
            ExitCritical();
			
            return(i);
        }
    }
    ExitCritical();
    return(invalid);
}

4> 系统定时器-任务函数

软件定时器是基于SysTick实现计时,所以必须要一个任务函数

void Timer_Task(void)
{
    uchar8_t i = 0;
	uchar8_t stateBackup;
	
    if (State == 0x00) {
		return;											// 状态表为空,跳出
	}	
	
    stateBackup = State;              					// 复制一份状态表
	
    while (stateBackup)	
    {
        if ((stateBackup & 0x01) == 1) 			
        {
            if ((--TimerBlock[i].Times) == 0) 			// 计数递减到0时
            {
                if (GET_BIT(Mode, i))     				// 获取工作模式                   
                    QUEUE_Post(MessageTimer, (ushort16_t)TimerBlock[i].Function);
                else 
                    (TimerBlock[i].Function)(); 	    // 系统节拍中处理
                    
                CLEAR_BIT(State, i);     			  	// 关闭这一路定时器                
            }
        }
        stateBackup = stateBackup >> 1;
        i++;
    }
}

5> 系统定时器-停止函数

/**
 * @brief	关闭某一路定时器
 * @id		TimerStart执行后返回的id,0,1,2... 	
 * @retval  无
 */ 
void TimerStop(uchar8_t id) 
{
    if (id >= TimerSum) return;     
        
    EnterCritical();
	
    CLEAR_BIT(State, id);
	
    ExitCritical();
}

你可能感兴趣的:(51单片机-毕业设计,51单片机,课程设计,c语言)