Forum: Mikrocontroller und Digitale Elektronik Atmel Mega 32 hängt sich bei Fast PWM mit Timer2 auf


von Rudolf P. (Gast)


Lesenswert?

Guten Abend Community,

Ich würde gernen den Timer2 eines Atmel Mega 32 im Fast PWM Mode 
betreiben, um eine Dimmung einer LED zu realsieren. Leider hängt sich 
der µC immer auf, sobald ich den OC2 (PD7) im TCCR2 einstelle. Lasse ich 
den OC2 aus den Einstellungen raus und betreibe den Timer im Fast-Pwm 
Mode funktioniert alles. Die Einstellungen sind wie folgt:
1
void Init_Timer2(void)  //Timer für PWM, kein Interrupt nötig, OCR2 wird über ADC eingestellt
2
{
3
  cli();
4
  TCCR2 = 0x6B;    //Timer2 Fast-PWM, Prescale von 8
5
  OCR2 = 30;    //Vergleichswert von 30
6
}

Am Port PD7 hängt nur ein Transistor dran (über 4,7k) der dann die LEDs 
ansteuert, bin echt langsam am verzweifeln :/

von STK500-Besitzer (Gast)


Lesenswert?

Ein compilierbares Programm im Anhang hilft allen...

von Rudolf P. (Gast)


Lesenswert?

1
void Init_Timer2(void);
2
void Init_ADC(void);
3
4
int main(void)
5
{
6
  Init_Timer2();
7
8
  while(1)
9
  {  
10
     
11
  }
12
}
13
14
void Init_ADC(void)
15
{
16
  ADMUX = 0x01;
17
  ADCSRA = 0x88;
18
  ADCSRA |= (1<<ADSC);  
19
}
20
21
void Init_Timer2(void)  //Timer für PWM, kein Interrupt nötig, OCR2 wird über ADC eingestellt
22
{
23
  cli();
24
  TCCR2 = 0x6B;    //Timer2 Fast-PWM, Prescale von 8
25
  OCR2 = 30;    //Vergleichswert von 30
26
}
27
28
29
ISR(ADC_vect)
30
{  
31
  
32
  if(ADCW/4  > (OCR2 + 10))
33
    OCR2 += 1;
34
  else if(OCR2 > 30)
35
    OCR2 -= 1;
36
}

von Rudolf P. (Gast)


Lesenswert?

Der Aufruf Init_ADC(); fehlt noch, sry

von STK500-Besitzer (Gast)


Lesenswert?

Wo ist das sei()?

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Und wo wird der OC2 Port auf Ausgang geschaltet ?

STK500-Besitzer schrieb:
> Wo ist das sei()?

Die nächste Frage in diesem Thema wäre dann gewesen, warum der ADC nie 
abgefragt wird.

Rudolf P. schrieb:
> TCCR2 = 0x6B;    //Timer2 Fast-PWM, Prescale von 8

Niemand hier ist sehr glücklich über diese Schreibweise, weil dann alle 
immer ins Datenblatt gucken müssen, ob deine Bits wirklich richtig 
gesetzt sind. Schreib lieber:
TCCR2 = (1<<WGM20) | (1<<COM20) | (1<<WGM21) |(1<<CS21) |(1<<CS20);

ist ausserdem weniger fehlerträchtig.

von Ben _. (burning_silicon)


Lesenswert?

Layout? Abblockkondensatoren?

von Rudolf P. (Gast)


Lesenswert?

1
void Init_Timer2(void);
2
void Init_ADC(void);
3
4
int main(void)
5
{
6
  Init_Timer2();
7
  Init_ADC();
8
  DDRD |= (1<<PD7);
9
  sei();
10
11
  while(1)
12
  {  
13
     
14
  }
15
}
16
17
void Init_ADC(void)
18
{
19
  ADMUX = 0x01;
20
  ADCSRA = 0x88;
21
  ADCSRA |= (1<<ADSC);  
22
}
23
24
void Init_Timer2(void)  //Timer für PWM, kein Interrupt nötig, OCR2 wird über ADC eingestellt
25
{
26
  cli();
27
  TCCR2 = (1<<WGM20) | (1<<COM21) | (1<<COM20) | (1<<WGM21) | (1<<CS21) | (1<<CS20);    //Timer2 Fast-PWM, Prescale von 8
28
  OCR2 = 30;    //Vergleichswert von 30
29
}
30
31
32
ISR(ADC_vect)
33
{  
34
  
35
  if(ADCW/4  > (OCR2 + 10))
36
    OCR2 += 1;
37
  else if(OCR2 > 30)
38
    OCR2 -= 1;
39
}

