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