Eingangsport auslesen und in den Ausgang(port) schreiben

OP #2118409
Lesenswert?

Hallo Freunde !
Wieder mal komme ich als Anfänger nicht weiter. Ich möchte gerne einen 
Port"D" bitweise auslesen und die pegel an den Port"B" als Ausgang 
schreiben, in einer Schleife und bekomme es einfach nicht hin weder in 
Bascom noch Assembler...
Ich habe versucht :

.....
...
config PortD = input
config PortB = output
dim P as bit

do
P = PortD.0
PortB.0 =P
....
....
P= PortD.7
PortB.7 = P
loop

end

-----------------------------------------

in ASSR:
------------

.include "m8515def.inc"      ; Definitionsdatei für den Prozessortyp

         ldi r16, 0xFF       ; lade Arbeitsregister r16 mit der 
Konstanten 0xFF
         out DDRB, r16       ; Inhalt von r16 ins IO-Register DDRB 
ausgeben

         ldi r16, 0b11111111 ; 0b11111111 in r16 laden
         out PORTB, r16      ; r16 ins IO-Register PORTB ausgeben

abfrage:    ldi r17, PORTD

      out PORTB, r17


    rjmp abfrage           ; Sprung zur Marke "abfrage" -> 
Endlosschleife

-----------------------------------------

es kann ja sein das meine Gedankengänge grundlegende Fehler haben, wie 
gesagt bin ja noch im Lernen..

Am Port D ist  jeder Pin eingangsmässig low-aktiv, d.h. bei Auslösung 
einer Schaltaktion wird der Pegel von Hi nach Low gezogen. Dann soll der 
entsprechende Pin im B-Port ebenfalls nach Low gehen.
Damit will ich erst mal die Funktion erreichen, später kommen noch 
programmierte Bedingungen dazu wie sich das mit Eingan -Low- und Ausgang 
-Hi- verhält, es soll ein Kontrollbaustein werden, der 8 Eingänge 
überwacht und diese dann Programmbedingt auf den Port B signalisiert..
Als Chip soll der 8515 erst mal in Betracht kommen, aber es geht mir ja 
erst mal darum die Funktion der Ports so zu erreichen wie oben erwähnt.

Gruss und Dank

Gerhard
Gast #2118418
Lesenswert?

Du willst nicht den Port lesen, sondern den Pin
Auszug aus Bascom

reading the PORT, will read the latch, that is the value
you have written to the PORT.
This is not the same as reading the logical values on the pins!
When you want to know the logical state of the attached hardware,
you MUST use the PIN register.
Gast #2118430
Lesenswert?

Auch Dir kann ich nur sagen. Schreibe hinter jeden Befehl was du dir da 
gedacht hast. So wirst du Merken das Du gar nicht soviel dabei denkst.
1
         ldi r16, 0xFF       ; lade Arbeitsregister r16 mit der Konstanten 0xFF
2
         out DDRB, r16       ; Inhalt von r16 ins IO-Register DDRB ausgeben
3

4
         ldi r16, 0b11111111 ; 0b11111111 in r16 laden
5
         out PORTB, r16      ; r16 ins IO-Register PORTB ausgeben

Nicht beschreiben was der Befehl macht sondern warum Du ihn machst.

So wird Dir z.B. auffallen das du r16 nicht mit 0b11111111 laden musst 
da du ihn ja vorab mit 0xFF geladen hast und er sich seitdem nicht 
geändert hat.

Nein das ist nicht dein Fehler aber Zeigt auf das Du nicht mitdenkst bei 
dem was Du machst.

Also fein hinter jedem Befehl schreiben warum du das machst was du damit 
bezwecken möchtest. Und schwups die Wups wird Dir geholfen :-)
Moderator (Firma: Titel) Persönliche Seite #2118444
Lesenswert?

1
      ldi r16, 0xFF       ; lade Arbeitsregister r16 mit der Konstanten 0xFF
2
      ldi r16, 0b11111111 ; 0b11111111 in r16 laden
Das sind überhaupt die allerblödsten Kommentare, den es je geben kann.
Denn morgen nehme ich diese Zeile, kopiere sie und passe sie an:
1
      ldi r16, 0xFE       ; lade Arbeitsregister r16 mit der Konstanten 0xFF
Und vergesse dabei den Kommentar...

Vivil schrieb:
> Auch Dir kann ich nur sagen. Schreibe hinter jeden Befehl was du dir da
> gedacht hast.
> So wird Dir z.B. auffallen...
Das Dahinterschreiben hilft da überhaupt nichts, man muß Sehen und 
Erkennen was man da tut, und da hilft nur Übung...
Gast #2118479
Lesenswert?