von Rudolf P. (Gast)


Lesenswert?

Kondensatoren sind vorhanden, der µC läuft über nen externen 16Mhz Quarz 
falls das noch helfen sollte

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

AVcc und AREF auch angeschlossen ? Poti sollte an PA1 hängen und du 
solltest ADATE in ADCSRA setzen für den Free run Modus oder am Schluss 
der ISR ADSC wieder setzen.
Sonst siehts nämlich alles richtig aus. Schreib doch mal, mit welcher 
Umgebung du arbeitest.

von Rudolf P. (Gast)


Lesenswert?

Ja alles wie beschrieben gemacht, wie gesagt ich bekomme ja auch auch 
die PWM raus, aber nach spätestens 10 Sekunden hängt sich der µC auf, 
sprich es wird nix mehr ausgegeben wenn ich in der main z.B. was über 
die UART rausgeben will. Das passiert aber nur wenn ich PD7 als PWM-Port 
des Timers benutzte, sonst nicht:(.
Ich programmiere mit AVRStudio4 wenn das weiterhilft

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Rudolf P. schrieb:
> Das passiert aber nur wenn ich PD7 als PWM-Port
> des Timers benutzte, sonst nicht:(.

Also, wenn die LED leuchtet ? Nach 10 Sekunden ? Hmm, ist deine 
Versorgungsspannung einigermassen stabil ?

Rudolf P. schrieb:
> wenn ich in der main z.B. was über
> die UART rausgeben will

Ach, da fehlen aber die Routinen in dem geposteten Programm.

von Rudolf P. (Gast)


Lesenswert?

Wie ich festgestellt habe hängt sich der µC auf, wenn Timer2 im oben 
genannten Mode läuft und ich gleichzeitig was über I2C auslesen möchte, 
in diesem Fall einen RTC DS1337. Ist sowas bekannt?

von holger (Gast)


Lesenswert?

>Wie ich festgestellt habe hängt sich der µC auf, wenn Timer2 im oben
>genannten Mode läuft und ich gleichzeitig was über I2C auslesen möchte,
>in diesem Fall einen RTC DS1337. Ist sowas bekannt?

Ja, nennt sich schlechter Programmierer.
Kein Mensch kann dir sagen was in deinem Programm
schief läuft wenn das Programm nicht bekannt ist.
Poste dein komplettes Programm oder such den Fehler selber.

von Karl H. (kbuchegg)


Lesenswert?

Rudolf P. schrieb:
> Wie ich festgestellt habe hängt sich der µC auf, wenn Timer2 im oben
> genannten Mode läuft und ich gleichzeitig was über I2C auslesen möchte,
> in diesem Fall einen RTC DS1337. Ist sowas bekannt?

Nein.
Du versuchst krampfhaft deiner Hardware einen Fehler anzuhängen, den du 
selber in deinem Programm gemacht hast.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Erst isses der USART, jetzt I2C ? Eins ist klar, wenn der Timer einmal 
im PWM Mode angeschubst wird, macht er das erstmal ohne jeden 
Programmeingriff alleine weiter. Vermutlich hat also der Timer gar 
nichts mit deinem Problem zu tun. Auch ein Schreiben ins OCR Register 
schluckt er einfach und tut seinen Job.

holger schrieb:
> Poste dein komplettes Programm oder such den Fehler selber.
Jup. Sieht mir nach einem Überblick-verloren Problem aus.

von Rudolf P. (Gast)


Angehängte Dateien:

Lesenswert?

Ok hier ist das komplette Programm. Ist zu viel als dass ich jede 
Headerdatei und jede Quelldatei hier posten will. Alles in AVRStudio 4 
erstellt

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Schönen Dank auch. Ich z.B. sitze gerade an einer Debian Squeeze Kiste. 
Auch die Mac User werden sich über RAR sehr freuen.

von Karl H. (kbuchegg)


Lesenswert?

Hab diese Woche meinen ersten Win7 Rechner in Betrieb genommen. WinRAR 
ist noch nicht drauf.


Rudolf, sei mir nicht böse. Aber du stellst dich an, dass man versucht 
ist, den Hut drauf zu hauen.
Erst postest du unvollständige Programme, dann stellt sich raus, dass da 
noch eine UART im Spiel ist, jetzt ist es plötzlich I2C anstelle der 
UART.

Wir WOLLEN dir doch helfen! Aber du machst es uns nicht leicht.

von Rudolf P. (Gast)


Angehängte Dateien:

Lesenswert?

Geht das? Oder was brauchst du?

von Karl H. (kbuchegg)


Lesenswert?

7z ist doch noch exotischer!

Was spricht gegen ein ganz banales ZIP, so wie es seit 30 Jahren benutzt 
wird, oder die paar Files direkt anhängen? Das werden ja wohl keine 200 
Files sein.

von Rudolf P. (Gast)


Lesenswert?

Ja tut mir Leid, merke ich selber dass ich mich da etwas anstelle, aber 
das Programm is halt schon relativ groß, ich dachte dass keiner von euch 
Lust hat sich da durch alles durchzuwühlen, deshalb wollte ich das 
Problem soweit eingrenzen wie möglich, leider hab ich mich in der 
Urasche geirrt, sonst hätte ich euch den Programmcode nicht 
vorenthalten...naja für jeden der helfen will, jez hab ich ihn ja 
hochgestellt:)

von Rudolf P. (Gast)


Angehängte Dateien:

Lesenswert?

So jez :-D

von Karl H. (kbuchegg)


Lesenswert?

Rudolf P. schrieb:

> Lust hat sich da durch alles durchzuwühlen, deshalb wollte ich das
> Problem soweit eingrenzen wie möglich, leider hab ich mich in der
> Urasche geirrt, sonst hätte ich euch den Programmcode nicht
> vorenthalten...naja für jeden der helfen will, jez hab ich ihn ja
> hochgestellt:)

Wenn wir nichts offensichtliches finden wird dir sowieso nichts anderes 
übrig bleiben, als dein Programm noch mal von 0 auf aufzubauen. 
Komponente für Komponente hinzufügen und nachsehen, bei welcher zuletzt 
hinzugefügten Komponente es hängt.

von Rudolf P. (Gast)


Lesenswert?

Ja das ist mir ja jetzt aufgefallen, dass es nicht mehr funktioniert 
hat, nachdem ich den RTC auslesen möchte. Ich kann entweder:

-nur PWM mit Timer2
-nur RTC über I2C auslesen

Sobald ich beides parallel laufen hab hängt sich der µC auf

von Karl H. (kbuchegg)


Lesenswert?

Wie ich sowas hasse, ich kann es dir gar nicht sagen
1
void Init_Timer0(void)  //Timer für MS und RPM
2
{
3
  cli();
4
  TCCR0 = 0x0A;    //Timer2 Prescale 64, CTC Mode
5
  OCR0 = 200;      //Vergleichswert von 200
6
  TIMSK = 0x02;    //Interrupt Freigabe
7
}

TIMSK = 0x02;

Das ist der Output Compare INterrupt, du hast aber keine ISR dafür. Du 
hast eine Overflow-ISR

SCHREIB DAS DOCH SO

   TIMSK = ( 1 << TOIE0 );

dann passiert dir so ein Scheiss nicht!

Wir predigen doch nicht zum Spass: Benutzt die Bitnamen!

: Wiederhergestellt durch User
von Rudolf P. (Gast)


Lesenswert?

1
ISR(TIMER0_COMP_vect)
2
{
3
  
4
  if(rpm_cnt < 1600)
5
    rpm_cnt++;
6
  
7
  if(ms_cnt < 16000)
8
    ms_cnt++;
9
10
  if(ms < ms_cnt)
11
    ms = ms_cnt;      
12
}

Ist das nicht die passende ISR?

: Wiederhergestellt durch User
von Rudolf P. (Gast)


Lesenswert?

Ok kannst meinen letzten Beitrag auch löschen;)

: Wiederhergestellt durch User
von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Nee das is für den Timer0 Compare Interrupt. Bisher haben wir immer über 
Timer2 im fast-PWM Betrieb ohne ISR geredet.
Sei mir nicht böse, aber ich glaube wirklich, das du im Moment den 
Überblick über die Software verloren hast.

von Karl H. (kbuchegg)


Lesenswert?

1
void put_number(float zahl, unsigned char x, unsigned char y, unsigned char laenge, unsigned char prec, unsigned char *font)
2
{  
3
  
4
  char str_zahl[laenge];
5
  unsigned char cnt;
6
  dtostrf(zahl,laenge,prec, str_zahl);

gefährlich. dtostrf nimmt keine Rücksicht darauf, wenn sich die Sache 
nicht ausgeht und er mehr Speicher im Buffer braucht. Wie auch immer 
str_zahl ist auf jeden Fall um 1 zu klein. Um einen String der l = 
strelen() zu speichern, brauchst du ein Array der Länge l+1

von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Wie ich sowas hasse, ich kann es dir gar nicht sagen

Mein Fehler.
Ich hab die ISR übersehen.

Ändert aber nichts daran, dass du die Bitnamen benutzen sollst.

> Ok kannst meinen letzten Beitrag auch löschen;)
Ich habs anders gemacht :-)

