You need to log in to create posts and topics.

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

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!)

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 */
    }

 

unbreakmyheart has reacted to this post.
unbreakmyheart

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!

KerimF has reacted to this post.
KerimF