前言
最近在調試項目過程中,用了 STM32F030 的定時器 16 作為系統時鍾,1ms 觸發一次中斷,過程中遇到一些值得記錄的問題。
記錄
STM32F030 中定時器 16 的初始化配置如下
void TIM16_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM16, ENABLE);
TIM_TimeBaseStructure.TIM_Prescaler = 48 - 1; //預分頻系數為48-1,這樣計數器計數頻率為48MHz/48 = 1MHz
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //設置時鍾分割
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //設置計數器模式為向上計數模式
TIM_TimeBaseStructure.TIM_Period = 1000; //設置計數溢出大小,每計1000個數就產生一個更新事件,1ms一次中斷
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; //重復n次計數才觸發中斷
TIM_TimeBaseInit(TIM16, &TIM_TimeBaseStructure); //將配置應用到TIM16中
TIM_ITConfig(TIM16, TIM_IT_Update, ENABLE); //使能TIM16的更新中斷
TIM_Cmd(TIM16, ENABLE); //開啟定時器16
//Enable the TIM16 Interrupt
NVIC_InitStructure.NVIC_IRQChannel = TIM16_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
對應的中斷配置
void TIM16_IRQHandler(void)
{
if(TIM_GetITStatus(TIM16, TIM_IT_Update) != RESET)
{
systime_ms++;
}
TIM_ClearITPendingBit(TIM16, 0x00ff);
}
配置使用了 Update 中斷,也就是更新事件中斷。值得注意的是初始化中的 TIM_RepetitionCounter,這個代表重復溢出多少次才觸發一個中斷,在一開始的配置中我忽略了這個參數,但仍然是 1ms 觸發一次中斷。但在后面開啟了 I2C 功能和初始化 I2C 后,這個定時器就變成了 2 次溢出才觸發一次中斷,只有配置
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
之后才正常中斷