Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
microcontrollertechnik:5._menuefuehrung [2023/04/04 14:00] mexleadminmicrocontrollertechnik:5_menuefuehrung [2024/03/29 20:24] (current) mexleadmin
Line 1: Line 1:
-====== 5Menüführung ======+====== 5 Menüführung ======
  
 ==== Ziele ==== ==== Ziele ====
Line 25: Line 25:
  
 <-- <--
---> III. Eingabe in Atmel Studio #+--> III. Eingabe in Microchip Studio #
 <WRAP group><WRAP column 40%><sxh c; first-line: 1> <WRAP group><WRAP column 40%><sxh c; first-line: 1>
 /*============================================================================= /*=============================================================================
Line 97: Line 97:
 #define CLR_BIT(BYTE, BIT)  ((BYTE) &= ~(1 << (BIT))) // Bit Zustand in Byte loeschen #define CLR_BIT(BYTE, BIT)  ((BYTE) &= ~(1 << (BIT))) // Bit Zustand in Byte loeschen
 #define TGL_BIT(BYTE, BIT)  ((BYTE) ^=  (1 << (BIT))) // Bit Zustand in Byte wechseln (toggle) #define TGL_BIT(BYTE, BIT)  ((BYTE) ^=  (1 << (BIT))) // Bit Zustand in Byte wechseln (toggle)
-  +#define GET_BIT(BYTE, BIT)  ((BYTE) &   (1 << (BIT))) // Bit Zustand in Byte einlesen
      
 // Konstanten // Konstanten
Line 273: Line 273:
  sw4_alt = sw4_neu;    sw4_alt = sw4_neu;  
 } }
-   +
-  +
      
 // Initialisierung Display-Anzeige ============================================ // Initialisierung Display-Anzeige ============================================
Line 303: Line 302:
      
 }    // Ende der Funktion }    // Ende der Funktion
-   + 
-  +
      
 /* Teilprogramm 1: Blinkende LED ============================================== /* Teilprogramm 1: Blinkende LED ==============================================
Line 360: Line 358:
      
 }    // Ende der Funktion }    // Ende der Funktion
-   
-   
      
      
Line 686: Line 682:
  
   - Zunächst werden zwei Initialisierungsroutinen aufgerufen (siehe weiter unten)   - Zunächst werden zwei Initialisierungsroutinen aufgerufen (siehe weiter unten)
-  - Dann werden die "__T__imer/__C__ounter __C__ontrol __R__egister" des Timers __2__ ''TCCR2A'' und ''TCCR2B'' gesetzt. Der Timer 2 ist im wesentlichen mit dem Timer 0 aus dem [[4._up_down_counter|Up/Down Counter]] vergleichbar. Er ist ein 8-Bit Timer und auch hier wird der "Normal Mode" zum hochzählen genutzt. Auch hier gibt das Register ''TCCR2B'' den Prescaler an.+  - Dann werden die "__T__imer/__C__ounter __C__ontrol __R__egister" des Timers __2__ ''TCCR2A'' und ''TCCR2B'' gesetzt. Der Timer 2 ist im wesentlichen mit dem Timer 0 aus dem [[4_up_down_counter|Up/Down Counter]] vergleichbar. Er ist ein 8-Bit Timer und auch hier wird der "Normal Mode" zum hochzählen genutzt. Auch hier gibt das Register ''TCCR2B'' den Prescaler an.
   - Auch hier gibt es eine "__T__imer __I__nterrupt __M__a__SK__" ''TIMSK2''. Auch hier wird mit dem Bit ''TOIE2'' ("__T__imer __O__verflow __I__nterrupt __E__nable") der Interrupt bei Überlauf aktiviert.   - Auch hier gibt es eine "__T__imer __I__nterrupt __M__a__SK__" ''TIMSK2''. Auch hier wird mit dem Bit ''TOIE2'' ("__T__imer __O__verflow __I__nterrupt __E__nable") der Interrupt bei Überlauf aktiviert.
   - Mit dem Befehl ''sei()'' wird die Bearbeitung von Interrupts aktiv   - Mit dem Befehl ''sei()'' wird die Bearbeitung von Interrupts aktiv
-  - in der Endlosschleife ist nur eine switch-case Anweisung zu finden. Diese stellt den Auswahlteil einer Zustandsmaschine dar: \\ {{drawio>Zustandsmaschine}} \\ Aus jedem Unterprogramm wird wieder zurück ins Hauptmenü gesprungen.+  - in der Endlosschleife ist nur eine switch-case Anweisung zu finden. Diese stellt den Auswahlteil einer Zustandsmaschine dar: \\ {{drawio>Zustandsmaschine.svg}} \\ Aus jedem Unterprogramm wird wieder zurück ins Hauptmenü gesprungen.
   - Beim ''case 1...4'' wird zunächst das jeweilige Programm aufgerufen. Nachdem Rückkehr aus diesem Programm wird zunächst der ''modus'' wieder auf 0 zurückgesetzt, sodass beim nächsten Durchlauf der Schleife der ''case 0'' ausgeführt wird. Jeder case wird mit ''break'' beendet.    - Beim ''case 1...4'' wird zunächst das jeweilige Programm aufgerufen. Nachdem Rückkehr aus diesem Programm wird zunächst der ''modus'' wieder auf 0 zurückgesetzt, sodass beim nächsten Durchlauf der Schleife der ''case 0'' ausgeführt wird. Jeder case wird mit ''break'' beendet. 
  
 ''Interrupt Routine ========================='' ''Interrupt Routine =========================''
   - Mit dem Befehl ''ISR()'' wird eine Interrupt Service Routine für den  __OV__er__F__low Interrupt für __TIMER2__ angelegt.    - Mit dem Befehl ''ISR()'' wird eine Interrupt Service Routine für den  __OV__er__F__low Interrupt für __TIMER2__ angelegt. 
-  - Der Überlauf-Interrupt durch den Timer2 wird erst bei Überlauf des 8-Bit Wert ausgeführt. Auch hier ergibt sich durch den Prescaler und Modus (''TCCR2A'' und ''TCCR2B'') eine Periode von $T_{ISR}= 0,16\bar{6}ms$. +  - Der Überlauf-Interrupt durch den Timer2 wird erst bei Überlauf des 8-Bit Wert ausgeführt. Auch hier ergibt sich durch den Prescaler und Modus (''TCCR2A'' und ''TCCR2B'') eine Periode von $T_{\rm ISR}= 0,16\bar{6}~\rm ms$. 
-  - Die Ermittlung von ''Timertick'', ''vorteiler'', ''takt10ms'', ''hundertstel'' und ''takt100ms'' ist hier wieder gleich dem im [[4._up_down_counter|Up/Down Counter]]. +  - Die Ermittlung von ''Timertick'', ''vorteiler'', ''takt10ms'', ''hundertstel'' und ''takt100ms'' ist hier wieder gleich dem im [[4_up_down_counter|Up/Down Counter]]. 
   - Eine große Änderung ist, dass bereits im Interrupt alle 10ms die Unterfunktion ''readButton()'' aufgerufen wird.  \\ \\ \\ \\ \\ \\ \\ \\ \\ \\  \\ \\ \\ \\ \\ \\   - Eine große Änderung ist, dass bereits im Interrupt alle 10ms die Unterfunktion ''readButton()'' aufgerufen wird.  \\ \\ \\ \\ \\ \\ \\ \\ \\ \\  \\ \\ \\ \\ \\ \\
 '' Funktion Tasten einlesen =============='' '' Funktion Tasten einlesen ==============''
 \\ \\ \\ \\ \\ \\
-  - In dieser Funktion werden zunächst die Stellungen aller Taster eingelesen (vgl. ''counterCounting(void)'' bei [[4._up_down_counter|Up/down Counter]]). \\ \\ \\+  - In dieser Funktion werden zunächst die Stellungen aller Taster eingelesen (vgl. ''counterCounting(void)'' bei [[4_up_down_counter|Up/down Counter]]). \\ \\ \\
   - Neu hier ist, dass über ''if ( (sw1_neu==0) & (sw1_alt==1) )'' die positive Flanke (=aufsteigende Flanke) erkannt wird und dies im Flag ''sw1_slope'' gespeichert wird. \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\   - Neu hier ist, dass über ''if ( (sw1_neu==0) & (sw1_alt==1) )'' die positive Flanke (=aufsteigende Flanke) erkannt wird und dies im Flag ''sw1_slope'' gespeichert wird. \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\
  
Line 716: Line 712:
 ''/* Teilprogramm 1: Blinkende LED ====='' ''/* Teilprogramm 1: Blinkende LED =====''
  
-Hier ist das Programm der [[1._hello_blinking_world|Blinking LED]] etwas angepasst eingefügt. +Hier ist das Programm der [[1_hello_blinking_world|Blinking LED]] etwas angepasst eingefügt. 
 \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\  \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ 
   - Zunächst wird ein Unterprogramm zur Anzeige das Displays aufgerufen   - Zunächst wird ein Unterprogramm zur Anzeige das Displays aufgerufen
Line 728: Line 724:
 ''/* Teilprogramm 2: Soundgenerierung ===='' ''/* Teilprogramm 2: Soundgenerierung ====''
  
-Hier ist das Programm [[2._sound_und_timer|Sound und Timer]] etwas angepasst eingefügt. +Hier ist das Programm [[2_sound_und_timer|Sound und Timer]] etwas angepasst eingefügt. 
 \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\
  
Line 734: Line 730:
   - Hier wird Timer 0 genutzt, um das gepulste Signal an den Lautsprecher zu verändern.   - Hier wird Timer 0 genutzt, um das gepulste Signal an den Lautsprecher zu verändern.
   - Die while-Schleife wird wieder abgebrochen, wenn die Taste 1 gedrückt wurde.   - Die while-Schleife wird wieder abgebrochen, wenn die Taste 1 gedrückt wurde.
-  - Neben dem Herunterzählen der Periodenlänge (über ''OCR0A--''), wird auch der Periodenzähler ausgegeben. Die Ausgabe ähnelt ''counterDisplay'' aus dem Programm [[4._up_down_counter|Up/Down Counter]].+  - Neben dem Herunterzählen der Periodenlänge (über ''OCR0A--''), wird auch der Periodenzähler ausgegeben. Die Ausgabe ähnelt ''counterDisplay'' aus dem Programm [[4_up_down_counter|Up/Down Counter]].
   - Da die for-Schleife zum Herunterzählen der Periodenlänge sehr lange dauert (etwa 2 Sekunden) wird auch darin der Tastendruck der Taste 1 abgefragt werden. \\ \\ \\ \\ \\    - Da die for-Schleife zum Herunterzählen der Periodenlänge sehr lange dauert (etwa 2 Sekunden) wird auch darin der Tastendruck der Taste 1 abgefragt werden. \\ \\ \\ \\ \\ 
   - Falls die Taste 1 gedrückt wurde, wird sowohl __in der for__-Schleife, als auch __nach der while__-Schleife der Timer gestoppt und die Flanken zurückgesetzt. \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\   - Falls die Taste 1 gedrückt wurde, wird sowohl __in der for__-Schleife, als auch __nach der while__-Schleife der Timer gestoppt und die Flanken zurückgesetzt. \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\
Line 742: Line 738:
 ''/* Teilprogramm 3: Logische Funktionen ===='' ''/* Teilprogramm 3: Logische Funktionen ====''
  
-Hier ist das Programm [[3._logische_funktionen|Logische Funktionen]] etwas angepasst eingefügt. +Hier ist das Programm [[3_logische_funktionen|Logische Funktionen]] etwas angepasst eingefügt. 
 \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\
  
Line 750: Line 746:
 ''/* Teilprogramm 4: Up-Down-Counter ===='' ''/* Teilprogramm 4: Up-Down-Counter ====''
  
-Hier ist das Programm [[4._up_down_counter|Up/Down Counter]] etwas angepasst eingefügt. +Hier ist das Programm [[4_up_down_counter|Up/Down Counter]] etwas angepasst eingefügt. 
 \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\
  
Line 773: Line 769:
  
 --> Aufgaben# --> Aufgaben#
 +
 +Vielleicht haben Sie es schon bemerkt: gelegentlich scheint das Display für einen kurzen Augenblick einzelne falsche Zeichen anzuzeigen. 
 +Der Grund dafür ist, dass das Auslesen der Taster und die Datenübertragung an das Display über die gleichen Pins stattfindet und nicht synchronisiert ist.
 +Um dies zu beheben ist eine Verbesserung des Programms notwendig.
 +
 Speicherauslastung und Programmoptimierung:  Speicherauslastung und Programmoptimierung: 
     - Merken Sie sich die Speicherauslastung des bisherigen Programms. Diese finden Sie z.B. über den Solution Explorer: ''Output Files'' >> ''5_Program_Menu.elf'' >> rechte Maustaste (Kontextmenu) >> ''Properties'' >> ''Flash size'' und ''RAM size'' (in Bytes).     - Merken Sie sich die Speicherauslastung des bisherigen Programms. Diese finden Sie z.B. über den Solution Explorer: ''Output Files'' >> ''5_Program_Menu.elf'' >> rechte Maustaste (Kontextmenu) >> ''Properties'' >> ''Flash size'' und ''RAM size'' (in Bytes).