468|16

1万

帖子

15

资源

版主

STM32F030C8T6的定时器怎么不准[问题解决:附解决方法] [复制链接]

 
本帖最后由 ddllxxrr 于 2021-2-6 09:11 编辑

我用STM32F030C8T6我用定时器延时,SYSTICK想给别的用比如OS,反正留用。

我在初使化的时候我已经把APB时钟2分频别的地方要用。

 if (HSEStatus == (uint32_t)0x01)
  {
    /* Enable Prefetch Buffer and set Flash Latency */
    FLASH->ACR = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY;
 
    /* HCLK = SYSCLK */
    RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
      
    /* PCLK = HCLK */
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE_DIV2;  //    //24MHZ

    /* PLL configuration = HSE * 6 = 48 MHz */
    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));
    RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLMULL6);   
            
    /* Enable PLL */
    RCC->CR |= RCC_CR_PLLON;

我的延时程序如下:

void TIM_Config(void)
{
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    /* TIM3 clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
  /* Compute the prescaler value */
  PrescalerValue = (uint16_t) (SystemCoreClock  / 1000000) - 1;
  /* Time base configuration */
  TIM_TimeBaseStructure.TIM_Period = 1;  //1 u second
  TIM_TimeBaseStructure.TIM_Prescaler = 23;//PrescalerValue;
  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Down;
  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
  TIM_Cmd(TIM3, DISABLE);
}

void TimeDelay1us(uint16_t Times)
{
  TIM3->CR1 |= TIM_CR1_CEN;  //启动定时器
  while(Times--)
  {
     while((TIM3->SR & TIM_FLAG_Update) == RESET);
         TIM3->SR &= ~TIM_FLAG_Update;
  }
   TIM3->CR1 &= ~TIM_CR1_CEN;  //关闭定时器
}

void Delay(uint16_t Times1)
{
        uint16_t dd,count;
        for(count=0;count<Times1;count++)
        {
             for(dd=1;dd<1000;dd++)
             TimeDelay1us(1);
        }        
        
}

void delay_us(uint16_t Times2)
{
          uint16_t count;
        for(count=0;count<Times2;count++)
        {
              TimeDelay1us(1);
        }        
}

void delay_ms(uint16_t Times3)
{
          uint16_t count;
          for(count=0;count<Times3;count++)
          Delay(1);
}

我运行了一下,怎么将4秒,而我定时是1秒。而且好像我改变参数时间并不变求解。

 

 

方法在16楼

此帖出自stm32/stm8论坛
个人签名http://shop34182318.taobao.com/
https://shop436095304.taobao.com/?spm=a230r.7195193.1997079397.37.69fe60dfT705yr

回复

91

帖子

0

资源

一粒金砂(中级)

TIM_TimeBaseStructure.TIM_Period = 1;  //1 u second   

TIM_TimeBaseStructure.TIM_Prescaler = 23;//PrescalerValue;

 

这两行是不是有点问题

点评

就是1U秒延时。 后边23是PrescalerValue = (uint16_t) (SystemCoreClock / 1000000) - 1; 的结果,因为2分频,所以48/2=24  详情 回复 发表于 2021-2-4 15:06

回复

1万

帖子

133

资源

管理员

楼主问题解决了吗?

点评

没我觉得不是一般地难  详情 回复 发表于 2021-2-4 15:07
个人签名

玩板看这里:

http://bbs.eeworld.com.cn/elecplay.html

EEWorld测评频道众多好板等你来玩,还可以来频道许愿树许愿说说你想要玩的板子,我们都在努力为大家实现!


回复

1万

帖子

15

资源

版主

Ansersion 发表于 2021-2-4 10:26 TIM_TimeBaseStructure.TIM_Period = 1;  //1 u second    TIM_TimeBaseStructure. ...

就是1U秒延时。

后边23是PrescalerValue = (uint16_t) (SystemCoreClock / 1000000) - 1;

