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!
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?
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
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
Hi, wenn man Dioden parallel schaltet, leuchten sie unterschiedlich hell, da die Schwellspannung immer stwas verschieden ist. Besser ist die Reihenschaltung. Gruß Oliver
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
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?
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
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.
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
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
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; }
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.