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:vorgaben_fuer_die_softwareentwicklung [2019/06/21 00:20]
tfischer [Modulblockbild/Blockschaltbild]
microcontrollertechnik:vorgaben_fuer_die_softwareentwicklung [2024/01/22 13:50] (aktuell)
mexleadmin
Zeile 1: Zeile 1:
-===== Allgemeine Tipps ===== +====== Vorgaben für die Softwareentwicklung ======
- +
-  * Wenn Sie erst eine Woche vor der Abgabe mit dem Programmieren beginnen, wird es in der Regel eng. Besonders, wenn es Unklarheiten und Nachfragen gibt. +
-  * Versuchen Sie Spaß am Programmieren zu finden. Es ist wie Puzzeln, nur dass Sie selbst das Bild bestimmen! +
- +
-===== Dokumentation ===== +
- +
-==== Lastenheft ==== +
- +
-In realen Projekten würden Sie zunächst ein Lastenheft erhalten, dass Sie in ein Pflichtenheft, Systembeschreibung, Hardware- und Software-Systembeschreibung herunterbrechen, wobei parallel dazu die Systemtests und Hardware-/Softwaresystemtests beschrieben werden. +
- +
-Dieses Vorgehen ist für die Arbeiten in EST zu umfänglich und wird wie folgt reduziert. Die Angaben auf der Wikiseite Ihres Projekts, sowie die während der Projektgespräche dienen als Lastenheft. Daraus ist ein Pflichtenheft zu erstellen, welches die Projektziele in obligatorische ("Muss"), gewünschte ("Soll") und fakultative ("Kann") Aufgaben untergliedert. Zusätzlich ist es auch möglich Projektziele explizit auszuschließen ("Nicht benötigt"). +
- +
-Um das Pflichtenheft gut zu strukturieren, bietet sich folgende Vorlage an: +
-++++Wiki-Format| +
-<code> +
-h1. Pflichtenheft +
- +
-|_. Nr |_. Projektziel |_. Beschreibung |_. Status|_. Priorität| +
-| 1 | 1. Teilaspekt des Zielzustands | Hier sollte eine kurze Beschreibung stehen | offen | Muss | +
-| 2 | 2. Teilaspekt des Zielzustands | Falls notwendig, kann auch auf eine Fußnote 1) referenziert werden | in Bearbeitung | Soll | +
-| 3 | weiterer Teilaspekt des Zielzustands | ... | erledigt | Kann | +
-| 4 | -noch ein Teilaspekt des Zielzustands- | ... | nicht mehr relevant | ausgenommen | +
- +
---- +
-1) Diese Fußnote dient nur dem Beispiel. +
-</code> +
-++++ +
-(Alternativ finden Sie eine Vorlage für das Pflichtenheft in Excel hier: {{:opl_ph.xlsx|opl_ph.xlsx}}) +
-  +
- +
-==== Offene Punkte Liste ==== +
- +
-Als weitere Aufgabe sollen Sie eine Offene-Punkte-Liste (OPL) anlegen und führen. Darin sollten wichtige Informationen und Aufgaben (z.B. aus Projektgesprächen) zusammengefasst sein. Ziel ist dabei nicht zwangsläufig, dass am Ende Ihres Projekts alle Punkte abgearbeitet sind. Die OPL kann auch Punkte enthalten, welche zukünftig noch bearbeitet werden müssen oder Ideen, welche noch umgesetzt werden könnten. Sie soll auch dazu dienen, dass andere - wie z.B. Ihre Nachfolger - Ihre Entscheidungen verstehen können. +
- +
-Die Offene Punkte Liste sollte bevorzugt über das Ticketsystem von Redmine geführt werden. +
- +
-==== Modulblockbild/Blockschaltbild ==== +
- +
-Für die Software ist ein Modulblockbild/Blockschaltbild beizufügen. Dies soll die Unterfunktionen und ihre gerichteten Schnittstellen zueinander (z.B. globale Variablen, Parameter) darstellen.  +
- +
-Ich würde Sie bitten aus Gründen der Wiederverwendbarkeit dafür <del>die Homepage [[https://www.draw.io/|draw.io]] zu nutzen</del> die Vorlage in Ihrem Projekt im Wiki nutzen ([[https://wiki.mexle.hs-heilbronn.de/doku.php?id=mexle:start|hier]]). <del>Eine geeignete Vorlage finden Sie in den ILIAS Kursen [[https://ilias.hs-heilbronn.de/goto.php?target=file_74476_download&client_id=iliashhn|(134142) Labor Elektronik]] bzw. [[https://ilias.hs-heilbronn.de/goto.php?target=file_74478_download&client_id=iliashhn|(134274) Elektronische Systeme]].</del>+
  
 ===== Codierung und Programmierung ===== ===== Codierung und Programmierung =====
Zeile 47: Zeile 6:
  
   * Es empfiehlt sich für alle definierten und deklarierten Namen die Englische Sprache zu verwenden. Für Variablen, Funktionen und Kommentare darf die Deutsche Sprache genutzt werden.   * Es empfiehlt sich für alle definierten und deklarierten Namen die Englische Sprache zu verwenden. Für Variablen, Funktionen und Kommentare darf die Deutsche Sprache genutzt werden.
-  * Eine detailliertere Liste ist im [[https://www.ipa.go.jp/files/000040508.pdf|Embedded System development Coding Reference guide]] zu finden.+  * Eine detailliertere Liste ist im [[https://www.ipa.go.jp/files/000040508.pdf|Embedded System development Coding Reference Guide]] zu finden
 +  * Neben der Struktur beim Programmieren zählt auch eine interessante und schöne Umsetzung für den Nutzer in die Bewertung
  
 ==== Kommentare ==== ==== Kommentare ====
Zeile 59: Zeile 19:
 ++++Beschreibung| ++++Beschreibung|
  
-<code c>+<sxh c; first-line: 1>
 /* ============================================================================ /* ============================================================================
  
Zeile 65: Zeile 25:
 =============    ========================================================= =============    =========================================================
  
-Dateiname:       MiniMEXLE_MeinProgramm.c+Dateiname:       MEXLE_MeinProgramm.c
  
 Autoren:         Max Integer (Hochschule Heilbronn) Autoren:         Max Integer (Hochschule Heilbronn)
Zeile 71: Zeile 31:
 Version:         0.5 vom 29.02.2019 Version:         0.5 vom 29.02.2019
  
-Hardware:        MiniMEXLE Ver. 3.0 (oder angepasste Version 2.0)+Hardware:        z.B. MiniMEXLE Ver. 3.0 (oder angepasste Version 2.0) oder MEXLE2020
                  AVR-USB-PROGI Ver. 2.0                  AVR-USB-PROGI Ver. 2.0
  
-Software:        Atmel Studio Ver. 7.0.1417+Software:        Microchip Studio Ver. 7.0.1417
  
 Funktion:        Diese Programm sol eine einfaches Beispiel der Ein- und Ausgabe am MiniMEXLE sein. Funktion:        Diese Programm sol eine einfaches Beispiel der Ein- und Ausgabe am MiniMEXLE sein.
Zeile 81: Zeile 41:
 Displayanzeige:        Start (fuer 2s):        Betrieb: Displayanzeige:        Start (fuer 2s):        Betrieb:
                      +----------------+        +----------------+                      +----------------+        +----------------+
-| Mein Programm   |Counter 0       | +                     | Mein Programm        |Counter 0       | 
-|   Zaehler      |   | Up Down        |+                     |   Zaehler      |        | Up Down        |
                      +----------------+        +----------------+                      +----------------+        +----------------+
  
Zeile 94: Zeile 54:
 Header-Files:     lcd_lib_de.h    (Library zur Ansteuerung LCD-Display Ver. 1.2) Header-Files:     lcd_lib_de.h    (Library zur Ansteuerung LCD-Display Ver. 1.2)
  
-Module:           1) Schalter einlesen +Module:           1) get_switch_state: Schalter einlesen 
-                  2) Werte ausgeben+                  2) set_display_values: Werte ausgeben
  
-    Modul 1:    ... +    1) get_switch_state:    ... 
-    Modul 2:    ...+    3) set_display_values:    ...
  
 =============================================================================*/ =============================================================================*/
-</code>+</sxh>
  
 ++++ ++++
Zeile 108: Zeile 68:
 ++++Beispiel für Code-Kommentierung| ++++Beispiel für Code-Kommentierung|
  
-|<fc #800000>**SCHLECHT**</fc>| <code c>+|<fc #800000>**SCHLECHT**</fc>| <sxh c; first-line: 1>
 if(i==0) output=0; // wenn i = 1, output=0 if(i==0) output=0; // wenn i = 1, output=0
-</code      +</sxh     
-|<fc #008000>**GUT**</fc>| <code c>+|<fc #008000>**GUT**</fc>| <sxh c; first-line: 1>
 if(i==0) output=0; // nur für erstes Element wird der Output zurückgesetzt if(i==0) output=0; // nur für erstes Element wird der Output zurückgesetzt
-</code      |+</sxh     |
  
 ++++ ++++
Zeile 121: Zeile 81:
 ++++Beispiel für auskommentierten Code| ++++Beispiel für auskommentierten Code|
  
-|<fc #800000>**SCHLECHT**</fc>| <code c>+|<fc #800000>**SCHLECHT**</fc>| <sxh c; first-line: 1>
 ... ...
     if (i==1) output("eins");    // ToBeChanged: noch an Zähler anpassen     if (i==1) output("eins");    // ToBeChanged: noch an Zähler anpassen
Zeile 130: Zeile 90:
 ... ...
  
-</code      +</sxh     
-|<fc #008000>**GUT**</fc>| <code c>+|<fc #008000>**GUT**</fc>| <sxh c; first-line: 1>
 ... ...
     if (i==STARTWERT) LCDoutput(startAusgabe);   // nur bei i=1 erfolgt eine Ausgabe     if (i==STARTWERT) LCDoutput(startAusgabe);   // nur bei i=1 erfolgt eine Ausgabe
Zeile 137: Zeile 97:
                         // Ausgabe, weil i <=1                         // Ausgabe, weil i <=1
 ... ...
-</code      |+</sxh     |
  
 ++++ ++++
Zeile 147: Zeile 107:
 ++++Beispiel für die vordefinierten Makros| ++++Beispiel für die vordefinierten Makros|
  
-|<fc #800000>**SCHLECHT**</fc>| <code c>+|<fc #800000>**SCHLECHT**</fc>| <sxh c; first-line: 1>
 #define    TWICE(x)    2*x // Port-Bit Setzen #define    TWICE(x)    2*x // Port-Bit Setzen
  
Zeile 161: Zeile 121:
     ...     ...
 } }
-</code      +</sxh     
-|<fc #008000>**GUT**</fc>| <code c>+|<fc #008000>**GUT**</fc>| <sxh c; first-line: 1>
 // Makros // Makros
  
Zeile 177: Zeile 137:
     ...     ...
 } }
-</code      |+</sxh     |
  
 ++++ ++++
Zeile 183: Zeile 143:
 ==== Konstanten ==== ==== Konstanten ====
  
-  * Konstanten per #define sollten z.B. für die feste Größe von Arrays verwendet werden. Sie können (bzw. werden) auch für hardwarenahe Werte, wie Portnummern, genutzt werden. +  * Konstanten per ''#define'' sollten z.B. für die feste Größe von Arrays verwendet werden. Sie können (bzw. werden) auch für hardwarenahe Werte, wie Portnummern, genutzt werden. 
-  * Für andere Konstanten empfiehlt es sich const Variablen zu nutzen. Dadurch werden auch die Typisierung überwacht+  * Auch Werte in ''enum'' sind Konstanten. Für Konstanten mit ähnlichem Hintergrund (z.B. Tage, s.u.) sollten ''enum'' genutzt werden. Damit können Variablen auch als ''enum''-Typ definiert werden, was den Code leserlicher macht. 
-  * Konstanten per #define werden komplett in Großbuchstaben geschrieben.+  * Bei Defines wird keine Typisierung überwacht. Ist dies notwendig empfiehlt es sich ''const'' Variablen zu nutzen.  
 +  * Konstanten per ''#define'' oder ''enum'' sind komplett in **Großbuchstaben** zu schreiben, um diese von Variablen zu unterscheiden.
   * Falls Sie aus mehreren Wörtern zusammengefügt sind, sollten Sie **mit Unterstrich**  getrennt werden.   * Falls Sie aus mehreren Wörtern zusammengefügt sind, sollten Sie **mit Unterstrich**  getrennt werden.
 +<sxh c; first-line: 1>
 +enum tage {MONTAG, DIENSTAG, MITTWOCH, DONNERSTAG, FREITAG, SAMSTAG, SONNTAG}; 
 +
 +for (enum tage aktuellerTag = MONTAG; aktuellerTag <= SONNTAG; aktuellerTag++)
 +{...};</sxh>
  
 ++++Beispiel für Konstanten| ++++Beispiel für Konstanten|
  
-|<fc #800000>**SCHLECHT**</fc>| <code c>+{{tablelayout?tableSort=1&tableSearch=1}} 
 +|<fc #800000>**SCHLECHT**</fc>| <sxh c; first-line: 1>
 // Konstanten // Konstanten
  
 #define    CONST1       1.414     // Korrekturwert #define    CONST1       1.414     // Korrekturwert
 #define    PORT1        4         // Erster Port #define    PORT1        4         // Erster Port
 +#define    gameIntro    0         // Spiel Zustand: aktuell wird das Intro gezeigt
 +#define    gameStarted  1         // Spiel Zustand: aktuell ist das Spiel gestartet
 +#define    gamePaused           // Spiel Zustand: aktuell ist das Spiel pausiert
 +#define    gameEnded    3         // Spiel Zustand: aktuell ist das Spiel zu Ende. Highscore etc wird angezeigt
  
 ... ...
Zeile 202: Zeile 173:
 ... ...
  
-</code      +</sxh     
-|<fc #008000>**GUT**</fc>| <code c>+|<fc #008000>**GUT**</fc>| <sxh c; first-line: 1>
 // Konstanten // Konstanten
  
Zeile 211: Zeile 182:
 #define YMAX_LCD     16     // Anzahl der Spalten #define YMAX_LCD     16     // Anzahl der Spalten
  
 +enum gameStates{
 +    GAMESTATE_INTRO, 
 +    GAMESTATE_STARTED, 
 +    GAMESTATE_PAUSED, 
 +    GAMESTATE_ENDED}; 
 +   
 ... ...
  
Zeile 217: Zeile 194:
 ... ...
  
-</code      |+</sxh     |
  
 ++++ ++++
Zeile 227: Zeile 204:
   * Variablen beginnen mit Kleinbuchstaben.   * Variablen beginnen mit Kleinbuchstaben.
   * Falls Sie aus mehreren Wörtern zusammengefügt sind, so werden die folgenden Wörter **ohne Unterstrich**  direkt angefügt, aber groß geschrieben. Dies wird auch als "BinnenMajuskel" oder "camelCase" bezeichnet.   * Falls Sie aus mehreren Wörtern zusammengefügt sind, so werden die folgenden Wörter **ohne Unterstrich**  direkt angefügt, aber groß geschrieben. Dies wird auch als "BinnenMajuskel" oder "camelCase" bezeichnet.
