I am attempting to program an Atmel SAM D21 microcontroller using C++ in Atmel Studio. I'm trying to create periodic hardware interrupts using one of the on-chip timers.
I created Timer4
class to set up the timer from main.cpp
. I tried to create a Timer4
instance called MyTimer4
in the main function, but it says
'Timer4' was not declared in this scope
'MyTimer4' was not declared in this scope
I've seen many similar discussions pointing to incorrect/circular #include
s. But, I don't seem to see the same problem on my own. Any ideas?
Main.cpp
#include "timerSAMD21.h"
#include "sam.h"
void SampleADC(void)
{
}
int main(void)
{
SystemInit();
Timer4 MyTimer4;
MyTimer4.setRate(1000);
MyTimer4.onEvent(SampleADC);
MyTimer4.start;
}
timerSAMD21.h
#ifdef TIMERSAMD21_H
#define TIMERSAMD21_H
#include "tc.h"
#include "tc4.h"
#include "gclk.h"
typedef void (*voidFuncPtr)(void);
class Timer4
{
public:
Timer4() {};
void setRate(int frequency);
void start(void);
void end(void);
void onEvent(voidFuncPtr funcOnEvent);
private:
void configure(int frequency);
void enable(void);
void disable(void);
void reset(void);
};
#endif
timerSAMD21.cpp
#include "timerSAMD21.h"
voidFuncPtr callback = NULL;
void Timer4::setRate(int frequency) {
configure(frequency);
}
void Timer4::start(void) {
enable();
}
void Timer4::end(void) {
disable();
reset();
}
void Timer4::configure(int frequency) {
//Configuration code here. Removed for Stack Overflow.
}
void Timer4::enable(void){
REG_TC4_CTRLA |= TC_CTRLA_ENABLE; //Enable timer
while (TC4->COUNT8.STATUS.bit.SYNCBUSY);
}
void Timer4::disable(void) {
REG_TC4_CTRLA &= ~TC_CTRLA_ENABLE;
while (TC4->COUNT8.STATUS.bit.SYNCBUSY);
}
void Timer4::reset(void) {
REG_TC4_CTRLA = TC_CTRLA_SWRST;
while (TC4->COUNT8.STATUS.bit.SYNCBUSY);
while (TC4->COUNT8.CTRLA.bit.SWRST);
}
void Timer4::onEvent(voidFuncPtr funcOnEvent){
callback = funcOnEvent;
}
#ifdef __cplusplus
extern "C" {
#endif
void IRQHandlerTimer4(void) {
if (callback != NULL)
{
callback();
}
REG_TC4_INTFLAG = TC_INTFLAG_MC0;
}
#ifdef __cplusplus
}
#endif
(Note: Making an answer in order to get this out of the list of unanswered questions. Miles seems to have decided not to answer and I do not consider the problem a typo.)
The way you attempt to prevent the reinclusion of your header is causing it to only make the content of the header visible if the guard-macro happens to be defined already, which it of course never is.
In order to fix this, change the
#ifdef TIMERSAMD21_H
#define TIMERSAMD21_H
into
#ifndef TIMERSAMD21_H
#define TIMERSAMD21_H
This will first keep the header content visible the first time it is included.
It will then define the guard macro, which will prevent the header content from being compiled a second time in the same translation unit, i.e. code file.