Forum: Mikrocontroller und Digitale Elektronik ATmega 8 Verständnisproblem (Assembler)


von Daniel M. (Gast)


Lesenswert?

Hallo,

Ich habe da ein Verständnisproblem. Ich besitze das Atmel Evaluation 
Borad von Pollin und betreibe es mit einem ATmega8.

Ich habe folgendes vor:
Ich möchte per Taster der an PORTD 5 liegt eine LED anschalten die an 
PORTD 6 liegt anschalten.

Ich habe folgenden Code

.include "m8def.inc"
.def tmp = r19

init:
;Stackpointer setzen
  ldi tmp, LOW(RAMEND)
  out SPL, tmp
  ldi tmp, HIGH(RAMEND)
  out SPH, tmp

prog:
;Port auf Eingabe stellen
  ldi tmp,0b11101111
  out DDRD, tmp

loop:
;Port auslesen
  in r16,PIND
  ldi r17, 0b00010000
  cp r16,r17
  brne loop
;Port auf Ausgabestellen und LED an
  ldi tmp,0b00100000
  out DDRD,tmp
  out PORTD,tmp

end:
  rjmp end

Das gewünschte Verhalten das ich mir von diesem Code verspreche ist, ich 
drücke den Schalten die LED leuchte und bleibt an beim loslassen.

Das Ergebnis was ich aber bekomme ist die LED leuchtet nur wenn der 
Taster gedrückt ist.

Der Prozessor müsste doch eigentlich in einer Endlossschleife hängen??

Vielen Dank für die Hilfe

Gruß Daniel

von Justus S. (jussa)


Lesenswert?

Daniel M. wrote:

> Das Ergebnis was ich aber bekomme ist die LED leuchtet nur wenn der
> Taster gedrückt ist.

kann eigentlich nicht sein, du fragst D4 ab und setzt D5...

von holger (Gast)


Lesenswert?

Watchdog Fuse abschalten.

von Jean P. (fubu1000)


Lesenswert?

Daniel M. wrote:
> Ich habe folgendes vor:
> Ich möchte per Taster der an PORTD 5 liegt eine LED anschalten die an
> PORTD 6 liegt anschalten.

Nach deinem Code liegt der Taster eher an PD4 und die LED an PD5.

Also:
 ;Port auf Eingabe stellen
   ldi tmp,0b11011111
   out DDRD, tmp
 loop:
 ;Port auslesen
   sbis PIND, 5
   rjmp loop
 ;Port auf Ausgabestellen und LED an
   sbi PORTD, 6

 end:
   rjmp end

> Das gewünschte Verhalten das ich mir von diesem Code verspreche ist, ich
> drücke den Schalten die LED leuchte und bleibt an beim loslassen.

Ein Wunder.

> Der Prozessor müsste doch eigentlich in einer Endlossschleife hängen??

Falls deine Pin Besschreibung stimmt, haste wahrscheinlich nen 
Kurzschluß an PD5 und 6. Oder die Pin Beschreibung von dir oben ist 
Mist.

von Karl H. (kbuchegg)


Lesenswert?

Daniel M. wrote:

> Ich möchte per Taster der an PORTD 5 liegt eine LED anschalten die an
> PORTD 6 liegt anschalten.

Wie sind die Taster angeschlossen?
Wie ist die LED angeschlossen?

Wenn der Taster nichtgedrückt ist, was bekommst du? Eine 1 oder eine 0? 
Brauchst du Pullup Widerstanände für die Taster oder sind die extern 
verbaut?
Wie muss der LED Ausgabepin gesetzt werden, damit die LED leuchtet? Auf 
0 oder auf 1?


> init:
> ;Stackpointer setzen
>   ldi tmp, LOW(RAMEND)
>   out SPL, tmp
>   ldi tmp, HIGH(RAMEND)
>   out SPH, tmp

An dieser Stelle solltest du die DDR Register richtig stellen, und ab da 
dann in Ruhe lassen. Für den Anfang ist es sicherer, die 
Port-Einstellungen als Initialisierung anzusehen: einmal einstellen und 
dann bleibt der komplette Port so eingestellt.

>  ldi tmp,0b11101111
>  out DDRD, tmp

Schreib das besser als:

   ldi tmp, 1 << PD7 | 1 << PD6 | 1 << PD5 |
            1 << PD3 | 1 << PD2 | 1 << PD1 | 1 << PD0

dann muss man nicht lange Bits zählen um zu wissen, welcher Pin denn nun 
auf Ausgang geschaltet ist. BTW. Warum schaltest du so viele Pins auf 
Ausgang, wenn doch eh nur an einem eine LED hängt?

