打印
[STM32F1]

TIM2定时器延时问题

[复制链接]
1199|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
guanyanqin1992|  楼主 | 2014-8-20 01:02 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
int main(void)
{
#ifdef DEBUG
  debug();
#endif

  RCC_Configuration();  //系统时钟配置

  NVIC_Configuration();         //NVIC配置

  GPIO_Configuration();         //通用IO端口配置

  /*-----------------------------------------------------------------------------*/

  /***772M下定时值的计算((1+预分频TIM_Prescaler)/72*(1+定时周期TIM_Period))*/

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //配置RCC,使能TIMx

  /* Time Base configuration */
  TIM_TimeBaseStructure.TIM_Prescaler = 8;  //时钟预分频数 例如:时钟频率=72/(时钟预分频+1)  
  
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; ////定时器模式 向上计数  

  TIM_TimeBaseStructure.TIM_Period = 7;//自动重装载寄存器周期的值(定时时间)累计 0xFFFF个频率后产生个更新或者中断(也是说定时时间到)

  TIM_TimeBaseStructure.TIM_ClockDivision = 0; ////时间分割值  

  TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;

  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //初始化定时器2

  TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); //打开中断 溢出中断  

//打开定时器
//  TIM_Cmd(TIM2, ENABLE);  
   /* Main Output Enable */
  TIM_CtrlPWMOutputs(TIM2, ENABLE);         //暂时没用
//   GPIO_Write( GPIOB ,0xff);
  while (1)
  {  
           GPIO_Write( GPIOB ,0xfe00); //将Count数据送到GPIOB高八位
         delay(1000000);
         GPIO_Write( GPIOB ,0xfd00); //将Count数据送到GPIOB高八位
         delay(1000000);
         GPIO_Write( GPIOB ,0xfb00); //将Count数据送到GPIOB高八位
          delay(1000000);
         GPIO_Write( GPIOB ,0xf700); //将Count数据送到GPIOB高八位
         delay(1000000);
         GPIO_Write( GPIOB ,0xef00); //将Count数据送到GPIOB高八位
         delay(1000000);
         GPIO_Write( GPIOB ,0xdf00); //将Count数据送到GPIOB高八位
         delay(1000000);
         
  }
}
void delay(u32 ntimecount)
{        timecount=ntimecount;
        TIM_Cmd(TIM2, ENABLE);
        while(timecount);
        TIM_Cmd(TIM2, DISABLE);
}
中断程序:
extern u32 timecount;
void TIM2_IRQHandler(void)
{
  
  if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)  //检测制定的中断是否发生

  {

     TIM_ClearITPendingBit(TIM2, TIM_IT_Update);  //清除中断处理位。
         if(timecount)
     timecount-- ;

   }
}

问题:如上所示,定时器设置为每1us进入一次中断将timecount减1,但是,但我延时要为1秒:delay(1000000)时,根据流水灯的变化,感觉延时不止1秒,而是1点多秒,为什么会这样呢?    如果将定时器设置为每10us进入一次中断,那么延时1秒为 delay(100000),这时候延时就差不多为1秒了?请问大家这是什么问题
沙发
guanyanqin1992|  楼主 | 2014-8-20 01:03 | 只看该作者
新人求解答,谢谢

使用特权

评论回复
板凳
Leeone| | 2014-8-20 09:24 | 只看该作者
while(timecount);
TIM_Cmd(TIM2, DISABLE);
中断时间短了在执行这两句时候肯定中间还会中断,这样又消耗一段时间,定时时间长就不存在这问题了

使用特权

评论回复
地板
mmuuss586| | 2014-8-20 18:46 | 只看该作者
定时时间短,受程序的影响大,中断次数多了以后,累计误差也大了;

用滴答定时器看看;

使用特权

评论回复
5
guanyanqin1992|  楼主 | 2014-8-20 19:47 | 只看该作者
mmuuss586 发表于 2014-8-20 18:46
定时时间短,受程序的影响大,中断次数多了以后,累计误差也大了;

用滴答定时器看看; ...

你的意思是定时器定时的时间太短,进入中断频率太高,会有很大的误差累积下来吗?
那么通用定时器这个问题无法解决嘛?
我有试过滴答定时器,问题不是很大,延时1秒基本准确。但是我听说滴答定时器是很重要的,不能随便用。所以想用其它定时器资源

使用特权

评论回复
6
guanyanqin1992|  楼主 | 2014-8-20 19:53 | 只看该作者
Leeone 发表于 2014-8-20 09:24
while(timecount);
TIM_Cmd(TIM2, DISABLE);
中断时间短了在执行这两句时候肯定中间还会中断,这样又消耗 ...

也就是说,要用定时器实现1us的延时,要实现准确是不太可能的咯。
那这个误差大概是多少,实现1us延时会不会变成好几个微妙

使用特权

评论回复
7
mmuuss586| | 2014-8-21 08:24 | 只看该作者
guanyanqin1992 发表于 2014-8-20 19:47
你的意思是定时器定时的时间太短,进入中断频率太高,会有很大的误差累积下来吗?
那么通用定时器这个问 ...

恩,可以这么理解;
滴答定时器占用的中断资源少,有些好像还是32位的;

不过你控制灯闪闪的话,还不如用PWM输出,又占用程序资源;

使用特权

评论回复
8
Leeone| | 2014-8-21 09:01 | 只看该作者
guanyanqin1992 发表于 2014-8-20 19:53
也就是说,要用定时器实现1us的延时,要实现准确是不太可能的咯。
那这个误差大概是多少,实现1us延时会 ...

1us时间到了在定时中断中把中断关闭,执行完相应延时后再打开这样要好,不会在执行其他程序时候被中断打断

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

14

主题

275

帖子

4

粉丝