www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Bascom: Variable aufteilen für 7-Segment Anzeigen


Autor: Manu N. (avr-manu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
Ich steuere gerade 3 7-Segment Anzeigen an:
Ein Mega 8 steuert ein Schieberegister (74HC595) an, an dem
8x BC547A hängen. Desweiteren steuert der Prozessor einen ULN 2803,
der dafür zuständig ist, die Anzeigen mit gemeinsamer Kathode 
nacheinander auf GND zieht (Multiplexen).
Das funktioniert nun, die Anzeigen lassen sich alle steuern.

Nun zur Software:
-Programmiert wird in Bascom, Beispiele in C oder Assembler helfen mir 
nicht
-Das Multiplexen wird per Timer0 Interrupt erledigt
-Es gibt ein Abfrage, die im Interrupt die Zahlen (1-9) Binäre Werte 
umwandelt, passend für die Anzeigen, die dann ins Schieberegister 
geschoben werden.
Code:
Select Case Zahl(1)
   Case 0 : T1 = &B11101101
   Case 1 : T1 = &B10000001
   Case 2 : T1 = &B11001110
   Case 3 : T1 = &B01101110
   Case 4 : T1 = &B00101011
   Case 5 : T1 = &B01100111
   Case 6 : T1 = &B11100111
   Case 7 : T1 = &B00101101
   Case 8 : T1 = &B11101111
   Case 9 : T1 = &B01101111

End Select


Select Case Zahl(2)
   Case 0 : T2 = &B11101101
   Case 1 : T2 = &B10000001
   Case 2 : T2 = &B11001110
   Case 3 : T2 = &B01101110
   Case 4 : T2 = &B00101011
   Case 5 : T2 = &B01100111
   Case 6 : T2 = &B11100111
   Case 7 : T2 = &B00101101
   Case 8 : T2 = &B11101111
   Case 9 : T2 = &B01101111

End Select



Select Case Zahl(3)
   Case 0 : T3 = &B11101101
   Case 1 : T3 = &B10000001
   Case 2 : T3 = &B11001110
   Case 3 : T3 = &B01101110
   Case 4 : T3 = &B00101011
   Case 5 : T3 = &B01100111
   Case 6 : T3 = &B11100111
   Case 7 : T3 = &B00101101
   Case 8 : T3 = &B11101111
   Case 9 : T3 = &B01101111

End Select

Ich habe also drei Variabeln, die jeweil eine Stelle, von 1 bis 9, 
darstellen.

Ich will eine ganze Zahl auf dieser Anzeige ausgeben, die in einer 
anderen
Varialble gespeichert ist, z.B. 142.


Wie schaffe ich es nun, diese Zahl aufzuteilen,
also in die Stellen 1, 2 und 3 ?

Hier die erste Methode, die ich mir ausgedacht hatte:
-Als erstes wird die Zahl durch 100 geteilt
-Dann werden die Kommastellen ermittelt
-Und dann abgezogen
-Jetzt könnte die Zahl z.B. lauten: 2.0
-Um das komma "wegzubringen" runde ich noch

Hier wieder der Code:
(Mit Derklerationen)
$regfile = "m8def.dat"                                      'ATmega8-Deklarationen
$crystal = 1000000
$baud = 4800

Config Portc.5 = Output
Config Portc.4 = Output
Config Portc.3 = Output
Config Portc.2 = Output
Config Portd.5 = Output
Config Portd.6 = Output
Config Portb.7 = Output

Portb.0 = 1
Portd.7 = 1

Clock Alias Portc.5
Stout Alias Portc.4
Dat Alias Portc.3

Down Alias Pind.7
Up Alias Pinb.0

L1 Alias Portd.6
L2 Alias Portd.5
L3 Alias Portb.7

Clock = 0
Stout = 0
Dat = 0


Dim Zahl(3) As Integer
Dim Zanz As Integer

Dim K1 As Single
Dim K2 As Single
Dim K3 As Single
Dim Fr As Single


Dim T1 As Byte
Dim T2 As Byte
Dim T3 As Byte
Dim A As Byte

On Timer0 Isr
Config Timer0 = Timer , Prescale = 8
Enable Timer0
Enable Interrupts

Zanz = 123

Do

K1 = Zanz / 100
Fr = Frac(k1)
K1 = K1 - Fr
T1 = Round(k1)


K2 = Zanz / 10
Fr = Frac(k2)
K2 = K2 - Fr
T2 = Round(k2)


Print "k1:" ; K1
Print "k2:" ; K2
Print "  "
Print "t1:" ; T1
Print "t2:" ; T2
Print "  "
Print "Fr:" ; Fr


Loop


Aber es funktioniert nicht.

Kennt jemand einen andere Methode,
so etwas "umzuwandeln"?

Oder findet jemand den Fehler in meinem Code ?
Falls nötig kann ich auch den ganzen Code posten. (oder noch mehr zur 
Hardware?!)



Vielen Dank schonmal

PS: Ich bin in ca. 45 Minuten wieder da, gespannt auf eure Antworten.

Autor: Volker Schulz (volkerschulz)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist zwar nicht Bascom, aber schau Dir doch das mal an:

http://www.mikrocontroller.net/articles/AVR-Tutori...

Alleine durch die Kommentare kommst Du ja schon drauf, was gemacht wird. 
;)


