现象
用定时器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){}
}