Forum: Compiler & IDEs Ein ganz einfacher C Code für PWM


von Lukas P. (lzaman)


Lesenswert?

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

von ozo (Gast)


Lesenswert?

Schlau mal ins GCC Tutorial

von Lukas P. (lzaman)


Lesenswert?

Da werde ich leider nicht so ganz schlau draus, deswegen die Suche nach 
einem   fertigen Code. Ich verstehe die Sachen irgendwie besser an 
Beispielen.

von Sven P. (Gast)


Lesenswert?

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.

von Mehmet K. (mkmk)


Lesenswert?

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 ....
1
#define PWM_MIN 75L
2
#define PWM_MAX 290L
3
4
BYTE test;
5
6
 
7
//************************************************************************/
8
//*  TIMER 1 Overflow   wird alle 20uSec aufgerufen
9
//************************************************************************/
10
ISR (TIMER1_OVF_vect)
11
{ 
12
  WORD dat;
13
  
14
  // sobald mehr als 5V anliegen, liegt ein L-Signal am Eingang PC0.
15
  // Ansonsten ein H-Signal.
16
  // D.h. bei einem H-Signal muss OCR1A erhoeht werden
17
18
  dat = OCR1A;
19
  if (BIT_IS_SET(PINC, 0))
20
  { if (dat < PWM_MAX)
21
      dat++;
22
    YELLOW_LED_ON;
23
  }
24
  else
25
  { if (dat > PWM_MIN)
26
      dat--;
27
    YELLOW_LED_OFF;
28
  }
29
30
  OCR1A = dat;
31
}
32
 
33
//************************************************************************/
34
//*  Compare A Interrupt  
35
//************************************************************************/
36
ISR (TIMER1_COMPA_vect)
37
{ 
38
39
  // compare occured TCNT1=OCR1A
40
  msec_1++;
41
}
42
43
44
//************************************************************************/
45
//*  Compare B Interrupt  
46
//************************************************************************/
47
ISR (TIMER1_COMPB_vect)
48
{
49
  // compare occured TCNT1=OCR1A
50
  test++;
51
}
52
 
53
//************************************************************************/
54
// Init Timer 1A Mode 14
55
// ICR1 : (MAX) Der Counter zaehlt bis zu dieser Marke hoch und resetet dann auf 0
56
//        
57
// OCR1A: (TOP) Sobald dieser Wert beim Hochzahelen erreicht wurde
58
//        wird der Ausgang geflippt.
59
// D.h. mit ICR1 wird die Frequenz eingestellt, mit OCR1A die Periode
60
// 
61
// Bsp.:PWM-freq = freq / (N * 1 + TOP)
62
//************************************************************************/
63
void Init_Timer_1A( void )
64
{ 
65
 
66
67
68
  // PWD Mode 14: 
69
  TCCR1B = 0x00;   //stop
70
  TCNT1  = 0x0000; 
71
  ICR1   = 401L;  // 400 = 50kHz
72
  OCR1A  = PWM_MIN;
73
  TCCR1A = (1 << COM1A1) | (1 << WGM11);
74
  TCCR1B = (1 << CS10) |  (1 << WGM12) | (1 << WGM13);   //start Timer  
75
}

von Lukas P. (lzaman)


Lesenswert?

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.

von Lukas P. (lzaman)


Lesenswert?

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;
}

von Lukas P. (lzaman)


Lesenswert?

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;
}

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.