LED-Helligkeit per Poti einstellen
Aus Port23Wiki
Version vom 8. Oktober 2014, 07:48 Uhr von Bastard (Diskussion | Beiträge)
Inhaltsverzeichnis |
Funktionsweise
- Eigentlich kann man eine LED nicht dimmen. Eine LED leuchtet, oder sie leuchtet nicht. Würde man die Spannung variieren, wäre die LED bis zum erreichen der Flußspannung aus. Oberhalb der Flußspannung wäre aber der Durchlassstrom sehr schnell höher als es die LED verträgt - sie würde durchbrennen. Deshalb eignet sich auch das Variieren der Stromstärke nicht um eine LED zu dimmen.
- Was bleibt ist das schnelle Ein- und Ausschalten. Im konkreten Beispiel mit ca. 4 kHz. Variiert wird dabei das Ein- / Aus-Verhältnis von nahe 0% (LED dunkel) bis 100% (LED hell).
- Die beiden Oszillogramme rechts zeigen oben ein Puls/Pausenverhältnis von ca. 20% zu 80%, unten ca. 80% zu 20%. Die LED erscheint im ersten Fall wesentlich dunkler als im Zweiten.
- Das Poti stellt einen Spannungsteiler dar. Am Schleifkontakt ist jede beliebige Spannung zwischen 0V und 5V einstellbar. Der Schleifkontakt wird vom ADC des ATtiny in einen digitalen Wert zwischen 0 und 255 konvertiert.
- Dieser Wert dient der PWM des ATtiny um das Puls- / Pausenverhältnis festzulegen.
Aufbau Breadboard
Schaltplan
mit PWM
/* ----------------------------------------------------------------------- * Title: Analog input changes led brightness - with PWM * Hardware: ATtiny25 * Software: WinAVR 20100110 * -----------------------------------------------------------------------*/ #include <avr/io.h> #include <util/delay.h> #include <stdint.h> #define F_CPU 8000000 #define LED PB0 // Define led ext output pin on PB2 /* Fast PWM */ void init_pwm(void); int main(void) { init_pwm(); // DDRB |= (1 << LED); // Set output direction on LED ADCSRA |= (1 << ADEN)| // Analog-Digital enable bit (1 << ADPS1)| // set prescaler to 8 (clock / 8) (1 << ADPS0); // set prescaler to 8 (clock / 8) ADMUX |= (1 << ADLAR)| // AD result store in (more significant bit in ADCH) (1 << MUX1); // Choose AD input AD2 (BP 4) while(1) { ADCSRA |= (1 << ADEN); // Analog-Digital enable bit ADCSRA |= (1 << ADSC); // Discarte first conversion while (ADCSRA & (1 << ADSC)) { // wait until conversion is done } ADCSRA |= (1 << ADSC); // start single conversion while (ADCSRA & (1 << ADSC)) { // wait until conversion is done ADCSRA &= ~(1<<ADEN); // shut down the ADC } OCR0A = ADCH; } return 0; } void init_pwm(void) { /* OCR0A als Ausgang */ DDRB |= (1<<LED); /* OCR0A als invertierender Ausgang */ TCCR0A |= (1<<COM0A1); /* Fast PWM */ TCCR0A |= (1<<WGM01)|(1<<WGM00); /* Vorteiler auf 1,32 kHz */ TCCR0B = (1<<CS00); /* Timer Interrupt deaktivieren */ TIMSK &= ~((1<<OCIE0A)); }
ohne PWM
/* ----------------------------------------------------------------------- * Title: Analog read example (Analog input change led brightness) * Hardware: ATtiny25 * Software: WinAVR 20100110 * Original from http://avrbasiccode.wikispaces.com/ * -----------------------------------------------------------------------*/ #include <avr/io.h> #include <util/delay.h> #define LED PB0 // Define led ext output pin on PB2 int i; // 8 bits integer int main(void) { DDRB |= (1 << LED); // Set output direction on LED ADCSRA |= (1 << ADEN)| // Analog-Digital enable bit (1 << ADPS1)| // set prescaler to 8 (clock / 8) (1 << ADPS0); // set prescaler to 8 (clock / 8) ADMUX |= (1 << ADLAR)| // AD result store in (more significant bit in ADCH) (1 << MUX1); // Choose AD input AD2 (BP 4) for (;;) { ADCSRA |= (1 << ADEN); // Analog-Digital enable bit ADCSRA |= (1 << ADSC); // Discarte first conversion while (ADCSRA & (1 << ADSC)); // wait until conversion is done ADCSRA |= (1 << ADSC); // start single conversion while (ADCSRA & (1 << ADSC)) // wait until conversion is done ADCSRA &= ~(1<<ADEN); // shut down the ADC //----------Show ADCH Byte in Led variable brightness indicator--------- for (i = 0 ; i < ADCH ; i++) // Loop x time until i reach ADCH value { _delay_us (1); // Loop delay } PORTB ^= (1 << LED); // Inverte led bit and show it for (i = 255 ; i > ADCH ; i--) // Loop x time until i reach ADCH value { _delay_us (1); // Loop delay } PORTB ^= (1 << LED); // Inverte led bit and show it } return 0; }