Forum: Mikrocontroller und Digitale Elektronik Slave Adresse auf einem LCD anzeigen


von Thomas Schmidt (Gast)


Lesenswert?

Hallöchen,

ich arbeite in der Schule an einem Mikrocontroller-Projekt mit
dem AVR 8515. Dazu sollen verschiedene Slave-Module mit einem
Master über einen Bus kommunizieren. Zu diesem Zweck soll über
8 DIP Schalter eine Adresse am Slave von 0-255 einstellbar sein.
Diese DIP Schalter benutze ich am PORTC des AVR.
Mein Problem ist das ich gerne die Adresse die ich als DIP Schalter
einstelle als Dezimalzahl auf einem LCD anzeigen möchte.
Leider kann ich ja nicht einfach das Byte vom PORTC auf das Display
senden da er ja 1 Zeichen interpretiert aber nicht die Dezimalzahl
die ja 3 Byte hätte. Kann mir jemand helfen wie ich dieses in
Assembler realisieren kann ?
Und das zweite ähnliche Problem ist das ich gerne meine Eingänge
auf PORTA als 0 und 1 auch auf dem Display darstellen möchte.
Also praktisch die Ausgabe "PORTA = 00011011" auf dem Display
haben möchte und die Bitfolge meine Eingänge repräsentieren soll.
Wäre wirklich super nett wenn mir jemand helfen könnte !

Liebe Grüße
Thomas

von Jens123 (Gast)


Lesenswert?

hi
schau dir mal die ACSII Tabelle an


in temp1, PORTC
rcall convert      ;2 Stellige Zahl teilen -> temp2 (10), Temp3 (1)
ldi temp, 0b00110000
mov temp1, temp3
or temp1, temp
rcall lcd_data                 ;temp wird ausgegeben
mov temp1, temp2
or temp1, temp
rcall lcd_data

ach ja PUSHen und POPen nicht vergessen sonnst sind bei rcall die
Register von temp bis temp 3 futch bei der LCD Routine aus dem
Tutorial
_______________

convert:
  ldi temp3, 0x00      ; 1te Stelle (1X)
  convert_11:
  cpi temp1, 0x0a
  brsh convert_1

  mov temp2, temp1    ; 2te Stelle (X)

  ret


convert_1:
  ldi temp, 0x0a
  sub temp1, temp
  inc temp3
  jmp convert_11

Das ist so fuer 2 Stellen ausgelegt solltest aber Problemlos fuer 3
Stellen umschreiben koennen

Gruss Jens

von Jens123 (Gast)


Lesenswert?

PS

>Und das zweite ähnliche Problem ist das ich gerne meine Eingänge
>auf PORTA als 0 und 1 auch auf dem Display darstellen möchte.
>Also praktisch die Ausgabe "PORTA = 00011011" auf dem Display
>haben möchte und die Bitfolge meine Eingänge repräsentieren soll.
>Wäre wirklich super nett wenn mir jemand helfen könnte !

nicht dein ernst, dass du damit Probleme hast?????

von Thomas Schmidt (Gast)


Lesenswert?

Hallo Jens,

erstmal vielen Dank für Deine Hilfe.
Ich bin gerade erst dabei richtig Assembler zu lernen und da fehlt es
mir manchmal noch etwas an Vorstellungsvermögen.
In C oder Basic hätte ich für die Bitfolge an PortC einfach
eine IF Anweisung geschrieben und mir einen String gebastelt
den ich an das LCD geschickt hätte aber sowas gibt es ja in Assembler
glaube ich nicht. Deshalb wäre ich wirklich dankbar wenn Du einen
Denkanstoss für mich hättest wie ich die Bitfolge aufs LCD bringe.

Liebe Grüße
Thomas

von Jens123 (Gast)


Lesenswert?

schau dir mal die ascii tabelle an
da steht alles, was du brauchst

in dem fall kannst du die 0 und die 1 einfach mit oder verknuepfen und
somit bekommst du das ascii zeichen raus

von crazy horse (Gast)


Lesenswert?

Sinnvoller wäre wahrscheinlich eine Hex-Anzeige (00...FF)?
In dem Fall einfach high- und low-nibble trennen,
dann prüfen ob >9
nein: 0x30 addieren
ja: 0x37 addieren
Finde ich deshalb sinnvoller, weil die Adressen von Bausteinen auch in
Hex angegeben werden (EEPROM 0xA0 z.B.)
ANsonsten kannst du das Adress-Byte natürlich auch in 3 Dezimal-digits
aufsplitten (durch Division oder fortlaufende Subtraktion),
anschliessend zu jedem Digit 0x30 addieren, dann hast du die Zahl im
Ascii-Format, die du an das Display schicken kannst.

Genauso geht es auch mit der Dual-Anzeige für die Eingänge. Bit für Bit
testen und dann entweder 0x30 (->"0") oder 0x31 (->"1") ausgeben.
Eleganter in einer Schleife, das Register durch carry schieben, je nach
Zustand von c 0x30 oder 0x31 ausgeben, das ganze 8 Mal.

von Andi (Gast)


Lesenswert?

Warum nicht gleich so:

Main:
  in    r20,PORTC
  rcall PrintDez
  ....

PrintDez:
  ldi   r16,'0'-1   ;Startziffer '0' als ASCCI laden
