ATMega8 PWM Programme funktionieren nicht

#6800925
Lesenswert?

Hallo alle miteinander,

ich habe folgendes Problem: ALLE PWM Programme funktionieren auf meinem 
Mega8 nicht...
Jedoch andere Programm schon, ohne Probleme, aber sobald es an die PWM 
geht, funktioniert nichts mehr. Selbst mit Copy/Paste Programmen aus dem 
Internet...
Habt ihr vielleicht eine Ahnung, woran das liegen könnte?
Den Controller hab ich auch schonmal ausgetauscht, und genau das selbe 
Problem gehabt.

Hier ein Biespielcode:

1
#include <avr/io.h>
2

3
int main( void )
4
{
5
  uint8_t pwm_soll = 20; 
6
  uint8_t pwm_phase = 0; 
7

8
  
9
  DDRB |= (1<<PB0); 
10
  
11

12
  while( 1 )
13
  {
14
    if( pwm_soll == pwm_phase )
15
    {
16
      PORTB |= (1<<PB0); 
17
    }
18
    pwm_phase++;
19
    if( pwm_phase == 100 )
20
    {
21
      pwm_phase = 0;
22
      PORTB &= ~(1<<PB0); 
23
    }
24
  }
25
  return 0;
26
}

Leider habe ich keinen Schematischen Aufbau zur Hand, sondern nur dieses 
Foto.
Die LED an PB0 soll zur PWM genutzt werden. Dort hängt auch ein RC-Glied 
dran, das hat aber nach try/error keine Auswirkungen da drauf.

VG
Lavy
Angehängte Dateien:
#6800941
Lesenswert?

W.S. schrieb:
> Lies die Dokumentation und versuche, die kopierten Quellen zu verstehen.

Ich verstehe sie ja... ich habe ja auch eigene. Ich verstehe nur nicht, 
warum sie auf einmal nicht mehr funktionieren.
Es hat ja auch schonmal vor einer Weile geklappt, jedoch habe ich dann 
etwas umgebaut und seit dem nichts mehr (und ja, ich habe auch schon 
alles wieder in den Ursprung zurück gebaut, und trotzdem nichts). Kurios 
ist eben wirklich, dass jedes andere Programm funktioniert, aber nichts 
mit PWM.
#6800943
Lesenswert?

H.Joachim S. schrieb:
> Copy & paste-Programme aus dem Internet....
>
> Setz dich hin und lies die wenigen Seiten über die diversen PWM-Modi.
> Beliebter Anfängerfehler: den betreffenden Port nicht als Ausgang
> gesetzt.

Das Copy/Paste kam erst, als ich angefangen habe an meinem Code zu 
zweifeln. Ich wollte checken, ob es an mir liegt, oder eben bspw. ein 
Hardwarefehler ist.
#6800957
Lesenswert?

Also ich hab es mal kurz probiert und bei mir funktioniert es.
Das war mit deinen Werten. (Bild)

Probier mal 20000 und 65535:
1
#include <avr/io.h>
2

3
int main( void )
4
{
5
  uint16_t pwm_soll = 20000;
6
  uint16_t pwm_phase = 0;
7

8
  DDRD |= (1<<PD6);
9

10
  while( 1 )
11
  {
12
    if(pwm_phase == pwm_soll)
13
    {
14
      PORTD |= (1<<PD6);
15
    }
16

17
    pwm_phase++;
18

19
    if(pwm_phase == 65535)
20
    {
21
      pwm_phase = 0;
22
      PORTD &= ~(1<<PD6);
23
    }
24
  }
25

26
  return 0;
27
}

Hierbei solltest du ein schnelles Flakern erkennen.
Sonst hast du ein Fehler im Aufbau.
Angehängte Dateien:
#6800961
Lesenswert?

Und falls du die PWM Peripherie nicht verwenden möchtest,
dann initialisier dir zumindest ein Timer mit Interrupt, dass du eine 
feste Zeitbasis hast.
Dann kannst du solche Dinge viel einfacher lösen.

Edit:
Im oberen Code habe ich es auf PORTD Pin6 geändert,
habs vergessen wieder auf deine Konfig zu ändern.
Gast #6800971
Lesenswert?

Beliebte Standart-Fehler : Da suche ich bei meinen Projekten immer als 
erstes. ;)

1. LED steckt falsch herum drin (nachschauen)

2. Pin nicht als Ausgang deklariert (nachschauen)

3. Wert der Variable ist falsch (als via Monitor anzeigen lassen).

4. Kein Vorwiderstand. (LED-Testschaltung nutzen um zu schauen ob die 
überhaupt noch geht. Reiche Leute haben ein LED-Tester ;) )

5. LED ist nicht dimmbar. (Es gibt einige da geht es einfach nicht, im 
Datenblatt schauen).

6. Notfalls mit einer kleinen analogen Birne den PWM testet. Ein Birne 
mit 5 Volt glimmt i.d.R. schon ab 2 Volt je nach Modell.