-  * Vermeiden Sie zu allgemeine Namen, wie anzahl, uebergabewert oder string. Sinnvoller sind Namen, wie anzahlBuchstaben, stunden, ausgabeString. Durch die Autovervollständigung (Vorschläge unter dem eingegebenen Text) sind auch längere Namen schnell einzugeben, bzw mit Cursortasten und TAB auswählbar.+  * Vermeiden Sie zu allgemeine Namen, wie anzahl, uebergabewert oder string. Sinnvoller sind Namen, wie ''anzahlBuchstaben''''stunden''''ausgabeString''. Durch die Autovervollständigung (Vorschläge unter dem eingegebenen Text) sind auch längere Namen schnell einzugeben, bzwmit Cursortasten und TAB auswählbar.
   * Nutzen sie auch bei Zählvariablen aussagekräftige Namen.   * Nutzen sie auch bei Zählvariablen aussagekräftige Namen.
-  * Auch kann eine zu allgemeine Deklaration kann zu Problemen führen. Schlecht ist z.B. "int a;"+  * Auch kann eine zu allgemeine Deklaration kann zu Problemen führen. Schlecht ist z.B. ''int a;''
-  * Es bietet sich an bei der Definition bereits zu initialisieren. Gut ist also "bool a=1;".+  * Es bietet sich an bei der Definition bereits zu initialisieren. Gut ist also ''bool a=1;''.
 ++++Beispiel für Variablen| ++++Beispiel für Variablen|
  
-|<fc #800000>**SCHLECHT**</fc>| <code c>+|<fc #800000>**SCHLECHT**</fc>| <sxh c; first-line: 1>
 // Variablen // Variablen
  
Zeile 244: Zeile 221:
 char    wasKopie2;         // unklar,Was was ist char    wasKopie2;         // unklar,Was was ist
  
-</code      +</sxh     
-|<fc #008000>**GUT**</fc>| <code c>+|<fc #008000>**GUT**</fc>| <sxh c; first-line: 1>
 // Variablen // Variablen
  
 const int       maxAnzSpieler   = 2;    // Maximale Anzahl der Spieler const int       maxAnzSpieler   = 2;    // Maximale Anzahl der Spieler
 uint8_t         gemesseneLaenge = 0;    // gemessene Länge in Meter uint8_t         gemesseneLaenge = 0;    // gemessene Länge in Meter
-unsigned char   gemesseneBreite;        // gemessene Breite in Meter+unsigned char   gemesseneBreite = 0   // gemessene Breite in Meter
 bool            zeichenAusgabe  = 1;    // Wahrheitswert zur Anzeige, ob bool            zeichenAusgabe  = 1;    // Wahrheitswert zur Anzeige, ob
                                         // ein Zeichen ausgegeben werden darf                                         // ein Zeichen ausgegeben werden darf
-</code      |+</sxh     |
  
 ++++ ++++
Zeile 260: Zeile 237:
  
   * Teilen Sie Ihr Projekt in sinnvolle Unterstrukturen. Diese sind meist Funktionen. Die Unterstrukturen sollten nicht zu groß werden, um die Übersichtlichkeit zu bewahren.   * Teilen Sie Ihr Projekt in sinnvolle Unterstrukturen. Diese sind meist Funktionen. Die Unterstrukturen sollten nicht zu groß werden, um die Übersichtlichkeit zu bewahren.
-  * Bei größeren Programmen ist auch die Aufteilung in mehrere Dateien sinnvoll, also z.b. main.c, LED.c, motorDriver.c. Dabei sollte darauf geachtet werden, dass globalen Variablen und Konstanten jeweils nur im Kontext der einzelnen Dateien genutzt werden und, dass header-Dateien angelegt werden. Das ermöglicht ein separates Testen der unterschiedlichen Dateien (z.B. mit einer Datei testLED.c, welche LED.h inlcude't). +  * Bei größeren Programmen ist auch die Aufteilung in mehrere Dateien sinnvoll, also z.b. ''main.c''''LED.c''''motorDriver.c''. Dabei sollte darauf geachtet werden, dass globalen Variablen und Konstanten jeweils nur im Kontext der einzelnen Dateien genutzt werden und, dass header-Dateien angelegt werden. Das ermöglicht ein separates Testen der unterschiedlichen Dateien (z.B. mit einer Datei testLED.c, welche LED.h include't). 
-  * Nutzen Sie den Zeileneinschub den AtmelStudio automatisch anbietet.+  * Nutzen Sie den Zeileneinschub den Microchip Studio automatisch anbietet. 
 +  * Für die Benennung von Funktionen bietet sich - wie bei Variablen - camelCase an. Zum leichteren Verständnis sollten die Funktionsnamen aus Objekt(e) und Verb zusammengesetzt werden (z.B. ''bool isI2cMessageNotSent()'' oder void ''sentI2cMessage()''). \\ Damit wird der Code besser lesbar, Z.B. ''if (isI2cMessageNotSent()) sentI2cMessage()''
   * Vermeiden Sie zu viele Leerzeilen.   * Vermeiden Sie zu viele Leerzeilen.
