\chapter{Die Hardware der AVR 8-Bit Mikrocontroller}

\section{CPU und Speicherzugriff}
Auf dem Chip der AVR 8-Bit Mikrocontroller ist alles vereinigt,
was ein digitaler Minirechner zum Arbeiten braucht.
Es ist ein Taktgenerator, Register, Arbeitsspeicher (RAM), Programmspeicher (Flash),
Eingaberegister und Ausgaberegister vorhanden. 
Der Inhalt von Registern und Arbeitsspeicher geht bei jedem Neustart verloren.
Der Inhalt des Programmspeicher (Flash) und auch des meistens zusätzlich vorhandenem
Datenspeicher (EEprom) bleiben aber erhalten.
Die Abbildung~\ref{fig:block} zeigt ein vereinfachtes Blockdiagramm eines
8-Bit AVR Mikrocontrollers.

\begin{figure}[H]
\centering
\includegraphics[]{../FIG/avr_block.eps}
\caption{Vereinfachtes Blockschaltbild eines AVR-Mikrocontrollers}
\label{fig:block}
\end{figure}

Aus dem Diagramm ist zu entnehmen, daß die
CPU (Central Processor Unit) sehr leicht auf die Register R0-R31 und
auf den RAM-Speicher zugreifen kann. Auch der Zugriff auf die
Eingabe (Input) oder Ausgabe (Output) Register ist leicht möglich.
Der Zugriff auf den Programmspeicher (Flash) ist dagegen nur über
den zugehörigen Controller möglich und deutlich komplizierter.

Nur die eigentliche Befehls-Ausführungseinheit kann einfach auf
die Daten des Flash Speichers für die eingestellte Programm-Adresse zugreifen.
Mit dem Load Immediate Befehl (LDI) können dann auch Bestandteile des 
16-Bit Befehls-Wortes zu den oberen Registern (R16-R31) transferiert werden. 
Auch bei den Befehlen ADIW, ANDI, CPI, ORI, SBCI, SBIW und SUBI werden Teile
des 16-Bit Befehls-Wortes verarbeitet.

Normalerweise wird bei der Programmausführung die Flash-Adresse
je nach Befehls-Größe um ein Wort oder zwei Worte erhöht.
Eine Ausnahme hiervon sind bei der normalen Programm-Abarbeitung nur
die bedingten oder unbedingten (RJMP, JMP, IJMP, RCALL, CALL, ICALL, RET, RETI) Sprung-Anweisungen.

Außerdem kann ein Reset Ereignis oder ein Unterbrechungs-Signal (Interrupt)
für eine Abweichung von der Regel führen.
Beim Reset wird der Prozessor zurückgesetzt und der Programm-Zähler auf eine
vorher eingestellte Adresse gesetzt.
Bei einem Interrupt wird der Programm-Zähler auf die dem
Ereignis zugehörende Adresse einer Sprungtabelle gesetzt.
Normalerweise ist die Start-Adresse für das Reset Ereignis die Adresse 0.
Für Bootloader-Zwecke kann dies aber bei vielen AVR-Prozessoren mit speziellen
Konfigurations-Bits (Fuse) anders eingestellt werden.

Ein wahlfreier Lesezugriff zum Programmspeicher ist nur über den Flash-Controller
möglich. Dabei muß dem Controller erst die gewünschte Byte-Adresse mitgeteilt werden.
Erst dann ist ein Lesen des Datenbytes mit einem Spezial-Befehl möglich.


Noch komplizierter wird es beim Schreibzugriff. Der Schreibzugriff des Programmspeichers
ist nur seitenweise möglich. Die Flash-Speicherseite muß vor jedem Beschreiben
vorher gelöscht sein. Die neuen Daten für eine Flash-Seite müssen vor dem
Beschreiben komplett in den Zwischenspeicher des Flash-Controllers geladen werden.
Erst dann kann der Controller mit dem Neubeschreiben der Flash-Seite beauftragt werden.
Dieses Verfahren läßt sich anschaulich mit dem Bedrucken einer Seite mit einem
Stempel vergleichen. Der Stempel kann mit austauschbaren Zeichen bestückt werden,
so daß jeder Text möglich ist. Für das Stempeln der Information muß aber
eine leere Papierseite vorhanden sein und der Stempel muß zuerst mit den
Zeichen für den Text bestückt sein.
Erst dann kann mit einem Stempeldruck die leere Seite neu beschrieben werden.

Auch der EEprom Speicher (nicht flüchtiger Speicher für Daten) wird über
einen speziellen Controller zugegriffen. Hier ist das Beschreiben des Speichers
aber etwas einfacher, ist aber auch nur über einen Controller möglich.
Der EEprom-Controller kann nicht zusammen mit dem Flash-Controller benutzt werden,
da die Controller wohl gemeinsame Teile haben.

\section{Eingabe und Ausgabefunktion}

Über die IO-Register kann die CPU auf die externen Pins zugreifen. Die Register
sind Byte weise (8-Bit) organisiert, so daß mit einem Register bis zu 8~Pins
angesprochen werden können. Die Abbildung~\ref{fig:port} zeigt den 
Aufbau einer Port Pin Beschaltung.

\begin{figure}[H]
\centering
\includegraphics[]{../FIG/port.eps}
\caption{Vereinfachtes Schaltbild jedes AVR-Portpins}
\label{fig:port}
\end{figure}

Jeder Pin ist mit einem Port Bit fest verknüpft und kann normalerweise sowohl
als Ausgangs-Pin (PORT) als auch als Eingangs-Pin (PIN) verschaltet werden.
Zur Umschaltung der Funktion der 8~Bits eines Ports dienen die 8~Bits des
Data~Direction~Registers DDR.
Es gibt also für jeden Pin eine zugeordnete Bitnummer in drei verschiedenen
Registern. Mit dem DDR Register kann die Datenrichtung für jedes des zugeordneten
Pins umgeschaltet werden. Das PIN Register gibt den Zustand der Spannung an
den 8 Eingangspins an. Unterhalb etwa der halben Betriebsspannung wird eine
0 angezeigt, darüber eine 1. Wenn das dem Pin zugehörige DDR Bit auf Ausgang (1)
geschaltet ist, wird mit dem zugehörigen PORT Bit der Ausgang auf 0~V oder
auf Betriebsspannung (VCC) geschaltet. 
Bei mit dem auf 0 gesetzten DDR Bit inaktiviertem Ausgang wird je nach Zustand
des zugehörigen PORT Bits ein Pull-Up Widerstand für diesen Pin zugeschaltet
(PORT Bit = 1) oder nicht (PORT Bit = 0). Wenn allerdings das PUD Bit im
MCU Konfigurations-Register MCUCR gesetzt ist, bleiben alle internen Pull-Up
Widerstände inaktiv.
Alle zugehörigen Register und Bits einer Gruppe (8-Bit) benutzen immer den
gleichen Kennbuchstaben. Also für die zweite Gruppe wäre der Buchstabe ein B.
Der Ausgabe Port würde also PORTB heißen, der Eingangs Port würde PINB heißen
und das Register für die Datenrichtung DDRB. Für die Bezeichnung der einzelnen
Bits wird jeweils eine Ziffer 0-7 angehängt. Zum Beispiel würde das Bit 0
des Eingangs Ports dann PINB0 heißen.
Diese Bezeichnungsweise wird so in der Beschreibung der Hardware von Atmel verwendet
und wird üblicherweise auch innerhalb von Programmiersprachen so verwendet.

\section{Das Starten des AVR Mikrocontrollers}

In der vom Werk ausgelieferten Konfiguration des Mikrocontrollers löst das erste 
Erreichen der erforderlichen Betriebsspannung einen Reset des Prozessors aus.
Dabei werden die IO-Register auf vorbestimmte Werte gesetzt, noch etwas Zeit
zur Stabilisierung der Betriebsspannung gewartet und dann der Befehl ausgeführt,
der auf der Adresse 0 des Flash-Speichers steht.
In aller Regel sind die Ausgabe-Funktionen aller Pins in diesem Zustand abgeschaltet.
Außer diesem Einschalt-Reset gibt es noch drei weitere Gründe für einen Reset
des Prozessors. Der Grund für den Reset wird in einem MCU Status-Register (MCUSR)
mit 4 Bits festgehalten.

