Archiv verlassen und diese Seite im Standarddesign anzeigen : Portpins zusammenfügen und 12-bit ausgeben
Hallo!
ich stehe gerade vor einem kleinem Problem.
Die "Aufgabe" lautet:
es soll erstens ein 12 bit breiter Gray-code eingelesen werden.
als eingangsports habe ich portb und portd genommen.
da ein Port nur 8 bit breit ist, nehme ich 2 ports:
Lobyte = Pinb
Hibyte = Pind
Hibyte = Hibyte And &B0000000000001111
so. dann soll das ganze in BCD-code umgerechnet werden.
mit den Befehl Gray2Bin
das wird auch kein Prob sein.
Das problem ist nur der umgerechnete BCD-code soll an ports A und C (auch zusammengefügt) ausgegeben werden.
Wie ich die Ports A und C zusammenfüge ist mir ungefähr klar.
aber wie gebe ich den BCD-Code aus?
Mir feht nur der Befehl. kann mir jemand helfen vielleicht?
Danke schön.
oder einfach mal als beispiel
ich möchte die zahl 100 als binär am portA ausgeben.
wie macht man das?
Ich könnte in Bascom hilfe natürlich gucken, aber ich weiss nicht wonach ich gucken soll.
Sauerbruch
22.04.2008, 13:05
Hibyte = Hibyte And &B0000000000001111
wird nicht klappen - da müssten die ersten 8 Nullen weg.
Wenn ich den letzten Thread noch richtig im Kopf habe, hattest Du als Ergebnis doch ein Word. Wenn Du das auf 2 Ports ausgeben willst, sind die Befehle LOW und HIGH hilfreich.
oder einfach mal als beispiel
ich möchte die zahl 100 als binär am portA ausgeben.
wie macht man das?
PortA = 100 =P~
ja, damals hast du mir sehr geholfen!
Warum müssen die ersten 8 nullen weg? Das ist doch der Eingang. oder verstehe ich was falsch?
Sauerbruch
22.04.2008, 13:18
Weil Du über ein Byte nur 8 Bits "drüberlegen" kannst - und keine 16.
Mit AND &B00001111 setzt Du die ersten 4 Bits des Ports auf 0 (da sie nicht an dem eigentlichen Wert beteiligt sind).
achso.
ich poste mal mein blöbes Programm, was ich bis jetzt habe. vielleicht hilft das ein wenig. und noch was... das sind jetzt 13 bit ;)
$regfile = "m32def.dat"
$crystal = 1000000
Dim Pac As Word
Dim Lobyte As Word
Dim Hibyte As Word
Dim Endlobyte As Word
Dim Endhighbyte As Word
Do
Endlobyte = Pina 'PortA Untere 8 bit (ausgang)
Endhighbyte = Pinc 'portC obere 5 bit (ausgang)
Endhighbyte = Endhighbyte And &B0000000000000111 'Endhighbyte ist also der Ausgang?
Lobyte = Pinb 'Port B untere 8 bit (eingang)
Hibyte = Pind 'portD obere 5 bit (eingang)
Hibyte = Hibyte And &B0000000000000111 ' zusammensetzen
Rotate Hibyte , Left , 8 '8 bits nach links
Pac = Lobyte + Hibyte ' zusammenzählen
Pac = Gray2bin(pac) 'in bin umwandeln
Endhighbyte = Pac an Endhighbyte die BIN ausgeben
Wait 1
Loop
ich weiss, da steht fast alles mist, aber ich mache, wie ich kann. in der Hoffnung, dass mit jemand hilft.
Sauerbruch
22.04.2008, 16:20
Dim Hibyte As Word
Okay - ich wusste nicht, dass "Hibyte" ein Word ist - sorry. Dann kannst Du natürlich auch 16 Bits drüberlegen, kein Problem.
Vielleicht habe ich etwas den Überblick verloren, aber grob & qualitativ sollte doch folgendes passieren:
1. 12 (oder 13?) bits werden über 2 Ports eingelesen
2. Die 5+8 Bits werden zu einem Word zusammengebastelt
3. Auf Word-Ebene findet irgendeine Umwandlung statt (Gray -> BCD?)
4. Das neue Word soll über 2 andere Ports ausgegeben werden.
Richtich?
Ja, es ist genau richtig was du da schreibst!
das problem ist der 4. Schritt. bis dahin komme ich in meinen Gedanken noch, und dann bleibe ich stecken. Wie fasse ich die anderen 2 ports zusammen und gebe aus den zusammengefassten Ports den umgerechneten BCD code aus?
Danke
Sauerbruch
22.04.2008, 22:02
Endhighbyte ist also Dein 16bit-Word ist, dessen "obere" 8 bits ( 15-8 ) auf PortC, und dessen "unteren" 8 bits ( 7-0 ) auf PortA ausgegeben werden sollen?
Dafür wäre die einfachste Lösung in etwa diese:
PortC = High(Endhighbyte)
PortA = Low(Endhighbyte)
Und wenn Du jetzt noch ´ne echte Herausforderung suchst: Man kann den ganzen Zauber auch mit einer einzigen (!) Word-Variable abarbeiten anstatt mit 5. Auch wenn einn Mega32 richtig viel Ressourcen hat - irgendwann wird der Punkt kommen, an dem die Programme so gruß werden, dass die Kapazitäten knapp werden =P~
Vielleicht kriegst Du ja raus wie :-)
"obere" 8 bits ( 15-8 ) auf PortC, und dessen "unteren" 8 bits ( 7-0 ) auf PortA ausgegeben werden sollen?
ich hab es nicht ganz verstanden. also als ausgang den Vollen portA von 0-7 und den rest von PortC 0-4.
ich kann es aber erst Freirag testen, weil ich morgen und übermorgen Berufschule habe, und Freitag komme ich wieder zur Arbeit.
Danke
Sauerbruch
23.04.2008, 00:43
Macht nix O:)
Du kannst doch ein ganzes byte in den PortC schreiben, auch wenn nur die bits 4-0 von Interesse sind. Die übrigen bits (7-5) hast Du ja ohnehin gelöscht (mit dem AND &B00011111 - Befehl). Und wenn Du ganz sicher gehen willst, kannst Du die Pins C5-C7 ja als Eingänge konfigurieren - dann kommt garantiert nur der relevante Teil vom byte raus (DDRC = &B00011111).
Stimmt! :)
und wie lautet der Befehl für "Ausgabe"?
Sauerbruch
23.04.2008, 20:30
Dafür braucht man keinen Befehl (und deshalb gibt´s ihn auch nicht =P~ )
Wenn ein Anschluss als Ausgang konfiguriert ist (DDR-Register), wird das dazugehörige Bit des Port-Registers immer und ohne weiteres Zutun auf den Ausgang gegeben. Das kannst Du für ganze Ports "am Stück" machen, aber auch für jede beliebige Kombination von Bits eines Port-Registers.
So einfach ist das...
achsooooo
dann ist meine Zeile:
Endhighbyte = Pac
sogar richtig?? weil Endhighbyte ist ja portA und portC zusammen und Pac ist ja der Umgerechneter Code.
ich habe das ganze nach gefühl geschrieben, weil ich mit dem Syntax von basic nicht so vertraut bin.
Was muss ich also in meinem Code oben verändern? ich werde mal bald den Schaltplan zeichnen.
so, und nun kommt der Schaltplan.. MAN BEACHTE DIE BELEGUNG DES PORTCs
Sauerbruch
24.04.2008, 11:30
...mit der Bascom-Syntax vertraut zu sein schadet aber nicht - das macht vieles einfacher!
Jetzt mal ganz allgemein:
Du kannst Ports als ganzes ansprechen, z.B.
PortA = &B10101010 (=binär) oder
PortA = 170 (=dezimal) oder
PortA = &HAA (=hexadezimal)
oder auch über eine Variable, z.B. so
Dim Zahl as Byte
Zahl = 170
PortA = Zahl
alles das gleiche: Die 8 Pins des PortA werden 10101010 nach außen führen.
Und wie verschiedene dezimale Zahlen im Binär- oder Hexydezimalsystem aussehen (was uns ja meistens nicht ganz so vertraut ist wie das dezimale), kann man sich mit Hilfe des Rechners im Wndows-Zubehör sehr einfach ansehen. Einfach mal ausprobieren, das schafft schneller Klarheit als hunderte von Seiten zu lesen.
Du kannst aber auch einzelne bits des Ports setzen:
PortA.0 = 0
PortA.1 = 1
PortA.2 = 0
...
Aber zwei Ports in einem Aufwasch (PortAC oder sowas), das geht nicht. Gar nicht. Niemals. Du musst Deinen Ausgangs-Ports A und C getrennt zuweisen, welche Werte sie haben sollen.
Für PortA ist das einfach, da er die untern 8 bits Deines 16bit-Words Endhighbyte haben soll. Das geht mit dem Befehl LOW( ). Ich kann die Bascom-Hilfe hierzu nur wärmstens empfehlen, aber es ist wirklich nur dieses hier:
PortA = LOW(Endhighbyte)
Fertig.
Bei PortC wird´s schwieriger, weil die bits "über Kreuz" zugeordnet werden. Da müsstest Du dann in die Trickkiste mit dem Ansprechen bzw. zuweisen einzelner bits greifen:
PortC.7 = Endhighbyte.8
PortC.6 = Endhighbyte.9
PortC.5 = Endhighbyte.10
PortC.4 = Endhighbyte.11
PortC.3 = Endhighbyte.12
Und auch fertig.
Es gibt 3 gute Methoden, ein "Gefühl" für die Bascom-Syntax zu bekommen:
1. Probieren, 2. probieren und 3. probieren.
Der Compiler lässt nur Code durch, der o.k. ist. Und eine wirklich ganz unglaublich gute Hilfe ist die "Help"-Funktion in Bascom, die für jeden, aber auch wirklich jeden Befehl die genaue Syntax beschreibt, und nicht nur das: Für viele Befehle sind sogar auch noch Code-Beispiele dabei, von denen man sich sehr viel abschauen kann. So haben das die meisten hier irgendwann mal gelernt :-)
hm, sorry das ich so blöd bin.
habe schon alles auspobiert, was ich probiern könnte.
nun wolte ich erst nur mit einem PORT (8 bit) machen und schauen, ob es überhaupt funktioniert.
habe sowas geschrieben:
$regfile = "m32def.dat"
$crystal = 1000000
Dim Pac As Byte
Portb = Pac
Do
Pac = Gray2bin(pac)
Porta = Pac
Wait 1
Loop
end
es funktioniert aber nicht. kommt am PORTA nichts raus.
Der µC ist ok...
"PORTA = 3" funktioniert. Gibt er 11000000 raus.
Wo ist mein Fehler?
Danke
Sauerbruch
25.04.2008, 10:38
Wo ist mein Fehler?
Wenn Du mit der Zeile
Portb = Pac
erreichen möchtest, dass die Variable Pac mit dem Eingangs-Wert gleichgesetzt wird (und davon gehe ich mal aus), stecken drei Fehlerchen drin:
1. Die Reihenfolge muss andersrum sein: Pac = PortB. Als erstes steht immer die Variable um die es geht, und als zweites der Wert, den diese Variable annehemen soll.
(Ganz analog zur deutschen Sprache: Fritz = doof weist einer bestimmten Person eine Eigenschaft zu, heißt aber mitnichten, dass alle doofen Menschen Fritz heißen =P~ )
2. Statt PortB musst Du PinB nehmen. Ist etwas verwirrend, aber zu jedem Ein-/Ausgangsbeinchen des Controllers gehören 3 Register:
-DDRX.Y legt fest, ob´s ein Ein- oder Ausgang sein soll
-PORTX.Y ist das bit, das ausgegeben wird, wenn der Anschluss als Ausgang konfiguriert ist
-PINX.Y enthält das bit, das an dem Anschluss anliegt, wenn er als Eingang konfiguriert ist. Eingänge also immer über das PIN-Register abfragen!!!
Um diese Verwirrung noch zu komplettieren: Auch wenn ein Anschluss als Eingang konfiguriert ist (DDRX.Y = 0), hat das dazugeörige PORT-Bit auch eine Bedeutung: Ist es 1, ist der interne PullUp-Widerstand aktiviert. Das ist wichtig, wenn der Eingang ansonsten "offen" ist.
3. Die somit korrigierte Zeile
Pac = PinB
gehört hinter das "do" - sonst wird sie genau ein einziges mal ausgeführt, und Änderungen an Deinem Eingang werden nicht mehr auf Pac übertragen.
Alles klar??
:) oh man...
aber mit dem Code hier
$regfile = "m32def.dat"
$crystal = 1000000
Dim Pac As Byte
Do
Pac = PinB
Pac = Gray2bin(pac)
Porta = Pac
Wait 1
Loop
End
lege ich 5V an PB0. Alle anderen Eingänge sind auf LOW-PEGEL.
Am PORTA gibt er mir aber sowas raus. Pa0 bis Pa7 : 01010101
warum denn sowas? es sollen doch 10000000 sein.
Sauerbruch
25.04.2008, 11:15
Also, erstmal müsste es 00000001 sein, wenn Du PB0 auf 5V legst (die Bits werden immer in der Reihenfolge 7-6-5-4...-0 gezählt). Aber das nur am Rande :-)
Wie legst Du denn technisch gesehen die Anschlüsse auf +5 bzw. 0 Volt? Hängen die Anschlüsse vielleicht "in der Luft", wenn sie nicht auf +5V sind?
die händen in der Luft! :(
habe schon lange versucht die pull-down intern zu aktivieren, aber hier
http://avrhelp.mcselec.com/index.html
habe ich nichts brauchbares unter "pull down" gefunden. vielleich falsches Stichwort.
Oder kann man sonst mit stk500 mit wenig aufwand die pins auf Masse legen? die Taster sind ja blöder weise auf 5V immer (wenn geöffnet) und schalten masse. Das hasse ich an dem Board
Sauerbruch
25.04.2008, 11:57
Interne Pulldown-Widerstände gibt´s auch nicht - nur PullUps. Frag mich aber nicht nicht warum...
Genau deshalb sind praktisch alle Boards mit Schaltern so konstruiert, dass die Schalter eben nach Masse schalten. Wenn der schalter geöffnet wird, wird der Eingang sauber auf +5V gezogen. Wenn so ein Eingangspin ganz alleine in der Luft hängt, fängt er sich jede Menge Stör-Schrott ein, da extrem hochohmig. Ohne PullUps wird´s nicht gehen - also aktivier sie doch einfach mal:
PortB = &B11111111 (oder PortB = 255, wenn Du Deine Tastatur schonen willst :-) )
habe ich gamacht. jetzt habe ich am portB alles 5V. (brauche ich zwar nicht, aber erstmal egal.
es hat sich aber nichts getan. am portA sind es immer noch 10101010 (5V 0,7V 5V 0,7V u.s.w.) :(
Sauerbruch
25.04.2008, 13:34
Und könnte das nicht vielleicht stimmen?
Ich muss gestehen, keinen Plan von den Details des Gray-Codes zu haben. Ich habe aber gerade in meinem bascom-Simulator ein Progrämmchen simuliert, das eine Variable mit dem Wert 255 (oder binär 11111111) von Gray in binär umwandelt - und das Ergebnis ist 10101010.
Witzig, aber wahr. Soweit scheint also alles erstmal o.k. zu sein...
tatsächlich??! :D ist echt witzig...
na gut, erstmal WE.
habe die Platine sowieso auf der Arbeit!
Danke!
Ich melde mich noch
Schönes We
Sauerbruch
25.04.2008, 16:05
habe die Platine sowieso auf der Arbeit!
...eine echt praktische Alternative ist der Simulator, der in Bascom integriert ist. Ordentlich compilierte Programme kann man damit Schritt für Schritt durchklingeln und sich den Inhalt beliebiger Register ansehen. Das kann sehr, sehr lehrreich sein...
Dann wünsch´ ich gute Erholung, und wenn´s nächste Woche noch klemmt, dann meld´ Dich hier wieder!
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.