-         

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 15

Thema: Mit Bascom Schleife starten, welche per Tastendruck unterbrochen wird

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    16.08.2011
    Beiträge
    28

    .........................

    Anzeige

    .........................
    Geändert von User45322 (25.08.2017 um 21:18 Uhr)

  2. #2
    Moderator Robotik Einstein Avatar von Kampi
    Registriert seit
    21.11.2009
    Ort
    Monheim, Nordrhein-Westfalen, Germany
    Alter
    28
    Beiträge
    3.517
    Blog-Einträge
    9
    Wenn der bei 200ms im Programm keine 200ms wartet sondern mehr oder weniger ist diese Zeile vlt falsch:

    $crystal = 1000000

    Mit dieser Zeile sagst du dem Compiler mit welchem Takt dein Controller läuft. Dieser Wert ist NUR fürs kompilieren wichtig und dient als Grundlage für die Berechnung von z.B. 200ms Pause.
    Wenn du da, wie in deinem Programm, einen Takt von 1MHz angibst aber an deinem Controller ein 16MHz Quarz dran ist und mit den Fusebits auch aktiviert ist dann stimmt z.B. der Befehl "Wait 1" nicht. Der wartet dann keine Sekunde in Echtzeit sondern weitaus länger, weil der Compiler die Berechnungen für die 1 Sekunde Pause anhand der 1MHz Taktvorgabe gemacht hat. Der Compiler weiß ja gar nicht das du deinen Controller mit 16MHz betreibst.
    Also guck mit welchem Takt dein Controller läuft, ob er wirklich mit 1MHz intern läuft oder mit 8MHz intern oder mit z.B. 16MHz extern. Anschließend schreibst du dann:

    $crystal = Dein Takt

    und dann sollte eine 200ms Pause auch etwa 200ms dauern.
    Zu deiner ersten Frage. Du machst dir einfach nen Flag z.B. so

    Byte Flag = 1

    If Taste = 1 Then
    Flag = 0
    else if Taste = 0 Then
    Flag = 1

    und anschließend sagste:

    Do
    while Flag = 1
    Dein Lauflicht

    Loop
    End

    Sobald nun "Taste" auf 0 liegt wird das Flag gelöscht und die while-Schleife die dein Lauflicht beinhaltet stopt. Den Pin wo der Taster dran ist legste mit einem Pull-down an GND und den Taster legst du zwischen Vcc und den Pin. So ist der Pin auf 0 wenn der Taster gedrückt wird und wenn der Taster los gelassen wird schreibt der Controller wieder eine 1 in die Variable Flag.
    Alternativ kannst du das mit dem Flag setzen auch in einer ISR machen.
    Ich hoffe das beantwortet deine Frage

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    16.08.2011
    Beiträge
    28
    .........................
    Geändert von User45322 (25.08.2017 um 21:18 Uhr)

  4. #4
    Neuer Benutzer Öfters hier
    Registriert seit
    16.08.2011
    Beiträge
    28
    .........................
    Geändert von User45322 (25.08.2017 um 21:18 Uhr)

  5. #5
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    54
    Beiträge
    5.782
    Blog-Einträge
    8
    Code:
    '###################################################
    'step2.bas.BAS
    'für
    'RoboterNetz.de AVR Tutorial in RN-Wissen
    '
    'Autor: Frank Brall
    'Weitere Beispiele und Beschreibung der Hardware
    'unter
    '  http://www.Roboternetz.de oder
    '  http://www.Roboternetz.de/wissen
    '#######################################################
    
    $regfile = "m32def.dat"
    $framesize = 32
    $swstack = 32
    $hwstack = 32
    $crystal = 16000000
    
    Declare Function Tastenabfrage() As Byte
    
    Dim I As Integer
    Dim N As Integer
    Dim Ton As Integer
    Dim Flag As Byte
    Config Adc = Single , Prescaler = Auto
    
    Config Pina.7 = Input
    Porta.7 = 1
    
    Dim Taste As Byte
    
    Flag = 1
    Portc.0 = 1
                Portc.1 = 1
                Portc.2 = 1
                Portc.3 = 1
                Portc.4 = 1
                Portc.5 = 1
                Portc.6 = 1
                Portc.7 = 1
    
    Do
       Taste = Tastenabfrage()
       If Taste = 1 Then
          Flag = 0
       End If
       'Else
       If Taste = 0 Then
          Flag = 1
       End If
    Loop
    
    
      Main:
    
      Do
       Taste = Tastenabfrage()
       If Taste <> 0 Then
    
          Select Case Taste
             Case 1
                Goto Led1
             Case 2
               Goto Led2
             Case 3
                Goto Lederror
             Case 4
                Goto Lederror
             Case 5
                Goto Lederror
          End Select
          Sound Portd.7 , 400 , 500
          Config Portc = Output
       End If
    
       Waitms 100
    
    Loop
    
    End
    
    Lederror:
         Return
    
    Led1:
                Portc.3 = 0
                Portc.4 = 0
                Do
                Config Portc = Output
                Waitms 125
                Portc.2 = 0
                Portc.5 = 0
                Waitms 125
                Portc.1 = 0
                Portc.6 = 0
                Waitms 125
                Portc.0 = 0
                Portc.7 = 0
                Waitms 125
                Portc.0 = 1
                Portc.7 = 1
                Waitms 125
                Portc.1 = 1
                Portc.6 = 1
                Waitms 125
                Portc.2 = 1
                Portc.5 = 1
                Loop
          Return
    
    Led2:
    Do
       While Flag = 1
          Config Portc = Output
          Portc.0 = 0
          Waitms 100
          Portc.1 = 0
          Waitms 100
          Portc.2 = 0
          Waitms 100
          Portc.3 = 0
          Waitms 100
          Portc.4 = 0
          Waitms 100
          Portc.5 = 0
          Waitms 100
          Portc.6 = 0
          Waitms 100
          Portc.7 = 0
          Waitms 100
          Portc.0 = 1
          Waitms 100
          Portc.1 = 1
          Waitms 100
          Portc.2 = 1
          Waitms 100
          Portc.3 = 1
          Waitms 100
          Portc.4 = 1
          Waitms 100
          Portc.5 = 1
          Waitms 100
          Portc.6 = 1
          Waitms 100
          Portc.6 = 0
          Waitms 100
          Portc.5 = 0
          Waitms 100
          Portc.4 = 0
          Waitms 100
          Portc.3 = 0
          Waitms 100
          Portc.2 = 0
          Waitms 100
          Portc.1 = 0
          Waitms 100
          Portc.0 = 0
          Waitms 100
          Portc.7 = 1
          Waitms 100
          Portc.6 = 1
          Waitms 100
          Portc.5 = 1
          Waitms 100
          Portc.4 = 1
          Waitms 100
          Portc.3 = 1
          Waitms 100
          Portc.2 = 1
          Waitms 100
          Portc.1 = 1
          Waitms 100
       Wend
    Loop
    End
    Return
    
    'Diese Unterfunktion fragt die Tastatur am analogen Port ab
    Function Tastenabfrage() As Byte
    Dim Ws As Word
    
       Tastenabfrage = 0
       Ton = 600
       Start Adc
       Ws = Getadc(7)
       'Print "Tastenabfrage anpassen!ADC Wert ws=" ; Ws
       If Ws < 500 Then
          Select Case Ws
             Case 400 To 450
                Tastenabfrage = 1
                Ton = 550
             Case 330 To 380
                Tastenabfrage = 2
                Ton = 500
             End Select
          Sound Portd.7 , 400 , Ton                             'BEEP
    
       End If
    
    End Function
    
    
    
    Ende:
    End
    Dein Programm ist ein bisschen unaufgeräumt, keine Ahnung was da funktioniert. :)

    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  6. #6
    Neuer Benutzer Öfters hier
    Registriert seit
    16.08.2011
    Beiträge
    28
    .........................
    Geändert von User45322 (25.08.2017 um 21:19 Uhr)

  7. #7
    Erfahrener Benutzer Roboter Genie Avatar von Searcher
    Registriert seit
    07.06.2009
    Ort
    NRW
    Beiträge
    1.410
    Blog-Einträge
    101
    Mir würden die ganzen WAIT Anweisungen nicht gefallen, da in der ganzen Zeit, in der die LEDs geschaltet werden, kein Taster abgefragt werden kann und auch sonst nichts anderes gemacht werden kann.

    Deshalb würd ich die LEDs durch einen Timer gesteuert schalten. Wie der Timer benutzt und auf die richtige Zeit eingestellt wird steht hier: http://www.rn-wissen.de/index.php/Bascom_und_Timer

    Grober Programmablauf und Interrupt Service Routine (ISR) könnte so aussehen:
    (nicht getestet, kein Syntaxcheck!)

    Code:
    const links = 1
    const rechts = 0
    
    dim Richtung as byte
    dim Maske as byte
    dim timervorgabe as word
    
    Config Timer1 ....
    timervorgabe = xxxx 'Vorgabewert für LED Schaltintervall einstellen
    Timer1 = timervorgabe
    
    portc = &B00000000
    Richtung = links
    Maske = &B00000000
    
    On Timer1 ISR_Led_schalten
    
    enable timer1
    enable interrupts
    
    
    do
      tastenabfrage
      if taste = 1 then timervorgabe = xxxx
      if taste = 2 then timervorgabe = yyyy
    loop
    
    
    
    ISR_Led_schalten:
    
      Timer = timervorgabe
    
      if Richtung = links then
        portc = portc or maske
        shift Maske , left
      end if
    
      if Richtung = rechts then
        portc = portc and maske
        shift Maske , right
      end if
    
      if portc = &B00000000 then
        Richtung = links
        Maske = &B00000001
      end if
    
      if portc = &B11111111 then
        Richtung = rechts
        Maske = &B01111111
      end if
    Return
    Gruß
    Searcher
    Hoffentlich liegt das Ziel auch am Weg
    ..................................................................Der Weg zu einigen meiner Konstruktionen

  8. #8
    Neuer Benutzer Öfters hier
    Registriert seit
    16.08.2011
    Beiträge
    28
    .........................
    Geändert von User45322 (25.08.2017 um 21:19 Uhr)

  9. #9
    Erfahrener Benutzer Roboter Genie Avatar von Searcher
    Registriert seit
    07.06.2009
    Ort
    NRW
    Beiträge
    1.410
    Blog-Einträge
    101
    Hi,
    in der ISR werden die LEDs für das Lauflicht geschaltet. Bei jeden Aufruf durch den Timerinterrupt eine LED. Verantwortlich dafür ist die Maske, die durch das shift immer eine LED weiterschaltet.

    Sollte so funktionieren:
    Portc = 0 - alle LEDs aus
    Dann LEDs mit jedem Interrupt beginnend an portc.0 der Reihe nach an.
    Wenn alle eingeschaltet (portc ist gleich &B11111111) beginnend mit portc7 wieder aus.

    Wenn Lauflicht ausgeschaltet werden soll, kann man nach der Tastenabfrage in der Hauptschleife abhängig von der Taste zB "disable timer1" ausführen. Dann wird das Lauflicht nicht weitergeschaltet sondern bleibt auf dem gegenwärtigen Stand.

    Oder Flags benutzen. Oder ...

    Hab grad nicht genügend Zeit alles aufzuschreiben. Konkrete Fragen beantworte ich gern.

    PS: Ohne Gewähr, da nicht getestet. Prinzip sollte jedoch funktionieren.

    Gruß
    Searcher
    Hoffentlich liegt das Ziel auch am Weg
    ..................................................................Der Weg zu einigen meiner Konstruktionen

  10. #10
    Moderator Robotik Einstein Avatar von Kampi
    Registriert seit
    21.11.2009
    Ort
    Monheim, Nordrhein-Westfalen, Germany
    Alter
    28
    Beiträge
    3.517
    Blog-Einträge
    9
    So ich hab mal ein bischen an meinem RN-Control rumprobiert und ein Programm für dich geschrieben. Hier hast du eine Anregung wie du das machen kannst:
    Code:
    'Mikrocontrollereinstellungen
    $regfile = "m32def.dat"
    $framesize = 32
    $swstack = 32
    $hwstack = 32
    $crystal = 16000000                                         '16MHz Takt
    
    
    ' Ports konfigurieren
    Config Portc = Output                                       'Port C als Ausgang konfigurieren
    Config Pinb.0 = Input                                       'Pin B.0 als Eingang konfigurieren
    Portc = 0                                                   'Port C auf 0 setzen
    Pinb.0 = 1                                                  'Pull-up für Pin B.0 aktivieren
    
    Taster Alias Pinb.0                                         'Pinb.0 in Taster umbenennen
    
    
    'Timer 1 konfigurieren
    Config Timer1 = Timer , Prescale = 1024                     'Timer1 als Timer konfigurieren und Prescaler auf 1024 setzen
    Timer1 = 15625                                              'Timer mit 49910 vorladen um jede Sekunde einen Interrupt zu erzeugen
    On Timer1 Lauflicht                                         'Festlegen der Timer ISR "Lauflicht"
    Enable Timer1                                               'Timer aktivieren
    
    
    'Variablen
    Dim Lauflicht As Byte                                       'Bitmuster für das Lauflicht
    Dim Zaehler As Byte                                         'Zähler für das schieben der Bits
    
    
    'Interrupts aktivieren
    Enable Interrupts                                           'Global Interrupt Bit setzen
    
    
    'Variablen setzen
    Lauflicht = 1                                               'Das erste Bit im Bitmuster setzen
    Zaehler = 0                                                 'Zähler auf 0 setzen
    
    
    'Hauptprogramm
    Do
    
    If Taster = 0 Then                                          ' Wenn Pin B.0 auf 0 gezogen wird, wird das Global Interruptflag
    Disable Interrupts                                          'gelöscht und es kann kein Interrupt mehr erfolgen.Dadurch läuft
    Else                                                        'Lauflicht nicht weiter. Wird der Pin wieder auf 1 gelegt, wird das
    Enable Interrupts                                           'Bit wieder gesetzt und das Lauflicht läuft weiter
    End If
    
    Loop
    End
    
    
    
    
    'ISR zum weiterschalten der LEDs
    Lauflicht:
    
    Portc = Lauflicht                                           'Ausgabe des Bitmusters in der Variable "Lauflicht"
    Shift Lauflicht , Left                                      'Das Bitmuster in der Variable "Lauflicht" um eine Stelle
                                                                'nach Links schieben
    Zaehler = Zaehler + 1                                       'Zähler um eins erhöhen
    
    If Zaehler = 8 Then                                         'Zähler um 8 Durchläufe zu Zählen. Wenn der 8. Durchlauf
    Lauflicht = 1                                               'erfolgt ist wird das Bit im Bitmuster wieder auf die erste
    Zaehler = 0                                                 'Stelle gesetzt und der Zähler wird resetet
    End If
    
    Return
    Das ganze Lauflicht ist Interruptgesteuert d.h. du kannst tausend andere Sachen nebenbei machen und das Lauflicht wird trotzdem immernoch im selben Zeitabstand weitergeschaltet. Ob der Timer jetzt jede Sekunde ein Interrupt macht, weiß ich nicht....laut den Berechnungen aber schon nur das RN-Control braucht irgendwie bischen länger. Vielleicht hab ich mich auch verrechnet aber das kannst du eh anpassen.
    Das Lauflicht sieht dann so aus:

    Variable Lauflicht: 0000 0001
    Zähler = 0

    Timer Interrupt und anschließend ein Shift Links. Zähler + 1

    Variable Lauflicht: 0000 0010
    Zähler = 1

    Timer Interrupt und anschließend ein Shift Links. Zähler + 1

    Variable Lauflicht: 0000 0100
    Zähler = 2

    usw. bis hierhin

    Timer Interrupt und anschließend ein Shift Links. Zähler + 1

    Variable Lauflicht: 1000 0000
    Zähler = 8

    If-Abfrage ist erfüllt
    Variable Lauflicht: 0000 0001
    Zähler = 0

    und dann geht das alles wieder von vorne los.
    Mit dem Taster (den ich über eine Drahtbrücke nach GND realisiert habe) schaltest du einfach die Interrupts ab. Ist einfach und funktioniert. Nachteil an der Sache ist, dass der Timer noch weiterläuft. Das heißt wenn du die Interrupts wieder aktivierst, wartet der nicht erst 1 Sekunde bis er springt sondern er kann direkt springen oder etwas verzögert je nachdem wie der Timer dann steht. Wenn du es elegant machen willst schaltest du bei betätigen des Tasters den Timer ab und löscht das Zählregister von diesem. Falls du Fragen zum Programm hast frag oder nutz die Bascomhilfe
    Achja und noch eine Anmerkung......ich habd en Taster jetzt nicht entprellt, weil ich wie gesagt eine Drahtbrücke als Taster benutzt hab. Wenn du einen richtigen Taster benutzt solltest du diesen Entprellen, da er sonst Interrupts aktiviert und deaktiviert da der Taster prellt. In diesem Programm hat das kaum auswirkungen, weil der Timer eh nur alle paar Sekunden überläuft und es dann egal ist ob er noch 20 oder 30 Schritte weiter zählt.... .
    Solltest du dir aber merken. Taster immer entprellen!
    Ebenfalls wichtig. Ich hab das Programm auf der Grundlage meines RN-Controls geschrieben. Wenn du die LEDs oder den Taster anders anschließen willst musst du das im Programm natürlich berücksichtigen.
    Hier hast du den Schaltplan für das RN-Control um das Programm besser zu verstehen:

    Geändert von Kampi (19.08.2011 um 14:32 Uhr) Grund: Was vergessen!

Seite 1 von 2 12 LetzteLetzte

Ähnliche Themen

  1. Wird leere For-Schleife wegoptimiert?
    Von masasibe im Forum C - Programmierung (GCC u.a.)
    Antworten: 8
    Letzter Beitrag: 25.01.2011, 21:34
  2. If-Schleife wird nicht ausgeführt
    Von Knipser-14 im Forum C - Programmierung (GCC u.a.)
    Antworten: 11
    Letzter Beitrag: 08.10.2010, 13:26
  3. Antworten: 8
    Letzter Beitrag: 15.06.2009, 15:52
  4. Erstes Projekt: auf Tastendruck soll Motor starten
    Von RN-Controler im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 11
    Letzter Beitrag: 23.07.2007, 14:00
  5. Bascom erzeugt Reset beim starten...
    Von Majus im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 0
    Letzter Beitrag: 22.04.2007, 16:29

Stichworte

Berechtigungen

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