当我尝试重新初始化stm32f303VB的定时器4时,不再调用中断例程。
static uint32_t delay_val;
uint8_t InitCounter(uint32_t period, uint16_t perscl, void(*inter_handler)(void)) {
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
NVIC_InitTypeDef NVIC_InitStructure;
//check if the timer is occupied
if(TIMx->CR1&TIM_CR1_CEN) {
return 1;
}
//enable clock for apb1
gint_handler = inter_handler;
RCC_APB1PeriphClockCmd(RCC_xPeriph_TIMx,ENABLE);
//interrupt enable
NVIC_InitStructure.NVIC_IRQChannel = TIMx_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 7;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 7;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//deinitialize timer
TIM_DeInit(TIMx);
//initialize, clock frequency 72 MHz
TIM_TimeBaseStructInit(&TIM_TimeBaseInitStruct);
TIM_TimeBaseInitStruct.TIM_ClockDivision = 0;
TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Down;
TIM_TimeBaseInitStruct.TIM_Period = period;
TIM_TimeBaseInitStruct.TIM_Prescaler = perscl;
TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0; //this parameter is only for TIM1 and TIM8
TIM_TimeBaseInit(TIMx,&TIM_TimeBaseInitStruct);
return 0;
}
static void Delay_decrement(void) {
if(delay_val) {
delay_val--;
}
}
static void initGreenLED(void) {
//LED3 red on PE9
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOE,ENABLE);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOE, &GPIO_InitStructure);
}
void UnitTestDelay(void) {
initGreenLED();
Delay(1000000);
GPIOE->ODR ^= GPIO_Pin_11;
Delay(1000000);
}
void StartUSCounter(void(*inter_handler)(void)) {
InitCounter(1,72,inter_handler);
StartCounter();
}
void Delay(uint32_t us) {
delay_val=us;
StartUSCounter(Delay_decrement);
while(delay_val);
StopCounter();
}
void TIM4_IRQHandler(void)
{
// UINT16 temp;
if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)
{
TIM4->CR1 &= ~TIM_CR1_CEN;
TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
if(gint_handler) {
(*gint_handler)();
}
TIM4->CR1 |= TIM_CR1_CEN;
}
}
int main(void)
{
while(1) {
UnitTestDelay();
}
}
UnitTestDelay的第一次调用正确地减少delay_val,在Timer被禁用后,下一次初始化不成功,TIM4_IRQHandler永远不再被调用。为什么以及如何正确地重新初始化计时器?