SimulIDE_1.1.0-R250918_Lin64 atmega8 no PWM on PB3 (OC2)

Quote from unbreakmyheart on October 21, 2025, 8:37 pmGood day, so bear metal MCU (AtMega8-16PU) outputs PWM on a PB3 pin just fine but i cant get simulator to do this.
#define F_CPU 8000000UL #include <avr/io.h> #include <util/delay.h> static inline void timer2_init_pwm_pc_prescale8_noninv(void) { /* 1) Make Timer2 synchronous and wait for any async updates to finish */ ASSR &= ~(1 << AS2); // ensure CPU-clocked Timer2 /* If AS2 was set before, writes to TCCR2/OCR2/TCNT2 need busy-wait: */ while (ASSR & ((1 << TCR2UB) | (1 << OCR2UB) | (1 << TCN2UB))) { /* wait */ } /* 2) Disable SPI so PB3 (MOSI/OC2) is free */ SPCR = 0; SPSR = 0; /* 3) PB3 as output, start low */ DDRB |= (1 << PB3); PORTB &= ~(1 << PB3); /* 4) Program Timer2: phase-correct 8-bit (WGM20=1), prescaler=8 (CS21=1) */ TCCR2 = 0; TCNT2 = 0; OCR2 = 128; // 50% duty to start while (ASSR & ((1 << OCR2UB) | (1 << TCN2UB))) { /* (paranoia) wait */ } TCCR2 = (1 << WGM20) | (1 << CS21); // phase-correct, clk/8 while (ASSR & (1 << TCR2UB)) { /* wait if needed */ } /* 5) Non-inverting on C (COM21=1, COM20=0) */ TCCR2 &= ~(1 << COM20); TCCR2 |= (1 << COM21); } int main(void) { timer2_init_pwm_pc_prescale8_noninv(); /* Steady PWM forever: ~8 MHz / (8 * 510) ≈ 1.96 kHz */ /* (If you want ~7.8 kHz, use prescaler=1: CS20=1, WGM20=1) */ while (1) { // do nothing — PWM runs continuously // (Optional: blink another pin to show the MCU is alive) _delay_ms(1000); } }
main.hex:
:1000000012C019C018C017C016C015C014C013C044 :1000100012C011C010C00FC00EC00DC00CC00BC06C :100020000AC009C008C011241FBECFE5D4E0DEBF5E :10003000CDBF02D029C0E4CF82B5877F82BD82B513 :1000400087708111FCCF1DB81EB8BB9AC39815BC30 :1000500014BC80E883BD82B586708111FCCF82E438 :1000600085BD02B400FCFDCF85B58F7E85BD85B50D :10007000806285BD2FEF89E698E121508040904055 :0C008000E1F700C00000F6CFF894FFCFBD :00000001FFPlease help you are my last hope!)
Good day, so bear metal MCU (AtMega8-16PU) outputs PWM on a PB3 pin just fine but i cant get simulator to do this.
#define F_CPU 8000000UL #include <avr/io.h> #include <util/delay.h> static inline void timer2_init_pwm_pc_prescale8_noninv(void) { /* 1) Make Timer2 synchronous and wait for any async updates to finish */ ASSR &= ~(1 << AS2); // ensure CPU-clocked Timer2 /* If AS2 was set before, writes to TCCR2/OCR2/TCNT2 need busy-wait: */ while (ASSR & ((1 << TCR2UB) | (1 << OCR2UB) | (1 << TCN2UB))) { /* wait */ } /* 2) Disable SPI so PB3 (MOSI/OC2) is free */ SPCR = 0; SPSR = 0; /* 3) PB3 as output, start low */ DDRB |= (1 << PB3); PORTB &= ~(1 << PB3); /* 4) Program Timer2: phase-correct 8-bit (WGM20=1), prescaler=8 (CS21=1) */ TCCR2 = 0; TCNT2 = 0; OCR2 = 128; // 50% duty to start while (ASSR & ((1 << OCR2UB) | (1 << TCN2UB))) { /* (paranoia) wait */ } TCCR2 = (1 << WGM20) | (1 << CS21); // phase-correct, clk/8 while (ASSR & (1 << TCR2UB)) { /* wait if needed */ } /* 5) Non-inverting on C (COM21=1, COM20=0) */ TCCR2 &= ~(1 << COM20); TCCR2 |= (1 << COM21); } int main(void) { timer2_init_pwm_pc_prescale8_noninv(); /* Steady PWM forever: ~8 MHz / (8 * 510) ≈ 1.96 kHz */ /* (If you want ~7.8 kHz, use prescaler=1: CS20=1, WGM20=1) */ while (1) { // do nothing — PWM runs continuously // (Optional: blink another pin to show the MCU is alive) _delay_ms(1000); } }
main.hex:
:1000000012C019C018C017C016C015C014C013C044 :1000100012C011C010C00FC00EC00DC00CC00BC06C :100020000AC009C008C011241FBECFE5D4E0DEBF5E :10003000CDBF02D029C0E4CF82B5877F82BD82B513 :1000400087708111FCCF1DB81EB8BB9AC39815BC30 :1000500014BC80E883BD82B586708111FCCF82E438 :1000600085BD02B400FCFDCF85B58F7E85BD85B50D :10007000806285BD2FEF89E698E121508040904055 :0C008000E1F700C00000F6CFF894FFCFBD :00000001FF
Please help you are my last hope!)

Quote from arcachofo on October 22, 2025, 9:25 amHi. Thanks for reporting.
I found the problem in Simulide.
As a workaround you can try this:At the end of
void timer2_init_pwm_pc_prescale8_noninv(void)
Change this:
TCCR2 = (1 << WGM20) | (1 << CS21); // phase-correct, clk/8 while (ASSR & (1 << TCR2UB)) { /* wait if needed */ } /* 5) Non-inverting on C (COM21=1, COM20=0) */ TCCR2 &= ~(1 << COM20); TCCR2 |= (1 << COM21);
By this:
TCCR2 = (1 << WGM20) | (1 << CS21) | (1 << COM21); // phase-correct, clk/8 while (ASSR & (1 << TCR2UB)) { /* wait if needed */ }
Hi. Thanks for reporting.
I found the problem in Simulide.
As a workaround you can try this:
At the end of void timer2_init_pwm_pc_prescale8_noninv(void)
Change this:
TCCR2 = (1 << WGM20) | (1 << CS21); // phase-correct, clk/8
while (ASSR & (1 << TCR2UB)) { /* wait if needed */
}
/* 5) Non-inverting on C (COM21=1, COM20=0) */
TCCR2 &= ~(1 << COM20);
TCCR2 |= (1 << COM21);
By this:
TCCR2 = (1 << WGM20) | (1 << CS21) | (1 << COM21); // phase-correct, clk/8
while (ASSR & (1 << TCR2UB)) { /* wait if needed */
}

Quote from unbreakmyheart on October 22, 2025, 9:59 amHOORAY! It worked! Thank you.
I cant appreciate enough how much you project saving me time to develop a working board.
except completely unusable Proteus i don't know any other software that allows fully develop a project almost exclusively 'in silica', it saved me tons of hours in past and still do. Thank you!
HOORAY! It worked! Thank you.
I cant appreciate enough how much you project saving me time to develop a working board.
except completely unusable Proteus i don't know any other software that allows fully develop a project almost exclusively 'in silica', it saved me tons of hours in past and still do. Thank you!