首页 > 解决方案 > Cortex-M0+ 定时器预分频器不会减慢 TIM2

问题描述

我正在尝试使用 STM32L031K6 (Cortex-M0+) 上的 TIM2 定时器来测量一些代码的性能。因为 M0+ 只提供 16 位计数器,所以我想将 TIM2 的预分频器设置为计数更慢。但是,它似乎根本没有任何效果。计时器仍然以最大速度运行,这对我的用例来说是不可取的。

我以前使用过 libopencm3,但现在我直接通过指针写入寄存器,因为无论如何我都无法访问 libopencm3。我查看了 STM32L0 系列的数据表,并阅读了如何直接设置定时器。设置计时器并测量一些小代码(带有 nops 的 for 循环)效果很好。但是设置预分频器不起作用。我将值(例如 0x1234)写入预分频寄存器并再次读取以确保写入确实有效。我试图触发更新事件,因为影子寄存器似乎正在进行一些缓冲,但它也不起作用。

void __attribute__ ((noinline)) timer_setup()
{
  *(  (uint32_t*) 0x40021038 ) |= 1; //Enable Timer in RCC_APB1ENR (Bit 0)

  *(  (uint32_t*) 0x40000028 ) = 0x1234; //Some prescaler

  *(  (uint32_t*) 0x4000002C ) = 0xFFFF; //Auto-Reload to max 2**16

  // *(  (uint32_t*) 0x40000000 ) ^= 2; //I tried triggering an update here

  // *(  (uint32_t*) 0x40000014 ) ^= 1; //But it also didn't work

  *(  (uint32_t*) 0x40000000 ) ^= 1; //Enable the timer
}

void __attribute__ ((noinline)) timer_stop()
{
  *(  (uint32_t*) 0x40000000 ) ^= 1; //Stop the timer
}

int __attribute__ ((noinline)) timer_value()
{
  return *(  (uint32_t*) 0x40000024 ); //Read the counter
}

如果我设置一个预分频器,我预计计数会更低。但是,我总是得到相同的值。例如 1326 表示 nops 循环。

标签: cassemblytimerstm32cortex-m

解决方案


您需要生成一个更新事件,您可以通过设置定时器EGR寄存器的位 0 来实现。

您评论“我尝试在此处触发更新”的两行,您正在使用^=运算符来设置寄存器使用中的位|=

您还应该使用 ST 为寄存器及其地址提供的人类可读定义。这将允许您编写类似TIM2->EGR |= TIM_EGR_UG;生成更新事件的东西,比*( (uint32_t*) 0x40000014 ) |= 1;


推荐阅读