'Timer2' was not declared in this scope

Post here first, or if you can't find a relevant section!
Post Reply
leonardo
Posts: 18
Joined: Sat Mar 06, 2021 2:37 pm

'Timer2' was not declared in this scope

Post by leonardo »

I encountered this problem when compiling this code,
'Timer2' was not declared in this scope.
I tried for a day and still not resolved. :cry:

PLATFORM: ST STM32 (8.0.0)> ST Nucleo F446RE
HARDWARE: STM32F446RET6 180MHz, 128KB RAM, 512KB Flash

Code: Select all

#include "Arduino.h"
int32_t channel_1_start, channel_1_stop, channel_1;

void handler_channel_1(void) {
  if (0b1 & GPIOB ->IDR) {
    channel_1_start = TIM2->CCR1;
    TIM2->CCER |= TIM_CCER_CC1P;
  }
  else {
    channel_1 = TIM2->CCR1 - channel_1_start;
    if (channel_1 < 0)channel_1 += 0xFFFF;
    TIM2->CCER &= ~TIM_CCER_CC1P;
  }
}

void setup() {
  Serial.begin(9600);
  pinMode(PA0, INPUT);
  delay(250);
  Timer2.attachCompare1Interrupt(handler_channel_1);
  TIM2->CR1 = TIM_CR1_CEN;
  TIM2->CR2 = 0;
  TIM2->SMCR = 0;
  TIM2->DIER = TIM_DIER_CC1IE;
  TIM2->EGR = 0;
  TIM2->CCMR1 = TIM_CCMR1_CC1S_1;
  TIM2->CCMR2 = 0;
  TIM2->CCER = TIM_CCER_CC1E;
  TIM2->PSC = 71;
  TIM2->ARR = 0xFFFF;
  TIM2->DCR = 0;
}

void loop() {
  delay(1000);
  Serial.println(channel_1);
}

Code: Select all

src/main.cpp: In function 'void setup()':
src/main.cpp:20:3: error: 'Timer2' was not declared in this scope
   20 |   Timer2.attachCompare1Interrupt(handler_channel_1);
      |   ^~~~~~
*** [.pio/build/nucleo_f446re/src/main.cpp.o] Error 1
Thanks.
ag123
Posts: 1657
Joined: Thu Dec 19, 2019 5:30 am
Answers: 25

Re: 'Timer2' was not declared in this scope

Post by ag123 »

do note that the api specs for HardwareTimer in the official stm core is different from that in libmaple
https://github.com/stm32duino/wiki/wiki ... er-library
did you try

Code: Select all

  void attachInterrupt(callback_function_t callback);
instead?
another thing is

Code: Select all

#include <HardwareTimer.h>
right at the beginning to see if it helps
User avatar
fpiSTM
Posts: 1746
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 91
Location: Le Mans
Contact:

Re: 'Timer2' was not declared in this scope

Post by fpiSTM »

Main issue is that Timer2 is not declated.
See the examples.
ag123
Posts: 1657
Joined: Thu Dec 19, 2019 5:30 am
Answers: 25

Re: 'Timer2' was not declared in this scope

Post by ag123 »

in addition use the 'correct' (i.e. official) core.
https://github.com/stm32duino/Arduino_Core_STM32
it may be feasible to use 'libmaple', but that this isn't one of the pre-defined boards
https://github.com/rogerclarkmelbourne/ ... 4/variants
which means u'd need to figure out how to set the clocks, which is more 'advanced' than more newbies are willing to meddle with

these posts are relevant if you have not reviewed them
viewtopic.php?f=2&t=301
viewtopic.php?f=2&t=3
leonardo
Posts: 18
Joined: Sat Mar 06, 2021 2:37 pm

Re: 'Timer2' was not declared in this scope

Post by leonardo »

ag123 wrote: Sun Mar 07, 2021 4:51 pm do note that the api specs for HardwareTimer in the official stm core is different from that in libmaple
https://github.com/stm32duino/wiki/wiki ... er-library
did you try

Code: Select all

  void attachInterrupt(callback_function_t callback);
instead?
another thing is

Code: Select all

#include <HardwareTimer.h>
right at the beginning to see if it helps
yeah,I have tried but it still doesn't work.
leonardo
Posts: 18
Joined: Sat Mar 06, 2021 2:37 pm

Re: 'Timer2' was not declared in this scope

Post by leonardo »

ag123 wrote: Sun Mar 07, 2021 5:31 pm in addition use the 'correct' (i.e. official) core.
https://github.com/stm32duino/Arduino_Core_STM32
it may be feasible to use 'libmaple', but that this isn't one of the pre-defined boards
https://github.com/rogerclarkmelbourne/ ... 4/variants
which means u'd need to figure out how to set the clocks, which is more 'advanced' than more newbies are willing to meddle with