> loop:
> ;Port auslesen
>   in r16,PIND

Dir ist schon klar, dass du hier nicht nur den Zustand von PD4 bekommst, 
sondern vom kompletten Eingabe Port. Die restlichen Pins, an denen kein 
Taster hängt, haben auch irgendeinen Wert.

>   ldi r17, 0b00010000

schreib das besser als:
    ldi r17, 1 << PD4

Macht genau dasselbe aber man braucht nicht lange Bits zählen um zu 
wissen, welches Bit gemeint ist.

>   cp r16,r17

Wie gesagt: in r16 stehen die Zustände aller 8 Eingapepins dieses Ports. 
Nicht nur der von PD4. Wenn r16 gleich r17 ist (in dem nur PD4 gesetzt 
ist), dann ist das Zufall, da du dich nicht um die restlichen Bits in 
r16 gekümmert hast (zb. mittels einem ANDI definiert auf 0 gesetzt hast)

>   brne loop
> ;Port auf Ausgabestellen und LED an
>   ldi tmp,0b00100000

    ldi tmp, 1 << PD5

>   out DDRD,tmp

Dir ist hoffentlich auch klar, dass du hier auch deinen Eingabpin auf 
PD4 ebenfalls beeinflusst. In dem Fall ist das egal, weil PD4 auch 
vorher schon auf Eingang war. Im Grunde ist das hier überflüssig, da 
auch PD5 vorher schon auf Ausgang war.
-> Gewöhn dir an: In der Initialisierungsphase werden die DDR Register 
richtig eingestellt, und dann lässt man sie in Ruhe. Es sei denn, man 
muss dezidiert einen Pin in der Richtung umschalten. Aber dann muss man 
besondere Vorsicht walten lassen, damit man die Konfiguration der 
anderen Pins nicht verändert.

>   out PORTD,tmp
>
> end:
>   rjmp end

von Daniel M. (Gast)


Lesenswert?

Ja die Beschreibung der Ports ist nicht richtig. Schalter an PD4 und LED 
an PD5. Aber die Binärekonstanten im Code sind richtig. Ich hab das 
ganze mal Testweise an einen anderen Schalter geschaltet der an PD2 
angeschlossen ist. Verhält sich gleich. LED nur an wenn der Schalter 
gedrückt wird.

Mein Board habe ich gerade nicht in Reichweite aber ich bin mir sicher 
das ich das FUSE WTDON mit PONYPROG gesetzt habe (Haken) das entspricht 
ja einer 0.

Ich hab das ganze gestern auch mal mit einem Multimeter nachgemessen.

Schalter gedrückt PD4 5V PD5 5V
Schalter nicht gedrückt PD4 0V PD5 0V

Wenn der Code richtig ist kann es ja nur sein das der µC irgendwie 
resetet wird. Dann habe ich mir mal das RESET Pin angeschaut. An dem Pin 
liegt immer 5V an und wird per Schalter gegen Masse geschaltet. Ich denk 
mal das ist wohl so richig.

Gruß
Daniel

von Justus S. (jussa)


Lesenswert?

Daniel M. wrote:

> Mein Board habe ich gerade nicht in Reichweite aber ich bin mir sicher
> das ich das FUSE WTDON mit PONYPROG gesetzt habe (Haken) das entspricht
> ja einer 0.

und 0 bedeutet angeschaltet, also resettet sich der µC die ganze Zeit...

von Daniel M. (Gast)


Lesenswert?

Ich habe den Code mal überarbeitet und danke für die Hilfestellung 
besonderen dank an Karl heinz Buchegger. Das ist mein erstes Prog und 
ich hab eigentlich noch keine Ahnung. Ich werde das ganze mal heute 
Abend ausprobieren im Simulator schaut es schon gut aus.
1
.include "m8def.inc"
2
.def tmp = r19
3
4
init:
5
  ldi tmp, 1 << PD7 | 1 << PD6 | 1 << PD5 | 1 << PD3 | 1 << PD2 | 1 << PD1 | 1 << PD0
6
  out DDRD,tmp
7
  
8
prog:
9
loop:
10
;Port auslesen
11
  in r16,PIND
12
  andi r16,0b00010000
13
  ldi r17, 1 << PD4
14
  cp r16,r17
15
  brne loop
16
;Port auf Ausgabestellen und LED an
17
  ldi tmp, 1 << PD5
18
  out PORTD,tmp
19
20
end:
21
  rjmp end

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.