Forum: Mikrocontroller und Digitale Elektronik [C] ADC --> PWM


von Paul (Gast)


Angehängte Dateien:

Lesenswert?

Hallo an alle,

ich bin sicher gefühlt der 200000 der das versucht.

Aber es will nicht, und ich kann mir nicht recht erklären warum, 
deswegen wende ich mich an euch.

Ich will an einem Atmega32 am Pinc.0 eine Spannung von einem Poti 
einlesen und als PWM ausgeben lassen um eine LED zu dimmen.

Ich habe dieses Tutorial hier genommen und die Registernamen an meinen 
AVR angepasst, trotzdem will es nicht funktionieren ;(.
http://www.mikrocontroller.net/articles/Absolute_Beginner-AVR_Steckbrettprojekte
(Ganz unten, Abschnitt PWM)

Der Code wird ohne Fehler compiliert und lässt sich auch ohne Probleme 
übertragen. Die LCD Ausgabe habe ich rausgeschmissen, da ich leider kein 
LCD hier habe.

Im Anhang "mein" Code, eventuell ist es ja was ganz Banales, was ich vor 
lauter Betriebsblindheit nicht mehr sehe.

Datenblatt Atmega32:
http://www.atmel.com/images/doc2503.pdf

Poti ist an Pinc.0, die LED hängt mit der Anode am Pinb.3 und geht über 
einen Widerstand nach Masse.

Ich hoffe ihr könnt mir auf die Sprünge helfen.
Vielen Dank schon mal.

von MWS (Gast)


Lesenswert?

> TCCR0 |=(1<<COM01 ) ;

COM01?

von Paul (Gast)


Lesenswert?

Ja, so heißt doch das Register. Seite 80 im DB des Atmega32.

Ich will ja den normalen PWM Modus, nicht den invertierten.

Oder macht dieses Register nur Sinn, wenn ich zwei Outputs über einen 
Timer laufen habe?

von MWS (Gast)


Lesenswert?

Paul schrieb:
> Ja, so heißt doch das Register.

Lies Dir doch mal den (eigenen?) Kommentar durch und vergleiche:
> //  COM0A0, COM0B1 and COM0B0 bleiben auf 0 (default)

von Paul (Gast)


Lesenswert?

Tut mir leid, ich steh auf dem Schlauch. Worauf willst du hinaus?

Das Kommentar stammt von dem verlinktem Beispiel, da wurde ein Atmega88 
verwendet, kein Atmega32. Der Atmega88 hat kann zwei PWM Kanäle mit 
Timer2 erzeugen, der Atmega32 doch aber nur einen? Deswegen habe ich den 
Registernamen aus dem DB des 32ers genommen.

Mit anderen Registernamen wie COM0A0 kommt ein Fehler beim Build, was 
meiner Meinung nach auch logisch ist, das es dieser Register ja nicht 
gibt beim Atmega32.

von Paul (Gast)


Lesenswert?

Pardon, ich meine mit Timer 0, nicht mit Timer2.

von MWS (Gast)


Lesenswert?

Immer schön, wenn der Kommentar nicht zum Prozessor passt...

Das hier dürfte der Fehler sein:
> TCCR0 |=(1<<COM01 ) ;
> TCCR0 =(1<<CS01|1<<CS00);

Die zweite Zeile überschreibt die erste.

von Paul (Gast)


Lesenswert?

MWS schrieb:
>> TCCR0 |=(1<<COM01 ) ;
Das ist der Modus "nicht invertierend", wenn "Fast PWM" verwendet wird, 
oder?


MWS schrieb:
>> TCCR0 =(1<<CS01|1<<CS00);
Diese Zeile stellt doch aber nur den Prescaler ein, oder?


MWS schrieb:
> Die zweite Zeile überschreibt die erste.

Ich hätte jetzt vermutet das sich das gar nicht beißt.
Aber wenn ich die zweite Zeile rausnehme, dann läuft das Programm leider 
immer noch nicht.

Hast du noch eine Idee?

von MWS (Gast)


Lesenswert?

Programming by trial and error? ;D

Die zweite Zeile darf natürlich nicht rausgenommen werden, sonst ist der 
Zähler ohne Takt. Sie muss nur wie die vorherige Zeile verodert werden.
Nur wenn man das Register in einer Zeile konfiguriert, kann man (sollte 
man sogar) ohne Oder arbeiten.

von Paul (Gast)


Lesenswert?

Ich geh kaputt, daran lags wirklich.

Ich danke dir recht herzlich! Da wär ich im Leben nicht drauf gekommen!
Wie viele Jahre muss man denn programmieren um SO etwas zu wissen?

von MWS (Gast)


Lesenswert?

Das lernst Du schnell, mach' Dir da keine Gedanken ;-)

von oder einloggen (Gast)


Lesenswert?

Paul schrieb:
> Ich geh kaputt, daran lags wirklich.
>
> Ich danke dir recht herzlich! Da wär ich im Leben nicht drauf gekommen!
> Wie viele Jahre muss man denn programmieren um SO etwas zu wissen?



5 Minuten !?
Wenn man halbwegs verstanden hat was man da macht sollte man sowas 
wissen.

Aus Flüchtigkeit kann man aber immer das Oder vergessen... Aber das war 
ja scheinbar kein Flüchtigkeitsfehler.

Schau dir am besten den Artikel zu den Bit Manipulationen hier auf der 
Seite einmal an, der ist sehr hilfreich.

von Rolf M. (rmagnus)


Lesenswert?

Paul schrieb:
>>> TCCR0 =(1<<CS01|1<<CS00);
> Diese Zeile stellt doch aber nur den Prescaler ein, oder?

Diese Zeile stellt alles ein, was in TCCR0 steht.

> MWS schrieb:
>> Die zweite Zeile überschreibt die erste.
>
> Ich hätte jetzt vermutet das sich das gar nicht beißt.

Wie kommst du darauf? Da steht links "TCCR0 = ". Also wird damit der 
Wert in TCCR0 überschrieben, und zwar komplett. Wenn du das schreibst:
1
uint8_t i = 3;
2
i = 10;
erwartest du dann auch, dass die zweite Zeile nur Teile von i 
überschreibt und dann nachher eine 13 drin steht?

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.