these posts are relevant if you have not reviewed them
viewtopic.php?f=2&t=301
viewtopic.php?f=2&t=3
My motherboard is Nucleo F446RE, the default is Arduino_Core_STM32 core, and I cannot use libmaple due to network problems.
I made some modifications to the code so that the code can be compiled in the Arduino_Core_STM32 core,
But I don’t know how to modify "Timer2.attachCompare1Interrupt(handler_channel_1);"mistake

Modified code

Code: Select all

#include <Arduino.h>
int32_t channel_1_start, channel_1_stop, channel_1;

void handler_channel_1(void) {
  if (0b1 & GPIOA->IDR) {
    channel_1_start = TIM2->CCR1;
    TIM2->CCER |= TIM_CCER_CC1P;
  }
  else {
    channel_1 = TIM2->CCR1 - channel_1_start;
    if (channel_1 < 0)channel_1 += 0xFFFF;
    TIM2->CCER &= ~TIM_CCER_CC1P;
  }
}

void setup() {
  Serial.begin(57600);
  pinMode(PA0, INPUT);
  delay(250);

  Timer2.attachCompare1Interrupt(handler_channel_1);
  TIM2->CR1 = TIM_CR1_CEN;
  TIM2->CR2 = 0;
  TIM2->SMCR = 0;
  TIM2->DIER = TIM_DIER_CC1IE;
  TIM2->EGR = 0;
  TIM2->CCMR1 = TIM_CCMR1_IC1PSC;
  TIM2->CCMR2 = 0;
  TIM2->CCER = TIM_CCER_CC1E;
  TIM2->PSC = 71;
  TIM2->ARR = 0xFFFF;
  TIM2->DCR = 0;
}

void loop() {
  delay(1000);
  Serial.println(channel_1);
}

mlundin
Posts: 94
Joined: Wed Nov 04, 2020 1:20 pm
Answers: 6
Location: Sweden

Re: 'Timer2' was not declared in this scope

Post by mlundin »

Dont try to modify the code written for another core. Take a look at the Timer documentation for the stm32duino core
https://github.com/stm32duino/wiki/wiki ... y#Examples
The InputCapture.ino example should help with configuring timers and attaching an input capture interrupt.
ag123
Posts: 1657
Joined: Thu Dec 19, 2019 5:30 am
Answers: 25

Re: 'Timer2' was not declared in this scope

Post by ag123 »

@leonardo

i tried modifying the codes you've posted as follows

Code: Select all

int32_t channel_1_start, channel_1_stop, channel_1;
void handler_channel_1(void);

void handler_channel_1(void) {
  if (0b1 & GPIOA->IDR) {
    channel_1_start = TIM2->CCR1;
    TIM2->CCER |= TIM_CCER_CC1P;
  }
  else {
    channel_1 = TIM2->CCR1 - channel_1_start;
    if (channel_1 < 0)channel_1 += 0xFFFF;
    TIM2->CCER &= ~TIM_CCER_CC1P;
  }
}

HardwareTimer *pTimer2 = new HardwareTimer(TIM2);

void setup() {
  Serial.begin(57600);
  pinMode(PA0, INPUT);
  delay(250);

  pTimer2->attachInterrupt(1, handler_channel_1);
  //Timer2.attachCompare1Interrupt(handler_channel_1);
  TIM2->CR1 = TIM_CR1_CEN;
  TIM2->CR2 = 0;
  TIM2->SMCR = 0;
  TIM2->DIER = TIM_DIER_CC1IE;
  TIM2->EGR = 0;
  TIM2->CCMR1 = TIM_CCMR1_IC1PSC;
  TIM2->CCMR2 = 0;
  TIM2->CCER = TIM_CCER_CC1E;
  TIM2->PSC = 71;
  TIM2->ARR = 0xFFFF;
  TIM2->DCR = 0;
}

void loop() {
	delay(1000);
	Serial.println(channel_1);
}
the codes actually compiles but that i'm not sure if at all what it does.
the main additions are i defined

Code: Select all

HardwareTimer *pTimer2 = new HardwareTimer(TIM2);
^ note it is a pointer, not an object

then i called attach interrupt this way

Code: Select all

  pTimer2->attachInterrupt(1, handler_channel_1);
that is based on hints described in the api
https://github.com/stm32duino/wiki/wiki ... er-library

