und mit And statt AND
Ich weiss nicht ob Bascom casesensitive ist?
und mit And statt AND
Ich weiss nicht ob Bascom casesensitive ist?
Manchmal frage ich mich, wieso meine Generation Geräte ohne Simulation entwickeln konnte?
Groß- und Kleinschreibung ist bei Bascom glaube ich ziemlich egal.
Was definitiv ein Problem zu sein scheint, sind die Klammern. Bascom meckert nämlich auch schon bei einer einfachen, unverschachtelten AND-Verknüpfung, wenn man sie in Klammern setzt. Da die Klammern ja aber aufgrund der Verschachtelung nötig wären, kann man das Problem lösen, indem man die beiden Verknüpfungen mit einem Hilfs-Bit nacheinander ausführen lässt:
Code:Dim Taste_old As Bit Dim Taste_new As Bit Dim X As Bit Dim Modus As Byte Do X = Taste_old Xor Taste_new X = X And Taste_new If X = 1 Then Incr Modus Loop
Dieser Code wird bei mir jedenfalls anstandslos kompiliert.
Und @ Bow-Hunter: Ganz einfach kann man einen Tastendruck erkennen, wenn man den Taster einen Interrupt auslösen lässt, indem der Taster einen Pegelwechsel am Interrupt-Eingangspin bewirkt. Dann braucht man die ganze "Merkerei" mit Taste_old und Taste_new nicht...
So Leute, das ist jetzt die Finale Version von mir. Jetzt funktioniert alles.
Bei Stromzufuhr ist alles aus.
Beim ersten und zweiten schalten blinkt es unterschiedlich.
Beim dritten schalten geht alles wieder aus.
So wollte ich das haben.
Jetzt ein paar Fragen zum Code.
Was bedeutet Dim - As Bit?
und Dim - As Integer?
und Xor?
Diese Begriffe sagen mir noch nichts.
Und wieso muss ich ca. ne halbe Sekunde den Taster drücken bis der Attiny13 reagiert?
Code:$regfile = "attiny13.dat" $crystal = 1200000 $hwstack = 10 $swstack = 10 $framesize = 10 Config Portb.1 = Output Config Portb.2 = Output Config Portb.3 = Output Config Portb.4 = Output Config Pinb.0 = Input Dim Modus As Integer Dim Anzahlmodi As Integer Dim Taste_old As Bit Dim Taste_new As Bit Dim X As Bit Modus = 1 Anzahlmodi = 3 Taste_new = 0 Do Taste_old = Taste_new Taste_new = Pinb.0 X = Taste_old Xor Taste_new X = X And Taste_new If X = 1 Then Incr Modus If Modus > Anzahlmodi Then Modus = 1 Select Case Modus Case 1 Gosub Lichteffekt1 Case 2 Gosub Lichteffekt2 Case 3 Gosub Lichteffekt3 End Select Loop End Lichteffekt1: Portb.1 = 0 Portb.2 = 0 Portb.3 = 0 Portb.4 = 0 Return Lichteffekt2: Portb.1 = 1 Portb.2 = 0 Portb.3 = 1 Portb.4 = 0 Waitms 100 Portb.3 = 0 Portb.4 = 1 Waitms 100 Portb.3 = 1 Portb.4 = 0 Waitms 100 Portb.1 = 0 Portb.2 = 1 Portb.3 = 0 Portb.4 = 1 Waitms 100 Portb.3 = 1 Portb.4 = 0 Waitms 100 Portb.3 = 0 Portb.4 = 1 Waitms 100 Return Lichteffekt3: Portb.1 = 1 Portb.2 = 1 Portb.3 = 1 Portb.4 = 1 Waitms 100 Portb.1 = 0 Portb.2 = 0 Portb.3 = 0 Portb.4 = 0 Waitms 100 Portb.1 = 1 Portb.2 = 1 Portb.3 = 1 Portb.4 = 1 Waitms 100 Portb.1 = 0 Portb.2 = 0 Portb.3 = 0 Portb.4 = 0 Waitms 100 Portb.1 = 1 Portb.2 = 1 Portb.3 = 1 Portb.4 = 1 Waitms 100 Portb.1 = 0 Portb.2 = 0 Portb.3 = 0 Portb.4 = 0 Waitms 100 Return
Hallo Bow-Hunter,
das was du in dem Code jetzt tust nennt sich "pollen" - das bedeutet so viel wie : du fragst den Taster im Hauptprogramm in einem Duchlauf der Hauptschleife ab. Der Grund, warum das jetzt ca 500ms oder etwas genauer sogar ca 600ms dauert, der sollte dir bewußt werden wenn du dir mal überlegst was passiert wenn du eine Unterroutione (gosub) anlegst und dann mit dem Tasterinput dort hin verzweigst? Zeit unempfindlicher wäre ein Interrupt der etwas weiter oben schon vorgeschlagen wurde. Ich empfehle einmal mit dem Cursor auf "Dim" zu gehen und dann F1 zu drücken -> Bascom Hilfe. Zusaätzlich verweise ich mal auf diese Seite (klick mich) - hier findest du unter anderem auch was informatives zum Interrupt.
Viele Grüße
Jörg
Okay, also das mit den 600ms hab ich wohl verstanden. Hätte ich eine Längere Schleife (Loop) so müsste ich halt immer das Ende von ihr abwarten. Bis die Taste Reagiert. Ich werd mich die Tage mal etwas genauer Informieren und versuch dann den Code mal umzubasteln, so das er sofort reagiert.
Danke für die schnellen Antworten.
Naja, fast - wichtig ist hier zu verstehen und auseinander zuhalten was wo passiert. Deine do-loop ist eine Schleife - Die Hauptschleife. Deine Unterroutinen, die du mit Gosub anwählst sind genau genommen nicht mehr Bestandteil diese Schleife. Der Zeitverlust entsteht in diesem Fall nicht in der Hauptschleife, sondern in der Unterroutine - allein zu sehen an den "6x waitms 100" - und natürlich fehlt der Interrupt. Diese Zeitverzögerung die du bemerkst ist also der Moment in dem sich Dein Programm in einer (langen) Unterroutine befindet. Damit hast du übrigens auch den schlechten Nebeneffekt vom pollen direkt bemerkt.
Manche Programme kann man durchaus damit laufen lassen, wenn es aber mal direkt gehen soll dann ist dieser Weg eher schlecht, weil man je nach dem wie lang eine Unterroutine ist dementsprechend warten - bzw den richtigen Moment der Tasterabfrage erwischen muss. Natürlich ist aber die Zeit die der µC benötigt um einmal die do-loop Schleife abzuarbeiten inklusiver der Unterroutinen die angewählt werden. Da kommt es dann eben noch drauf an was in ihnen passiert.
Beim "Case 1" passiert dir das übrigens auch, nur nicht so extrem auffällig weil keine waits drin sind und der Zeitverzug einfach für "uns" nicht direkt wahrnehmbar ist.
Viele Grüße
Jörg
Geändert von HeXPloreR (23.09.2014 um 21:39 Uhr)
Hallo Bow-Hunter,
ich habe mal versucht bisherige Vorschläge in einem ungetesteten Entwurf für direkte Reaktion auf Tastendruck und Vermeidung von WAITs unterzubringen. Das Debounce Kommando fragt die Taste ab und entprellt auch gleich.
Gruß
Searcher
Code:'### hwstack vergrößern. Wichtig bei Verwendung von Interrupts $hwstack = 34 '### Alle Variablen können als Byte deklariert werden (spart Speicher im kleinen Tiny13) '### Der Timer0 wird für die Blink- bzw. Schaltfrequenz konfiguriert Compare0a = 116 '99,84ms Interruptperiode bei 1,2MHz µC-Takt Config Timer0 = Timer , Prescale = 1024 , Clear_timer = 1 'Timer0 im Clear Timer on Comparematch On Compare0a Isr_blink 'ISR wird bei Compare Match A aufgerufen '### In der Haupschleife steht nur die Tastenabfrage inclusive Tastenentprellung Do 'Beginn Hauptschleife Debounce Pinb.0 , 1 , Changemodus , Sub 'Führt Unterprogramm aus, wenn Pinb.0 auf 1 wechselt Loop 'Ende Hauptschleife '### Nach Tastendruck wird dieses Unterprogramm ausgeführt, daß den Lichteffekt weiterschaltet und '### die nötigen Parameter für die Interruptserviceroutine setzt. Changemodus: 'Unterprogramm setzt Werte für Lichteffekt nach Tastendruck Disable Compare0a 'Vermeidet Inkonsistenzen in der ISR If Modus < Anzahlmodi Then Incr Modus Else Modus = 1 Select Case Modus Case 1 : Anzahlphasen = 0 'Muß Anzahl der Daten in den DATA-Zeilen entsprechen Case 2 : Anzahlphasen = 5 'Wert von 0 = ein Eintrag, 5 = sechs Einträge bei DATA Case 3 : Anzahlphasen = 1 '. End Select Phase = 0 Enable Compare0a Return '### In der Interruptserviceroutine wird alle 100ms das neue Schaltmuster für die LEDs gelesen und '### die LEDs geschaltet. Isr_blink: 'wird alle ca. 100ms aufgerufen und schaltet die LEDs If Phase < Anzahlphasen Then Incr Phase Else Phase = 0 'setzt die nächste Effektphase Select Case Modus 'entsprechend dem Modus wird das Bitmuster für LEDs geholt Case 1 : Pattern = Lookup(phase , Lichteffekt1) Case 2 : Pattern = Lookup(phase , Lichteffekt2) Case 3 : Pattern = Lookup(phase , Lichteffekt3) End Select Portb.1 = Pattern.3 'LED wird geschaltet Portb.2 = Pattern.2 'LED wird geschaltet Portb.3 = Pattern.1 'LED wird geschaltet Portb.4 = Pattern.0 'LED wird geschaltet Return End 'end program '### Hier sind die Schaltmuster abgelegt. Lichteffekt1: Data &B0000 Lichteffekt2: Data &B1010 , &B1001 , &B1010 , &B0101 , &B0110 , &B0101 Lichteffekt3: Data &B1111 , &B0000
Hoffentlich liegt das Ziel auch am Weg
..................................................................Der Weg zu einigen meiner Konstruktionen
Danke für den Code...
Code:$regfile = "attiny13.dat" $crystal = 1200000 $hwstack = 34 '### hwstack vergrößern. Wichtig bei Verwendung von Interrupts $swstack = 10 $framesize = 10 Config Portb.1 = Output Config Portb.2 = Output Config Portb.3 = Output Config Portb.4 = Output Config Pinb.0 = Input Dim Anzahlmodi As Integer Dim Modus As Byte Modus = 1 Anzahlmodi = 3 '### Alle Variablen können als Byte deklariert werden (spart Speicher im kleinen Tiny13) '### Der Timer0 wird für die Blink- bzw. Schaltfrequenz konfiguriert Compare0a = 116 '99,84ms Interruptperiode bei 1,2MHz µC-Takt Config Timer0 = Timer , Prescale = 1024 , Clear_timer = 1 'Timer0 im Clear Timer on Comparematch On Compare0a Isr_blink 'ISR wird bei Compare Match A aufgerufen '### In der Haupschleife steht nur die Tastenabfrage inclusive Tastenentprellung Do 'Beginn Hauptschleife Debounce Pinb.0 , 1 , Changemodus , Sub 'Führt Unterprogramm aus, wenn Pinb.0 auf 1 wechselt Loop 'Ende Hauptschleife '### Nach Tastendruck wird dieses Unterprogramm ausgeführt, daß den Lichteffekt weiterschaltet und '### die nötigen Parameter für die Interruptserviceroutine setzt. Changemodus: 'Unterprogramm setzt Werte für Lichteffekt nach Tastendruck Disable Compare0a 'Vermeidet Inkonsistenzen in der ISR If Modus < Anzahlmodi Then Incr Modus Else Modus = 1 Select Case Modus Case 1 : Anzahlphasen = 0 'Muß Anzahl der Daten in den DATA-Zeilen entsprechen Case 2 : Anzahlphasen = 5 'Wert von 0 = ein Eintrag, 5 = sechs Einträge bei DATA Case 3 : Anzahlphasen = 1 '. End Select Phase = 0 Enable Compare0a Return '### In der Interruptserviceroutine wird alle 100ms das neue Schaltmuster für die LEDs gelesen und '### die LEDs geschaltet. Isr_blink: 'wird alle ca. 100ms aufgerufen und schaltet die LEDs If Phase < Anzahlphasen Then Incr Phase Else Phase = 0 'setzt die nächste Effektphase Select Case Modus 'entsprechend dem Modus wird das Bitmuster für LEDs geholt Case 1 : Pattern = Lookup(phase , Lichteffekt1) Case 2 : Pattern = Lookup(phase , Lichteffekt2) Case 3 : Pattern = Lookup(phase , Lichteffekt3) End Select Portb.1 = Pattern.3 'LED wird geschaltet Portb.2 = Pattern.2 'LED wird geschaltet Portb.3 = Pattern.1 'LED wird geschaltet Portb.4 = Pattern.0 'LED wird geschaltet Return End 'end program '### Hier sind die Schaltmuster abgelegt. Lichteffekt1: Data &B0000 Lichteffekt2: Data &B1010 , &B1001 , &B1010 , &B0101 , &B0110 , &B0101 Lichteffekt3: Data &B1111 , &B0000
Hab ich da was falsch kopiert? Folgende Fehlermeldung kommt.
Und könntest du mir diesen Bereich etwas genauer erklären?Code:Compare0a = 116 '99,84ms Interruptperiode bei 1,2MHz µC-Takt Config Timer0 = Timer , Prescale = 1024 , Clear_timer = 1 'Timer0 im Clear Timer on Comparematch On Compare0a Isr_blink 'ISR wird bei Compare Match A aufgerufen
Gruß Glenn
Das könnte daran liegen, dass Du die Variablen Phase und Anzahlphase nicht dimensioniert hast.
Du kannst eine Variable zwar nennen wie Du willst - aber damit Bascom vernünftig mit den Variablen arbeiten kann muss es wissen, um was für einen Typ von Variable es sich handelt. Das ist die Geschichte mit "Dim XY as Bit (bzw. byte, Integer o.ä.).
Ein Bit ist die kleinste Einheit und kann nur die Werte 1 oder 0 annehmen. Ideal also, um einen Zustand wie "ein/aus" zu speichern.
Ein Byte sind 8 Bits und kann Werte zwischen 0 und 255 darstellen (keine negativen Zahlen!)
Ein Word sind zwei Bytes und kann Werte zwischen 0 und 65535 darstellen (ebenfalls nur positive Zahlen)
Ein Integer sind auch zwei Bytes, diese Variable kann aber Werte zwischen -32768 und +32767 annehmen.
Und dann gibts noch DWord, Single, Double, Long und String, aber die brauchst Du hier erstmal nicht. Wie Searcher ja schon in seinem Codevorschlag auskommentiert hat, kann man für Deine Anwendung alle Variablen als Byte dimensionieren, um Speicherplatz zu sparen.
Der langen Rede kurzer Sinn:
Wenn Du irgendwo in Deinem Programm Variablen einsetzt, musst Du sie vorher dimensioniert haben.
In Deinem Fall fehlen also irgendwo die Zeilen
Dim Phase as Byte
Dim Anzahlphase as Byte
Lesezeichen