diff --git a/20210114/blink-0a.c b/20210114/blink-0a.c
new file mode 100644
index 0000000000000000000000000000000000000000..569e7c5b9160c1fe750f1b34492dec99ef814012
--- /dev/null
+++ b/20210114/blink-0a.c
@@ -0,0 +1,9 @@
+#include <avr/io.h>
+
+int main (void)
+{
+  DDRD = 0x7c;   /* binär: 0111 1100 */
+  PORTD = 0x41;  /* binär: 0100 0001 */
+  while (1);
+  return 0;
+}
diff --git a/20210114/blink-0b.c b/20210114/blink-0b.c
new file mode 100644
index 0000000000000000000000000000000000000000..1f9ee2b0d4bd483103e56c571180f6e50f11dba9
--- /dev/null
+++ b/20210114/blink-0b.c
@@ -0,0 +1,13 @@
+#include <avr/io.h>
+
+#define F_CPU 16000000l
+#include <util/delay.h>
+
+int main (void)
+{
+  DDRD = 0x7c;   /* binär: 0111 1100 */
+  _delay_ms (1);
+  PORTD = 0x40;  /* binär: 0100 0000 */
+  while (1);
+  return 0;
+}
diff --git a/20210114/blink-0c.c b/20210114/blink-0c.c
new file mode 100644
index 0000000000000000000000000000000000000000..28fe2e148c88fa68547d55e5ba025a70c5ea42ae
--- /dev/null
+++ b/20210114/blink-0c.c
@@ -0,0 +1,13 @@
+#include <avr/io.h>
+
+#define F_CPU 16000000l
+#include <util/delay.h>
+
+int main (void)
+{
+  DDRD = 0x7d;   /* binär: 0111 1101 */
+  _delay_ms (1);
+  PORTD = 0x40;  /* binär: 0100 0000 */
+  while (1);
+  return 0;
+}
diff --git a/20210114/blink-3a.c b/20210114/blink-3a.c
new file mode 100644
index 0000000000000000000000000000000000000000..388ed658bb7494d5483f311908a1251892aef196
--- /dev/null
+++ b/20210114/blink-3a.c
@@ -0,0 +1,18 @@
+#include <avr/io.h>
+
+#define F_CPU 16000000
+#include <util/delay.h>
+
+int main (void)
+{
+  DDRD = 0x7c;   /* binär: 0111 1100 */
+  PORTD = 0x42;  /* binär: 0100 0010: PORT für Input für 1 setzen = internen Pull-Up-Widerstand aktivieren */
+  while (1)
+    {
+      while ((PIND & 0x02) == 0)   /* binär: 0000 0010 */
+        ; /* just wait */
+      PORTD ^= 0x40;
+      _delay_ms (200);
+    }
+  return 0;
+}
diff --git a/20210114/blink-3c.c b/20210114/blink-3c.c
new file mode 100644
index 0000000000000000000000000000000000000000..d978187a6dd73fb489ef5a231c92032405715aa7
--- /dev/null
+++ b/20210114/blink-3c.c
@@ -0,0 +1,18 @@
+#include <avr/io.h>
+
+#define F_CPU 16000000
+#include <util/delay.h>
+
+int main (void)
+{
+  DDRD = 0x7c;   /* binär: 0111 1100 */
+  PORTD = 0xc0;  /* 0x40 = 0100 0000; 0xc0 = 1100 0000 */
+  while (1)
+    {
+      while ((PIND & 0x02) == 0)
+        ; /* just wait */
+      PORTD ^= 0x40;
+      _delay_ms (200);
+    }
+  return 0;
+}
diff --git a/20210114/blink-3d.c b/20210114/blink-3d.c
new file mode 100644
index 0000000000000000000000000000000000000000..7940918580dac53ea5ca7cb717062a6a2e4fc4d9
--- /dev/null
+++ b/20210114/blink-3d.c
@@ -0,0 +1,18 @@
+#include <avr/io.h>
+
+#define F_CPU 16000000
+#include <util/delay.h>
+
+int main (void)
+{
+  DDRD = 0x7c;   /* binär: 0111 1100 */
+  PORTD = 0xc0;  /* 0x40 = 0100 0000; 0xc0 = 1100 0000 */
+  while (1)
+    {
+      while ((PIND & 0x02) == 0)
+        ; /* just wait */
+      PORTD ^= 0x80;
+      _delay_ms (200);
+    }
+  return 0;
+}
diff --git a/20210114/blink-3e.c b/20210114/blink-3e.c
new file mode 100644
index 0000000000000000000000000000000000000000..20dd315377a479c739502993dcb88b28015e9ebc
--- /dev/null
+++ b/20210114/blink-3e.c
@@ -0,0 +1,18 @@
+#include <avr/io.h>
+
+#define F_CPU 16000000
+#include <util/delay.h>
+
+int main (void)
+{
+  DDRD = 0xfc;   /* binär: 1111 1100 */
+  PORTD = 0xc0;  /* 0x40 = 0100 0000; 0xc0 = 1100 0000 */
+  while (1)
+    {
+      while ((PIND & 0x02) == 0)
+        ; /* just wait */
+      PORTD ^= 0x80;
+      _delay_ms (200);
+    }
+  return 0;
+}
diff --git a/20210114/download.sh b/20210114/download.sh
new file mode 100755
index 0000000000000000000000000000000000000000..770c3b5dca74ac09778be055c9d6f5adb0df293b
--- /dev/null
+++ b/20210114/download.sh
@@ -0,0 +1,3 @@
+port=$(ls -rt /dev/ttyACM* | tail -1)
+echo avrdude -P $port -c arduino -p m328p -U flash:w:$(ls -rt *.hex | tail -1)
+avrdude -P $port -c arduino -p m328p -U flash:w:$(ls -rt *.hex | tail -1) 2>/dev/null
diff --git a/20210114/hp-musterloesung-20210114.tex b/20210114/hp-musterloesung-20210114.tex
index 2027ef6d209d940a82a925f8d8fee50f54ab0048..cb7514e9303ffa538c78d1a9ca7bc5efc8e9b141 100644
--- a/20210114/hp-musterloesung-20210114.tex
+++ b/20210114/hp-musterloesung-20210114.tex
@@ -1,4 +1,4 @@
-% hp-musterloesung-20210107.pdf - Solutions to the Exercises on Low-Level Programming
+% hp-musterloesung-20210114.pdf - Solutions to the Exercises on Low-Level Programming
 % Copyright (C) 2013, 2015, 2016, 2017, 2018, 2019, 2020, 2021  Peter Gerwinski
 %
 % This document is free software: you can redistribute it and/or
