Hi. Ich möchte mit meinem Atmel 89C52 ein Programm schreiben, mit dem ich dann mit dem Drehimpulsgeber die Farbe einstellen kann. Die Software für den Drehimpulsgeber habe ich schon. Es sollte folgender Maßen aussehen: Wenn ich den MC einschalte, dann sollte einfach nur die rote Led leuchten. Drehe ich dann den Drehimpulsgeber nach rechts, dann sollte die rote Led bei jedemmal drehen dünkler werden und die grüne dann immer heller werden. Wenn die grüne dann ganz hell ist, dann sollte es auf blau übergehen und von blau dann wieder auf rot. Mein erstes Problem ist, wie kann ich das realisieren und mein zweites ist, daß wenn nur die rote Led leuchtet und ich eins nach rechts drehe, das die grüne Led schon zu hell leuchtet, obwohl sie eigentlich fast dunkel sein sollte.
Hi .. viele Wege führen nach Rom. Einer davon wäre eine Zählervariable hoch- oder runterzuzählen und eine mathematische Zuordnung zu finden, z.b. mit if ((x>20) and (x<30)) {rot=x-20;} Das zweite Problem was Du hast, ist die Nichtlinearität von LEDs. Darüber wurde hier schon oft diskutiert und diverse Lösungsansätze vorgeschlagen. Such einfach mal nach PWM und LED. Tendenziell läufts auf eine Quadrierung des Sollwertes hinaus. Also 10 Stufen --> PWM-Werte 1,4,9,16,...,100. der Flo
Hi Flo. Also ich hätte es mir so vorgestellt: P2.0 = Rot P2.1 = Grün P2.2 = Blau Zuerst läuft das Programm die Farbe Rot durch. Programm: setb P2.0 Rot_ein: djnz 255mal,Rot_ein ;255 mal leuchtet Rot clr P2.0 Rot_aus: djnz 0mal,Rot_aus ;0 mal leuchtet sie nicht setb P2.1 Grün_ein: djnz 0mal,Grün_ein ;0 mal leuchtet Grün clr P2.1 Grün_aus: djnz 255mal,Grün_aus ;255 mal leuchtet sie nicht setb P2.2 Blau_ein: djnz 0mal,Blau_ein ;0 mal leuchtet Blau clr P2.2 Blau_aus: djnz 255mal,Blau_aus ;255 mal leuchtet sie nicht jmp Programm So würde das Programm schon ganz gut funktionieren. Nur grün und blau leuchten dabei auch schon. Zwar nicht hell, aber sie leuchten. Wenn ich jetzt die Pausen für blau und grün verlängere, dann wird rot wieder dunkel. Es ist ein hin und her, da wo ich kein mittelmaß finden kann. Verstehst du Flo?
Hi. Könnte mir jemand sagen, ob ich da den richtigen weg gehe, oder ob ich es anders machen sollte.?
Das dürfte sehr schwer sein, wenn man alles so zusammen manscht. Du must die verschiedenen Aufgaben trennen: 1. Du brauchst erstmal 3 PWM-Ausgänge, entweder mit dem PCA (z.B. im AT89C51ED2) oder in Software mit einem Timerinterrupt. 2. Dann brauchst Du einen Timerinterrupt, der den Drehgeber abfragt (kann der gleiche sein). 3. Und im Hauptprogramm wird mit dem Wert vom Drehgeber eine Variable hoch- bzw. runtergezählt. 4. Diese Variable zeigt nun auf eine Tabelle, wo je 3 Byte (für jede LED) logarithmisch gestuft abgelegt sind, die dann in die 3 PWM geladen werden. Damit laufen diese 4 Aufgaben voneinander unabhängig und es können leicht noch weitere Aufgaben eingefügt werden (z.B. Abspeichern des letzten Wertes im EEPROM). Bzw. Du kannst die Aufgaben überhaupt erstmal einzeln entwickeln und testen. Peter
Hallo Peter. Das Problem mit dem Drehimpulsgeber habe ich schon gelöst. Ich habe das Programm dafür auf einen 89C2051 abgelegt. Dre tut nichts anderes, als den Drehimpulsgeber abfragen. Sobald ich dann drehe, dann kommt entweder bei P1.0 oder bei P1.1 ein kurzez Signal heraus. Diese beiden Signale steuern dann die Interupt's des 89c52. Habe es deshalb so gemacht, weil es so 100 % läuft und ich brauche keine Timer dafür. 1.) Ich hab nur zwei Timer, was kann ich dagegen machen? Wie würde das im allgemeinen ausschauen.Brauch ich dann3 oder nur einen Timer? 2.) hab ich oben erklärt. 3.) Das mit dem ruf und runterzählen mache ich mit den Interuppts 4.) meinst du das so?:: DB #00000001b, DB #00000010b, DB #00000100b, Wenn ja, wie soll ich das dann realisieren?
Gegen zwei Timer kann man nichts machen ;) Aber versuch das ganze Programm mal umzustricken, denn so wie Du es im Moment hast, beeinflussen sich die Helligkeiten gegenseitig, so wie ich das verstehe. Dass das Programm läuft, nutzt dir nichts, wenn es nicht das tut was es soll. Also mein Vorschlag: Nutze die PWM Ausgänge von deinem Controller. Da kannst Du dann direkt über die Compare Register einen Sollwert sowie eine Skalierung der PWM angeben. Das ist die eigentlich gängige Methode, so etwas zu realisieren. Lies dich erstmal ein wenig in die Timer Behandlung ein. Die Tipps von Peter zielen genau darauf ab, aber dazu muss man erstmal verstanden haben, wieso das so funktioniert, wie es funktioniert. Wenn man es verstanden hat, ist es nicht mehr wirklich schwer, da so etwas selber zu bauen. Vielen anderen Leuten hier im Forum ging das schon genauso. ;) der Flo
Ups, ich hab ja drei Timer. Da läßt sich doch was machen... Ich werde mal probieren, hab zwar nicht sehr viel Ahnung, was ihr hier geschreiben habt, aber trotzdem Danke. Vielleicht gehts mit den 3 Timern.
"1.) Ich hab nur zwei Timer, was kann ich dagegen machen?" Dann hast du ja schon einen mehr als Du brauchst. Irgendwo gabs hier mal einen Link zu Software-PWM (8 bzw. 12 Kanäle). Sinn macht es keinen, nur für den Drehgeber eine extra CPU zu verschwenden. Eher im Gegenteil, so lernt man nie effektives Planen des Programmablaufs. Peter
Mann kann mit einem Timer die Drei Farben ansteuern? Wie kann man das machen? ---------------------------------------------------------- In meinem 2051 habe ich dieses Programm: INCLUDE 89C2051.mc abfrage: IF P1 = #11111111b THEN JMP aus IF P1 = #11111100b THEN JMP ein JMP abfrage aus: IF P1 = #11111110b THEN CLR P3.0 NOP NOP SETB P3.0 LCALL wait_20000 JMP abfrage END IF IF P1 = #11111101b THEN CLR P3.1 NOP NOP SETB P3.1 LCALL wait_20000 JMP abfrage END IF JMP aus ein: IF P1 = #11111110b THEN CLR P3.1 NOP NOP SETB P3.1 LCALL wait_20000 JMP abfrage END IF IF P1 = #11111101b THEN CLR P3.0 NOP NOP SETB P3.0 LCALL wait_20000 JMP abfrage END IF JMP ein INCLUDE wait.asm Ich bin leider nur auf diese Idee gekommen, bzw ein Bekannter. Wie ich es mit einem MC machen kann, bin ich leider noch nicht draufgekommen.
Hallo Peter. Du hattest recht. Weg mit dem 2051... Es funktioniert jetzt mit dem Drehimpulsgeber und mit einem Timer. Da Spare ich mir ja viel Hardware und so wie ich es sehe, läuft es auch zu 100 Prozent. Danke Peter. Jetzt muß ich nur mehr mit der PWM draufkommen...
Hm.... Lassen wir mal den Drehimpulsgeber weg. Im Grunde schaut ja eine PWM so aus: 254 Schritte Led ein 1 Schritt Led aus dann leuchtet die Led ganz hell 1 Schritt Led ein 254 Schritte Led aus dann ist die Led ganz dunkel. 127 Schritte Led ein 128 Schritte Led aus dann ist die Led im mittleren Bereich. Ist das richtig so? Nehmen wir an, ich möchte nur eine Led mit dem Drehimpulsgeber dimmen, wie kann ich das dann mit einem Timer realisieren=? Ich könnte es mir so vorstellen: Ich sage R0=#0Ah Mit dem Drehimpulsgeber kann ich dann R0 erhöhen oder verringern. Dann könnte ich R1 immer Inkrementieren. Wenn R1 < R0 ist, dann soll die Led leuchten. Wenn R1 > R0 ist, dann soll sie nicht leuchten. Nur geht dieser Befehl nicht: if R0 < R1 then setb bit 2.0 Bin ich da am richtigen weg?
Eine Software-PWM macht man im Timerinterrupt. Im Interrupt hat man einen Zähler, der nach einer bestimmten Zeit alle LEDs ausschaltet. Und für jeden benötigten Ausgang hat man einen weiteren Zähler, der die ihm zugeordnete LED einschaltet. Die Differenz zwischen beiden Zählern ist dann das Tastverhältnis. Läßt man die Zähler bis 255 zählen, spart man sich das Rücksetzen, da nach 255 automatisch 0 kommt. Für einfachere Software zählt man nicht hoch, sondern runter, da der 8051 dafür einen speziellen Befehl hat, der zählt und gleichzeitig auf 0 testet (DJNZ). Bei einem AT89C2051 mit 24MHz Quarz setzt man z.B. den Timer T0 in den Reloadmode, so daß er alle 52 Zyklen einen Interrupt auslöst: MOV TH0, #-52 Dann ergibt sich eine PWM-Frequenz von: 24MHz 12 52 / 256 = 150Hz Benötigt man noch andere Interrupts, dann muß T0 auf die hohe Priorität gesetzt werden, damit die LEDs nicht flackern. Peter
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.