Day13_定时器中断处理

方法:

采用了一个定时器链表,按照定时时间从早到大进行排序,可加速处理的速度
并且加入了一个哨兵节点,定时时间设置为0xffffffff,来简化节点插入的操作

Timer.h

#ifndef __TIMER_H__
#define __TIMER_H__


#include "fifo.h"

//设定最多有500个定时器
#define MAX_TIMER 500
//已配置状态
#define TIMER_FLAGS_ALLOC   1
//定时器运行状态
#define TIMER_FLAGS_USING   2
//该定时器没有分配 使用
#define TIMER_FLAGS_NOT_USE 0

struct TIMER
{
    struct TIMER *pNext;
    unsigned int u32TimeOut;
    unsigned int u32Flag;//记录当前的定时器是否被使用过
    struct FIFO *pFifo;//缓冲区队列
    int nData;
};


struct TIMER_CONTRAL
{
    unsigned int u32Count;//当前总共计数的秒数
    unsigned int u32Next;//下一个需要比较的定时器的时间
    struct TIMER *pTimerHead;//定时器 链表的 头结点
    struct TIMER TimerArr[MAX_TIMER];   
};



//获得一个定时器
struct TIMER *GetTimer(void);

//释放一个定时器
void TimerFree(struct TIMER *pTimer);

//初始化定时器
void TimerInit(struct TIMER *pTimer, struct FIFO *pFifo,  int nData);

//设置定时器
void SetTimer(struct TIMER *pTimer, unsigned int u32TimeOut);




#endif

初始化定时器

//初始化定时器 每10ms 发生一次中断
void InitPit(void)
{
	int i;

	struct TIMER *pShaoBIng;//感觉没有必要添加哨兵节点

	//使用计数器0 先写入低字节在写入高字节 方式2循环计数 采用二进制
	io_out8(PIT_CTRL, 0x34);//00 11 010 0
	io_out8(PIT_COUNT0, 0x9c);
	io_out8(PIT_COUNT0, 0x2e);

	TimerCtl.u32Count = 0;

	//将所有的定时器都设置为 未使用
	for(i = 0; i < MAX_TIMER; i++)
	{
		TimerCtl.TimerArr[i].u32Flag = TIMER_FLAGS_NOT_USE;
	}

	//获得一个SB定时器 并将其放在定时器链表的最后
	pShaoBIng = GetTimer();
	pShaoBIng->u32TimeOut = 0xffffffff;
	pShaoBIng->u32Flag = TIMER_FLAGS_USING;
	pShaoBIng->pNext = 0;

	//没有正在运行的定时器 所以就设置为SB的定时时间
	TimerCtl.u32Next = 0xffffffff;
	//设定定时器链表的头结点 为SB节点
	TimerCtl.pTimerHead = pShaoBIng;

	return;
}

定时器的中断处理

每次将TCL 的计数值+1 , 如何没有大于头结点设置的那个定时值,那么直接返回,到了后,查找定时值最小的那个,设置为头结点

void IntHandler20(int *pEsp)//定时器中断IRQ0
{
	struct TIMER *pTimerTemp;

	io_out8(PIC0_OCW2, 0x60);

	//每次中断+1 来计数
	TimerCtl.u32Count++;

	//下一个需要比较的时间 未到 那么什么也不做
	if(TimerCtl.u32Next > TimerCtl.u32Count)
	{
		return;
	}

	//把定时器链表的 头结点 赋值给 Temp
	pTimerTemp = TimerCtl.pTimerHead;

	
	//Temp 在循环结束时候 是第一个未超时的那个 或者都超时了 
	while(1)
	{
		//一直运行到 不超时那个TIMER 为止 因为pTimer数组是经过排序的
		if(pTimerTemp->u32TimeOut > TimerCtl.u32Count)
		{
			break;
		}

		//处理超时的定时器
		pTimerTemp->u32Flag = TIMER_FLAGS_ALLOC;
		FifoSaveData(pTimerTemp->pFifo, pTimerTemp->nData);
		pTimerTemp = pTimerTemp->pNext;
	}

	//改变头结点
	TimerCtl.pTimerHead = pTimerTemp;

	TimerCtl.u32Next = TimerCtl.pTimerHead->u32TimeOut;

	return;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值