@@ -20,7 +20,7 @@
 % Attribution-ShareAlike 3.0 Unported License along with this
 % document.  If not, see <http://creativecommons.org/licenses/>.
 
-% README: Fakultät, Länge von Strings (Neuauflage), Hexdumps
+% README: Zahlensysteme, Mikrocontroller
 
 \documentclass[a4paper]{article}
 
@@ -30,328 +30,363 @@
 \begin{document}
 
   \section*{Hardwarenahe Programmierung\\
-            Musterlösung zu den Übungsaufgaben -- 7.\ Januar 2021}
+            Musterlösung zu den Übungsaufgaben -- 14.\ Januar 2021}
+
+  \exercise{Zahlensysteme}
+
+  Wandeln Sie ohne Hilfsmittel
+
+  \begin{minipage}[t]{0.3\textwidth}
+    \begin{itemize}
+      \item
+        nach Dezimal:
+        \begin{itemize}
+          \item[(a)]
+            0010\,0000$_2$
+          \item[(b)]
+            42$_{16}$
+          \item[(c)]
+            17$_8$
+        \end{itemize}
+    \end{itemize}
+  \end{minipage}\hfill
+  \begin{minipage}[t]{0.3\textwidth}
+    \begin{itemize}
+      \item
+        nach Hexadezimal:
+        \begin{itemize}
+          \item[(d)]
+            0010\,0000$_2$
+          \item[(e)]
+            42$_{10}$
+          \item[(f)]
+            192.168.20.254$_{256}$
+        \end{itemize}
+    \end{itemize}
+  \end{minipage}\hfill
+  \begin{minipage}[t]{0.3\textwidth}
+    \begin{itemize}
+      \item
+        nach Binär:
+        \begin{itemize}
+          \item[(g)]
+            750$_8$
+          \item[(h)]
+            42$_{10}$
+          \item[(i)]
+            AFFE$_{16}$
+        \end{itemize}
+    \end{itemize}
+  \end{minipage}
+  
+  \medskip
 
-  \exercise{Fakultät}
+  Berechnen Sie ohne Hilfsmittel:
+  \begin{itemize}
+    \item[(j)]
+      750$_8$ \& 666$_8$
+    \item[(k)]
+      A380$_{16}$ + B747$_{16}$
+    \item[(l)]
+      AFFE$_{16} >> 1$
+  \end{itemize}
 
-  Die Fakultät $n!$ einer ganzen Zahl $n \ge 0$ ist definiert als:
-  \begin{eqnarray*}
-    1 & \mbox{für} & n = 0, \\
-    n \cdot (n-1)! & \mbox{für} & n > 0.
-  \end{eqnarray*}
+  Die tiefgestellte Zahl steht für die Basis des Zahlensystems.
+  Jede Teilaufgabe zählt 1 Punkt. \addtocounter{points}{12}
 
-  Mit anderen Worten: $n! = 1\cdot2\cdot3\cdot\dots\cdot n$.
+  (In der Klausur sind Hilfsmittel zugelassen,
+  daher ist dies \emph{keine\/} typische Klausuraufgabe.)
 
-  Die folgende Funktion \lstinline{fak()} berechnet die Fakultät \emph{rekursiv}
-  (Datei: \gitfile{hp}{2020ws/20210107}{aufgabe-1.c}):
+  \solution
 
-  \begin{lstlisting}
-    int fak (int n)
-    {
-      if (n <= 0)
-        return 1;
-      else
-        return n * fak (n - 1);
-    }
-  \end{lstlisting}
+  Wandeln Sie ohne Hilfsmittel
 
-  \begin{enumerate}[\quad(a)]
-    \item
-      Schreiben Sie eine Funktion, die die Fakultät \emph{iterativ} berechnet,\\
-      d.\,h.\ mit Hilfe einer Schleife anstelle von Rekursion.
-      \points{3}
+  \begin{itemize}
     \item
