Binärwert auf Display ?

Afu

Neues Mitglied
05. Feb. 2009
6
0
0
Sprachen
Hallo !

Ich bin neu im Forum und auch blutiger Anfänger bez. AVR.

Ich suche eine Möglichkeit, die Zahlen 0 bis 255, die als Binärzahl an 8 Pins einer gegebenen Schaltung vorliegen, also 00000000 bis 11111111 in die Dezimalzahlen 0 bis 255 zu wandeln
und z.B. auf 3 Siebensegmentanzeigen
(3 ports) anzuzeigen. Als Hardware würde ATMEGA16 oder 32 passen. Man könnte dann für die Siebensegmentanzeigen 3 ports nehmen und die ganze Ansteuerung wäre gelöst. Der AVR hat keine weiteren Aufgaben.
Kann mir da jemand helfen und in Bascom Basic mir ein kleines Programm stricken ?

Ich freue mich auf Antworten.

LG Afu
 
Am Anfang war die Harware...

Hi Afu,

nichst leicher als das, aber bevor wir Dir hier eine fertig Lösung vorgekauft servieren, was wir in der regel natürlich nicht machen, denn etwas Spass und Gehirnschmalz sollte bei der eigenen Arbeit auch noch dabei sein :p solltest Du Dir zunächst Gedanken über Deine Hardware machen.

Hast Du Dir mal das Datenblatt von einem Mega16 oder Mega32 angesehen? Wenn nein so solltest Du dies zunächst als erstes machen.

Ja, der Mega16 und der Mega32 hat 4 Ports (A,B,C,D) zur Verfügung an denen Du Bits/PIN's zappel lassen kannst. Aber dann stellt sich für mich gelich mal die Frage, wie möchtest Du Deinen MegaX programmieren? Wenn Du ihn mittels ISP programmieren möchtest so sind schon mal drei PIN's von Port B (MISO, MOSI, SCK) mit Doppelfunktionen belegt und Du musst Dir bei Deinem HW-Design genau überlegen wie Du das handeln möchtest.

Also lass mich Dir den Vorschlag machen, zunächst mal theoretisch ein paar HW-Gedanken anstellen und dann sehen wir weiter. BASCOM ist dann keine Problem mehr :D

Am besten Du verräts uns kurz auf welcher HW Du experimentieren möchtest. Hast Du ein STK500 oder ein Steckbrett mit Bauteilen. Was ist Deine Idee. Zunächst würde ich Dir nämlich empfehlen Dich für einen Mega16 oder 32 zu entscheiden (by the way, ich denke das speielt bei dieser Anwendung keine Rolle), dann den Prototypen mal zusammenstecken oder zusammenlöten und wenn der läuft, Du die LED's Deiner 7-Segemen-Anzeigen zum blinken bringen kannst und damit auch die Programmierung geklärt ist dann verrate ich Dir Schritt für Schritt den rest.

Spass muß sein.....

was hältsts Du von der Idee?

Grüße,
Markus
 
Hallo Markus,
das ging ja schnell mit der Reaktion auf mein Problem.
Ja, ich habe eine Platine mit dem 40 poligen ATMEGA32 mit einem 8 MHz Quarz und die 4 ports sind mit Vcc und Gnd auf 10 polige Wannenstecker geführt.
Brennen kann ich mit einem Parallelbrenner vom PC zu einer ISP Schnittstelle ebenfalls auf der Platine. Ich habe schon ein wenig mit Bascom gespielt und Progrämmchen über PonyProg in den ATMEGA geschoben.
Bisher habe ich eine Sache aufgebaut, bei der man mit einem Zehngangpoti einen AD-Wandler ansteuert, der dann 8 LEDs (später Relais) binär schaltet.
Umzu sehen, welche LEDs geschaltet sind, soll nun diese Anzeige parallel dazu geschaltet werden, damit man nicht immer im Dualcode rechnen um zu sehen, welche Stellung der Poti hat.
Das ist die Ausgangslage.
Jetzt suche ich praktisch nur diese Anzeige, hätte man vielleicht auch irgendwie mechanisch machen können, aber mit dem ATMEGA erscheint es mir einfacher (wenn mans kann) und sieht auch besser aus.
Als Anzeigen habe ich 7 Segment mit gem. Anode. Als Treiber könnte man diese ULN 2803 nehmen.
Mir fehlt jetzt der Zugang zu einer Art Tabelle, die man aufrufen könnte mit den Spalten 0-255 um dort die Codierung für die 3 Anzeigen abzurufen.
Ist wahrscheinlich einfach, aber ich blicke da noch nicht durch.
So das wärs erst mal von hier .
Ich hoffe, Du konnte Dir das Problem näher schildern.

Gruß
Gerd
 
Tabellen unc Co

Hallo Afu,

das ist nicht schwer. Ich stelle die Hypothese in den Raum, dass Du die Zahl (Bytewert) welche Du auf einer dreistelligen 7-Segment-Anzeige ausgeben möchtests in einer Variable X bereits schon durch Deinen Drehgeber und die Railaisansteuerung verfügbar hast.

Gut, also stellen wir uns mal die Frage wie weiter machen.....

Fakt ist, dass Du für die einzelnen drei Segmente die Einer, Zener, und Hunderter extrahieren musst. Das geht durch mathemastische ganzzahlige Division.

z.B. so: (angenommen X ist 136)
1. Hunderter = X / 100 (Ergebnis sollte 1 sein)
2. X = X - (Hunderter * 100) (gefundene Hunderter von Gesamtsumme abziehen, Rest in diesem Fall 36)
3. Zener = X / 10 (Ergebnis solle 3 sein)
4. X = X - (Zener * 10) (gefundene Zener von Gesamtsumme abziehen, Rest in diesem Fall 6)
5. Einer = X

Zugegeben, die Umsetzung ist vielleicht eine Holzhammer-Methode aber zum Verständnis sicherlich Zielführen. Zu beachten ist noch, dass es für Integer-Divisionen bei BASCOM das Backslash '\' gibt. Die Berechnung des Restbertrages kann man auch über Module MOD machen. Schau dazu einfach mal in die BASCOm Hilfe.

So, nun gehe ich weiter davona us, dass Du in den Variablen Zener, Einer und Hunderter sauber nur noch Ziffern von 0 bis 9 bzw. von 0 bis zwei für die Hunderter stehen hast.

Das mit der Tabelle ist in BASCOM auch kein Hexenwerk. Tabellen definiert man mit einem Label und dem Statement DATA. Du kannst Also damit ganz einfach ein Butmuster für ein Sieben-Segment definieren.

Beispiel:
Code:
Mappingtable:
DATA &B00000000 ' für Zahl 0
DATA &B00110000 ' für Zahl 1
...
DATA &B01111111 ' für Zahl 9

Achtung: Dies ist nur ein Beispiel. Welches Bit Du für welche Zahl auf 1 oder 0 setzt hängt von Deiner Beschaltung ab!
Weiter ist noch bei DATA zu beachten, dass (O-Ton BASCOM Hilfe) :
- Integer and Word constants must end with the %-sign.
- Long constants must end with the &-sign.
- Single constants must end with the !-sign.
- Double constants must end with the #-sign.

Für weitere Infos schau mal in die BASCOM Hilfe unter dem Begriff DATA.

Nun hat BASCOm weiter einen "virtuellen" Tabellenzeiger welchen Du mit dem Befehl
RESTORE Mappingtable
auf den Anfang der Tabelle setzen kannst. RESTORE benötigst Du, wenn Du sequentiell mit READ alle Elemente aus der Tablel lesen möchtest. Schau Dir hierzu mal die BASCOm Hilfe an. Ich gehe darauf nun nicht weiter ein weil ein anderes Verfahren für Dich viel besser geeignet ist.

Das heißt : Lookup().

Mit der Funktion LookUp() kannst Du indiziert jede Position Deiner Tabelle auslesen. Mit LookUp( 0, Mappingtable ) holst Du das erste Byte aus Deiner Tabelle, in diesem Fall den Bytewert für die Zahl 0. Mit LookUp( 9, Mappingtable) holst Du das 10 Byte aus Deiner Tabelle, in diesem Fall das Bitmuster für die Zahl 9.

Hast Du gemerkt, dadurch das LookUp immer mit 0 anfängt kannst Du mit Deinen variablen für Einer und Zener und Hunderter direkt auf die Tabelle zugreifen und Dir das Bitmuster herausholen.

Wenn Du die 7-Segment-Anzeigen direkt an drei separaten Ports hängen hast dann ist der Rest auch simple.

