OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5438|回复: 7

stm32f103定时器总是固定快了1s多,加大定时精度可以缓解,但不知为什么

[复制链接]

11

主题

34

帖子

0

精华

初级会员

Rank: 2

积分
105
金钱
105
注册时间
2016-2-19
在线时间
19 小时
发表于 2016-8-5 16:24:40 | 显示全部楼层 |阅读模式
3金钱
代码中 t1 是1s钟定时。我在主函数中 if(t1==10)led(ON);  但是,我按下复位的同时按下手机的秒表,发现当秒表计时8s多,led就亮了。
如果改成 if(t1==20)时,在秒表计时到 18s 多led点亮。 当 if(t1==15) 时,在13s多就点亮led了。  总有个时间差。。。

我的解决办法是增加定时精度,当我把 t1 换成 1ms 定时的时候,if(t1==5000),基本就是过5s就点灯,时间差看不出来了

不知道为什么,虽然可以经过加减时间差或其他方式来解决,但是总感觉不安啊。有大神知道为什么吗?

[mw_shl_code=c,true]#include "Timing.h"
#include "stm32f10x.h"

uint16_t T=0,t1=0;  //

#define PERIOD 10000   // 1s 定时

void Timing_Config(void)
{
TIM_TimeBaseInitTypeDef TIM_T;
        NVIC_InitTypeDef NVIC_I;
       
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
       
        TIM_T.TIM_ClockDivision=TIM_CKD_DIV1;
        TIM_T.TIM_CounterMode=TIM_CounterMode_Up;
        TIM_T.TIM_Period=PERIOD;
        TIM_T.TIM_Prescaler=7199;
        //TIM_T.TIM_RepetitionCounter
        TIM_TimeBaseInit(TIM2,&TIM_T);
       
  NVIC_I.NVIC_IRQChannel=TIM2_IRQn;
        NVIC_I.NVIC_IRQChannelCmd=ENABLE;
        NVIC_I.NVIC_IRQChannelPreemptionPriority=0;
        NVIC_I.NVIC_IRQChannelSubPriority=1;
        NVIC_Init(&NVIC_I);

        TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
       
        TIM_Cmd(TIM2,ENABLE);
       
        TIM2->CR1 &= (uint16_t)(~((uint16_t)TIM_CR1_CEN));//   DISABLE
       
        TIM_ClearITPendingBit (TIM2,TIM_IT_Update);
}

void Timing_Open(void)
{
TIM2->CR1 |= TIM_CR1_CEN;//                            ENABLE
}


void Timing_Close(void)
{
TIM2->CR1 &= (uint16_t)(~((uint16_t)TIM_CR1_CEN));//   DISABLE
        t1=0;
}


void TIM2_IRQHandler(void)
{
if(TIM_GetITStatus(TIM2,TIM_IT_Update)==1)
{
  TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
         t1++;
         if(t1==10000)
         {
                 t1=0;
         }
}
}[/mw_shl_code]

最佳答案