Wenn er hinter seinen befehl schreibt warum er das macht was er sich 
dabei denkt wird ihm auffallen das es zwei die gleichen gedankengänge 
sind.

lass sie doch mal überlegen. und da der E da schon nicht mit anfängt 
mitzuarbeiten warum sollten ihm dan user aus dem forum alles vorkauen?
Gast #2118496
Lesenswert?

Vivil schrieb:
> Für ein Anfänger hilft es sehr viel weil er merkt das er da nicht denkt.
> Seine Gedanken zu Selektieren, Sortieren ist das a und o.

Das ist im Prinzip ja auch nicht falsch. Nur in dem Kommentar sollte 
nicht die Erklärung des Befehls stehen. Sondern zusatzliche 
Informationen, die nicht direkt aus dem lesen des Quelltextes 
ersichtlich sind.

z.B. so:
  /////////////////////////////////////////////////////////
  // Timer 2 konfigurieren, wird für das multiplexen der LEDS benötigt
  // alle 0,1 ms wird ein CompareMatch-Interrupt ausgeloest

  TCCR2  = (1<<CS01);   // Prescaler CPU/8
  TCCR2 |= (1<<WGM01);  // CTC-Modus einstellen
  OCR2 = 149;           // OCR2-Register laden für 0,1 ms
  TIMSK |= (1<<OCIE2);  // CompareMatch-Interrupt aktivieren

ist zwar "C" aber fürs Prinzip:

Programm in einezelne kleinere Blöcke aufteilen. Am Anfang eines Blockes 
schreiben was er bewirken soll.
Die Zeile selber ist eigentlich selbst erklärend. Da ich mir aber die 
Register und deren Bezeichnungen nicht alle Merken kann, habe ich mir 
hier ebenfalls dahinter geschrieben was diese Zeile bewirken soll.
Das ersparte mir schon so manchmal einen Blick ins Datenblatt.

just my 2 cent
Dietmar
Gast #2118623
Lesenswert?

Hi

>in einer Schleife und bekomme es einfach nicht hin weder in
>Bascom noch Assembler...

>abfrage:    ldi r17, PORTD

Damit lädst du r17 mit der Adresse ($12) von PORTD.

Den Zustand der Pins bekommst du mit 'in r17,PIND'.

MfG Spess
OP #2118774
Lesenswert?

Hallo Freunde,

Habt vielen Dank für alle Erläuterungen und Hinweise, ich habe mich auch 
vielleicht falsch noch ausgedrückt , weiss immer noch nicht so recht wie 
ich es beschreiben soll, eben noch Anfänger der lernt.
Ich mache zur Zeit die Schaltung fertig und stelle sie dann auf meinen 
Webspace, da kann man vieleicht besser erkennen was ich da meine..

Vorerst allen recht herzlichen Dank, Ihr seid wie immer, mir eine grosse 
Hilfe !!

Gruss Gerhard
Gast #2118800
Lesenswert?

Vivil schrieb:
> ldi r16, 0xFF       ; lade Arbeitsregister r16 mit der Konstanten 0xFF
>          out DDRB, r16       ; Inhalt von r16 ins IO-Register DDRB ausgeben
>
>          ldi r16, 0b11111111 ; 0b11111111 in r16 laden
>          out PORTB, r16      ; r16 ins IO-Register PORTB ausgeben
>
> Nicht beschreiben was der Befehl macht sondern warum Du ihn machst.

DU selbst hast in Deinem Beispiel unübertreffbar genau das exakte 
Gegenteil von dem gemacht, was Du (völlig korrekterweise!) als falsch 
beschreibst:

Du dokumentierst dort lediglich, WAS Du programmierst (oder treffender: 
was die CPU ausführt), OHNE auch nur anzudeuten, WARUM.

Sonst hättest Du bspw. in den Kommentaren darauf hingewiesen, daß Du 
Einser-Bit nicht "nur einfach nur so" in das DDRB Register schreibst, 
sondern weil die CPU den jeweils dazugehörenden Port-Pin als Ausgang 
verwenden soll.

Oder noch besser - um Dich noch näher dem praktischen Betrieb des 
Systems anzunäheren - mußt Du im Kommentar erklären, warum das eine oder 
andere Port überhaupt gegenüber dem Post-Reset-Status des Controllers 
als Ausgang eingerichtet werden muß.

Also erklären, welche Systemanforderung jeder einzelne Programmschritt 
wie erfüllt.

Erst Beschreibungen dieser Qualität sind kompatibel mit Deiner eigenen 
Forderung.