-  * Für die Benennung von Funktionen bietet sich - wie bei Variablen - camelCase an. Zum leichteren Verständnis sollten die Funktionsnamen aus Objekt(e) und ggf. Verb zusammengesetzt werden (z.B. bool istGesendet() oder void I2CBotschaftSenden()). 
   * Stellen Sie auch jeder Funktion eine kurze Beschreibung voran. Aus dieser sollte hervorgehen, was Sinn und Zweck der Funktion ist.   * Stellen Sie auch jeder Funktion eine kurze Beschreibung voran. Aus dieser sollte hervorgehen, was Sinn und Zweck der Funktion ist.
 ++++Beispiel für Anweisungsblöcke| ++++Beispiel für Anweisungsblöcke|
  
-|<fc #800000>**SCHLECHT**</fc>| <code c>+|<fc #800000>**SCHLECHT**</fc>| <sxh c; first-line: 1>
 uint8_t unter2_neu(uint8_t Was) uint8_t unter2_neu(uint8_t Was)
 { {
Zeile 283: Zeile 260:
 return 0; return 0;
 } }
-</code      +</sxh     
-|<fc #008000>**GUT**</fc>| <code c>+|<fc #008000>**GUT**</fc>| <sxh c; first-line: 1>
 uint8_t schluesselPositionFinden(uint8_t schluessel) uint8_t schluesselPositionFinden(uint8_t schluessel)
 /*    Das Array schluesselArray wird nach dem übergebenen Schlüssel durchsucht. /*    Das Array schluesselArray wird nach dem übergebenen Schlüssel durchsucht.
Zeile 291: Zeile 268:
 */ */
 { {
-    int a; +    for( int aktuelleSchluesselPosition=ERSTE_SCHLUESSEL_POSITION; a<=LETZTE_SCHLUESSEL_POSITIONaktuelleSchluesselPosition++)
-    for( a=ersteSchluesselPosition ; a<=letzteSchluesselPosition a++)+
     {                        // durchlaufe alle Schlüsselpositionen     {                        // durchlaufe alle Schlüsselpositionen
-        if(schluesselArray[a]==schluessel) return a;+        if(schluesselArray[aktuelleSchluesselPosition]==schluessel) return aktuelleSchluesselPosition;
                             // falls Schlüssel gefunden,                             // falls Schlüssel gefunden,
     };                        // gib die erste Position zurück     };                        // gib die erste Position zurück
     return 0;     return 0;
 } }
-</code      In diesem Beispiel wäre der Funktionsname schluesselPosition statt schluesselPositionFinden auch geeignet gewesen.    |+</sxh     In diesem Beispiel wäre der Funktionsname ''SchluesselPosition'' statt ''schluesselPositionFinden'' auch geeignet gewesen.  \\ Weiterhin bietet es sich an hier auch einen Zeiger auf das Array und die Werte für erste und letzte Position als Parameter der Funktion zu übergeben, um diese flexibler anwenden zu können. 
 + 
 +++++ 
 + 
 +==== Arrays, Schleifen und Abfragen ==== 
 +  * Es ist sinnvoll Deklaration und Definition der Schleifenvariable direkt in den if-Befehl zu packen. Also: ''for(uint8_t i=0; i<MAX; i=i+1)'' . Damit wird der Code etwas kompakter. 
 +  * Vermeiden Sie Zugriffe auf Bereiche von Arrays, welche nicht definiert wurden. So erhält man bei einem Array ''uint8_t array[10];'' mit Zugriff auf ''array[-1]'', ''array[10]'' oder ''array[21]'' keine Werte des eigentlichen Array, sondern Werte von anderen Variablen. Ein Beschreiben dieser Bereich kann zu unerwarteten Werten in anderen Variablen führen.  
 + 
 +++++Beispiel für Arrays, Schleifen und Abfragen| 
 + 
 +|<fc #800000>**SCHLECHT**</fc>| <sxh c; first-line: 1> 
 +#define MAX 10 
 + 
 +uint8_t array[MAX]; 
 + 
 +... 
 +    for(unit8_t a = 0 ; a<=MAX ; a++) 
 +    {                        // durchlaufe alle Schlüsselpositionen 
 +        array[a*2] = array[a*2-1]; 
 +    };                        
 + 
 +</sxh>      | 
 +|<fc #008000>**GUT**</fc>| <sxh c; first-line: 1> 
 +#define MAX 10 
 + 
 +uint8_t array[MAX]; 
 + 
 +... 
 +    for(unit8_t a = 1 ; a<=MAX/2 ; a++) 
 +    {                        // durchlaufe alle notwendigen Schlüsselpositionen 
 +        array[a*2] = array[a*2-1]; 
 +    };                        
 + 
 +</sxh>   |
  
 ++++ ++++
Zeile 310: Zeile 319:
 ++++Beispiel für ähnliche Zeilen| ++++Beispiel für ähnliche Zeilen|
  
-|<fc #800000>**SCHLECHT**</fc>| <code c>+|<fc #800000>**SCHLECHT**</fc>| <sxh c; first-line: 1>
 ... ...
     temp = hunderter;     temp = hunderter;
Zeile 325: Zeile 334:
 ... ...
  
