首页 > 解决方案 > 如何在 stm32 微控制器上读取 TIMx CNT 寄存器:等号问题

问题描述

我一直在玩核板 f411RE,特别是通用定时器 TIM9、TIM10、TIM11。我想使用 TIM10(16 位定时器)通过启用它并让它运行来测量时间,然后使用存储在 TIM10->CNT 中的值通过使用 if 条件来做出决定(是否打开 LED) .

当我使用 <,>, <=, >= 运算符将计数器 (TIM10->CNT) 的值与任何其他数字进行比较时,例如:

if( (TIM10->CNT) <= 10000 ){

//do something
****actually does something****

}

甚至:

if( (TIM10->CNT) == 0 ){

/**this one with the equals sign only works when equaled to zero, any number but zero
seems to not being recognized**/

//do something
****actually does something****
}

一切都按我预期的那样工作,我的功能按照我想要的方式运行。

每当我尝试使用等号将定时器计数器寄存器与不为零的数字(表示为“任何值”)进行比较时,就会出现问题,如下所示:

if( (TIM10->CNT) == any value ){

//do something
****this block does not get executed****

}

正如上面的评论中所表达的,每当我明确使用等号 ( == ) 且数字不为零时,由该条件定义的块不会被执行。似乎我可以使用和比较 TIM10 计数器的唯一方法是使用不等式运算符(>、<、=>、>=)或将其显式与零进行比较。

到目前为止,我还没有发布实际代码,因为这是唯一困扰我的部分,所有其他组件都像魅力一样工作。无论如何,这是我的代码的一瞥:

伪代码:

--- 程序开始 ---

--- TIM10 -> CNT 初始化为零 ---

---while循环开始---

---读取 TIM10->CNT 寄存器并将其值存储在变量中---

---按下按钮启用 TIM10---

---如果在计数器已经运行时再次按下按钮,则停止计时器并将其值存储在一个变量中以用于下一个函数---

---根据经过时间的值打开或关闭 LED 的功能 TIM10 -> CNT ---

实际的 C++ 代码是:

#include <GPIO_PORT.h> //includes the class GPIO_PORT which I created to manage the register configuration when initializing a GPIO port. With this I can easily set whether a pin is an input or an output and many other things as writing and reading to it.

int main(void){

  uint32_t time_value;

  GPIO_PORT led('A',5,0); //GPIO_PORT object that configures and initializes PORTA 5 pin as output pin.
  GPIO_PORT boton('C',13,1);//GPIO_PORT object that configures and initializes PORTC 13 pin as an input pin for the push button

  system_config(); //function that configures the clock source, pll, and all the system clock selection and configuration related registers

  /*here starts the TIM10 configuration*/

  RCC->APB2ENR |= (1<<17);     //TIM10 clock peripheral enabled
  TIM10->PSC = 160 - 1 ;       //TIM10 preescaler needed accordingly to my calculations
  TIM10->ARR = 65535;          //value that the counter has to reach before overflow occurs. In this case the maximum possible 0xFFFF.
  TIM10->CR1 |= (1<<3);        //one pulse mode enable so the counter stops at update event generation (may it be overflowing or setting the UG bit)
  TIM10->CNT = 0;              //TIM10 counter initialized to zero
  
  while(1){
      
       //in the first iteration, the timer has not been enabled yet so it's value is zero, in following iterations, timer simply gets the value of the TIM10 counter so it can be used in the drive led function
      time_value = TIM10->CNT;

      //if time_value is zero (has not been enabled before yet) and the push button is pressed, then initializes TIM10->CNT to zero and enables start counting.
      if( (time_value == 0) & (!boton.read_pin_status()) ){
          
          TIM10->CR1 |= (1<<0);    //TIM10 counter enabled
          TIM10->CNT = 0;          //TIM10 counter placed at a value of zero
          time_value = TIM10->CNT; //need to "return" the value of the timer counter(in this case zero) in order to use it in the drive led function.

      }else if( (time_value != 0) & (!boton.read_pin_status()) ){
      
          time_value = TIM10->CNT;    //"returns" the current value of timer counter by storing it in another variable.
          TIM10->EGR |= (1<<0);     //software generated update event in order to stop the timer as well as reseting the TIM10 counter to zero.            
      }

      if(time_value == 0){

          //this block gets executed
          led.set_pin_status(0);

      }else if( (time_value < 10000) & (timer != 0)){

          //this block gets executed
          led.set_pin_status(0);

      }else if((time_value < 20000) & (timer >= 10000)){

          //this block gets executed
          led.set_pin_status(1);

      }else if((time_value < 40000) & (timer >= 20000)){

          //this block gets executed
          led.set_pin_status(0);

      }else if(time_value == 65535 ){

          //THIS BLOCK DOES NOT GETS EXECUTED NO MATTER WHAT YOU REPLACE 65535 FOR, THE FACT OF USING "==" BUGS THE BLOCK EXECUTION

          led.set_pin_status(1);
          HAL_Delay(1500);
          led.set_pin_status(0);
          HAL_Delay(1500);
          
          TIM10->EGR |= (1<<0); //since 65535 is the maximum possible value, when reaching this point, the timer counter shall be reseted to zero as well as being disabled. In one pulse mode, setting the UG bit does so.
      }

  }
}

关于为什么我不能将“==”运算符与定时器计数器寄存器一起使用的帮助和评论将不胜感激。

pd:实际上,任何评论都会受到赞赏。

pd2:有人可能会认为延迟在某种程度上干扰了最后一个 if 条件,但实际上放在那里的指令并不重要,由于“==”的使用,该块将不会执行

pd3:正如我之前所说,问题似乎是明确使用“==”,因为我已经尝试了代码的所有其他部分并且它们完美地工作(时钟配置,定时器配置,GPIO配置以及写入和读取每个相应引脚的方法)

标签: timermicrocontrollerstm32f4register-allocation

解决方案


推荐阅读