\begin{table}[H]
  \begin{center}
    \begin{tabular}{| c | c |}
    \hline
              Name des Flags & Grund für den Reset \\
    \hline
    \hline
              PORF & Power-on Reset \\
                   & Dieser Reset wird beim ersten Erreichen der Betriebsspannung ausgelöst.\\
                   & Dieser Grund kann nicht abgeschaltet werden.\\
    \hline
              BORF & Brown-out Reset \\
                   & Der Reset wegen Spannungseinbruch kann nur dann vorkommen, \\
                   & wenn die Funktion mit den BODLEVEL Bits in dem Fuse-Bit \\
                   & freigeschaltet ist und kein Brown-out Interrupt benutzt wird.\\
    \hline
              EXTRF & External Reset \\
                    & Wird ausgelöst durch Pegel 0 am Reset Pin, \\
                    & wenn RSTDISBL nicht konfiguriert wurde. \\
    \hline
              WDRF & Watchdog Reset \\
		   & Wird nur ausgelöst, wenn der zugehörige Interrupt \\
		   & nicht freigeschaltet wurde. \\
    \hline
    \end{tabular}
  \end{center}
  \caption{Die verschiedenen Reset Gründe im MCUSR Register}
  \label{tab:resets}
\end{table}

Durch Setzen der entsprechenden Konfigurations-Bits in den Fuses des AVR-Mikrocontrollers
kann die Start-Adresse abweichend von 0 eingestellt werden.
Die Abbildung~\ref{fig:pages} zeigt die Möglichkeiten für den ATmega168.
Dieser Prozessor hat insgesamt 16384~Byte Arbeitsspeicher (Flash).
Der Befehls-Interpreter des Mikrocontrollers greift übrigens auf
einen 16-Bit breiten Befehlscode des Flash Speicher zu.
Deshalb ist der höchste Programm-Zähler Wert nur 8190!
Das es nicht 8192 ist, ist klar, weil ja die Zählung bei 0 beginnt,
aber es ist noch ein Wort weniger, weil das letzte Wort im Flash Speicher
für die Versionsnummer von Optiboot verwendet wird.

\begin{figure}[H]
\centering
\includegraphics[width=12cm]{../FIG/boot_pages.eps}
\caption{Verschiedene Start-Möglichkeiten für den ATmega168}
\label{fig:pages}
\end{figure}


Als mögliche Bootloader-Größen unterstützt der ATmega168 256~Bytes (BOOTSZ=3),
512~Bytes (BOOTSZ=2), 1024~Bytes (BOOTSZ=1) und 2048~Bytes (BOOTSZ=0).
Für das Anwenderprogramm ist natürlich interessant, den Bootloader-Bereich
möglichst klein zu wählen, damit möglichst viel Speicherplatz für das
Anwenderprogramm zur Verfügung steht.
Der Bootloader wird ja immer auf die höchstmögliche Start-Adresse platziert.
Durch Programmieren der Lock-Bits des AVR-Mikrocontrollers läßt sich
der Bootloader-Bereich  gegen Überschreiben sichern. Die einmal installierte
Sicherung des Flash-Speichers läßt sich dann aber nur durch komplettes Löschen (erase)
des AVR Speichers wieder zurücksetzen.


Für diesen Prozessor, wie auch für den Mega48 und Mega88, befinden sich
die Steuerbits für den Bootloader Start in der extended Fuse.
Dies gilt auch für die BOOTRST Fuse, mit der die Startadresse von 0
auf den Bootloader Start umgeschaltet wird.
Für viele andere AVR Mikrocontroller, auch dem ATmega328, befinden sich
die gleichen Steuerbits in der high Fuse.
Die Tabelle~\ref{tab:bootsz} zeigt die Speichergrößen für verschiedene
AVR-Mikrocontroller sowie die Möglichkeiten für den Bootloader-Bereich. 
Die verwendeten Bit-Nummern für die Bootloader Einstellung sind übrigens
die gleichen, egal ob high oder extended Fuse Register.