1. Einer, Zener, Hunderter berechnen
2. für Jede Ziffer das Bitmuster (Byte) mit LoopUp aus der Tabelle holen
3. Jedes Byte für die einzelnen Ziffern auf dem jeweiligen Port ausgeben.

So, nun habe ich Dir genug Kanonenfutter geliefert um mal loszulegen. Ja, es ist wie schon angekündigt keine Komplettlösung aber glaube mir, das macht es spannender und ich hoffe mit meinen Ausführen hier, Dir die relevanten und notwendigen Informationen gegeben zu haben.

Übrigens, einen ähnlichen Beitrag gibt es auch schon hier im Forum. Der Benutzer heißt Michael, frag mich nicht nach seinem NickName. Er htte zunächst das gleiche Problem, ist dann allerdings um Ressourcen zu sparen auf Multiplexbetrieb der Anzeige umgestiegen. Aber die Grundproblematik mit der Anzeige und der Tabelle war die gleiche.

Grüße,
Markus
 
Jetzt ist mri der Name wieder eingefalln. Der User heißt "dg2ygq" alias Michael :)

Grüße,
Ma
 
Hi Markus,

ich denke, ich habe das soweit verstanden.
Was mir unklar ist, warum ich nicht in eine Zeile
zwei Operationen schreiben kann.
z.B Zehner = zahl - (dreist * 100)
ich habe dann zwei Zeilen geschrieben:
mult1=dreist * 100
zehner = zahl - mult1
so gab es keine Fehlermeldung im Bascom.

Jetzt ist es so, dass die Eingabe an Port A , also die 8 Bits gelesen werden müssen, das ist mir nicht ganz klar wie.
Die Wandlung in die Zahl 132 in meinem Beispiel kann ja so erfolgen:
zahl = bit0 *1 +bit1*2 + bit2*3 usw.
Das ergibt dann die "Zahl", die dann wieder zerlegt wird.
Die Tabelle habe ich auch fertig.
Nun müssen die 3 Ausgangswerte Ausgport b, ausgportC und ausgportD an den jew. Ports ausgegeben werden , aber wie ?
Das noch meine Fragen.
ich habe mal mein "Basicfragment" angehängt und freue mich auf Deine Antwort

Gruß
Gerd



'Anzeigev1
$regfile = "m32def.dat"
$crystal = 8000000

Dim Zahl As Byte
Dim Dreist As Byte
Dim Zweist As Byte
Dim Einst As Byte
Dim Zehner As Byte
Dim Mult1 As Byte
Dim Mult2 As Byte
Dim Ausgportd As Byte
Dim Ausgportc As Byte
Dim Ausgportb As Byte


Do
'Lesen der 8 bit von Port A



Zahl = 132 'erzeugte Dezimalzahl
Dreist = Zahl \ 100
Mult1 = Dreist * 100 '3. Stelle (Hunderter)
Zehner = Zahl - Mult1
Zweist = Zehner \ 10
Mult2 = Zweist * 100 '2. Stelle (Zehner)
Einst = Zehner - Mult2 '1. Stelle (Einer)






Ausgportd = Lookup(einst , Tabelle) 'Ausgabewert der Einer auf Port D
Ausgportc = Lookup(zweist , Tabelle) 'Ausgabewert der Zehner auf Port C
Ausgportb = Lookup(dreist , Tabelle) 'Ausgabewert der Hunderter auf Port B


'Ausgabe auf den Ports B;C;D

Loop

End


Tabelle: ' Leer, g,f,e,d,c,b,a der 7Segmentanzeige

Data &B00111111 '0
Data &B00000110 '1
Data &B01011011 '2
Data &B01001111 '3
Data &B01100110 '4
Data &B01101101 '5
Data &B01111101 '6
Data &B00000111 '7
Data &B01111111
Data &B01101111
 
Hi Markus,
dies ist jetzt die erste lauffähige Version.
Ich habe nur eine Anzeige zusammengelötet und zeige einfach die Hunderter, Zehner und Einser nacheinander an.
Parallel dazu habe ich auch die LCD Anzeige installiert.
Hier habe ich die gleiche Anzeigeweise benutzt. Wenn ich nur die Zahl anzeigen will, bleiben immer die nicht benutzen alten Zahlen stehen zB alt 189 kommt jetzt neu mit 24, so steht dann 124 in der Anzeige, wenn man nicht vorher cls eingibt. Das dauert dann aber zu lange. Vielleicht gibt es da einen Trick.

