Ich würde das mal so angehen.
Dimmen bedeutet, dass es erst mal möglich sein muss
eine Led auf eine (fast) beliebige Helligkeitsstufe
zu setzen.
Daher würde ich damit mal anfangen: Eine Led auf eine
bestimmte Helligkeitsstufe zu setzen.
Da das ganze mit _delay_ms gemacht werden soll, ist als
erstes mal eine Funktion notwendig, die eine bestimmte
Zeit in ms abwarten kann.
1 | void Delay( uint8_t ms )
|
2 | {
|
3 | while( ms > 0 ) {
|
4 | _delay_ms( 1 );
|
5 | --ms;
|
6 | }
|
7 | }
|
Soweit so gut. Wie wird eine LED gedimmt?
Sie wird dadurch gedimmt, dass das Verhältnis von Einschalt
zu Ausschaltzeit variiert wird. Ist die Led lange ein aber
nur kurz aus, dann leuchtet sie heller als wie wenn sie nur
kurz ein aber lange aus ist.
Das heist, in einer bestimmten Zeiteinheit x ist die Led
y Zeiteinheiten ein und x-y Zeiteinheiten aus.
Als Basiszeit nehme ich mal 50ms. D.h. die LED durchläuft
so einen ein/aus Zyklus 20 mal in der Sekunde. Das wird zwar
noch zu einem gewissen Flackern führen, ist aber fürs Testen
erst mal gar nicht so schlecht und mit Millisekunden erst mal
auch nicht anders machbar. Wir wollen ja auch genügend Helligkeits-
stufen für die LED haben.
1 | void LedZyklus( uint8_t OnTime )
|
2 | {
|
3 | if( OnTime > 0 ) {
|
4 | // Led ein
|
5 | PORTD = 0x00;
|
6 | // OnTime abwarten
|
7 | Delay( OnTime );
|
8 | }
|
9 |
|
10 | if( OnTime < 50 ) {
|
11 | // Led aus
|
12 | PORTD = 0xFF;
|
13 | // Aus-Zeit abwarten
|
14 | Delay( 50 - OnTime );
|
15 | }
|
16 | }
|
Ein Aufruf der Funktion LedZyklus dauert 50 Millisekunden (und
ein paar Zerquetschte) und zwar unabhängig davon, wie 'hell'
die Led leuchten soll.
Das ist es mir schon mal wert, dafür ein Testprogramm zu schreiben
um zu sehen, ob das auch funktioniert.
1 | int main()
|
2 | {
|
3 | DDRD = 0xFF; // auf Ausgang
|
4 |
|
5 | while( 1 )
|
6 | LedZyklus( 10 ); // Led soll nur schwach leuchten
|
7 | }
|
Wenn ich jetzt keinen Tippfehler gemacht habe, dann sollte die
Led am Port D dunkel leuchten (flackern).
Durch Variation der 10 beim Aufruf von LedZyklus sollten sich
verschiedene Werte einstellen lassen. Ausprobieren!
Bei einem Aufruf
dürfte die Led überhaupt nicht leuchten, während sie bei
mit voller Kraft leuchten sollte. Werte dazwischen führen
zu verschiedenen Helligkeitsstufen.
Das ist ja schon mal ein Anfang. Um die Led zu dimmen, genügt
es daher, diesen Wert laufend zu ändern. Zb. indem man ihn in
der Schleife variiert:
1 | int main()
|
2 | {
|
3 | uint8_t UpDown;
|
4 | uint8_t Level;
|
5 |
|
6 | DDRD = 0xFF; // alles auf Ausgang
|
7 |
|
8 | Level = 0;
|
9 | UpDown = 0;
|
10 |
|
11 | while( 1 ) {
|
12 | LedZyklus( Level );
|
13 |
|
14 | if( UpDown == 0 ) { // Led soll heller werden
|
15 | if( Level >= 50 ) // Obere Grenze erreicht ?
|
16 | UpDown = 1; // Ja: Auf dunkler werden umschalten
|
17 | else
|
18 | Level += 1; // Nein: Na dann mach sie heller
|
19 | }
|
20 |
|
21 | else { // Led soll dunkler werden
|
22 | if( Level == 0 ) // Untere Grenze erreicht ?
|
23 | UpDown = 0; // Ja: Auf heller werden umschalten
|
24 | else
|
25 | Level -= 1; // Nein: Na dann mach sie dunkler
|
26 | }
|
27 | }
|
28 | }
|
Damit sollte die Led dann eigentlich laufend dunkler/heller
werden.
Von da weg, ist es nur noch ein kleiner Schritt einen Taster
mit einzubauen.
Ich denke das Hauptproblem des OP ist dasselbe, dass viele
Einsteiger haben: Ihr versucht immer zuviel in main() hinein-
zupacken. Schreibt euch Funktionen für Teilaufgaben! Dadurch
wird die Entwicklung sehr viel einfacher und auch wesentlich
überschaubarer. In diesem konkreten Fall besteht der Trick
darin, die effektive Helligkeitseinstellung von der Dimmerei
zu trennen.