www.mikrocontroller.net

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


Autor: Michael H. (overthere)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: Michael H. (overthere)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Usart.c

Autor: Michael H. (overthere)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
pwm.c

Autor: Michael H. (overthere)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
und last but not least pwm.h

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Michael H. (overthere)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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.htm...
>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.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
#define pwm_set_val(val) { \
  OCR1A=0xFFFF-val; \
}
...
  uint_fast8_t rec;
...
      rec=usart0_getc();
      //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?

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oder geht es hierum?
    send=adc_read(0);
    pwm_set_val(send);

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

Worin soll denn die Hervorhebung bestehen?

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.