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
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_80assbitatLATD.B7
4
RELAIS_60.....
5
6
LCD_RSassbitatLATB.B2
7
LCD_ENassbitatLATB.B3
8
LCD_D4assbitatLATB.B4
9
LCD_D5assbitatLATB.B5
10
LCD_D6assbitatLATB.B6
11
LCD_D7assbitatLATB.B7
12
13
.....
14
15
16
ifausgabe>80then
17
RELAIS_80=1
18
ausgabe=ausgabe-80
19
else
20
RELAIS_80=0
21
endif
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
ifausgabe>80thenportd=128'stelle8berechnen80db
2
ausgabe=ausgabe-80
3
'elseportc=0
4
endif
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
ifausgabe>80then
2
portd=128
3
ausgabe=ausgabe-80
4
else
5
portc=0
6
endif
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.