Forum: Mikrocontroller und Digitale Elektronik ATMega168PU-20 Assembler - Leds leuchten ungewollt


von Christian383 (Gast)


Lesenswert?

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

von Michael (Gast)


Lesenswert?

Hallo,

ohne, dass ich jetzt Assembler kann:
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     ;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

von Tobi L. (derarzt)


Lesenswert?

Christian383 schrieb:

> ---------------------------------------------
>
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
25
>


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...

von Ben _. (burning_silicon)


Lesenswert?

> 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:
...

von Herr M. (herrmueller)


Lesenswert?

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

von Christian S. (christian_s78)


Lesenswert?

Hallo nochmal,

Problem folgendermaßen gelöst...
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 komplett Ausgang
11
  
12
    
13
warten_auf_S1:
14
  
15
  sbis pinc, pc0      ; weiter wenn S1 gedrueckt wird
16
  rjmp wenn_S1_nicht_gedrueckt    
17
  ldi r16, 0x00      
18
  out portd, r16      ; Port D high    
19
  rjmp warten_auf_S1
20
  
21
wenn_S1_nicht_gedrueckt:
22
  ldi r17, 0xff
23
  out portd, r17
24
  rjmp warten_auf_S1

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

von Herr M. (herrmueller)


Lesenswert?

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

von Ben _. (burning_silicon)


Lesenswert?

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.

von Christian S. (christian_s78)


Lesenswert?

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

von Herr M. (herrmueller)


Lesenswert?

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

von Ben _. (burning_silicon)


Lesenswert?

Hat halt jeder seine Vorlieben... :) Vor allem bei Assembler.

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
Noch kein Account? Hier anmelden.