问题: 在一个工程中往往需求用到多个守时,可是咱们选用的CPU一般也只要2,3个守时器。显然是不够用的,那么应该怎么办呢?
我想假如运用过体系的人都会知道,在体系中有个时钟节拍,而多个使命都是一起运用这个时钟节拍进行延时或使命切换。那么咱们是否能够学习一下呢?
下面咱们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;// 告诉V%&&&&&%中止处理完毕
}
⑥. 编写标志方位位函数:
/**************************************************************************************
* 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功率会高一些。