Wenn das alles getestet ist, dann überlege ich wo der Fehler sonst 
steckt. Ist bisher nur sehr sehr selten vorgekommen. 99% aller Fehler 
sind Flüchtigkeitsfehler. Sagte schon mein Lehrer damals in der 
Grundschule. Recht hatte er zufälligerweise ;)
Gast #6801028
Lesenswert?

Roland F. schrieb:
> Kannst du mal ein Beispiel nennen.

Leider nein. Aber ich hatte mal ein paar "billig LED's" aus der 
Grabeltüte da hat es nicht funktioniert. Die gingen entweder an oder 
aus. Als ich das Teil gegen welche "mit Datenblatt" ausgetauscht habe, 
funktionierte es.

k.a. warum.  Jedenfalls kaufe ich seit dem nur noch welche mit 
Datenblatt.
(Firma: matzetronics) #6801044
Lesenswert?

Svenja S. schrieb:
> IMG_20210826_104121.jpg

1. Ich sehe da mal wieder keinen einzigen Abblockkondensator am Mega8. 
Bitte immer mindestens einen 100nF parallel zur Versorgung nahe dem MC 
schalten.
2. Steckbrettprojekte führen einen wg. der schlechten Kontaktgabe der 
Federleisten gerne an der Nase rum.
3. Es gibt nicht einfacheres, als im Steckbrett die Funktion einer LED 
zu kontrolieren.
#6801119
Lesenswert?

Hallo,

Dein Code funktioniert schon, nur die Logik ist je nach Ansicht 
verdreht, kannst du korrigieren. Ich habe den Endwert zum ausschalten 
auf 200 erhöht.
Wenn du jetzt den Wert von pwm_soll zwischen 0 und 200 änderst, dann 
solltest du eine Helligkeitsänderung sehen.

Wenn du am Ende der while ein 2ms delay einbaust und pwm_soll auf 100 
setzt, dann solltest du ein 50:50 blinken sehen.

Damit kannste in Ruhe rumspielen. Bei der PWM Geschichte immer daran 
denken wann wird eingeschalten und wann wird ausgeschalten und man 
benötigt 2 Zeiträume. Beide Zeiträume addiert ergeben die Periodendauer.

Der Keramik links Reihe 30 sollte direkt neben die VCC/GND Pins am µC.
Ein kleiner Elko in die Versorgungsschiene nahe µC kann auch nicht 
schaden.
1
int main( void )
2
{
3
  const uint8_t pwm_soll = 150; 
4
  uint8_t pwm_phase = 0;  
5

6
  DDRB |= (1<<PB0); 
7

8
  while(1)
9
  {
10
    if( pwm_phase == pwm_soll)
11
    {
12
      PORTB |= (1<<PB0); 
13
    }
14

15
    pwm_phase++;
16

17
    if( pwm_phase >= 200 )
18
    {
19
      pwm_phase = 0;
20
      PORTB &= ~(1<<PB0); 
21
    }
22
  }
23
}
#6801289
Lesenswert?

Hallo,

falls einfach nur die Frage falsch gestellt ist und du das PWM Dimming 
sehen möchtest, dann muss man sich die Funktionalität eines 
Hardware-Timer nachbauen. Man benötigt einen Timerzähler und einen 
Pulsweitenzähler. Beide Zähler setzt man  an entsprechenden Stellen 
zurück. Das Bsp. lässt die LED aufdimmen. Dafür lassen wir 
kontinuierlich die Pulsweite erhöhen. Ohne logarithmische Anpassung 
sieht das nicht ganz linear aus. Probiere es aus.
1
// https://www.mikrocontroller.net/topic/523867#6800925
2

3
#include <avr/io.h>
4
#include <util/delay.h>
5

6
uint8_t pwmTimer;  
7
uint8_t pwmPulsweite;
8
const uint8_t pwmPeriode = 200;
9
  
10
int main( void )
11
{
12
  DDRB |= (1<<PB0); 
13
  
14
  while(1)
15
  {
16
    if(pwmTimer == 0)             // Periodenstart
17
    {
18
      PORTB |= (1<<PB0);          // einschalten
19
    }
20

21
    pwmTimer++;
22
    
23
    if(pwmTimer == pwmPulsweite)  // Phasenwechsel
24
    {
25
      PORTB &= ~(1<<PB0);         // ausschalten
26
    }
27

28
    if(pwmTimer >= pwmPeriode)    // Periodenende
29
    {
30
      pwmTimer = 0;               // Timer wieder bei 0 starten lassen
31
      pwmPulsweite++;             // Pulsweite erhöhen
32
    }
33

34
    if(pwmPulsweite >= pwmPeriode)  // Pulsweite hat mögliches Maximum erreicht
35
    {
36
      pwmPulsweite = 0;
37
    }
38
    
39
    _delay_us(100);                 // damit man etwas sieht
40
  }
41
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren