If you don't define your own main(), your program will be linked with
the main() provided by the Arduino core library, which roughly looks
like this (I am simplifying a little bit):
int main(void)
{
init(); // Arduino core initialization
setup(); // user's initialization
for (;;)
loop(); // user's main loop
}
The core's init() function configures Timer 1 for 8-bit phase
correct PWM at 490 Hz, which means that, by the time your setup()
runs, the timer's control registers are not in their default state
anymore, and some of their bits are already set to 1. If you then
update these registers using the |= operator, you end up with a mix of
the core's configuration and your own.
This can be fixed either by zeroing these registers first or, more
simply, by setting their values with the = operator, which has the
effect or setting every bit of those registers to the value you want.
The following works whether you use or not the Arduino core library:
#ifdef NOCORE
int main(void)
#else
void setup()
#endif
{
DDRB = _BV(PB1PB5) | _BV(PB2PB6);
TCCR1A = _BV(COM1A1)
| _BV(COM1B1)
| _BV(WGM11);
TCCR1B = _BV(WGM12)
| _BV(WGM13)
| _BV(CS10);
ICR1 = 0x7fff; // TOP
OCR1A = 0x3fff; // 50% of ICR1
OCR1B = 0x3fff; // 50% of ICR1
}
#ifndef NOCORE
void loop(){}
#endif
Note that:
- The control registers are set (
=) rather than just modified with|= - The mode is set before the output compare registers. This is because setting the output compare registers does not work well when the timer is in an 8-bit mode.