ATmega164P Fast PWM keine funktion

OP #2470334
Hi Leute

und wieder eine PWM Frage. Ich hab leider nix passendes in der Suche 
gefunden, also muss ich jetzt einen neuen Beitrag erstellen...

Folgendes, ich will mit meinem ATmega164P 4 Relais ansteuern. Um energie 
zu sparen, will ich die PWMs der Ports PD4,5 (OC1B/OC1A) und PD6,7 
(OC2B/OC2A) verwenden.

Jetzt hab ich alles schoen ausm Datenblatt rausgelesen und programmiert. 
Leider bekomm ich aber nur am PD6 (OC2B) ein Signal!!

Die anderen Bleiben tot...

Hier ist mal die Definition der Pins
1
#define OC1A_PWM     PD5
2
#define OC1A_PWM_PORT   PORTD
3
#define OC1A_PWM_DDR  DDRD
4

5
#define OC1B_PWM     PD4
6
#define OC1B_PWM_PORT   PORTD
7
#define OC1B_PWM_DDR  DDRD
8

9
#define OC2A_PWM     PD7
10
#define OC2A_PWM_PORT   PORTD
11
#define OC2A_PWM_DDR  DDRD
12

13
#define OC2B_PWM     PD6
14
#define OC2B_PWM_PORT   PORTD
15
#define OC2B_PWM_DDR  DDRD

Dann ist hier mein .c in dem ich die Funktionen und die 
Initialisierungen habe
1
/**** OC1A/B ****************************/
2

3
void OC1A_B_PWM_Init(void)
4
{
5
  OC1B_PWM_DDR = (1<< OC1B_PWM);
6
  OC1A_PWM_DDR = (1<< OC1A_PWM);
7

8
  TCCR1A = (1<<COM1A1) | (1<<COM1B1) | (1<<WGM10) | (1<<WGM11);
9
  TCCR1B = (1<<CS10);
10
}
11

12
void OC1A_PWM_OFF(void)
13
{
14
  OCR1AH = 0x00;
15
  OCR1AL = 0x00;
16
}
17

18
void OC1A_PWM_Static(void)
19
{
20
  OCR1AH = 0x00;
21
  OCR1AL = 0xFF;
22
}
23

24
void OC1A_PWM_ON_8bit(uint8_t OCRValue)
25
{
26
  OCR1AH = 0x00;
27
  OCR1AL = OCRValue;
28
}
29

30
void OC1B_PWM_OFF(void)
31
{
32
  OCR1BH = 0x00;
33
  OCR1BL = 0x00;
34
}
35

36
void OC1B_PWM_Static(void)
37
{
38
  OCR1BH = 0x00;
39
  OCR1BL = 0xFF;
40
}
41

42
void OC1B_PWM_ON_8bit(uint8_t OCRValue)
43
{
44
  OCR1BH = 0x00;
45
  OCR1BL = OCRValue;
46
}
47

48
/**** OC2 ****************************/
49

50
void OC2A_B_PWM_Init(void)
51
{
52
  OC2A_PWM_DDR = (1<< OC2A_PWM);
53
  OC2B_PWM_DDR = (1<< OC2B_PWM);
54

55
  TCCR2A = (1<<COM2A1) | (1<<COM2B1) | (1<<WGM21) | (1<<WGM20);
56
  TCCR2B = (1<<CS20);
57
}
58

59
void OC2A_PWM_OFF(void)
60
{
61
  OCR2A = 0x00;
62
}
63

64
void OC2A_PWM_Static(void)
65
{
66
  OCR2A = 0xFF;
67
}
68

69
void OC2A_PWM_ON(uint8_t OCRValue)
70
{
71
  OCR2A = OCRValue;
72
}
73

74
void OC2B_PWM_OFF(void)
75
{
76
  OCR2B = 0x00;
77
}
78

79
void OC2B_PWM_Static(void)
80
{
81
  OCR2B = 0xFF;
82
}
83

84
void OC2B_PWM_ON(uint8_t OCRValue)
85
{
86
  OCR2B = OCRValue;
87
}

und aufrufen tu ich sie so
1
void Relay1_ON(uint8_t PWM)
2
{
3
  OC1B_PWM_Static();
4
  _delay_ms(10);
5
  OC1B_PWM_ON_8bit(PWM);
6
}
7

8
void Relay1_OFF()
9
{
10
  OC1B_PWM_OFF();
11
}
12

13
void Relay2_ON(uint8_t PWM)
14
{
15
  OC1A_PWM_Static();
16
  _delay_ms(10);
17
  OC1A_PWM_ON_8bit(PWM);
18
}
19

20
void Relay2_OFF()
21
{
22
  OC1A_PWM_OFF();
23
}
24

25
void Relay3_ON(uint8_t PWM)
26
{
27
  OC2B_PWM_Static();
28
  _delay_ms(10);
29
  OC2B_PWM_ON(PWM);
30
}
31

