PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Unterprogramme



Zardest
05.06.2012, 16:18
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

Zardest
05.06.2012, 18:33
$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?

Zardest
05.06.2012, 22:51
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:

Kampi
05.06.2012, 23:38
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 ;)

Zardest
06.06.2012, 14:08
kann einer von euch nich meinen code umändern weil ich kp von usart habe

bitte :D

Kampi
06.06.2012, 14:38
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.

Zardest
06.06.2012, 16:33
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...

Zardest
06.06.2012, 17:10
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:

Kampi
06.06.2012, 17:21
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

Zardest
06.06.2012, 17:29
ich kann gerade nich mehr programmieren "could not detect chip,auto program failed"

Zardest
06.06.2012, 22:28
geht das mit zahlen genau so ? ja oder

Kampi
06.06.2012, 22:36
Ja.
Siehst du doch in der If-Abfrage welches Zeichen ich auswerte.

Zardest
12.06.2012, 14:58
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

Kampi
12.06.2012, 15:17
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.

Zardest
12.06.2012, 15:20
ja ok da haste recht aber ich komm damit nicht kla das ich die gesendeten daten in die var bekomme

Kampi
12.06.2012, 15:24
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?

Zardest
12.06.2012, 18:05
ich habe 5 var muss sie erst bestimmern welche ich gerade bearbeite und dann den neuen wert hineinspeichern

Zardest
13.06.2012, 14:56
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 ~

Kampi
13.06.2012, 15:11
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.

Zardest
13.06.2012, 15:20
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

Kampi
13.06.2012, 15:47
Das Print war auch nur ein Beispiel. Statt Print kannst du da jeden anderen Befehl reinsetzen......