新闻中心

EEPW首页>嵌入式系统>设计应用> 1个定时器多处复用的问题

1个定时器多处复用的问题

作者: 时间:2016-11-10 来源:网络 收藏

问题: 在一个工程中往往需要用到多个定时,然而我们采用的CPU一般也只有2,3个定时器。显然是不够用的,那么应该怎么办呢?

我想如果使用过系统的人都会知道,在系统中有个时钟节拍,而多个任务都是共同使用这个时钟节拍进行延时或任务切换。那么我们是否可以借鉴一下呢?

本文引用地址://m.amcfsurvey.com/article/201611/317373.htm

下面我们LPC2131举例说明:

①.宏定义:

#define T0_CLOCK_TICK (100)// 1S中计数次数

#define T0_TASK_NUM (3) // 3个定时

②. 进行定义一个定时数组:

uint32 T0_Counter[T0_TASK_NUM] ={0};// NUM 为需要使用的定时个数

③. 在相应的定义一个数组来存储标志位:

uint8 T0_Mark[T0_TASK_NUM]= {0};// 标志位为1表示定时时间到

④. 编写定时器初始化函数:

/**************************************************************************************
* FunctionName : Timer0Init()
* Description : 初始化定时器0
* EntryParameter : NO
* ReturnValue : NO
**************************************************************************************/
void Timer0Init(void)
{
/*Fcclk = Fosc x 4 = 11.0592MHz x 4 = 44.2368MHz
Fpclk = Fcclk / 4 = 44.2368MHz / 4 = 11.0592MHz*/

T0TC = 0; // 定时器设置为0
T0PR = 0; // 设置定时器0分频为1分频
T0MCR = 0x03;// 匹配通道0匹配中断并复位T0TC
T0MR0 = Fpclk/T0_CLOCK_TICK;// 比较值(1/T0_CLOCK_TICK s定时值)
T0TCR = 0x00;// 关闭定时器0
T0Open();// 开定时器

/* 设置定时器0中断IRQ*/
VICIntSelect = 0x00; // 所有中断通道设置为IRQ中断
VICVectCntl4 = 0x20|0x04;// 定时器0中断通道分配最高优先级
VICVectAddr4 = (uint32)IRQ_Time0;// 设置中断服务程序地址向量
VICIntEnable = 1 << 0x04;// 使能定时器0中断
}

⑤. 编写中断服务函数:

/**************************************************************************************
* FunctionName : IRQ_Time0()
* Description : 定时器0中断服务
* EntryParameter : NO
* ReturnValue : NO
**************************************************************************************/

void __irq IRQ_Time0(void) // 中断服务函数

{

uint8 i;

for (i=0; i {
if (T0_Counter[i] != 0)
{
T0_Counter[i]--;// 计数值减1
if (T0_Counter[i] == 0)
{
T0_SetMark(i);// 相应标志位置1
}
}
}

T0IR = 0x01;// 清除中断标志
VICVectAddr = 0x00;// 通知VIC中断处理结束

}

⑥. 编写标志位置位函数:

/**************************************************************************************
* FunctionName : T0_SetMark()
* Description : 设置相应标准位
* EntryParameter : NO
* ReturnValue : NO
**************************************************************************************/
void T0_SetMark(uint8 num)
{
switch (num)
{
case 0: T0_Mark[0] = 1; break;// 标志位置位
case 1: T0_Mark[1] = 1; break;//
case 2: T0_Mark[2] = 1; break;//

default: break;
}
}

⑦. 编写相应的函数,在需要使用的函数中设定计数时间:

voidFunction1(void)

{

T0_Mark[0] = 0; // 清除标志位

T0_Counter[0] = 100;// 1s计数器100次

while (1)

{

if (T0_Mark[0] == 1)// 判断时间是否到

{

T0_Mark[0] = 0;// 清除标志

...

}

}

}

⑧. 编写其他函数,按照以上方法。

注意事项:

①. 可以根据具体需要更改计数个数。

②. 定时器计数1S的此时可以根据具体需要设定,如果设定计数此时太多,CPU的效率会降低,但是精确度会高一下;反正精确度低,但是CUP效率会高一些。



关键词:定时器多处复

评论


技术专区

关闭