我正在尝试使用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,表示循环进行一次。
答案 0 :(得分:7)
您需要生成一个更新事件,可以通过将计时器的EGR
寄存器的位0设置来实现。
在注释了“我试图在此处触发更新”的两行中,您使用的是^=
运算符,而使用|=
来设置寄存器中的位。
对于寄存器及其地址,还应使用ST提供的可读定义。这将使您可以编写类似于TIM2->EGR |= TIM_EGR_UG;
的东西来生成更新事件,比*( (uint32_t*) 0x40000014 ) |= 1;