Das was Du im Beispiel oben rechts hinter die Semikoli "gedichtet" hast, 
ist dagegen nichts weiter als eine sinngemäße 1:1-Wiedergabe aus der 
Befehlssatzbeschreibung des Controllers - und entsprechend redundant.

MfG
Gast #2118882
Lesenswert?

Wenn Du schon Erbsen zählst so zähle richtig.

Das war ein  Auszug aus seinem Code wie du oben nachlesen kannst.
Also auch Du erst Denken, richtig lesen und dann motzen.

Also hau mich hier nicht so an, schon klar das in diesem Forum dieses 
gerne gemacht wird. Aber Obacht wenn schon dan richtig grins
OP #2119021
Lesenswert?

Hallo Leute, bitte streitet Euch doch nicht, ich denke jeder kann mal 
was falsch machen oder ein Anderer sieht es anders als man selbst.

So ich habe mal die Schaltung ,noch mehr Entwurf und nicht komplett 
vollständig, ins Web geladen :

http://werkstatt.oderlachs.de/avr/pictures/signal_controll.gif

Diese Schaltung ist noch mit dem AM8535, drum nicht wundern warum ich 
oben vom 8515 schrieb, den habe ich zum experimentieren, vor allem zum 
Lernen auf den STK 500...
Also wird eine der Tasten in der Schaltung betätigt soll der 
entsprechende Ausgang vom µC den dazugehörigen Optokoppler schalten und 
das ziemlich schnell, ein Durchlauf der Portabfrage(Eingang) sollte max 
1 Sec. dauern und dann ausgegeben werden.
Vielleicht ist es jetzt besser zu verstehen, was ich machen möchte, will 
Euch ja auch nicht übermässig mit meinen Anfängerproblemen  belasten.
Später soll dann die Eingabe/Ausgabe etwas präzisiert werden, also Länge 
der Ausgabezeit usw.
Mir geht es aber jetzt nur darum zu wissen, wie ich das vom Eingang auf 
den Ausgang bekomme.
Die Tasten gegen Masse und Optokoppler gegen +5V habe ich darum gewählt, 
um es auf dem STk nachvollziehen zu können.

Ich dank Euch schon mal im Voraus, für Hilfe und Ratschläge

Gerhard

Edit 1: Morgen oder übermorgen werde ich mal schreiben wie ich mit dem 
Programm überhaupt was weiter gekommen bin, habe nicht immer so Zeit 
dafür.
OP #2119244
Lesenswert?

Also zumindestens habe ich den Schritt geschafft mit den Eingangspegeln 
die Ausgangspegel zu schalten, allerdings mit anderen Port.
ich habe bei RN-Wissen.de dazu folgenes in einem Assembler-Tutorial 
gefunden

Hier das Zitat:
Beispiel

An PORTC haben wir (mit Vorwiderständen) ein paar LEDs angeschlossen. 
Und die sollen einfach nur zeigen, welche 0-er und 1-er am PORTB 
anliegen.

 ; Eigene Initialisierungen
  LDI R24, 0            ; der wert "0" ins allgemeine Register R24
  OUT DDRB, R24         ; das kommt ins Controll-register f. PortB
                        ; dadurch sind diese PINs als INPUT festgelegt
  LDI R24, 255          ; der wert "255" = FF ins allgemeine Register 
R24
  OUT DDRC, R24         ; das kommt ins Controll-register f. PortC
                        ; dadurch ist das Port auf OUTPUT gestellt

 ; Eigene Befehle (in der Hauptschleife)
  IN  R24, PINB         ; die Bits vom PortB ins allgemeine Register R24
  OUT PORTC, r24        ; schreiben wir nach PortC
                        ; wo ein 1-er ist, leuchtet nun die LED

Wenn wir diese Befehle in das Programm-Schema oben einfügen, haben wir 
also das erste Assemblerprogramm schon geschrieben.
.........

Zitatende

Nur eines begreife ich dabei nicht wie es zu der "Hauptschleife" kommt, 
ich habe nur folgenden Code daraus gemacht, d.h. die erste Zeile 
hinzugefügt :

.include "m8515def.inc"

  LDI R24, 0            ; der wert "0" ins allgemeine Register R24
  OUT DDRB, R24         ; das kommt ins Controll-register f. PortB
                        ; dadurch sind diese PINs als INPUT festgelegt
  LDI R24, 255          ; der wert "255" = FF ins allgemeine Register 
R24
  OUT DDRC, R24         ; das kommt ins Controll-register f. PortC
                        ; dadurch ist das Port auf OUTPUT gestellt

 ; Eigene Befehle (in der Hauptschleife)
  IN  R24, PINB         ; die Bits vom PortB ins allgemeine Register R24
  OUT PORTC, r24        ; schreiben wir nach PortC