-      Wie viele Multiplikationen (Landau-Symbol)
-      erfordern beide Versionen der Fakultätsfunktion\\
-      in Abhängigkeit von \lstinline$n$?
-      Begründen Sie Ihre Antwort.
-      \points{2}
+      nach Dezimal:
+      \begin{itemize}
+        \item[(a)]
+          $0010\,0000_2 = 32_{10}$
+
+          Eine Eins mit fünf Nullen dahinter steht binär für $2^5 = 32$:\\
+          mit $1$ anfangen und fünfmal verdoppeln.
+        \item[(b)]
+          $42_{16} = 4 \cdot 16 + 2 \cdot 1 = 64 + 2 = 66$
+        \item[(c)]
+          $17_8 = 1 \cdot 8 + 7 \cdot 1 = 8 + 7 = 15$
+      \end{itemize}
+      Umwandlung von und nach Dezimal ist immer rechenaufwendig.
+      Umwandlungen zwischen Binär, Oktal und Hexadezimal gehen ziffernweise
+      und sind daher wesentlich einfacher.
     \item
-      Wieviel Speicherplatz (Landau-Symbol)
-      erfordern beide Versionen der Fakultätsfunktion\\
-      in Abhängigkeit von \lstinline$n$?
-      Begründen Sie Ihre Antwort.
-      \points{3}
-  \end{enumerate}
+      nach Hexadezimal:
+      \begin{itemize}
+        \item[(d)]
+          $0010\,0000_2 = 20_{16}$
 
-  \solution
+          Umwandlung von Binär nach Hexadezimal geht ziffernweise:\\
+          Vier Binärziffern werden zu einer Hex-Ziffer.
+        \item[(e)]
+          $\rm 42_{10} = 32_{10} + 10_{10} = 20_{16} + A_{16} = 2A_{16}$
+        \item[(f)]
+          $\rm 192.168.20.254_{256} = C0\,A8\,14\,FE_{16}$
 
-  \begin{itemize}
-    \item[(a)]
-      \textbf{Schreiben Sie eine Funktion, die die Fakultät \emph{iterativ} berechnet,\\
-      d.\,h.\ mit Hilfe einer Schleife anstelle von Rekursion.}
+          Umwandlung von der Basis 256 nach Hexadezimal geht ziffernweise:\\
+          Eine 256er-Ziffer wird zu zwei Hex-Ziffern.
 
-      Datei: \gitfile{hp}{2020ws/20210107}{loesung-1.c}
-      \begin{lstlisting}[gobble=8]
-        int fak (int n)
-        {
-          int f = 1;
-          for (int i = 2; i <= n; i++)
-            f *= i;
-          return f;
-        }
-      \end{lstlisting}
+          Da die 256er-Ziffern dezimal angegeben sind,
+          müssen wir viermal Dezimal nach Hexadezimal umwandeln.
+          Hierfür bieten sich unterschiedliche Wege an.
 
-    \item[(b)]
-      \textbf{Wie viele Multiplikationen (Landau-Symbol)
-      erfordern beide Versionen der Fakultätsfunktion\\
-      in Abhängigkeit von \lstinline$n$?
-      Begründen Sie Ihre Antwort.}
+          $\rm 192_{10} = 128_{10} + 64_{10} = 1100\,0000_{2} = C0_{16}$
 
-      In beiden Fällen werden $n$ Zahlen miteinander multipliziert --
-      oder $n - 1$, wenn man Multiplikationen mit 1 ausspart.
-      In jedem Fall hängt die Anzahl der Multiplikationen
-      linear von $n$ ab; es sind $\mathcal{O}(n)$ Multiplikationen.
-      Insbesondere arbeiten also beide Versionen gleich schnell.
+          $\rm 168_{10} = 10_{10} \cdot 16_{10} + 8_{10} = A_{16} \cdot 10_{16} + 8_{16} = A8_{16}$
 
-    \item[(c)]
-      \textbf{Wieviel Speicherplatz (Landau-Symbol)
-      erfordern beide Versionen der Fakultätsfunktion\\
-      in Abhängigkeit von \lstinline$n$?
-      Begründen Sie Ihre Antwort.}
-
-      Die iterative Version der Funktion benötigt 2 Variable vom Typ \lstinline{int},
-      nämlich \lstinline{n} und \lstinline{f}.
-      Dies ist eine konstante Zahl;
-      der Speicherplatzverbrauch ist daher $\mathcal{O}(1)$.
-
-      Die rekursive Version der Funktion erzeugt
-      jedesmal, wenn sie sich selbst aufruft,
-      eine zusätzliche Variable \lstinline{n}.
-      Es sind $n + 1$ Aufrufe; die Anzahl der Variablen \lstinline{n}
-      hängt linear von $n$ ab; der Speicherplatzverbrauch ist also $\mathcal{O}(n)$.
+          $20_{10} = 16_{10} + 4_{10} = 10_{16} + 4_{16} = 14$
+          
+          $\rm 254_{10} = 255_{10} - 1_{10} = FF_{16} - 1_{16} = FE_{16}$
+      \end{itemize}
+    \item
+      nach Binär:
+      \begin{itemize}
+        \item[(g)]
+          $750_8 = 111\,101\,000_2$
+
+          Umwandlung von Oktal nach Binär geht ziffernweise:\\
+          Eine Oktalziffer wird zu drei Binärziffern.
+        \item[(h)]
+          $\rm 42_{10} = 2A_{16}$ (siehe oben) $= 0010\,1010_{16}$
+
+          Umwandlung von Hexadezimal nach Binär geht ziffernweise:\\
+          Eine Hex-Ziffer wird zu vier Binärziffern.
+        \item[(i)]
+          $\rm AFFE_{16} = 1010\,1111\,1111\,1110_2$
+
+          Umwandlung von Hexadezimal nach Binär geht ziffernweise:\\
+          Eine Hex-Ziffer wird zu vier Binärziffern.
+      \end{itemize}
   \end{itemize}
