Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen Revision Vorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
microcontrollertechnik:5_menuefuehrung [2022/09/20 11:36]
tfischer
microcontrollertechnik:5_menuefuehrung [2024/03/29 20:24] (aktuell)
mexleadmin
Zeile 1: Zeile 1:
-====== 5Menüführung ======+====== 5 Menüführung ======
  
 ==== Ziele ==== ==== Ziele ====
Zeile 19: Zeile 19:
   - Initialisieren des Programms    - Initialisieren des Programms 
     - Öffnen Sie SimulIDE und öffnen Sie dort mittels {{microcontrollertechnik:simulide_open.jpg?25}} die Datei ''5._menuefuehrung.sim1''      - Öffnen Sie SimulIDE und öffnen Sie dort mittels {{microcontrollertechnik:simulide_open.jpg?25}} die Datei ''5._menuefuehrung.sim1'' 
-    - Laden Sie ''5._menuefuehrung.hex'' als firmware auf den 328 Chip+    - Laden Sie ''5._menuefuehrung.hex'' als firmware auf den 88 Chip
     - Zunächst wird eine Startanzeige mit dem Namen des Programms dargestellt.     - Zunächst wird eine Startanzeige mit dem Namen des Programms dargestellt.
     - Als nächstes ist im Display ein Menu zu sehen, in dem verschiedene Programme P1 ... P4 durch Tastendruck auswählbar ist. Dadurch sind die bisherigen Programme auswählbar. Im Unterprogramm ermöglicht der Schalter S1 das Zurückspringen ins Menu.     - Als nächstes ist im Display ein Menu zu sehen, in dem verschiedene Programme P1 ... P4 durch Tastendruck auswählbar ist. Dadurch sind die bisherigen Programme auswählbar. Im Unterprogramm ermöglicht der Schalter S1 das Zurückspringen ins Menu.
Zeile 25: Zeile 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>
 /*============================================================================= /*=============================================================================
Zeile 31: Zeile 31:
 Experiment 5:   Programm-Menu Experiment 5:   Programm-Menu
 =============   ============= =============   =============
-   d e  +
 Dateiname:   Program_Menu.c Dateiname:   Program_Menu.c
      
Zeile 97: Zeile 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
Zeile 273: Zeile 273:
  sw4_alt = sw4_neu;    sw4_alt = sw4_neu;  
 } }
-   +
-  +
      
 // Initialisierung Display-Anzeige ============================================ // Initialisierung Display-Anzeige ============================================
Zeile 303: Zeile 302:
      
 }    // Ende der Funktion }    // Ende der Funktion
-   + 
-  +
      
 /* Teilprogramm 1: Blinkende LED ============================================== /* Teilprogramm 1: Blinkende LED ==============================================
Zeile 360: Zeile 358:
      
 }    // Ende der Funktion }    // Ende der Funktion
-   
-   
      
      
Zeile 686: Zeile 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. \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\
  
Zeile 716: Zeile 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
Zeile 728: Zeile 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. 
 \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\
  
Zeile 734: Zeile 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. \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\
Zeile 742: Zeile 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. 
 \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\
  
Zeile 750: Zeile 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. 
 \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\
  
Zeile 773: Zeile 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).