的结果,因为2分频,所以48/2=24

个人签名http://shop34182318.taobao.com/
https://shop436095304.taobao.com/?spm=a230r.7195193.1997079397.37.69fe60dfT705yr

回复

1万

帖子

15

资源

版主

okhxyyo 发表于 2021-2-4 10:47 楼主问题解决了吗?

没我觉得不是一般地难

个人签名http://shop34182318.taobao.com/
https://shop436095304.taobao.com/?spm=a230r.7195193.1997079397.37.69fe60dfT705yr

回复

795

帖子

2

资源

版主

会不会是外部时钟的锅?

点评

外部时钟8MHZ,这个还没考虑,等我查查  详情 回复 发表于 2021-2-4 18:55

回复

1万

帖子

15

资源

版主

w494143467 发表于 2021-2-4 16:59 会不会是外部时钟的锅?

外部时钟8MHZ,这个还没考虑,等我查查

点评

我觉得需要先排除硬件问题,再去找软件的问题。  详情 回复 发表于 2021-2-4 19:29
个人签名http://shop34182318.taobao.com/
https://shop436095304.taobao.com/?spm=a230r.7195193.1997079397.37.69fe60dfT705yr

回复

795

帖子

2

资源

版主

ddllxxrr 发表于 2021-2-4 18:55 外部时钟8MHZ,这个还没考虑,等我查查

我觉得需要先排除硬件问题,再去找软件的问题。

点评

硬件应没问题,网上也有反应定时不准,但我不明白是怎么解决地  详情 回复 发表于 2021-2-4 20:10

回复

1万

帖子

15

资源

版主

w494143467 发表于 2021-2-4 19:29 我觉得需要先排除硬件问题,再去找软件的问题。

硬件应没问题,网上也有反应定时不准,但我不明白是怎么解决地,还是说这块是个BUG

个人签名http://shop34182318.taobao.com/
https://shop436095304.taobao.com/?spm=a230r.7195193.1997079397.37.69fe60dfT705yr

回复

287

帖子

2

资源

版主

第一个,你看一下TIM3的总线时钟频率是多少,这个至关重要。

第二个,TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;这个不是1分频吗?

第三个,计数模式你改为向上计数

个人签名

没有什么不可以,我就是我,不一样的烟火! 


回复

19

帖子

0

资源

一粒金砂(初级)

030我批量用过,定时器没问题啊


回复

287

帖子

2

资源

版主

参考一些这个代码

//通用定时器3中断初始化
//这里时钟选择为APB1的2倍,而APB1为36M
//arr:自动重装值。
//psc:时钟预分频数
//这里使用的是定时器3!
void TIM3_Int_Init(u16 arr,u16 psc)
{
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能

    TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值     计数到5000为500ms
    TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值  10Khz的计数频率
    TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位

    TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断

    NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中断
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
    NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器

    TIM_Cmd(TIM3, ENABLE);  //使能TIMx外设

}
//定时器3中断服务程序
void TIM3_IRQHandler(void)   //TIM3中断
{
    if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
        {
        TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  //清除TIMx的中断待处理位:TIM 中断源
        LED1=!LED1;
        }
}

 

个人签名

没有什么不可以,我就是我,不一样的烟火! 


回复

287

帖子

2

资源

版主

楼主,我知道你的问题了。

//arr:自动重装值。 。 psc:时钟预分频数 

//定时器溢出间计算方法  :Tout=((arr+1)*(psc+1))/Ft us. //Ft=定时器工作频率单位 :Mhz

根据你的程序,

  • TIM_TimeBaseStructure.TIM_Period = 1; //1 u second
  • TIM_TimeBaseStructure.TIM_Prescaler = 23;//PrescalerValue

所以,Tout=((arr+1)*(psc+1))/Ft=(TIM_Period +1)*(TIM_Prescaler+1)/24000000 = (1+1)*(23+1)/24000000=2us。

再根据你的计数值可以看出,定时是4s。一定是这个问题,你可以自己测试,我已经测试过了

点评

谢谢,找到了毛病  详情 回复 发表于 2021-2-6 09:01
个人签名

没有什么不可以,我就是我,不一样的烟火! 


回复

1万

帖子

133

资源

管理员

看看这个贴:

STM32定时器(自动重装)经验分享

http://bbs.eeworld.com.cn/thread-1156637-1-1.html

个人签名

玩板看这里:

http://bbs.eeworld.com.cn/elecplay.html

EEWorld测评频道众多好板等你来玩,还可以来频道许愿树许愿说说你想要玩的板子,我们都在努力为大家实现!


回复

1万

帖子

15

资源

版主

annysky2012 发表于 2021-2-5 13:50 楼主,我知道你的问题了。 //arr:自动重装值。 。 psc:时钟预分频数  //定时器溢出间计算方法 ...

谢谢,找到了毛病

个人签名http://shop34182318.taobao.com/
https://shop436095304.taobao.com/?spm=a230r.7195193.1997079397.37.69fe60dfT705yr

回复

1万

帖子

15

资源

版主

谢谢annysky2012帮忙找到了毛病。其实如果我设为零是不能运行地。所以设为1,就这样自已挖个坑,自已进去了,而且还大呼小叫地让人帮忙。

我的这种延时是不用中断地,这样就费了时间,也就是说你想延1000MS是写1000而底层的那个函数延2US得写350。

改后程序如下:


void TIM_Config(void)
{
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    /* TIM3 clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
  /* Compute the prescaler value */
  PrescalerValue = (uint16_t) (SystemCoreClock  / 1000000) - 1;
  /* Time base configuration */
  TIM_TimeBaseStructure.TIM_Period = 1;  //2 u second
  TIM_TimeBaseStructure.TIM_Prescaler = 23;//PrescalerValue;
  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Down;
  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
  TIM_Cmd(TIM3, DISABLE);
}

void TimeDelay2us(uint16_t Times)
{
  TIM3->CR1 |= TIM_CR1_CEN;  //启动定时器
  while(Times--)
  {
     while((TIM3->SR & TIM_FLAG_Update) == RESET);
     TIM3->SR &= ~TIM_FLAG_Update;
  }
   TIM3->CR1 &= ~TIM_CR1_CEN;  //关闭定时器
}

void Delay(uint16_t Times1)
{
    uint16_t dd,count;
    for(count=0;count<Times1;count++)
    {
         for(dd=0;dd<350;dd++)  //必须延这么多才到1秒
         TimeDelay2us(1);
    }    
    
}

void delay_us(uint16_t Times2)   //2倍
{
      uint16_t count;
    for(count=0;count<Times2;count++)
    {
          TimeDelay2us(1);
    }    
}

void delay_ms(uint16_t Times3)
{
      uint16_t count;
      for(count=0;count<Times3;count++)
      Delay(1);
}

点评

找到就行,一般要看一下寄存器或者仿真。  详情 回复 发表于 2021-2-6 11:50
个人签名http://shop34182318.taobao.com/
https://shop436095304.taobao.com/?spm=a230r.7195193.1997079397.37.69fe60dfT705yr

回复

287

帖子

2

资源

版主

ddllxxrr 发表于 2021-2-6 09:10 谢谢annysky2012帮忙找到了毛病。其实如果我设为零是不能运行地。所以设为1,就这样自已挖个坑,自已进去了 ...

找到就行,一般要看一下寄存器或者仿真。

个人签名

没有什么不可以,我就是我,不一样的烟火! 


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

最新文章 更多>>
    关闭
    站长推荐上一条 1/6 下一条

    About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

    站点相关: 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

    北京市海淀区知春路23号集成电路设计园量子银座1305 电话:(010)82350740 邮编:100191

    电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2021 EEWORLD.com.cn, Inc. All rights reserved
    快速回复 返回顶部 返回列表