====== Light-emitting Diode (LED) ====== //Notwendiges Wissen: [HW] [[de:hardware:homelab:controller]], [HW] [[de:hardware:homelab:digi]], [ELC] [[de:electronics:led_resistor]], [AVR] [[de:avr:registers]], [AVR] [[de:avr:io]], [LIB] [[de:software:homelab:library:pin]]// ===== Theorie ===== [{{ :examples:digi:led:led_picture.jpg?150|5 mm legged LED}}] Leuchtdioden sind Halbleiter die Licht abstrahlen, wenn Strom in Durchlassrichtung durch die Diode fließt. Die Abkürzung LED steht für "light-emitting diode". Es gibt verschiedenfarbige Leuchtdioden, mittlerweile ist sogar weißes Licht möglich. Wie jede normale Diode auch hat die LED 2 Kontakte - Anode und Kathode. In Zeichnungen ist die Anode mit einem "+" markiert und die Kathode mit einem "-". [{{ :examples:digi:led:led_designator.png?150|Schematische Darstellung einer LED and ihrer Polarität}}] Wenn Strom in Durchlassrichtung durch die LED fließt, ist die Anode mit der positiven und die Kathode mit der negativen Spannung verbunden. Die Spannung der LED hängt von der Farbe der LED ab: lange Wellenlängen (rot) ~2V, kürzere Wellenlängen (blau) ~3V. Die Stromverbrauch einer LED ist in der Regel nicht mehr als ein paar Dutzend mW. Die Stromstärke darf daher nicht zu hoch sein, wenn größere Stromstärken oder Spannungen verwendet werden kann die LED zerstört werden. Wenn die LEDs nur zur Beleuchtung verwendet werden, sollte man spezielle elektrische Schaltkreise verwenden, welche die Spannung und die Stromstärke für die LEDs regulieren. Jedoch werden LEDs sehr oft als Indikatoren genutzt und direkt vom Mikrocontroller mit Strom versorgt. Da die Betriebsspannung eines Mikrocontrollers höher ist, als die der LEDs, muss ein Widerstand in Serie mit der LED geschaltet werden um die Stromstärke zu regulieren und für den nötigen Spannungsabfall zu sorgen. Das Kapitel "Elektronik" enthält Anleitungen zur Berechnung des richtigen Widerstands. LEDs werden in vielen Formen gefertigt. Die meisten LEDs haben runde eine Hülle mit 3mm oder 5mm Durchmesser und zwei lange metallische Pins. Der längere Pin ist die Anode, der kürzere die Kathode. "Surface mounted casing" LEDs (SMD - Surface Mounted Device) sind unten mit einem T gekennzeichnet, um so die Polarität anzugeben. Das Dach des T's steht für die Anode und der Fuß markiert die Kathode. [{{ :examples:digi:led:led_pin_markings.png?200|Polarität von legged und SMD LED's}}] ===== HomeLab Übung 1 ===== Das HomeLab Controller Controllermodul hat eine rote LED, dessen Anode über einen Widerstand an die +5V Stromversorgung angeschlossen ist und dessen Kathode am ATmega128 Pin PB7. Um die LED an- und auszuschalten muss PB7 als Output Pin definiert werden und entweder high oder low gesetzt werden. Wenn der Pin high gesetzt wird ist die LED aus, wird er low gesetzt ist die LED an. Grundsätzlich ist es möglich die LED so anzubringen, dass die Anode am PB7 angeschlossen wird und die Kathode geerdet wird (Widerstand nicht vergessen) - dann leuchtet die LED wenn der Pin high gesetzt ist und der LED ist aus wenn der Pin low ist. Alle praktischen Beispiele für das HomeLab kit, inklusive LEDs schalten, nutzen die HomeLab Pin Bibliothek. Die Pin Bibliothek hat den Datentyp //pin//, welcher die Addressen des zum Pin gehörigen Register und der Bitmaske des Pins enthält. Wenn eine Pin Variable mit der Makrofunktion Pin im Programm erschaffen und initialisiert wird, kann der Pin mit dieser Variable im gesamten Programm genutzt werden, ohne Register benutzen zu müssen. Hier sind 2 Beispielprogramme, welche exakt das gleiche machen. Das eine Programm nutzt die HomeLab Bibliothek, das andere nicht. // // HomeLab Controllermodule LED Testprogramm. // Der Cose basiert auf der HomeLab Bibliothek. // #include // // LED Pin Konfiguration. // pin debug_led = PIN(B, 7); // // Hauptprogramm // int main(void) { // konfiguriert LED Pin als Output pin_setup_output(debug_led); // Aufleuchten der LED pin_clear(debug_led); } // // HomeLab Controllermodul LED Testprogramm. // Der Code greift direkt auf Register zu. // #include // // Hauptprogramm // int main(void) { // Konfiguriert LED Pin als Output DDRB |= (1 << 7); // Aufleuchten der LED PORTB &= ~(1 << 7); } Das erste Beispiel nutzt die Pin Bibliothek (//pin.h// Datei). Zuerst wird eine Pin-Typ Variable //debug led// erschaffen, welche Informationen über den LED Pin enthält. Im Hauptprogramm wird dieser Pin mit //pin_setup_output// als Output gesetzt. Danach wird der Pin low gesetzt: //pin_clear//. Das Ergebnis: die LED leuchtet. Im zweiten Beispiel werden keine Variablen genutzt. Um die LED als Output zu markieren und zum Leuchten zu bringen, werden die Datenrichtung des Port B und die Output Registerwerte verändert. Der Leser, der mehr über den AVR weiß bemerkt, dass in beiden Beispielen kein Befehl nötig ist um die LED zum leuchten zu bringen, da der Standardoutputwert des AVR 0 ist. Aus Gründen der Vollständigkeit wird es jedoch hier beschrieben. Was ist der Unterschied zwischen dem Gebrauch von Bibliothek und Register? Der Unterschied liegt im Komfort - Die Bibliothek ist einfacher, weil man die Registernamen und deren Auswirkungen nicht kennen muss. Der entscheidende Vorteil der Bibliothek ist jedoch die Anpassungsfähigkeit. Arbeitet man mit Registern müssen im Programm stets die Registernamen und Bitmasken geändert werden um einen Pin zu ändern. Nutzt man die Bibliothek muss dieses nur am Anfang, bei Initialisierung der Variable erfolgen. Die Nutzung von Registern hat jedoch einen entscheidenden Vorteil: Die Nutzung eines Pins erfolgt direkt und nicht über den Programmspeicher und zeitfressenden Funktionen. Jedoch sind die neuren AVR-GCC Kompiler Versionen so schlau, dass sie die Bibliotheksfunktionen zu direkten Befehle für die Registermanipulation transformieren, so als würde man die Register direkt im Programm ansprechen. Die Compiler können den Code aber nur dann optimieren wenn sie mit konstanten Variablen arbeiten und nicht mit unbeständigen Variablen die sich während des Programms oder mit Arrays ändern. Der folgende Programmcode ist ein Teil der Pin Operations Bibliothek, um die Vorgehensweise mit Pin Variblen zu erklären. Es wird für Anfänger nicht einfach sein zu verstehen, da C-Sprache Pointer genutzt werden, die nicht in diesem Buch beschrieben sind. Es gibt jedoch sehr viel Material über Pointer in Büchern und natürlich im Internet. // Makrokonstante um Register-Pointer zu definieren #define _REG_PTR_ volatile uint8_t * // // Pin Datentyp // typedef struct pin { _REG_PTR_ ddr; _REG_PTR_ port; _REG_PTR_ pin; uint8_t mask; } pin; // // Makrofunktion für Initialisierung der Pin Variable // #define PIN(port_char, bit_index) \ { \ (_REG_PTR_)&DDR ## port_char, \ (_REG_PTR_)&PORT ## port_char, \ (_REG_PTR_)&PIN ## port_char, \ bit_mask(bit_index) \ } // // Konfiguriere Pin als Output // inline void pin_setup_output(pin pin) { bitmask_set(*pin.ddr, pin.mask); } // // Setze Pin high // inline void pin_set(pin pin) { bitmask_set(*pin.port, pin.mask); } // // Setze Pin low // inline void pin_clear(pin pin) { bitmask_clear(*pin.port, pin.mask); } ===== HomeLab Übung 2 ===== Zusätzlich zum Controllermodul befinden sich LEDs auch auf der digtalen I/O Modulplatine. Sie sind elektrisch genau so angeschlossen wie auf dem Controllerboard, die Kathode ist also am AVR Pin angeschlossen. Die rote LED ist am PC5 Pin angeschlossen, die gelbe am PC4, und die grüne am PC3. Das auf der HomeLab Bibliothek basierende Beispielprogramm sieht folgendermaßen: // // HomeLab Digitales i/o Modul LED Testprogramm. // #include // // LED Pin Konfiguration. // pin led_red = PIN(C, 5); pin led_yellow = PIN(C, 4); pin led_green = PIN(C, 3); // // Hauptprogramm // int main(void) { // Konfiguriere LED Pins als Output pin_setup_output(led_red); pin_setup_output(led_yellow); pin_setup_output(led_green); // Aufleuchten der grünen LED pin_clear(led_green); // Ausschalten der roten und gelben LED pin_set(led_red); pin_set(led_yellow); } ~~Diskussion~~