STM32F103ZE的AHB时钟为72MHz,通过HSE的8M倍频到72M,然后APB1预分频系数为2,所以TIM2-7时钟为2*36M。由于定时器是16位,PSC寄存器最大为65536,不支持71999,所以只能以0.1ms计数。
整个系统在获取时间的累增时,定义64位变量,即可运行很久的时间,不用担心溢出或者死机。定义64位变量有2个方法,一就是用long long 直接定义,通过sizeof测试为8个字节;二就是利用”stdint.h”,typedef uint64_t u64。
一般情况下,定时器计时结果算法公式为:Tout = (ARR+1)(PSC+1)/Tclk。Tclk即为时钟频率。
准备工作
1)建立一个struct
typedef struct{
void (*fTask)(void);
u32 uNextTick;
u32 uLenTick;
}sTask;
1
2
3
4
5
2)任务列表
static sTask mTaskTab[] =
{
{Task_SysTick, 0, 0} ,
{Task1, 0, 100} , // 10ms执行一次
{Task2, 0, 200} // 200ms执行一次
};
1
2
3
4
5
6
3)初始化定时器
void TaskTimer_Init()
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Period = 65535;
TIM_TimeBaseStructure.TIM_Prescaler = 7199;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
TIM_SetCounter(TIM2, 0);
/* TIM enable counter */
TIM_Cmd(TIM2, ENABLE);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
4)获取启动后时间
u64 GetTimingTick()
{
return TimingTick;
}
1
2
3
4
5)任务执行期间获取系统时间
在这里插入void Task_SysTick()
{
u32 temp = TIM_GetCounter(TIM2);
if(temp > 10000)
{
TIM_SetCounter(TIM2,0);
TimingTickHold = TimingTickHold + temp;
temp = 0;
}
TimingTick = temp + TimingTickHold;
}
1
2
3
4
5
6
7
8
9
10
11
运行实例
#define ARRAYSIZE(a) (sizeof(a)/sizeof((a)[0]))
static sTask mTaskTab[] =
{
{Task_SysTick, 0, 0},
{DATA_HANDLE, 0, 500},//50ms
{Key_Scan, 0, 500}
};
while(1)
{
for(int i = 0;i < ARRAYSIZE(mTaskTab);i++ )
{
if(mTaskTab[i].uNextTick <= GetTimingTick() )
{
mTaskTab[i].uNextTick += mTaskTab[i].uLenTick;
mTaskTab[i].fTask();
}
}
}