搜索
ST MCU Finder
安装免费手机应用,
寻找理想的ST MCU

[STM32L0] 请教,关于LL库定时中断时间不准问题

[复制链接]
104|8
 楼主 | 2020-9-25 11:43 | 显示全部楼层 |阅读模式
LL库定时器配置不准问题请教,程序如下,实际用示波器测出来的定时时间值为960ms(测试时发现:如果 LL_TIM_InitStruct.Prescaler = 20时,计时正常的1s,但是改成200,计时又不是准确的10s,实测9秒多),看到这个贴的麻烦看看哪里出了问题?先谢谢了!

//初始化
void  Configure_TIMTimeBase(void)
{
       
  LL_TIM_InitTypeDef LL_TIM_InitStruct = {0};
  /* Enable the timer peripheral clock */
  LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2);        

  LL_TIM_InitStruct.Prescaler = 19;
  LL_TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
  LL_TIM_InitStruct.Autoreload = 9999;
  LL_TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
       
        LL_TIM_Init(TIM2, &LL_TIM_InitStruct);
       
        LL_TIM_DisableARRPreload(TIM2);
        LL_TIM_SetClockSource(TIM2,LL_TIM_CLOCKSOURCE_INTERNAL);
        LL_TIM_SetTriggerOutput(TIM2,LL_TIM_TRGO_RESET);
        LL_TIM_DisableMasterSlaveMode(TIM2);
       
       
        /* Configure the NVIC to handle TIM2 update interrupt */
        NVIC_SetPriority(TIM2_IRQn, 0);
        NVIC_EnableIRQ(TIM2_IRQn);
        LL_TIM_EnableIT_UPDATE(TIM2);
       
        LL_TIM_EnableCounter(TIM2);

       
}
//中断
void TIM2_IRQHandler(void)
{
        static uint8_t cntSysTick=0;
  if(LL_TIM_IsActiveFlag_UPDATE(TIM2) != RESET)
  {
    /* Clear the update interrupt flag*/
    LL_TIM_ClearFlag_UPDATE(TIM2);
                cntSysTick++;                                       
                if(cntSysTick >= 10)
                {
                                cntSysTick -= 10;
                                tim2_flag=1;
                }
  }
}

//主函数
int main(void)
{

  SystemClock_Config();  //2M系统时钟频率

  SysTick_Config(SystemCoreClock / 1000);   
       
  Configure_TIMTimeBase();
       


       
        while (1)  
  {
                  if(tim2_flag==1)      //想实现1秒置位一次
                        {
                                tim2_flag=0;
                          LL_GPIO_TogglePin(GPIOA,LL_GPIO_PIN_3);//翻转
                        }


使用特权

评论回复
| 2020-9-25 13:39 | 显示全部楼层
你直接在中断服务函数里翻转GPIO啊,放到main里肯定被延迟了,中断里判断完10次立刻翻转,清标志位什么的放在后面执行

使用特权

评论回复
 楼主 | 2020-9-25 13:48 | 显示全部楼层
sonicll 发表于 2020-9-25 13:39
你直接在中断服务函数里翻转GPIO啊,放到main里肯定被延迟了,中断里判断完10次立刻翻转,清标志位什么的放 ...

应该不是这个问题,这个运行的时间很短的,实际按你的方法操作后,基本没什么变化。

使用特权

评论回复
| 2020-9-25 13:59 | 显示全部楼层
本帖最后由 sonicll 于 2020-9-25 14:00 编辑

那就检查系统时钟,晶振,看看频率准不准,还有你的systick中断是否会抢断TIM2的中断,systick中断服务函数里是否有耗时的操作

使用特权

评论回复
 楼主 | 2020-9-25 15:00 | 显示全部楼层
sonicll 发表于 2020-9-25 13:59
那就检查系统时钟,晶振,看看频率准不准,还有你的systick中断是否会抢断TIM2的中断,systick中断服务函数 ...

systick耗时很短,把systick中断程序屏蔽后(相当于不进入systick中断),实验结果没改善。调用   LL_RCC_ClocksTypeDef  RCC_Clocks;  LL_RCC_GetSystemClocksFreq(&RCC_Clocks);查看系统时钟频率设置为0x00200000,即2M。使用的是MSI晶振,至于准不准确怎么判断?

使用特权

评论回复
| 2020-9-25 15:04 | 显示全部楼层
雪海 发表于 2020-9-25 15:00
systick耗时很短,把systick中断程序屏蔽后(相当于不进入systick中断),实验结果没改善。调用   LL_RCC ...

STM32F1系列是可以通过PA8管脚把晶振信号输出出来的,可以示波器查看频率,L0系列我不知道有没有这个功能

使用特权

评论回复
| 2020-9-25 15:58 | 显示全部楼层
本帖最后由 香水城 于 2020-9-25 16:00 编辑

首先要保证时钟源尽量精准,再就是配置方面的问题了。
看你的配置没啥问题,注意那些从0开始计算的小细节。

具体到你这里,还跟你的用法也有关系。 你跑到Main里通过
GPIO翻转都是会导致误差的。

你用MSI RC振荡时钟的话,它在全温度范围内的偏差在正负3%。

它也可以通过MCO脚引出来查看。

使用特权

评论回复
 楼主 | 2020-9-25 16:38 | 显示全部楼层
sonicll 发表于 2020-9-25 15:04
STM32F1系列是可以通过PA8管脚把晶振信号输出出来的,可以示波器查看频率,L0系列我不知道有没有这个功能 ...

确实是晶振的精度问题,实测出来2.1072M,结合我之前的测试,理论上也符合现象。

使用特权

评论回复
 楼主 | 2020-9-25 16:40 | 显示全部楼层
香水城 发表于 2020-9-25 15:58
首先要保证时钟源尽量精准,再就是配置方面的问题了。
看你的配置没啥问题,注意那些从0开始计算的小细节。 ...

是的,MSI时钟晶振偏差的问题导致的,实测出来的晶振频率跟表现的现象一致。

使用特权

评论回复
扫描二维码,随时随地手机跟帖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

我要发帖 投诉建议 创建版块 申请版主

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式

论坛热帖

在线客服 快速回复 返回顶部 返回列表