Nächster und neuer Punkt: Könnte man die Erzeugung des 8 bit Dualcodes, den ich momentan mit einem Taktgenerator und einem ADC mache auch vom ATMEGA32 durchführen lassen ?
Wenn ich die LCD-Anzeige verwende, sind ja noch Ports frei ?

Wie kann man das realisieren ?

Gruß Gerd

P.S. listing beigefügt
 

Anhänge

  • ausgabetestlcdled.zip
    922 Bytes · Aufrufe: 5
Bascom

Hallo Afu,

ich habe mir Deinen Code angesehen und dazu habe ich gleich en paar Fragen die Dir vielleicht helfen:

1. Warum arbeitest Du fast ausschließlich mit vorzeichenbehafteten INTEGER?
-> Integer ist unnötigt. Bei 8 Bit wird keine Zahl größer als 255 und da reicht Byte voll aus!

2. Warum liest Du Port A BIT für BIT?
-> Du Hast PortA komplett als Eingang definiert. Damit kannst Du mit "Bytevariable = PINA" den kompletten Port lesen
-> Auf diese Weise kannst Du Dir das aufwände zusammenrechnen sparen.

3. CLS
Prinzipiell kommst Du bei LCD's wenn Du einen leeren Bildschirm haben möchtest nicht um den Befehl CLS herum. Manchmal kann man dies aber durch geeignete Ausgabe von Leerezeichen umgehen. Das hängt von Fall zu Fall ab.

4. Konfiguratione
Dein LCD-Display erscheint mir aus dem Grund so langsam, weil Du IMMER in der Hauptschleife die Konfiguration durchführst!!!!!!
-> CONFIG hat in der Hauptschleife durch die Du 10.0000 Millionen mal durchläufst NIX zu suchen
-> Raus damit dem LCD-Teil vor die Hauptschleife. Du musst nur einmal das LCD-Display konfigurieren!!

5. Stelle bleibt stehen
Hmmm, das habe ich jetzt noch nicht begriffen warum immer eine Stelle stehen bleiben soll da Du auf jeden Fall immer alle drei Ziffern ausgibst, selbst wenn die Ziffer 0 ist. Ich würde aber sagen Du bringst zunächst die Baustellen 1-4 in Ordnung und dann sehen wird weiter. Somit müsste nämlich auch Dein CLS-Befehl schneller laufen!

6. Taktgenerator und ADC
Hmmmm, Hier muss ich gestehen habe ich noch nicht ganz begriffen, was Du wie machst um den Dualcode zu erzeugen bzw. wie Du genau den ADC verschaltest um ein Binärmuster zu bekommen. Ich habs noch nicht begriffen und vielleicht kannst Du es nochmals genauer erklären. Welcher Mega macht was und wie sieht die Beschaltung bzw. die Software dazu aus?

Grüße,
Markus
 
Hallo Markus,

so jetzt habe ich das Programm nochmal aufgeräumt, habe aber die alternative mit den 7Segmentanzeigen im Programm gelassen zusätzlich zur LCD-Anzeige, die jetzt auch etwas schneller ist.
Die Sache mit dem ADC lasse ich mal so wie sie momentan läuft.

Jetzt wäre es aber schön, wenn man viele ? ( mehr als 10 bis beliebig viele) Anzeigewerte abspeichern und dann wieder aufrufen könnte.
Anwählen der Speicherstelle z.B. mit zwei Tasten up/dwn, eine Taste "STOx", eine "RCLx" so wie beim Taschenrechner.
Wie geht sowas ?
Mein neuestes Listing ist beigefügt.

Gruß
Gerd
 

Anhänge

  • ausgabefinal.zip
    751 Bytes · Aufrufe: 10
Lebenszeichen

Ja, mich gibt es noch! Sorry, habe Dich versenkt :eek:

Bin grad ein bissle knapp in der Zeit und meine Aufgen fallen mir langsam zu. War ein anstrengender Tag! Werde mir morgen das Thema mal genau ansehen und mir etwas überlegen. Rechne nicht mit einer Lösung sondern ich sehe meine Aufgabe zunächst mal darin, Querzudenken. OK?