von Rudolf P. (Gast)


Lesenswert?

@Matthias
Ich hab nen sehr guten Überblick über das Programm, daran solls nicht 
liegen.

@Karl
Gibts da noch ne bessere Funktion? Ich könnte das warscheinlich auch zu 
Fuß machen, dtostrf war die einzige Funktion die ich gefunden hab :/

von Karl H. (kbuchegg)


Lesenswert?

Rudolf P. schrieb:
> @Matthias
> Ich hab nen sehr guten Überblick über das Programm, daran solls nicht
> liegen.
>
> @Karl
> Gibts da noch ne bessere Funktion? Ich könnte das warscheinlich auch zu
> Fuß machen, dtostrf war die einzige Funktion die ich gefunden hab :/

Ganz ehrlich:
Benutz halt ein Array, das mit Sicherheit ein bischen zu groß ist. Dann 
bist du auf der sicheren Seite. Die paar Bytes im SRAM hast du so gut 
wie immer. Mach ihn halt 10 oder 15 Zeichen lang.

von Rudolf P. (Gast)


Lesenswert?

Ok das ist ja kein Problem, ist schon geändert:) Aber Ursache für das 
Hauptproblem ist das auch nicht

von Karl H. (kbuchegg)


Lesenswert?

Sonst seh ich eigentlich beim drüberlesen nichts mehr.

Hmm. Nach 10s hängt sich alles auf?
Hast du tatsächlich externe Ursachen (einbrechende SPannung etc.) in 
Betracht gezogen.

von Rudolf P. (Gast)


Lesenswert?

Spätestens 10 Sekunden. Ja alles überprüft, Strom und Spannung sind ok, 
Kondensatoren zum Abblocken etc. auch.
Was ich grad im Programm nochmal geändert hab:

Ich hab die Zeile
1
DDRD |= (1<<PD7);    //PWM LED Helligkeit
auskommentiert, sodass am PD7 nix ausgegeben wird, und dann läuft das 
Programm auch soweit, außer dass der RTC nicht mehr ausgelesen wird. 
Kann das nicht sein dass sich der Pin und das TWI irgendwie stören? 
Liegen ja auch portmäßig direkt nebeneinander

von holger (Gast)


Lesenswert?

>außer dass der RTC nicht mehr ausgelesen wird.
>Kann das nicht sein dass sich der Pin und das TWI irgendwie stören?
>Liegen ja auch portmäßig direkt nebeneinander

Dann schau doch mal nach ob da ein Kurzschluss ist.

von Rudolf P. (Gast)


Lesenswert?

Kein Kurzschluss, nix.
Ich werd mir die Tage mal nen neuen Prozessor holen und schauen ob es 
dann weg ist, vllt liegts ja wirklich dran dass da schon  was 
durchgeschossen ist

von Rudolf P. (Gast)


Lesenswert?

Also ein neuer µC bringt leider keine Änderung.
Das einzige was mir auffällt ist, dass wenn ich ich im DDRD Register den 
PD7 NICHT auf 1 setze (was ja für die Ausgabe der PWM erforderlich ist), 
das Programm ohne Probleme läuft. Erst wenn ich PD7 als Ausgang 
initialisiere bekomme ich die Programmabstütze. Muss ich da vllt noch 
irgend nen anderes Bit setzten dass der Fast-PWM Mode einwandfrei läuft? 
Hab im Datenblatt leider nix dazu gefunden

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Poste mal was zum  Aufbau - ist das auf einem Steckbrett? Falls ja, 
steckt da vllt. ein Drahtrest drin, brückt Kontakte und treibt einen zur 
Verzweiflung. Hatte ich auch schon öfter. Ich mach zwar nicht so viel 
mit dem Mega32, hatte mit seinen 40 pol. Brüdern aber keine Anomalien, 
wie du sie beschreibst.

von Rudolf P. (Gast)


Lesenswert?

Matthias ich glaube dein Tip zum Aufbau war Gold wert, hab nochmal alles 
kontrolliert und dabei ist mir aufgefallen, dass ich als Pullup für den 
RTC 100k (warum auch immmer) Widerstände hatte anstatt 2k2 :(

Widerstände getauscht und jez läuft das Programm schon über 2 min ohne 
Absturz. Ich denke mal das war der Fehler. Also vielen Dank für eure 
Hilfe und sry für meinen dummen Fehler :/

Das Problem war dann auch nicht dass sich der µC aufgehängt hat sondern 
dass der RTC nicht mehr reagiert hat und das Programm natürlich solange 
wartet bis der RTC antwortet

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.