www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik PWM - Frage


Autor: funker (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Habe hier in der Codesammlung eine Datei für PMW gefunden, die für den
AT90S4433 umgeschrieben worden ist.
Die LEDs hängen bei mir an PIN B0-B5, also 6 stück.
Jetzt kompiliere ich das Programm und lade es in den µC, aber es wird
nur eine LED gedimmt.
Es wird immer nur an PIN B1 gedimmt!

dann habe ich die Zeile
PORTB = 0xFF;
gelöscht, jetzt leuchten zwar alle LEDs, aber wieder wird nur B1
gedimmt...

Brauche Rat!

Autor: funker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hat sich erledigt, eine Bestätigung wäre noch gut:

Laut Datenblatt AT90S4433 ist PIN B1 -> OC1

darum oder?

gibt es aber nicht eine Möglichkeit alle LEDs dimmen zu lassen?

Autor: funker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und was ich eigentlich damit gemeint?

#define OC1A PD5                   // output compareA pin

Wenn ich die Zeile komplett weglasse ändert sich auch nichts...

die Zeilen haben scheinbar auch keine Funktion, das gleiche ohne sie:
sbi(DDRD,OCR1);                // set OC1A pin as output
cbi(PORTD,OCR1);               // clear OC1A

Autor: Fabian Braun (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Servus funker!

Gut bemerkt! Mit diesem Programm kannst du nur
die eine LED dimmen lassen, da nur dies der PWM
Ausgang ist...um mehrer zu dimmen müsstest du
sie halt parallel oder in serie schalten. Dann
werden aber alle gleich gedimmt. Um alle verschieden
zu dimmen und z.b. 8 pins dimmen müsstest du
dann eher ein softwaremässigen pwm programmieren
mit timer, sofern dies überhaupt möglich ist.
also theoretisch schon :-)

#define OC1A PD5
hat meiner meinung nach auch kein sinn, daa OC1A im
Programm nirgens benötigt wird :-S...komische sache

beim anderen bin ich mir jetzt gerade nicht so sicher
möchte nichts behaupten und hab jetzt keine zeit mehr
sorry!

hoffe es hat dir geholfen!

gruss fabian

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,
wenn man Dioden parallel schaltet, leuchten sie unterschiedlich hell,
da die Schwellspannung immer stwas verschieden ist. Besser ist die
Reihenschaltung.

Gruß Oliver

Autor: Frank Linde (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eine Software-PWM mit 8 unabhängigen Kanälen ist problemlos machbar.
Hier geistert irgendwo auch eine fertige Version (Assembler) von Peter
Dannegger herum. Ist IMHO sehr elegant, kurz und schnell.

Gruß, Frank

Autor: funker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke schon mal für eure Hilfe!
Ach zum C-Programm: delay(1000000) ist natürlich Schwachsinn, mehr als
65536 wird wohl wegen der 16bit Integer nicht gehen.

Mir reicht vorerst die eine LED. Aber ich würde gerne diese Stelle
delay(10000);
also den Wert von delay durch ein Poti regeln.
10k-Poti, also 10k Ohm -> delay(10000)

Kann mir da jemand helfen?

Autor: Frank Linde (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Im Prinzip ganz einfach: Potentiometer als Spannungsteiler an einem
ADC-Port anschließen, Wert einlesen, Wert in gewünschte Delayzeit
umrechnen und als Variable an Delay-Routine übergeben.

Gruß, Frank

Autor: funker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe jetzt eine ganze weile die Codesammlung und die Suchmaschine
durchforstet und von Andreas Schwarz was gefunden, der gibt es
allerdings über UART weiter, die Werte...

Kann sich mal jemand ansehen, ob es so funktionieren könnte:

.include "include/4433def.inc"

.def temp = r16
.def temp2 = r17

;Stackpointer initialisieren
ldi temp, RAMEND
out SP, temp

;Port C auf Eingang schalten
ldi temp, 0x00
out DDRC, temp

;ADC initialisieren
;ADEN (ADC Enable) = 1
;ADSC (ADC Start Conversion) = 1
;ADFR (ADC Free Run Select) = 1
ldi temp, ((1<<ADEN)|(1<<ADSC)|(1<<ADFR))+7
out ADCSR, temp

      ;Kanal auswählen
ldi temp, 0    ;PC0 als Eingang
out ADMUX, temp

loop:
in temp, ADCL      ;ADC einlesen
in temp2, ADCH
push temp          ;temp auf dem Stack sichern
rjmp loop

Und ob ich das Assembler (was mir immer besser gefällt) - Programm
richtig verstanden habe.
Also die Initialisierung sollte doch so klappen, wobei mir "free run"
nicht wirklich viel sagt.
Der Wert (Spannung?) wird an PC.0 eingelesen und in "r16" und "r17"
abgelegt, anschliessend mit push temp auf dem Stack gesichert.

Sollte das einlesen und "speichern" meines Wertes klappen, dann muss
ich also den Wert vom Stack holen und in mein C-Programm in der
While-Schleife einfügen.

while(temp){}  <- wie sieht das dann richtig aus?
while(r16){}   <- oder so?
pop r17        <- brauche ich den pop-Befehl? der holt doch eigentlich
die Wert aus den Registern zurück?

Brauche ich eigentlich temp2 ???


...ganz so einfach ist das für mich jetzt auch wieder nicht.

Autor: Frank Linde (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Free runing mode bedeutet, daß der AD-Wandler ununterbrochen die
anliegende Spannung digitalisiert, also kein "Los, digitalisier das
jetzt"-Kommando erforderlich ist. Da der ADC einen 10-Bit-Wert
ausgibt, benötigst Du temp2.

Was Du mit den while-Konstruktionen bezwecken möchtest, erschließt sich
mir gerade nicht. Außerdem kannst Du den ADC doch auch direkt in C
auslesen:

variable1 = in (ADCL)
variable2 = in (ADCH)

So geht's jedenfalls mit dem AVRGCC...

Gruß, Frnak


Gruß, Frank

Autor: funker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für den Hinweis mit dem auslesen in C... Ich muss momentan noch
immer erst Google fragen, dann hier die Suchmaschine anwerfen und was
rauskommt ist meistens Assembler!

Gute Beschreibungen in AVR-GCC habe ich noch nirgends gefunden, ausser
bei Peter Fleury, den ich jetzt mal loben möchte dafür. Auch das
Tutorial hier ist ganz gut, aber auch viel in Assembler.

Wo ich gerade meine Schwierigkeiten habe, das sind die Timerfunktionen
in C und einen Wert irgendwo ablegen und später im Programm wieder
zurückholen. Darum wollte ich auch einfach mal einen abgespeicherten
Wert zurückholen und in die While-Schleife schreiben.
Ich benutze die Assemblerprogramme um den Ablauf zu verstehen und mit
der C-Syntax für die AVR-Befehle habe ich meine Schwierigkeiten. Ich
nutze dann meistens Fleurys-C-Programme um an die Syntax zu kommen.

Initialisierung in C: korrekt?

void InitADC(void)
{
  sbi(ADCSR, ADEN);  // ADC bekommt Power
  cbi(ADCSR, ADFR);  // Free Run Modus
  sbi(ADCSR, ADIE);  // enable ADC interrupts
  sei();    // Interrupts on - wenn nicht schon on
}


Das in C zu übersetzen, daran hänge ich mich auf!

loop:
in temp, ADCL      ;ADC einlesen
in temp2, ADCH
push temp          ;temp auf dem Stack sichern
rjmp loop

Autor: funker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich meine das "push temp" und dann später wieder zurückholen...
Hat vielleicht jemand ein kleines progrämmchen, mit dem man das
nachvollziehen kann?

cbi(ADCSR, ADIE);  muss es ja heissen

funktioniert das dann so?



while(1){
          uint16_t temp = in (ADCL);
          uint16_t temp2 = in (ADCH);
          uint16_t speichern;

          in (ADCL);
          in (ADCH);
          speichern = temp;
}

Autor: Frank Linde (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du denkst in Assembler. Warum programmierst Du dann nicht in Assembler?
Es gibt nichts Besseres, um die Grundlagen zu lernen. Danach kannst Du
immer noch auf C wechseln. So wie Du es jetzt versuchst, mußt Du Dich
mit Assembler UND C auseinandersetzen, was offensichtlich beides
Neuland für Dich ist.

Wenn Du einen Wert in C einliest, dann brauchst Du diesen Wert nicht
explizit über den Stack in eine Unterroutine zu schaufeln, das erledigt
der Compiler für Dich. Wenn schon C, dann nutze auch die Vorteile (hier
Variablen).

Gruß, Frank

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.