Forum: Compiler & IDEs AVR: 16 Bit PWM funktioniert nur sporadisch


von Michael H. (overthere)


Angehängte Dateien:

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

von Michael H. (overthere)


Angehängte Dateien:

Lesenswert?

Usart.c

von Michael H. (overthere)


Angehängte Dateien:

Lesenswert?

pwm.c

von Michael H. (overthere)


Angehängte Dateien:

Lesenswert?

und last but not least pwm.h

von Karl H. (kbuchegg)


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?

von Michael H. (overthere)


Angehängte Dateien:

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.

von Stefan E. (sternst)


Lesenswert?

1
#define pwm_set_val(val) { \
2
  OCR1A=0xFFFF-val; \
3
}
4
...
5
  uint_fast8_t rec;
6
...
7
      rec=usart0_getc();
8
      //pwm_set_val(rec);
Verstehe ich das richtig, dass deine Frage lautet, warum du damit die 
PWM nur in einem 8-Bit-Bereich variieren kannst?

von Stefan E. (sternst)


Lesenswert?

Oder geht es hierum?
1
    send=adc_read(0);
2
    pwm_set_val(send);

> main.c: Der Main loop, hier ist auch nochmal die Funktion die zickt
> hervorgehoben.

Worin soll denn die Hervorhebung bestehen?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.