Hi,
I wrote an Arduino programm using interrupts for timing:
//set timer1 interrupt at 1Hz
TCCR1A = 0;// set entire TCCR1A register to 0
TCCR1B = 0;// same for TCCR1B
TCNT1 = 0;//initialize counter value to 0
// set compare match register for 1hz increments
OCR1A = 15624;// = (16*10^6) / (1*1024) - 1 (must be <65536)
// turn on CTC mode
TCCR1B |= (1 << WGM12);
// Set CS12 and CS10 bits for 1024 prescaler
TCCR1B |= (1 << CS12) | (1 << CS10);
// enable timer compare interrupt
TIMSK1 |= (1 << OCIE1A);
//set timer2 interrupt at 2kHz
TCCR2A = 0;// set entire TCCR2A register to 0
TCCR2B = 0;// same for TCCR2B
TCNT2 = 0;//initialize counter value to 0
// set compare match register for 2khz increments
OCR2A = 249;// = (16*10^6) / (2000*32) - 1 (must be <256)
// turn on CTC mode
TCCR2A |= (1 << WGM21);
// Set CS20 , CS 21 and CS22 bit for 128 prescaler
TCCR2B |= (1 << CS22) | (0 << CS21) | (1 << CS20);
// enable timer compare interrupt
TIMSK2 |= (1 << OCIE2A);
It works well, but if I use a 8MHz Arduino pro mini, the timing is halfed.
I would like to write the interrupts routine to be independent of the hardware used.
How can I get a compiler conditional directive to sense the speed of the used Arduino?
Thank you for your help...
Use the F_CPU macro to determine the clock frequency at compile time, and change the prescalers appropriately.
Pieter
PieterP:
Use the F_CPU macro to determine the clock frequency at compile time, and change the prescalers appropriately.
Pieter
Thank you for the incredibly fast answer.
Could you please ellaborate on how to use the F_CPU macro to sense the CPU speed and buil an appropriate compiler directive?
I tried to google for it, but get a lot of confusing information, nat really related to the Arduino IDE.
Thank you
Laszlo
RIN67630:
Thank you for the incredibly fast answer.
Could you please ellaborate on how to use the F_CPU macro to sense the CPU speed and buil an appropriate compiler directive?
I tried to google for it, but get a lot of confusing information, nat really related to the Arduino IDE.
Thank you
Laszlo
First off, F_CPU isn't read from the fuses into the compiler at compile time. It's set by the board profile in the Arduino IDE and assumes the fuses have been set accordingly. So, it's defined by the code that is compiled. It is possible to burn the fuses at 8MHz and F_CPU to be set for 16MHz and your timing will be off accordingly.
That said, I doubt this can be done for ANY and ALL speeds of F_CPU, but certainly for the common speeds, you can work out the values for OCR1A and CS12 and CS10. Then use #ifndef/#ifdef macros to include the right values for that defined speed.
Perehama:
First off, F_CPU isn't read from the fuses into the compiler at compile time. It's set by the board profile in the Arduino IDE and assumes the fuses have been set accordingly. So, it's defined by the code that is compiled. It is possible to burn the fuses at 8MHz and F_CPU to be set for 16MHz and your timing will be off accordingly.
That said, I doubt this can be done for ANY and ALL speeds of F_CPU, but certainly for the common speeds, you can work out the values for OCR1A and CS12 and CS10. Then use #ifndef/#ifdef macros to include the right values for that defined speed.
I just wanted to write a code that adapts to the some variants provided in the standard IDE: ATmega328p3,3V@8MHZ or any other Arduino ATmega328 models running@16MHz.
How could I sense with an #ifdef if I am compiling for an ATmega328p3,3V@8MHZ?
As stated, the macro 'F_CPU' will be defined for you at compile time based on the board you selected in the IDE under 'Tools --> Board'. You can use that in pre-processor '#if' macros to control what code gets compiled. See: http://www.cplusplus.com/doc/tutorial/preprocessor/
EDIT:
You can also use the 'F_CPU' macro in run-time if() statements.
[color=#5e6d03]#if[/color] [color=#000000]F_CPU[/color] [color=#434f54]==[/color] [color=#000000]16000000[/color]
[color=#5e6d03]#pragma[/color] [color=#000000]message[/color] [color=#005c5f]"16 MHz"[/color]
// set prescaler for 16 MHz here
[color=#5e6d03]#elif[/color] [color=#000000]F_CPU[/color] [color=#434f54]==[/color] [color=#000000]8000000[/color]
[color=#5e6d03]#pragma[/color] [color=#000000]message[/color] [color=#005c5f]"8 MHz"[/color]
// set prescaler for 8 MHz here
[color=#5e6d03]#else[/color]
[color=#5e6d03]#error[/color] [color=#005c5f]"Unsupported clock speed"[/color]
[color=#5e6d03]#endif[/color]
RIN67630:
I just wanted to write a code that adapts to the some variants provided in the standard IDE: ATmega328p3,3V@8MHZ or any other Arduino ATmega328 models running@16MHz.
How could I sense with an #ifdef if I am compiling for an ATmega328p3,3V@8MHZ?
Who set up the board profile? Assuming you are using MiniCore or something similar, F_CPU is defined in boards.txt so, just as PieterP has illustrated.
PieterP:
[color=#5e6d03]#if[/color] [color=#000000]F_CPU[/color] [color=#434f54]==[/color] [color=#000000]16000000[/color]
#pragma message "16 MHz"
// set prescaler for 16 MHz here
#elif F_CPU == 8000000
#pragma message "8 MHz"
// set prescaler for 8 MHz here
#else
#error "Unsupported clock speed"
#endif
Super! besten Dank.