查看完整内容[请看2#楼]

一般这样的计时方式误差在中断周期时间以内,在你的情况就是1s以内。 假设在第0秒你的t1值为0,在第1秒时刻,你的t1值为1,而当你在第1.5秒时读t1的值,其值还是1,这样你在第2秒时刻时,t1变为2,从你读取t1值得变化来看是变化了2-1= 1秒,而实际是过了500ms,所以在这样的情况下,你定10秒就会在9.5秒出结束。所以会有一个固定偏差。 当你设定中断周期为1ms的话,那偏差就会在1ms之内。时差感觉就很小了。 但你这里偏差大于1s ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

9

主题

538

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3371
金钱
3371
注册时间
2015-1-7
在线时间
794 小时
发表于 2016-8-5 16:24:41 | 显示全部楼层
一般这样的计时方式误差在中断周期时间以内,在你的情况就是1s以内。
假设在第0秒你的t1值为0,在第1秒时刻,你的t1值为1,而当你在第1.5秒时读t1的值,其值还是1,这样你在第2秒时刻时,t1变为2,从你读取t1值得变化来看是变化了2-1= 1秒,而实际是过了500ms,所以在这样的情况下,你定10秒就会在9.5秒出结束。所以会有一个固定偏差。
当你设定中断周期为1ms的话,那偏差就会在1ms之内。时差感觉就很小了。
但你这里偏差大于1s了可能还有其他类似的偏差值在里面。
机器生汇编,汇编生B,B生C,C生万物.... 经过长期对C语言的研究,目前只有两个方面不懂:这也不懂,那也不懂
https://github.com/ianhom
回复

使用道具 举报

3

主题

548

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1383
金钱
1383
注册时间
2015-2-3
在线时间
197 小时
发表于 2016-8-5 16:34:35 | 显示全部楼层
你可以调试一下(在中断服务程序加个断点)就会发现,刚刚打开中断时会自动进入一次中断,所以计数次数实际上多了1,原因和解决方法不太清楚,期待大神解答
我的解决方法就是把这个数减一……
回复

使用道具 举报

11

主题

34

帖子

0

精华

初级会员

Rank: 2

积分
105
金钱
105
注册时间
2016-2-19
在线时间
19 小时
 楼主| 发表于 2016-8-5 16:57:12 | 显示全部楼层
yyx112358 发表于 2016-8-5 16:34
你可以调试一下(在中断服务程序加个断点)就会发现,刚刚打开中断时会自动进入一次中断,所以计数次数实际 ...

看三楼
回复

使用道具 举报

11

主题

34

帖子

0

精华

初级会员

Rank: 2

积分
105
金钱
105
注册时间
2016-2-19
在线时间
19 小时
 楼主| 发表于 2016-8-5 16:59:13 | 显示全部楼层
ianhom 发表于 2016-8-5 16:43
一般这样的计时方式误差在中断周期时间以内,在你的情况就是1s以内。
假设在第0秒你的t1值为0,在第1秒时 ...

感觉2楼跟3楼的答案是不是就是正好对上了我定时器的偏差。。。
回复

使用道具 举报

9

主题

538

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3371
金钱
3371
注册时间
2015-1-7
在线时间
794 小时
发表于 2016-8-5 17:30:39 | 显示全部楼层
123军 发表于 2016-8-5 16:59
感觉2楼跟3楼的答案是不是就是正好对上了我定时器的偏差。。。

恩,才发现你会关定时器的中断。
我一般不会去启动和关闭这个中断,这个t1会自己不断++,作为一个free running的clock,每次开始计时的时候记录一个t1值,在检查的时候再次检查一个t1值,这样两次的差值就是时间差(不用担心 1-65535的情况,会借位计算差值)。楼主可以试试这个方法,看看误差是不是就会落在0~1秒之间,
机器生汇编,汇编生B,B生C,C生万物.... 经过长期对C语言的研究,目前只有两个方面不懂:这也不懂,那也不懂
https://github.com/ianhom
回复

使用道具 举报

11

主题

34

帖子

0

精华

初级会员

Rank: 2

积分
105
金钱
105
注册时间
2016-2-19
在线时间
19 小时
 楼主| 发表于 2016-8-7 19:35:30 | 显示全部楼层
ianhom 发表于 2016-8-5 17:30
恩,才发现你会关定时器的中断。
我一般不会去启动和关闭这个中断,这个t1会自己不断++,作为一个free r ...

经实验,此方法有效,误差在1s内。但是,不方便。
还是搞不懂少了的那1s去哪了,万一以后遇到需要精确定时的时候就麻烦了
回复

使用道具 举报

9

主题

538

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3371
金钱
3371
注册时间
2015-1-7
在线时间
794 小时
发表于 2016-8-7 19:41:28 | 显示全部楼层
123军 发表于 2016-8-7 19:35
经实验,此方法有效,误差在1s内。但是,不方便。
还是搞不懂少了的那1s去哪了,万一以后遇到需要精确定 ...

。。。那1s就是三楼说的原因啊。。。。。。。。。
机器生汇编,汇编生B,B生C,C生万物.... 经过长期对C语言的研究,目前只有两个方面不懂:这也不懂,那也不懂
https://github.com/ianhom
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-5 11:23

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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