but really, the codes that you have posted made many direct register access, e.g. configures the timers
i've not deciphered them and do not understand what they are intending to do.
to really understand your codes it would be necessary to review the reference manual
in particular chpt 17 general purpose timers, review the functionalities and features of the timers how they work.
and check that against the registers referenced to figure out what it does.
https://www.st.com/resource/en/referenc ... ronics.pdf

what would be more appropriate is to review and try the examples that has been created by the authors e.g. fpistm et.al.
e.g. some short ones here
https://github.com/stm32duino/wiki/wiki ... ry#3-usage
then many more here
https://github.com/stm32duino/wiki/wiki ... 4-examples
https://github.com/stm32duino/STM32Examples
https://github.com/stm32duino/STM32Exam ... dwareTimer

i tried this code it blinks my led. I created this reading the api docs and examples.

Code: Select all

#include <Arduino.h>
#include <HardwareTimer.h>

HardwareTimer *pTimer2 = new HardwareTimer(TIM2);

void blink() {
	digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}

void setup() {
	uint8_t channel = 1;
	pTimer2->pause(); // pause the timer
	pTimer2->setMode(channel, TIMER_OUTPUT_COMPARE); //output compare mode, got this from reading the api notes
	pTimer2->setOverflow(500000, MICROSEC_FORMAT); // blink my led every 0.5 sec
	pTimer2->attachInterrupt(blink); // attach the blink handler
	pTimer2->refresh(); //reset the counters
	pTimer2->resume(); //start the timer
}

void loop() {
	delay(1000);
}
note that loop() here does nothing. that delay(1000) statement can be deleted and the led still blinks

note that i've been messing with libmaple core, so official stm core is just as 'new' to me as anyone.
it takes time to learn all these and keep the manual handy and review the manual especially about the hardware timers.
that will help you understand the actual hardware features offered by the timers and review the examples and api and try them out.
the api is to a large extent somehow related to the (timer) hardware features, hence reading both the manual and the api and trying
the examples would actually help. some of the api features i'd guess are 'in development' so it may after all 'grow' over time to encompass
more features available on stm32.

the board i used is stm32f401ccu black pill, rather common to find on aliexpress, ebay etc these days
https://stm32-base.org/boards/STM32F401 ... -Pill-V1.2

stm32's timers are pretty advanced (lots of complicated, small and large features). a main use i commonly used them for
is just like my code above, i.e. call back my isr handler, function. then quite a lot of things can be done from within the isr call.
just that doing it this way has very high overheads. normally, it may not even go above 1 mhz for that isr calls with all the codes
done in the isr handler. other more advanced uses of timers is that they can initiate dma, linked with adc etc.
and they do pwm. it takes quite a few settings to setup, but once done the pulse train is generated by hardware, the cpu can process other stuff.
ag123
Posts: 1657
Joined: Thu Dec 19, 2019 5:30 am
Answers: 25

Re: 'Timer2' was not declared in this scope

Post by ag123 »

ok one more example, 'breathing led' pwm example. hw timer does the work.

Code: Select all

#include <Arduino.h>
#include <HardwareTimer.h>

HardwareTimer *pTimer2 = new HardwareTimer(TIM2);

int16_t count;
int8_t dir;

void ledon() {
	int8_t channel = 1;
	digitalWrite(LED_BUILTIN, LOW);
	if(count > 100) {
		dir = -1;
		count = 100;
	} else if (count < 1) {
		dir = 1;
		count = 1;
	}
	pTimer2->setCaptureCompare(channel, count, PERCENT_COMPARE_FORMAT); // count here is the duty cycle 1-100
}

void ledoff() {
	digitalWrite(LED_BUILTIN, HIGH);
	count += dir;
}

void setup() {
	count = 0;
	dir = 1;

	pinMode(LED_BUILTIN, OUTPUT);
	digitalWrite(LED_BUILTIN, LOW);

	uint8_t channel = 1;
	pTimer2->pause(); // pause the timer
	pTimer2->setMode(channel, TIMER_OUTPUT_COMPARE_PWM1); //output compare mode, got this from reading the api notes
	pTimer2->setOverflow(50, HERTZ_FORMAT); // call back at 50 hz
	pTimer2->attachInterrupt(ledon); // attach ledon() every cycle turn on the led
	pTimer2->attachInterrupt(channel, ledoff); // attach ledoff() end of duty cycle turn off the led
	pTimer2->refresh(); //reset the counters
	pTimer2->resume();

}

void loop() {
	delay(1000);
}
inspirations from the pwm exmple (9th)
https://github.com/stm32duino/wiki/wiki ... ry#3-usage
Post Reply

Return to “General discussion”