Hallo zusammen, ich würde mich als absoluten µC-Anfänger bezeichnen, auch wenn ich schon schon das eine oder andere Miniprojekt in Assembler zum Laufen gebracht habe... ;) Nun bin ich dabei und habe eine Spannungauswertung mit dem ATtiny13 in Assembler erstellt. Der A/D-Wandler (Eingang: PB4)läuft auch soweit. Die Ausgänge treiben drei LEDs die einzeln die jeweiligen Spannungsbereiche anzeigen. LED1 = bis xxV LED2 = xxV bis yyV LED3 = YYV bis zzV LED3 blinkend = über zzV Nun möchte die LEDs (wenn möglich) über den letzten freien Port(PB3) noch auf eine geringere Helligkeit dimmen/schalten können. Den Port PB5 brauche ich unbedingt als Reset für spätere Änderungen per ISP. Hat jemand von Euch eine Idee, wie ich das realisieren könnte? Ich habe schon Stunden damit verbracht eine geeignete PWM-Lösung zu finden, scheitere aber wahrscheinlich an mangelnder Erfahrung oder meiner eigenen Blödheit, jedenfalls hat mich kein Programmbeispiel wirklich weiter gebracht... :-( Ist es irgendwie möglich wenigstens zwei der drei Ausgänge (z.B. PB0 u. PB1) irgendwie dunkler zu schalten, wenn sich der Zustand an PB3 von High auf Low ändert? Vielleicht hat einer von Euch sowas schon in der "Schublade" oder kann mich wenigstens gedanklich in die richtige Richtung schubbsen? Viele Grüße aus dem Norden Michael
Hallo Falk, danke für den Tip, aber das habe ich auch schon 'zig Mal gelesen. :-( Viele Grüße Michael
Angenommen du hast active low geschaltete LEDs:
1 | +-------####------->|-----o PORT für LED1 |
2 | | |
3 | Vcc o---------+-------####------->|-----o PORT für LED2 |
4 | | |
5 | +-------####------->|-----o PORT für LED3 |
dann kannst du die Stromzufuhr mit einem PNP-Transistor drosseln
1 | +-------####------->|-----o PORT für LED1 |
2 | | |
3 | Vcc o--- ---+-------####------->|-----o PORT für LED2 |
4 | v / | |
5 | ----- +-------####------->|-----o PORT für LED3 |
6 | | |
7 | +------------####--------------o PORT für PNP (PB3) |
Basiswiderstand Den PORT für PNP schaltest du wechselweise die Zufuhr von Strom zu den LEDs an/aus. Wenn das schneller als ca. 25x in der Sekunde ist, kann das Auge das Blinken die LEDs nicht mehr sehen, sieht also eine schwächer leuchtende LED. Der Leuchteindruck ist fürs Auge aber nicht linear LED-Fading. Du wirst längere AUS Zeiten als AN Zeiten brauchen, damit die LED deutlich dunkler ist. Also deine Variablen sind Frequenz (AN/AUS Wechsel) und der Dutycycle (Dauer AN:AUS). Damit bist du bei der PWM. Wenn der PNP-Transistor mit HIGH an 'PORT für PNP' nicht komplett sperrt (was hier nicht tragisch wäre, weil die LEDs darüber nicht komplett abschalten musst) und dich das stört, kannst du noch einen Pullup-Widerstand von der Basis des PNP zu Vcc legen. So wie du mit PB3 schaltest, kannst du natürlich auch ohne Transistor direkt an den PORT für LEDx arbeiten. Du musst dann dreimal eine PWM einrichten. Idealerweise wenn es die Hardware des AVR für dich macht, weiss aber ohne Datenblattstudium nicht ob das meim Attiny13 möglich ist. Es geht aber auf jeden Fall "von Hand" per Software.
Hallo Stefan, Die Idee mit der schaltbaren Strombegrenzung war mir auch schon gekommen. ;-) Da ich aber nur noch den PB3 zur freien Verfügung habe, aber dann auch noch einen Eingang für für das Steuersignal hell/dunkel brauche, komme ich wohl tatsächlich um die soft-PWM nicht herum... Derzeit sieht meine Auswertung und Ansteuerung der LEDs so aus:
1 | ;------------------------------------------------------------------------ |
2 | ; Hauptprogramm-Schleife: Einlesen der Werte und Srung zur jeweiligen Ausgabe |
3 | ;------------------------------------------------------------------------ |
4 | mainloop: wdr |
5 | rcall getValueADCandWait |
6 | cpi r16,0b00110010 ;Spannungsvorgabe bis 60 |
7 | brcs mehr_als_60 |
8 | cpi r16,0b01100100 ;Spannungsvorgabe für Bereich v. 60-120 |
9 | brcs mehr_als_120 |
10 | cpi r16,0b11011001 ;Spannungsvorgabe für Bereich v. 120-130 |
11 | brcs mehr_als_130 |
12 | ldi r17,0b00000100 ;Out wenn mehr als 130 LED3 blinkt |
13 | out PORTB,r17 |
14 | rcall myWait_500ms |
15 | ldi r17,0b00000000 |
16 | out PORTB,r17 |
17 | rcall myWait_500ms |
18 | rjmp mainloop |
19 | ;-------------------------------------------------------------------- |
20 | mehr_als_60: |
21 | ldi r17,0b00000010 |
22 | out PORTB,r17 |
23 | rcall myWait_1000ms |
24 | rjmp mainloop |
25 | ;-------------------------------------------------------------------- |
26 | mehr_als_120: |
27 | ldi r17,0b00000100 |
28 | out PORTB,r17 |
29 | rcall myWait_1000ms |
30 | rjmp mainloop |
31 | ;-------------------------------------------------------------------- |
32 | mehr_als_130: |
33 | ldi r17,0b00000001 |
34 | out PORTB,r17 |
35 | rcall myWait_1000ms |
36 | rjmp mainloop |
Ich muss es also jetzt irgendwie schaffen, die Schleifen "mehr_als_XXX" zum Pulsen zu bringen und das Puls/Pause-Verhältnis je nach Zustand des PB3 zu ändern... und genau da hakt es bei mir (noch)... ;-) Viele Grüße Michael
Du bist an einem Punkt angelangt, an dem du mit der Warteschleifen Methode nicht mehr so recht weiterkommst. Du bist fällig für die nächste Stufe: Timer einsetzen. Ich würde eine Software-PWM machen (findet sich auch im Tutorial) und damit alle 3 LED unabhängig voneinander ansteuern lassen. Dann kannst du auch 7 Bereiche machen LED1 halbe Helligkeit LED1 volle Helligkeit LED2 halbe Helligkeit LED2 volle Helligkeit LED3 halbe Helligkeit LED3 volle Helligkeit alle LED blinken bzw Kombinationen davon LEE1_h LED1_v LED1_v + LED2_h LED1_v + LED2_v LED1_v + LED2_v + LED3_h LED1_v + LED2_v + LED3_v blinken (oder alle 3 LED auf halbe Helligkeit, oder nur glimmen) Vorteile: Du kannst jede LED unabhängig von allen anderen auf einen Helligkeitswert einstellen. Du brauchst keine zusätzliche Hardware
Ganz schnell hingeschaut
1 | cpi r16,0b00110010 ;Spannungsvorgabe bis 60 |
2 | brcs mehr_als_60 |
3 | cpi r16,0b01100100 ;Spannungsvorgabe für Bereich v. 60-120 |
4 | brcs mehr_als_120 |
5 | cpi r16,0b11011001 ;Spannungsvorgabe für Bereich v. 120-130 |
6 | brcs mehr_als_130 |
mit welchen Zahlenwerten wird jeweils verglichen, warum wird es das, und was haben die im Kommentar genannten Zahlen (was sind das überhaupt? Sind das Äpfel oder Birnen oder Volt oder direkte ADC Werte?) damit zu tun Bei solchen Sachen, ist Binärschreibweise die schlechteste aller Möglichkeiten. Warum nicht dezimal?
1 | cpi r16, 50 ;Spannungsvorgabe bis 60 |
2 | brcs mehr_als_60 |
3 | cpi r16, 100 ;Spannungsvorgabe für Bereich v. 60-120 |
4 | brcs mehr_als_120 |
5 | cpi r16, 217 ;Spannungsvorgabe für Bereich v. 120-130 |
6 | brcs mehr_als_130 |
dann fällt schon mal das Rätselraten weg, ob die Zahlen mit denen hier verglichen wird, eventuell die im jeweiligen Kommentar genannten Zahlen sind (nein, sie sind es ganz offensichtlich nicht). Welche Schreibeweise man für Zahlen benutzt, sei es binär, hex oder dezimal, hängt davon ab, wofür die Zahl steht. Welche Schreibweise der Zahl an dieser Stelle die natürlichste ist. Du vergleichst hier mit vorberechneten Grenzwerten. Dann benutz die Zahlendarstellung, in der du die Berechnung auch auf dem Papier machen würdest.
Hallo Karl, ...ich hab's befürchtet. ;-) Dann werde ich mal versuchen mich da durch zu wurschteln. <edit=on> zweites Posting nicht mitbekommen... Die wirklichen Vorgabewerte stehen noch gar nicht 100%ig fest. Die Werte kommen von einem Öltemperatursensor und das Ganze soll dann im Cockpit die Temperaturbereiche "0-60°C", "60-120°C, "120-130°C und "über 130°C anzeigen. Dabei kommt es absolut nicht auf eine exakte Genauigkeit an und auch die "Schaltstufen" werden sicherlich noch angepasst, bzw. sollten anpassbar sein. <edit=aus> Viele Grüße Michael
Hallo Karl Heinz, ich habe es (fast) geschafft das Soft-PWM erstmal grundsätzlich ansatzweise auf dem ATtiny13 zum Laufen zu bringen, auch wenn es nach meinem Dafürhalten ziemlich langsam ist. Die LEDs flackern nicht, aber das Umschalten zwischen den Spannungsstufen und zwischen Hell und Dunkel dauert eine kleine Ewigkeit. Würdest Du mal über den Code gucken... ich habe das Gefühl, dass da noch irgendwas "nicht ganz Richtig" ist. Bin aber schon heilfroh, dass ich wenigstens so weit gekommen bin. grins Viele Grüße Michael
Wozu springst du in jedem bis_xxx Abschnitt ständig nach TIMER? Den Timer startest du 1 mal und dann läuft der ständig alleine durch. Um den brauchst du dich nicht mehr weiter kümmern. Den Timer startest du daher einmal ganz am Programmanfang. In weiterer Folge veränderst du nur noch die OCR Werte. Und schmeiss die ganzen waits da in der Hauptschleife raus. Du wartest da auf nichts mehr. OCR Wert setzen und die LED brennt in dieser Helligkeitsstufe. Das wars. Mehr brauchst du nicht mehr. Genauso wie du das PORTB Register in der mainloop in Ruhe lässt. Die einzige Funktion, die sich daran zu schaffen macht, ist die Timer Overflow Routine. Die schaltet die LED und sonst niemand. Und was machen die ganzen SBIC PINB, 3 in den jeweiligen bis_xxx Abschnitten?
Moin Karl, SUUUPER! - Vielen Dank! Das war genau der richtige "Schubbs" in die richtige Richtung. Jetzt habe ich es zum Laufen. Diese "waits" am Anfang sind/waren lediglich eine Spielerei... das wird am Ende eine kurze Testsequenz nach dem Reset/Einschalten werden um zu schauen, ob die LEDs OK sind... ;-) Die SBIC PINB3 brauche ich aber doch um die ocr-Werte zu ändern, wenn ich bei einer Änderung an PB3 die Helligkeit der jeweiligen LED ändern will. - Erschien mir jedenfalls am einfachsten. Nochmals vielen Dank und viele Grüße aus dem Norden Michael
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.