RESOLVED - use of main() in arduino IDE

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();
}

using main overrides the internal main.

It also calls a function named init() that also sets up timers and PWM.

So your 1st and 2nd codes override it and setup/loop aren't even called in the 2nd code.

the 3rd uses the default main, sets up the timers, then you make further changes using mainx.

EDIT: main is the program entry point, the Arduino default calls init(), then setup(), then calls loop() in a never ending loop.

thanks for the reply

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 (;:wink: 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 ?

 TCCR1B |= (1 << WGM12 ) | (1 << CS10 ) ; // Configure timer 1 for CTC mode

Don't do this. You don't want to mask TCCR1B, you want to set it. Just do

TCCR1B = (1 << WGM12 ) | (1 << CS10 ) ; // Configure timer 1 for CTC mode

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

Arlight !. With you guys help I got it. What I think I learned

  1. using a routine name 'main' in an arduino sketch short circuits the arduino configuration routine which includes init() , setup() and loop()
  2. Dont use a mask to set register bits, do an assignment
  3. Set the timer registers to a known value ( I had to do that with TCCR1A below as I was toggling at a different speed without setting it to zero
  4. My arduino wasnt resetting as i thought it was. The timers were just operating with the default values from the init()

This works for me. Now I can move things into setup and loop and get rid of the mainx altogether. I shoulda asked you guys yesterday :slight_smile: Thanks again

void setup ()
{
}

int mainx ( void )
{
  DDRD |= (1 << 3) ; // Set LED as output
  TCCR1A = 0;
  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();
}