Archiv verlassen und diese Seite im Standarddesign anzeigen : Unterprogramme
Hallo
wie kann ich in bascom Unterprogramme machen ich habe ein sehr langes Programm und es ist auch mit rs232 steuerbar und ich möchte diese Steuerung gerne in ein Unterprogramm packen Sodas die restliche Steuerung ohne Pausen weiter läuft.
Danke im Voraus
Sauerbruch
05.06.2012, 18:04
Mit den Befehlen Gosub und Return.
peterfido
05.06.2012, 18:13
Do
Reset Watchdog' wenn man ihn nutzt
Gosub Uhranzeigen ' wird jedesmal aufgerufen
If Ischarwaiting() = 1 Then ' Wenn Zeichen über RS232 angekommen ist, dann dahin, sonst einfach mit Hauptschleife weitermachen
Gosub Empfangen
End If
Loop
End
Empfangen:
A = Inkey()
If A >= 13 Then ' alles kleiner 13 wird einfach abgeschnitten. Nutze ich hauptsächlich, da ich Werte im String übertrage
If A = 13 Then
Gosub Auswerten
Else
If Len(seingang) < Maxlaenge Then ' nicht, dass seingang "platzt" und die nächsten Variablen überschreibt
Seingang = Seingang + Chr(a)
End If
End If
End If
Return
Auswerten:
... ' hier der Code, um das Empfangene auszuwerten
...
...
return
$crystal = 1000000
$regfile = "m16def.dat"
$baud = 2400
Config Pinb.6 = Input
Config Portc = Output
Config Timer1 = Pwm , Pwm = 10 , Compare A Pwm = Clear Down , Prescale = 1
Config Lcdpin = Pin , Db4 = Portb.2 , Db5 = Portb.3 , Db6 = Portb.4 , _
Db7 = Portb.5 , E = Portb.1 , Rs = Portb.0
Config Adc = Single , Prescaler = Auto , Reference = Avcc
Start Adc
Config Lcd = 16 * 2
Cursor Off
Cls
Dim Asd As String * 255
Dim P1 As Integer
Dim P2 As Integer
Dim P3 As Integer
Dim P4 As Integer
Dim P5 As Integer
Dim P6 As Integer
Dim P7 As Integer
Dim P8 As Integer
Dim P9 As Integer
Dim P10 As Integer
Do
If Pinb.6 = 0 Then
Locate 1 , 1
Lcd P1
Locate 1 , 5
Lcd "P1"
Locate 1 , 8
Lcd P2
Locate 1 , 12
Lcd "P2"
Locate 2 , 1
Lcd P3
Locate 2 , 5
Lcd "P3"
Locate 2 , 7
Lcd P4
Locate 2 , 11
Lcd "P4"
Locate 2 , 13
Lcd P5
Else
Locate 1 , 1
Lcd P6
Locate 1 , 5
Lcd "P6"
Locate 1 , 8
Lcd P7
Locate 1 , 12
Lcd "P7"
Locate 2 , 1
Lcd P8
Locate 2 , 5
Lcd "P8"
Locate 2 , 7
Lcd P9
Locate 2 , 11
Lcd "P9"
Locate 2 , 13
Lcd P10
End If
P6 = Getadc(0)
P7 = Getadc(1)
P8 = Getadc(2)
P9 = Getadc(3)
P10 = Getadc(4)
If P1 <> P6 Then Portc.0 = 1 Else Portc.0 = 0
If P1 = P6 Then Portc.1 = 1 Else Portc.1 = 0
If P2 <> P7 Then Portc.2 = 1 Else Portc.2 = 0
If P2 = P7 Then Portc.3 = 1 Else Portc.3 = 0
If P3 <> P8 Then Portc.4 = 1 Else Portc.4 = 0
If P3 = P8 Then Portc.5 = 1 Else Portc.5 = 0
If P4 <> P9 Then Portc.6 = 1 Else Portc.6 = 0
If P4 = P9 Then Portc.7 = 1 Else Portc.7 = 0
'ANFANG UNTERPROGRAMM
Asd = ""
Input Asd
Select Case Asd
Case "1,"
Input P1
Print P1
Case "2," 'p2 schreiben
Input P2
Print P2
Case "3," 'p3 schreiben
Input P3
Print P3
Case "4," 'p3 schreiben
Input P4
Print P4
Case "5," 'p3 schreiben
Input P5
Print P5
End Select
'ENDE UNTERPROGRAMM
Loop
End
ICH MÖCHTE DEN BEREICH WO anfang und ende unterprogramm steht in ein unterprogramm packen damit der rest einfach weiter läuft
peterfido
05.06.2012, 18:56
Der Rest läuft nicht einfach weiter. Ein Input blockiert den MC auch in einem Unterprogramm, wenn da keine Daten anliegen.
$crystal = 1000000
$regfile = "m16def.dat"
$baud = 2400
Config Pinb.6 = Input
Config Portc = Output
Config Timer1 = Pwm , Pwm = 10 , Compare A Pwm = Clear Down , Prescale = 1
Config Lcdpin = Pin , Db4 = Portb.2 , Db5 = Portb.3 , Db6 = Portb.4 , _
Db7 = Portb.5 , E = Portb.1 , Rs = Portb.0
Config Adc = Single , Prescaler = Auto , Reference = Avcc
Start Adc
Config Lcd = 16 * 2
Cursor Off
Cls
Dim Asd As String * 5
Dim P0 As Byte At Asd Overlay
Dim P1 As Word At Asd + 2 Overlay
Dim B As Byte
Dim P(10) As Word
Do
If Pinb.6 = 0 Then
Locate 1 , 1
Lcd P(1)
Locate 1 , 5
Lcd "P1"
Locate 1 , 8
Lcd P(2)
Locate 1 , 12
Lcd "P2"
Locate 2 , 1
Lcd P(3)
Locate 2 , 5
Lcd "P3"
Locate 2 , 7
Lcd P(4)
Locate 2 , 11
Lcd "P4"
Locate 2 , 13
Lcd P(5)
Else
Locate 1 , 1
Lcd P(6)
Locate 1 , 5
Lcd "P6"
Locate 1 , 8
Lcd P(7)
Locate 1 , 12
Lcd "P7"
Locate 2 , 1
Lcd P(8)
Locate 2 , 5
Lcd "P8"
Locate 2 , 7
Lcd P(9)
Locate 2 , 11
Lcd "P9"
Locate 2 , 13
Lcd P(10 )
End If
P(6) = Getadc(0)
P(7) = Getadc(1)
P(8) = Getadc(2)
P(9) = Getadc(3)
P(10) = Getadc(4)
If P(1) <> P(6) Then Portc.0 = 1 Else Portc.0 = 0
If P(1) = P(6) Then Portc.1 = 1 Else Portc.1 = 0
If P(2) <> P(7) Then Portc.2 = 1 Else Portc.2 = 0
If P(2) = P(7) Then Portc.3 = 1 Else Portc.3 = 0
If P(3) <> P(8) Then Portc.4 = 1 Else Portc.4 = 0
If P(3) = P(8) Then Portc.5 = 1 Else Portc.5 = 0
If P(4) <> P(9) Then Portc.6 = 1 Else Portc.6 = 0
If P(4) = P(9) Then Portc.7 = 1 Else Portc.7 = 0
'ANFANG UNTERPROGRAMM
If Ischarwaiting() = 1 Then
Gosub Empfangen
End If
'ENDE UNTERPROGRAMM
Loop
End
Empfangen:
B = Inkey()
If Len(asd) < 5 Then
Asd = Asd + Chr(b)
End If
If Len(asd) = 5 Then
Gosub Auswerten
End If
Return
Auswerten:
If P0 > 0 And P0 < 6 Then
P(p0) = P1
Print P(p0)
End If
asd=""
Return
Könnte jetzt laufen.
Jedoch wird keine Abweichung / Versatz abgefangen
Wer sendet denn die Daten und wie werden die abgeschlossen?
sie werden vom pc gesendet (bascom oder putty ) per rs232
also jetzt ist es so das wenn ich 1, absende weiß der amtega16 die vari. p1 wird jetzt mit der nächsten zahl beschrieben und wenn er das gemacht hat gibt er die gleiche zahl zurück. nur hält das programm an wenn ich nichts sende was mein prob. ist :confused:
Und was spricht dagegen einen USART Interrupt zu verwenden?
Dann läuft das Programm weiter solange nichts empfangen wird. Sobald was empfangen wird, springt der Controller in die ISR und dort musst du dann die Daten aus dem Buffer holen und das Empfangene richtig zusammensetzen (wenn es ein String ist den du sendest).
Guckste hier:
http://www.rowalt.de/mc/avr/avrboard/06/avrb06.htm
(http://www.rowalt.de/mc/avr/avrboard/06/avrb06.htm)
USART-Interrupts sind eh die elegantere Wahl um was zu empfangen. Eben aus deinem speziellen Grund.
Edit:
Und pack mal deinen Code zwischen {code} und {/code}. Nur halt diese Klammern nehmen []
Dann sieht das so aus
Blablablabla
Blablablabla
Blablablabla
Blablablabla
Blablablabla
Blablablabla
Blablablabla
Blablablabla
Blablablabla
und die Leser haben nicht direkt so eine Textwand vor sich. Ich für meinen Teil habe mir da erstmal nur gedacht TLDR - Too long don´t read....und ich bin sicher nicht der einzigste ;)
kann einer von euch nich meinen code umändern weil ich kp von usart habe
bitte :D
kann einer von euch nich meinen code umändern weil ich kp von usart habe
bitte :D
Was verstehst du den am USART nicht?
Sagen wir es mal so....USART ist von den "Busen" her der einfachste ;)
Und wenn du den Bus nicht verstehst, dann nutz doch die Gelegenheit deines Problems um dich mal etwas intensiver mit ihm zu beschäftigen.
Wenn dir das jetzt jemand vorkaut wirst du das Prinzip nie verstehen. Am meisten lernst du nicht wenn etwas funktioniert sondern wenn etwas NICHT funktioniert.
Hilfestellung kann dir jeder hier geben.
Aber wie heißt es so schön.....wir können dir den Weg zeigen. Aber ans Ziel musst du alleine kommen.
Fang erstmal klein an. Nutze dafür den Link den ich dir gegeben habe. Und dann arbeite dich immer weiter vor.
danke aber ich blick da echt nich durch habe mir die seite angeschaut aber nop ich hab kp wie das gehen soll kanste mir den code nich machen dann hab ich was wo ich sehen kann aha da is mein eingang was ich sende und da schaltet der das so um das das programm weiter leuft.
peterfido
06.06.2012, 16:39
Demnach scheint mein letztes Beispiel wohl nicht zu laufen...
in deinem habe ich nirgenswo gefunden wo ich die daten übertrage halt mit 1, die variable bestimmen und dann den wert irg wie ka :confused:
Hier ist ein kleines Programm welches 1 Zeichen empfängt und in einem String speichert. Im Hauptprogramm wird dieses Zeichen dann ausgewertet:
$regfile = "m32def.dat"
$crystal = 16000000
$baud = 19200
Dim Eingabe As String * 1
On URXC OnRxD
Enable URXC
Enable Interrupts
Do
If Eingabe = "1" Then
Print "Zahl 1"
Eingabe = ""
End If
Loop
End
Onrxd:
Eingabe = Chr(udr)
Return
ich kann gerade nich mehr programmieren "could not detect chip,auto program failed"
geht das mit zahlen genau so ? ja oder
Ja.
Siehst du doch in der If-Abfrage welches Zeichen ich auswerte.
ich habe gafragt ob es mit zahlen geht und du hast ja gesagt und sagst im nächsten satzt welches zeichen ich auswerte zeichen sind keine zahlen zeichen kann ich nicht in eine var laden und auswert und damit rechnen
Wenn Zahlen keine Zeichen sind wieso stehen die dann hier drin?:
http://www.asciitable.com/
Sowohl Zeichen als auch Zahlen bestehen aus Bits. Der Mikrocontroller weiß nicht ob ein Bitmuster eine Zahl oder ein Buchstabe ist.
Mal davon abgesehen rechnet man sehr wohl mit Buchstaben (Stichwort Hex-System).
Die If-Abfrage macht nichts anderes als das BITMUSTER was in der Variable steht (du erinnerst dich vielleicht, dass die ISR ein Zeichen empfängt. Ein Zeichen ist nichts anderes als ein Bitmuster) mit einem Bitmuster welches du vorgibst zu vergleichen.
Natürlich macht der Mikrocontroller einen Unterschied zwischen 0x01 (welches den Wert 1 darstellt und den Wert 0x31 welches der ASCII Wert für 1 ist).
Wenn du schreibst "If Variable = "1" then" wird der Inhalt der Variable mit dem ASCII-Code von der 1 verglichen. Sprich du tippst am Terminal ne 1 ein und dann wird die Bedingung erfüllt. Wenn du nun aber schreibst "If Variable = 1 then" wird der Hex-Wert(!) der Variable verglichen. Ist der Hex-Wert(!) = 1 dann wird der Befehl ausgeführt.
Beispiel:
Hex-Wert von der "1" auf der Tastatur ist 0x31.
Ein ASCII Zeichen mit dem Hex-Wert von 1 ist der Befehl "SOH"
Siehst du am besten in der ASCII Tabelle.
Das Programm was ich da gepostet habe vergleicht das was du an der Tastatur mittels Terminal an den µC senden willst. Wenn du nun einen Zahlenwert vergleichen willst (z.B. von nem Zähler) musst du "If Variable = (Wert)" schreiben.
ja ok da haste recht aber ich komm damit nicht kla das ich die gesendeten daten in die var bekomme
Das macht doch die ISR.
Die speichert das empfangene Zeichen in nem String.
Den musst du nur noch auswerten....oder verstehe ich gerade dein Problem nicht?
ich habe 5 var muss sie erst bestimmern welche ich gerade bearbeite und dann den neuen wert hineinspeichern
wie kann ich 2 var vergleichen und unterschiede von +-5 eingeben also der soll sagen var 1 und 2 sind gleich auch wenn die +-5 abweichung haben also ~
Du machst eine If-Abfrage mit deinen Grenzen als Bedingung.
Sprich
Ergebnis = var1 - var 2
If Ergebnis > 5 Then
Print "Variable 1 ist um mehr als 5 größer als Variable 2"
elseif Ergebnis < -5
Print "Variable 2 ist um 5 größer als Variable 1"
else
Print "Variable 1 und 2 sind beinahe gleich"
End if
Ist ungetestet aber es soll nur das Prinzip verdeutlichen.
nein ohne print ich muss nur den port auf 1 setzten wenn die um min +-5 gleich sind p1 und o2 werden über getadc ermittelt
Das Print war auch nur ein Beispiel. Statt Print kannst du da jeden anderen Befehl reinsetzen......
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.