www.mikrocontroller.net

Forum: GCC Ein ganz einfacher C Code für PWM

Autor: Lukas Piet (lzaman)
Datum: 09.05.2008 18:41

Hallo, ich hab über die Suchfunktion leider kein einfaches Beispiel
gefunden.
Deshalb meine Bitte:

Wer hat Links oder sogar einen fertigen code in C für eine ganz Simple
PWM Ausgabe.

Ich will den beiden Pins PD4 und PD5 vom Atmega16 einen PwmWert von 155
zuweisen. Der max Wert sollte bei 255 liegen, also 8 Bit. Die Werte
werden nicht verändert, die sollen konstant bleiben für eine
Motorsteuerung.

Danke
Autor: ozo (Gast)
Datum: 09.05.2008 18:51

Schlau mal ins GCC Tutorial
Autor: Lukas Piet (lzaman)
Datum: 09.05.2008 18:58

Da werde ich leider nicht so ganz schlau draus, deswegen die Suche nach
einem   fertigen Code. Ich verstehe die Sachen irgendwie besser an
Beispielen.
Autor: Sven Pauli (haku) Benutzerseite
Datum: 09.05.2008 19:03

Funktioniert in C nicht anders als in Assembler, da es quasi nur drum
geht, ein paar Register zu beschreiben.

Les halt das Datenblatt...steht alles ausführlich drin.
Autor: Mehmet Kendi (mkmk)
Datum: 09.05.2008 19:32

Mir ging es beim PWM genauso wie dir. Bei mir führte aber der Rat von
Sven Pauli "les halt das Datenblatt" zum gewünschten Aha-Erlebnis. Aber
ein einfaches Beispiel haette auch mir die Sache erleichtert.
Hoffe, dass ich nicht zuviel gekürzt habe ....
#define PWM_MIN 75L
#define PWM_MAX 290L

BYTE test;

 
//************************************************************************/
//*  TIMER 1 Overflow   wird alle 20uSec aufgerufen
//************************************************************************/
ISR (TIMER1_OVF_vect)
{ 
  WORD dat;
  
  // sobald mehr als 5V anliegen, liegt ein L-Signal am Eingang PC0.
  // Ansonsten ein H-Signal.
  // D.h. bei einem H-Signal muss OCR1A erhoeht werden

  dat = OCR1A;
  if (BIT_IS_SET(PINC, 0))
  { if (dat < PWM_MAX)
      dat++;
    YELLOW_LED_ON;
  }
  else
  { if (dat > PWM_MIN)
      dat--;
    YELLOW_LED_OFF;
  }

  OCR1A = dat;
}
 
//************************************************************************/
//*  Compare A Interrupt  
//************************************************************************/
ISR (TIMER1_COMPA_vect)
{ 

  // compare occured TCNT1=OCR1A
  msec_1++;
}


//************************************************************************/
//*  Compare B Interrupt  
//************************************************************************/
ISR (TIMER1_COMPB_vect)
{
  // compare occured TCNT1=OCR1A
  test++;
}
 
//************************************************************************/
// Init Timer 1A Mode 14
// ICR1 : (MAX) Der Counter zaehlt bis zu dieser Marke hoch und resetet dann auf 0
//        
// OCR1A: (TOP) Sobald dieser Wert beim Hochzahelen erreicht wurde
//        wird der Ausgang geflippt.
// D.h. mit ICR1 wird die Frequenz eingestellt, mit OCR1A die Periode
// 
// Bsp.:PWM-freq = freq / (N * 1 + TOP)
//************************************************************************/
void Init_Timer_1A( void )
{ 
 


  // PWD Mode 14: 
  TCCR1B = 0x00;   //stop
  TCNT1  = 0x0000; 
  ICR1   = 401L;  // 400 = 50kHz
  OCR1A  = PWM_MIN;
  TCCR1A = (1 << COM1A1) | (1 << WGM11);
  TCCR1B = (1 << CS10) |  (1 << WGM12) | (1 << WGM13);   //start Timer  
}

Autor: Lukas Piet (lzaman)
Datum: 09.05.2008 19:52

DDRB = 0xff;
    DDRD = 0xff;
   PORTB = 0x01;

   TCCR1A = (1 << WGM10) | (1 << COM1A1);
   TCCR1B = (1<<CS11) | (1<<CS10);
   OCR1A = 15;
   OCR1B = 245;

habs mal so versucht, bin noch am tüffteln.

Was fehlt noch? In diesem beispiel wollte ich erreichen, das PWM an
OCR1B fast 5V beträgt.
Autor: Lukas Piet (lzaman)
Datum: 10.05.2008 19:43

Juhu, ich habs geschafft, naja fast.

Ich kann meine PWM setzen und auf einen festen Wert einstellen

im Beispel 128 also ca. 2,5V

Aber wieso nur am Ausgang OCR1A, ich möchte PWM an OCR1B ebenfalls
realisieren.

Hat jemand eine Lösung?

Hier mein Code:

#include <avr/io.h>
#define F_CPU 8000000

int main  (void)
{

   DDRD=0b1111111;

// PWM Konfig.

   TCCR1B |= (1<<CS10);  //
   TCCR1A |= (1<<WGM10)|(1<<COM1A1); //PWM 8 Bit

       OCR1A=128;

       OCR1B=128;

  return 0;
}
Autor: Lukas Piet (lzaman)
Datum: 11.05.2008 01:03

Danke bin fertig:

#include <avr/io.h>
#define F_CPU 8000000

int main  ()
{

DDRD=0xFF;

 while(1)
 {
   // PWM Konfig.
   TCCR1B |= (1<<CS10);           // Frequenz Vorgabe
   TCCR1A |= (1<<WGM10)|(1<<COM1A1)|(1<<COM1B1); //PWM 8 Bit und nicht
invertierend für OCR1A und OCR1B


       OCR1B=128;

       OCR1A=128;
 }
  return 0;
}

Antwort schreiben

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

Wichtige Regeln - erst lesen, dann posten!

  • Suchfunktion und Betreffsuche benutzen - vielleicht gibt es schon einen ähnlichen Beitrag
  • Aussagekräftigen Betreff wählen
  • Im Betreff angeben um welchen Controllertyp es geht (AVR, PIC, ...)
  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
  • JPEG-Dateien (.jpg) nur für Fotos verwenden, Schaltpläne, Screenshots usw. als PNG oder GIF anhängen

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [pre]vorformatierter Text (z.B. Code in anderen Sprachen)[/pre]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel






webmaster@mikrocontroller.netImpressumWerbung auf Mikrocontroller.net