找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 16682|回复: 3
打印 上一主题 下一主题
收起左侧

STM32 高级定时器TIM1“计时不准”?

[复制链接]
跳转到指定楼层
楼主
ID:65608 发表于 2014-9-15 17:16 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
      最近,在学习STM32单片机,选用的型号是通用型STM32F103,在学习定时器应用时,遇到了一个很头疼的问题,怀疑STM32 高级定时器TIM1“计时不准”。       事情的来龙去脉是这样的,之前写了一个通过tim1定时器中断实现led闪烁的程序,测试时led闪烁频率和我设置的频率一致,当我后面继续这个程序上添加ad采样程序后,调试时,偶然发现led闪烁频率变慢,RCC时钟配置和原来一样,为什么加个ad采样程序,会影响定时器工作,这让我觉得非常奇怪。
       led闪烁频率变慢,可以肯定与RCC配置和定时器配置有关,当时写的程序如下:
void RCC_Configuration(void)
{
ErrorStatus HSEStartUpStatus;
RCC_DeInit();                     
RCC_HSEConfig(RCC_HSE_ON);
HSEStartUpStatus=RCC_WaitForHSEStartUp();
if(HSEStartUpStatus == SUCCESS)
{
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);  
FLASH_SetLatency(FLASH_Latency_2);
RCC_HCLKConfig(RCC_SYSCLK_Div1);  
RCC_PCLK2Config(RCC_HCLK_Div1);
RCC_PCLK1Config(RCC_HCLK_Div2);   
RCC_ADCCLKConfig(RCC_PCLK2_Div6);
RCC_PLLConfig(RCC_PLLSource_HSE_Div2,RCC_PLLMul_9);     //16M外部晶振,16/2M*9=72
RCC_PLLCmd(ENABLE);              
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET);
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
while(RCC_GetSYSCLKSource() !=0x08);
}
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);      
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
}

void TIM1_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef     TIM_OCInitStructure;
TIM_DeInit(TIM1);
TIM_InternalClockConfig(TIM1);
TIM_TimeBaseStructure.TIM_Period = 2000;          //计数2000次,每2000/2K=1s产生一次中断   
TIM_TimeBaseStructure.TIM_Prescaler = 35999;    //进行预分频35999+1,72M/36K=2K Hz
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;  
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure);

TIM_PrescalerConfig(TIM1,35999,TIM_PSCReloadMode_Immediate);
TIM_ClearFlag(TIM1,TIM_FLAG_Update);
        TIM_ARRPreloadConfig(TIM1, DISABLE);
TIM_ITConfig(TIM1,TIM_IT_Update,ENABLE);
}


      从程序上看Tim1每一秒产生一次中断,在中断函数中实现led亮一秒暗一秒,但是实际led闪烁频率会变慢,而当我改变ad采集口时,led闪烁频率会变得更慢,配置io会影响时钟,很无厘头,这芯片还敢用吗?实在没办法,我配置了一下Tim2,用Tim2定时中断,结果一切都工作正常。这是什么逻辑,高级定时器tim1反而没普通定时器tim2靠谱,无语。。。。。
       最近又查了下资料,终于发现tim1定时器有一些特有的配置功能,它可以控制溢出中断的周期,它是由寄存器TIM1_RCR控制,如下图所示,库函数中是由TIM_TimeBaseStructure.TIM_RepetitionCounter 来控制


当TIM_TimeBaseStructure.TIM_RepetitionCounter=N时,表示重复溢出N次后,才产生一次中断;当TIM_TimeBaseStructure.TIM_RepetitionCounter=0时,当然就表示溢出直接中断。所以当在配置tim1定时器时,在TIM_TimeBaseInit();前面加一句TIM_TimeBaseStructure.TIM_RepetitionCounter=0;定时器1一切工作正常。
       问题虽然解决,但依然很奇怪的是,TIM1_RCR的复位值为0,即使我不在程序中将其置零,也不会影响它的值,为什么程序运行时它的值会莫名其妙的被改变,这个问题想不通!
       P.S. 测试时又偶然发现,TIM1和TIM2工作时的时钟频率都是72M,不是说TIM2是来源于APB2,是36M吗?

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:77005 发表于 2016-5-11 23:33 | 只看该作者
哥们  特意注册一个号来感谢你啊,这个问题困扰我好久。。。
回复

使用道具 举报

板凳
ID:142416 发表于 2016-10-12 12:07 | 只看该作者
感谢~查了半天~终于知道了~以前能用的就是调整优化级别后出现的问题~
那个来源APB2的定时器是有一个2倍频的~所以也是72m
回复

使用道具 举报

地板
ID:194316 发表于 2017-4-27 19:36 | 只看该作者
哥们。我特意注册了一个号码,来感谢你的,今天下午排查这个问题半天,看到你的提示,解决问题了,谢谢。对于你说的为什么TIME2 时钟会是72MHZ,你仔细看时钟树,当你配置住时钟为72Mhz,经过APB1 2分频为36MHZ,这个时钟一个是给给了APB1外设,另外是给定时器2-7,但是给定时器2-7之前,有句话是“如果APB1预分频系数为1,那么频率不变,不为1,那么频率为*2”,我们APB1预分频系数为2,所以定时器2-7的时钟频率就为了72Mhz。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表