Hallo Forum, ich habe einen AD-Port, an dem ich ein Poti habe. Ich lasse die Werte am Port wandeln (8 Bit). Das funktioniert bis hierhin. Dann habe ich acht LEDs an acht Ports. P0-P7. Bis jetzt habe ich das Ergebnis der AD-Wandlung auf die LEDs ausgegeben. Das funktioniert auch soweit. So wird das Ergebnis der AD-Wandlung quasi binär auf den LEDs ausgegeben. In etwa PortXY= ADCWert; Nun würde ich aber gerne das ganze etwas anders ausgeben, aber auch wieder auf den LEDs. Ich würde nun aber gerne mit steigendem ADCWert mehr LEDs angehen lassen. Also 8 LEDs auf 8 Bit verteilt: 256/8= 32. Wenn ADCWert= 0, soll keine LED leuchten, bei ADCWert 255 sollen alle acht LEDs leuchten. Wenn der ADCWert zwischen 1 und 32 liegt, soll die erste LED leuchten, wenn der ADCWert 32-64 ist, soll die erste und zweite LED leuchten usw. Ich weiß leider nicht, wie ich das genau umsetzen soll. Ich könnte mehrere if / if else Abfragen nehmen oder das ganze über switch gestalten. Wollte aber einmal fragen, ob es wohl möglich ist, das ganze einfacher zu gestalten, anstatt über viele Bedingungen. Grüße Volker
Du kannst einen Schleifenzähler bauen der alle n ADC-Werte eine Variable erhöht bzw. deren Bits verschiebt, wie bei einem Bargraphen. Diese Variable gibst Du dann auf dem LED-Port aus.
1. Eine Tabelle mit 8 Einträgen im Flash ablegen: Tabelle: ; "eine LED leuchtet" bis "alle 8 LEDs leuchten" .DB 0b11111110, 0b11111100 .DB 0b11111000, 0b11110000 .DB 0b11100000, 0b11000000 .DB 0b10000000, 0b00000000 2. Den ADC-Wert 5 mal nach rechts schieben. Das ergibt einen Wert zwischen 0 und 7. Diesen Wert als Index auf die Tabelle verwenden. Tabelleneintrag mit 'lpm' auslesen und auf den Port mit den LEDs schreiben. Ich zähle 11 Assemblerbefehle für alles:
1 | ; 8-Bit-ADC-Rohwert in Register t |
2 | lsr t |
3 | lsr t |
4 | lsr t |
5 | lsr t |
6 | lsr t |
7 | ldi ZL, Low (2*Tabelle) |
8 | ldi ZH, High(2*Tabelle) |
9 | add ZL, t |
10 | adc ZH, _0 ; Register _0 immer = 0 |
11 | lpm |
12 | out PORTB, r0 |
Falls Du auch noch den Zustand "alle LEDs aus" haben willst, wirds einen Tick komplizierter (selbst überlegen).
>Wenn ADCWert= 0, soll keine LED leuchten, bei ADCWert 255 sollen alle >acht LEDs leuchten. Wenn der ADCWert zwischen 1 und 32 liegt, soll die >erste LED leuchten, wenn der ADCWert 32-64 ist, soll die erste und >zweite LED leuchten usw. >Ich weiß leider nicht, wie ich das genau umsetzen soll. Ich könnte >mehrere if / if else Abfragen nehmen oder das ganze über switch >gestalten.
1 | switch (ADC_Wert>>5) |
2 | {
|
3 | case 0: PORTxy = 0b00000000; break; |
4 | case 1: PORTxy = 0b00000001; break; |
5 | case 2: PORTxy = 0b00000011; break; |
6 | case 3: PORTxy = 0b00000111; break; |
7 | case 4: PORTxy = 0b00001111; break; |
8 | case 5: PORTxy = 0b00011111; break; |
9 | case 6: PORTxy = 0b00111111; break; |
10 | case 7: PORTxy = 0b01111111; break; |
11 | }
|
Hallo, ich habe mal folgende Version getestet:
1 | switch (ADC_Wert>>5) |
2 | {
|
3 | case 0: PORTxy = 0b00000000; break; |
4 | case 1: PORTxy = 0b00000001; break; |
5 | case 2: PORTxy = 0b00000011; break; |
6 | case 3: PORTxy = 0b00000111; break; |
7 | case 4: PORTxy = 0b00001111; break; |
8 | case 5: PORTxy = 0b00011111; break; |
9 | case 6: PORTxy = 0b00111111; break; |
10 | case 7: PORTxy = 0b01111111; break; |
11 | }
|
Ich hab das Problem, dass von Anfang an die erste LED leuchtet und wenn ich dann an dem Poti drehe und die Spannung am ADC erhöhe, gehen weitere LEDs an bis acht Stück leuchten. eigentlich sollten doch nur 7 leichten maximal nach dem obigen code oder verstehe ich da was falsch und es sollte auch vorkommen, dass keine LED leuchtet, aber es leuchtet immer mindestens die erste LED. Da steig ich nicht ganz durch.
Wahrscheinlich: Wenn die LEDs wie üblich gegen VCC geschaltet sind, dann leuchten die acht LEDs wegen der Zeile "PORTxy = 0b00000000" und die eine LED am anderen Potiende leuchtet wegen der Zeile "PORTxy = 0b01111111". >und die Spannung am ADC erhöhe Erhöhst oder erniedrigst? Miss mal mit nem Multimeter direkt am Poti nach.
Ahhhhhhh, ok ein Teil hat sich erledigt...Ich muss das ganze invertieren, um die LEDs zum leichten zu bringen...... Aber wie bekomme ich die achte LED zum leuchten?
>Aber wie bekomme ich die achte LED zum leuchten?
Meine Operation ADC_Wert>>5 ist ja dasselbe wie eine Teilung durch 32.
Somit teilst du die 256Werte des Potis in 8 Zustände (0..7).
Willst du Null bis alle acht Leds leuchten lassen, musst du neun
Zustände erzeugen.
1 | switch ( ADC_Wert / (uint8_t)(256/9) ) |
2 | {
|
3 | case 0: PORTxy = 0b11111111; break; |
4 | case 1: PORTxy = 0b11111110; break; |
5 | case 2: PORTxy = 0b11111100; break; |
6 | case 3: PORTxy = 0b11111000; break; |
7 | case 4: PORTxy = 0b11110000; break; |
8 | case 5: PORTxy = 0b11100000; break; |
9 | case 6: PORTxy = 0b11000000; break; |
10 | case 7: PORTxy = 0b10000000; break; |
11 | case 8: PORTxy = 0b00000000; break; |
12 | }
|
Hallo, vielen Dank! Nun funktioniert es....Hab mal durch die Bitverschiebung wieder nicht ganz so durchgeblickt, bzw. mich mal wieder ein wenig verwirren lassen. Vielen Dank. Grüeß Volker
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.