-
-  \exercise{Länge von Strings}
-
-  Diese Aufgabe ist eine Neuauflage von Aufgabe 3 der
-  Übung vom 14.\ November 2019,\\
-  ergänzt um die Teilaufgaben (f) und (g).
-
+  
   \medskip
 
-  Strings werden in der Programmiersprache C durch Zeiger auf \lstinline{char}-Variable realisiert.
-
-  Beispiel: \lstinline{char *hello_world = "Hello, world!\n"}
-
-  Die Systembibliothek stellt eine Funktion \lstinline{strlen()} zur Ermittlung der Länge von Strings\\
-  zur Verfügung (\lstinline{#include <string.h>}).
-
-  \begin{enumerate}[\quad(a)]
-    \item
-      Auf welche Weise ist die Länge eines Strings gekennzeichnet?
-      \points{1}
-    \item
-      Wie lang ist die Beispiel-String-Konstante \lstinline{"Hello, world!\n"},
-      und wieviel Speicherplatz belegt sie?\\
-      \points{2}
-    \item
-      Schreiben Sie eine eigene Funktion \lstinline{int strlen (char *s)},
-      die die Länge eines Strings zurückgibt.\\
-      \points{3}
-  \end{enumerate}
+  Berechnen Sie ohne Hilfsmittel:
+  \begin{itemize}
+    \item[(j)]
+      $750_8\,\&\,666_8
+      = 111\,101\,000_2\,\&\,110\,110\,110_2
+      = 110\,100\,000_2
+      = 640_8$
+
+      Binäre Und-Operationen lassen sich am leichtesten
+      in binärer Schreibweise durchführen.
+      Umwandlung zwischen Oktal und Binär geht ziffernweise:
+      Eine Oktalziffer wird zu drei Binärziffern und umgekehrt.
+
+      Mit etwas Übung funktionieren diese Operationen
+      auch direkt mit Oktalzahlen im Kopf.
+
+    \item[(k)]
+      $\rm\phantom{+}A380_{16}$\\
+      $\rm+\kern2ptB747_{16}$\\[-\medskipamount]
+      \rule{1.4cm}{0.5pt}\\
+      $\rm 15AC7_{16}$
+      \begin{picture}(0,0)
+        \put(-1.4,0.35){\mbox{\scriptsize\bf 1}}
+      \end{picture}
+
+      Mit Hexadezimalzahlen (und Binär- und Oktal- und sonstigen Zahlen)
+      kann man genau wie mit Dezimalzahlen schriftlich rechnen.
+      Man muß nur daran denken, daß der "`Zehner"'-Überlauf nicht bei
+      $10_{10}$ stattfindet, sondern erst bei $10_{16} = 16_{10}$
+      (hier: $\rm 8_{16} + 4_{16} = C_{16}$ und
+      $\rm 3_{16} + 7_{16} = A_{16}$, aber
+      $\rm A_{16} + B_{16} = 10_{10} + 11_{10}
+      = 21_{10} = 16_{10} + 5_{10} = 10_{16} + 5_{16} =  15_{16}$).
+
+    \item[(l)]
+      $\rm AFFE_{16} >> 1
+      = 1010\,1111\,1111\,1110_2 >> 1
+      = 0101\,0111\,1111\,1111_2
+      = 57FF_{16}$
+
+      Bit-Verschiebungen lassen sich am leichtesten
+      in binärer Schreibweise durchführen.
+      Umwandlung zwischen Hexadezimal und Binär geht ziffernweise:
+      Eine Hex-Ziffer wird zu vier Binärziffern und umgekehrt.
+
+      Mit etwas Übung funktionieren diese Operationen
+      auch direkt mit Hexadezimalzahlen im Kopf.
 
-  \goodbreak
+  \end{itemize}
 
-  Wir betrachten nun die folgenden Funktionen (Datei: \gitfile{hp}{2020ws/20210107}{aufgabe-2.c}):
-  \begin{center}
-    \begin{minipage}{8cm}
-      \begin{lstlisting}[gobble=8]
-        int fun_1 (char *s)
-        {
-          int x = 0;
-          for (int i = 0; i < strlen (s); i++)
-            x += s[i];
-          return x;
-        }
-      \end{lstlisting}
-    \end{minipage}%
-    \begin{minipage}{6cm}
-      \vspace*{-1cm}
-      \begin{lstlisting}[gobble=8]
-        int fun_2 (char *s)
-        {
-          int i = 0, x = 0;
-          int len = strlen (s);
-          while (i < len)
-            x += s[i++];
-          return x;
-        }
-      \end{lstlisting}
-      \vspace*{-1cm}
-    \end{minipage}
-  \end{center}
-  \begin{enumerate}[\quad(a)]\setcounter{enumi}{3}
-    \item
-      Was bewirken die beiden Funktionen?
-      \points{2}
-    \item
-      Schreiben Sie eine eigene Funktion,
-      die dieselbe Aufgabe erledigt wie \lstinline{fun_2()},\\
-      nur effizienter.
-      \points{4}
-    \item
-      Von welcher Ordnung (Landau-Symbol) sind die beiden Funktionen
-      hinsichtlich der Anzahl ihrer Zugriffe auf die Zeichen im String?
-      Begründen Sie Ihre Antwort.
-      Sie dürfen für \lstinline{strlen()} Ihre eigene Version der Funktion voraussetzen.
-       \points{3}
-    \item
-      Von welcher Ordnung (Landau-Symbol) ist Ihre effizientere Funktion?\\
-      Begründen Sie Ihre Antwort.
-      \points{1}
-  \end{enumerate}
+  \exercise{Mikrocontroller}
+
+  \begin{minipage}[t]{10cm}
+    An die vier Ports eines ATmega16-Mikrocontrollers sind Leuchtdioden angeschlossen:
+    \begin{itemize}
+      \item
+        von links nach rechts an die Ports A, B, C und D,
+      \item
+        von oben nach unten an die Bits Nr.\ 0 bis 7.
+    \end{itemize}
+
+    Wir betrachten das folgende Programm (\gitfile{hp}{2020ws/20210114}{aufgabe-2.c}):
+
+    \begin{lstlisting}[gobble=6]
+      #include <avr/io.h>
+
+      int main (void)
+      {
+        DDRA = 0xff;
+        DDRB = 0xff;
+        DDRC = 0xff;
+        DDRD = 0xff;
+        PORTA = 0x1f;
+        PORTB = 0x10;
+        PORTD = 0x10;
+        PORTC = 0xfc;
+        while (1);
+        return 0;
+      }
+    \end{lstlisting}
+  \end{minipage}\hfill
+  \begin{minipage}[t]{3cm}
+    \strut\\[-\baselineskip]
+    \includegraphics[width=3cm]{leds.jpg}
+  \end{minipage}
+
+  \vspace*{-3cm}
+
+  \strut\hfill
+  \begin{minipage}{11.8cm}
+    \begin{itemize}
+      \item[(a)]
+        Was bewirkt dieses Programm? \points{4}
+      \item[(b)]
+        Wozu dienen die ersten vier Zeilen des Hauptprogramms? \points{2}
+      \item[(c)]
+        Was würde stattdessen die Zeile \lstinline{DDRA, DDRB, DDRC, DDRD = 0xff;} bewirken?
+        \points{2}
+      \item[(d)]
+        Schreiben Sie das Programm so um,
+        daß die durch das Programm dargestellte Figur spiegelverkehrt erscheint. \points{3}
+      \item[(e)]
+        Wozu dient das \lstinline{while (1)}? \points{2}
+      \item
+        Alle Antworten bitte mit Begründung.
+    \end{itemize}
+  \end{minipage}
 
   \solution
 
   \begin{itemize}
     \item[(a)]
-      \textbf{Auf welche Weise ist die Länge eines Strings gekennzeichnet?}
-
-      Ein String ist ein Array von \lstinline{char}s.
-      Nach den eigentlichen Zeichen des Strings enthält das Array
-      \textbf{ein Null-Symbol} (Zeichen mit Zahlenwert 0,
-      nicht zu verwechseln mit der Ziffer \lstinline{'0'}) als Ende-Markierung.
-      Die Länge eines Strings ist die Anzahl der Zeichen
-      \emph{vor\/} diesem Symbol.
+      \textbf{Was bewirkt dieses Programm?}
+
+      \newcommand{\x}{$\bullet$}
+      \renewcommand{\o}{$\circ$}
+
+      \begin{minipage}[t]{0.75\textwidth}\parskip\smallskipamount
+        Es läßt die LEDs in dem rechts abgebildeten Muster aufleuchten,\\
+        das z.\,B.\ als die Ziffer 4 gelesen werden kann.
+
+        (Das Zeichen \x\ steht für eine leuchtende, \o\ für eine nicht leuchtende LED.)
+
+        Die erste Spalte (Port A) von unten nach oben gelesen (Bit 7 bis 0)\\
+        entspricht der Binärdarstellung von \lstinline{0x1f}: 0001\,1111.
+
+        Die dritte Spalte (Port C) von unten nach oben gelesen (Bit 7 bis 0)\\
+        entspricht der Binärdarstellung von \lstinline{0xfc}: 1111\,1100.
+
+        Die zweite und vierte Spalte (Port B und D) von unten nach oben gelesen\\
+        (Bit 7 bis 0) entsprechen der Binärdarstellung von \lstinline{0x10}: 0001\,0000.
+
+        Achtung: Die Zuweisung der Werte an die Ports erfolgt im Programm\\
+        \emph{nicht\/} in der Reihenfolge A B C D, sondern in der Reihenfolge A B D C.
+      \end{minipage}\hfill
+      \begin{minipage}[t]{0.15\textwidth}
+        \vspace*{-0.5cm}%
+        \begin{tabular}{cccc}
+          \x & \o & \o & \o \\
+          \x & \o & \o & \o \\
+          \x & \o & \x & \o \\
+          \x & \o & \x & \o \\
+          \x & \x & \x & \x \\
+          \o & \o & \x & \o \\
+          \o & \o & \x & \o \\
+          \o & \o & \x & \o \\
+        \end{tabular}
+      \end{minipage}
 
     \item[(b)]
-      {\bf Wie lang ist die Beispiel-String-Konstante \lstinline{"Hello, world!\n"},
-      und wieviel Speicherplatz belegt sie?}
+      \textbf{Wozu dienen die ersten vier Zeilen des Hauptprogramms?}
 
-      Sie ist 14 Zeichen lang (\lstinline{'\n'} ist nur 1 Zeichen;
-      das Null-Symbol, das das Ende markiert, zählt hier nicht mit)
-      und belegt Speicherplatz für 15 Zeichen
-      (15 Bytes -- einschließlich Null-Symbol / Ende-Markierung).
+      Mit diesen Zeilen werden alle jeweils 8 Bits aller 4 Ports
+      als Output-Ports konfiguriert.
 
     \item[(c)]
-      \textbf{Schreiben Sie eine eigene Funktion \lstinline{int strlen (char *s)},
-      die die Länge eines Strings zurückgibt.}
+      \textbf{Was würde stattdessen die Zeile \lstinline{DDRA, DDRB, DDRC, DDRD = 0xff;} bewirken?}
 
-      Siehe die Dateien \gitfile{hp}{2020ws/20210107}{loesung-2c-1.c} (mit Array-Index)
-      und \gitfile{hp}{2020ws/20210107}{loesung-2c-2.c} (mit Zeiger-Arithmetik).
-      Beide Lösungen sind korrekt und arbeiten gleich schnell.
+      Der Komma-Operator in C bewirkt, daß der erste Wert berechnet
+      und wieder verworfen wird und stattdessen der zweite Wert weiterverarbeitet wird.
+      Konkret hier hätte das zur Folge,
+      daß \lstinline{DDRA}, \lstinline{DDRB} und \lstinline{DDRC}
+      gelesen und die gelesenen Werte ignoriert werden;
+      anschließend wird \lstinline{DDRD} der Wert \lstinline{0xff} zugewiesen.
+      Damit würde also nur einer von vier Ports überhaupt konfiguriert.
 
-      Die Warnung \lstinline[style=terminal]{conflicting types for built-in function "strlen"}
-      kann normalerweise ignoriert werden;
-      auf manchen Systemen (z.\,B.\ MinGW) hat jedoch die eingebaute Funktion \lstinline{strlen()}
-      beim Linken Vorrang vor der selbstgeschriebenen,
-      so daß die selbstgeschriebene Funktion nie aufgerufen wird.
-      In solchen Fällen ist es zulässig, die selbstgeschriebene Funktion
-      anders zu nennen (z.\,B.\ \lstinline{my_strlen()}).
+      Da es sich bei den \lstinline{DDR}-Variablen
+      um \lstinline{volatile}-Variable handelt,
+      nimmt der Compiler an, daß der Lesezugriff schon irgendeinen Sinn hätte.
+      Der Fehler bliebe also unbemerkt.
 
     \item[(d)]
-      \textbf{Was bewirken die beiden Funktionen?}
+      \textbf{Schreiben Sie das Programm so um,
+      daß die durch das Programm dargestellte Figur spiegelverkehrt erscheint.}
 
-      Beide addieren die Zahlenwerte der im String enthaltenen Zeichen
-      und geben die Summe als Funktionsergebnis zurück.
+      Hierzu vertauschen wir die Zuweisungen
+      an \lstinline{PORTA} und \lstinline{PORTD}
+      sowie die Zuweisungen
+      an \lstinline{PORTB} und \lstinline{PORTC}:
 
-      Im Falle des Test-Strings \lstinline{"Hello, world!\n"}
-      lautet der Rückgabewert 1171 (siehe \gitfile{hp}{2020ws/20210107}{loesung-2d-1.c} und \gitfile{hp}{2020ws/20210107}{loesung-2d-2.c}).
+      \begin{lstlisting}[gobble=8]
+          PORTD = 0x1f;
+          PORTC = 0x10;
+          PORTA = 0x10;
+          PORTB = 0xfc;
+      \end{lstlisting}
+
+      Damit ergibt sich eine Spiegelung an der vertikalen Achse.
+
+      Alternativ kann man auch an der horizontalen Achse spiegeln.
+      Dafür muß man die Bits in den Hexadezimalzahlen umdrehen:
+
+      \begin{lstlisting}[gobble=8]
+          PORTA = 0xf8;
+          PORTB = 0x08;
+          PORTD = 0x08;
+          PORTC = 0x3f;
+      \end{lstlisting}
+
+      Die Frage, welche der beiden Spiegelungen gewünscht ist,
+      wäre übrigens \emph{auch in der Klausur zulässig}.
 
     \item[(e)]
-      \textbf{Schreiben Sie eine eigene Funktion,
-      die dieselbe Aufgabe erledigt wie \lstinline{fun_2()},
-      nur effizienter.}
-
-      Die Funktion wird effizienter,
-      wenn man auf den Aufruf von \lstinline{strlen()} verzichtet
-      und stattdessen die Ende-Prüfung in derselben Schleife vornimmt,
-      in der man auch die Zahlenwerte der Zeichen des Strings aufsummiert.
-
-      Die Funktion \lstinline{fun_3()} in der Datei \gitfile{hp}{2020ws/20210107}{loesung-2e-1.c}
-      realisiert dies mit einem Array-Index,
-      Die Funktion \lstinline{fun_4()} in der Datei \gitfile{hp}{2020ws/20210107}{loesung-2e-2.c}
-      mit Zeiger-Arithmetik.
-      Beide Lösungen sind korrekt und arbeiten gleich schnell.
-
-      \textbf{Bemerkung:} Die effizientere Version der Funktion
-      arbeitet doppelt so schnell wie die ursprüngliche,
-      hat aber ebenfalls die Ordnung $\mathcal{O}(n)$ -- siehe unten.
-
-    \item[(f)]
-      \textbf{Von welcher Ordnung (Landau-Symbol) sind die beiden Funktionen
-      hinsichtlich der Anzahl ihrer Zugriffe auf die Zeichen im String?
-      Begründen Sie Ihre Antwort.
-      Sie dürfen für \lstinline{strlen()} Ihre eigene Version der Funktion voraussetzen.}
-
-      Vorüberlegung: \lstinline{strlen()} greift in einer Schleife
-      auf alle Zeichen des Strings der Länge $n$ zu,
-      hat also $\mathcal{O}(n)$.
-
-      \lstinline{fun_1()} ruft in jedem Schleifendurchlauf
-      (zum Prüfen der \lstinline{while}-Bedingung) einmal \lstinline{strlen()} auf
-      und greift anschließend auf ein Zeichen des Strings zu,
-      hat also $\mathcal{O}\bigl(n\cdot(n+1)\bigr) = \mathcal{O}(n^2)$.
-
-      \lstinline{fun_2()} ruft einmalig \lstinline{strlen()} auf
-      und greift anschließend in einer Schleife auf alle Zeichen des Strings zu,
-      hat also $\mathcal{O}(n+n) = \mathcal{O}(n)$.
-
-    \item[(g)]
-      \textbf{Von welcher Ordnung (Landau-Symbol) ist Ihre effizientere Funktion?\\
-      Begründen Sie Ihre Antwort.}
-
-      In beiden o.\,a.\ Lösungsvarianten
-      -- \gitfile{hp}{2020ws/20210107}{loesung-2e-1.c}
-      und \gitfile{hp}{2020ws/20210107}{loesung-2e-2.c} --
-      arbeitet die Funktion mit einer einzigen Schleife,
-      die gleichzeitig die Zahlenwerte addiert und das Ende des Strings sucht.
-
-      Mit jeweils einer einzigen Schleife
-      haben beide Funktionen die Ordnung $\mathcal{O}(n)$.
+      \textbf{Wozu dient das \lstinline{while (1)}?}
 
-  \end{itemize}
+      Mit dem \lstinline{return}-Befehl am Ende des Hauptprogramms
+      gibt das Programm die Kontrolle an das Betriebssystem zurück.
 
-  \exercise{Hexdumps}
-
-  Das folgende Programm (\gitfile{hp}{2020ws/20210107}{aufgabe-2.c}) liest
-  einen String ein und gibt die ASCII-Werte der Buchstaben hexadezimal aus.
-  (Anders als z.\,B.\ \lstinline{scanf()}
-  akzeptiert die Funktion \lstinline{fgets()} zum Lesen von Strings auch Leerzeichen,
-  und sie vermeidet Pufferüberläufe.)
-  \begin{lstlisting}[style=numbered]
-    #include <stdio.h>
-
-    int main (void)
-    {
-      char buffer[100];
-      fgets (buffer, 100, stdin);
-      for (char *p = buffer; *p; p++)
-        printf ("%02x", *p);
-      printf ("\n");
-    }
-  \end{lstlisting}
-  Beispiel: Bei der Eingabe von \lstinline[style=cmd]{Dies ist ein Test.}
-  erscheint die Ausgabe\\
-  \lstinline[style=terminal]{44696573206973742065696e20546573742e0a}.
-
-  Schreiben Sie ein Programm, das diese Umwandlung in umgekehrter Richtung vornimmt,
-  also z.\,B.\ bei Eingabe von \lstinline[style=cmd]{44696573206973742065696e20546573742e0a}
-  wieder \lstinline[style=terminal]{Dies ist ein Test.} ausgibt.
-
-  \points{6}
-
-  Hinweis für die Klausur:
-  Abgabe in digitaler Form ist erwünscht, aber nicht zwingend.
+      Dieses Programm jedoch läuft auf einem Mikrocontroller,
+      auf dem es kein Betriebssystem gibt.
+      Wenn das \lstinline{return} ausgeführt würde,
+      hätte es ein undefiniertes Verhalten zur Folge.
 
-  \solution
+      Um dies zu verhindern, endet das Programm in einer Endlosschleife,
+      mit der wir den Mikrocontroller anweisen,
+      nach der Ausführung des Programms \emph{nichts mehr\/} zu tun
+      (im Gegensatz zu: \emph{irgendetwas Undefiniertes\/} zu tun).
 
-  Siehe \gitfile{hp}{2020ws/20210107}{loesung-2.c}.
-
-  Das Programm macht mehrfach davon Gebrauch,
-  daß in C Zeichen und Zahlen äquivalent sind.
-  Wenn z.\,B.\ die \lstinline{char}-Variable \lstinline{c}
-  den Wert \lstinline{'3'} (Ziffer 3) enthält,
-  dann hat der Ausdruck \lstinline{c - '0'} den Wert \lstinline{3} (Zahlenwert 3).
-  Hierfür ist es insbesondere nicht nötig, vorauszusetzen,
-  daß wir den ASCII-Zeichensatz verwenden und \lstinline{'0'}
-  den Wert \lstinline{48} hat.
-
-  Bei Eingabe von \lstinline[style=cmd]{44696573206973742065696e20546573742e0a}
-  gibt das Programm zusätzlich eine Leerzeile aus.
-  Die liegt daran, daß das \lstinline[style=cmd]{0a} am Ende
-  bereits eine Zeilenschaltung enthält und das Programm mit
-  \lstinline{printf ("\n")} eine zusätzliche Zeilenschaltung ausgibt.
+  \end{itemize}
 
 \end{document}
diff --git a/20210114/hp-uebung-20210114.pdf b/20210114/hp-uebung-20210114.pdf
index 9afd3ffcd9d2f7db7bdc28cf1ebfeb186060650d..0ae342976a00e5c500c3c9a39d463bd4650869f9 100644
Binary files a/20210114/hp-uebung-20210114.pdf and b/20210114/hp-uebung-20210114.pdf differ
diff --git a/20210114/hp-uebung-20210114.tex b/20210114/hp-uebung-20210114.tex
index c1af612e29887e3ab2b8c650a00a5e526fcc368c..eb358f56632229ddaa946ea6b758195c0785c8dc 100644
--- a/20210114/hp-uebung-20210114.tex
+++ b/20210114/hp-uebung-20210114.tex
@@ -114,7 +114,7 @@
         von oben nach unten an die Bits Nr.\ 0 bis 7.
     \end{itemize}
 
-    Wir betrachten das folgende Programm (\gitfile{hp}{2019ws/20191121}{aufgabe-2.c}):
+    Wir betrachten das folgende Programm (\gitfile{hp}{2020ws/20210114}{aufgabe-2.c}):
 
     \begin{lstlisting}[gobble=6]
       #include <avr/io.h>
@@ -161,105 +161,6 @@
     \end{itemize}
   \end{minipage}
 
-  \exercise{LED-Blinkmuster}
-
-  Wir betrachten das folgende Programm für einen ATmega32-Mikro-Controller
-  (Datei: \gitfile{hp}{2019ws/20191128}{aufgabe-3.c}).
-
-  \begin{minipage}[t]{7cm}
-    \begin{lstlisting}[gobble=6]
-      #include <stdint.h>
-      #include <avr/io.h>
-      #include <avr/interrupt.h>
-
-      uint8_t counter = 1;
-      uint8_t leds = 0;
-
-      ISR (TIMER0_COMP_vect)
-      {
-        if (counter == 0)
-          {
-            leds = (leds + 1) % 8;
-            PORTC = leds << 4;
-          }
-        counter++;
-      }
-    \end{lstlisting}
-  \end{minipage}\hfill\begin{minipage}[t]{8.5cm}
-    \begin{lstlisting}[gobble=6]
-      void init (void)
-      {
-        cli ();
-        TCCR0 = (1 << CS01) | (1 << CS00);
-        TIMSK = 1 << OCIE0;
-        sei ();
-        DDRC = 0x70;
-      }
-
-      int main (void)
-      {
-        init ();
-        while (1)
-          ; /* do nothing */
-        return 0;
-      }
-    \end{lstlisting}
-  \end{minipage}
-
-  An die Bits Nr.\ 4, 5 und 6 des Output-Ports C des Mikro-Controllers sind LEDs angeschlossen.\\
-  Sobald das Programm läuft, blinken diese in charakteristischer Weise:
-  \begin{quote}
-    \newcommand{\tdn}[1]{\raisebox{-2pt}{#1}}
-    \begin{tabular}{|c|c|c|c|}\hline
-      \tdn{Phase} & \tdn{LED oben (rot)} & \tdn{LED Mitte (gelb)} & \tdn{LED unten (grün)} \\[2pt]\hline
-      1 & aus & aus & an  \\\hline
-      2 & aus & an  & aus \\\hline
-      3 & aus & an  & an  \\\hline
-      4 & an  & aus & aus \\\hline
-      5 & an  & aus & an  \\\hline
-      6 & an  & an  & aus \\\hline
-      7 & an  & an  & an  \\\hline
-      8 & aus & aus & aus \\\hline
-    \end{tabular}
-  \end{quote}
-  Jede Phase dauert etwas länger als eine halbe Sekunde.
-  Nach 8 Phasen wiederholt sich das Schema.
-
-  Erklären Sie das Verhalten des Programms anhand des Quelltextes:
-  \vspace{-\medskipamount}
-  \begin{itemize}\itemsep0pt
-    \item[(a)]
-      Wieso macht das Programm überhaupt etwas,
-      wenn doch das Hauptprogramm nach dem Initialisieren lediglich eine Endlosschleife ausführt,
-      in der \emph{nichts} passiert?
-      \points{1}
-    \item[(b)]
-      Wieso wird die Zeile \lstinline|PORTC = leds << 4;| überhaupt aufgerufen,
-      wenn dies doch nur unter der Bedingung \lstinline|counter == 0| passiert,
-      wobei die Variable \lstinline|counter| auf 1 initialisiert,
-      fortwährend erhöht und nirgendwo zurückgesetzt wird?
-      \points{2}
-    \item[(c)]
-      Wie kommt das oben beschriebene Blinkmuster zustande?
-      \points{2}
-    \item[(d)]
-      Wieso dauert eine Phase ungefähr eine halbe Sekunde?
-      \points{2}
-    \item[(e)]
-      Was bedeutet "`\lstinline|ISR (TIMER0_COMP_vect)|"'?
-      \points{1}
-  \end{itemize}
-
-  Hinweis:
-  \vspace{-\medskipamount}
-  \begin{itemize}\itemsep0pt
-    \item
-      Die Funktion \lstinline|init()| sorgt dafür, daß der Timer-Interrupt Nr.\ 0 des Mikro-Controllers
-      etwa 488mal pro Sekunde aufgerufen wird.
-      Außerdem initialisiert sie die benötigten Bits an Port C als Output-Ports.
-      Sie selbst brauchen die Funktion \lstinline|init()| nicht weiter zu erklären.
-  \end{itemize}
-
   \begin{flushright}
     \textit{Viel Erfolg!}
   \end{flushright}