Forum: Mikrocontroller und Digitale Elektronik Brauche mal Hilfe bei Mikrobasic programm


von Christian P. (christian_p20)


Lesenswert?

Hallo liebe Elektroniker zusammen. Ich brauche mal die Hilfe eines 
Programmieres in Mikrobasic. Ich hoffe ihr könnt mir helfen. Ich habe 
bisher nur als Anwender fertige Programme in Pics programiert. Ich habe 
hier die Vollversion von Mikrobasic Plus.Ich habe eine Schaltung mit 
einem Pic 18f4520 entworfen, an dem hängt eine 4x3 Tastatur an Port C, 
an Port B hängt ein LCD-Display 2x16 und an Port D sollen bistabile 
Relais geschaltet werden.
Ziel ist es eine Eichleitung von  0-140 db in 1 db Schritten zu bauen. 
Die bistabilen Relais schalten über eine Ansteuerplatine  in 1,2,4,8 db, 
dann 10,20,40,80 db und zum Schluß bit 9 mit 100 db. Die Hardware stellt 
kein Problem da und ich habe auch schon die Möglichkeiten auf dem Keypad 
eine Ziffer mit getky abzufragen und auf dem Display dar zu stellen. Nun 
aber zu meinem eigentlichen Problem.
Ich brauche folgende Routine. oder Programm
Auf dem Keypad sollen 3 Zahlen eingegeben werden und mit einer 
Eingabetaste (#) bestätigt werden. Alo erste Zahl einlesen und merken, 2 
Zahl einlesen und merken dann 3 Zahl einlesen und merken. Diese 3 Zahlen 
werden in einer weiteren Variablen abgelegt, sollen dann in Ascii 
umgewandelt werden und auf dem Display als String plus Zusatztext 
ausgegeben werden. Gleichzeitig möchte ich den Inhalt der Variablen 
(Wertebereich zwischen 0 und 150) verwenden um aus einer Tabelle einen 
passenden 9 Bit breiten Binärwert zu holen und diesen an Bit 0-7 port B 
und einem Bit von Port A aus zu geben. Damit werden dann die Relais in 
einen binäcode geschaltet. Durch drücken der * Taste werden die Zahlen 
gelöscht und das ganze soll von vorne beginnen. Ebenso sollte durch 
drücken der *-Taste jederzeit die Routinen abgebrochen werden. Da ich 
absoluter Anfänger in Mikrobasic bin habe ich da so meine 
Schwierigkeiten. Es wäre sehr freundlich wenn mir hier einer behilflich 
ist.
mit freundlichen Grüßen Christian Petersen

von Karl H. (kbuchegg)


Lesenswert?

Christian P. schrieb:

> kein Problem da und ich habe auch schon die Möglichkeiten auf dem Keypad
> eine Ziffer mit getky abzufragen und auf dem Display dar zu stellen.


Na, das ist ja schon mal was.

> Ich brauche folgende Routine. oder Programm
> Auf dem Keypad sollen 3 Zahlen eingegeben werden und mit einer
> Eingabetaste (#) bestätigt werden. Alo erste Zahl einlesen und merken, 2
> Zahl einlesen und merken dann 3 Zahl einlesen und merken. Diese 3 Zahlen
> werden in einer weiteren Variablen abgelegt

Das ist keine so gute Idee.

Mach es besser so:
Du hast da eine Variable, in der die Zahl entstehen soll. Mit jedem mal, 
wenn der Benutzer eine Taste drückt kommt an die Zahl eine Ziffer dazu.

Diese Variable startet bei 0 und ich nenne die Variable mal 'Wert'
Der Benutzer drückt zb die Taste '5'. Das stellst du in bewährter Manier 
fest und rechnest

    Wert = Wert * 10 + Tastenwert

Das ist mehr oder weniger in Formelsprache das, was mathematisch 
passiert, wenn du an eine Zahl eine Stelle drann hängst. Wenn aus der 
bisherigen Zahl 43 rechts die Ziffer 8 drann gehängt werden soll (aus 43 
also 438 werden soll), dann rechnet man einfach die 43 mal 10, macht 430 
und dann noch die 8 dazugezählt, ergibt 438. Voila

Und genau das machst du mit deinem Tastendruck, wobei Wert natürlich bei 
0 gestartet ist. Der Benutzer hat also '5' gedrückt. Diesen Tastendruck 
bearbeitest du mittels

    Wert = Wert * 10 + Tastenwert

(wobei Tastenwert natürlich der numerische Wert der Taste sein muss) und 
kriegst so in Wert eine numerische 5

Drückt der Benutzer als nächstes die Taste 8, dann rechnest du wieder

    Wert = Wert * 10 + Tastenwert

Wert, das war 5, mal 10 ergibt 50 und die 8 aus dem Tastendruck dazu, 
macht 58. Und genau das hat der Benutzer ja auch gewollt als er zuerst 5 
und dann 8 gedrückt hat.
Und mit dem nächsten Tastendruck genau dasselbe.


Nimm dir das mal als dein erstes Zwischenziel. Den Inhalt von Wert auf 
deinem LCD ausgeben und mittels Tastendrücken eine Zahl einzugeben.

> sollen dann in Ascii
> umgewandelt werden und auf dem Display als String plus Zusatztext
> ausgegeben werden.

Na ja.
Das ist ja in BASIC keine Hexerei, eine numerische Variable auszugeben 
und noch ein wenig Text drumherum zu platzieren. Das musst du schon 
alleine mit der Hilfe bzw. mit dem Studium von Democode bzw. anderen 
Beispielen  hinkriegen.

> Gleichzeitig möchte ich den Inhalt der Variablen
> (Wertebereich zwischen 0 und 150) verwenden um aus einer Tabelle einen
> passenden 9 Bit breiten Binärwert zu holen und diesen an Bit 0-7 port B
> und einem Bit von Port A aus zu geben.

Die Tabelle vergisst du gleich wieder.
In dem Moment in dem du eine Zahl hast, ist die Sache nämlich ganz 
einfach. Das sind einfach nur ein paar Abfragen nach immer dem gleichen 
Muster.
Deine Denkweise ist:

Ich muss den Wert dieser Zahl realisieren, wobei ich diese Zutaten zur 
Verfügung habe.

   Wenn der zu realisiernde Wert größer/gleich 100 ist, dann schalte
   ich das 100dB Relais ein (ansonsten aus). Da ich mit dem einschalten
   dieses Relais sozusagen vom zu realisiernden Wert 100 bereits
   'reledigt' habe, ziehe ich 100 davon ab und mir bleibt übrig, was
   noch zu realisieren ist. Lautete die Vorgabe auf 123, dann sind
   davon 100 abgehakt und 23 sind noch einzustellen.

Was dir dann noch übrig bleibt ist von genau der Gestalt, dass du diese 
Zahl ganz einfach auf den Port legen kannst und wenn du deine Relais 
vernünftig angeschlossen hast, dann stellt sich aufgrund der interenen 
Darstellung der Zahl automatisch die richtige Relais-Stellung ein.

> einen binäcode geschaltet. Durch drücken der * Taste werden die Zahlen
> gelöscht und das ganze soll von vorne beginnen. Ebenso sollte durch
> drücken der *-Taste jederzeit die Routinen abgebrochen werden.

Das ist ja nicht viel mehr als eine Auswertung dessen was dir deine 
getkey-Funktion liefert. Wenn also die Tasten zu Zahlen zusammengesetzt 
werden und du beim Einlesen einen '*' feststellst, dann stellst du Wert 
wieder auf 0.

> Da ich
> absoluter Anfänger in Mikrobasic bin habe ich da so meine
> Schwierigkeiten.

Tja.
Dann musst du halt üben. Das man als Anfänger für sowas schon ein paar 
Tage braucht, ist ganz normal. Aber solange du das nicht selber machst, 
wirst du immer Anfänger bleiben. Soo schwer ist das ganze jetzt auch 
wieder nicht. Du darfst nur nicht wie das Kaninchen vor der Schlange 
sitzen, weil dich die scheinbar komplexe Gesamtaufgabenstellung 
ungeheuer beeindruckt. Teil es dir auf! Wenn es darum geht, dass du mit 
deinen Tasten eine Zahl eingeben sollst, brauchst du dir keine Gedanken 
um die Relais zu machen. Also ignorier die erst mal. Erst mal brauchst 
du nur die Eingabe bzw. Ausgabe einer Zahl. Und der Knackpunkt dabei ist 
die Beobachtung, dass 'an eine Zahl rechts eine Ziffer anhängen' nichts 
anderes als eine Multiplikation mit 10 und eine Addition eines 
Zahlenwertes ist. Ein Zahlenwert, den du von den Tasten kriegst.

von Christian P. (christian_p20)


Lesenswert?

Hallo und danke schon mal für den Hinweis. Das mit den Zahlen einlesen 
werde ich nachher gleich mal umsetzen.Mit der ausgabe habe ich es noch 
nicht ganz klar. Schon klar , wenn die Zahl größer 100 ist kann das bit 
gleich gesetzt werden. Leider ist bei meiner Ansteuerplatine (Rhode und 
Schwarz) die ansteuerung nicht ganz im schönen Binärcode, bei den 
nidrigwertigen bits 0-3 klappt das schon mal (1,2,4,8 wertigkeit) die 4 
höheren bits haben die wertigkeit 10,20,40,80) das hat die firma 
seinerzeit so auf der Ansteuerlogig verdrahted und soll auch nicht 
geänder werden, die Ansteuerung war mal mit einem 8047 Prozessor, schon 
ein weile her. Ich habe füher vor meinem PC eine Menge Programme alle in 
Basic geschrieben (TRS80)dann nachher in Quickbasic, aber vieles ist 
weider weg. Daher auch meine Frage zur Tabelle. Ich hatte da an eine 
Matrix-varibable gedacht. Früher ging das mit read und Data, da war es 
dann sehr schnell möglich aus einer 2 dimensionalen Matrix einen 
x-beliebig großen Wert zu holen. Ja , und die Schlange, mit dem Karnikel 
, die kenne ich auch.... Mein Spruch, Versuch macht Kluch..... Bin schon 
mal froh, das ich die Hardware mit dem ersten Programmen so gurt am 
laufen bekommen habe , auch wenn das erst mit der Diskplayausgabe nicht 
gehen wollte. War einer Fehler in den SFR-Registern mit einer Zuweisung. 
Ich bin noch einer von denen, die in der von Neuman-Maschinenlogik 
denken, ist halt schwer umzu steigen. Danke schon mal für deinen Tipp 
mit der Keyeingabe
Gruß Christian Petersen

von Karl H. (kbuchegg)


Lesenswert?

Christian P. schrieb:
> Hallo und danke schon mal für den Hinweis. Das mit den Zahlen einlesen
> werde ich nachher gleich mal umsetzen.Mit der ausgabe habe ich es noch
> nicht ganz klar. Schon klar , wenn die Zahl größer 100 ist kann das bit
> gleich gesetzt werden. Leider ist bei meiner Ansteuerplatine (Rhode und
> Schwarz) die ansteuerung nicht ganz im schönen Binärcode, bei den
> nidrigwertigen bits 0-3 klappt das schon mal (1,2,4,8 wertigkeit) die 4
> höheren bits haben die wertigkeit 10,20,40,80) das hat die firma
> seinerzeit so auf der Ansteuerlogig verdrahted und soll auch nicht
> geänder werden,

