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

Tru*_*nyx 1 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
}
Run Code Online (Sandbox Code Playgroud)

我希望如果设置预分频器,该计数会降低。但是,我总是得到相同的值。例如,循环1326。

Col*_*lin 8

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

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

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

  • XOR运算符会更努力地向后射击。示例:您的“ timer_stop();”将在偶然被两次调用时“启动”计时器。 (5认同)