-</code      +</sxh     
-|<fc #008000>**GUT**</fc>| <code c>+|<fc #008000>**GUT**</fc>| <sxh c; first-line: 1> 
 +#define ASCII_ZERO 0x30  
 +#define MOD_TEN 10 
 + 
 +#define DISP_LINE1 
 + 
 +#define DISP_POS0 
 +#define DISP_POS1 
 +#define DISP_POS2 
 ... ...
 void printDecimalDigit(int x, int y, int DigitToBePrint) void printDecimalDigit(int x, int y, int DigitToBePrint)
 { {
     lcd_goto(x,y);     lcd_goto(x,y);
-    lcd_putc(0x30 + DigitToBePrint%10);+    lcd_putc(ASCII_ZERO + DigitToBePrint%MOD_TEN );
 }; };
 ... ...
-    printDecimalDigit(10, hunderter); +    printDecimalDigit(DISP_LINE1DISP_POS0, hunderter); 
-    printDecimalDigit(11, zehner); +    printDecimalDigit(DISP_LINE1DISP_POS1, zehner); 
-    printDecimalDigit(12, einer);+    printDecimalDigit(DISP_LINE1DISP_POS2, einer);
 ... ...
-</code      |+</sxh     |
  
 ++++ ++++
  
   * Prüfen Sie, ob aufeinanderfolgende, ähnliche if-Anweisungen sich nicht direkt über Arrays lösen lassen (Beispiel Verzweigungen 1). Wählen Sie bei Verzweigungen statt vielen if-Anweisungen mit ähnlichen Bedingungen Switch-Case-Anweisungen (Beispiel Verzweigungen 2). Falls diese nicht möglich sind, eine For-Schleife und Arrays (Beispiel Verzweigungen 3).   * Prüfen Sie, ob aufeinanderfolgende, ähnliche if-Anweisungen sich nicht direkt über Arrays lösen lassen (Beispiel Verzweigungen 1). Wählen Sie bei Verzweigungen statt vielen if-Anweisungen mit ähnlichen Bedingungen Switch-Case-Anweisungen (Beispiel Verzweigungen 2). Falls diese nicht möglich sind, eine For-Schleife und Arrays (Beispiel Verzweigungen 3).
 +  * Auch Switch case kann auch durch verschiedene Vereinfachungen noch verbessert werden.
 +
 ++++Beispiel für Verzweigungen 1 - Umwandlung in Array | ++++Beispiel für Verzweigungen 1 - Umwandlung in Array |
  
-|<fc #800000>**SCHLECHT**</fc>| <code c>+|<fc #800000>**SCHLECHT**</fc>| <sxh c; first-line: 1>
 ... ...
     if (i==0) output("null");    // wenn 0 dann null     if (i==0) output("null");    // wenn 0 dann null
Zeile 355: Zeile 375:
 ... ...
  
-</code      +</sxh     
-|<fc #008000>**GUT**</fc>| <code c>+|<fc #008000>**GUT**</fc>| <sxh c; first-line: 1> 
 +#define MAX_ANZ_AUSGABE 6 
 +#define MAX_ZEICHEN_AUSGABE 4 
 ... ...
-    char AusgabeZahl[6][4] = {+    char AusgabeZahl[MAX_ANZ_AUSGABE][MAX_ZEICHEN_AUSGABE] = {
             "null",             "null",
             "eins",             "eins",
Zeile 369: Zeile 392:
     outputToLCD(AusgabeZahl[i]);     outputToLCD(AusgabeZahl[i]);
 ... ...
-</code      |+</sxh     |
  
 ++++++++Beispiel für Verzweigungen 2 - Umwandlung in Switch-Case| ++++++++Beispiel für Verzweigungen 2 - Umwandlung in Switch-Case|
  
-|<fc #800000>**SCHLECHT**</fc>| <code c>+|<fc #800000>**SCHLECHT**</fc>| <sxh c; first-line: 1>
 ... ...
     if (i==0) doZero;    // wenn 0 dann null     if (i==0) doZero;    // wenn 0 dann null
Zeile 383: Zeile 406:
 ... ...
  
-</code      +</sxh     
-|<fc #008000>**GUT**</fc>| <code c>+|<fc #008000>**GUT**</fc>| <sxh c; first-line: 1>
 ... ...
     switch(i) {     switch(i) {
Zeile 395: Zeile 418:
     };     };
 ... ...
-</code      |+</sxh     |
  
-++++++++Beispiel für Verzweigungen 3 - Umwandlung in For-Next|+++++++++Beispiel für Verzweigungen 3 - Optimierung von Switch-Case|
  
-|<fc #800000>**SCHLECHT**</fc>| <code c>+|<fc #800000>**OPTIMIERBAR**</fc>| <sxh c; first-line: 1> 
 +... 
 +    switch(i) { 
 +        case 1: doOne;   break;                // - die ersten beiden Cases 
 +        case 2: doOne;   break;                //   haben die gleichen Konsequenzen 
 +        case 3: doThree;doFour;doFive; break;  // - hier werden - je nach Zahl -  
 +        case 4: doFour;doFive;         break;  //   nach und nach aufeinanderfolgende 
 +        case 5: doFive;                break;  //   Funktionen aufgerufen 
 +        case 6: doOne;   break;                // - hier haben mehrere Cases 
 +        case 7: doOne;   break;                //   haben die gleichen Konsequenzen 
 +        case 8: doOne;   break;                //   
 +        case 9: doOne;   break;                //   
 +        default: break; 
 +    }; 
 +... 
 + 
 +</sxh>      | 
 +|<fc #008000>**BESSER**</fc>| <sxh c; first-line: 1> 
 +... 
 +    switch(i) { 
 +        case 1: 
 +        case 2:                               // Einzelne Zahlen können mit case's untereinander ... 
 +        case 6 ... 9:      doOne;   break;    // ... und Gruppen mit '...' kombiniert werden 
 +        case 3:            doThree;           // Ohne Break werden alle folgenden Befehle bis zum nächsten Break ausgeführt 
 +        case 4:            doFour;             
 +        case 5:            doFive;  
 +        default:           break; 
 +    }; 
 +... 
 +</sxh>      | 
 + 
 +++++++++Beispiel für Verzweigungen 4 - Umwandlung in For-Next| 
 + 
 +|<fc #800000>**SCHLECHT**</fc>| <sxh c; first-line: 1>
 ... ...
     if (( 0<i) && (i<= 7)) j=j+2;     if (( 0<i) && (i<= 7)) j=j+2;
Zeile 409: Zeile 465:
 ... ...
  
-</code      +</sxh     
-|<fc #008000>**GUT**</fc>| <code c>+|<fc #008000>**GUT**</fc>| <sxh c; first-line: 1>
 ... ...
     int maxSteps            = 6;     int maxSteps            = 6;
Zeile 420: Zeile 476:
     };     };
 ... ...
