Hello
I am learning about timers and found some avr code that I am experimenting with to aid in my learning. This code is not formatted for the arduino. I guess you would call it straight C. My hardware is an arduino UNO.
When I put the code in the arduino IDE, it works , until I rename main () to mainx (). I dont understand why. When its working my code toggles the pin at ~ 38khz, which is my goal. When it's not working, the pin toggles at ~ 500hz ( I have a feeling the AVR is resetting but have no facts to back this feeling up ). I would like to use this code as a base for further development in the arduino environment, but am stuck. Thanks in advance
This works. the pin toggles at 38khz
int main ( void )
{
DDRD |= (1 << 3) ; // Set LED as output
TCCR1B |= (1 << WGM12 ) | (1 << CS10 ) ; // Configure timer 1 for CTC mode
OCR1A = 210;
for (;;)
{
if ( TIFR1 & (1 << OCF1A ) )
{
PORTD ^= (1 << 3) ; // Toggle the LED
TIFR1 = (1 << OCF1A ) ; // clear the CTC flag ( writing a logic one to the set flag clears it )
}
}
}
So I try to get it into the arduino format. This still works. the pin toggles at 38khz
void setup ()
{
}
int main ( void )
{
DDRD |= (1 << 3) ; // Set LED as output
TCCR1B |= (1 << WGM12 ) | (1 << CS10 ) ; // Configure timer 1 for CTC mode
OCR1A = 210;
for (;;)
{
if ( TIFR1 & (1 << OCF1A ) )
{
PORTD ^= (1 << 3) ; // Toggle the LED
TIFR1 = (1 << OCF1A ) ; // clear the CTC flag ( writing a logic one to the set flag clears it )
}
}
}
void loop () {
main();
}
However if I just change the name of main to anything else, it doesnt work.. the pin toggles at ~500hz.
void setup ()
{
}
int mainx ( void )
{
DDRD |= (1 << 3) ; // Set LED as output
TCCR1B |= (1 << WGM12 ) | (1 << CS10 ) ; // Configure timer 1 for CTC mode
OCR1A = 210;
for (;;)
{
if ( TIFR1 & (1 << OCF1A ) )
{
PORTD ^= (1 << 3) ; // Toggle the LED
TIFR1 = (1 << OCF1A ) ; // clear the CTC flag ( writing a logic one to the set flag clears it )
}
}
}
void loop () {
mainx();
}
Why doesnt the timer operate the same way in the 3rd example. I think the flow of the program is the same.
--> empty setup --> loop >> mainx >> setup timers >> stay in conditonal (; in mainx.
Is it that the timers are misconfigured now. I'm going to go look up that init() you mentioned. maybe that is what is configuring my timers differently ?
Using |= is a good idea when you want to take what you have but turn on more bits. However, here you're trying to set every bit so you should just use = rather than |= or &=
I'm going to go look up that init() you mentioned. maybe that is what is configuring my timers differently ?
Yeah it does do some things, it is in wiring.c
Here is the timer1 stuff:
// timers 1 and 2 are used for phase-correct hardware pwm
// this is better for motors as it ensures an even waveform
// note, however, that fast pwm mode can achieve a frequency of up
// 8 MHz (with a 16 MHz clock) at 50% duty cycle
#if defined(TCCR1B) && defined(CS11) && defined(CS10)
TCCR1B = 0;
// set timer 1 prescale factor to 64
sbi(TCCR1B, CS11);
#if F_CPU >= 8000000L
sbi(TCCR1B, CS10);
#endif
#elif defined(TCCR1) && defined(CS11) && defined(CS10)
sbi(TCCR1, CS11);
#if F_CPU >= 8000000L
sbi(TCCR1, CS10);
#endif
#endif
// put timer 1 in 8-bit phase correct pwm mode
#if defined(TCCR1A) && defined(WGM10)
sbi(TCCR1A, WGM10);
#elif defined(TCCR1)
#warning this needs to be finished
#endif