und schon geht es...
Gast #2119260
Lesenswert?

Hi

>Nur eines begreife ich dabei nicht wie es zu der "Hauptschleife" kommt,
>ich habe nur folgenden Code daraus gemacht, d.h. die erste Zeile
>hinzugefügt :

Meinst du die:  .include "m8515def.inc" ?

Wenn ja: Dadurch weiss der Assembler erst, welche Adresse Portx, ... 
haben.
Die sind bei unterschiedlichen AVRs durchaus verschieden.

> LDI R24, 255

benutze bitte LDI R24,0b11111111 oder LDI R24,$FF (0xFF). Dezimalzahlen 
sind an der Stell irreführend bzw. total unverständlich.

MfG Spess
OP #2119282
Lesenswert?

Hallo Spess !
Ja ich verstehe das schon mit der Dezimalzahlangabe, das mit binärem 
Wert sieht mann auch gleich das Bitmuster, ist mir auch klar.
Ich habe auch das nur so org. aus dem Tuto übernommen, das mit der 
m8515def.inc ist mir auch verständlich , dort werden dem Compiler die 
Adressen für die Worte wie PortA,DDRB usw.. übergeben. Man müsste wohl 
sonst den Code in kopfzermarternden Adressangaben schreiben, aus C64er 
Zeit mir noch gut bekannt...

Was ich nicht verstehe ist hier :
IN  R24, PINB         ; die Bits vom PortB ins allgemeine Register R24
OUT PORTC, r24        ; schreiben wir nach PortC

Wie kommt der Progcounter nach der Abarbeitung der out ... Anweisung 
wieder zurück in die In... Anweisung, um PortB neu abzufragen, ob sich 
da was geändert hat ??

Aber je mehr Probleme ich habe um so mehr muss ich lernen und das ist 
gut !!

Euch Allen, auch natürlich besten Dank für alle Hilfe !!!

Gerhard
Gast #2119297
Lesenswert?

Hi

>Was ich nicht verstehe ist hier :
>IN  R24, PINB         ; die Bits vom PortB ins allgemeine Register R24
>OUT PORTC, r24        ; schreiben wir nach PortC

>Wie kommt der Progcounter nach der Abarbeitung der out ... Anweisung
>wieder zurück in die In... Anweisung, um PortB neu abzufragen, ob sich
>da was geändert hat ??

Eigentlich gar nicht. Wenn allerdings der Rest des Programmspeichers 
durch Löschen mit $FF gefüllt ist, wird er wohl bis zum Speicherende 
durchlaufen und dann von vorn wieder anfangen.
Um eine Programmschleife zu erhalten, musst du folgendes machen:

label:
  IN  R24, PINB         ; die Bits vom PortB ins allgemeine Register R24
  OUT PORTC, r24        ; schreiben wir nach PortC
  rjmp label            ; Sprung nach label

Wobei 'label' ein Bezeichner deiner Wahl ist.

MfG Spess
OP #2119315
Lesenswert?

Danke Spess,  habe selbiges eben gemacht "rjmp schleife"...geht

Danke Paul, ja das mit dem PinD  o.ä.  ja das weiss ich noch nicht alles 
so genau aus dem Kopf, meine ersten IO-Schritte dieser Art, die ich 
mache... Danke für den Hinweis.

Ich freue mich ja so ,daß ich hier nachfragen darf, wenn ich mich auch 
manchmal böd anstelle, aber so im "Selbststudium" erkennt man seine 
eigenen Fehler schlecht selber.. ;)

Ich habe vor 15 Jahre mal Assembler 8085 gemacht, davor noch  mit dem 
C64er. da ist ein wenig hängen geblieben, aber sind die Mnemonik und die 
Bezeichner doch oft anders, gerade in ASSR bei verschiedenen Chips...

Gruss Gerhard
Gast #2119334
Lesenswert?

Hi

>Ich habe vor 15 Jahre mal Assembler 8085 gemacht, davor noch  mit dem
>C64er. da ist ein wenig hängen geblieben, aber sind die Mnemonik und die
>Bezeichner doch oft anders, gerade in ASSR bei verschiedenen Chips...

Ich habe in den 80-ern mit dem U880(Z80) angefangen. Mit dem 
Hintergrundwissen fand ich den Einstieg bei den AVRs nicht sehr 
kompliziert.

Sie dir mal in Ruhe das Instruction Set an:

http://www.atmel.com/dyn/resources/prod_documents/doc0856.pdf

MfG Spess

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren