I've been toying around with nucleo board f411RE, specifically the general purpose timers TIM9,TIM10,TIM11. I wanted to use TIM10 (16 bits timer) to measure time by just enabling it and letting it run, then use the value stored in TIM10->CNT to make a decision (whether or not turn on a led) by using an if condition.
When I compare the value of the counter (TIM10->CNT) with any other number while using <,>, <=, >= operators like:
if( (TIM10->CNT) <= 10000 ){
//do something
****actually does something****
}
or even:
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****
}
everything works as I expect it to do, my function behaves just the way I want.
The problem, as so the protagonist of this post, arises whenever I try to use the equal sign to compare the timer counter register with a number different than zero (expressed as 'any value') as the following statement:
if( (TIM10->CNT) == any value ){
//do something
****this block does not get executed****
}
As expressed in the comment above, whenever I use explicitly the equal sign ( == ) with a number not being zero, the block defined by that condition does not get executed. Seems like the only way in which I can use and compare TIM10 counter is when using the inequality operator (>, <, => , >= ) or when comparing it explicitly to zero.
up to this point I have not posted the actual code since this is the only part bugging me, all of the other components are working like a charm. Anyways, here is a glimpse of my code:
pseudocode:
--- program starts ---
--- TIM10 -> CNT initialized to zero ---
---while loop starts---
---read TIM10->CNT register and store its value in a variable---
---TIM10 enabled by pushing a button---
---if button is pressed again while the counter is already running, then stop the timer counter and store it's value in a variable to be used in the next function---
---function that turns ON or OFF a led depending on the value of the elapsed time TIM10 -> CNT ---
the actual c++ code is:
#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.
}
}
}
help and comments on why cant I use the "==" operator in conjunction with the timer counter register will be appreciated.
pd: any comment will be appreciated actually.
pd2: one might think that the delay is somehow bugging the last if condition but actually it does not matter what instruction is placed there, that block will just not execute due to the "==" usage
pd3: as I said earlier, the problems seems to be explicitly the use of "==" since I have tried all the other parts of the code and they work flawlessly (the clock configuration, the timer configuration, the GPIO configuration as well as the methods to write and read into each corresponding pin)
You are checking the value of a 16-bit timer that is updating continuously. The chances that the particular value you are looking for occur at the exact moment you are looking is 1 in 65535... ie pretty remote.
If you need something to happen exactly when a timer reaches a particular value, you need to generate an interrupt when the timer reaches that value, then take the appropriate action in the interrupt routine.