如果我们需要用oled实现秒表(计时)的功能,在oled上显示秒钟的变化,我们可以使用TIM定时中断来实现。
1.配置TIM时基单元:
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
TIM_InternalClockConfig(TIM3); //选择时钟(内部)
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;//配置时基单元
TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1; //预分频系数(1,2,4)(预分频系数是滤波的频率,一般设置成1分频就行)
TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; //向上计数,向下计数,中央对齐模式
TIM_TimeBaseInitStruct.TIM_Period = 10000-1; //ARR(自动重装载值)0~65535
TIM_TimeBaseInitStruct.TIM_Prescaler = 7200-1; //PSC(预分频值) 0~65535
TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0; //PCR,不需要用,设置成0就可以
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStruct);
TIM_ClearFlag(TIM3, TIM_FLAG_Update); //清除标志位
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); //使能TIM3更新中断
TIM_Cmd(TIM3,ENABLE);//使能定时器
因为我们想要的效果是一秒钟记一次数,所以我们的计数频率要为1,也就是说要让要设置ARR和PSC,使得72MHZ/(ARR+1)/(PSC+1)=1,这里ARR和PSC的值可以随意调整,只需要保证两值都在0~65535范围内即可。
值得注意的是TIM_ClearFlag(TIM3, TIM_FLAG_Update)这个函数,在TIM_Timebaseinit函数中,初始化的过程会自动触发中断,如果我们不清除标志位,会导致程序多进入一次中断。
2.配置NVIC:
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStructure);
配置NVIC没什么好说的,选择好对应的通道就可以了。
3.编写中断服务函数:
void TIM3_IRQHandler(void)
{
if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET)//判断标志位
{
num++;
TIM_ClearITPendingBit(TIM3,TIM_IT_Update);//清除标志位
}
}
因为我们的时基单元配置的是1秒钟进入一次中断,所以我们在每次进入中断的时候让num++,就可以达到每秒钟更新一次,按秒计时的功能了,剩下的只需要在主函数里extern num,不断的在oled上更新num的值即可。