Na, dann geht das Spielchen eben weiter.
Die 100 sind bereits abgehackt und die nächste Frage lautet

   ist der zu realisierende Wert größer/gleich 80?
   wenn ja, dann schalte das 80-er Relais ein (ansonsten aus) und ziehe
   vom zu realisiernden Wert 80 ab.

   ist der zu realisiernde Wert größer/gleich 40?
   wenn ja, dann schalte das 40-er Relais ein und ziehe vom zu
   relaisiernden Wert 40 ab.

   ist der ....


usw.
Das ganze sind also lediglich ein paar Abfragen hintereinander, sodass 
der 'zu realisiernde Wert' mit jedem eingeschaltetem Relais immer 
kleiner wird.


Machst du ja zb bei Gelddingen auch nicht anders.
Du sollst deinem Gegenüber 153 Euro geben.
153, das ist größer als 100, also gibst du ihm erst mal einen Hunderter 
und du musst ihm noch 53 Euro geben
53, das ist größer als 50, also gibst du ihm noch einen 50-er und du 
musst ihm noch 3 Euro geben
3 ist nicht größer als 20, also brauchst du ihm keinen 20-er geben
3 ist nicht größer als 10, also kriegt er auch keinen 10-er
3 ist nicht größer als 5, also kriegt er da auch nichts
3 ist größer als 2, also kramst du noch eine 2 Euro Münze raus und du 
musst ihm danach noch 1 Euro geben
1 Euro ist größer/gleich 1, also kriegt er auch noch eine 1 Euro Münze, 
und du musst ihm noch 0 Euro geben

kleinere Münzen gibt es nicht, und wenn du alles zusammenzählst, dann 
hast du ihm 153 Euro in Form von
   1 Hunderter
   1 Funfziger
   1 2 Euro
   1 1 Euro
gegeben. Macht zusammen die 153.


Wobei es bei Gelddingen ein klein wenig komplizierter ist, weil sich 
nicht alle Beträge dadurch darstellen lassen, indem man von jeder Sorte 
nicht mehr als 1 Schein benutzt. Aber bei deinen Relais geht das, weil 
die sinnvollerweise in 2-er Potenzen (zumindest fast) gestaffelt sind. 
Ganz im Gegenteil, du hast sogar für einige Werte mehrere Möglichkeiten. 
Und mit dem System bevorzugst du dann immer das Schalten von möglichst 
wenigen Relais.

Den Wert 1 realisierst du dadurch mit den Relais für 10 und 1, und nicht 
mit den Relais für 8+2+1

> weider weg. Daher auch meine Frage zur Tabelle. Ich hatte da an eine
> Matrix-varibable gedacht.

Viel zu kompliziert.
Das sind 9 if, mit jeweils einem Portbit schalten bzw. einer 
Subtraktion. Mehr ist das nicht.

Aber: Eins nach dem anderen. Die Relais kommen ein andermal drann. Erst 
mal muss die Zahl durch Tastendrücke entstehen.

von Christian P. (christian_p20)


Lesenswert?

Guten Morgen, danke schon einmal für deine Hinweise und Tipps,
habe mich gestern da mal durchgewurschtelt und kann den Wert von der 
Tastatur kommend auch schon ausgeben auf dem LED-Feld, welches ich 
ersatzweise für die später folgenden Relais verwende. Allerdings habe 
ich noch meine Probleme mit der ausgabe und Umrechnung der Binärwerte 
für die Relais, so wie du es vorgeschlagen hast.
Ich sende dir mal mein Programmlisting mit der Bitte da einmal einen 
Blick
drauf zu werfen
Vielleicht kannst du mir ja die ausgabe noch ein wenig plausibler 
machen.
Ich hatte das schon verstanden , das du es über 9 If- Abfragen machen 
wolltest statt wie von mir vorgeschlagen mit einer riesen Tabelle. Gebe 
mir doch bitte noch einmal einen hinweis wo der Fehler liegt.



------------------------------------------------------------------------ 
---
program Eichleitung_1
' Programm für Pic 18f4520 zur Datenausgabe an die Relaissteuerung einer 
R&S
'Eichleitung mit 9 bistabilen Relais an Bit 0-7 port D und Bit 1 Port E
' An Port C liegt ein 3x4 Tastenfeld
'An Port B ist das LCD-Display angeschlossen

dim taste, ausgabe, dummi, wert, summe, kp, cnt  as byte
    txt as char[5]   ' Variablen deklarieren

dim keypadPort as byte at PORTC

dim
       LCD_RS as sbit at LATB.B2
       LCD_EN as sbit at LATB.B3
       LCD_D4 as sbit at LATB.B4
       LCD_D5 as sbit at LATB.B5
       LCD_D6 as sbit at LATB.B6
       LCD_D7 as sbit at LATB.B7

       LCD_RS_Direction as sbit at TRISB2_bit
       LCD_EN_Direction as sbit at TRISB3_bit
       LCD_D4_Direction as sbit at TRISB4_bit
       LCD_D5_Direction as sbit at TRISB5_bit
       LCD_D6_Direction as sbit at TRISB6_bit
       LCD_D7_Direction as sbit at TRISB7_bit
' Ende der Deklaration für das LCD-Display

main:
  dummi = 0
  wert = 0
  summe = 0
  taste = 0
  ausgabe = 0
   portd = dummi                       ' Anzeige LEDS auf Ausgang und 0 
setzen

  trisa =0                           'Port A = auf Ausgang setzten
   Trisd = 0                     ' Port dals Ausgang und auf 0 setzten
    Trise = 0                    ' port auf Ausgang und 0 setzten


  Keypad_Init()                      ' Initialisiere Keypad

   Lcd_Init()                         ' Initialize LCD
   Lcd_Cmd(_LCD_CLEAR)                 ' Clear display
   Lcd_Cmd(_LCD_CURSOR_OFF)            ' LCD Cursor ausschalten

   Lcd_Out(1, 1, "DD7LP-Elektronik")    ' Text ausgeben Einschaltmeldung
   Lcd_Out(2, 1, "Step-Att 1-140db")
   delay_ms(3000)                       ' Delay von 3 Sekunden

   Lcd_Cmd(_LCD_CLEAR)                  ' Display löschen
   Lcd_Cmd(_LCD_CURSOR_OFF)             ' LCD Cursor ausschalten

   Lcd_Out(1, 1, "Attenuator ")             ' Schreibt  message text on 
LCD
   Lcd_Out(1, 14, " db")
   Lcd_Out(2, 1, "DD7LP-Elektronik")

 while TRUE

    kp = 0                            ' Tasten Variable auf 0 setzen

    ' Waretn auf Tastendruck und fortfahren
    while ( kp = 0 )
      kp = Keypad_Key_Click()     ' Speichert den Tastencode in kp
    wend
     if kp = 13  then
         taste = 0
         wert = 0
         kp = 0
         end if

    ' Bereitet die Zahl für die Ausgabe vor,transformiert Taste in 
ASCII Zahl
    select case kp
                         'standart: kp += 48
                         'ausgelegt für ein 4x4 Tastenfeld
    case 1
      kp = 49  ' 1
    case 2
      kp = 50  ' 2
    case 3
      kp = 51  ' 3
    case 4
      kp = 65  ' A
    case 5
      kp = 52  ' 4
    case 6
      kp = 53  ' 5
    case 7
      kp = 54  ' 6
    case 8
      kp = 66  ' B
    case 9
      kp = 55  ' 7
    case 10
      kp = 56  ' 8
    case 11
      kp = 57  ' 9
    case 12
      kp = 67  ' C
    case 13
      kp = 42  ' *
    case 14
      kp = 48  ' 0
    case 15
      kp = 35  ' #
    case 16
      kp = 68  ' D
    end select

      taste = kp - 48                  'Taste hat jetz den wert von kp
      wert = wert * 10  + taste        ' in Wert steht der db-Wert 
dezimal

    if (wert  >  140) then      ' maximalwert 140 db erreicht, dann 
löschen
       taste = 0                ' Variablen auf 0 setzten
       kp = 0
       wert = 0
       portd = 0
      Lcd_Out(1, 11 ,"   ")
    end if

          WordToStr( wert ,txt)  '     Transformiert Zählerwert in 
String
          Lcd_Out(1, 9 , txt)    '     Zeigt Zählerwert auf LCD

           'portd = wert         Testausgabe zur Kontrolle
           ' gibt den eingegebenen Tastenwert binär an port D
           ' an die LEDs statt der Relais aus
        ausgabe = wert   ' Ausgabevariable  mit Wertvariable setzen

      if ausgabe > 100 then porte = 1    ' stelle 9 berechnen 100 db
      ausgabe = ausgabe - 100
      'else porte =0
       end if

      if ausgabe > 80 then portd  = 128    ' stelle 8 berechnen 80 db
      ausgabe = ausgabe - 80
      'else portc =0
       end if

      if ausgabe > 40 then portd  = 168   ' stelle 8 berechnen 80 db
      ausgabe = ausgabe - 40
      'else portc =0
       end if

       if ausgabe > 20 then portd  = 188    ' stelle 8 berechnen 80 db
       ausgabe = ausgabe - 20
       'else portc =0
        end if

       if ausgabe > 10 then portd  = 198    ' stelle 8 berechnen 80 db
       ausgabe = ausgabe - 10
       'else portc =0
        end if

       if ausgabe > 8 then portd  = 206    ' stelle 8 berechnen 80 db
       ausgabe = ausgabe - 8
       'else portc =0
        end if

       if ausgabe > 4 then portd  = 132    ' stelle 8 berechnen 80 db
       ausgabe = ausgabe - 4
       'else portc =0
        end if

       if ausgabe > 2 then portd  = 134    ' stelle 8 berechnen 80 db
       ausgabe = ausgabe - 2
       'else portc =0
        end if

       if ausgabe > 1 then portd  = 135    ' stelle 8 berechnen 80 db
       ausgabe = ausgabe - 1
       'else portc =0
        end if

       if ausgabe > 0 then portd  = 136    ' stelle 8 berechnen 80 db
       ausgabe = ausgabe - 0
       'else portc =0
        end if

  wend      ' Ende der Programmschleife

end.

------------------------------------------------------------------------ 
---



mit freundlichem Gruß Christian

von Karl H. (kbuchegg)


Lesenswert?

Ich greif mal eine heraus
1
     if ausgabe > 80 then portd  = 128    ' stelle 8 berechnen 80 db
2
      ausgabe = ausgabe - 80
3
      'else portc =0
4
       end if

du kannst (und willst) hier nicht den kompletten Port als ganzes mit 
einer Zahl bestücken, sondern nur EIN EINZIGES BIT daran umstellen. Wie 
das in Mikrobasic geht, kann ich dir nicht sagen, weil ich das nicht 
kenne. Aber wenn ich aus dem restlichen Programm mal interpoliere und 
mich an dem orientiere was da für das LCD gemacht wird, dann würde ich 
sowas schätzen
1
dim
2
3
       RELAIS_80  as sbit at LATD.B7
4
       RELAIS_60  .....
5
6
       LCD_RS as sbit at LATB.B2
7
       LCD_EN as sbit at LATB.B3
8
       LCD_D4 as sbit at LATB.B4
9
       LCD_D5 as sbit at LATB.B5
10
       LCD_D6 as sbit at LATB.B6
11
       LCD_D7 as sbit at LATB.B7
12
13
.....
14
15
16
     if ausgabe > 80 then
17
       RELAIS_80 = 1
18
       ausgabe = ausgabe - 80
19
     else
20
       RELAIS_80 = 0
21
     end if





und gewöhn dir eine saubere und konsistente Form an!
Wenn du zb bei einem if die abhängigen Anweisungen einrückst (und das 
solltest du tun), dann musst du das auch konsistent tun! Das kann dann 
nicht sein, das du schreibst
1
     if ausgabe > 80 then portd  = 128    ' stelle 8 berechnen 80 db
2
      ausgabe = ausgabe - 80
3
      'else portc =0
4
       end if

das portd =   steht auf der gleichen Zeile, die weiteren abhängigen 
Anweisungen stehn in den Zeilen darunter, das else ist nicht richtig 
eingerückt, die abhängige Anweisung vom else steht wieder in der 
gleichen Zeile und das end if steht zuweit rechts.
1
     if ausgabe > 80 then
2
       portd  = 128
3
       ausgabe = ausgabe - 80
4
     else
5
       portc =0
6
     end if

Die Form des Codes entspricht seiner Struktur! Vom Ausgang des 
Vergleichs ist etwas abhängig, nämlich die Anweisungen nach dem then. 
Und welche das sind, kann man mit einem Blick leicht erfassen. Denn die 
stehen alle sauber untereinander aufgereiht und um 2 Stellen eingerückt 
darunter. Und sie enden beim 'else', welches logisch zum if gehört und 
daher auch in der gleichen Spalte wie das if steht. Die Einrückung 
verdeutlicht mir, wie die Dinge logisch zusammengehören.

PS: ist dir aufgefallen, dass du im then an Port D zuweist, beim else 
aber an Port C? Ist aber hinfällig, da es anscheinend bei diesem Basic 
ja eine Möglichkeit gibt, wie man sich beim DIM einzelne Bits am Port 
mit Namen versehen kann und dann in weiteren Code nur noch mit diesem 
Namen arbeitet.

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.