-         

Ergebnis 1 bis 6 von 6

Thema: "schleife" unterbrechen

  1. #1
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    24
    Beiträge
    1.544

    "schleife" unterbrechen

    Anzeige

    servus leude,

    ich will für ein etwas größeres projekt einige einzelteile davon fertigstellen.
    mein jetztiges problem ist es, dass ich eine schleife mit einem tastendruck unterbrechen möchte.

    Code:
    for i = 1 to 100
    for n = 0 to 7
    portc.n = 0
    waitms 100
    portc.n = 1
    next n
    next i
    diese schleife läuft im normalfall 100 mal durch, bis das programm etwas anderes macht. das soll auch so sein.
    nur habe ich in dem programm die tastenabfrage vom rn-control. jetzt möchte ich, dass bei taste 3 dieser obige code durchläuft.
    sollte jedoch bevor i = 100 eine andere taste gedrückt worden sein, soll dieser code sofort verlassen werden und es soll die aktion von taste x (dem tastendruck, der diesen code unterbrochen hat) ausgeführt werden.

    ich hoffe, mein gefassel ist so halbwegs verständlich und ihr könnt mir helfen.
    danke für eure bemühungen.

    gruß
    chris

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    16.02.2006
    Beiträge
    1.112
    Hi,
    ich geh' mal davon aus, dass der obige code nicht in einer ISR ausgeführt wird, denn dann ist er nicht unterbrechbar.
    Es gibt zwei Möglichkeiten, wie du auf Tastendrücke reagieren kannst. Entweder du fragst dauernd die Pins ab oder du hast die taster an einem externen Interrupt Eingang (z.B. Pin Change) angeschlossen.
    Wenn du selber abfragst und es nur eine Taste oder mehrere Tasten an einem Port sind, dann würde ich nach dem Wait eine If Abfrage einbauen. Etwa so:

    Code:
    Config Porta = Input
    Config Portc = Output
    Config Portd = Output
    Dim I As Byte , N As Byte , Taste As Byte , Tasten_flag As Byte
    If Taste = 1 Then
       For I = 1 To 100
          For N = 0 To 7
             portc.n = 0
             Waitms 100
             portc.n = 1
             If Pina > 0 Then
                Tasten_flag = 1
                Exit For
             End If
          Next N
          If Tasten_flag = 1 Then
             Exit For
          End If
       Next I
    Elseif Taste = 2 Then
       For I = 1 To 100
          For N = 0 To 7
             Portd.n = 0
             Waitms 100
             Portd.n = 1
             If Pina > 0 Then
                Tasten_flag = 1
                Exit For
             End If
          Next N
          If Tasten_flag = 1 Then
             Exit For
          End If
       Next I
    End If
    Tasten_flag = 0
    Taste = Pina
    Bei der Taste 1 habe ich jetzt einfach mal PortC eingeschaltet, bei Taste 2 PortD.
    Wenn mehrere tasten gleichzeitig gedrückt sein können, musst die Tastendrücke erst einmal zwischenspeichern.
    Löst der Druck einen externen Interrupt aus, dann wird das tasten_flag in der ISR gesetzt und anstelle des "If PINA > 0 Then" abgefragt.

    Klaro?

    Gruß

    Rolf

  3. #3
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    24
    Beiträge
    1.544
    hallo rolf,

    danke für deine antwort!

    allerdings funktioniert das so nicht
    ich habe hier mal meinen code, vielleicht kannst du dir das ja mal ansehen?!?!
    währe nett von dir!
    das gilt natürlich für alle

    Code:
    $regfile = "m32def.dat"
    $crystal = 16000000
    $baud = 9600
    $hwstack = 32
    $swstack = 10
    $framesize = 40
    
    Declare Function Tastenabfrage() As Byte
    Declare Sub Batteriespannung()
    
    Config Lcd = 20 * 4
    Config Lcdpin = Pin , Db4 = Portc.0 , Db5 = Portc.1 , Db6 = Portc.2 , Db7 = Portc.3 , E = Portc.4 , Rs = Portc.5
    Config Lcdbus = 4
    Config Adc = Single , Prescaler = Auto
    Config Pina.7 = Input
    Porta.7 = 1
    
    Config Timer1 = Timer , Prescale = 1024
    Enable Timer1
    Enable Interrupts
    Timer1 = 49910
    On Timer1 Isr_von_timer1
    
    Config Timer0 = Counter , Edge = Falling
    Enable Timer0
    Timer0 = 255
    On Timer0 Isr_von_timer0
    
    Dim A As Integer
    Dim Taste As Byte
    Dim Volt As Single
    Dim Secu As Single
    Dim Minu As Single
    Dim Hour As Single
    Dim X As Single
    Dim Tasten_flag As Byte
    Dim F As Single
    Dim T As Single
    Dim Freq As Single
    Dim N As Long
    
    Const Ref = 5 / 1023
    
    A = 1
    X = 1
    Secu = 00
    Minu = 00
    Hour = 00
    T = 0
    Tasten_flag = 0
    F = 0
    
    Cls
    Locate 1 , 4
    Lcd "Daten-Terminal "
    Locate 2 , 1
    Lcd "Zeit = "
    Locate 2 , 8
    Lcd Hour ; Minu ; Secu
    
    Do
    
    Taste = Tastenabfrage()
       If Taste <> 0 Then
    
          Select Case Taste
             Case 1
                Tasten_flag = 0
                Call Batteriespannung
             Case 2
                Tasten_flag = 0
                Writeeeprom Secu , 1
                Writeeeprom Minu , 10
                Writeeeprom Volt , 20
             Case 3
                For N = 1 To 100000000
                Freq = F / T
                Cls
                Locate 1 , 1
                Lcd "Sekunden = " ; T
                Locate 2 , 1
                Lcd "Signale = " ; F
                Locate 3 , 1
                Lcd "==> Frequenz = "
                Locate 4 , 1
                Lcd Freq ;
                If Taste <> 3 Then
                Tasten_flag = 1
                Exit For
                End If
                If Tasten_flag = 1 Then
                Exit For
                End If
                Wait 1
                Next N
             Case 4
                Tasten_flag = 0
                If Secu = 60 Then
                Secu = 00
                Minu = Minu + 1
                Elseif Minu = 60 Then
                Minu = 00
                Hour = Hour + 1
                End If
                Cls
                Locate 2 , 1
                Lcd "Zeit = "
                Locate 2 , 8
                Lcd Hour ; Minu ; Secu ;
                Waitms 10
             Case 5
                Tasten_flag = 0
                Readeeprom Secu , 1
                Readeeprom Volt , 20
                Cls
                Locate 1 , 4
                Lcd " Daten-Terminal "
                Locate 2 , 1
                Lcd Secu ; " Sekunden "
                Locate 3 , 1
                Lcd Minu ; " Minuten "
                Locate 4 , 1
                Lcd Volt ; " Volt "
          End Select
       End If
    
    Loop
    
    Isr_von_timer1:
    Timer1 = 49910
    Incr Secu
    Incr T
    Return
    
    Isr_von_timer0:
    Timer0 = 255
    Incr F
    Return
    
    Function Tastenabfrage() As Byte
    Local Ws As Word
    
       Tastenabfrage = 0
       Start Adc
       Ws = Getadc(7)
       If Ws < 500 Then
          Select Case Ws
             Case 400 To 450
                Tastenabfrage = 1
             Case 330 To 380
                Tastenabfrage = 2
             Case 260 To 305
                Tastenabfrage = 3
             Case 180 To 220
                Tastenabfrage = 4
             Case 90 To 130
                Tastenabfrage = 5
          End Select
    
       End If
    
    
    End Function
    
    Sub Batteriespannung()
    Local W As Word
       Start Adc
       W = Getadc(6)
       Volt = W * Ref
       Volt = Volt * 5.2941
       Cls
       Locate 1 , 1
       Lcd "Die aktuelle "
       Locate 2 , 1
       Lcd "Spannung  betraegt: "
       Locate 3 , 1
       Lcd Volt ; " Volt "
       Waitms 100
    End Sub
    im prinzip möchte ich ja nur, dass der code in case 3 bis zu einem tastendruck (der dafür sorgt, dass das prog zu einem anderem case springt) ausgeführt wird und dann soll der andere case-code laufen.

    gruß
    chris

  4. #4
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.791
    Hallo chris,

    wenn du innerhalb der Schleife mit der Variable N keine Tastaturabfrage machst, kann die Variable "Taste" nie einen anderen Wert als 3 annehmen. Der Wert 3 ist ja im "Case 3" Abschnitt immer gleich.

    Gruß Dirk

  5. #5
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    24
    Beiträge
    1.544
    ok, danke
    jetzt funzt's.

    jetzt habe ich nur noch eine frage:

    ich möchte das display immer aktualisieren, deshalb das cls und wait1 in case 3.
    gibt es dafür nicht einen befehl, der mir das macht??
    außerdem habe ich das problem bei wait 1, dass ich solange auf die taste drücken muss, bis der teil-code durchgelaufen ist (im extremfall 1 sec)....
    wenn ich allerdings waitms 1 oder so schreibe, dann kann man auf dem lcd nichts mehr lesen, da das zu schnell ist.
    gibt es dafür auch eine lösung???

    gruß
    chris

  6. #6
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.791
    Hallo chris,
    ... dann kann man auf dem lcd nichts mehr lesen, da das zu schnell ist. gibt es dafür auch eine lösung???
    Das ist eine grundsätzliche Frage zur Ansteuerung eines LCD.

    Die stabilste Anzeige ergibt sich auf einem LCD dann, wenn man immer nur dann (und auch nur 1x) etwas auf das LCD schreibt, wenn sich die Anzeige ändern soll.
    Bei einer Uhrenanzeige ist das einfach: Man schreibt nur dann auf das LCD, wenn sich die Sekunde ändert. Dazu speichert man sich in einer Variablen (z.B. Oldsecond) die Sekunde ab, die man beim letzten Mal auf das LCD geschrieben hat. Ist Second noch = Oldsecond, dann wird der Schreibbefehl für das LCD einfach übersprungen.
    Ist Second <> Oldsecond, dann wird die Uhrzeit neu auf das LCD geschrieben und Oldsecond = Second gesetzt.

    Das alles geht dann völlig ohne Cls. Cls würde ich auch weitgehend vermeiden, weil es ein Flimmern durch das Löschen des ganzen LCDs macht, sondern immer nur die geänderten Infos an die Stelle schreiben, wo sie hinsollen. Alle nicht geänderten Texte ("Daten-Terminal") bleiben immer da stehen und werden nicht überschrieben.

    Wenn du das so machst, kannst du Wait-Befehle in deiner Hauptschleife ganz weglassen.

    Gruß Dirk

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •