简体   繁体   English

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

[英]Cortex-M0+ timer prescaler is not slowing down TIM2

I am trying to measure the performance of some code using the TIM2 timer on the STM32L031K6 (Cortex-M0+). 我正在尝试使用STM32L031K6(Cortex-M0 +)上的TIM2计时器来评估某些代码的性能。 Because the M0+ only offers 16-bit counters, I want to set the prescaler of TIM2 to count slower. 由于M0 +仅提供16位计数器,因此我想将TIM2的预分频器设置为较慢的计数。 However, it seems to show no effect at all. 但是,似乎完全没有效果。 The timer still runs at maximum speed, which is not desirable for my use case. 计时器仍以最大速度运行,这对于我的用例而言并不理想。

I used libopencm3 before, but now I am writing to the registers directly via pointers, because I won't have access to libopencm3 afterwards anyways. 我以前使用过libopencm3,但是现在我直接通过指针写入寄存器,因为无论如何我以后都无法访问libopencm3。 I looked through the datasheet of the STM32L0 series and read how to set up the timers directly. 我浏览了STM32L0系列的数据表,并了解了如何直接设置定时器。 Setting up the timer and measuring some small code code (for loop with nops) works perfectly. 设置计时器并测量一些小的代码(适用于带nops的循环)非常有效。 But setting the prescaler won't work. 但是设置预分频器将不起作用。 I wrote the value (for example 0x1234) to the prescale register and read it again to make sure the write actually worked. 我将值(例如0x1234)写入了预分频寄存器,然后再次读取该值,以确保写入操作确实有效。 I tried to trigger the update event, because it seems some buffering is going on with shadow registers but it also didn't work. 我试图触发更新事件,因为似乎影子寄存器正在进行某些缓冲,但它也没有起作用。

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
}

I expected that the count is lower if I set a prescaler. 我希望如果设置预分频器,该计数会降低。 However, I always get the same value. 但是,我总是得到相同的值。 For example 1326 for a loop of nops. 例如,循环1326。

You need to generate an update event, you can do this by setting bit 0 of the timer's EGR register. 您需要生成一个更新事件,可以通过将计时器的EGR寄存器的位0设置为该事件。

Your two lines where you've commented "I tried triggering an update here", you're using the ^= operator, to set bits in a register use |= instead. 在注释了“我尝试在此处触发更新”的两行中,您使用的是^=运算符,而是使用|=来设置寄存器中的位。

You should also use the human readable defines provided by ST for the registers and their addresses. 对于寄存器及其地址,还应使用ST提供的可读定义。 This will allow you to write something like TIM2->EGR |= TIM_EGR_UG; 这将使您可以编写类似TIM2->EGR |= TIM_EGR_UG; to generate your update event, much more readable than *( (uint32_t*) 0x40000014 ) |= 1; 生成更新事件,比*( (uint32_t*) 0x40000014 ) |= 1;更可读

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM