mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Software PWM


Autor: Marius Meier (micro4)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen

Ich wollte mal hier meinen C-Code posten und fragen, was daran falsch 
sein sollte. Es funktioniet nicht wirklich. Ich realisiere mein PWM 
Signal mit einem Counter welcher funktioniert. Jedoch wird in der 
Interrupt Serviceroutine das PWM Signal nicht richtig erzeugt:

#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>
#include <string.h>
#include <avr/interrupt.h>

#define t_Period  1000;

//pwm_on & pwm_off sind das Tastverhältnis
unsigned int pwm_on, pwm_off;
unsigned int pwm_on_count, pwm_off_count;


void init_timer()
{
  TCCR1A = 0b00000000; //Set timer to compare OCR1A register
  TCCR1B = 0b00001011; //Set prescaler to 64 and set Timer to compare OCR1A register
  TIMSK = 0b00010000; //Enable Timer 1 Compare A Interrupt
  OCR1A = 0x20; //Exact number for 2ms interrupts

  sei();
}



ISR(TIMER1_COMPA_vect)
{
  if(pwm_on_count < pwm_on) {
    PORTC |= (0 << 0);
    pwm_on_count++;  
  }

  else {
    if(pwm_off_count < pwm_off) {
      PORTC |= (1 << 0);
      pwm_off_count++;  
    }

    else {
      pwm_on--;
      pwm_on_count = 0;
      pwm_off = t_Period - pwm_on;
      pwm_off_count = 0;
    }
    
  }

  

}



void initIO(void) 
{
  DDRC = 0xff;
}

void main()
{
  //Initialisieren
  initIO();
  init_timer();
  pwm_on = t_Period;
  pwm_off = 0;
  pwm_on_count = 0;
  pwm_off_count = 0;

  while(1) {

  }

}


}

Ich verwende eine Atmega16. Ich danke für die Hilfe.

MFG

Autor: Benedikt K. (benedikt) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Marius Meier schrieb:

> Ich wollte mal hier meinen C-Code posten und fragen, was daran falsch
> sein sollte. Es funktioniet nicht wirklich.

Lass mich raten: Der Pin ist dauerhaft an?

Der Fehler liegt wohl hier:
 PORTC |= (0 << 0);

Damit schaltest du den Pin nicht ab, sondern machst garnichts.
So sollte es besser gehen:
 PORTC &=~(1 << 0);

Autor: Mark Brandis (markbrandis)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Benedikt K. schrieb:
>
 PORTC &=~(1 << 0);

Warum eigentlich schiebt Ihr Bits um Null Stellen? Ist das besonders 
performant? ;-)

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

wenn Du in der ISR auf Variablen zugreifst, musst Du sie als "volatile 
deklarieren".

Michael

Autor: Benedikt K. (benedikt) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mark Brandis schrieb:

> Warum eigentlich schiebt Ihr Bits um Null Stellen? Ist das besonders
> performant? ;-)

Es macht den Code leichter lesbar.

Wenn man einmal
PORTC &=~0;
das nächste mal
PORTC &=~(1 << 1);
oder dann auch mal noch
PORTC &=~_BV(2);
oder gar
cbi(PORTC,3);
schreibt, dann trägt das nicht wirklich zum leichten Verständnis des 
Codes bei.
Man sollte daher eine der 4 Schreibweisen durchgehend im gesamten Code 
verwenden.

Autor: Vlad Tepesch (vlad_tepesch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
und statt literalen sollte man aber auch dann
(1 << PIN0) oder (1 << PINB0) schreiben, wobei ich letzteres schon 
wieder sinnlos finde, da mann, wenn man den Port ändert auch überall 
PINxn in PINynx ändern muss.

Edit:
>Ist das besonders performant? ;-)
der kompiler optimiert das sowiso weg.

Edit Edit:
@benedikt:
du hast die beiden ersten Varianten von Marius vergessen:
>  TIMSK = 0b00010000; //Enable Timer 1 Compare A Interrupt
>  OCR1A = 0x20; //Exact number for 2ms interrupts

Autor: Marius Meier (micro4)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke vielmals. Ich habe die ganze Zeit am falschen Ort den Code 
betrachtet. Habe nicht gesehen das ich das Bit falsch lösche. Danke!

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.