Grüße,
Markus
 
Werte speichern

Hallo Afu,

so, nun möchte ich Dir einige meiner Gedankengänge niederschreiben um Dich mit Deinem "Neuen" Problem auf die Schiene zu setzen. Vielleicht gelingt es mir auch, Dich anzuschieben :p

Jetzt wäre es aber schön, wenn man viele ? ( mehr als 10 bis beliebig viele) Anzeigewerte abspeichern und dann wieder aufrufen könnte.
Anwählen der Speicherstelle z.B. mit zwei Tasten up/dwn, eine Taste "STOx", eine "RCLx" so wie beim Taschenrechner.
Wie geht sowas ?

Sicherlich gibt es verschiedene Ansätze solch ein Abspeichern-Problem zu lösen. Allen Lösungen zugrundeliegend ist aber die Benutzung eines Speichers der von der Spannung unabhängig ist, der gelesen und geschrieben werden kann und der mit seinen Daten auch nach längerer Abschaltzeit zur Verfügung steht.
Mit dem Mega32 verfügst Du bereits quasi on board über solch einen Speicher. Nämlich der EEPROM-Speicherbereich mit einer Größe von 1024 Bytes. Bei diesem Speicher handelt es sich um einen nicht flüchtigen Speicher der beliebig beschrieben und gelesen werden kann.
Aber Achtung: Gemäß Datenblatt werden von ATMEL nur 100.000 Schreibzugriffe garantiert. Bedeutet, wenn Du öffters als 100.000 mal auf EINE Speicherzelle schreiben möchtest besteht die Gefahr, dass die Speicherzelle defekt ist und nicht mehr das zurückliefert, was geschrieben wurde.
In der Regel verwendet man bei sehr vielen Schreibzugriffen dann externe EEPROM Speicherbausteine welche schon für wenig Geld und z.B. I2C-Bus erhältlich sind. Ich z.B. habe in einem Projekt auch schon mal einen externen 512 kBit Baustein mit I2C verwendet.

So, nun kommt sicher von Dir die Frage was Du nehmen sollst. Die Antwort dieser Frage kann Dir niemand abnehmen da es davon abhängt, wie oft Du in solch ein EEPROM schreiben möchtest und indirekt damit verbunden, wie lang Deine HW leben soll. Ggf. würde ich - um auf der sicheren Seite zu sein - auf externe HW ausweichen.

Siehe hierzu folgenden Thread in dem ich beide Themen (internes und externes EEPROM) an einem Beispiel "durchgekaut" habe:
http://www.avr-praxis.de/forum/showthread.php?t=48

Wahrscheinlich kommt von Dir als nächstes die Frage, wie man Zugriff auf ein internes und externes EEPROM nimmt. Also:
- auch hierzu kannst Du in den Link schauen, ich neige dazu meine Source-Codes umfangreich zu kommentieren
- auch die BASCOM-Hilfe bietet hierzu sehr viel Hilfestellungen

Wenn Dir die reine Online-Hilfe nicht gefällt so kannst Du von der Homepage des BASCOM-Herstellers
http://www.mcselec.com/
direkt aktuelle AVR-User-Manuals herunterladen (PDF-Formart) und durcharbeiten. In den PDF's ist teilweis enoch mehr beschrieben als in der Online-Hilfe und außerdem sind die Beispielprogramme vollständiger.
Zu finden sind die Dokumente unter Downloads -> BASCOM -> BASCOM-AVR -> Documents.

Sicherlich sind noich weitere Möglichkeiten denkbar, z.B. könntest Du Messwerte
- auf USB Speicher sepichern, dazu musst Du aber ein USB-Interface designen
- auf SD-Karte speichern. Achtung wegen den Fileformaten und Formatierungen
- im RAM halten, bedeutet aber Du darfst die Spannung nie abschalten und bei Stromausfall sind die Daten futsch
- SRAM's mit Batteriebufferung

usw.

Ich an Deiner Stelle würde mir das EEPROM-Thema mal ansehen und mir dann in einem 2. Schritt eine saubere Datenstruktur und einen Algorithmus überlegen der Dir Daten dort abspeichert.

So, nun hoffe ich, dass ich Dir mit diesen infos etwas weiter helfen konnte.

Grüße,
Markus
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)