Cortex-M0 +定时器预分频器不会降低TIM2的速度

时间:2019-07-11 07:49:51

标签: c assembly timer stm32 cortex-m

我正在尝试使用STM32L031K6(Cortex-M0 +)上的TIM2计时器来测量某些代码的性能。 由于M0 +仅提供16位计数器,因此我想将TIM2的预分频器设置为较慢的计数。但是,似乎完全没有效果。计时器仍以最大速度运行,这对于我的用例来说是不希望的。

我以前使用过libopencm3,但是现在我直接通过指针写入寄存器,因为无论如何我以后将无法访问libopencm3。 我浏览了STM32L0系列的数据表,并了解了如何直接设置定时器。设置计时器并测量一些小的代码(适用于带nops的循环)非常有效。但是设置预分频器将不起作用。我将值(例如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,表示循环进行一次。

1 个答案:

答案 0 :(得分:7)

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

在注释了“我试图在此处触发更新”的两行中,您使用的是^=运算符,而使用|=来设置寄存器中的位。

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

更具可读性