Volker

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Bascom kennt doch den Modulo-Operator:

z.B. 142

142/100     = 1  ->erste Stelle
142 MOD 100 = 42 ->Rest
42 / 10     = 4  ->zweite Stelle
42 MOD 10   = 2  ->dritte Stelle

fertig.

MfG Spess

Autor: Manu N. (avr-manu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 142 MOD 100 = 42 ->Rest

Und was mach ich mit dem Rest ?


Ich fange gleich mal an das zu Programmieren,
wobei ich die letztere  Methode für die einfacherere halte.


Danke an euch beide,
ichteste mal und melde mich nochmal.

Autor: Volker Schulz (volkerschulz)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Manu N. schrieb:
>> 142 MOD 100 = 42 ->Rest
>
> Und was mach ich mit dem Rest ?

Der wird doch kurz danach MOD 10 genommen...


Volker

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Und was mach ich mit dem Rest ?

Das ist der Rest von 142/100. Also deine Zehner- und Einerstellen.

MfG Spess

Autor: Manu N. (avr-manu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hm,
weder die Bascom Hilfe noch die passende Fachliteratur
kennt den Befehl "mod".
Könntest du das noch mal etwas genauer erklären, ich stehe
glaub ich auf dem Schlauch.

Ansonsten probiere ich Methode Nr.1


Danke

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Auszug aus der Bascom-Hilfe:

Language Fundamentals ->Arithmetic

Modulo Arithmetic
Modulo arithmetic is denoted by the modulus operator MOD.
Modulo arithmetic provides the remainder, rather than the quotient, of 
an integer division.

Example: X = 10 \ 4 : remainder = 10 MOD 4

MfG Spess

Autor: Volker Schulz (volkerschulz)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Manu N. schrieb:
> Hm,
> weder die Bascom Hilfe noch die passende Fachliteratur
> kennt den Befehl "mod".

MOD ist auch kein Befehl sondern ein Operator... Und laut Google gibt es 
den in Bascom. ;)


Volker


P.S.: Das Vorgehen in ASM ist auch nur der "Modulus zu Fuss"...

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Beispiel findest du in der Hilfe zum Befehl 'SET'.

MfG Spess

Autor: Rolf Im forum (for_ro)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Manu N. schrieb:
> Select Case Zahl(1)
>    Case 0 : T1 = &B11101101
>    Case 1 : T1 = &B10000001
>    Case 2 : T1 = &B11001110
>    Case 3 : T1 = &B01101110
>    Case 4 : T1 = &B00101011
>    Case 5 : T1 = &B01100111
>    Case 6 : T1 = &B11100111
>    Case 7 : T1 = &B00101101
>    Case 8 : T1 = &B11101111
>    Case 9 : T1 = &B01101111
>
> End Select

Da multiplexen normalerweise etwas zeitkritisch ist, würde ich sowas 
nicht machen, besonders nicht 3 mal.
Im Falle der Zahl 9 muss er 10 Vergleiche ausführen und dann eine 
Zuweisung machen und zum End Select springen.
Wenn du noch 10 Byte im SRAM frei hast, würde ich die Werte in einem 
Array abspeichern.
Dim Ziffern(10) as Byte
Ziffern(1) = &B10000001
Ziffern(2) = &B11001110
...
Ziffern(10) = &B11101101

Dann kannst du mit

T1 = Ziffern(Zahl(1))
T2 = Ziffern(Zahl(2))
T3 = Ziffern(Zahl(3))

die ganze Arbeit der drei Select-Blöcke erledigen.
Wenn du jetzt genau hinsiehst, hat das aber einen kleinen Fehler. Die 0 
steht im 10 Element und nicht im 0-ten Element.
BASCOM startet die Indexe leider bei 1 und nicht bei 0. Aber es gibt 
einen Trick, wie man BASCOM 0-basierte Indexe beibringen kann. Und zwar 
so:

Dim Ziffern_0 As Byte
Dim Ziffern(9) As Byte

Ziffern_0 = &B11101101
Ziffern(1) = &B10000001
Ziffern(2) = &B11001110
...
Ziffern(9) = &B01101111

Wenn jetzt in Zahl(1) z.B. eine 0 steht, dann würde die Zuweisung

T1 = Ziffern(Zahl(1))

so aussehen

T1 = Ziffern(0)

Ziffern(0) ist zwar in BASCOM nicht erlaubt, wird aber in die Adresse im 
SRAM vor der Adresse von Ziffern(1) übersetzt. Also tatsächlich auf die 
Dummy Variable Ziffern_0, die die Segmente der Zahl 0 enthält.

Wenn man sich erst einmal daran gewöhnt hat, funktioniert dies ganz 
automatisch.

Autor: Manu N. (avr-manu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Rolf Im forum (for_ro) :
Später werde ich das mal ändern, aber im Moment funktioniert das so 
super.


Leider verstehe ich diese mod Geschichte immer noch nicht stöhn
Hier mal ein kleiner Versuch: (der nicht funzt ...)
Rest = Zanz / 100
Zahl(1) = Rest

Rest = Rest Mod 10
Zahl(2) = Rest


Rest = Rest Mod 1
Zahl(3) = Rest


Danke für eure Bemühungen ...

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rolf Im forum schrieb:
> Ziffern(0) ist zwar in BASCOM nicht erlaubt, wird aber in die Adresse im
> SRAM vor der Adresse von Ziffern(1) übersetzt.

Solche häßlichen Tricks sollte man sich garnicht erst angewöhnen. Die 
werden mit Sicherheit mal Probleme machen und dann suchst Du Dich dumm 
und dämlich.

Mach eben ne Funktion draus und dann wird zum Argument noch 1 addiert. 
Fertig ist die Laube.

Du kannst aber auch das Select zu ner Funktion machen.
Ob Bascom die Tabelle oder das Select besser implementiert, kann man 
dann anhand der Codegröße vergleichen.


Peter

Autor: Volker Schulz (volkerschulz)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Manu N. schrieb:
> Leider verstehe ich diese mod Geschichte immer noch nicht *stöhn*
> Hier mal ein kleiner Versuch: (der nicht funzt ...)
>
> Rest = Zanz / 100
> Zahl(1) = Rest
> 
> Rest = Rest Mod 10
> Zahl(2) = Rest
> 
> 
> Rest = Rest Mod 1
> Zahl(3) = Rest
> 

Das ist ja auch nicht das von oben...
Zahl(1) = Zanz / 100
Rest = Zanz MOD 100 

...


Muesste es beginnen...


Volker

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Leider verstehe ich diese mod Geschichte immer noch nicht stöhn
>Hier mal ein kleiner Versuch: (der nicht funzt ...)

>Rest = Zanz / 100
>Zahl(1) = Rest

>Rest = Rest Mod 10
>Zahl(2) = Rest

>Rest = Rest Mod 1
>Zahl(3) = Rest

Machs mal so:

Zahl(1) = Zanz / 100
Rest    = Zanz MOD 100

Zahl(2) = Rest/10
Zahl(3) = Rest MOD 10

Ich kann es nicht testen, weil ich nicht mit BASCOM programmiere.

MfG Spess

Autor: MWS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Segmentdaten würde man besser mit Data & Lookup holen, außerdem 
beginnt bei Lookup der erste Datensatz bei 0, da ist dann auch kein so 
ein Gebastel notwendig.
T1 = Lookup(Zahl(1) , 7Seg_data)
...
7Seg_data:
Data &B11101101
Data &B10000001
...

Und warum SRam verschwenden, wenn's eh' Konstanten sind, die man im 
Flash vorhalten kann ?

Autor: Manu N. (avr-manu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Yippi Yippi Yeah

Es funktioniert.
Nur mit einem Problem habe ich noch zu kämpfen:
Wenn die Zehnerstelle umschaltet flackert bzw. leuchtet eine eins kurz
an der Hunderterstelle. Wiso bloß?
Hab auch schonmal den Timer Prescaler verändert, kein Erfolg.

Hat da jemand ne Ahnung ?

Autor: Manu N. (avr-manu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ah, jetzt ist der Spuk vorbei,
war nur n´ kleiner Bug im Programm.
Jetzt ist es Fehlerfrei.


Morgen werde ich noch das mit Lookup und Data Sachen einbauen.

Vielen Dank nochmal an alle die mir hier geholfen haben.
Manu

Autor: Hannes Lux (hannes)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Im Anhang ist noch eine Variante, sie gehört zu dieser Bastelei:
http://www.hanneslux.de/avr/divers/pm24/index.html

> Und warum SRam verschwenden, wenn's eh' Konstanten sind, die man im
> Flash vorhalten kann ?

Weil z.B. die SRAM-Zugriffe schneller sind und genügend SRAM zur 
Verfügung steht. Und weil man (in ASM) mit nur einer 
Pointer-Adressierung auf mehrere Arrays (mit gleichem Index) zugreifen 
kann (LDD/STD), was sehr schnelle (also Interrupt-taugliche) Zugriffe 
auf mehrere Arrays ermöglicht.

...

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.