现象

用定时器TIM4定时翻转GPIO用低电平灌电流驱动LED闪烁的简单测试程序不能正常执行。LED灯不闪烁,debug查看GPIO口却是正确的被翻转了。测试IO口电压不对。

问题代码

void main(void)
{
  // 系统时钟不分频(内部16MHz)
  CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);
  // TIM4进行128分频,同时设置溢出上限值保证1ms一次中断
  TIM4_TimeBaseInit(TIM4_PRESCALER_128, 124);
  // 开TIM4更新事件中断
  TIM4_ITConfig(TIM4_IT_UPDATE, ENABLE);
  // 开总中断
  enableInterrupts();
  //  使能定时器4
  TIM4_Cmd(ENABLE);
  //  初始化GPIO,输出上拉模式
  GPIO_Init(LED_GPIO_PORT, (GPIO_Pin_TypeDef)LED_GPIO_PINS, GPIO_MODE_OUT_PP_LOW_SLOW);

  while (1){}
}

直接原因

继续debug发现GPIO的方向寄存器DDR和模式寄存器CR1没有被设置。

根本原因

在GPIO初始化完成之前定时器就开始运行了。导致不断进入定时器中断,后面的GPIO初始化代码没有正确被执行(或者定时器中断中不能被正确执行?这个没有深究了)

解决

将GPIO初始化代码放在定时器初始化之前(放在使能之前即可)

正确代码

void main(void)
{
  // 系统时钟不分频(内部16MHz)
  CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);
  // GPIO的初始化要放在timer初始化之前,否则初始化的过程会被中断打断导致输出有问题(DDR还没来得及配置成输出模式)
  GPIO_Init(LED_GPIO_PORT, (GPIO_Pin_TypeDef)LED_GPIO_PINS, GPIO_MODE_OUT_PP_LOW_SLOW);
  // TIM4进行128分频,同时设置溢出上限值保证1ms一次中断
  TIM4_TimeBaseInit(TIM4_PRESCALER_128, 124);
  // 开TIM4更新事件中断
  TIM4_ITConfig(TIM4_IT_UPDATE, ENABLE);
  // 开总中断
  enableInterrupts();
  //  使能定时器4
  TIM4_Cmd(ENABLE);

  while (1){}
}
Last modification:November 26, 2020
If you think my article is useful to you, please feel free to appreciate