Hallo zusammen,
ich beginne gerade damit Assembler programmieren zu lernen.
Ich habe mir das Entwicklungsboard "Rumpus" von
http://www.lochraster.org/rumpus/ zusammengelötet, welches mit einem
Atmel ATMega168PU-20 bestückt ist. Erste LEDs habe ich schon zum
leuchten bringen können, das Testprogramm des Herstellers läuft gut.
Zu meinem Problem:
Ich möchte mit dem Schalter an S1 (Port C, PC0) die LEDs an Port D
(PD3,PD6,PD7) zum leuchten bringen, solange der Taster gedrückt ist.
Leider leuchten die LEDs mit dem folgenden Programm schon vor dem
Drücken des Tasters mit halber Leuchtkraft. Der Tastendruck bringt sie
dann voll zum Leuchten.
Eigentlich ist die Funktion also schon fast da...irgendwas ist aber noch
faul.
---------------------------------------------
1
.include "m168def.inc"
2
3
main:
4
ldi r16, 0x00
5
out ddrc, r16 ; Port C komplett Eingang
6
7
ldi r16, 0xff
8
out portc, r16 ; Port C PullUps high
9
10
out ddrd, r16 ; Port D Ausgang
11
12
ldi r16, 0xff
13
out portd, r16 ; Port D komplett low
14
15
16
warten_auf_S1:
17
sbis pinc, pc0 ; Weiter wenn S1 gedrueckt wird
18
rjmp warten_auf_S1
19
rjmp wenn_S1_gedrueckt
20
21
wenn_S1_gedrueckt:
22
ldi r17, 0x00
23
out portd, r17
24
rjmp main
-----------------------------------------------
Die Suchfunktion konnte mir leider nicht helfen.
Vielen Dank
Christian
sbis pinc, pc0 ; Weiter wenn S1 gedrueckt wird ;invertiert, da Pullup + Taster gegen GND
18
rjmp warten_auf_S1 ;mit Tastendruck
19
rjmp wenn_S1_gedrueckt ;ohne Tastendruck
20
21
wenn_S1_gedrueckt:
22
ldi r17, 0x00 ;macht, wenn Taste nicht gedrückt ständig ein und aus (50% PWM), da (unter anderem) ständig zwischen main und wenn_S1_gedrueckt gewechselt wird. einmal wird portd eben auf 255 und einmal auf 0 gesetzt.
23
out portd, r17
24
rjmp main
Hoffe, dass stimmt soweit (mit meinem Asm-Halbwissen)...
Vorschlag: In der main 0x00 laden, das mit dem invertieren beherzigen,
bei wenn_S1_gedrueckt 0xff laden und rjmp auf warten_auf_S1.
Deine Main ist nämlich nicht wirklich als Dauerschleife geeignet. Du
solltest dir einen Init-Block anlegen, der einmal aufgerufen wird.
Gruß
Michael
also ich muss gestehen ich bin in assembler auch nciht sooo die leuchte,
aber wenn Oxff den kompletten Kanal auf LOW schaltet. (was mich
irritiert weil es in C den kompletten Kanal auf High schaltet) dann
würde ich vermuten dass Ox00 den Kompletten auf High schaltet und damit
den LEDs anmacht^^^....
das halbe leuchten sieht aber für mich danach aus dass die LEDS nicht
als ausgang geschaltet sind...
> ldi r16, 0xff> out portd, r16 ; Port D komplett low
0xFF bedeutet alle 8 Bits high. Nicht low!
Ich gehe mal davon aus, Deine LEDs sind zwischen Vcc und den AVR-Pin
geschaltet? Schaltplan hast Du ja leider nicht beigefügt.
Übrigens ist es auch unschön, die Ports bei jedem Schleifendurchlauf neu
zu initialisieren. Sowas macht man einmal und dann ändert sich
eigentlich nichts mehr daran (weil sich an der extenen Beschaltung ja
auch nichts ändert). Bidirektionale Bussysteme, für die man eine
Umschaltung zwischen Ein- und Ausgang brauchen würde, sehe ich da nicht.
.include "m168def.inc"
Init:
ldi r16, 0x00
out ddrc, r16 ; Port C komplett Eingang
ldi r16, 0xff
out portc, r16 ; Port C PullUps high
out ddrd, r16 ; Port D Ausgang
ldi r16, 0xff
out portd, r16 ; Port D komplett low
Main:
warten_auf_S1:
...
Leider weiss ich nicht, wie die Led und der Taster angeschlossen sind.
(gegen GND oder VCC)
Das Problem aber liegt daran, dass Du immer wieder zu Main springst, und
damit die evt. leuchtende Led sofort wieder ausschaltest.
warten_auf_S1:
sbis pinc, pc0 ; Weiter wenn S1 gedrueckt wird - vertauscht?
rjmp warten_auf_S1
rjmp wenn_S1_gedrueckt
wenn_S1_gedrueckt:
ldi r17, 0x00
out portd, r17
rjmp main
der Beitrag von Michael hat sehr geholfen!
Mein Dank gilt trotzdem euch allen!
@Tobi:
Hast du bedacht, dass meine Leds auf GND liegen?
Liebe Grüße
Christian
Du hast das Problem zwar schon gelöst, aber für Lernzwecke schau Dir das
mal an.
.include "m168def.inc"
main:
ldi r16, 0x00
out ddrc, r16 ; Port C komplett Eingang
ldi r16, 0xff
out portc, r16 ; Port C PullUps high
out ddrd, r16 ; Port D komplett Ausgang
L1:
ldi r16, 0x00 ; LED an
sbis pinc, pc0 ; weiter wenn S1 gedrueckt wird
ldi r16, 0xFF ; LED aus
out portd, r16 ; an- oder ausschalten
rjmp L1
>@Tobi:>Hast du bedacht, dass meine Leds auf GND liegen?
woher sollte er das wissen ?
viele Gruesse
herrmueller
Ich habe nicht daran gedacht zu erwähnen, dass der Schaltplan unter dem
Link im ersten Post zu finden ist. Die Taster, sowie die LEDs liegen
alle auf GND. Deswegen sind die ersten Schritte mit dem Tutorial hier
auch etwas umständlich.
Die Variante von Herrn Mueller wird heute abend ausprobiert. Ich lerne
wie gesagt noch und bin dankbar für alle Hinweise.
Muss ich den Thread hier irgendwie als gelöst kennzeichnen?
Danke + Gruß
Christian
Ben _ schrieb:> Naja ist schön kurz, aber solange ich keinen Speicher sparen muß find> ich das ständige neu-setzen des Ports auf 0x00 unschön.
Den Einwand verstehe ich nicht ganz. Wenn die Taste gedrückt ist, ist
der Port 0, wenn nicht $FF, genau wie im Programm darüber. Ich finde es
nur übersichtlicher, weil sich alles innerhalb einer Schleife abspielt.
herrmueller