-</code      |+</sxh     |
  
 ++++ ++++
Zeile 427: Zeile 483:
 ++++Beispiel für Verzweigungen 4 - Verwenden von Else if| ++++Beispiel für Verzweigungen 4 - Verwenden von Else if|
  
-|<fc #800000>**SCHLECHT**</fc>| <code c>+|<fc #800000>**SCHLECHT**</fc>| <sxh c; first-line: 1>
 ... ...
     if (( 0<i) && (i<= 7)) j=j+2;     if (( 0<i) && (i<= 7)) j=j+2;
Zeile 437: Zeile 493:
 ... ...
  
-</code      +</sxh     
-|<fc #008000>**GUT**</fc>| <code c>+|<fc #008000>**GUT**</fc>| <sxh c; first-line: 1>
 ... ...
     if      (( 0<i) && (i<= 7)) { j = j + 2;}     if      (( 0<i) && (i<= 7)) { j = j + 2;}
Zeile 447: Zeile 503:
     else if ((12<i) && (i<=20)) { j = j + 3;};     else if ((12<i) && (i<=20)) { j = j + 3;};
 ... ...
-</code      |+</sxh     |
  
 ++++++++Beispiel für Verzweigungen 5 - Reduzieren der Anweisungen| ++++++++Beispiel für Verzweigungen 5 - Reduzieren der Anweisungen|
  