32
void Relay3_OFF()
33
{
34
  OC2B_PWM_OFF();
35
}
36

37
void Relay4_ON(uint8_t PWM)
38
{
39
  OC2A_PWM_Static();
40
  _delay_ms(10);
41
  OC2A_PWM_ON(PWM);
42
}
43

44
void Relay4_OFF()
45
{
46
  OC2A_PWM_OFF();
47
}
Alle 4 PWM-Ports sollten ohne Prescaler, auf Fast PWM (TOP 0xFF) 
eingestellt sein....

Hab ich da irgendwo was uebersehen?

mfg
Bastian
Gast
Relais steuert man nicht über eine PWM an, damit veringert sich die 
Haltekraft des E-Magneten. Was dann dazu führt dass du nicht mehr den 
angegebenen Strom darüber fließen lassen kannst.
OP
Doch man kann es Relais ueber PWM ansteuern.

Das Relais braucht eine Mindestspannung zum sicheren Schalten (bei 
meinen 12V Relais min. 8,4V). Die Abfallspannung liegt aber viel weiter 
unten, bei ungefaehr 3V (laut DB 1,2V).

Ich nutze diese Toleranzen und die Traegheit der Spule jetzt aus und 
verringere durch meine PWM die Spannung von besagten 12 V auf die 8,4 V.

Somit ist immer noch sicher geschaltet...

Mein Problem ist aber das PWM und nicht ob es sinnvoll ist...

mfg
Bastian
Gast
Lass mich raten du initializierst Port PD6 als letztes. So wie du das 
machst überschreibst du immer deine letze zuweisung.

Damit
OC1A_PWM_DDR = (1<< OC1A_PWM); setzt du genau das eine Bit uns löscht 
alle anderen.
 machst du das aber so
OC1A_PWM_DDR |= (1<< OC1A_PWM);
setzt du das  eine Bit und übernimmst die anderen so wie sie stehen.

Daher ist nur der letzte Port den du  initializierst als Ausgang 
geschaltet.

Grüße
Gast
1. Relais lassen sich sehr wohl per PWM nach dem
   Einschalten in der Leistungsaufnahme drosseln,
   Mache ich gelegentlich auch.

2. Denke bitte daran daß bei den Atmegas die Pins
   mit den Sonderfunktionen wie z.B. PWM aolange als
   "normaler" Pin arbeiten, bis die "Sonderfunktion"
   z.B. PWM aktiviert wird, dann wird der Pin automatisch
   auf die Sonderfunktion umgeschaltet. Die im
   "Normalbetrieb" definierten Bedingungen (Richtung, Low/High)
   bleiben aber erhalten. Wird die Sonderfunktion beendet
   gelten wieder die Normal-Betriebs-Bedingungen.
OP
Chris schrieb:
> Lass mich raten du initializierst Port PD6 als letztes. So wie du das
> machst überschreibst du immer deine letze zuweisung.
>
> Damit
> OC1A_PWM_DDR = (1<< OC1A_PWM); setzt du genau das eine Bit uns löscht
> alle anderen.
>  machst du das aber so
> OC1A_PWM_DDR |= (1<< OC1A_PWM);
> setzt du das  eine Bit und übernimmst die anderen so wie sie stehen.
>
> Daher ist nur der letzte Port den du  initializierst als Ausgang
> geschaltet.
>
> Grüße

Danke Chris!!

Genau das hab ich ueber Stunden gesucht!! Dass mir immer wieder solche 
dummen Fehler unterlaufen!! Und dann selber nicht finden...

Danke nochmal

mfg

Bastian
OP
Einen "Fehler" hab ich aber noch...

bei meinem OC2 PWMs hab ich wenn ich in das OCR Register 0x00 
reinschreib immer wieder Peaks drin. Ist das normal?

Bei den OC1 PWMs kommts nicht.

Und ich hab 2 unterschiedliche frequenzen, obwohl ich den Teiler auf 1 
gestellt hab!!

Ausgebesserte Fehler:
1
void OC1A_B_PWM_Init(void)
2
{
3
  OC1B_PWM_DDR |= (1<< OC1B_PWM);
4
  OC1A_PWM_DDR |= (1<< OC1A_PWM);
5

6
  TCCR1A |= (1<<COM1A1) | (1<<COM1B1) | (1<<WGM10) | (1<<WGM12);
7
  TCCR1B |= (1<<CS10);
8
}

hier hatte ich aus versehen noch auf den 10Bit phasecorrect PWM 
gestellt, jetzt is der 8Bit Fast PWM.
1
void OC2A_B_PWM_Init(void)
2
{
3
  OC2A_PWM_DDR |= (1<< OC2A_PWM);
4
  OC2B_PWM_DDR |= (1<< OC2B_PWM);
5

6
  TCCR2A |= (1<<COM2A1) | (1<<COM2B1) | (1<<WGM21) | (1<<WGM20);
7
  TCCR2B |= (1<<CS20);
8
}

mfg
Bastian

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 14 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.