PDez100:
  inc   r16         ;Die auszugebene Ziffer solange um 1 erhöhen
  subi  r20,100     ;und die Zahl solange durch 100 teilen
  brcc  PDez100     ;bis Unterlauf.
  rcall lcd_data    ;Zeichen ausgeben.

  ldi   r16,'9'+1   ;Startziffer '9' als ASCCI laden
PDez10:
  dec   r16         ;Die auszugebende Ziffer solange um 1 verringern
  subi  r20,-10     ;und die Zahl solange durch 10 teilen
  brcc  PDez10      ;bis Überlauf.
  rcall lcd_data    ;Zeichen ausgeben.

  mov   r16,r20     ;Rest von der Ausgabezahl nach r16.
  subi  r20,-'0'    ;Erste ASCII-Ziffer '0' dazu addieren.
  rjmp  lcd_data    ;Zeichen ausgeben.

In r20 wird der auszugebende Wert übergeben.
Der Wert wird erst durch 100 geteilt und währenddessen die
100ter-Stelle ermittel und ausgegeben.
Das gleiche passiert dann für die 10er-Stelle.
Auf die übriggebliebene 1er-Stelle wird dann einfach nur der ASCII-Wert
aufaddiert z. B. bei 2 + ASCII '0' = ASCII '2'.

Für die binäre Anzeige hät ich auch was:

Main:
  in    r20,PORTA
  rcall PrintBin
  ....

PrintBin:
  ldi   r19,8       ;Schleifenzähler für 8 Bit.
PBin1:
    clr   r16       ;r16 löschen.
    lsl   r20       ;Oberes Bit ins Carry-Bit schieben.
    rol   r16       ;Aus dem Carry-Bit nach r16 an die unterste Stelle
    subi  r16,-'0'  ;ASCII-Zeichen aufaddieren.
                    ;Ist je nach Carry dann '0' oder '1'.
    rcall lcd_data  ;Zeichen ausgeben.
    dec   r19       ;Schleifenzähler verringern.
  brne  PBin1       ;Solange wiederholen bis alle 8 Bit angezeigt sind
  ret

Erklärt sich eigentlich von selber.
Oberstes Bit in das Carry-Bit schieben, an die unterste Stelle von r16
und den ASCII-Wert '0' aufaddieren und ausgeben.

Gruß
Andi

von Andi (Gast)


Lesenswert?

Ach ja, verd..... Tippfehler!
Der letzte Block in der Routine "PrintDez" sollte eigentlich so
sein:

  mov   r16,r20     ;Rest von der Ausgabezahl nach r16.
  subi  r16,-'0'    ;Erste ASCII-Ziffer '0' dazu addieren.
  rjmp  lcd_data    ;Zeichen ausgeben.

Gruß
Andi

von Thomas Schmidt (Gast)


Lesenswert?

Hallo Andi,

deine Binär-Bitanzeige klappt wirklich ausgezeichnet !
Ich habe allerdings Probleme mit der DEZ-Umrechnung.
Mein LCD zeigt nur Hyroglyphen an. Welches Register
enthält denn die einzelnen Ziffern ? Das ist doch r16 oder ?

Liebe Grüße
Thomas

von Andi (Gast)


Lesenswert?

Stimmt, in r16 (Temp1 aus dem Tut) ist das auszugebende Zeichen.
Allerdings steckt der Fehlerteufel mal wieder im Detail:

  ldi   r20,197
  rcall PrintDez

HALT:
  rjmp  HALT

PrintDez:
  ldi   r16,'0'-1   ;Startziffer '0' als ASCCI laden
PDez100:
  inc   r16         ;Die auszugebene Ziffer solange um 1 erhöhen
  subi  r20,100     ;und die Zahl solange durch 100 teilen
  brcc  PDez100     ;bis Unterlauf.
  rcall lcd_data    ;Zeichen ausgeben.

  ldi   r16,'9'+1   ;Startziffer '9' als ASCCI laden
PDez10:
  dec   r16         ;Die auszugebende Ziffer solange um 1 verringern
  subi  r20,-10     ;und die Zahl solange durch 10 teilen
  brcs  PDez10      ;bis Überlauf.
  rcall lcd_data    ;Zeichen ausgeben.

  mov   r16,r20     ;Rest von der Ausgabezahl nach r16.
  subi  r16,-'0'    ;Erste ASCII-Ziffer '0' dazu addieren.
  rjmp  lcd_data    ;Zeichen ausgeben.

Da der Zeichencode bei der 10er-Teilung (PDez10) nicht wie bei der
100er-Teilung durch Aufwärtszählen sondern durch rückwärts zählen von
r16 ermittelt wird muß es dort brcs und nicht brcc heißen.
Oben die korrekte Version.
Hatte die beiden kleinen Progs auch hier nur mal schnell reingehackt
und nicht getestet.
Ein Wunder, dass das mit der Bit-Ausgabe PrintBin auf Anhieb geklappt
hat was ich selbst noch nicht getestet habe aber dafür Du.

Wenn Du noch andere (größere) Zahlen, 16, 24 und 32Bit, Dezimal
ausgeben möchtest gibs noch was in der Codesammlung:
http://www.mikrocontroller.net/forum/read-4-127504.html#new
Lies Dir bei Bedarf dazu alles durch und hole Dir dann erst unten die
neueste Version.

Gruß
Andi

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.