\begin{table}[H]
  \begin{center}
    \begin{tabular}{| c | c | c | c | c | c | c | c | c | c |}
    \hline
             Processor & Flash & EEprom & RAM & UART & Boot   & \multicolumn{4}{ c| }{BOOTSZ} \\
              Typ      & Größe & Größe  & Größe &    & Config & \multicolumn{4}{ c| }{} \\
                       &       &        &     &      & Fuse   &   =3 &   =2 &   =1&   =0 \\
    \hline
    \hline
              ATmega48  & 4K    & 256  & 512  &  1   & Ext.  & 256  & 512 & 1K  & 2K  \\
    \hline
              ATtiny84  & 8K    & 512  & 512  &  -   &  -    &  \multicolumn{4}{ c| }{(N x 64)} \\
    \hline
              ATmega8   & 8K    & 512  & 1K   &  1   & High  & 256  & 512 & 1K  & 2K  \\
    \hline
              ATmega88  & 8K    & 512  & 1K   &  1   & Ext.  & 256  & 512 & 1K  & 2K  \\
    \hline
              ATmega16  & 16K   & 512  & 1K   &  1   & High  & 256  & 512 & 1K  & 2K  \\
    \hline
              ATmega168 & 16K   & 512  & 1K   &  1   & Ext.  & 256  & 512 & 1K  & 2K  \\
    \hline
              ATmega164 & 16K   & 512  & 1K   &  1   & High  & 256  & 512 & 1K  & 2K  \\
    \hline
              ATmega32  & 32K   & 1K   & 2K   &  1   & High  & 512  & 1K  & 2K  & 4K  \\
    \hline
              ATmega328 & 32K   & 1K   & 2K   &  1   & High  & 512  & 1K  & 2K  & 4K  \\
    \hline
              ATmega324 & 32K   & 1K   & 2K   &  2   & High  & 512  & 1K  & 2K  & 4K  \\
    \hline
              ATmega644 & 64K   & 2K   & 4K   &  2   & High  & 1K   & 2K  & 4K  & 8K  \\
    \hline
              ATmega640 & 64K   & 4K   & 8K   &  4   & High  & 1K   & 2K  & 4K  & 8K  \\
    \hline
             ATmega1284 & 128K  & 4K   & 16K  &  2   & High  & 1K   & 2K  & 4K  & 8K  \\
    \hline
             ATmega1280 & 128K  & 4K   & 8K   &  4   & High  & 1K   & 2K  & 4K  & 8K  \\
    \hline
             ATmega2560 & 262K  & 4K   & 8K   &  4   & High  & 1K   & 2K  & 4K  & 8K  \\
    \hline
    \end{tabular}
  \end{center}
  \caption{Bootloader Konfigurationen für verschiedene Mikrocontroller}
  \label{tab:bootsz}
\end{table}

Übrigens funktioniert ein Bootloader selbst dann beim ersten Mal, wenn
das BOOTRST Fuse Bit nicht gelöscht wurde. Dann steht der Reset-Vektor
immer noch auf Adresse 0, auf den normalerweise das Anwenderprogramm steht.
Da aber noch kein Anwenderprogramm geladen wurde, läuft die CPU
durch den Flash Speicher, bis er auf den Bootloader-Code trifft.
Bei diesem Prozessor sind das weniger als 8000 Befehle, die die CPU bei
8~MHz Taktrate in weniger als 1~ms durchläuft.
Sobald aber ein Anwenderprogramm geladen wurde, startet mit einem Reset
immer das Anwenderprogramm, solange das BOOTRST Bit gesetzt bleibt.
Der Bootloader würde mit gesetztem BOOTRST Bit nicht mehr funktionieren,
weil er gar nicht mehr angesprochen wird.


\section{Das Beschreiben des AVR Speichers}

Die AVR Mikrocontroller kennen 3 verschiedene nicht flüchtige Speicher.
Der wichtigste ist der Programmspeicher, der sogenannte Flash-Speicher.


Daneben gibt es noch einige Konfigurationsbits, mit denen die Eigenschaften
des Prozessors eingestellt werden können.
Diese sind Konfigurationsbits sind aufgeteilt in mehrere Bytes, die lfuse (low Fuse),
hfuse (high Fuse), efuse (extended Fuse), das lock-Byte und das Kalibrations-Byte.
Das Kalibrations-Byte dient dem Frequenz-Abgleich des internen RC-Oszillators.
Mit dem lock-Byte können Zugriffe auf die Speicher gesperrt werden.
Beim lock-Byte lassen sich einmal aktivierte Bits nicht wieder zurücksetzen.
Der einzige Weg, einmal gesetzte lock-Bits wieder zurückzusetzen, ist ein komplettes
Löschen aller AVR-Speicher. Beim lock-Byte werden die Schutzfunktionen durch Löschen 
von entsprechenden Bits auf 0 aktiviert.
Im gelöschten Zustand des AVR-Mikrocontrollers sind alle wirksamen Bits des lock-Bytes auf 1 gesetzt.
Die Aufteilung des Konfigurationsbits auf die verschiedenen Fuse-Bytes unterscheidet
sich für die verschiedenen Prozessor-Modelle und sollte im jeweiligen Datenblatt nachgelesen werden.
Mit den Konfigurationsbits lassen sich Art der Taktgewinnung für den Prozessor, eine
Startverzögerung und eine Betriebsspannungsüberwachung einstellen.


Die meisten AVR Mikrocontroller verfügen auch über einen nicht flüchtigen Datenspeicher,
das EEprom. Dieser Speicher hat keine spezielle Aufgabe für den Prozessor. Es ist lediglich
eine Möglichkeit, Daten für den nächsten Programmstart festzuhalten.

\subsection{parallele Programmierung}
Alle drei Speicherarten können mit verschiedenen Methoden beschrieben und auch gelesen werden.
Normalerweise wird die parallele Methode zum Beschreiben der nicht flüchtigen Speicher eher
selten verwendet. Manchmal hilft diese Methode aber Prozessoren wieder zu beleben,
die mit anderen Methoden nicht mehr ansprechbar sind.
Beispielsweise funktioniert die serielle Programmierung dann nicht mehr, wenn mit den Fuse-Bits
die Funktion des Reset-Pins abgeschaltet wurde.
Diese Methode ist daran zu erkennen,
daß bei der Programmierung der Reset Eingangspin auf höhere Spannungswerte (12V) gesetzt wird.
Deshalb heißt diese Methode auch HV-Programmierung.
Einzelheiten zu dieser Programmierung sollten dem jeweiligen Datenblatt entnommen werden.

\subsection{serieller Download mit ISP}

Der normale Weg zum Programmieren des nicht flüchtigen Speichers ist die serielle Programmierung.
Die Atmel Dokumentation spricht auch von Serial Downloading. Dabei wird eine SPI (Serial Parallel Interface)
Schnittstelle verwendet.
Die SPI Schnittstelle besteht aus drei Signalen, MOSI, MISO und SCK.
Damit der Prozessor überhaupt diese spezielle Art der Programmierung benutzt, ist außerdem
das Reset Signal erforderlich, das auf 0 gehalten werden muß.
Zusammen mit den Betriebsspannungs Signalen GND und VCC (etwa 2.7V bis 5V) ergibt sich eine
Schnittstelle, die oft bereits auf einer Platine integriert ist, die ISP (In System Programming) 
Schnittstelle. Die Abbildung~\ref{fig:ISP} zeigt zwei gebräuchliche Stecker, die auf
Platinen mit AVR Mikrocontrollern integriert sind.

\begin{figure}[H]
\centering
\includegraphics[width=12cm]{../FIG/ISP.eps}
\caption{Zwei verschiedene Arten von ISP Steckern}
\label{fig:ISP}
\end{figure}

Bei der 10-poligen Variante des ISP-Steckers kann zusätzlich das Takt Signal OSC für die Versorgung
des AVR mit einem Takt aufgelegt sein.
Einer dieser beiden Stecker ist also in der Regel erforderlich, um einen neuen Bootloader in den
Flash-Speicher eines AVR-Mikrocontrollers zu schreiben. Die Daten für den Flash-Speicher werden
im allgemeinen auf einem PC erzeugt.
Für das Transferieren der Daten zum AVR-Mikrocontroller ist ein ISP-Programmer
erforderlich, der meistens zur Rechnerseite hin über einen USB-Anschluss verfügt. Es ist aber auch
ein Anschluss des ISP-Programmers über eine serielle oder parallele Schnittstelle möglich.
Die USB-Schnittstelle hat aber den Vorteil, daß auch die Stromversorgung (5V oder 3.3V) für
dem Mikrocontroller direkt über die Schnittstelle zur Verfügung gestellt wird.
Es gibt auf dem Markt eine Auswahl an solchen ISP-Programmern, von Atmel wird beispielsweise der 
AT AVR-ISP MK2 Programmer angeboten.
Auch die Verwendung eines Arduino UNO oder eines anderen Arduino ist mit
Spezialprogramm für eine angeschlossene ISP-Schnittstelle  möglich.
Ich selbst verwende einem DIAMEX ALL-AVR, der über beide 
ISP-Steckervarianten verfügt und einige Zusatzfunktionen hat.

\subsection{Selbstprogrammierung mit serieller Schnittstelle}

Da der AVR-Prozessor den Flash und EEprom Speicher auch selbst beschreiben kann, kann man
mit einer der beiden anderen Methoden ein kleines Programm in den Flash-Speicher laden,
der Daten über eine serielle Schnittstelle empfängt und diese Daten in den Flash- oder
auch EEprom-Speicher schreibt. Genau das macht der Bootloader Optiboot.
Das Setzen der Fuses oder des Lock-Bytes ist mit dieser Methode oft nicht möglich und
wird auch vom Bootloader nicht unterstützt. Die Fuses und das Lock-Byte müssen also
immer mit einer der anderen Methoden geschrieben werden.
Für die Übermittlung der Daten werden Teile des STK500 Communication Protocol von Atmel verwendet.
Da moderne Rechner meist nicht mehr über serielle Schnittstellen verfügen, wird heute 
meistens ein USB - Seriell UART Wandler wie beispielsweise das FTDI Chip von Future Technology Devices
International Ltd verwendet. Ein Modul mit diesem Wandler-Chip ist z.B. das UM232R.
Die Chips PL2303 von Prolific Technology Inc. und CP2102 von Silicon Laboratories Inc. 
erfüllen wohl den gleichen Zweck.
Von Atmel kann ein entsprechend programmierter ATmega16U2 auch
diese Aufgabe übernehmen. 
Alle Chips haben eine einstellbare Baud-Rate und haben TTL-Pegel für die Signale.
Für echte RS232 Signale müßten noch Pegelwandler verwendet werden.
Die sind aber für die AVR Mikrocontroller nicht notwendig.
Einer dieser Chips ist auf den Arduino Platinen mit USB-Schnittstelle integriert.
Für eine schnelle Reaktion auf die Programm-Datenübertragung sollte das DTR-Signal des
Schnittstellenwandlers über einen 100nF Kondensator mit dem Reset Eingang des AVR-Prozessors
verbunden sein. Die Abbildung~\ref{fig:UM232} zeigt eine typische Anschlussart.

\begin{figure}[H]
\centering
\includegraphics[width=12cm]{../FIG/UM232.eps}
\caption{Anschluss eines USB-seriell Wandlers an den Mikrocontroller}
\label{fig:UM232}
\end{figure}

Bei der Verwendung von USB-seriell Modulen sollte auf die richtige Wahl der Betriebsspannung
geachtet werden. Viele Module können auf 3.3V oder 5V Signalpegel gestellt werden (Jumper).
Wenn man einen Arduino UNO mit gesockeltem ATmega328p besitzt, kann man den ATmega328p 
entfernen und das Board als USB-seriell Wandler benutzen. 
So kann man dann auch die Programmdaten zu einem anderen AVR-Prozessor übertragen.
Bei häufigem Gebrauch ist natürlich ein separates USB-seriell Modul sinnvoll.
Die beiden 1~nF Kondensatoren an den RX-Eingängen filtern Impulsspitzen weg. Der Test
des Software-UART Programms war nur erfolgreich mit einem kleinen Kondensator am RX Eingang
des AVR Prozessors. Die Tastspitze eines Oszilloskops war aber als ,,Filter'' schon ausreichend.
Die Hardware-UART Schnittstelle filtert wohl besser und läuft mit und ohne Kondensator einwandfrei.

Bei der Arduino Entwicklungsumgebung Sketch ist unter ,,Tools - serieller Port'' die Möglichkeit vorgesehen,
eine serielle Schnittstelle auszuwählen. Weiter kann dann unter ,,Tools - Serial Monitor'' ein Kontrollfenster
geöffnet werden, welches die seriellen Ausgaben des AVR Mikrocontrollers auf dem Bildschirm darstellen
kann. Die Baud-Rate der seriellen Schnittstelle kann in diesem Fenster eingestellt werden.
Der laufende Serial Monitor des Arduino Sketch stört aber das Laden von Programmen über die serielle
Schnittstelle, wenn das gleiche USB-Seriell Wandlermodul verwendet wird.
Es gibt aber die Möglichkeit, ein weiteres USB-Seriell Modul in den PC einzustecken und bei diesem
nur das RX-Signal an den TX-Port des AVR-Mikrocontrollers anzuschließen.
Dieser zweite serielle Eingang horcht so die Ausgaben des AVR mit und stört dabei die serielle 
Kommunikation beim Programm-laden nicht, wenn diese Schnittstelle für den Serial Monitor gewählt wird.

\subsection{Diagnose Werkzeuge}
Unter dem Linux-Betriebssystem gibt es ein Werkzeug (Tool) mit dem seltsamen Namen jpnevulator, mit dem
zwei serielle Eingänge zur selben Zeit überwacht werden können.
Die übertragenen Daten werden im sedezimal (hex) Format dargestellt und mit der Option -a auch als ASCII-Zeichen.
Mit der Option --timing-print werden die System-Zeiten der empfangenen seriellen Datenpakete gezeigt.
Um eine Beeinflussung des Datenverkehrs beim Laden von Programmdaten auszuschließen, sollten
zwei separate USB-Seriell Module für die Überwachung benutzt werden.
Der serielle Eingang eines Moduls wird an das TX-Signal und der serielle Eingang des anderen Moduls
an das RX-Signal des AVR-Mikrocontrollers angeschlossen.
Zusammen mit dem Modul für das Programmladen sind dann drei solche Module an den PC angeschlossen.
Natürlich müssen alle drei Module auf die gleiche Baudrate eingestellt sein (stty ... -F /dev/ttyUSB1).
Der komplette Aufruf für das Werkzeug mit dem Beginn der Ausgaben könnte beispielsweise so aussehen:
\begin{verbatim}
jpnevulator -a --timing-print --read --tty "/dev/ttyUSB1" --tty "/dev/ttyUSB2"
2016-05-29 11:05:06.589614: /dev/ttyUSB0
30 20                                           0
2016-05-29 11:05:06.589722: /dev/ttyUSB1
14 10                                           ..
2016-05-29 11:05:06.593593: /dev/ttyUSB0
41 81 20                                        A.
2016-05-29 11:05:06.594581: /dev/ttyUSB1
14 74 10                                        .t.
2016-05-29 11:05:06.597583: /dev/ttyUSB0
41 82 20                                        A.
2016-05-29 11:05:06.598574: /dev/ttyUSB1
14 02 10                                        ...
2016-05-29 11:05:06.601586: /dev/ttyUSB0
42 86 00 00 01 01 01 01 03 FF FF FF FF 00 80 04 B...............
00 00 00 80 00 20                               .....
2016-05-29 11:05:06.603608: /dev/ttyUSB1
14 10                                           ..
2016-05-29 11:05:06.605639: /dev/ttyUSB0
45 05 04 D7 C2 00 20                            E.....
2016-05-29 11:05:06.606576: /dev/ttyUSB1
14 10                                           ..
...
\end{verbatim}