-|<fc #800000>**SCHLECHT**</fc>| <code c>+|<fc #800000>**SCHLECHT**</fc>| <sxh c; first-line: 1>
 ... ...
     if      (i<=7) {     if      (i<=7) {
Zeile 469: Zeile 525:
 ... ...
  
-</code      +</sxh     
-|<fc #008000>**GUT**</fc>|noch leserlich: +|<fc #008000>**GUT**</fc>\\ noch leserlich: \\ <sxh c; first-line: 1>
-   <code c>+
 ... ...
     if      (i<=7) {     if      (i<=7) {
Zeile 486: Zeile 541:
     DoOne;     DoOne;
 ... ...
-</code       auch möglich, aber etwas schwerer leserlich:  <code c>+</sxh      auch möglich, aber etwas schwerer leserlich:  <sxh c; first-line: 1>
 ... ...
-    if              (i<=7)                j=j+2; +    if           (i<=7)              j=j+2; 
-    else     { +    else{if     (( 7<i) && (i<=12))  j=j+5; 
-        if      (( 7<i) && (i<=12))     j=j+5; +        else if  (12<i)              j=j+3;
-        else if (12<i)                j=j+3;+
         DoZero;         DoZero;
     };     };
     DoOne;     DoOne;
- 
 ... ...
-</code    |+</sxh   |
  
 ++++ ++++
Zeile 506: Zeile 559:
 ++++Beispiel für Schleifen 1 - main()| ++++Beispiel für Schleifen 1 - main()|
  
-|<fc #800000>**SCHLECHT**</fc>| <code c>+|<fc #800000>**SCHLECHT**</fc>| <sxh c; first-line: 1>
 void main() void main()
 { {
Zeile 518: Zeile 571:
 } }
  
-</code      +</sxh     
-|<fc #008000>**GUT**</fc>| <code c>+|<fc #008000>**GUT**</fc>| <sxh c; first-line: 1>
 void main() void main()
 { {
Zeile 535: Zeile 588:
 } }
  
-</code      |+</sxh     |
  
 ++++++++Beispiel für Schleifen 2 - Abbrechen von verschachtelten Schleifen| ++++++++Beispiel für Schleifen 2 - Abbrechen von verschachtelten Schleifen|
  
-|<fc #800000>**SCHLECHT**</fc>| <code c>+|<fc #800000>**SCHLECHT**</fc>| <sxh c; first-line: 1>
     for(int xpos=0;xpos<10;xpos++){     for(int xpos=0;xpos<10;xpos++){
         initYPos;         initYPos;
Zeile 551: Zeile 604:
 ... ...
  
-</code      +</sxh     
-|<fc #008000>**GUT**</fc>| <code c>+|<fc #008000>**GUT**</fc>| <sxh c; first-line: 1>
     int xposMax=10, yposMax=20;     int xposMax=10, yposMax=20;
  
Zeile 567: Zeile 620:
 ... ...
  
-</code      **Beachten Sie, dass in diesem Fall CancelButton eine Variable sein muss und sich zwischen den beiden if-Bedingungen nicht ändern darf (z.B. durch Interrupts).**     |+</sxh     **Beachten Sie, dass in diesem Fall CancelButton eine Variable sein muss und sich zwischen den beiden if-Bedingungen nicht ändern darf (z.B. durch Interrupts).**     |
  
 ++++ ++++
  
-  * _delay_ms() und _delay_us() sind zu 99% nicht notwendig. Verwenden Sie stattdessen Interrupts, bzw. Timer. Es können z.B. durch Interrupts Takte angelegt werdentakt10ms, takt100ms, takt1s. Diese können dann im main() Verzweigungen in einer Zustandsmaschine auslösen.+  * _delay_ms() und _delay_us() sind zu 99% nicht notwendig. Verwenden Sie stattdessen Interrupts, bzw. Timer. \\ Es sollten durch Interrupts Takte angelegt werden, z.B. takt10ms, takt100ms, takt1s welche nur im ''main()'' abgefragt werden.  
 +  * Häufig bietet es sich an, in den Takten dann auch Verzweigungen in einer Zustandsmaschine aufzubauen (z.B. mit Zustandsvariablen wie ''outputState'': ''<nowiki>switch(outputState) {case initOutput: outputState++; ... break; case startOutput: outputState++; ... break; }</nowiki>'').
   * Wenn Sie Zahlen in Variablen speichern und diese auch mathematisch weiterverwenden, so wandeln Sie diese Variable erst bei der Ausgabe in das ASCII-Format um.   * Wenn Sie Zahlen in Variablen speichern und diese auch mathematisch weiterverwenden, so wandeln Sie diese Variable erst bei der Ausgabe in das ASCII-Format um.
 ++++Beispiel für Variablen mit Ausgabe| ++++Beispiel für Variablen mit Ausgabe|
  
-|<fc #800000>**SCHLECHT**</fc>| <code c>+|<fc #800000>**SCHLECHT**</fc>| <sxh c; first-line: 1>
 ... ...
     Zahlenwert = (ADC_Wert/10)%10 + 0x30;     Zahlenwert = (ADC_Wert/10)%10 + 0x30;
Zeile 583: Zeile 637:
 ... ...
  
-</code      +</sxh     
-|<fc #008000>**GUT**</fc>| <code c>+|<fc #008000>**GUT**</fc>| <sxh c; first-line: 1> 
 + 
 +#define ASCII_ZERO 0x30  
 +#define MOD_TEN 10 
 ... ...
-    Laenge     = (ADC_Wert/10)%10 ;+    Laenge     = (ADC_Wert/MOD_TEN)%MOD_TEN;
     Laengen[i] = Laenge;     Laengen[i] = Laenge;
     Flaeche    = Laenge * Breite;     Flaeche    = Laenge * Breite;
-    LCD_putc(Laengen[i]+ 0x30);+    LCD_putc(Laengen[i]+ ASCII_ZERO);
 ... ...
-</code\\   \\   |+</sxh |
  
 ++++ ++++
Zeile 597: Zeile 655:
 ====== Bewertung ====== ====== Bewertung ======
  
-===== abzugebende Work Products ===== +Zur Bewertung lege ich {{microcontrollertechnik:bewertung_ws21_prjxx.xlsx|diese Checkliste (xls-File)}} als Maßstab an.
- +
-Bitte legen Sie folgende Unterlagen in einem Zip-File unter ILIAS ab: +
- +
-  * Lastenheft und OPL als xls +
-  * Modulblockbild/Blockschaltbild als xml +
-  * Programm mit main.c sowie weitere für Ihr Projekt benötigte c- und h-Files +
- +
-Die ATMEL-spezifischen Dateien (*.cproj, *.atsln, Debug-Ordner, etc.) nicht mit ablegen. Überprüfen Sie, ob aus diesen Files lauffähiger Code erstellt werden kann. Wenn dabei etwas zu beachten ist (z.B. Anlegen neuer Compiler Symbole), sollte dies in die Programmbeschreibung aufgenommen werden. +
- +
-===== Bewertung ===== +
- +
-Zur Bewertung lege ich {{:checkliste_290718.pdf|diese Checkliste}}  ({{:checkliste_290718.xlsx|xls-File}} als Maßstab an. +
- +
-\\ +