AVR: 16 Bit PWM funktioniert nur sporadisch

OP #1384251
Lesenswert?

Hallo,

ich habe hier einen 16 Bit PWM Timer, der als Software-PWM arbeitet. 
Dabei funktioniert das PWM nur wenn eine Funktion zum senden des UARTS 
aufgerufen wird, die eigentlich nichts mit dem PWM zu tun hat.
Die Fehlfunktion (also wenn das USART-Funktion nicht aufgerufen wird), 
nimmt der Duty bis zu 255, darüber geht mein PWM aus. Bis 255 (also 
8-Bit geht es aber nach meiner Einschätzung richtig.

Das ganze ist mir arg dubios und ich habe keine Ahnung womit das 
zusammenhängen kann. Kann es eventuell sein, dass wenn OCR1A geschrieben 
beschrieben wird, der Interrupt ausfällt? Aber wieso geht es dann bis 8 
Bit.

Hoffentlich hat jemand von euch eine Idee... Ich bin jedenfalls 
Ratlos...

Grüße

Michael

Dateiübersicht:
main.c: Der Main loop, hier ist auch nochmal die Funktion die zickt 
hervorgehoben.
usart.c: Die USART-sendefunktion
pwm.c: Die PWM sende funktion
pwm.h: Headerdatei mit ein paar Makros
Angehängte Dateien:
#1384277
Lesenswert?

Langer Rede kurzer Sinn:

Hör auf dem Compiler mit deinen Assembler und Register-Reservierungs 
Escapaden ins Handwerk zu pfuschen.
Oder was glaubst du, wie er bei den UART Routinen, die getrennt von 
allem anderem übersetzt werden, berücksichtigen soll, dass du dir für 
die PWM Routinen ein paar Register reseviert hast?
OP #1384441
Lesenswert?

Dort kommt es aber auf jeden Takt an, zudem sagt mir die avrlibc, dass 
es okay ist was ich mache.
http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_regbind
>Typically, it should be safe to use r2 through r7 that way.

Anbei mal das Listing...

Auszüge:
void usart0_putc( char data )
{
 502:  28 2f         mov  r18, r24
    unsigned char tmp;
    tmp = ( USART0_TxHead + 1 ) & USART0_TX_BUFFER_MASK;
 504:  90 91 fb 00   lds  r25, 0x00FB
 508:  9f 5f         subi  r25, 0xFF  ; 255
 50a:  9f 73         andi  r25, 0x3F  ; 63
    while ( tmp == USART0_TxTail );
 50c:  80 91 fc 00   lds  r24, 0x00FC
 510:  98 17         cp  r25, r24
 512:  e1 f3         breq  .-8        ; 0x50c <usart0_putc+0xa>
    USART0_TxBuf[tmp] = data;
 514:  e9 2f         mov  r30, r25
 516:  f0 e0         ldi  r31, 0x00  ; 0
 518:  e5 54         subi  r30, 0x45  ; 69
 51a:  ff 4f         sbci  r31, 0xFF  ; 255
 51c:  20 83         st  Z, r18
    USART0_TxHead = tmp;
 51e:  90 93 fb 00   sts  0x00FB, r25
    UCSR0B |= (1<<UDRIE0);
 522:  55 9a         sbi  0x0a, 5  ; 10
}
 524:  08 95         ret

000006d2 <__vector_8>:

// In inline ASM Schreiben, da sonst zu langsam!
ISR(SIG_OVERFLOW1){
  asm volatile (
 6d2:  4c bc         out  0x2c, r4  ; 44
 6d4:  5d bc         out  0x2d, r5  ; 45
 6d6:  32 ba         out  0x12, r3  ; 18
 6d8:  18 95         reti

000006da <__vector_6>:
  */

}

ISR(SIG_OUTPUT_COMPARE1A){
  asm volatile (
 6da:  22 ba         out  0x12, r2  ; 18
 6dc:  18 95         reti

000006de <__vector_1>:
           [addr_PIND] "M" (_SFR_IO_ADDR(PORTD))
  );
  // Old c code: PIND=_pwm_on;
}

ich sehe da kein Problem, dass sich die Regisgter irgendwie überplappen. 
Wäre aber echt toll, wenn du mir das gegenteil beweisen könntest.
Angehängte Dateien:

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren