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