<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
	<id>https://www.mikrocontroller.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Frankalicious</id>
	<title>Mikrocontroller.net - Benutzerbeiträge [de]</title>
	<link rel="self" type="application/atom+xml" href="https://www.mikrocontroller.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Frankalicious"/>
	<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/articles/Spezial:Beitr%C3%A4ge/Frankalicious"/>
	<updated>2026-04-13T02:33:37Z</updated>
	<subtitle>Benutzerbeiträge</subtitle>
	<generator>MediaWiki 1.39.7</generator>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Mikrocontroller.net:Impressum&amp;diff=104459</id>
		<title>Mikrocontroller.net:Impressum</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Mikrocontroller.net:Impressum&amp;diff=104459"/>
		<updated>2021-06-04T10:48:24Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: Änderung 104458 von 172.26.40.146 (Diskussion) rückgängig gemacht.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Rechtliches=&lt;br /&gt;
&lt;br /&gt;
==Lizenz für die hier veröffentlichten Beiträge==&lt;br /&gt;
Alle Beiträge dieses Wikis stehen automatisch unter der&lt;br /&gt;
[http://creativecommons.org/licenses/by-sa/2.0/de/ Creative Commons Share-Alike Lizenz].&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
[http://www.mikrocontroller.net/contact Impressum von www.mikrocontroller.net]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=KiCad&amp;diff=100357</id>
		<title>KiCad</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=KiCad&amp;diff=100357"/>
		<updated>2019-02-27T14:10:04Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: /* Eeschema */ fix typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Wegen eines Umbaus dieser Seite bitte unter Diskussion lesen!&#039;&#039;&#039; [[Diskussion:KiCad#Seitenumbau]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;KiCad&#039;&#039;&#039; ist ein Open Source [[Schaltplaneditoren|Schaltplaneditor]] und PCB Layoutprogramm für Windows, Linux, Mac OSX. &lt;br /&gt;
Diese Seite ist zunächst eine Zusammenfassung aus den KiCad Beiträgen im Forum. Und gleich zu Anfang ein grosses DANKE an alle KiCad-User aus dem Forum. Ihr seid zu viele, um jeden einzeln zu nennen. Aber wer sich diese Seite durchliest und den Links folgt, wird euch kennenlernen.  &lt;br /&gt;
&lt;br /&gt;
Hier sollen alte und neue KiCad-Anwender einen Anlaufpunkt finden und neue, insbesondere µC-relevante Aktivitäten stattfinden. &lt;br /&gt;
&lt;br /&gt;
Diese Seite will keine Konkurrenz zum offiziellen KiCad Wiki sein, d.h. was dort steht soll hier nicht wiederholt werden und was hier steht wird hoffentlich zum offiziellen KiCad Wiki wandern.&lt;br /&gt;
&lt;br /&gt;
Die Bedienung von KiCad setzt Hintergrundwissen über die Vorgänge voraus. Die Bedienungsweise entspricht eher einem alten Orcad, Altium oder auch BAE und weniger der von Eagle. Daher ist es Neulingen dringend angeraten, sich vorher die Handbücher und Tutorials gut durch zu sehen. Zur Einarbeitung benötigt man schon etwas Geduld.&lt;br /&gt;
Wer offizielle Releases verwendet, wird oft Bugs feststellen, die aber in den Testing Versionen im allgemeinen beseitigt sind.&lt;br /&gt;
Wenn ihr Kritik oder Fragen zu KiCad habt, dann nutzt das Forum! Sobald KiCad im Betreff steht, wird der Beitrag gelesen und nach Möglichkeit beantwortet. Auch Ideen zu dieser Seite sind sehr willkommen! &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Suchen und Finden&#039;&#039;&#039; Da diese Seite hier etwas umfangreich geworden ist, empfehle ich eine Textsuche. Jeder Internetbrowser, der etwas auf sich hält, hat auch eine Suchfunktion, mit der der Text der Seite durchsucht werden kann. Bei Firefox/Iceweasel oben im Pull-down Menue unter &amp;quot;Bearbeiten&amp;quot; &amp;gt; &amp;quot;suchen&amp;quot; oder per Shortcut &amp;lt;Strg-F&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== FAQ ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Link defekt -- Siehe auch die offizielle FAQ: http://kicad.sourceforge.net/wiki/index.php/FAQ --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Allgemein ===&lt;br /&gt;
&amp;lt;!-- alt 2007 -- &lt;br /&gt;
* Warum gefällt dir KiCad?&lt;br /&gt;
** http://www.mikrocontroller.net/topic/70905#584639&lt;br /&gt;
** http://www.mikrocontroller.net/topic/81396#680502&lt;br /&gt;
** http://www.mikrocontroller.net/topic/83311#697917&lt;br /&gt;
** http://www.mikrocontroller.net/topic/42614#321502&lt;br /&gt;
* Warum gefällt dir KiCad nicht?&lt;br /&gt;
** Ich verstehe nicht, was du meinst ;-)&lt;br /&gt;
** http://www.mikrocontroller.net/topic/81396#680502&lt;br /&gt;
** http://www.mikrocontroller.net/topic/83311#697969&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Wo gibt es weitere Infos zu KiCad?&lt;br /&gt;
** Offizielle Homepage: http://KiCad-pcb.org&lt;br /&gt;
** Die Offizielle Dokumentation: http://KiCad-pcb.org/help/&lt;br /&gt;
** Einige allgemeine Notizen zur &#039;&#039;&#039;Installation&#039;&#039;&#039; und zur &#039;&#039;&#039;Arbeitsweise&#039;&#039;&#039; von KiCad finden sich hier: https://docs.google.com/document/d/1M38ByFyqnhwGo8b_jDDyBceyZtEGeaSAuQaP9REzWrU/edit?usp=sharing&lt;br /&gt;
&amp;lt;!-- alt 2008 -- ** http://www.mikrocontroller.net/topic/98034#848661 (Von 2008, also seeeehr überholt) --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Welche Leiterplattenfertiger akzeptieren KiCad Layouts?&lt;br /&gt;
** PCB-Pool.de KiCad kann &amp;quot;Extended&amp;quot; Gerber RS-274-X erzeugen. &amp;lt;!-- alt -- Das wird von PCB-Pool akzeptiert. Dabei http://www.pcb-pool.com/download/spezifikation/deu_cmso020_ext_gerber.pdf beachten! Alternativ, wer KiCad (noch) nicht traut, diese RS-274-X in deren (PCB-Pools) Tool GC-Prevue  http://www.mikrocontroller.net/topic/120373#1092375 einlesen und als .GWK exportieren. AKTUELL August 2012: Wenn man bei PCB-Pool bestellt, ist deren GC-Prevue NICHT mehr erforderlich, weil --&amp;gt; PCB-Pool akzeptiert KiCad *.brd Dateien auch direkt. Siehe http://www.pcb-pool.com/ppde/info_dataformat.html&lt;br /&gt;
** http://fischer-leiterplatten.de&lt;br /&gt;
** https://www.oshpark.com/&lt;br /&gt;
&lt;br /&gt;
* Welche Gerberfiles benötigt der Leiterplattenhersteller?&lt;br /&gt;
** Siehe https://www.mikrocontroller.net/topic/399503#new und ergänzend https://www.mikrocontroller.net/articles/Gerber-Tools sowie https://www.mikrocontroller.net/articles/Richtiges_Designen_von_Platinenlayouts#CAM_Input_und_Produktion_.2F_Ber.C3.BCcksichtigung_von_Technologiegrenzen &lt;br /&gt;
&lt;br /&gt;
* Wie kriege ich raus, welche Leiterbahn welchen Netznamen hat, bzw. ich habe den Überblick verloren und weiß nicht mehr, was aus dem Layout nun was im Schaltplan ist?&lt;br /&gt;
** http://www.mikrocontroller.net/topic/316539#3427724 (Funktioniert nur gut, wenn großes Fadenkreuz gewählt ist.)&lt;br /&gt;
** Genauere Informationen, z.B. über die Länge einer Leiterbahn etc.&lt;br /&gt;
*** Dazu in PCBnew den gleichen Button rechts wie für das Hinzufügen von Leiterbahnen aktivieren. Oder besser noch rechts den zweiten Button von oben &amp;quot;Netz hervorheben&amp;quot;. Dann mit der rechten Maustaste die fragliche Leiterbahn anklicken. Unten in der Statusleiste werden die Informationen angezeigt.&lt;br /&gt;
&lt;br /&gt;
* KiCad ohne Maus bedienen. http://www.mikrocontroller.net/topic/267538#new&lt;br /&gt;
* Gibt es Sonderzeichen, die ich für Symbole, Module/Footprints oder Files nicht verwenden sollte?&lt;br /&gt;
** Ja, alles was Sonderzeichen außer &amp;quot;- _ .&amp;quot; (Bindestrich, Tiefstrich, Punkt) und keine Zahl ist. Siehe: http://www.mikrocontroller.net/topic/302664#3249204&lt;br /&gt;
&lt;br /&gt;
* Wie stelle ich in KiCad das Zeitintervall für &amp;quot;automatisch Speichern&amp;quot; ein?&lt;br /&gt;
** Siehe https://www.mikrocontroller.net/topic/459135#5551638&lt;br /&gt;
&lt;br /&gt;
=== Installation ===&lt;br /&gt;
* Woher beziehe ich KiCad?&lt;br /&gt;
** Offizielle Seite (alle Betriebssysteme): http://kicad-pcb.org/download/&lt;br /&gt;
** Nightly Development Builds auch von der offiziellen Seite&lt;br /&gt;
** KiCad kann man aus den Sourcen selbst compilieren. Dazu gibt es Skripte zur Unterstützung, die dieses automatisieren, so dass man nicht unbedingt C/C++ Kenntnisse braucht. Die meisten gängigen Linux Distributionen enthalten aber &amp;quot;old stable&amp;quot; KiCad Releases in ihren Repositories.&lt;br /&gt;
&amp;lt;!-- alt -- ** Windows: http://www2.futureware.at/~nickoe/ &lt;br /&gt;
*** Welcher Typ? ...-x86_64.exe oder ...-i686.exe ? Ich brauche x86 32 bit.&lt;br /&gt;
**** Für Windows PC 32 bit die ...-i686.exe, und für Windows PC 64 bit ...-x86_64.exe.&lt;br /&gt;
** Veraltet: http://www71.zippyshare.com/v/28617008/file.html Die Quelle ist hier genannt. https://groups.yahoo.com/neo/groups/kicad-users/conversations/messages/18534 --&amp;gt;&lt;br /&gt;
* Liste der Versionsänderungen auf der KiCad Launchpad Seite via bazaar. Siehe: http://www.mikrocontroller.net/topic/298311#3187885&lt;br /&gt;
* Ich habe KiCad unter Linux installiert, aber wenn ich KiCad starten will, passiert einfach nichts, oder ich erhalte eine Fehlermeldung wie: &amp;quot;Datei nicht gefunden&amp;quot;. Siehe: http://www.mikrocontroller.net/topic/307517#new&lt;br /&gt;
** 1) KiCad und seine zugeordneten Programme sollten im Suchpfad stehen. Es wird für Debian und Ableger empfohlen, KiCad unter usr/local/bin zu installieren. Anmerkung: Das ist die aktuelle Verfahrensweise. Oktober 2013 wurde aber noch folgende Struktur verwendet:&lt;br /&gt;
*** /usr/bin                            - Binaries (executable files).&lt;br /&gt;
*** /usr/share/doc/kicad/               - Various documentation.&lt;br /&gt;
*** /usr/share/doc/kicad/help           - Interactive help.&lt;br /&gt;
*** /usr/share/kicad/demos              - Sample schematics and printed boards.&lt;br /&gt;
*** /usr/share/kicad/internat           - Dictionaries for interface localization.&lt;br /&gt;
*** /usr/share/kicad/library            - Interface localization files.&lt;br /&gt;
*** /usr/share/kicad/modules            - Module libraries for printed boards.&lt;br /&gt;
*** /usr/share/kicad/modules/packages3d - 3D component models (.wrl and .wings format).&lt;br /&gt;
*** Quelle: http://iut-tice.ujf-grenoble.fr/cao/install.txt Hier sind auch Hinweise für Windows user enthalten.&lt;br /&gt;
&lt;br /&gt;
** 2) User sollten dort Lese- und Ausführungsrechte haben. Aber keine Schreibrechte.&lt;br /&gt;
** 3) Wenn ein fertiges Packgage auf einem 64 bit System verwendet wurde, könnte es daran liegen, das es für 32 bit compiliert wurde, und nicht für 64 bit. Es gibt zwei Möglichkeiten:&lt;br /&gt;
*** a) Selbst aus den Sourcen für sein eigenes System compilieren.&lt;br /&gt;
*** b) Die Runtime Libs für 32 Bit könnten fehlen. Nachinstallieren mit sudo apt-get install ia32-libs. Siehe: http://www.mikrocontroller.net/topic/307517#3307638&lt;br /&gt;
* Ich habe das umgekehrte Problem: 32bit system aber 64bit Binarys.&lt;br /&gt;
** Selbst aus den Sourcen neu compilieren.&lt;br /&gt;
&amp;lt;!-- alt -- *Ich will/muss mir KiCad selber compilieren. Wie gehe ich vor?&lt;br /&gt;
** Aktuell nach: http://www.kicad-pcb.org/display/DEV/Build+KiCad&lt;br /&gt;
**&lt;br /&gt;
**Veraltet! siehe: http://www.mikrocontroller.net/topic/310766#3351269 Aber Achtung. Diese Anleitung (Oktober 2013) muss nicht aktuell sein. --&amp;gt;&lt;br /&gt;
* Sicherheitseinstellungen von Java sind für PCBnew unter JAVA -&amp;gt; JAVA konfigurieren zu finden.&lt;br /&gt;
&lt;br /&gt;
* Diskussionen zum Thema Installation und compilieren:&lt;br /&gt;
** FEDORA: http://www.mikrocontroller.net/topic/338600#new&lt;br /&gt;
** ARCH Linux: http://www.mikrocontroller.net/topic/339509#new&lt;br /&gt;
* Konfigurationsdateien:&lt;br /&gt;
** Ab BZR5114 (ca. 5. September 2014) hat sich der Ordner für die Files mit den Konfigurationsdaten geändert. Unter Linux sind nun die Konfigurations Dateien in $HOME/.config/kicad (entsprechen der FreeDesktop.org Spezifikation). Um Ihre gegenwärtigen Konfigurierungen zu erhalten, können die KiCAd Konfigurationsfiles aus dem Home-Verzeichnis in den aktuellen Ordner kopiert werden. Es muss allerdings der führende &amp;quot;.&amp;quot; (Punkt) der Datei entfernt werden. Ebenso muss die globale &amp;quot;fp-lib-table&amp;quot; aus dem home-Verzeichnis dorthin kopiert werden. Windows User müssen KiCad leider reconfigurieren. Es gab keinen einfachen Weg um die Registry-Keys in die Konfigurationsdateien zu extrahieren. Die Konfigurationsdateien unter Windows werden genau wie die fp-lib-table im %APPDATA%\kicad Ordner gespeichert. Es ist angeraten, sämtliche Reste der KiCad Installation aus der Registry zu entfernen, wenn nicht KiCad Versionen vor der BZR5114 verwendet werden. Diese Lösung beseitigt die $home Ordner &amp;quot;Verschmutzung&amp;quot; und vermeidet die Benutzung der Windows registry, wie es häufig gewünscht wurde. Für OS X User ergeben sich keine Änderungen. Link auf die Originalnachricht (englisch): https://groups.yahoo.com/neo/groups/kicad-users/conversations/messages/18889 (KiCad-User Group, 05. September 2014, Titel: Configuration file location changes (#18889) Autor: Wayne Stambaugh)&lt;br /&gt;
&lt;br /&gt;
=== Schaltplan ===&lt;br /&gt;
* Wie stellt man die Blattgröße beim Schaltplan ein?&lt;br /&gt;
** In Page Settings die Blattgröße verstellen (z.B. von A4 auf A3) http://www.mikrocontroller.net/topic/33653#974295&lt;br /&gt;
* Wie mache ich eine neue Schaltplan Seite auf?&lt;br /&gt;
** Nur in Form eines neuen hierarchischen Schaltplans. Siehe nächsten Punkt und hier im Forum: https://www.mikrocontroller.net/topic/398489#new&lt;br /&gt;
* Wie kann man den Schaltplan auf mehreren Seiten verteilen (hierarchical sheets)?&lt;br /&gt;
** http://www.mikrocontroller.net/topic/96060&lt;br /&gt;
** http://www.mikrocontroller.net/topic/117873#1060062&lt;br /&gt;
*Wie geht man mit &amp;quot;Power Pins&amp;quot; in hi­e­r­ar­chischen Schaltplänen um?&lt;br /&gt;
**http://www.mikrocontroller.net/topic/207905#new&lt;br /&gt;
* Wie kann man die &amp;quot;hierachical sheets&amp;quot; benutzen, um aus vorgefertigten Subschaltplänen mit immer gleichen Bauteilgruppen rationell Schaltpläne zusammenzustellen (Building Blocks)?&lt;br /&gt;
** http://www.mikrocontroller.net/articles/KiCad#Tipps.26Tricks:_Building_Blocks&lt;br /&gt;
** http://www.mikrocontroller.net/topic/175597#1687653&lt;br /&gt;
** http://www.mikrocontroller.net/topic/178683#1724114&lt;br /&gt;
* Ich habe einen hierarchischen Schaltplan angelegt. Wenn ich ihn ausdrucke, werden die Subschaltpläne in der Reihenfolge ausgedruckt, in der sie oben in der Übersicht stehen. Diese Reihenfolge ist aber in meinem Fall ungünstig. Wie kann ich diese nun ändern?&lt;br /&gt;
** Leider im Programm z.Z. noch nicht. Trotzdem ist es machbar. Entweder von Hand oder mit einem Python Skript. Näheres zu beidem findet sich hier: http://www.mikrocontroller.net/topic/288394#3064087 . Ein Python 3 Skript, das den Umgang mit dem Kicad-Schaltplan erleichtert, findet sich hier: [[Media:PyKicadSchematic-ID_Interchanger_RevC.zip]].&lt;br /&gt;
*Wie geht man mit Bussen um?&lt;br /&gt;
**http://www.mikrocontroller.net/topic/208870#new&lt;br /&gt;
** und speziell bei hierarchischen Schaltplänen: http://www.mikrocontroller.net/topic/209156#new&lt;br /&gt;
* Wie kann man Schaltplanentwurf (KiCad) und Schaltungssimulation (Spice) verbinden?&lt;br /&gt;
** NGspice ist in den Grundzügen mittlerweile in den entwicklungsversionen von KiCad integriert. Aktuell (Nov. 2016) muss man sich aber noch KiCad selber compilieren und dabei auch einen passenden Schalter für den Compiler setzten. Siehe: https://www.mikrocontroller.net/topic/412350#4803960&lt;br /&gt;
** [http://Fuhaweb.hartford.edu/kmhill/suppnotes/KiCadDia/AimSPICE/KiCad_AimSPICE_01.pdf] Imformationen zur Zusammenspiel KiCad &amp;lt;&amp;gt; AimSpice.&lt;br /&gt;
* Ein Tutorial zum Symboleditor für KiCad, mit dem die Symbole für das Schaltplanmodul (EEschema) erzeugt bzw. editiert werden, findet sich hier: [[Media:SymboleFuerKiCad318082009-RevC-DE.pdf]].&lt;br /&gt;
* Zur Erstellung von Schaltplansymbolen in aufgelöster Darstellung (Relais: Kontaktsätze einzeln und getrennt von der Spule; IC: Versorgungsspannung getrennt von den einzelnen Gattern) siehe http://www.mikrocontroller.net/topic/273891#new. Bei Problemen noch mal hier nachlesen: http://www.mikrocontroller.net/topic/294095#3136180. Aktuell: https://www.mikrocontroller.net/topic/449373#new&lt;br /&gt;
* Wie kann man im Schaltplan Symbole zum Verschieben gruppieren?&lt;br /&gt;
** Siehe http://www.mikrocontroller.net/topic/170913#&lt;br /&gt;
* Und wenn es darum geht, eine solche Gruppe in einen anderen Schaltplan oder Subschaltplan zu verschieben?&lt;br /&gt;
** Die Gruppe ins &amp;quot;Clipboard&amp;quot; stecken. Dazu nach dem Markieren der Gruppe rechte Maustaste klicken, und dort &amp;quot;Gruppe speichern&amp;quot; wählen. Nun ist die Gruppe im Clipboard. jetzt in den gewünschten Unterschaltplan gehen und die Gruppe dort mithilfe des Clipboardbuttons (Das Klemmbrett Symbol links neben dem &amp;quot;Undo&amp;quot;-Button) in den Schaltplan einfügen. NICHTS mit der rechten Maustaste versuchen! Siehe auch: http://www.mikrocontroller.net/topic/244836#2499782 Das ganze geht nicht nur mit Subschaltplänen, sondern auch genauso in einen ganz anderen Schaltplan, den man dann halt in Eeschema öffnen muss, hinein. Wenn nach dem Einfügen allerdings nur ein Kästchen mit Fragezeichen erscheint, waren die nötigen Symbolbibliotheken für diese Symbole noch nicht in der Projektdatei eingetragen. Das muss man nun nachholen, indem man unter &amp;quot;Einstellungen&amp;quot; die &amp;quot;Bibliotheken&amp;quot; wählt, und die passenden Bibliotheken einträgt. Wenn man nicht genau weiß, wo diese zu finden sind, kann es sinnvoll sein, die *-cache.lib des Herkunftsschaltplanes einzubinden.&lt;br /&gt;
** Ist es möglich, im Schaltplan gruppierte Bauteile automatisch im Board als Gruppe zu verschieben?&lt;br /&gt;
*** Nein. Siehe https://www.mikrocontroller.net/topic/398996#new&lt;br /&gt;
* Wie wird man den merkwürdigen Rahmen los?&lt;br /&gt;
** 1) Bei neueren KiCad Versionen, ab ca. Mitte 2013 (von mir getestet ab BZR 4513 29 November 2013) kann man sich eine Vorlage ohne Rahmen erstellen. Dazu den pl_editor (der ganz rechte Button im KiCad Hauptfenster) starten, und FAST alles entfernen. Dazu in der linken Spalte nacheinander alles aktivieren, und mit rechts anklicken und dann &amp;quot;entfernen&amp;quot; wählen. Aber Vorsicht, wenn alles Entfernt wird, taucht das Original Layout wieder auf. Workaround war bei mir, eine zusätzliche Alibilinie hinzuzufügen, die von X 0,000 Y 0,000 bis  X 0,001 Y 0,000 reicht. Das ist ein &amp;quot;Fliegenschiss&amp;quot; in der linken oberen Ecke. Jetzt kann alles andere gelöscht werden. Den so geleerten Rahmen unter einem beliebigen Namen mit der Endung .kicad_wks wegspeichern. Im geöffneten Schaltplan kann der dann unter Datei &amp;gt; Seite einrichten ganz unten unter &amp;quot;page layout file description&amp;quot; die entsprechende Datei eingebunden werden. Es bleibt aber dem Anwender offen, ob er den Rahmen komplett entfernt, oder noch Felder mit Textbeschreibungen übernimmt. Für gesteigerten Komfort kann diese Datei dann auch in ein Template eingebunden werden. &lt;br /&gt;
** 2) Beim Ausdrucken Frame deaktivieren.&lt;br /&gt;
** 3) Als SVG exportieren. Dort den Frame deaktivieren.&lt;br /&gt;
** Siehe: http://www.mikrocontroller.net/topic/343509#3791448&lt;br /&gt;
* Wie schalte die Footprint-Namen in Eeschema global ab?&lt;br /&gt;
** http://www.mikrocontroller.net/topic/253564#new&lt;br /&gt;
* Ich habe ein Problem mit dem ERC. Ständig kommt die Fehlermeldung: &amp;quot;Pin ist mit anderen Pins verbunden, wird jedoch von keinem angesteuert&amp;quot;&lt;br /&gt;
** Netze, die nicht angesteuert werden, werden von Kicad misstrauische beäugt. Das &amp;quot;nicht ansteuern&amp;quot; kann aber schnell passieren, weil Kicad u.A. erwartet, das irgendwo ein Spannungsversorgung ist. Wenn diese aber z.B. über eine Sicherung oder einen Pull-up Widerstand gehen, so wird das nicht bemerkt, weil Sicherungen und Widerstände (oder auch Entstördrosseln) &amp;quot;passive&amp;quot; Pins haben. Siehe: http://www.mikrocontroller.net/topic/292988#new und http://www.mikrocontroller.net/topic/298401#new&lt;br /&gt;
* Ich habe ein Problem mit dem ERC. Immer in Verbindung mit GND kommt die Fehlermeldung: &amp;quot;Pin ist mit anderen Pins verbunden, wird jedoch von keinem angesteuert&amp;quot;&lt;br /&gt;
**Siehe: http://www.mikrocontroller.net/topic/284089#new&lt;br /&gt;
* Beim ERC kommt die Fehlermeldung &amp;quot;PIN not connected&amp;quot; an Verbindungen, die per Label angeschlossen sind. Was ist da falsch?&lt;br /&gt;
**Sie sind tatsächlich nicht angeschlossen. Siehe: http://www.mikrocontroller.net/topic/346976#new&lt;br /&gt;
* Wie ist der Zusammenhang zwischen Bauteilen und Netznamen? Wie bekomme ich heraus, an welchem Netz mein Bauteil angeschlossen ist?&lt;br /&gt;
** Eeschema vergibt bzw. aktualisiert erst dann Netznamen, wenn eine Netzliste erzeugt wird. Darauf besteht entweder ein Zugriff über PCBnew, oder aber mit einem Editor. Siehe Beitrag http://www.mikrocontroller.net/topic/316539#new&lt;br /&gt;
* Ich habe einen Schaltplan geöffnet, aber alle oder einige der Symbole zeigen nur Kästen mit Fragezeichen.&lt;br /&gt;
** Es fehlen die passenden Symbolbibliotheken für diese Symbole.&lt;br /&gt;
** Hat man von anderswo einen Schaltplan bekommen, kann dieser auf anderen Symbolbibliotheken beruhen, als man selber verwendet. Diese Fehlen nun. Man braucht die Originalbibliotheken oder aber die Cache-Bibliothek dieses Schaltplans.&lt;br /&gt;
*** Diese müssen in der Liste der Bibliotheken nachgetragen werden. Siehe dazu die Handhabung von Bibliotheken: https://www.mikrocontroller.net/articles/KiCad#Handhabung_von_Bibliotheken&lt;br /&gt;
** Hat man von anderswo einen Schaltplan bekommen, kann dieser auf anderen Symbolbibliotheken beruhen, als man selber verwendet. Diese Fehlen nun. Man braucht nun die Originalbibliotheken oder aber die Cache-Bibliothek dieses Schaltplans. Zu den Cache-Bibliotheken siehe hier: https://www.mikrocontroller.net/articles/KiCad#Handhabung_von_Bibliotheken&lt;br /&gt;
** Ab BZR4646 (Jan./Feb. 2014) behandelt KiCad Symbolnamen &amp;quot;Case Sensitive&amp;quot;. Das führt zu Problemen mit älteren Schaltplänen, wo das anders gehandhabt wurde. Siehe hier: https://www.mikrocontroller.net/articles/KiCad#Handhabung_von_Bibliotheken&lt;br /&gt;
*Wieviele Textfelder für Symbole kann ich anlegen und wie groß dürfen diese sein?&lt;br /&gt;
** Mindestens 35 Felder, die mindestens 256 Zeichen (tatsächlich deutlich mehr) beinhalten können. Aber Zeilenumbrüche gehen nicht. Siehe: http://www.mikrocontroller.net/topic/331201#3658695&lt;br /&gt;
* Ich habe ein Symbol im Symboleditor geändert. Aber irgendwie taucht diese Änderung dann in Eeschema trotzdem nicht auf.&lt;br /&gt;
** Die Reihenfolge der Einträge in der Bibliotheksliste ist wichtig. Bei gleichem Namen wird immer das zuerst gefundene Symbol verwendet. Steht die -cache.lib in der Reihenfolge zu oberst, wird immer zuerst das Bauteil aus der -cache.lib verwendet. Beheben: Die -cache.lib aus der Bibliotheksliste von Eeschema austragen und neu eintragen, so dass sie unten angefügt wird, und zuletzt geladen wird. Alternativ: Bei Änderungen einen neuen Namen für das Symbol vergeben. Z.B. durch das Pflegen eines Revisions- oder Datecode im Symbolnamen. Einfach nur die -cache.lib löschen langt möglicherweise nicht, weil diese u.U. mit alten Daten neu geschrieben wird (wenn z.b. Eeschema dabei nicht geschlossen ist). Siehe: http://www.mikrocontroller.net/topic/331201&lt;br /&gt;
* Wie erstelle ich eine Stückliste (BOM, Bill of Materials)?&lt;br /&gt;
** 1) In PCBnew oben im Pull down Menue Datei &amp;gt; Fertigungsdateien &amp;gt; BOM (Bill of materials) Geht nur, wenn die Netzliste schon importiert wurde.&lt;br /&gt;
** 2) In EEschema unter Werkzeuge &amp;gt; Stückliste erstellen &amp;gt; und dann ein Plugin wählen. Es gibt verschieden Plugins mit verschiedenen Eigenschaften z.B. auch für kumulierende Listen. Die Plugins kann man von hier beziehen: https://github.com/KiCad/kicad-source-mirror/tree/master/eeschema/plugins Achtung, ein kleiner &#039;&#039;&#039;BUG&#039;&#039;&#039; In den Voreinstellungen der Kommandozeile muss in den Optionen &amp;quot;%O&amp;quot; in &amp;quot;%O.csv&amp;quot; umgewandelt werden, sonst hat die erzeugte Datei keinen .csv extender. Grundsätzlich: Hier wird zuerst eine behelfsmäßige Netzliste im .xml Format erstellt. Die Kommandozeile startet dann ein Programm, was widerum ein .xsl Skript (Das Plugin) abarbeitet, und als output eine .csv Datei erzeugt, die in Tabellenkalkulationen importiert werden kann. In die Kommandozeile kann natürlich auch etwas anderes eingetragen werden, so dass man dort z.B. auch Python Skripte verwenden kann.&lt;br /&gt;
** 3) Man kann sich selber ein separates Skript erstellen, welches die .kicad_sch Datei parst, und daraus eine .csv oder anders gestaltete BOM-Datei erstellt, so wie man es braucht. Da man auch ohne Plugins bei drücken von &amp;quot;Erstellen&amp;quot; die oben erwähnte behelfsmäßige Netzliste erhält, kann man diese auch mit externen Skripten bearbeiten. Es gibt Mittelwege zwischen 2) und 3). Für ein Python Skript siehe hier: https://forum.kicad.info/t/kibom-python-bom-generation-tool/3038&lt;br /&gt;
** Info:&lt;br /&gt;
*** [http://www.mikrocontroller.net/topic/402089#new] &amp;quot;KiCad Stückliste&amp;quot; hier im Forum. &lt;br /&gt;
*** [http://www.mikrocontroller.net/topic/376977?goto=new#new] &amp;quot;Kicad Bauteilliste(BOM) erstellen&amp;quot; hier im Forum.&lt;br /&gt;
** Klaus hat ein Plugin geschrieben, dass in html überträgt. Siehe hier den Download und die Bedienungsanleitung: https://www.mikrocontroller.net/topic/402565#new&lt;br /&gt;
* Ich möchte eine Stückliste (BOM, Bill of Materials) mit einer Datenbank, z.B. für Bestellnummern verbinden.&lt;br /&gt;
** Tipps dazu sind z.B. hier zu finden: https://www.mikrocontroller.net/topic/416192#4856645&lt;br /&gt;
&lt;br /&gt;
=== Netlist ===&lt;br /&gt;
* Was genau muss man beim Übergang vom Schaltplan (SCH) zum Layout (BRD) machen?&lt;br /&gt;
** http://www.mikrocontroller.net/topic/33653#898771&lt;br /&gt;
** http://www.mikrocontroller.net/topic/39243#290309&lt;br /&gt;
** http://www.mikrocontroller.net/topic/39243#891530&lt;br /&gt;
* Kann man fertige Netzlisten für Gruppen von Bauteilen einbinden?&lt;br /&gt;
** http://www.mikrocontroller.net/topic/33653#1462871&lt;br /&gt;
* Wie sieht das allgemein mit der Zuordnung Symbol zu Footprint aus?&lt;br /&gt;
** Symbole und Footprints sind zwar von der Idee her erst einmal getrennt, und Footprints werden über CVpcb und Netzliste den Symbolen zugeordnet.&lt;br /&gt;
** Allerdings besteht auch eine Möglichkeit, Symbolen einen bevorzugten Footprint  fest zuzuweisen, der dann automatisch in die Netzliste zum Einlesen in das Board eingetragen wird. Wenn dann der Zuweisungsschritt mit CVbcb in der Netzliste gemacht wird, ist dort schon etwas eingetragen, was man so lassen oder aber ändern kann.&lt;br /&gt;
*** Dazu in EEschema mit der Maus auf ein Symbol gehst und &amp;quot;E&amp;quot; drücken. Alternativ über rechten Mausklick auf Symbol und dann das Kontextmenuest gehen. Wenn man im Symboleditor arbeitet, aus der oberen buttonleiste den Button mit dem &amp;quot;T&amp;quot;-Symbol wählen. Es poppt ein Fenster auf &amp;quot;component properties&amp;quot;. In der Mitte ist eine Tabelle mit unter anderem einem Eintrag &amp;quot;Footprint&amp;quot;. Wenn dann &amp;quot;Footprint&amp;quot; aktiviert wird. kann rechts der Name eines Footprintes eingebenwerden (kompliziert), oder, wesentlich einfacher, darunter gibt es einen Button &amp;quot;browse Footprints&amp;quot;. Wenn der aktiviert wird, öffent sich ein Fenster, in dem sich in den in die Bibliothekslisten eingetragenen Footprintbiblotheken herumwühlen lässt.&lt;br /&gt;
** Desweiteren kann auch eine Kopie des Symbols unter anderem Namen angelegt werden, und dort ein anderer Footprint eingetragen werden, als Variante. Falls das Pinning nicht passt, müssen halt auch noch die Pinne im Symbol passend zum Footprint gemacht werden.&lt;br /&gt;
** Diskussion dazu: https://www.mikrocontroller.net/topic/432920#5112114&lt;br /&gt;
* Kann man Daten für automatische Bestückung erzeugen?&lt;br /&gt;
** Ja. aber nicht in CVpcb für die Symbol &amp;gt; Footprint Zuordnung, sondern im Layout Modul PCBnew.&lt;br /&gt;
* In meiner Netlist fehlen Bauteile, die im Schaltplan vorhanden und angeschlossen sind. Der ERC läuft problemlos durch. Die Annotation auch, aber nach Erstellung der Netlist sind die Symbole plötzlich mit einem vorangestellten &amp;quot;#&amp;quot; im Schaltplan bezeichnet.&lt;br /&gt;
** Vermutlich sind sie versehentlich als &amp;quot;virtuelles&amp;quot; Bauteil gekennzeichnet. Siehe http://www.mikrocontroller.net/topic/268626#new&lt;br /&gt;
* Wie exportiere ich eine Netlist NUR für einen Subschaltplan?&lt;br /&gt;
** Das geht, nachdem dieser Schaltplan explizit in EEschema geöffnet wurde. Siehe: http://www.mikrocontroller.net/topic/330740#new&lt;br /&gt;
* Ich finde CVpcb nicht mehr am gewohnten Platz zwischen all den anderen Startbuttons!&lt;br /&gt;
** CVpcb ist inzwischen aus diesen entfernt worden, und durch Startbuttons für den Symboleditor und den Footprinteditor ersetzt worden. Dafür kann CVpcb jetzt direkt aus Eeschema heraus gestartet werden. Es findet sich jetzt im oberen Pulldown Menue unter &amp;quot;Werkzeuge&amp;quot; und dann &amp;quot;Bauteilfootprints zuweisen&amp;quot; oder in der oberen Buttonleiste als dritter Button von rechts (BZR5175 vom 11 Oktober 2014).&lt;br /&gt;
** Sollte KiCad abstürzen, wenn man versucht, CVpcb zu starten, so kann man CVpcb auch direkt aus einem Terminal oder aus der Eingabeaufforderung heraus starten.  &lt;br /&gt;
** Versuchsweise mal 10 Minuten warten.....bei Problemen mit der Erkennung von Symbolnamen und Footprintnamen (beim öffnen ganz alter Projekte mit alten Dateiformaten) kann es manchmal extrem lange dauern.&lt;br /&gt;
* Was bedeuten die Maßangaben in der Netlist?&lt;br /&gt;
* Wie überträgt man Kicad Schaltpläne in QUCS Schaltpläne für Simulation?&lt;br /&gt;
&lt;br /&gt;
=== Layout ===&lt;br /&gt;
* Wie stellt man die Rastergrösse im Layout ein?&lt;br /&gt;
** Mit der Rechten Maustaste in das Board klicken. Es poppt ein Menue auf. Dort Raster wählen..... Geht im Modul-Editor genauso.&lt;br /&gt;
* Wie verteile ich die übereinander geladenen Bauteile?&lt;br /&gt;
**Oben das IC Symbol mit den zwei Pfeilen (Mode footprint) aktivieren und mit der rechten Maustaste auf der Platine im Menü &amp;quot;Global spread and place&amp;quot; anwählen und die gewünschte Art auswählen.&lt;br /&gt;
* Wie werden Pads und Leiterbahnen verbunden?&lt;br /&gt;
**Siehe: http://www.mikrocontroller.net/topic/119755#1081455&lt;br /&gt;
**Aktueller: http://www.mikrocontroller.net/topic/220733#new&lt;br /&gt;
* Ich kann keine Leiterbahnen ziehen!&lt;br /&gt;
** Vermutlich hast Du den automatischen DRC (Design rule check) aktiviert. Deaktiviere ihn halt. In PCBnew im linken Buttonbar der oberste Button (Insekt mit Verbotszeichen). http://www.mikrocontroller.net/topic/306476#new&lt;br /&gt;
* Aber jetzt habe ich beim Ziehen der Leiterbahnen so merkwürdige Ergebnisse!&lt;br /&gt;
** Option &amp;quot;Remove redundant tracks&amp;quot; wählen! Siehe https://www.mikrocontroller.net/topic/381906#new &lt;br /&gt;
* Mir fehlen Airwires/Luftlinien/Gummibänder!&lt;br /&gt;
** Vieleicht die falschen Pins als Typ &amp;quot;Spannungsausgang&amp;quot; definiert? Siehe: http://www.mikrocontroller.net/topic/330817#3620918&lt;br /&gt;
* Ich bekomme immer eine Fehlermeldung vom DRC, das ein Pad nicht angeschlossen ist, aber ich habe es angeschlossen.&lt;br /&gt;
**Siehe: http://www.mikrocontroller.net/topic/204717#2018724&lt;br /&gt;
* Ich will ein Bauteil für geringeren Leiterwiderstand sowohl auf der Unterseite- als auch der Oberseite anschließen. KiCad löscht aber immer den alten Leiterbahnzug, wenn ich den neuen lege. &lt;br /&gt;
** Deaktiviere unter Einstellungen-&amp;gt;Allgemein das &amp;quot;auto-entfernen-von-Leiterbahnen&amp;quot; (einfachste Lösung). &lt;br /&gt;
** Alternativ: Designe dafür Bauteile mit speziellen Pads. http://www.mikrocontroller.net/topic/187606#1823596 (realistischste u. sauberste Lösung, aber etwas umständlich.)&lt;br /&gt;
* Das Löschen der Leiterbahnen Segment für Segment ist sehr umständlich. Geht es besser?&lt;br /&gt;
** Ja. Siehe: https://www.mikrocontroller.net/topic/385768#new &#039;&#039;&#039;Achtung:&#039;&#039;&#039; Bei neueren (RC4 z.B.) Versionen von PCBnew kann unter &amp;quot;View&amp;quot; verschiedene &amp;quot;Canvas&amp;quot; verwendet werden. Jeder dieser &amp;quot;Canvas&amp;quot; verhält sich etwas anders und hat andere Vorzüge.&lt;br /&gt;
** Aktuell (Jan. 2019) mit Auswahlbox. Achtung: Die Auswahlbox hat anderes Verhalten in KiCad 6, je nachdem ob man sie von rechts oder von links aufgezogen hat! Details siehe: https://www.mikrocontroller.net/topic/467735#new&lt;br /&gt;
* Wie kann man ein Bauteil mit Pads und Leiterbahnen bewegen? &lt;br /&gt;
** http://www.mikrocontroller.net/topic/118539#1067219&lt;br /&gt;
* Wie füllt man eine Fläche aus?&lt;br /&gt;
** Siehe: http://www.mikrocontroller.net/topic/93131#854802&lt;br /&gt;
** Etwas aktueller: http://www.mikrocontroller.net/topic/182271#1772119 Zweiter Teil des Posts.&lt;br /&gt;
** Und wie erzeuge ich konzentrisch ineinanderliegende Flächen?&lt;br /&gt;
*** Siehe: http://www.mikrocontroller.net/topic/327475#new&lt;br /&gt;
** Ja, aber meine Fläche wird nicht gefüllt oder es passiert was ganz merkwürdiges.&lt;br /&gt;
***Siehe: http://www.mikrocontroller.net/topic/298692#new &lt;br /&gt;
***Konkreter: Es sollte darauf geachtet werden, das mindestens ein Endpunkt oder ein Via oder ein Knickpunkt der Leiterbahn, die mit der zu füllenden Fläche verbunden sein soll, innerhalb der als zu füllen definierten Fläche liegen. Siehe http://www.mikrocontroller.net/topic/366199#new&lt;br /&gt;
* Die Flächen habe ich jetzt, aber wie sieht das mit &amp;quot;Stitching&amp;quot; aus? Anmerkung: Als &amp;quot;Stitching&amp;quot; (von Engl. &amp;quot;stitch&amp;quot;: Nähen) bezeichnet man das Verbinden mehrerer Flächen oder Leiterbahnen gleichen Potentials mit Durchkontaktierungen durch die Platine hindurch. Üblich z.B. für Masseflächen. Die gleiche Technik kann auch verwendet werden, wenn man für Hochstromverbindungen mehrere Durchkontaktierungen parallel schalten möchte, wobei KiCad beim ziehen des Tracks nur eine  Durchkontaktierung setzt, und die anderen von Hand dazugesetzt werden müssen. &lt;br /&gt;
** Es gibt verschiedene Methoden. Je nach Geschmack. Siehe: http://www.mikrocontroller.net/topic/380550#new und https://www.youtube.com/watch?v=Hp5ngKtl7S4&amp;amp;list=PLJhdeJOBBRdnPgqcUiONoV4NLCo12f-jT&amp;amp;index=5&lt;br /&gt;
* Ich habe eine Platine, die von oben und unten bestückt ist. Wenn ich jetzt Bauteile zusammengruppiere, um sie gemeinsam zu verschieben, erwische ich immer alle Bauteile auf Vorder- und Rückseite. Wie bekomme ich das jetzt hin, das ich nur Module auf einer Seite bewege?&lt;br /&gt;
** Indem im Lagenmanager die Seite, die nicht bewegt werden soll, abgeschaltet wird. Siehe: http://www.mikrocontroller.net/topic/311586#new&lt;br /&gt;
* Wie bekommt man ein vernünftiges Boardoutline hin?&lt;br /&gt;
** http://www.mikrocontroller.net/topic/96060#1057511 &lt;br /&gt;
* Wie erstellt man ein rundes Loch, z.B. eine Befestigungsbohrung / nichtdurchkontaktierte Bohrung?&lt;br /&gt;
** VERALTET: http://www.mikrocontroller.net/topic/179308#1726990&lt;br /&gt;
** VERALTET:http://www.mikrocontroller.net/topic/120373#1122219 ?????&lt;br /&gt;
** KiCad kann mittlerweile auch direkt nichtdurchkontaktierte Bohrungen erzeugen. Siehe dazu http://www.mikrocontroller.net/topic/263069#2732405 Enthält auch allgemeine Informationen zum Umgang mit durchkontaktierten und nicht durchkontaktierten Bohrungen.&lt;br /&gt;
Da Löcher mit einem Durchmesser ab 2mm gefräst statt gebohrt werden können, und ab 6mm Durchmesser mit hoher Sicherheit gefräst werden, ist es sinnvoll, Löcher ab ca. 4mm Durchmesser in PCBnew mit dem Kreistool in das Layer &amp;quot;edge.cuts&amp;quot; zu zeichnen.&lt;br /&gt;
&lt;br /&gt;
* Ich möchte für Passermarken / Fiducials eine deutlich größere Freistellung in der Lötstoppmaske haben. Wie geht das?&lt;br /&gt;
** http://www.mikrocontroller.net/topic/266730#2779498&lt;br /&gt;
* Wie geht das überhaupt mit den Lötstoppmasken?&lt;br /&gt;
** http://www.mikrocontroller.net/topic/283721#new&lt;br /&gt;
* Ja, aber die Lötstoppmaske wird leider nicht angezeigt.&lt;br /&gt;
** http://www.mikrocontroller.net/topic/298028#new&lt;br /&gt;
* Ich möchte Text und Markierungen/Grafik statt im Bestückungsdruck im Lötstopplack erstellen. Geht das überhaupt und wie ist das zu bewerkstelligen?&lt;br /&gt;
** Das geht, und dazu ist der Text oder die grafischen Linien/Kreise direkt in die Lötstoppmaske zu schreiben. Siehe: http://www.mikrocontroller.net/topic/347702#new Die Lötstoppmasken Lagen heissen F.Mask (Bestückungsseite) und B.Mask (Lötseite).&lt;br /&gt;
* Ich möchte Text invers im Bestückungsdruck haben.&lt;br /&gt;
** Das geht. Siehe: http://www.mikrocontroller.net/topic/417961#4888742&lt;br /&gt;
* Wie kann man Bauteilmaße in den Ansichten (Footprint, Layout, 3D-View) anzeigen?&lt;br /&gt;
** Anzeige im Layout: Layer &amp;quot;Zeichnung&amp;quot; anwählen. In der rechten Menueleiste &amp;quot;Bemaßung hinzufügen&amp;quot; wählen. Das ist der fünfte Button von unten mit der &amp;quot;blauen Bemaßung&amp;quot;. Jetzt an einer Stelle links ins Layout klicken. Maus verschieben und noch einmal links klicken und die Maus seitlich verschieben. Es wird ein Maßpfeilsystem zwischen erstem und zweitem Mausklick angelegt, dessen höhe man mit der Maus einstellen kann. Ein weiterer linker Mausklick fixiert das System. Das Anklicken der Beschriftung mit der rechten Maustaste erlaubt das Editieren. Das System wird immer in der Einheit angelegt, die in der linken  Menueleiste vorgewählt wurde. Die Rasterung der aktuellen Einstellung wird auch übernommen. Späteres Ändern von Einheit- und Raster ändern die Beschriftung nicht mehr. In 3D und im Footprint geht diese Möglichkeit nicht.&lt;br /&gt;
** Weitere Möglichkeiten: Einen Maßstab als footprint/Modul anfertigen und zum Messen in das Board einfügen.&lt;br /&gt;
** Wenn man im Layout aber direkt etwas ausmessen möchte, so geht das über den relativen Nullpunkt. Unten im Rahmen rechts sind vier Felder. Die beiden linken zeigen die absoluten Koordinaten, an, die beiden rechten die relativen Koordinaten in Bezug auf einen relativen Nullpunkt. Defaultmäßig stimmen absoluter und relativer Nullpunkt ersteinmal überein. Per &amp;quot;Space bar&amp;quot; drücken setzt Du den relativen Nullpunkt an den Ort des Mauszeigers. Wenn Du nun die Maus verfährst, zeigen die relativen Koordinaten nun den vertikalen und horizontalen Abstand zum Nullpunkt. Die Diagonale muss leider über den Pythagoras selber ausgerechnet werden, oder indem man die Polarkoordinateneinstellung wählt (linke Menueleiste). Durch geschicktes setzten des Nullpunktes kann man nun auf der Platine herummessen. Winkel können auch über die Polarkoordinateneinstellung gemessen werden. Im Moduleditor geht das analog. Das 3D-View kann zur Zeit (Januar 2011) überhaupt keine Bemaßung.     &lt;br /&gt;
* Wie kann man mit der KiCad Version 20100314 &#039;&#039;&#039;einseitige&#039;&#039;&#039; Platinen erstellen?&lt;br /&gt;
** http://www.mikrocontroller.net/topic/172015#1651239&lt;br /&gt;
** aktueller: http://www.mikrocontroller.net/topic/172015#1794699&lt;br /&gt;
*Und wie teile ich KiCad mit, daß der Autorouter nur eine Seite verwenden soll?&lt;br /&gt;
** Auf die doofe Tour: Erst in KiCad zweiseitig wählen, und dann beide Lagen im Autorouter als &amp;quot;Unterseite&amp;quot; wählen.&lt;br /&gt;
&lt;br /&gt;
* Wie gehen runde Bögen in KiCad?&lt;br /&gt;
**http://www.mikrocontroller.net/topic/202512#1994063&lt;br /&gt;
* Ich brauche für einen Platinenumriss eine geschlossene Linie. Das klappt aber irgendwie nicht.&lt;br /&gt;
** Die Endpunkte müssen exakt aufeinander liegen. Dazu&lt;br /&gt;
*** A) Passende Raster verwenden&lt;br /&gt;
*** B) parametrisch die Endpunkte direkt als Koordinaten eingeben.&lt;br /&gt;
*** Siehe Diskussion dazu: https://www.mikrocontroller.net/topic/418296#new&lt;br /&gt;
* Wie benutze ich den interaktiven Router (Push &amp;amp; Shove) in PCBnew?&lt;br /&gt;
** Dazu muss in PCBnew im Pulldown-Menue unter &amp;quot;Ansicht&amp;quot; die Option &amp;quot;Canvas nach OpenGL umschalten&amp;quot; oder &amp;quot;Canvas nach Cairo umschalten&amp;quot;gewählt werden. Wenn man nun, wie gewohnt, aus der rechten Button Leiste das Verlegen von Leiterbahnen wählt, eine Leiterbahn/Luftlinie wählt und rechts anklickt, erhält man den interaktiven Router. Aber Achtung - wegen des geänderten Kontextmenues kann es sinnvoll sein, für andere Tätigkeiten auf die Voreinstellungen zurückzuschalten.&lt;br /&gt;
* Wie stelle ich beim Routen die Leiterbahnbreiten ein?&lt;br /&gt;
** Sie müssen vorher in den Design Rules definiert werden. Siehe: https://www.mikrocontroller.net/topic/452117#new&lt;br /&gt;
* Ich habe mein Board fertig geroutet, stelle aber jetzt fest, das ich noch einige Leiterbahnbreiten ändern muss. Wie geht das am einfachsten?&lt;br /&gt;
** Eine Leiterbahn rechts anklicken und Segment oder Track ändern. Das Verhalten ist im Detail vom gewählten Canvas anhängig. Und die Leiterbahnbreite muss schon in den Design rules existieren. Siehe hier: https://www.mikrocontroller.net/topic/452117#new&lt;br /&gt;
*** Ab KiCad 5.1 bzw. 6 wird es die verschiedenen Modi nicht mehr geben. Siehe https://www.mikrocontroller.net/topic/467735#5718645&lt;br /&gt;
* Wie gestalte ich einen gleitenden, stetigen Übergang bei einer Änderung der Leiterbahnbreite?&lt;br /&gt;
** Mit Workarounds wie dreieckigen/trapezförmigen Pads oder einem sehr fein gestaffelten stufigen Übergang. Siehe: https://www.mikrocontroller.net/topic/438242&lt;br /&gt;
**http://www.mikrocontroller.net/topic/205851#new&lt;br /&gt;
*Ich kann Pads nicht anschließen bzw. ich bekomme vom DRC Fehlermeldungen, daß ich Pads nicht angeschlossen habe, obwohl sie angeschlossen sind.&lt;br /&gt;
**http://www.mikrocontroller.net/topic/204717#new&lt;br /&gt;
*Wie kann ich Daten für automatische Bestückung (Pick&amp;amp;Place) erzeugen?&lt;br /&gt;
** In PCBnew unter Datei &amp;gt; Fertigungsdateien &amp;gt; Bauteile Positionsdatei (.pos). Aber dieses verlangt, das die Footprints auch die richtigen Informationen dazu enthalten. Um diese einzustellen, den Footprint im Moduleditor öffnen und unter dem Button &amp;quot;Bauteileigenschaften&amp;quot; in &amp;quot;Attribute&amp;quot; eine Markierung bei &amp;quot;Normal+Einfügen&amp;quot; machen. Dann wird der Ankerpunkt des Modules für die Positionsdatei verwendet. Damit sinnvolle Daten entstehen, sollte der Ankerpunkt bei SMD-Footprints in die Mitte des Footprintes gesetzt worden sein. &lt;br /&gt;
* Gibt es &amp;quot;Regeln&amp;quot; für das Setzten von Ankerpunkten bei Footprints?&lt;br /&gt;
** Es gibt Konventionen. Bei SMD-Bauteilen der &amp;quot;Mittelpunkt&amp;quot; des Bauteiles. Dieser wird auch für Pick&amp;amp;Place Daten in der automatischen Bestückung verwendet. &lt;br /&gt;
** Bei THT-Bauteilen wird als Konvention die Mitte von Pin 1 als Ankerpunkt verwendet.&lt;br /&gt;
*Und wie erzeuge ich ein Excellon Drillfile?&lt;br /&gt;
** In PCBnew unter Datei &amp;gt; Fertigungsdateien &amp;gt; Bohrdaten. Die Datei enthält auch eine Werkzeugliste. Kicad legt u.U. zwei Drillfiles an, wenn erforderlich. Eines für durchkontaktierte, und eines für nicht durchkontaktierte Bohrungen. Wer eine extra Liste und eine Statistik wünscht, muss auch noch &amp;quot;Bericht über Bohrung&amp;quot; anwählen.&lt;br /&gt;
** Bei mir wird aber nur ein Drillfile erzeugt. Was läuft falsch?&lt;br /&gt;
***Die NPTH Drills müssen im Pad-Editor explizit als solche gekennzeichnet werden. In PCBnew erkennt man sie dann als dicke gelbe Flächen. Siehe: http://www.mikrocontroller.net/topic/322941#3989397 Bei älteren Footprints ist das aber noch nicht komplett umgesetzt. &lt;br /&gt;
* Wenn PCBnew die Netzliste eingelesen hat, liegen alle Bauteile auf einem Haufen. Zum Plazieren eines herausgreifen ist mühsam. Wie geht das am einfachsten?&lt;br /&gt;
** In PCBnew &amp;quot;T&amp;quot; drücken. Es poppt ein Fenster auf, wo man die Bauteilreferenz (den Namen) eingeben kann. Und schon hängt das Bauteil zum Bewegen am Zeiger. Die Bedienung ist letztlich genauso wie das &amp;quot;m&amp;quot; und die Komandozeile in Eagle. Siehe http://www.mikrocontroller.net/topic/293903#3133990&lt;br /&gt;
** &amp;quot;Raef&amp;quot; hat ein Python Script erstellt, das Bauteile automatisch ähnlich der Anordnung im Schaltplan plaziert. Siehe: http://www.mikrocontroller.net/topic/293903#3245990&lt;br /&gt;
** In neueren PCBnew Version gibt es ein gutes parametrisches Plazieren: https://www.mikrocontroller.net/topic/432920#5108442&lt;br /&gt;
* Ich habe ein fertiges Layout. Jetzt möchte ich aber andere Footprints verwenden, und anschließend nicht neu routen müssen. Wie geht das?&lt;br /&gt;
** Über CVpcb und Neueinlesen der Netzliste. Siehe: http://www.mikrocontroller.net/topic/297885#new&lt;br /&gt;
* Ich will links herum routen, aber Kicad meint unbedingt rechts herum (...oder umgekehrt). Wie kann ich die Leiterbahnen &amp;quot;flippen&amp;quot;?&lt;br /&gt;
** Mit &amp;quot;/&amp;quot; (Slasch) http://www.mikrocontroller.net/topic/280028#new&lt;br /&gt;
* Ich hätte gerne die Tastenkürzel in kicad so wie in meinem gewohnten Programm. Wie geht das?&lt;br /&gt;
** Siehe http://www.mikrocontroller.net/topic/283959#3007173 . Vieleicht ist einer ja so nett, und stellt Konfigurationsfiles für Leute die aus EAGLE, ORCAD oder so wechseln, bereit.&lt;br /&gt;
* Ich habe ein kleines Board fertig geroutet. Jetzt möchte ich mehrere davon zu einer größeren Platine zusammenführen (sog. Mehrfachnutzen), um sie rationeller fertigen zu können.&lt;br /&gt;
** Siehe http:http://www.mikrocontroller.net/topic/292334#new . Das geht natürlich genauso, wenn man verschiedene Platinen so zu Nutzen zusammenfügen möchte, oder halt kleinere Teillayouts zu einem Gesamtboard.&lt;br /&gt;
*** Nachtrag: Wenn in PCBnew &amp;quot;append Board&amp;quot; oder &amp;quot;save as&amp;quot; ausgegraut sind, so schliesse KiCad Eeschem und PCBnew komplett und starte PCBnew direkt ohne über KiCad zu gehen. Das ist in neueren KiCad Versionen so vorgesehen. Siehe https://www.mikrocontroller.net/topic/399145#new&lt;br /&gt;
&lt;br /&gt;
* Ich habe einen Schaltplan mit Subschaltplänen, zu denen ich separate Layouts erstellen möchte.&lt;br /&gt;
** Dazu diesen Subschaltplan explizit in EEschema öffnen, und die Netzliste nur für diesen Subschaltplan exportieren.  Weitergehen wie üblich. Siehe: http://www.mikrocontroller.net/topic/330740#new&lt;br /&gt;
* Ich möchte Varianten eines Layouts erstellen. Was ist dazu zu sagen? Siehe: http://www.mikrocontroller.net/topic/330740#3616697&lt;br /&gt;
** Siehe http://www.mikrocontroller.net/topic/292123#new&lt;br /&gt;
* Wie importiere ich DXF-Dateien in PCBnew? z.B. ein Platinenumriss aus einem mechanischen CAD-Programm?&lt;br /&gt;
** Dafür existiert eine Import Funktion in PCBnew: Datei &amp;gt; Importieren &amp;gt; DXF-Datei. Siehe http://www.mikrocontroller.net/topic/327628#new &lt;br /&gt;
aktueller: https://www.mikrocontroller.net/topic/469438#new&lt;br /&gt;
* Wie wird man den merkwürdigen Rahmen los?&lt;br /&gt;
** 1) Genauso wie im Schaltplan. Dazu den pl_editor (der ganz rechte Button im KiCad Hauptfenster) starten, und FAST alles entfernen. Dazu in der linken Spalte nacheinander alles aktivieren, und mit rechts anlicken und dann &amp;quot;entfernen&amp;quot; wählen. Aber vorsicht, wenn alles Entfernt wird, taucht das Original Layout wieder auf. Workaround war bei mir, eine zusätzliche Alibilinie hinzuzufügen, die von X 0,000 Y 0,000 bis  X 0,001 Y 0,000 reicht. Das ist ein &amp;quot;Fliegenschiss&amp;quot; in der linken oberen Ecke. Jetzt kann alles andere gelöscht werden. Den so geleerten Rahmen unter einem beliebigen Namen mit der Endung .kicad_wks wegspeichern. Im geöffneten Schaltplan kann der dann unter Datei &amp;gt; Seite einrichten ganz unten unter &amp;quot;page layout file description&amp;quot; die entsprechende Datei eingebunden werden. Es bleibt aber dem Anwender offen, ob er den Rahmen komplett entfernt, oder noch Felder mit Textbeschreibungen übernimmt. Für gesteigerten Komfort kann diese Datei dann auch in ein Template eingebunden werden. &lt;br /&gt;
** 2) Beim Ausdrucken Frame deaktivieren.&lt;br /&gt;
** 3) Als SVG exportieren. Dort den Frame deaktivieren.&lt;br /&gt;
** 4) Beim Plotten (z.B. in Gerber) Frame deaktivieren. Ist eigentlich defaultmäßig eingestellt. &lt;br /&gt;
** Siehe: http://www.mikrocontroller.net/topic/343509#3791448&lt;br /&gt;
* Ich möchte einen bestimmten Footprint verwenden (von dem ich weiss, dass er existiert), kann ihn aber in der Auswahl der Footprints von PCBnew nicht finden.&lt;br /&gt;
**Die Bibliothek, in der er enthalten ist, muss erst in das Verzeichnis der aktiven Bibliotheken in PCBnew eingetragen werden. &lt;br /&gt;
* Ich möchte Footprint-Bibliotheken in das Verzeichnis der verwendeten Bibliotheken von PCBnew eintragen. Wie geht das?&lt;br /&gt;
** https://www.mikrocontroller.net/topic/372123#new  &lt;br /&gt;
* Ich habe Probleme mit den Umgebungsvariablen KISYSMOD, KISYS3DMOD, KIPRJMOD, KIGITHUB beim Eintragen der Bibliothekstabellen.&lt;br /&gt;
** KISYSMOD ist eine Variable, die den Pfad zu den global verwendeten KICAD-Modulen (Footprints) angibt. KIPRJMOD ist das gleiche, für projektspezifische Module. KISYS3DMOD beschreibt den Pfad zu den 3D-Modellen, und KIGITHUB weisst den Pfad ins Internet zu den Githubbibliotheken.&lt;br /&gt;
** Nähere Informationen dazu findet man hier: http://www.mikrocontroller.net/topic/344139#new und hier : http://www.mikrocontroller.net/topic/344029#new&lt;br /&gt;
** Aktueller: http://www.mikrocontroller.net/topic/368660&lt;br /&gt;
** Falls alles nichts hilft: Nan kann den Pfad auch komplett am Stück in die Bibliothekstabelle eintragen. Copy&amp;amp;Paste funktioniert dort aber nicht per rechtem Mausklick, sondern per &amp;lt;Str-c&amp;gt; (Kopieren) und &amp;lt;Str-v&amp;gt; (einfügen). Einfacher als die Bibliothekstabelle lässt sich darum die fp-lib-table Datei per Editor bearbeiten. Unter Linux findet sich die Tabelle für globale Bibliotheken bis zur BZR5113 direkt im Homeverzeichnis. Ab BZR5114 (ca. 5. September 2014) fiondet sich die globale fp-lib-table in $HOME/.config/kicad. Die fp-lib-table für projektbezogene Bibliotheken finden sich in den korrespondierenden  Projektverzeichnissen.&lt;br /&gt;
* Ich würde gerne die Mikrowellen Tools verwenden, aber irgendwie funktioniert das nicht.&lt;br /&gt;
** In älteren KiCad Versionen funktionieren sie nur im &amp;quot;legacy Canvas&amp;quot;. Den &amp;quot;legacy Canvas&amp;quot; schaltet man mit &amp;quot;F9&amp;quot; ein, bzw. im Pull down Menue unter &amp;quot;View&amp;quot; &amp;gt; &amp;quot;legacy Canfas&amp;quot;. In neueren KiCad Versionen (daily Build ab mindestens 2017-06-16 revision dab73e1) funktionieren die Tools in allen Canvasversionen.&lt;br /&gt;
** Manchmal sieht man nur etwas, wenn man &amp;quot;Refresh&amp;quot; (F3) drückt.&lt;br /&gt;
** Eine kleine Erklärung ist hier: https://www.mikrocontroller.net/topic/434998#new&lt;br /&gt;
* Ich würde gerne aus den Mikrowellen Tools die Funktion &amp;quot;Polynominales Muster&amp;quot; verwenden. Dabei werde ich nach einem KiCad-Shapefile gefragt, aber ich weiss nicht, wie das File aussehen muss.&lt;br /&gt;
** Einen Hinweis zum Aussehen des Files gibt es hier: https://www.mikrocontroller.net/topic/369330#4166392 Allerdings müssen die Werte der Polynomstruktur anderweitig berechnet werden, und mit einem Editor manuell in diese Form gebracht werden.&lt;br /&gt;
* Wie erstelle ich koplanare Leitungen in KiCad?&lt;br /&gt;
** siehe diese Diskussion: https://www.mikrocontroller.net/topic/370700#new&lt;br /&gt;
* Ich möchte Bauteile im Kreis oder in einem Gittermuster/Array anordnen. Gibt es dafür automatische Hilfestellungen?&lt;br /&gt;
** Ja. Objekt Deiner Wahl rechts anklicken, eventuell Auswahl verfeinern, und dann im aufpoppenden Menue &amp;quot;Array erstellen&amp;quot; wählen. Geht nicht nur für Bauteile, sondern auch für Pads, Leiterbahnen ec. Siehe: http://www.mikrocontroller.net/topic/178816#new&lt;br /&gt;
* Ich bräuchte Pads mit ungewöhnlicher Form.&lt;br /&gt;
** Aus mehreren Pads mit der gleichen Pad Nummer zusammensetzten. Pads gleicher Nummer am gleichen Footprint werden dem gleichen Netz zugeordnet. Dabei aber beachten, dass sich diese Pads sich weit genug überlappen (z.B. 0,2mm) , so dass sie nicht in einzelne Pads zerfallen, wenn in der Leiterplattenfabrik mal die Kupferflächen &amp;quot;zurückgezogen&amp;quot; werden müssen, um die Mindestabsrände für die Produktion (Galvanik) nicht zu unterschreiten.&lt;br /&gt;
** Das Mikrowellentool benutzen, um mit einem Workaround Pads als Polygon zu erzeugen. Als ein Beispiel z.B:https://www.mikrocontroller.net/attachment/259709/SMP-Test-1.png Das Mikrowellentool kannst Du mit einem Workaround dazu bekommen, Pads als Polygone zu erstellen. Näheres siehe hier: https://www.mikrocontroller.net/topic/414834#new oder hier: https://www.mikrocontroller.net/topic/369330#4166392&lt;br /&gt;
* Meine Grafikkarte unterstützt keine openGL 3D-Beschleunigung.&lt;br /&gt;
** Vieleicht kannst Du mit MESA openGL ersetzten? Siehe: https://www.mikrocontroller.net/topic/389712#4465775 Zu MESA selber siehe: https://de.wikipedia.org/wiki/Mesa_3D&lt;br /&gt;
* Ich würde gerne eine Starrflex Leiterplatte machen. Was muss ich beachten?&lt;br /&gt;
** Siehe https://www.mikrocontroller.net/topic/399330#new&lt;br /&gt;
* Wie Verbinde ich verschiedene Massen, oder allgemein verschiedene Potentiale, die aus Layouttechnischen Gründen getrennt gehalten werden sollten, ohne das der DRC zusehr meckert? Ähnliches Problem: Einzelne Vias vom Anschluss an umgebende Masseflächen ausschliessen.&lt;br /&gt;
** Voraussetzung: Die Leiterbahnen/Vias/Kupferflächen müssen unterschiedliche Potentiale haben, damit KiCad weiss, dass sie getrennt gehalten werden müssen. Wenn das nicht der Fall ist, müssen diese Segmente mit einem &amp;quot;Bauteil&amp;quot; so vom Rest der Schaltung abgedretnnt werden, dass der abgetrennte Bereich einen neuen Netznahmen/Potentialnahmen bekommt. Diese speziellen Bauteile können unterschiedlicher Art sein:&lt;br /&gt;
*** 1) Mit 0 Ohm Brücken. Das sind Bauteile, die aus einer Drahtbrücke bestehen. So sind für den ERC und DRC die Netzte getrennt, aber tatsächlich mit einer Drahtbrücke verbunden. &lt;br /&gt;
**** [http://www.mikrocontroller.net/topic/142930?goto=1321550] &amp;quot;Drahtbrücken in KiCad?&amp;quot;  hier im Forum.&lt;br /&gt;
*** 2) Ein anderer Workaround sind &amp;quot;Net ties&amp;quot; (Netties). Das sind Footprints, die aus zwei oder mehr verschiedenen Pads bestehen(wie jedes andere normale Bauteile auch, die aber direkt mit Kupfer verbunden sind. Also eigentlich ein 0 Ohm Widerstand, wo der &amp;quot;Widerstand&amp;quot; als Kupfer auf der Leiterplatte existiert. Es ist sinnvoll, zu den &amp;quot;Net tie&amp;quot; Footprints auch entsprechende Schaltplansymbole zu definieren. Zu Net ties siehe:&lt;br /&gt;
**** [http://www.grant-trebbin.com/2015/04/pcb-net-ties-and-grounding-in-kicad.html] (in Englisch)&lt;br /&gt;
**** [http://www.mikrocontroller.net/topic/330196] &amp;quot;KiCad zwei verschiedene Netze verbinden in Pcbnew&amp;quot; hier im Forum.&lt;br /&gt;
**** Etwas aktueller (geht auch auf Probleme ein): &lt;br /&gt;
***** [http://www.mikrocontroller.net/topic/389988] &amp;quot;Kicad Leiterbahn im Footprint möglich?&amp;quot; hier im Forum.&lt;br /&gt;
***** [http://www.mikrocontroller.net/topic/360510] &amp;quot;Leiterbahn aus Massepolygon isolieren&amp;quot; hier im Forum.&lt;br /&gt;
***** [https://www.mikrocontroller.net/topic/401430#new] &amp;quot;Via-Anbidung an Polygon ausschließen&amp;quot;&lt;br /&gt;
***** Ein ganz anderer Ansatz wäre, ganz auf unterschiedliche Massepotentiale zu verzichten, wenn diese sowieso verbunden werden, wie hier vorgeschlagen: https://www.mikrocontroller.net/topic/453991#5465447&lt;br /&gt;
* Wie kann man den Nullpunkt eines Layouts verschieben?&lt;br /&gt;
** http://www.mikrocontroller.net/topic/179680#1730452 Aktueller:https://www.mikrocontroller.net/topic/427130#5008806 für den Layout Editor PCBnew. Im Moduleditor bei Erstellung eines Footprints kann man den Ankerpunkt frei Mithilfe des Anker-Tools aus der rechten Menüleiste (das Ankersymbol) setzten. Gleiches gilt für den Symboleditor.&lt;br /&gt;
* Ich habe im Layout einen weissen Kringel mit einem weissen Kreuz, der sich beim Zoomen merkwürdig verhält. Was ist das, und wie kriege ich das weg?&lt;br /&gt;
** Das ist der Ursprung des Rasters. Den sollte man nicht wegbekommen, aber man kann ihn versetzten. Siehe: https://www.mikrocontroller.net/topic/411681#new&lt;br /&gt;
* Wie erzeuge ich Thermals (Wärmefallen/thermal Pads) um Pins die in Kupferflächen sitzen?&lt;br /&gt;
** https://www.mikrocontroller.net/topic/443639#5287943&lt;br /&gt;
* Ich möchte Langlöcher anlegen. Wie geht das am einfachsten?&lt;br /&gt;
** Als Footprint bzw. im Footprint im Footprinteditor anlegen. Dort ein Pad plazieren und als &amp;quot;Drill Shape&amp;quot; die Option &amp;quot;Oval hole&amp;quot; wählen. Den Rest des Footprints mit dem Kupfer nach eigenen Bedürfnissen gestalten, oder das Kupfer ganz weglassen. Für reine Befestigungslöcher ohne Kupfer &amp;quot;Pad type&amp;quot; zu &amp;quot;NPTH, Mechanical&amp;quot; wählen. Langlöcher landen genauso wie runde Löcher im Excellon Drill-File. Es gibt dort spezielle Kennzeichnungen dafür. Um mit dem &amp;quot;Workflow&amp;quot; konform zu bleiben, für Befestigungslöcher z.b. ein Symbol anlegen, dem ein passendes Loch oder auch Langloch als Footprint zuweisen. In einem extra hierachischen Schaltplanblatt solche Sonderfälle ablegen. Für vier löcher z.B. vier mal dieses Symbol. Es lassens sich den Symbolen unterschiedlich definierte Löcher zuweisen. Die Löcher werden dann beim Einlesen der Netzliste in PCBnew gemäß der eingetragenen Footprints auf das Board gestellt und können frei plaziert werden. Siehe: https://www.mikrocontroller.net/topic/449952#5395495&lt;br /&gt;
* Wie ist das mit der Pinnummerierung bei Symbolen und Footprints mit abweichenden Pinbelegungen? Ändere ich die Pin/Pad Nummerierung im Symbol oder im Footprint?&lt;br /&gt;
** Das hängt am Einzelfall. Aber meistens ist das Anlegen einer Symbolvariante unter anderem Namen mit geändertem Pinning am sinnvollsten. Es gibt aber Sonderfälle. Genaueres steht hier: https://www.mikrocontroller.net/topic/452154#new&lt;br /&gt;
&lt;br /&gt;
=== Layout: Python Scripting ===&lt;br /&gt;
&lt;br /&gt;
Das Python2-Scripting ist bisher nur in PCBnew implementiert und noch sehr experimentell. Daher ist leider auch der aktuelle Stand der Dokumentation zum Python-Skripting in PCBnew noch etwas dürftig. Trozdem hier Links dazu:&lt;br /&gt;
* http://confluence.kicad-pcb.org/display/KICAD/KiCad+Scripting+Reference+Manual (Allgemein. Achtung! Kicad braucht beim compilieren spezielle Befehle, um Python-Scripting tauglich zu sein.)&lt;br /&gt;
* http://ci.kicad-pcb.org/job/kicad-doxygen/ws/build/pcbnew/doxygen-python/html/namespacepcbnew.html (Definitionen von Namespaces, Classes und Files)&lt;br /&gt;
&lt;br /&gt;
Für Linux-Debian:&lt;br /&gt;
Aktuell (07. Februar 2014) mit  Pcbnew Version: (2014-01-27 BZR 4641)-product Release build auf&lt;br /&gt;
Platform: Linux 3.2.0-4-686-pae i686, 32 bit, Little endian, wxGTK (Debian Wheezy) gilt:&lt;br /&gt;
* Geht aktuell nur für PCBnew.&lt;br /&gt;
* Klassenbibliotheken: Zwei Dateien pcbnew.py und _pcbnew.so auf dem Pfad: /usr/lib/python2.7/dist-packages/&lt;br /&gt;
* Die Klassenbibliothek wird mit den üblichen Python2 Methoden importiert: z.B. &amp;quot;import pcbnew&amp;quot; oder &amp;quot;from pcbnew import *&amp;quot; &lt;br /&gt;
&lt;br /&gt;
Beispielprogramm, das alle Footprints aus einer Legacy-Fotprint Datei auflisted und den Referenzbezeichner dazuschreibt::&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python &lt;br /&gt;
# das war das Shebang.&lt;br /&gt;
&lt;br /&gt;
from pcbnew import * # Import der Bibliothek. &lt;br /&gt;
libpath = &amp;quot;/home/DuUser/KiCad-Daten/Module/ModuleGrosserSampler/KiCadLegacyFottprints.mod&amp;quot; # Übergabe des Pfades.&lt;br /&gt;
lst = FootprintEnumerate(libpath) &lt;br /&gt;
for name in lst:&lt;br /&gt;
    m = FootprintLoad(libpath,name)&lt;br /&gt;
    print name,&amp;quot;-&amp;gt;&amp;quot;, m.GetReference()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Scripting Möglichkeit ist so neu, dass bis jetzt die Scripting Testdateien für das KiCad interne automatische Qualitätssicherungssystem noch nicht komplett sind.&lt;br /&gt;
Unter http://bazaar.launchpad.net/~kicad-product-committers/kicad/product/files/head:/qa/testcases/ finden sich bereits geprüfte Testskripte, und unter http://bazaar.launchpad.net/~kicad-product-committers/kicad/product/files/head:/pcbnew/scripting/examples/ finden sich ungetestete Testskripte.&lt;br /&gt;
&lt;br /&gt;
Sie alle können als Beispiele genommen werden, wie das mit dem Skripting gemeint ist, und als Vorbild für eigene Skripte dienen.&lt;br /&gt;
&lt;br /&gt;
Weitere Skripting Info: &lt;br /&gt;
* [https://kicad.mmccoo.com/kicad-scripting-table-of-contents/ Anleitung für Python Skripting in KiCad] (Englisch)&lt;br /&gt;
&lt;br /&gt;
=== Module Editor ===&lt;br /&gt;
* Wie erstellt man Footprints für Bauteile?&lt;br /&gt;
** Mit dem Footprint Editor. Er ist bei älteren KiCad Versionen nur aus PCBnew heraus zu starten. Bei neueren KiCad Versionen hat er einen eigenen Button im KiCad Start Window.&lt;br /&gt;
** Spezielleres: http://www.mikrocontroller.net/topic/356151#new&lt;br /&gt;
* Wie verbinde kopiere ich etwas aus einem Footprint in einen anderen hinein, bzw. wie verbinde/merge ich zwei Footprints?&lt;br /&gt;
** http://www.mikrocontroller.net/topic/288167#3061997&lt;br /&gt;
* Kann man im Module Editor die Eigenschaften aller Pads gleichzeitig ändern?&lt;br /&gt;
** http://www.mikrocontroller.net/topic/93131#799550 &lt;br /&gt;
* Ich brauche einen Footprint, bei dem mehrere Pads verbunden sind, will aber nicht im Schaltplan zig Pins aufführen und anschliessen müssen.&lt;br /&gt;
**http://www.mikrocontroller.net/topic/208982#new&lt;br /&gt;
**http://www.mikrocontroller.net/topic/204717#new&lt;br /&gt;
* Wie erzeugt man thermal Vias in Kicad?&lt;br /&gt;
** Leider bisher nur experimentell: http://www.mikrocontroller.net/topic/298028#3187259&lt;br /&gt;
* Wie kann man Bauteilmaße in in den Ansichten (Footprint, Layout, 3D-View) anzeigen?&lt;br /&gt;
* Wie verwalte ich Footprint Bibliotheken?&lt;br /&gt;
** Indem man sich ein Board erstellt, alle Footprints, die man zusammenfassen möchte, auf das Board stellt, und dann untet Dateien &amp;gt; Footprints archivieren &amp;gt; Footprint Archiv erstellen wählt. Das so erstellte Board kann auch zu Dokumentationszwecken geplottet werden. Eventuell möchte man einige Footprints, die zu Hilfszwecken (z.B. Skalen) auf dem Board sind, anschliessend mit dem Bibliothekseditor daraus löschen.&lt;br /&gt;
** Alternativ, im dem &amp;quot;neuen&amp;quot; *.pretty Format, mit einem Dateiverwaltungsprogramm Deiner Wahl. Siehe http://www.mikrocontroller.net/topic/320301#new&lt;br /&gt;
* Wie werden die Parameter für Lötpaste/Lötstopmaske vergeben?&lt;br /&gt;
**http://www.mikrocontroller.net/topic/356151&lt;br /&gt;
* Ich möchte für einen Footprint Pads in einem Gittermuster/Array oder im Kreis anordnen. Gibt es dafür automatische Hilfestellungen?&lt;br /&gt;
** Ja. Pad rechts anklicken. Eventuell erfolgt noch eine Feinauswahl. Dann im aufpoppenden Menue &amp;quot;Array erstellen&amp;quot; wählen.&lt;br /&gt;
* Wie archiviere ich die in einem KiCad Board enthaltenen Footprints?&lt;br /&gt;
** Nicht im Footprint-editor, sondern in PCBnew. Dort in der oberen Toolleiste unter Datei/File &amp;gt; archive Footprints. Es muss dort eine bereits im Bibliotheksverzeichnis eingetragene existierende Bibliothek angegeben werden. &#039;&#039;&#039;Achtung:&#039;&#039;&#039; Diese Bibliothek sollte &#039;&#039;&#039;speziell für diesen Zweck&#039;&#039;&#039; angelegt sein, weil ihr &#039;&#039;&#039;vorheriger Inhalt komplett entfernt&#039;&#039;&#039; wird. Idealerweise legt man die Bibliothek als &amp;quot;Projektname.pretty&amp;quot; im Projektordner an. Sie sollte spätestens bei Abschluss des Projektestens erstellt werden und &#039;&#039;&#039;MUSS bei Archivierung des Projektes oder Übergabe mit Archiviert bzw. Übergeben werden!&#039;&#039;&#039; Aber &#039;&#039;&#039;VORSICHT&#039;&#039;&#039;, bei der Bibliothekserstellung lauert ein &#039;&#039;&#039;Bug. Siehe:&#039;&#039;&#039; https://www.mikrocontroller.net/articles/KiCad#Problem:_Neue_leere_Footprintbibliothek_kann_nicht_erstellt_werden_.28kicad_Version:_4.0.0.7Erc1a-stable_release_build_.2F_RC4.29&lt;br /&gt;
* Ich brauche in einem Footprint einen Ausschnitt in der Platine. Wie mache ich das?&lt;br /&gt;
** https://www.mikrocontroller.net/topic/404998#4696232&lt;br /&gt;
* Für Masken wie Lötpaste oder Klebstoff hätte ich gerne Pads mit abgerundeten Ecken. Wie geht das?&lt;br /&gt;
** Das geht erst seit ca. Version: 2016-11-22 revision ccdfabc-master. Siehe https://www.mikrocontroller.net/topic/427536#5015335&lt;br /&gt;
&lt;br /&gt;
=== 3D-Ansicht ===&lt;br /&gt;
[[Bild:Kicad xilinx demo.jpg|300px|thumb|right|KiCAD-Demoplatine exportiert und mit Renderer illustriert]]&lt;br /&gt;
KiCAD bietet eine eingebaute einfache 3D-Ansicht der gerouteten Platine. Mittels Export können diese weiterverarbeitet werden. KiCad beruht diesbezüglich auf Wings3D, und die 3D-Modelle der Bauteile sind standardisierte wrl-files, die mit entweder Wings3D oder Blender erstellt werden können. Daher sei hier auf ein Wings3D Handbuch verwiesen: http://www.oortman3d.com/wings3d/TheWings3dHandbook.pdf&lt;br /&gt;
&lt;br /&gt;
Viele Bauteilhersteller (vor allem von eher mechanischen, wie z.B. Stecker, Buchsen, Befestigung...) bieten fertige 3D-Modelle an. Diese sind meistens in den Formaten STEP oder IGES. So kann man diese in das von KiCad benötigte .wrl (VRML 2.0) konvertieren:&lt;br /&gt;
# STEP oder IGES in [http://gcad3d.org/ gCAD3D] öffnen (File &amp;gt; Open Model)&lt;br /&gt;
# als Wavefront .obj speichern (File &amp;gt; Save Model as &amp;gt; OBJ)&lt;br /&gt;
# Das .obj in [http://www.wings3d.com/ Wings 3D] importieren (File &amp;gt; Import &amp;gt; Wavefront .obj)&lt;br /&gt;
# Als VRML 2 exportieren (File &amp;gt; Export &amp;gt; VRML 2.0 .wrl)&lt;br /&gt;
# Im KiCad-Moduleditor die .wrl-Datei als 3D-Modell auswählen&lt;br /&gt;
# Eventuell muss man die Skalierung und Positionierung anpassen, die angezeigten Pads und Löcher helfen dabei. Die am meisten benötigten Faktoren dürften dabei 0,3937 und 2,54 sein - bei den Konvertierungen kommt leicht die Einheit Zoll oder cm durcheinander.&lt;br /&gt;
&lt;br /&gt;
Eine andere Möglichkeit .obj oder .stl-Dateien aus STEP und IGES zu erzeugen ist [http://free-cad.sourceforge.net/ FreeCAD]. Obwohl es auch .wrl direkt erzeugen kann, können diese nicht in KiCad geladen werden. Der Umweg über .obj oder .stl und Wings 3D löst dies aber auch hier.&lt;br /&gt;
&lt;br /&gt;
Wenn man das Board wieder in einem CAD-Programm verwenden will um z.B. ein Gehäuse zu konstruieren, sollte man wieder STEP-Dateien erzeugen. Neuere KiCad-Versionen können zwar VRML exportieren, doch das beschreibt nur Umrisse und keine Körper (Solids). CAD-Programme zum Gehäusedesign brauchen jedoch letzteres. So geht die Konvertierung:&lt;br /&gt;
# VRML aus KiCad exportieren (File &amp;gt; Export &amp;gt; VRML)&lt;br /&gt;
# .wrl-Datei mit Hilfe von [http://www.cs.princeton.edu/~min/meshconv/ meshconv] in eine STL-Datei konvertieren: &amp;lt;code&amp;gt;meshconv boardname.wrl -c stl -o boardname.stl&amp;lt;/code&amp;gt;&lt;br /&gt;
# Die STL-Datei mit [http://www.solveering.com/products/products_stl2step.html stl2step] in eine STEP-Datei konvertieren&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ACHTUNG:&#039;&#039;&#039;&lt;br /&gt;
Man sollte hinterher im CAD nochmal genau die Maße kontrollieren. Denn die Konvertierung von STL nach STEP ist nur eine Approximierung und keine exakte, verlustfreie Konvertierung.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ACHTUNG:&#039;&#039;&#039;&lt;br /&gt;
Bei der Verwendung von Modellen aus fremden Quellen die Rechtslage prüfen. Es kann bei Veröffentlichungen zu Problemen führen, wenn die verwendeten Modelle unter einer problematischen privaten Lizenz stehen!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Appropos Einheit: Welche Einheit benutzt WRL (Wings3d)?&lt;br /&gt;
* Das ist leider nicht soooo klar. Tatsache ist aber, das KiCad die Einheit als 1/10 Inch (100mil) interpretiert.&lt;br /&gt;
** Es könnte sein, dass die Einheit von WRL offiziell mal zu einem Meter gedacht war. Siehe: https://www.mikrocontroller.net/topic/405477#4704394&lt;br /&gt;
&lt;br /&gt;
*Und wie bedient man Wings3d?&lt;br /&gt;
** Ein (vorläufiger) Merkzettel/Ultrakurzanleitung zur Bedienung von Wings3D findet sich hier: [[Media:Kicad-Wings3D_Merkzettel_29November2012.pdf]]. Wenn man nur mit Wings3d Modelle für Kicad erstellen will, langt das eventuell schon als Tutorial. There is also an English translation of this leaflet about using wings3d for kicad  at [[Media:Kicad-Wings3D_Leaflet_25April2013.pdf]].&lt;br /&gt;
** Aktueller: [http://roberthall.net/Wings3D_Tutorial_KiCad Tutorial zur Benutzung von Wings3D im KiCad Umfeld (englisch)]&lt;br /&gt;
&lt;br /&gt;
Weitere Diskussionen um KiCAD 3D:&lt;br /&gt;
* Die 3D-Ansicht funktioniert bei mir nicht.&lt;br /&gt;
** http://www.mikrocontroller.net/topic/289075#new&lt;br /&gt;
** https://www.mikrocontroller.net/topic/404658#new&lt;br /&gt;
* Kann man die 3D-Ansicht in ein 3D-CAD Programm exportieren? &lt;br /&gt;
**http://www.mikrocontroller.net/topic/203388#new&lt;br /&gt;
* Wie kann man Bauteilmaße in in den Ansichten (Footprint, Layout, 3D-View) anzeigen?&lt;br /&gt;
&lt;br /&gt;
* Irgendwie werden meine 3D-Bibliotheken nicht gefunden.&lt;br /&gt;
** Das kann z.b. passieren, wenn eine KiCad v5 3D-bibliothek mit einer v4 Bauteilebibliothek verwendet wird. Siehe:https://www.mikrocontroller.net/topic/467178#new&lt;br /&gt;
* Ich habe 3D-Modelle/STEP-Modelle von einem Hersteller heruntergeladen. Aber nach Einbindunge liegen sie neben dem Footprint, schweben darüber oder durchdringen die Platine.&lt;br /&gt;
** Der Hersteller hat einen anderen Ursprung für sein Modell gewählt als üblich ist. Weit verbreitet ist, den Bauteil/Footprint Ursprung bei THT Bauteilen auf die &amp;quot;Mitte&amp;quot; von Pin 1 zu setzen. Bei SMD Bauteilen wird der Ursprung auf die Mitte des Bauteiles gesetzt, meint, da wo sich beide Symmetrieachsen des Bauteiles schneiden. Bleibt das Problem, wenn das Bauteil nur eine Symmetrieachse hat. Dann einen Punkt auf der Symmetrieachse wählen, der die Mitte zwischen den extremsten Bauteilgrenzen bildet. Wenn keine Symmetrie überhaupt existiert, halt irgendwo etwas &amp;quot;in der Mitte&amp;quot;. Das ist dann aber immer soweit in der Nähe des Footprints, dass Du es in KiCad selber anpassen kannst. Angepasst wird das entweder im Footprinteditor in der oberen Buttonleiste &amp;quot;footprint Eigenschaften&amp;quot; (Icon IC mit Zahnrad davor). Es poppt ein Fenster auf. Dort den zweiten Reiter von Links wählen: &amp;quot;3D-einstellungen&amp;quot;. Dort können Korrekturwerte für koordinaten, Skalierung und Drehungen angegeben werden. Siehe Diskussion: https://www.mikrocontroller.net/topic/467095#new&lt;br /&gt;
&lt;br /&gt;
=== Drucken/Plotten/Gerber Export/Excellon Drillfiles Export ===&lt;br /&gt;
&lt;br /&gt;
==== Drucken ====&lt;br /&gt;
* Wie exportiert man den Schaltplan oder das Layout als Bild (PNG o.ä.)? &lt;br /&gt;
** Drucken über Postscript-Treiber und Umwandeln mit Ghostscript&lt;br /&gt;
** [http://www.mikrocontroller.net/topic/96060#1061492]&lt;br /&gt;
** Plot to Clipboard [http://www.mikrocontroller.net/topic/117562#1056566]&lt;br /&gt;
* Wie kann ich GENAU ausdrucken? Mein Ausdruck auf ABC ist ca. X % zu klein oder Y% zu groß! &lt;br /&gt;
** So genau sind einfache Drucker bzw. Druckertreiber selten. Aber meistens hilft folgendes: Mache einen 1:1 (100%) Probeausdruck. Messe auf dem Ausdruck nach, wie groß er tatsächlich geworden ist. Berechne die Abweichung und gebe sie in den Drucker bzw. Druckertreiber unter Einstellung ein, vorausgesetzt, der Drucker bzw. Druckertreiber kann das. Mit dem Wert machst Du wieder eine Probeausdruck, messe wieder nach, und wenn es mit der Einstellung funktioniert hat, kannst Du Deine Folie bedrucken. Wenn das nicht klappen kann, weil Du stark abweichende Werte für horizontal und vertikal bräuchtest, aber der Drucker nur einen gleichen Wert für beides kennt, hast Du einen (zu) schlechten Drucker. Trozdem nicht verzweifeln, weil KiCad beim Drucken oder Plotten in der X- und Y-Achse getrennt skalieren kann. Aber Vorsicht bei Weitergabe der so erzeugten Dateien: Sie sind individuell auf einen Drucker angepasst, und produzieren auf einem anderen Drucker nur falsch skalierte Ausdrucke. Weil der Wert von Drucker zu Drucker unterschiedlich ist, ist es auch sinnvoll, diese Skalierung direkt am speziellen Drucker/Druckertreiber zu machen. Tipp: Wenn Du den Wert erfolgreich ermittelt hast, so kleb Dir einen Zettel auf den Drucker mit dem Wert. Die Werte sind zwar individuell für jeden Drucker, aber meistens für den speziellen Drucker durchaus fix. Und Du hast ihn sofort wieder parat, wenn der Drucker resettet wurde. Dies ist übrigens ein allgemeiner Tipp für das Ausdrucken, der auch für Eagle, Target, Altium usw. gilt.&lt;br /&gt;
** Thema Skalieren - Die aktuelle Situation (August 2013): http://www.mikrocontroller.net/topic/304619#new &lt;br /&gt;
** Und nochmal Thema Skalieren: http://www.mikrocontroller.net/topic/371079#4191106&lt;br /&gt;
* Wie kann man das Layout invers ausdrucken, d.h. alle Leiterbahnen und Pads müssen weiß bleiben, der Rest wird schwarz ausgedruckt?&lt;br /&gt;
** Beim Plotten den Haken bei Negativ-Plot setzen [http://www.mikrocontroller.net/topic/156202#1474507]&lt;br /&gt;
* Ich habe irgendwie Probleme mit dem Ausdrucken.&lt;br /&gt;
** Verzerrt: http://www.mikrocontroller.net/topic/207764#new&lt;br /&gt;
** Sonderzeichen: http://www.mikrocontroller.net/topic/207310#new&lt;br /&gt;
** In der aktuellen Version 2012-01-19 BZR 3256)-stable besteht ein generelles Druckproblem. Aber Plotten geht wunderbar!&lt;br /&gt;
** Aktualisierter Stand 23. Dezember 2012: http://www.mikrocontroller.net/topic/280958#new&lt;br /&gt;
** Aktualisierter Stand vom 21. Juli 2013: http://www.mikrocontroller.net/topic/303043#3249166&lt;br /&gt;
&lt;br /&gt;
* Ich würde gerne PDF Dateien aus meinem Layout erstellen, aber irgendwie ist der Ausdruck defekt.&lt;br /&gt;
** Drucken ist aus Kicad manchmal ein Problem, auch in eine Datei hinein. Aber Plotten und Exportieren in SVG funktioniert gut. Von SVG zu PDF kommt man über Inkscape. Siehe hier: http://www.mikrocontroller.net/topic/303043#3249166&lt;br /&gt;
** Aktuell: https://www.mikrocontroller.net/topic/430532#new&lt;br /&gt;
** Problem dabei: Vektorfonts siehe https://www.mikrocontroller.net/topic/431522#new&lt;br /&gt;
* Wie kann ich mir einen Bohrplan ausdrucken, um mit der Hand zu bohren?&lt;br /&gt;
**http://www.mikrocontroller.net/topic/266037#new&lt;br /&gt;
&lt;br /&gt;
==== SVG Plotten ====&lt;br /&gt;
&lt;br /&gt;
* Meine erzeugten SVG Plots sind kaputt. Ich erhalte nur Fehlermeldungen, wenn ich sie in Inkscape oder Gimp einlesen will.&lt;br /&gt;
** Es besteht ein Problem mit dem SVG Export, wenn man Schaltpläne oder Boards in SVG exportiert, die ein Ampersand (Kaufmansund, &amp;quot;&amp;amp;&amp;quot;) im Dateinamen haben. Dieser Dateiname tauch dann innerhalb der SVG Datei in einem Titelblock auf, wo das &amp;quot;&amp;amp;&amp;quot; dann ein Problem bedeutet (Es leitet eine Art Escape-Sequenz ein). Sowohl Kicad als auch Inkscape/Gimp akzeptieren &amp;quot;&amp;amp;&amp;quot; im Dateinamen, und sowol unter Windows als auch Linux ist das &amp;quot;&amp;amp;&amp;quot; im Dateinamen legal....darum bringt auch eine Veränderung des Namens der SVG-Datei keine Lösung. Eine Lösung ist, Grundsätzlich in Kicad keine &amp;quot;&amp;amp;&amp;quot; in Dateinamen zu verwenden, wenn man einen SVG-Export macht. Alternativ kann man mit einem Editor das &amp;quot;&amp;amp;&amp;quot; aus dem Titelblock (Das ist NICHT der Dateiname, sondern in der Datei selber alles zwischen &amp;lt;titel&amp;gt; und &amp;lt;/titel&amp;gt;) der SVG-Datei löschen. Angeblich kommt der Bug aus den verwendeten wx-Bibliotheken. Siehe den Bugreport: https://bugs.launchpad.net/kicad/+bug/1171160&lt;br /&gt;
* Wie kann ich unter Windows die SVG Dateien überhaupt nutzen? &lt;br /&gt;
** Die SVG Datei kann mit Microsoft Edge auf einen Drucker gedruckt werden, nützlich bei negativ Plot. Das Öffnen mit GIMP ging mit 1000pixel/in. Das Programm, mit dem sich SVG Dateien am besten bearbeiten lassen, ist aber Inkscape. Davon gibt es sogar einen Windows Ableger.&lt;br /&gt;
** Grundsätzliche Infos zum SVG Format: https://de.wikipedia.org/wiki/Scalable_Vector_Graphics&lt;br /&gt;
** Grundsätzliche Infos zu Inkscape: https://de.wikipedia.org/wiki/Inkscape&lt;br /&gt;
&lt;br /&gt;
==== Gerber Export ====&lt;br /&gt;
&lt;br /&gt;
* Kann man Gerber-Dateien exportieren?&lt;br /&gt;
** Ja. Es wird extended Gerber 274X exportiert. Einheit ist inch (doppelt sowohl im 274d als auch im 274x Stil definiert). Die Y-Koordinaten sind im allgemeinen negativ. KiCad verwendet für Flächen das in Gerber spezifizierte Polygon Makro und kein &amp;quot;stroke fill&amp;quot;.&lt;br /&gt;
** Um Gerber Dateien zu erstellen, wählt man aus der oberen Menueleiste ganz links Datei &amp;gt; Plotten und dann oben links unter Plotformat &amp;quot;Gerber&amp;quot; &lt;br /&gt;
** KiCad unterstützt auch die kürzlich eingeführten Gerber-Attribute. Die Anwendung derselben muss aber explizit angewählt werden. Dazu setzt man im Gerber-Plottmenue im Feld &amp;quot;Gerber Optionen&amp;quot; bei &amp;quot;include extended attributes&amp;quot; einen Haken.&lt;br /&gt;
** KiCad kann automatisch die Lötstoppmaske von der Siebdruckmaske (Silk screen - Bestückungsaufdruck) abziehen, damit nicht der Bestückungsaufdruck versehentlich über Pads liegt und dort das Löten verhindert. Dazu muss aber im Gerber-Plottmenue im Feld &amp;quot;Gerber Optionen&amp;quot; bei &amp;quot;Subtrahiere Lötstoppmaske von Siebdruckmaske&amp;quot; ein Haken gesetzt werden.&lt;br /&gt;
* Welche Gerber Lagen werden zur Herstellung einer Platine benötigt?&lt;br /&gt;
** Grundsätzlich zu Herstellung der Platine die Gerberfiles: Alle Kupferlagen, Bestückungsdruck Top und Bottom (Falls auf Bottom was steht), Lötstoppmaske Top und Bottom. Eine Umrisslage mit dem Platinenumriss und Ausfräsungen. Drillfiles (Excellon) Für durchkontaktierte und NICHT durchkontaktierte (NPTH) Bohrungen. Dazu: Ein Textfile mit einer Erläuterung, welche Lage welche ist, sowie Angaben, wie dick die Kupferschichten der Kupferlagen und wie dick die Isolierlagen dazwischen sein sollen, und aus welchem Material. Wenn Du eine einfache rechteckige Platine hast, schreibst Du dort auch noch die Kantenlängen hinein. Wenn die Platinenumrisse komplizierter sind (z.B. verwinkelt, mit Ausfräsungen ec.), noch eine Masszeichnung als Gerber File. Siehe dazu: https://www.mikrocontroller.net/topic/399503#new&lt;br /&gt;
** Zum Bestücken wird mindestens noch eine Stückliste (BOM) benötigt. Eventuell noch ein spezieller Bestückungsplan (Assembly), wenn der Bestückungsaufdruck nicht reicht. Für SMD eventuell noch die Gerberdaten für Klebstoffmaske und Lötpastenmaske, und eventuell die Pick and Place Daten für den Bestückungsautomaten.&lt;br /&gt;
* Wie kann man den Gerber-Plot so ausdrucken, dass in der Mitte von Pads und Vias ein Zentrierloch frei bleibt?&lt;br /&gt;
** http://article.gmane.org/gmane.comp.cad.kicad.user/3457&lt;br /&gt;
* Was ist &#039;&#039;&#039;allgemein&#039;&#039;&#039; beim Export von Gerber Daten zu  beachten?&lt;br /&gt;
** Allgemeine Informationen zum Gerber File Format findet sich hier: https://www.mikrocontroller.net/articles/Gerber-Tools&lt;br /&gt;
** Speziell zu Passermarken/Fiducials (add layer alignment target) diese Diskussion: https://www.mikrocontroller.net/topic/396624#new&lt;br /&gt;
** Aktuell: https://www.mikrocontroller.net/topic/428569#new&lt;br /&gt;
* Ich würde gerne meine Gerberdaten gespiegelt ausdrucken, aber das &amp;quot;gespiegelt&amp;quot; ist ausgegraut.&lt;br /&gt;
** Gerber Daten werden nur sehr selten vom Layouter gespiegelt benötigt. Wenn aber doch, so öffne die Gerber Daten mit dem Gerberviewer (Gerbview). Wenn Du dort ausdruckst, kannst du auch spiegeln. Trotzdem solltest Du Dir in dieser Diskussion durchlesen, warum Du vermutlich keine Gerberdaten gespiegelt ausdrucken musst: https://www.mikrocontroller.net/topic/466448#new&lt;br /&gt;
&lt;br /&gt;
==== Excellon Drillfiles exportieren ====&lt;br /&gt;
&lt;br /&gt;
* Wie erstelle ich mit KiCad Excellon Drillfiles?&lt;br /&gt;
**siehe hier: http://www.mikrocontroller.net/topic/310333#new&lt;br /&gt;
&lt;br /&gt;
==== KiCad Board Dateien direkt zum Hersteller ====&lt;br /&gt;
&lt;br /&gt;
* Bei Bestellungen bei PCB-Pool ist deren GC-Prevue NICHT mehr erforderlich, weil PCB-Pool mittlerweile KiCad *.brd Dateien direkt akzeptiert. Siehe http://www.pcb-pool.com/ppde/info_dataformat.html Das gilt auch für viele andere Hersteller. im Zweifel dort einmal nachfragen.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Trotzdem&#039;&#039;&#039; sollte man &#039;&#039;&#039;besser Gerber Dateien&#039;&#039;&#039; zum Platinenhersteller senden. Das gilt &#039;&#039;&#039;grundsätzlich&#039;&#039;&#039; so auch für andere Platinen Layout Programme. Der Grund ist hier angegeben: https://www.mikrocontroller.net/wikisoftware/index.php?title=Gerber-Tools&amp;amp;action=edit&amp;amp;section=8&lt;br /&gt;
&lt;br /&gt;
=== Import ===&lt;br /&gt;
* Kann man EAGLE Dateien importieren? (=&amp;gt; Obacht bei Weitergabe der Daten!)&lt;br /&gt;
** http://www.mikrocontroller.net/topic/70905#797416&lt;br /&gt;
** http://www.mikrocontroller.net/topic/120373#1089933&lt;br /&gt;
** https://www.mikrocontroller.net/topic/417848#new&lt;br /&gt;
** Aktuell: http://www.mikrocontroller.net/articles/KiCad#Konverter&lt;br /&gt;
* Wie bindet man fremde KiCad Bibliotheken ein?&lt;br /&gt;
** EESchema (Schaltplaneditor) starten, unter Einstellungen &amp;quot;Bibliothek&amp;quot;  auswählen, auf &amp;quot;Hinzufügen&amp;quot; klicken, neue Bibliothek auswählen dann &amp;quot;öffnen&amp;quot; und in der Projektdatei &amp;quot;Speichern&amp;quot;. Gültig für Version 20090216Final, 2011-04-29-BZR2986-WinXP und Version: (2011-11-27 BZR 3249)-stable unter Platform: Linux 2.6.32-5-686 i686, 32 bit, Little endian, wxGTK.&lt;br /&gt;
&lt;br /&gt;
** VERALTET! Das Verfahren zur Einbindung eigener oder fremder Bibliotheken ist under PCBnew genauso.&lt;br /&gt;
** Aktuell: Siehe http://www.mikrocontroller.net/topic/356855#3988114&lt;br /&gt;
Es empfielt sich dringenst, eigene Bibliotheken NICHT zu den KiCad Bibliotheken im Ordner kicad/share/library bzw. kicad/share/modules für Footprints zu speichern, weil diese dort bei einem Upgrade gelöscht würden. Stattdessen sollte man sich einen kicad Ordner im eigenen home bzw. Benutzerverzeichnis (oder sonstwo, wo es opportun ist, und man Schreibrechte hat) anlegen, mit einem Ort, um eigene Bibliotheken abzulegen.&lt;br /&gt;
&lt;br /&gt;
=== Neues Projekt ===&lt;br /&gt;
Ein neues Projekt legt kicad automatisch nach der in kicad/share/template hinterlegten Projektdatei an. Möchte man, das kicad ein neues Projekt von vorneherein nur mit ausgewählten eigenen Bibliotheken anlegt, so ist eine entsprechende Projektdatei unter kicad/share/template/kicad.pro abzulegen.&lt;br /&gt;
Dies erfordert dort Schreibrechte. Linux roots müssen diese Datei anschliessend mit chmod 755 Dateiname für user lesbar machen.&lt;br /&gt;
Bei einem upgrade würde kicad.pro gelöscht. Daher sollte man sich davon eine Sicherheitskopie in seinem benutzerverzeichnis hinterlegen.&lt;br /&gt;
&lt;br /&gt;
=== Einstellungen sichern / wiederherstellen===&lt;br /&gt;
* Wo speichert KiCad die Einstellungen ab und wie lassen sich die originalen Einstellungen wiederherstellen?&lt;br /&gt;
** [[http://kicad.sourceforge.net/wiki/index.php/DE:KiCadHB#Einstellungen_sichern_.2F_wiederherstellen]]&lt;br /&gt;
**Man erstelle ein neues Projekt beliebigen Namens, nehme alle Einstellungen (Bibliotheken, Pfade usw.) vor und speichere diese in der aktuellen Projektdatei &amp;quot;name.pro&amp;quot;. Im Ordner KiCad Verzeichnis ....../kicad/share/template befindet sich eine Datei &amp;quot;kicad.pro&amp;quot;. Diese Datei &amp;quot;kicad.pro&amp;quot; ist die &amp;quot;Musterprojektdatei&amp;quot;, die für alle neuen Projekte verwendet wird. Man benenne sie um in &amp;quot;kicad-orig.pro, und kopiere die aktuelle Projektdatei &amp;quot;name.pro&amp;quot; nun als &amp;quot;kicad.pro&amp;quot; in diesen Template-Ordner. Leider Funktioniert dieses Verfahren nicht in allen KiCad Versionen. Den originalen Zustand stellt man wieder her, indem man &amp;quot;kicad.pro&amp;quot; umbenennt, und &amp;quot;kicad-org.pro&amp;quot; wieder in &amp;quot;kicad.pro&amp;quot; zurückumbenennt.&lt;br /&gt;
&lt;br /&gt;
=== Bitmaps als Symbol oder Footprint importieren ===&lt;br /&gt;
Der Programmteil Bitmap2component wandelt Bitmaps wahlweise in Symbole oder in Footprints um. Auf diese Weise können also auch Logos oder spezielle Muster für HF-anwendungen in KiCad importiert werden, sobald sie als Bitmap vorliegen. Es gibt allerdings auch andere Möglichkeiten, Grafiken zu importieren. Siehe dazu https://www.mikrocontroller.net/topic/428745#new&lt;br /&gt;
&lt;br /&gt;
== Tipps&amp;amp;Tricks / Eigenheiten / Bugs ==&lt;br /&gt;
&lt;br /&gt;
* Nachbearbeitung mit Skript oder Texteditor (Pin Swapping, Versionskontrolle via SVN, Generierung von Packages aus UCF-Listen) &lt;br /&gt;
** http://www.mikrocontroller.net/topic/120373#1100467&lt;br /&gt;
** http://www.mikrocontroller.net/topic/96860#836967&lt;br /&gt;
** http://stawoo.com/dokuwiki/doku.php?id=ecld:kicad:board&lt;br /&gt;
&lt;br /&gt;
* Veraltet! (2006) Schaltplan: Durchnummerieren von GND und PWR erforderlich http://www.mikrocontroller.net/topic/39243#290309&lt;br /&gt;
&lt;br /&gt;
* Zum Verbinden von Schaltplan und Layout müssen an den Bauteilen die Pinnummern mit den Padnummern der Footprints korrespondieren. Das ist &amp;quot;defaultmäßig&amp;quot; nicht immer zu erreichen, weil es unterschiedliche Nummerierungssysteme gibt. Ausser dem Anlegen eines speziellen Footprints kann diese Anpassung für einzelne Bauteile wärend des Layoutens im Moduleditor vorgenommen werden. http://www.mikrocontroller.net/topic/186121#1805890&lt;br /&gt;
* Ich habe einen hierarchischen Schaltplan angefertigt, indem sich eine Schaltung zig mal wiederholt. Eine dieser Subschaltungen habe ich schon geroutet, und möchte dieses Layout genau wie die hierarchischen Schaltpläne mehrfach auf dem Board verwenden.&lt;br /&gt;
** In PCBnew lassen sich mit &amp;quot;Datei&amp;gt;Platine hinzufügen&amp;quot; auch schon geroutete Gruppen von Bauteilen quasi als Modul einfügen, wenn sie zuvor als Board abgelegt wurden. Ebenso kann eine Bauteilgruppe, die in der Form mehrmals vorkommt, und die die schon einmal geroutet worden ist, gruppiert, kopiert und wiederverwended werden. Die dazu nötige Annotation und das Löschen der überzähligen Bauteile muss aber sorgfältig von Hand gemacht werden. &#039;&#039;&#039;Anmerkung:&#039;&#039;&#039; In neueren Versionen von PCBnew ist diese Funktion ausgegraut, wenn PCBnew &amp;quot;normal&amp;quot; aus dem Menue des KiCad Hauptfensters gestartet wurde. Um diese Funktion zu aktivieren, KiCad schliessen und PCBnew wie ein alleinstehendes Program direkt starten.&lt;br /&gt;
** Wer seinen Subschaltplan separat routen möchte, sollte den Subschaltplan explizit in EEschema öffnen und die Netliste nur dieses Subschaltplanes exportieren. Diese Netlist in ein neues Board in PCBnew einlesen und wie üblich routen.&lt;br /&gt;
* Bibliotheken verwalten, umsortieren bzw. neu strukturieren: http://www.mikrocontroller.net/topic/187107#1817559 &lt;br /&gt;
&lt;br /&gt;
* Layout: Rest-Gummiband an Pins http://www.mikrocontroller.net/topic/120373#1092375&lt;br /&gt;
&lt;br /&gt;
* Produktion: http://www.mikrocontroller.net/topic/98034#848965&lt;br /&gt;
&lt;br /&gt;
* Bug in Version 2010-03-14: Unter Einstellungen lässt sich keine einseitige Platine wählen (wichtig für Autorouter). Lösung: Modifikation des .brd Files mit einem Editor [http://www.mikrocontroller.net/topic/172015#1651239]:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;pre&amp;gt;&lt;br /&gt;
:In der *.brd Datei gleich ganz oben...&lt;br /&gt;
:&lt;br /&gt;
:$GENERAL&lt;br /&gt;
:LayerCount 2                 -&amp;gt; auf 1 setzen&lt;br /&gt;
:&lt;br /&gt;
:$SETUP&lt;br /&gt;
:InternalUnit 0.000100 INCH&lt;br /&gt;
:ZoneGridSize 250&lt;br /&gt;
:Layers 2                     -&amp;gt; auf 1 setzen&lt;br /&gt;
:Layer[0] Rückseite power&lt;br /&gt;
:Layer[15] Vorderseite power  -&amp;gt; hab&#039; ich mal beides so gelassen&lt;br /&gt;
:&amp;lt;/pre&amp;gt;                                                                aktueller: http://www.mikrocontroller.net/topic/172015#1794699&lt;br /&gt;
&lt;br /&gt;
* Das Anlegen von Symbolen/Bauteilen in aufgelöster Darstellung ist etwas stolperig. Siehe: http://www.mikrocontroller.net/topic/294095#3136180&lt;br /&gt;
&lt;br /&gt;
* Es empfielt sich, in Kicad vorläufig KEIN Ampersand (Kaufmansund, &amp;quot;&amp;amp;&amp;quot;) im Namen einer Schaltplan- oder Boarddatei zu Verwenden. Es besteht ein Bug beim Export/Plotten nach SVG. Siehe oben unter &amp;quot;Drucken / Export&amp;quot; und dann &amp;quot;Meine erzeugten SVG Plots sind kaputt.&amp;quot;. Siehe auch: http://tech.groups.yahoo.com/group/kicad-users/message/14952&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Kühlkörper&#039;&#039;&#039; können als Symbol und Footprint (Modul) angelegt werden. Die Befestigungslöcher können im  Modul als Pad ausgeführt werden. Die Padnummer aller Pads sollte gleich sein (gleicher Anschluss / über Kühlkörper verbunden), z.B. &amp;quot;1&amp;quot;. Entsprechend ein Symbol mit Pin und korrespondierender Pinnummer anlegen. Wenn der Kühlkörper elektrisch nirgendwo verbunden sein soll, dann die Anschlusspinne im Schaltplan als &amp;quot;unused&amp;quot; markieren. Als Referenz in Symbol und Footprint habe ich &amp;quot;HS&amp;quot; (HeatSink) gewählt. Es ist zu überlegen, ob &amp;quot;HS&amp;quot; nicht auch als Padnummer besser wäre.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Kartenumrisse/Outlines&#039;&#039;&#039;: Für immer wiederkehrende Platinengrössen, z.B. die beliebte Eurokarte, kann zur Vereinfachung des Zeichnens einmal ein Eurokartenumriss im Layer &amp;quot;outlines&amp;quot; gezeichnet werden, und als Modul abgelegt werden. Um die Zahl der Kollisionen beim Einlesen der Netzliste zu verringern, wird im Schaltplan ein Dummy-Symbol ohne Pinne angelegt. In CVpcb dann dieses Symbol mit dem passenden Kartenumriss Footprint/Modul verbinden, und es wird automatisch in PCBnew eingefügt. Als Referenz in Symbol und Footprint habe ich &amp;quot;Outl&amp;quot; (OUTLine) gewählt.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Sprachanpassung&#039;&#039;&#039;: Ich will mein KiCad auf Deutsch / Englisch / Französisch / Finnisch oder sonst eine Sprache umstellen. Wie geht das?&lt;br /&gt;
** Siehe : http://www.mikrocontroller.net/topic/262039#2719056&lt;br /&gt;
**Die deutsche Übersetzung der Texte und Hilfetexte/Tooltips ist manchmal etwas unelegant. Wem so etwas auffält, bitte Mitteilung am Ende dieses Threads: http://www.mikrocontroller.net/topic/255932#2641638 (deutschsprachig) oder an die KiCad user group unter https://groups.yahoo.com/neo/groups/kicad-users/info (englischsprachig, auch bei Fällen wo es um die deutsche Übersetzung geht). Diese Mitteilungen nach Möglichkeit nicht in Launchpad.&lt;br /&gt;
** Ich habe aber keine Möglichkeit, die Sprache umzustellen!&lt;br /&gt;
*** Wenn Debian eine Fehlermeldung &amp;quot;Cannot set locale to &#039;xy_XY&#039;. kommt, ist die entsprechende Umgebung nicht installiert. Unter Debian als root in der Konsole: &amp;quot;dpkg-reconfigure locales&amp;quot; aufrufen. Es öffnet sich eine ncurses-gui, wo die entsprechenden Einstellungen gemacht werden können. Für &amp;quot;Deutsch&amp;quot; wähle ich &amp;quot;de_DE.utf8&amp;quot;.&lt;br /&gt;
*** Wenn nichts passiert, fehlen möglicherweise die localisierungs Dateien. Sie sind NICHT Teil der Sourcen, und finden sich in http://bazaar.launchpad.net/~kicad-developers/kicad/doc/files/head:/internat/. Auf Debian und verwandten Systemen müssen die einzelnen localisationsordner, z. B. &amp;quot;de&amp;quot; nach /usr/local/share/kicad/internat kopiert werden. Dann als root dort Leserechte erteilen mit &amp;quot;chmode -R 755 /usr/local/share/kicad/internat&amp;quot;.&lt;br /&gt;
*** Wenn ein Mischmasch aus Englisch und der gewählten Sprache existiert, sind entweder nicht alle Begriffe übersetzt (siehe oben) oder wegen Umbenennung von Variablen ist eine Inkonsistenz entstanden. Siehe: http://www.mikrocontroller.net/topic/326622#3565178&lt;br /&gt;
** Für die KiCad Localsisation wird &amp;quot;GNU gettext&amp;quot; verwendet. Eine kleine Hilfestellung zur Anpassung der Localisation findet sich hier: http://docs.kicad-pcb.org/en/gui_translation_howto.html. Info zu Gnu gettext findet sich hier: http://de.wikipedia.org/wiki/GNU_gettext&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Projektdateien (.pro) Pfadschreibweise&#039;&#039;&#039;: In einer Windowsumgebung ist es anscheinend nötig, relative Pfade speziell zu kennzeichnen. Siehe: http://www.mikrocontroller.net/topic/326869#new&lt;br /&gt;
&lt;br /&gt;
=== Problem: Der Ursprung für die Pick und Place bzw. Drill-Daten wurde verändert und lässt sich nicht zurücksetzten. === &lt;br /&gt;
Siehe: http://www.mikrocontroller.net/topic/363280#new&lt;br /&gt;
&lt;br /&gt;
=== Problem: Case Senitive Symbols ab BZR4646 (Jan./Feb. 2014) in Schaltplänen. (Migration alter Projekte auf neue) ===&lt;br /&gt;
Ab BZR4646 sind die Symbole in Eeschema &amp;quot;Case Sensitive&amp;quot;. Das bedeutet: In alten Schaltplandateien wurden für die Symbolnamen nur Großbuchstaben verwendet, auch wenn die Originalnamen in der Library Kleinbuchstaben enthielten. Ab BZR4646 werden die Symbolnamen in den Schaltplandateien genauso geschrieben wie die Originalnamen in der Library. Leider werden dadurch bei alten Schaltplandateien die großgeschriebenen Symbolnamen nicht mehr in den Bibliotheksdateien erkannt. Auch nicht in den &amp;quot;-cache.lib&amp;quot; Dateien. Ganz so kritisch, wie es sich anhört, ist es wiederum auch nicht, weil KiCad schon seit geraumer Zeit die Schaltpläne in der neuen Version speichert. Jemand, der mit aktuellen KiCad Versionen an aktuellen Schaltplänen arbeitet, wird darum den Übergang vermutlich nicht bemerken. Allerdings tritt das Problem bei alten Schaltplänen auf, die möglicherweise Jahrelang unberührt auf der Festplatte lagen. Um die Symbolnamen in diesen alten Schaltplandateien anzupassen, existiert das Python3 Skript &amp;quot;PyKiCad-CaseSensitiveLibCure_RevD_13Apr2015.zip&amp;quot;. Es ist ein &amp;quot;Stand alone&amp;quot; Python3 skript, das nicht in das KiCad interne Python skripting eingebunden ist. Die Datei kann hier bezogen werden:[[Media:PyKiCad-CaseSensitiveLibCure_RevD_13Apr2015.zip]].&lt;br /&gt;
Autor: Bernd Wiebus, GNU-GPL.&lt;br /&gt;
&lt;br /&gt;
Be einigen Linux Distributionen (z.B. Archlinux) wird neben Python 3 auch noch das Paket &amp;quot;python3-tk&amp;quot; benötigt. Oder eine irgendwie anders genannte Einbindung von Tkinter in Python3. Anmerkung: &amp;quot;Tkinter&amp;quot; für Python3 wird im allgemeinen kleingeschrieben &amp;quot;tkinter&amp;quot; zur Unterscheidung vom großgeschriebenen &amp;quot;Tkinter&amp;quot; für das alte Python(2). &lt;br /&gt;
Sonst gibt es die Fehlermeldung &amp;quot;ImportError: No module named tkinter&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Manueller Start mit: &amp;quot;python3 PyKiCad-CaseSensitiveLibCure_RevD_13Mar2015.py&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Dieses Skript kann benutzt werden, um Schaltpläne, die mit der Eeschema Version (2013-11-29 BZR 4513) von Ende 2013, die in Linux Repositorys (z.B. Debian 7 &amp;quot;Wheezy&amp;quot;) noch sehr verbreitet ist, auf aktuelle KiCad Versionen anzupassen.&lt;br /&gt;
&lt;br /&gt;
In RC4 übernimmt ein &amp;quot;Rescue-Helper&amp;quot; diese (und andere) Funktion. Aber auch dieser kann genau wie das Python Skript nur funktionieren, wenn entweder die Originalsymbole (Cache.lib!) oder entsprechend benannte Nachfolger der Bibliotheken existieren, so dass ein auf den Namen passendes Symbol existiert.&lt;br /&gt;
&lt;br /&gt;
=== Problem: Backporting KiCad-Board Dateien (.kicad_pcb) von Version 4 auf Version 3 2014/2015) ===&lt;br /&gt;
&lt;br /&gt;
Möchte man z.B mit einer KiCad/PCBnew Version BZR 4027 vom 22 Juni 2014, welche in vielen Repositorys noch weit verbreitet ist, eine Board-Datei ( .kicad_pcb), die mit einer neueren PCBnew Version erstellt wurde, z.B. einer BZR 5513 vom 14. März 2015 (die aktuell kompiliert wurde), öffnen, so stösst man auf Probleme. Aktuell die BZR 5513 verwendet für die Board Dateien Version 4, und die alte BZR 4027 verwendet dort die Version 3. Obwohl das Schema der Boarddateien fast gleich ist, enthält die Version 4 Elemente, die es zur Zeit der Version 3 noch nicht gab, und die darum zu Fehlermeldungen und zum Abbruch des Einlesens der Datei führen. Diese Neuerungen beziehen sich auf den Export von Gerberfiles mit Attributen sowie Platinenlagen, die es vorher noch nicht gab. Diese Fehler sind dank der einfachen, klarschriftlesbaren Filestruktur von KiCad sehr leicht mit einem Texteditor zu beheben. Eine Beschreibung, wie dieses manuell zu machen ist, finden Sie hier: [[Media:KiCad-PCBnewBoardDateienMigrierenVonVersion4Auf5.pdf]] Achtung Irrtum: Hier sind Version 4 und 5 genannt, dabei sind aber Version 4 und 3 gemeint.&lt;br /&gt;
&lt;br /&gt;
=== Problem: Portieren von älteren KiCad-Board Dateien auf neuere Versionen.  ===&lt;br /&gt;
&lt;br /&gt;
In einigen Fällen funktioniert das Erkennen von selbstvergebenen Layer Namen aus der älteren Version nicht. Abhilfe schafft das manuelle Umbenennen der betroffenen Layer per Editor in den Board Dateien in KiCad-Standard Bezeichnungen und natürlich das konsequente Einpflegen in den Rest der Datei. Eine Vorstellung, wie das zu bewerkstelligen ist, ist ebenfalls aus [[Media:KiCad-PCBnewBoardDateienMigrierenVonVersion4Auf5.pdf]] zu ersehen. Achtung Irrtum: Hier sind Version 4 und 5 genannt, dabei sind aber Version 4 und 3 gemeint. Einen Überblick, welche Layernamen die jeweils aktuelle KiCad Version verwendet, bekommt man indem man sich ein Testboard anlegt, indem ALLE möglichen Layer verwendet werden, dieses abspeichert und sich die Datei mit einem Texteditor ansieht.&lt;br /&gt;
Die Portierung von alten KiCad-board Dateien (Projektname.brd) funktioniert dagegen im Allgemeinen problemlos.&lt;br /&gt;
&lt;br /&gt;
=== Problem: Neue leere Footprintbibliothek kann nicht erstellt werden (kicad Version: 4.0.0~rc1a-stable release build / RC4) ===&lt;br /&gt;
&lt;br /&gt;
Soll eine neue, leere Footprintbibliothek angelegt werden, so funktioniert das nicht mit den angebotenen Tools (z.B. dem Wizzard) weil die automatisch den Typ der Bibliothek ermitteln wollen, was nicht funktioniert, weil die Bibliothek noch leer ist. Auch das manuelle Eintragen des Pfades funktioniert nicht, weil die leere Bibliothek nicht als solche erkannt wird, und wegen dieses Fehlers der Abschluss des Eintrages nicht übernommen wird. Abhilfe schafft dabei das Anlegen eines Ordners &amp;quot;Bibliotheksname.pretty&amp;quot; (Erinnerung: Neue KiCad Footprintbibliotheken bestehen aus einem Ordener &amp;quot;xyz.pretty&amp;quot;, indem die einzelnen Footprints jeder für sich in einer extra Datei &amp;quot;Footprintname.kicad_mod&amp;quot; existieren). Anschliessend kopiert man eine einzige beliebige Footprintdatei &amp;quot;Nameirgendwie.kicad_mod&amp;quot; in diesen Ordner. Somit ist &amp;quot;Bibliotheksname.pretty&amp;quot; eine &amp;quot;echte&amp;quot; Bibliothek, welche als solche problemlos eingebunden werden kann. Enthält die Bibliothek dann irgendwann die gewünschten richtigen Einträge, so kann der Footprint, der zu Anfangs zum Erstellen der Bibliothek hineinkopiert wurde, auch wieder gelöscht werden.&lt;br /&gt;
&lt;br /&gt;
=== Problem: Fehlende Backannotationsmöglichkeit in KiCad ===&lt;br /&gt;
&lt;br /&gt;
Es gibt Leute, die sich in KiCad eine Backannotationsmöglichkeit wünschen (andere warnen davor, sowas zu benutzen, selbst wenn es existiert). KiCad bietet aktuell selber diese Möglichkeit nicht, doch lässt sich aufgrund der offenen Dateistrukturen ein z.b. Python Skript schreiben, welchess die Backannotation durchführt. Als ein Beispiel siehe hier: &amp;lt;ref&amp;gt;https://hasanyavuz.ozderya.net/?p=256&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Problem: Platinenerstellung durch Isolationsfräsen ===&lt;br /&gt;
&lt;br /&gt;
Einer der möglichen Wege ist hier beschrieben: https://www.daedalus.ei.tum.de/index.php/de/3d-druck-cnc/cnc/layout-und-g-code-erstellung-mit-kicad  Allerdings scheint die dort erwähnte Software mittlerweile aus einer anderen ecke zu kommen: http://carbide3d.com/apps/pcb/community.html Es gibt aber noch andere Wege, zb. über: http://flatcam.org/discussion#!/?HPGL Eine Diskussion dazu findet sich hier: https://www.mikrocontroller.net/topic/447442#new&lt;br /&gt;
&lt;br /&gt;
=== Tipps&amp;amp;Tricks: Building Blocks ===&lt;br /&gt;
* Eine unfertige Dokumentation, wie man das hierarchische Schaltplansystem von KiCad verwendet, um daraus schnell und rationell Schaltpläne mit vorgefertigten Schaltplänen (Building Blocks) nach dem Baukastensystem aufzubauen. Enthält auch ein Beispielprojekt. Beachte die Liesmich.txt Datei. [[Media:BuildingBlocksKiCad-EXPERIMENTELL.zip]] Das File  KiCad-HierarchischeSchaltplaene+buildingBlocksRevA_Vorlaeufig.pdf, enthält eine vorläufige Beschreibung dazu. KiCad-HierarchischeSchaltplaene+buildingBlocksRevA-EN.pdf is an English description how to use hirarchical schematics as building blocks for a fast and rationel schematic design. Es fehlt noch die Übersetzung und die Bebilderung und ein paar Berichtigungen und Ergänzungen. ;-) . Das echte Hauptbeispielprojekt ist UnderVoltageDetector24V-2Group_Experimental.pro bzw. UnderVoltageDetector24V-2Group_Experimental.sch. Im Ordner Experimentalprojekt23052010 findet sich ein weiterer Ordner BuildingBlocksExperimental. Dieser enthält die Ausgangsbausteine VoltageRegulatorBuildingBlock.sch mit VoltageRegulatorBuildingBlock-cache.lib und  VoltageDetectorBuildingBlock.sch mit VoltageDetectorBuildingBlock-cache.lib. Die Projektdateien der Buildingblocks .pro sind nur der Vollständigkeit und zur leichteren Bearbeitung zugefügt. Aus VoltageDetectorBuildingBlock.sch und VoltageRegulatorBuildingBlock.sch wurde (nach umkopieren, umbenenen und kleiner Änderung) im übergeordneten Ordner das Projekt VoltageRegulatorBuildingBlock.pro unter verwendung des &amp;quot;Zwischenbuildingblocks&amp;quot; UnderVoltageDetectorBuildingBlock.sch zusammengesetzt. NICHT VERGESSEN DIE CACHE.LIB EINZUBINDEN! Sonst gibt es nur Fragezeichen statt Bauteile. Das Beispielprojekt enthält eine 24V Unterspannungsüberwachung für einen Bleiakku, die zwei 12V Gruppen überwacht. Nicht elegant, aber hoffentlich robust. Autor: Bernd Wiebus , GNU-GPL. Der dazubezügliche Beitrag im Forum ist: http://www.mikrocontroller.net/topic/178683#1724114&lt;br /&gt;
*[[Media:HierarchischeSchaltplaeneAlsBausteineInKicad_RevC_23Dec2013.pdf]] VERBESSERTE und AKTUALISIERTE Version von KiCad-HierarchischeSchaltplaene+buildingBlocksRevA_Vorlaeufig.pdf aus obiger Zip-Datei. Beschreibt, wie mit Hilfe der hierarchischen Schaltplanstruktur aus einzelnen, vorgefertigten Schaltplänen schnell und rationell neue Schaltpläne modular zusammengesetzt werden können. There is also a English translation of this tutorial about using hierarchical schematics as building blocks. You can get it here: [[Media:HierarchicalSchematicsAsBuildingblocksAtKiCad_RevC-EN_06May2015.pdf]]&lt;br /&gt;
* Eine Sammlung von gängigen Schaltungen mit den Längstreglern LM317 /LM78xx /LM79xx und dem Timer 555, die nach dem in obig erwänten Dokument KiCad_HierarchischeSchaltplaene+buildingBlocksRevA_Vorlaeufig.pdf beschriebenen Vorgehen als Building Blocks in KiCad verwendet werden können, findet sich unter: http://www.mikrocontroller.net/articles/KiCad#Building-Blocks&lt;br /&gt;
&lt;br /&gt;
=== Tipps&amp;amp;Tricks: Shortcuts/Hotkeys ===&lt;br /&gt;
&lt;br /&gt;
KiCad besitzt eine ganze Anzahl von Shortcuts/Hotkeys. Diese lassen sich editieren, abspeichern und importieren.&lt;br /&gt;
Dieses erfolgt in EEschema, dem Symboleditor und in PCBnew in der oberen Menueleiste unter &amp;quot;Einstellungen&amp;quot; &amp;gt; &amp;quot;Tastaturbefehle&amp;quot; (&amp;quot;Preferences&amp;quot; &amp;gt; &amp;quot;Hotkeys&amp;quot;). Dort finden sich weitere Menuepunkte, um eine Liste der verfügbaren Hotkeys anzuzeigen, die Hotkeys zu editieren oder um sie zu exportieren oder importieren.&lt;br /&gt;
&lt;br /&gt;
Eine &#039;&#039;&#039;Liste&#039;&#039;&#039; der aktuell verfügbaren Hotkeys erhält man mit &amp;quot;?&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Es gibt eine Reihe von Hotkeys, die in EEschema, dem Symboleditor und PCBnew gleich sind:&lt;br /&gt;
&lt;br /&gt;
*Help (this window)		?&lt;br /&gt;
*Zoom In			        F1&lt;br /&gt;
*Zoom Out			F2&lt;br /&gt;
*Zoom Redraw			F3&lt;br /&gt;
*Zoom Center			F4&lt;br /&gt;
*Fit on Screen			Home&lt;br /&gt;
*Reset Local Coordinates	Space&lt;br /&gt;
*Edit Item			E&lt;br /&gt;
*Delete Item			Del&lt;br /&gt;
*Rotate Item			R&lt;br /&gt;
*Drag Item			G&lt;br /&gt;
*Undo				Ctrl+Z&lt;br /&gt;
*Redo				Ctrl+Y&lt;br /&gt;
*Mouse Left Click		Return&lt;br /&gt;
*Mouse Left DClick		End&lt;br /&gt;
&lt;br /&gt;
Die anderen variieren je nachdem, in welcher Umgebung man sich befindet.&lt;br /&gt;
&lt;br /&gt;
Ein wichtiger Hotkey in PCBnew ist &amp;quot;T&amp;quot;. Wird &amp;quot;T&amp;quot; gedrückt, poppt ein Fenster auf, in dem nach dem Referenzbezeichner des Bauteils gefragt wird. Den gibt man ein, drückt &amp;lt;Enter&amp;gt; und der Footprint des Bauteiles hängt am Mauszeiger. Das ist eine wichtige Funktion beim &#039;&#039;&#039;Plazieren der Bauteile&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Eine PDF Datei mit Notizen zu den Shortcuts in KiCad und Listen von Shortcuts findet sich hier: [[Media:KiCad-Shortcuts-Hotkeys_Notizen_BZR4803_28Jun2014.pdf]]&lt;br /&gt;
&lt;br /&gt;
=== Tipps&amp;amp;Tricks: Lochraster/Lötleisten Platinen Entwurf mit KiCad ===&lt;br /&gt;
&#039;&#039;&#039;Dieses hier beschriebene Verfahren ist KiCad unabhängig und geht grundsätzlich mit jedem Layoutprogramm, das ein Raster anzeigen kann.&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Wer viel mit Lochraster Platinen arbeitet, hat gelegentlich auch ein Bedürfnis, diese Tätigkeit mit einem Layoutprogramm zu begleiten. Zum einen um den Platzbedarf besser abschätzen zu können, zum anderen, um dadurch auch eine schnelle und einfache Dokumentation auch für Lochrasterprojekte zu schaffen. Auch dazu kann KiCad verwendet werden.&lt;br /&gt;
* Vorgehensweise: Schaltplan in Eeschema erstellen wie üblich, Netzliste erzeugen, und in CVpcp die Bauteile zuordnen. In PCBnew dann das Raster einblenden und auf 2,54mm (100mil) stellen. Nun geben die Rasterpunkte die Position der Löcher der Lochrasterplatine vor. Nach dem Einlesen der Netzliste bei Lochraster mit Streifenleitungen am besten zweiseitig manuell routen. Auf der Unterseite der Richtung der Streifenleitung in Längstrichtung folgen (z.b. wagerecht). Auf der Oberseite die Brücken dazu quer legen (z.B. senkrecht). Zweipolige Bauteile immer senkrecht oder wagerecht positionieren. &lt;br /&gt;
** Wer eine Platine erstellen möchte, die nur teilweise ein Lochraster aufweist, dem sei diese Diskussion empfohlen: https://www.mikrocontroller.net/topic/369534#new&lt;br /&gt;
* Noch ein Vorschlag für Lochraster bzw. Lötleistenentwürfe in KiCad: http://www.mikrocontroller.net/topic/395181#4547206&lt;br /&gt;
&lt;br /&gt;
=== Tipps&amp;amp;Tricks: KiCad und Freeroute ===&lt;br /&gt;
Leider ist die Freeroute Seite abgeschaltet. Grund:http://www.mikrocontroller.net/topic/337014#new Allerdings gibt es eine Möglichkeit, Freeroute selber zu installieren und zu nutzen: https://github.com/nikropht/FreeRouting und http://freerouting.net/index_de.php &lt;br /&gt;
*Freerouting einseitig bzw. für Lochraster verwenden: http://www.mikrocontroller.net/topic/363335#new&lt;br /&gt;
*Fehlermeldungen beim Start von Freeroute: Es ist wichtig, dass der Leiterplattenumriss in der Lage edge.cuts geschlossen ist: https://www.mikrocontroller.net/topic/435039#new&lt;br /&gt;
&lt;br /&gt;
=== Tipps&amp;amp;Tricks: KiCad und Specctra Autorouter ===&lt;br /&gt;
Es treten beim Export der Netzlisten/Designs Fehlermeldungen der Art: &amp;quot;IO_ERROR: Multiple components have identical reference IDs&amp;quot; auf, obwohl offensichtlich keine doppelten Referenzbezeichner vergeben wurden.&lt;br /&gt;
* Die &amp;quot;doppelten Referenzbezeichner&amp;quot; sind doch &amp;quot;irgendwie&amp;quot; versteckt vorhanden. Z.B. dadurch, das Bauteile nicht Referenziert oder Annotiert wurden. Im Zweifel die Files mit einem Texteditor danach durchsuchen, oder die Autoannotation über das Board laufen lassen. Siehe: https://www.mikrocontroller.net/topic/365185#new&lt;br /&gt;
&lt;br /&gt;
=== Tipps&amp;amp;Tricks: Platinen von ALLPCB ===&lt;br /&gt;
Hinweise, wie die Design Restrictions von ALLPCB in KiCad umgesetzt werden können, als Beispiel auch für andere Platinenhersteller (entsprechend anpassen)&lt;br /&gt;
* https://www.mikrocontroller.net/topic/443533#new&lt;br /&gt;
&lt;br /&gt;
= Bibliotheken =&lt;br /&gt;
&lt;br /&gt;
== Handhabung von Bibliotheken ==&lt;br /&gt;
&lt;br /&gt;
=== Eeschema ===&lt;br /&gt;
&lt;br /&gt;
* Symbolbibliotheken in Eeschema einbinden.&lt;br /&gt;
** Zur Benutzung müssen Bibliotheken mit Symbolen in das Bibliotheksverzeichnis von Eeschema eingetragen werden. Siehe: https://www.mikrocontroller.net/topic/416835 [[Bild:EeschemaBibliotheksliste.png|300px|thumb|right|Bearbeitung einer KiCad 4 Eeschema Bibliotheksliste]]&lt;br /&gt;
* Cache Bibliothek:&lt;br /&gt;
**  Hat man von anderswo einen Schaltplan bekommen, kann dieser auf anderen Symbolbibliotheken beruhen, als man selber verwendet. Aus diesem Grunde existiert zu jeder Schaltplandatei (Dateiname.sch) eine Cache Bibliothek (Dateiname-cache.lib). Diese enthält alle im Schaltplan verwendeten Symbole, und sollte darum mit dem Schaltplan zusammen übergeben werden. Diese Cache-Bibliothek sollte auch in die Bibliothekstabelle übernommen werden.&lt;br /&gt;
* Fehler mit Case-Senitiven Bibliotheken&lt;br /&gt;
** Ab BZR4646 (Jan./Feb. 2014) behandelt KiCad Symbolnamen &amp;quot;Case Sensitive&amp;quot;. Das führt zu Problemen mit älteren Schaltplänen, wo &amp;quot;Mixed Case&amp;quot; Symbolnamen aus den Bibliotheken automatisch in &amp;quot;Upper Case&amp;quot; Symbolnamen konvertiert wurden. Diese werden jetzt nicht mehr erkannt. Näheres siehe: http://www.mikrocontroller.net/articles/KiCad#Problem:_Case_Senitive_Symbols_ab_BZR4646_.28Jan..2FFeb._2014.29&lt;br /&gt;
&lt;br /&gt;
== Bibliothekssammlungen ==&lt;br /&gt;
&lt;br /&gt;
In diesem Abschnitt sollen unsere Arbeiten an Bibliotheken koordiniert werden. Dabei sollen alle Arbeiten unter der Creative Commons Lizenz stattfinden. Das heisst insbesondere, dass keine Arbeiten mit anderem Copyright unseren Bibliothekspool vergiften sollen z.&amp;amp;nbsp;B. durch unerwünschte Konvertierung von EAGLE-Bibliotheken.  &lt;br /&gt;
&lt;br /&gt;
Unsere Designziele sind:&lt;br /&gt;
* Frei benutzbar (Creative Commons Lizenz) &lt;br /&gt;
* Einheitlich (Richtlinien?)&lt;br /&gt;
** Vorschlag von Marko für Bohrungen und Pads siehe [http://www.mikrocontroller.net/topic/124070#1176177]&lt;br /&gt;
** Die Richtlinien, die die KiCad Librarys selber verwenden: [https://github.com/KiCad/kicad-library/blob/master/KiCad_Library_Convention.txt]&lt;br /&gt;
* Fehlerfrei (Nachkontrolle durch andere User)&lt;br /&gt;
&lt;br /&gt;
=== Wünsche ===&lt;br /&gt;
&lt;br /&gt;
Hier soll eine Strichliste geführt werden, welche neuen Bauteile gesucht sind bzw. welche oder besseren, genaueren Versionen benötigt werden. Bitte gebt an, was bei bestehenden Bauteilen problematisch ist.&lt;br /&gt;
&lt;br /&gt;
Bevor wir Bibliotheken erstellen, sollten auf jeden Fall einige Parameter - insbesondere für die Schaltplansymbole - festgelegt werden: Pinlänge, Pinabstand, Größe der Schriften, Konventionen bzw. Nummerierung (z.B. bei gepolten Bauteilen wie Dioden, Elkos usw.). Sonst entsteht Wildwuchs, weil jeder für sich anderes festlegt.&lt;br /&gt;
&lt;br /&gt;
* Stehende Layouts für 7805 und N-FETs: ||||&lt;br /&gt;
** Passt TO220_VERT ? Natürlich! Nur die Anschlussnumerierung muss ev. passend adaptiert werden. Ist unter &amp;quot;TO-220&amp;quot; in [[Media:KiCAD_Module_Footprints_3D_29Aug2014.zip]] enthalten. In allen Perversionen. Stehend, liegend, rumgedreht von der Rückseite usw....&lt;br /&gt;
* LPC21xx / LPC22xx / LPC23xx |&lt;br /&gt;
* EINE AVR ATmega-Bibliothek, wo ALLE Controller drin sind. ||||||||&lt;br /&gt;
* AVR XMegas |&lt;br /&gt;
* AT90CAN128 / allgemein mehr AVRs (MEGA &amp;amp; TINY) ||||||&lt;br /&gt;
* Wegen der AVRs und ATMEGAs: Bitte hier http://www.kicadlib.org/Fichiers/Kerusey_Karyu_Atmel_Library.html mal schauen, und den Wunsch auf den Typ konkretisieren! Der Atmelzoo ist so verwirrend vielfältig.....&lt;br /&gt;
** Leider ist die dazugehörige Bibliothek defekt.&lt;br /&gt;
** Ist aktualisiert worden und in die aktuelle KiCad Symbol Library eingeflossen: [https://github.com/KiCad/kicad-library/blob/master/library/atmel.lib]&lt;br /&gt;
*** Weitere Aktualisierungen und Erweiterungen: [https://github.com/KiCad/kicad-library/blob/master/library/atmel.dcm]&lt;br /&gt;
* Schaltregler (u.A. LM257x, LM267x, MC33063, L5973D) |||| Der MC33063 hat gleiches Pinning und Gehäuse wie MC34063! Darum kann der in http://www.mikrocontroller.net/wikifiles/8/84/Symbols_ICs-Diskrete_RevD9.lib verwendet werden.&lt;br /&gt;
* Spulen (z.&amp;amp;nbsp;B. diverse Wuerth) ||&lt;br /&gt;
* Drosseln (B82790 für CAN, Würth 744207) ||&lt;br /&gt;
* Transformatoren (allgemein) |&lt;br /&gt;
* Ferrite (7427930 - 32, 742792651, 74279263) |&lt;br /&gt;
** ??? Was genau ist nun Footprint und Referenzmaeßig der Unterschied zwischen Drosseln, Spulen und Ferriten, wenn ich jetzt mal davon ausgehe, das die Teile weder Anzapfung noch mehr als eine Wicklung haben (dann wären es Trafos oder Uebertrager), und die elektrischen Werte in ein Feld eingetragen werden?? Schau mal unten in http://www.mikrocontroller.net/wikifiles/d/da/KiCad_Module_Footprints_3D_16Sep2013.zip. Kleinere SMD-Entstörferrit Module lassen sich uebrigens aus Footprints für SMD-Widerstaenden zaubern, in dem man sie umbenahmt und mit der Referenz &amp;quot;L&amp;quot; versieht. ;-)&lt;br /&gt;
* STM32 Mikrocontroller Bibliothek (sofern möglich alle) ||||&lt;br /&gt;
* Arduinos ||&lt;br /&gt;
** Arduino Due ||&lt;br /&gt;
** Arduino Nano |&lt;br /&gt;
&lt;br /&gt;
=== Entwürfe ===&lt;br /&gt;
&lt;br /&gt;
Neue Bibliotheken oder Änderungen sollen zunächst in diesem Abschnitt &lt;br /&gt;
vorgestellt werden. &lt;br /&gt;
&lt;br /&gt;
==== Symbolbibliotheken ====&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/96460#832961 ATmega3250/TQFP100] von Fred S. (Gast)&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/96460#844741 ATMega3290 im 100Pin-Gehäuse] von Fred S. (Gast)&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/132811#1205130 RFM12-Funkmodul] von Dominik C.&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/133310#1210137 CAN Controller MCP2515 und Transceiver MCP2551] von Dominik C.&lt;br /&gt;
&lt;br /&gt;
* [https://www.mikrocontroller.net/topic/394700#4540445 STLib für KiCad mit STM32F4x] von Markus W.&lt;br /&gt;
&lt;br /&gt;
* [[Media:SymbolsSimilarEN60617+oldDIN617-RevB-en.lib]] VERALTET! Nur aus Kompatibilitätsgründen behalten. Ersetzt für Neuentwicklungen durch Revision E1. Schaltplan Symbolbibliothek fuer KiCad mit Symbolen, die denen aus der EN60617 oder der ALTEN DIN 617 ÄHNLICH sind. Von Bernd Wiebus&lt;br /&gt;
&lt;br /&gt;
* [[Media:SymbolsSimilarEN60617+oldDIN617-RevC-en.lib]] VERALTET! Nur aus Kompatibilitätsgründen behalten. Ersetzt für Neuentwicklungen durch Revision E1! Schaltplan Symbolbibliothek für KiCad mit Symbolen, die denen aus der EN60617 oder der ALTEN DIN 617 ÄHNLICH sind. Aenderung gegenueber Rev.B: Kleinere Symbole hinzugefügt. Mit Vorsicht geniessen! Von Bernd Wiebus.&lt;br /&gt;
 &lt;br /&gt;
* [[Media:SymbolsSimilarEN60617+oldDIN617-RevD3-en.lib]] VERALTET! Nur aus Kompatibilitätsgründen behalten. Ersetzt für Neuentwicklungen durch Revision E1! Schaltplan Symbolbibliothek für KiCad mit Symbolen, die denen aus der EN60617 oder der ALTEN DIN 617 ÄHNLICH sind.  Aenderung gegenueber Rev.C: Kleinere Fehler beseitigt. CLD Symbol hinzugefuegt. Kuehlkoerper Symbol und Dummy-Symbol fuer Boardoutlines hinzugefuegt. Thyristor und Triac Symbol zugefuegt. Copyright Symbole GNU-GPL und CC zugefuegt. Mit Vorsicht geniessen! Von Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
 &lt;br /&gt;
* [[Media:SymbolsSimilarEN60617+oldDIN617-RevE8.lib]] AKTUELLE Version! Ersetzt die Rev. B, C und die Rev. D sowie Vorgängerversionen E1-E7! Schaltplan Symbolbibliothek für KiCad mit Symbolen, die denen aus der EN60617 oder der ALTEN DIN 617 ÄHNLICH sind.  Aenderung gegenueber Rev.D: Kleinere Fehler beseitigt. Ankerpunkte in die Nähe der Symetrieachsen verlegt. Verbinder DIN41612 / EN60603-2 &amp;quot;Eurokartenstecker&amp;quot; hinzugefügt. Große &amp;quot;BIG&amp;quot; Symbole entfernt und in der Datei BIG-SymbolsSimilarEN60617+oldDIN617-RevE.lib ausgelagert. Mit Vorsicht geniessen! Von Rene Belau und Bernd Wiebus.  CC-Zero/Public Domain!  Defektes Symbol &amp;quot;RESISTOR_RevE_Date15jun2010&amp;quot; repariert am 02. Maerz 2011. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
   &lt;br /&gt;
* [[Media:BIG-SymbolsSimilarEN60617+oldDIN617-RevE.lib]] Einige EN60617 oder der DIN 617 ÄHNLICHE Symbole in besonders GROSSER Ausführung. Vermutlich werden Sie diese GROSSEN Symbole eher NICHT benutzen wollen. Mit Vorsicht geniessen! Von Rene Belau und Bernd Wiebus. Unter GNU GPL. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[http://www.mikrocontroller.net/attachment/74203/obi.lib]] KiCad Symbol für einen ATMEGA644. Von obi&lt;br /&gt;
&lt;br /&gt;
* [[Media:Symbols_ICs-Diskrete_RevD10.lib]] KiCad Symbole für einige diskrete ICs. Enthält L200 (Pentawatt Gehäuse), LM2587 (Pentawatt Gehäuse), Längstregler LM317, LM78xx, LM79xx, Timer NE555, NF-Verstärker LM1875 und TDA2003 (Pentawatt Gehäuse), Schaltregler UC38xx (DIP8/SO8 und DIP14/SO14), LM2587, MC34036, LM78S40 und MCP1640, Treiber MIC4422 (DIP8/SO8 und Pentawatt Gehäuse). Allegro Halleffekt Stromwandler Typ ACS754/ACS755/ACS756 und LEM Halleffekt Stromwandler der Serie &amp;quot;HX&amp;quot;. Programierbarer Oszillator Si570/Si571 sowie Quarzoszillator Typ KXO-200. Dazu Transistor Arrays BC847S und BC857S (in einfacher und in aufgelöster Darstellung) und Supressordioden Array SR05. Schieberegister 74HC4094 . Spannungs-/Laderegler uA723/LM723 in 14 und 20 poligem Gehäuse. HF/ZF Verstärker/Mischer/Demodulator TCA440 alias exDDR A244D, FM Frontend TA7358. Spannungsmonitor ICL7665. Autor Bernd Wiebus.  CC-Zero/Public Domain!  Mit Vorsicht geniessen! Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:Symbols_ICs-Opto_RevB_16Sep2013.lib]] KiCad Symbole für Optokoppler CNY17, IL300. IL388, TLP250, SFH617A-1, SFH617A-2, SFH617A-3, SFH617A-4, KPC357, LTV35x, und PC357. LWL Empfänger Toshiba TORX170 TORX173 TORX193  und TORX194 (Toslink). LWL Sender Toshiba TOTX170 TOTX173 TOTX193  und TOTX194 (Toslink). LWL Empfänger Agilent HFBR-252x und Sender Agilent HFBR-152x Serie (Versatile Link). 7 Segment Anzeigen HDSM531, HDSM533, LTS6760, LTS6780, SBC18-11EGWA. Autor Rene Belau und Bernd Wiebus. CC-Zero / Public domain. Mit VORSICHT geniessen! Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:Transformer-Diskrete_RevA.lib]] KiCad Symbole für einige diskrete Transformatoren. Coilcraft Q4434-B = Rhombus T1311 und Myrra-74040 ETD29. Autor: Bernd Wiebus. Mit Vorsicht geniessen! Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:Symbols_DCDC-ACDC-Converter_RevC_29Aug2014.lib]] KiCad Symbole für einige DCDC/ACDC-Converter. Enthält CINCON EC5BC12, CINCON EC6C11, TRACO TED-1212, TRACO TED-XXXX Dual Output, TRACO TED-XXXX Single Output, TRACO TEN10-1212, TRACO TEN10-XXXX, TRACO TME-XXXX, TRACO TMH-XXXX Single Output, TRACO TMH-XXXX Dual Output, sowie TRACO ACDC-Converter der TMLM Serie. BOTHHAND CF-Serie und DELTA DPS05U09D. Neu seit 29 August 2014: Floeth DCDC-Converter SD14-XXXX und SD18-XXXX. Autor: Bernd Wiebus. GNU-GPL. Mit Vorsicht geniessen! Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:Symbols_Socket-DIN41612_RevA.lib]] KiCad Symbole für DIN41612 Stecker und Buchsen (Die bekannten Eurokartenstecker). Autor: Bernd Wiebus. GNU-GPL. Mit Vorsicht geniessen! Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:Symbols_EN60617_13Mar2013.lib]] KiCad Symbole für die EN60617. Strikter als die Symbole aus SymbolsSimilarEN60617+oldDIN617-Rev~~.lib. Autor: Bernd Wiebus. CC-Zero/Public Domain! Mit Vorsicht geniessen! Hierzu gehört der Katalog: [[Media:Symbols_EN60617_13Mar2013.pdf]] Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:Symbols_EN60617-10_HF-Radio_DRAFT_12Sep2013.lib]] HF-Blockschaltbild Symbole für KiCad. EXPERIMENTELL! Autor: Bernd Wiebus. Mit Vorsicht geniessen! Lizenz: CC-Zero / Public domain.  Hierzu gehört der Katalog: [[Media:EN60617-10_HF-Radio_SymbolCatalog_DRAFT.pdf]] Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:Symbols_Microcontroller_Philips-NXP_RevA_06Oct2013.lib]] Symbole der NXP Microcontroller LPC2104, LPC2105 und LPC2106 fuer KiCad.  Autor: Bernd Wiebus. Mit Vorsicht geniessen! Lizenz: CC-Zero / Public domain. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:Symbols_ORringController_RevA_03Aug2015.lib]] Symbole verschiedener ORing-Controller fuer KiCad. Enthält IR5001, ISL4166 (QFN20+TSSOP16) und LM5050/LM5051. Autor: Bernd Wiebus. Mit Vorsicht geniessen! Lizenz: CC-Zero / Public domain. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de.&lt;br /&gt;
&lt;br /&gt;
==== Modulbibliotheken ====&lt;br /&gt;
&lt;br /&gt;
* [[Media:KiCAD_Module_Footprints_3D_29Aug2014.zip]] Eine Sammlung von KiCad Modulen bzw. Footprints diskreter Bauteile. Neben den obligatorischen Rs, Cs und Ls sind Schrack und Omron Kartenrelais (die Footprints passen auch fuer andere Hersteller), diverse Dioden, Klemmen WAGO 236 (RM 5mm) Serie und WAGO 734 Serie, Sicherungshalter (Schurter und Bulgin) für 5x20 und 6x30, SMD Sicherungen 1206 und Sicherungen/Sicherungshalter TE5/TR5,Flachsicherungen Standard und Mini, Kuehlkoerper und Eurokartenoutlines enthalten. Zusaetzlich TO92, TO220, TO220-5 (Pentawatt) und TO247 Gehaeuse. Ebenso die vermissten PISN und PISR SMD Drosseln. Einige Throughhole C&amp;amp;D Bobin Drosseln, Bourns 3296, Spectrol Type 43 / Econtrim und Piher PT15 Trimmer . Potentiometer Alps RK16 und Spectrol Type 148/149. Transformatoren Coilcraft Q4434-B / Rhombus T1311 sowie ETD29 von Epcos und Myrra sind auch dabei. Eurokartenstecker/-buchsen DIN 41612 Typ B1, B2, C1, C2 und C3. Ebenfalls enthalten: GNU-GPL und Creative Commons  Symbole. Dazu Messpunkte. BNC-Buchse, Quarzoszillator, SMD Widerstände und Kondensatoren.  (0805, 1206, 2512) sowie experimentelle Universalfootprints SMD/Throughole. SMD-Dioden: MELF, Mini-MELF, SMA, SMB und SMC. Halleffekt Stromwandler mit Allegro CB-PFF, CB-PSF und CB-FSS Gehäusen.Dazu Stecker Molex Serie KK, Würth SMD Drosseln und Doppeldrosseln. Neosid Filter und Drosseln. TRACO ACDC-Converter der TMLM Seie und SOT23, SOT143, SOT143R, TSOT-6 / MK06A sowie SC70-6 SMD Footprints für Dioden, Transistoren bzw. Dioden und Transistor Arrays und kleinere ICs. Mini Universal Mate-N-Lock Steckersockel (Tyco/AMP). 2-6 Pin, vertikale und horizontale Typen. Verbesserte Fiducials und Logos. Dazu SMD-Tantalkondensatoren und ETAL NF-Transformatoren. TO50-3 und TO50-4 Gehäuse. 7 Segment Anzeigen. LQFP48/TQFP48 Gehäuse. Hallsonden Stromwandler mit Allegro CB-PFF, CB-PSF und CB-FSS Gehäusen. Halleffekt Stromwandler der Serie &amp;quot;HX&amp;quot; von LEM.  Neu in der Version vom 29. August 2014: Floeth DCDC-Converter SD14 und SD18. Fast alles ohne 3D Modelle, aber manchmal mit PDF-Ausdruck zur leichten Identifikation. Mit Vorsicht geniessen! Ohne Garantie und  CC-Zero/Public Domain!  Von Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* Viel Standardkram in 3D: http://smisioto.no-ip.org/elettronica/kicad/kicad-en.htm&lt;br /&gt;
&lt;br /&gt;
* [[Media:KiCAD-Module_Buzzer_Beeper_RevA_25Oct2010.zip]] Einige Footprints von Summern /Buzzern / Beepern für KiCad. Enthaelt Kingstate KCG0601, Pro Signal ABI-009-RC, Pro Signal ABI-010-RC, Pro Signal ABT-410-RC, Star Micronics HMB-06/HMB-12 und Projects Unlimited AI-4228-TWT-R. Alles ohne 3D Modelle, aber mit PDF-Ausdruck zur leichten Identifikation. Mit Vorsicht geniessen! Ohne Garantie und  CC-Zero/Public Domain!  Von Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:KiCAD-Module_CommonModeChoke_Wuerth_Type-WE-CMB_RevA_25Oct2010.zip]] Footprints der Gleichtaktdrosseln der Serie Würth WE CMB (through hole) für KiCad. Enthält die Verschieden Bauformen XS, S, M, L, XL und XXL. Alles ohne 3D Modelle, aber mit PDF-Ausdruck zur leichten Identifikation. Mit Vorsicht geniessen! Ohne Garantie und  CC-Zero/Public Domain!  Von Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:DCDC-ACDC-Converter_RevC_20Jul2012.zip]] Footprints von DCDC/ACDC-Convertern für KiCad. Enthält CINCON EC5BC12, CINCON EC6C11, TRACO TED-1212, TRACO TED-XXXX Dual Output, TRACO TED-XXXX Single Output, TRACO TEN10-1212, TRACO TEN10-XXXX, TRACO TME-XXXX, TRACO TMH-XXXX Single Output, TRACO TMH-XXXX Dual Output, BOTHHAND CF-Serie und DELTA DPS05U09D. Neu seit 20 Juli: TRACO ACDC-Converter der TMLM Serie. Alles ohne 3D Modelle, aber mit PDF-Ausdruck zur leichten Identifikation. Mit Vorsicht geniessen! Ohne Garantie und  CC-Zero/Public Domain!  Von Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:Opto-Devices_RevC_03Oct2012.zip]] Footprints von Optoelectronischen Bauteilen für KiCad. Enthält 6 Polige DIL Footprints für CNY17, auch in &amp;quot;wide&amp;quot;, SMD Optokoppler Footprints (1 Kanalig) und Footprints für Toshiba (Toslink) und Agilent (Versatile Link) LWL Ssender und Empfänger. Alles ohne 3D Modelle, aber mit PDF-Ausdruck zur leichten Identifikation. Mit Vorsicht geniessen! Ohne Garantie und unter GNU-GPL. Von Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:Pentawatt_RevB_24Oct2012.zip]] Footprints von Pentawatt Gehäusen für KiCad. Enthält verschiedene Ausführungen der TO220-5 Gehäuse in gerade und verkröpft, sowie stehend und liegend. Mit 3D-Modellen und mit PDF-Ausdruck zur leichten Identifikation. Mit Vorsicht geniessen! Ohne Garantie und unter GNU-GPL. Von Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
*[[Media:Transistor_TO-220_RevB_03Sep2012.zip]] Footprints von TO220-3 Gehäusen für KiCad. Enthält verschiedene Ausführungen der TO220 Transistor Gehäuse in  stehend und liegend. Mit 3D-Modellen und mit PDF-Ausdruck zur leichten Identifikation. Mit Vorsicht geniessen! CC-Zero/Public domain! Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
*[[Media:Transistor_TO-247_RevC.zip]] Footprints von TO247 Gehäusen für KiCad. Enthält verschiedene Ausführungen der Transistor Gehäuse in  stehend und liegend. Mit PDF-Ausdruck zur leichten Identifikation. Mit Vorsicht geniessen! CC-Zero/Public domain! Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[http://www.mikrocontroller.net/topic/176405#new]] KiCad Modul / Footprint für ein TSSOP38 Gehäuse. Autor Raphael Reu.&lt;br /&gt;
&lt;br /&gt;
* [[http://www.mikrocontroller.net/topic/190088#1856759]] Texas Instruments TPIC8101 Klopfsensor Interface (für Verbrennungsmotoren). Autor Peter Diener.&lt;br /&gt;
&lt;br /&gt;
* [[Media:IR-directFET_Packages_RevB.zip]] Footprints von directFET SMD-Transistor Gehäusen von International Rectifier für KiCad. Enthält die SH, SJ, SQ, ST, S1, MN, MP, MT, MX, MZ und die L8-Outline. Nähere Informationen in den Datenblättern betroffener Transistoren und in der International Rectifier Applikationsnotiz AN-1035. &amp;quot;directFET&amp;quot; ist übrigens eine Handelsmarke von International Rectifier und die Gehäuse sind proprietär. Also vorsichtig sein und an &amp;quot;second source&amp;quot; denken. Mit 3D Modellen und mit PDF-Ausdruck zur leichten Identifikation. Mit Vorsicht geniessen! Ohne Garantie und unter CC-Zero / Public domain. Von Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:Neosid-Devices_Coils_Filters_25Apr2012.zip]] Footprints von NEOSID Bauteilen. Spulen, Luftspulen, Filter ec. für KiCad. Through hole und SMD. Alles ohne 3D Modelle, aber mit PDF-Ausdruck zur leichten Identifikation. Mit Vorsicht geniessen! Ohne Garantie und unter GNU-GPL. Von Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:SOT23_SOT143_SOT143R_TSOT6_MK06A_SC70-6_Housing_14Mar2014.zip]] Footprints von SOT23, SOT143, SOT143R, TSOT-6 /MK06A und SC70-6 SMD Gehäusen, wie sie oft für Dioden und Transistoren, aber auch Dioden und Transistor Arrays verwendet werden. Auch ICs findet man in der Bauform. Es sind Standard Footprints und spezielle für Handlötung vorhanden. KiCad Legacy Format und neues .pretty Format. Alles ohne 3D Modelle, aber mit PDF-Ausdruck zur leichten Identifikation. Mit Vorsicht geniessen! Ohne Garantie und unter GNU-GPL. Von Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:MiniUniversalMate-N-LokSockets_13Aug2012.zip]] Footprints von Mini Universal Mate-N-Lok Steckersockeln (Tyco/AMP). 2-6 Pin, verticale und horizontale Typen. Alles ohne 3D Modelle, aber mit PDF-Ausdruck zur leichten Identifikation. Mit Vorsicht geniessen! Ohne Garantie und unter GNU-GPL. Von Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:NF-Transformer_ETAL_RevA_28Aug2012.zip]] Footprints und 3D-Mesh Modelle von NF-Transformatoren der Firma ETAL (http://www.etalgroup.com). SMD und THT Typen. Mit PDF-Ausdruck zur leichteren Identifikation. In der Bibliothek ist auch der bekannte Übertrager ETAL P1200, der von Box73 (http://www.box73.de) vertrieben wird. Mit Vorsicht geniessen! Ohne Garantie und unter GNU-GPL. Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de &lt;br /&gt;
&lt;br /&gt;
* [[Media:TantalCapacitors_SMD_RevA_28Aug2012.zip]] Footprints von Tantal Kondensatoren SMD Größe A bis E (EIA-3216, EIA-3528, EIA-6032, EIA-7343 und EIA-7360). Alles ohne 3D Modelle, aber mit PDF-Ausdruck zur leichten Identifikation. Ohne Garantie und unter GNU-GPL. Mit Vorsicht geniessen! Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:SOT89-3_SOT89-5_Housing_RevA_02Sep2012.zip]] Footprints und 3D-Mesh Modelle von SOT89-3 und SOT89-5 SMD Gehäusen. Mit PDF-Ausdruck zur leichteren Identifikation. Ohne Garantie und unter GNU-GPL.  Mit Vorsicht geniessen! Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:SOT126_SOT32_Housings_RevA_22Oct2012.zip]] Footprints und 3D-Mesh Modelle von SOT126 / SOT32 Gehäusen. Mit PDF-Ausdruck zur leichteren Identifikation. Ohne Garantie und unter GNU-GPL.  Mit Vorsicht geniessen! Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:Allegro_HallSensors_24Oct2012.zip]] Footprints und 3D Modelle von Allegro Hall-Effect Stromsensoren mit PFF, PSF oder PSS Gehäuse (ACS754, ACS755, ACS756).  Mit PDF-Ausdruck zur leichteren Identifikation. Ohne Garantie und unter GNU-GPL.  Mit Vorsicht geniessen! Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:VML0806_Housing_Rohm_27Oct2012.zip]] Footprints und 3D Modell eines Transistors im 0806 Format (VML0806 / Rohm).  Mit PDF-Ausdruck zur leichteren Identifikation. Ohne Garantie und unter GNU-GPL.  Mit Vorsicht geniessen! Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
*[[Media:TO-50_Housings_RevA_21Apr2013.zip]]  Footprints/Module von TO50-3 und TO50-4 Transistor Gehäusen.Mit PDF-Ausdruck zur leichteren Identifikation. Ohne Garantie und unter CC-Zero / Public Domain.  Mit Vorsicht geniessen! Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
*[[Media:OldSowjetAera_Transistor_RevA.zip]] Footprints/Module von Kleinleistungstransistoren aus der Sowjetära.Mit 3D-Modell und PDF-Ausdruck zur leichteren Identifikation. Ohne Garantie und unter CC-Zero / Public Domain.  Mit Vorsicht geniessen! Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
*[[Media:SIP9_Housing_14Jun2013.zip]] Footprints/Module von SIP9 Gehäusen (z.B. TA7358).Mit 3D-Modell und PDF-Ausdruck zur leichteren Identifikation. Ohne Garantie und unter CC-Zero / Public Domain.  Mit Vorsicht geniessen! Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
*[[Media:7Segment_16Sep2013.zip]] Footprints/Module von 7-Segment Anzeigen HDSM531 (SMD), HDSM533 (SMD), LTS6760, LTS6780 undSBC18-11EGWA. Dazu PDF-Ausdruck zur leichteren Identifikation. Ohne Garantie und unter CC-Zero / Public Domain.  Mit Vorsicht geniessen! Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
*[[Media:BNC-Sockets_RevA.zip]] Footprints/Module von TYCO BNC-Buchsen für KiCad. Mit 3D Modellen und PDF Preview. Ohne Garantie und unter CC-Zero / Public Domain.  Mit Vorsicht geniessen! Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
*[[Media:LQFP_TQFP_RevA_06Oct2013.zip]] Footprints/Module von LQDP48/TQFP48 Gehäuseb für KiCad. Ohne 3D Modelle, aber mit PDF Preview. Ohne Garantie und unter CC-Zero / Public Domain.  Mit Vorsicht geniessen! Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
*[[Media:LEM_HallEffectTransducers_RevA_13Oct2012.zip]] Module/Footprints von Halleffekt Stromwandlern der Serien &amp;quot;HX&amp;quot; und &amp;quot;HTFS&amp;quot; von LEM. Mit 3D-Modellen  und PDF Preview. Ohne Garantie und unter CC-Zero / Public Domain.  Mit Vorsicht geniessen! Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
==== 3D-Modelle ====&lt;br /&gt;
&lt;br /&gt;
* [[Media:MeshModells_VRML-Wings3D_13Oct2013.zip]]  3D-Modelle diverser elektronischer Bauteile im wrl 2.0 und wings Format. Enthalten: DD-PAK (TO263AB), D-PAK (TO252AA), SMD Dioden MELF, MiniMELF, SMA, SMB und SMC, Transformatoren ETAL P1165, P1200, P2781, P3000, P3181, PP3188 und P3191, SO126 / SOT32 in horizontal und vertikal, SOT223-3, TO263-3, SOT89-3, SOT89-5, TO220 horizontal und vertikal und reverse. TO220-5 horizontal, vertical, inline und verkröpft, VML0806. SIP9. 7 Segment SMD Anzeige HDSM531/HDSM533 in Grün, gelb, rot und orange. directFET SMD-Transistor Gehäusen von International Rectifier für KiCad. Enthält die SH, SJ, SQ, ST, S1, MN, MP, MT, MX, MZ und die L8-Outlines. Flachsicherungen Standard und Mini. Halleffekt Stromwandler LEM &amp;quot;HX&amp;quot; Serie und Allegro ACS754/ACS755/ACS756 mit CB-PFF, CB-PSF und CB-FSS Gehäusen. Ohne Garantie und unter CC-Zero / Public Domain Lizenz. Mit Vorsicht geniessen! Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
==== Building-Blocks ====&lt;br /&gt;
*[[Media:BuildingBlocks_16Jun2013.zip]] enthält eine Sammlung von gängigen Schaltungen mit den Längstreglern LM317 /LM78xx /LM79xx und dem Timer 555, die nach dem in diesem [[Media:HierarchischeSchaltplaeneAlsBausteineInKicad_RevC_23Dec2013.pdf]] Dokument beschriebenen Vorgehen als Building Blocks in KiCad verwendet werden können. Ein Katalog dazu befindet sich hier: [[Media:KatalogUeberKiCadBuildingBlocks_21Apr2013.pdf]]. Autor: Bernd Wiebus, Lizenz: Creative Commons. Experimentell! Ohne Garantie! Mit Vorsicht geniessen!&lt;br /&gt;
&lt;br /&gt;
Wenn mindestens ein weiterer KiCad User die Bibliothek geprüft hat, kann sie in den folgenden Unterabschnitt verschoben werden.&lt;br /&gt;
&lt;br /&gt;
=== Geprüfte ===&lt;br /&gt;
&lt;br /&gt;
Hier sollen geprüfte Bibliotheken gesammelt werden. Bitte angeben, wer die Prüfung gemacht hat.&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/132288#new STM32F103xx (LQFP64) Schaltplansymbol] erstellt/geprüft: Dominik C.; Marko S.&lt;br /&gt;
* Bei der STMF103xx fehlt glaub ich der Portpin PD2 :) Grüße :)&lt;br /&gt;
&lt;br /&gt;
=== Sonstige Bibliotheken im Netz ===&lt;br /&gt;
&lt;br /&gt;
Die Einträge hier sind nach [[KiCad-Bibliotheken#Bibliotheken_im_Netz|KiCad-Bibliotheken im Netz]] verschoben worden. &#039;&#039;&#039;Bitte Überarbeitungen und neue Einträge nur dort vornehmen!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Bitte diesen Unterpunkt &#039;&#039;&#039;nicht Löschen&#039;&#039;&#039;, da es Verweise aus dem Forum oder von sonstwo geben mag, die sonst ins Leere laufen, ohne eine Erklärung für den User.&lt;br /&gt;
&lt;br /&gt;
= Tools =&lt;br /&gt;
&lt;br /&gt;
== Allgemeine Werkzeuge ==&lt;br /&gt;
&lt;br /&gt;
Da die in KiCad verwendeten Dateien klarschriftlesbar sind, lassen sie sich sehr leicht mit externen Programmen und Skripten bearbeiten, um spezielle Funktionalitäten zu erzeugen. Eine kleine Auswahl an Programmen/Skripten ist hier zusammengestellt:&lt;br /&gt;
&lt;br /&gt;
* [http://kicad.rohrbacher.net/quicklib.php Quick KICAD Library Component Builder]&lt;br /&gt;
* Gerber-Tools sind für KiCad weniger nötig, da KiCad mit GerbView seinen eigenen Gerberviewer mitbringt. Dieser ist mächtig genug, die eingelesenen Gerberfiles als Platine in PCBnew zu exportieren, wo sie manipuliert werden können. Dieses geht aber nur mit Gerber-RS274X Daten. Ebensowenig können Gerberfiles zu Nutzen zusammengefügt werden. Hierzu bietet sich &amp;quot;Gerbmerge&amp;quot; http://ruggedcircuits.com/gerbmerge (http://claymore.engineer.gvsu.edu/~steriana/Python/gerbmerge/ Veraltet) an. Wer lediglich aus Sicherheitsgründen die von KiCad erzeugten Gerberdaten mit einem fremden Gerber-Vierer inspizieren möchte, findet hier Hinweise:http://www.mikrocontroller.net/articles/Gerber-Tools&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/204063#2011138 KiCad (Multi-)Symbol Tool] von Joghurt3000 zur Erstellung von Symbolen aus einer Textvorlage&lt;br /&gt;
* [http://cyclerecorder.org/footprintbuilder Footprintbuilder] Java-Programm zu Erstellung von Footprints.&lt;br /&gt;
*Wer seine Platine &amp;quot;panelisieren&amp;quot; (d.h. mehrmals nebeneinander anordnen um in einem &amp;quot;Nutzen&amp;quot; gleich mehrere Platinen fertigen zu können) möchte, kann das mit dem Python 2 Skript &amp;quot;panelize.py&amp;quot; tun. Das Programm arbeitet direkt auf den kicad .brd Files, so das das Mehrfachnutzen Board unter PCBnew nachbearbeitet werden kann, für z.B. einen  DRC. &amp;quot;panelize.py&amp;quot; kann hier bezogen werden: http://blog.borg.ch/?p=12&lt;br /&gt;
* &amp;quot;Raef&amp;quot; hat ein Python Script erstellt, das Bauteile automatisch ähnlich der Anordnung im Schaltplan plaziert. Siehe: http://www.mikrocontroller.net/topic/293903#3245990&lt;br /&gt;
*Wer die Reihenfolge der Subschaltpläne ändern will (Wegen Übersichtlichkeit/Bestimmt auch die Reihenfolge beim Ausdrucken), kann dieses Python 3 Skript verwenden (Liesmich/Readme beachten): http://www.mikrocontroller.net/wikifiles/9/90/PyKicadSchematic-ID_Interchanger_RevC.zip Autor: Bernd Wiebus, GNU-GPL. Dieses Skript ist unabhängig von der PCBnew internen Python 2 Schnittstelle.&lt;br /&gt;
* Um ältere Schaltpläne von vor Jan./Feb. 2014 (BZR4646) mit &amp;quot;upper case&amp;quot; Symbolnamen zu konvertieren, kann dieses Python 3 Skript verwendet werden: [[Media:PyKiCad-CaseSensitiveLibCure_RevD_13Apr2015.zip]]. Autor: Bernd Wiebus, GNU-GPL. Dieses Skript ist unabhängig von der PCBnew internen Python 2 Schnittstelle.&lt;br /&gt;
* Wem das Tricksen mit Dateimanager oder Schematic oder Board als Bibliotheksmanager nicht gefällt, findet vieleicht im &amp;quot;KiCad Libarian&amp;quot; ein passendes Tool: http://www.compuphase.com/electronics/kicadlibrarian_en.htm&lt;br /&gt;
* Diverse Skripte, um KiCad Symbole, Footprints oder sonstigen Bibliothekskram zu bearbeiten. [https://github.com/KiCad/kicad-library-utils]&lt;br /&gt;
* Cirillo Bernardo hat einige Programme geschrieben, um VRML 3D Gitter Modelle für Bauteile parametrisch zu erzeugen. Sie finden sich hier: https://github.com/cbernardo/kicad3Dmodels&lt;br /&gt;
* Peter Hofbauer hat einige Windows Programme geschrieben, die zur KiCad Unterstützung dienen: http://www.hcp-hofbauer.de/software.htm Bei den Programmen handelt es sich um &amp;quot;Aufräumprogramme für Bibliotheken, Stücklistenerzeugung, Extraktionsprogramm um eine Verdrahtungsliste aus einer Netzliste zu erzeugen, Ein Programm um Boherdurchmesser zu vereinheitlichen und ein Programm, um zusammen mit &amp;quot;Linegrinder&amp;quot; G-Code aus KiCad Boarddateien zu erzeugen. &lt;br /&gt;
* [http://escalalibre.com/edwt/kicad_sizeConverter.php KiCad Bitmap2Component Skalierer] Erlaubt es, Logos zu skalieren.&lt;br /&gt;
* [http://escalalibre.com/edwt/kicad_modTextChanger.php KiCad Module Text Changer]&lt;br /&gt;
* [https://www.mikrocontroller.net/topic/381605?reply_to=4346454#4346280 KiCad Symbol Generator Tool] KiCad Symbol Generator Tool als Python Skript&lt;br /&gt;
* [https://github.com/tlantela/KiCad_layout_cloner/blob/master/layout_cloner.py KiCad Layout Cloner] Python Skript. Siehe http://www.mikrocontroller.net/topic/382657#4363261&lt;br /&gt;
* [https://forum.kicad.info/t/kicad-stepup-the-sketcher-for-getting-to-blinky/7826] StepUp, eine Workbench für FreeCAD (ein open source 3D CAD Program) um den Import und Export von mecanichen CAD Daten von KiCad zu erleichtern.&lt;br /&gt;
* [https://hasanyavuz.ozderya.net/?p=256 Ein Backannotationstool für KiCad] als Pythonskript&lt;br /&gt;
* [https://www.mikrocontroller.net/topic/450655#new Ein Tool, um per Skripting Messpunkte für einen Nadelbettadapter zu erzeugen.] Geht von Gerberdaten aus, die in KiCad importiert werden&lt;br /&gt;
&lt;br /&gt;
== Konverter ==&lt;br /&gt;
&lt;br /&gt;
Konverter wandeln KiCad-Daten in die Daten anderer Layoutprogramme bzw. die Daten anderer Layoutprogramme in KiCad-Daten um.&lt;br /&gt;
Nativ kann KiCad gEDA Footprints bzw. neuere Eagle Footprints direkt als Bibliothek einbinden. Das ganze ist aber als noch sehr experimentell zu betrachten.&lt;br /&gt;
&lt;br /&gt;
Des Weiteren gibt es einige Programme oder Skripte von dritter Seite, die Daten anderer Layoutprogramme in KiCad Daten umwandeln. Auch diese sind als experimentell einzustufen.&lt;br /&gt;
&lt;br /&gt;
Hier eine Auswahl:&lt;br /&gt;
* https://github.com/thesourcerer8/altium2kicad Wandelt Altium Schaltpläne und Layouts in KiCad Daten um.&lt;br /&gt;
* https://github.com/DanChianucci/Eagle2Kicad Wandelt Eagle 6.0 Layouts in KiCad Layouts.&lt;br /&gt;
* https://github.com/lachlanA/eagle-to-kicad Wandelt Eagle 6.0 Layouts in KiCad Layouts.&lt;br /&gt;
* http://www.cadsoft.de/downloads/file/eagle2kicad-0.9c.ulp Direkt von der Cadsoft Seite, ein ULP das Eagle Daten in KiCad Daten wandelt.&lt;br /&gt;
* http://www.cadsoft.de/downloads/file/eagle2kicad_sch.ulp Ebenfalls direkt von der Cadsoft Seite, ein ULP, das Eagle Schaltpläne in KiCad Schaltpläne wandelt.&lt;br /&gt;
* http://sourceforge.net/projects/pcad2kicad/ Wandelt P-CAD Schaltpläne, Layouts und Bibliotheken in KiCad Daten um.&lt;br /&gt;
* Gerber_Settings    [https://www.mikrocontroller.net/attachment/319118/originpoint.png originpoint]     [https://www.mikrocontroller.net/topic/319266?page=5#4891032 Gerber_Settings] [https://www.mikrocontroller.net/attachment/319192/Bohrdatei.png Drill_Files_Generation]&lt;br /&gt;
* https://github.com/mtl/svg2mod Tool, welches SVG in KiCad Board Layers wandelt. Einleitende Informationen finden sich hier: https://www.mikrocontroller.net/topic/440552#5234307&lt;br /&gt;
&lt;br /&gt;
Erfahrungsberichte willkommen!&lt;br /&gt;
&lt;br /&gt;
= Beispielprojekte =&lt;br /&gt;
&lt;br /&gt;
* http://www.mikrocontroller.net/topic/33653#963083 JTag-wiggler&lt;br /&gt;
* http://www.mikrocontroller.net/topic/190088#1856757 Klopfsensor von Peter Diener.&lt;br /&gt;
* http://www.mikrocontroller.net/topic/188897 Open-Hardware / Open-Source USB-basierter SPI BIOS-Chip Programmer von Uwe Hermann&lt;br /&gt;
* http://www.mikrocontroller.net/articles/Modellbahn_Servodecoder_f%C3%BCr_Weichen_mit_R%C3%BCckmeldung Modellbahn Servodecoder für Weichen mit Rückmeldung&lt;br /&gt;
* http://www.mikrocontroller.net/articles/RS485_IO_Board_-_ModellBahnLichtSteuerung RS485 IO Board - ModellBahnLichtSteuerung&lt;br /&gt;
* [[Media:UndervoltageProtection_RevD_14Aug2012.zip]] Beispielprojekt eines Tiefentladeschutzes für einen Blei-Gel Akku, der von den Platinenabmessungen her auf einen typischen 12V/7,2Ah Akku passt. Ausserdem bietet er abgesicherten Zugang zu den Akkuklemmen, was auch in vielen Fällen beachtenswert ist. Leider ist das Projekt noch etwas unaufgeräumt, es fehlen noch Bauteilwerte, und in der Form wurde noch keine fertige Platine daraus hergestellt, aufgebaut und getestet. Autor: Bernd Wiebus, GNU-GPL.&lt;br /&gt;
* http://www.mikrocontroller.net/topic/338835#3724591 Universeller Adapter PDI, JTAG, ISP mit KICAD&lt;br /&gt;
* http://n8vem-sbc.pbworks.com/w/page/4200908/FrontPage Eine Seite mit Selbstbaucomputern, teilweise &amp;quot;Retro&amp;quot; mit S100 Bus.&lt;br /&gt;
* [[Media:DC-50Ohm_Terminierung_RevE_25Mar2015.zip]] 50 Ohm DC entkoppelte Terminierung fuer Oszilloskope. [[Bild:DC-50Ohm_Terminierung_Downside.png|thumb|150px|Unterseite des DC-Messadapters mit kapazitiv entkoppelter 50 Ohm Terminierung]] [[Bild:DC-50Ohm_Terminierung_Upside.png|thumb|150px|Oberseite des DC-Messadapters mit kapazitiv entkoppelter 50 Ohm Terminierung]] Dieses Beispiel enthält Board-Dateien Version 5. Möchte man diese mit einem älteren KiCad, welches nur Version 4 kennt, öffnen, so müssen die Dateien angepasst werden. Eine Anleitung findet sich hier: [[Media:KiCad-PCBnewBoardDateienMigrierenVonVersion4Auf5.pdf]]&lt;br /&gt;
* https://www.mikrocontroller.net/attachment/261855/QRP-SWR-Bridge_ModC_RevA-pretty_11Jul2015.zip Resistive SWR-Messbrücke für QRP Kleinleistung auf Kurzwelle. Einer der Vorteile ist hohe Empfindlichkeit und dass sie auch bei Fehlanpassung dem Senderausgang einen bedämpften, halbwegs passenden Abschluss bietet. Anwendungsbeispiel Moqsquita ( http://www.qrpproject.de/Media/pdf/Mosquita40.pdf ) für 40m und weitere Infos, auch zu Bauteilen, finden sich hier im Thread: https://www.mikrocontroller.net/topic/371365#4194810 Dieses Beispiel enthält Board-Dateien Version 5. Möchte man diese mit einem älteren KiCad, welches nur Version 4 kennt, öffnen, so müssen die Dateien angepasst werden. Eine Anleitung findet sich hier: [[Media:KiCad-PCBnewBoardDateienMigrierenVonVersion4Auf5.pdf]]&lt;br /&gt;
* [http://hforsten.com/third-version-of-homemade-6-ghz-fmcw-radar.html Ein selbstgebautes 6GHz FMCW Radar] Die KiCad Files dazu liegen [https://github.com/Ttl/fmcw3 hier auf Github]. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- alt -- &lt;br /&gt;
= Diskussionen (teilweise seeeehr alt) =&lt;br /&gt;
&lt;br /&gt;
* http://www.mikrocontroller.net/topic/120373#1089075 &lt;br /&gt;
* http://www.mikrocontroller.net/topic/98034#848559&lt;br /&gt;
* http://www.mikrocontroller.net/topic/95864#828660&lt;br /&gt;
* http://www.mikrocontroller.net/topic/77738#647041&lt;br /&gt;
* http://www.mikrocontroller.net/topic/103806#907523&lt;br /&gt;
* http://www.mikrocontroller.net/topic/41999#316195&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Weblinks =&lt;br /&gt;
&lt;br /&gt;
* [http://www.KiCad-pcb.org KiCad-pcb.org] Die neue Homepage&lt;br /&gt;
* [http://kicad-pcb.org/help/documentation/ Offizielle Dokumentation]&lt;br /&gt;
* [https://bugs.launchpad.net/kicad Bugreports] erstellen und nach vorhandenen Fehlern suchen, wenn einem etwas komisch vorkommt.&lt;br /&gt;
&lt;br /&gt;
* Tutorials: &lt;br /&gt;
&amp;lt;!-- alt -- ** [http://kicad.sourceforge.net/wiki/index.php/DE:Mini_tutorial Mini-Tutorial] --&amp;gt;&lt;br /&gt;
** [http://timogruss.de/kicad-loesung-fuer-die-leiterplatten-entwicklung/ KiCad Tutorial auf timogruss.de] (deutsch) (2013)&lt;br /&gt;
** https://www.youtube.com/watch?v=XD_PaSrLKBk Schematic Pages and Hierarchy In KiCad - Hierarchischer Schaltplan (2014)&lt;br /&gt;
** https://www.youtube.com/watch?v=YCdpXwRKbYc Create a library and put your own component in that library. (2014)&lt;br /&gt;
&amp;lt;!-- alt --&lt;br /&gt;
** http://store.curiousinventor.com/guides/kicad&lt;br /&gt;
** https://contextualelectronics.com/course/kicad-tutorial/ (Video Tutorials auf Englisch)&lt;br /&gt;
** http://xtronics.com/reference/kicad.html --&amp;gt;&lt;br /&gt;
** http://bastler-archiv.de/elektronik/platinenherstellung-platinenlayout-mit-kicad-teil-1/ (deutsch, Teil 1) (2011)&lt;br /&gt;
** http://bastler-archiv.de/elektronik/platinenherstellung-platinenlayout-mit-kicad-teil-2/ (deutsch, Teil 2) (2011)&lt;br /&gt;
** http://www.kramann.info/73_COACH3/06_Layouting/Layouting_art_Guido_Kramann_12122010.pdf (2010)&lt;br /&gt;
** [https://rheingoldheavy.com/category/education/kicad/ KiCad Tutorials zum Workflow, Migration alter KiCad Versionen und zu Stücklisten (RheingoldHEAVY, auf englisch)] (2015)&lt;br /&gt;
&amp;lt;!-- alt -- ** [http://roberthall.net/Wings3D_Tutorial_KiCad Tutorial zur Benutzung von Wings3D im KiCad Umfeld (englisch)] --&amp;gt;&lt;br /&gt;
** https://www.youtube.com/watch?v=i4vLxAoLvPk Video Tutorial auf Deutsch. Relativ aktuell.&lt;br /&gt;
&lt;br /&gt;
* Info&lt;br /&gt;
** [https://kicad.mmccoo.com/kicad-scripting-table-of-contents/ Python Scripting for KiCad] und [http://docs.kicad-pcb.org/doxygen-python/namespacepcbnew.html Befehlsliste]&lt;br /&gt;
** [https://wiki.aalto.fi/display/MEX/Introduction+to+KiCad] Ein paar Tips am Rande (2014)&lt;br /&gt;
** [http://www.daedalus.ei.tum.de/index.php/de/3d-druck-cnc/cnc/layout-und-g-code-erstellung-mit-kicad] Info für Leute, die Platinen durch Isolationfräsen statt ätzen erstellen&lt;br /&gt;
** [http://davidetienne.me/blog/2015/10/05/kicad-convert-ti-bxl-cad-files-to-kicad-libraries/] Ein Weg, um Libraries, die im Texas Instruments Format &amp;quot;.bxl&amp;quot; vorliegen, in KiCad Bibliotheken zu konvertieren. (2015)&lt;br /&gt;
&lt;br /&gt;
* Usergroups:&lt;br /&gt;
** [https://groups.yahoo.com/neo/groups/kicad-users/info Yahoo-KiCad-User-Group (Englischsprachig)]&lt;br /&gt;
** [https://forum.kicad.info/ Endlischsprachiges KiCad Forum]&lt;br /&gt;
&amp;lt;!-- alt -- ** [http://1.cad-kicad-user.cadtalk.us/ Englischsprachige Diskussionen über KiCad im &amp;quot;Cadtalk&amp;quot;-Forum] Leider nicht mehr existent. --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Tools&lt;br /&gt;
** [http://www.freerouting.net/ Freerouting] Autorouter (down: Download siehe [https://www.mikrocontroller.net/articles/KiCad#Tipps.26Tricks:_KiCad_und_Freeroute Tipps und Tricks])&lt;br /&gt;
** [http://www.mikrocontroller.net/articles/KiCad#Tools Liste mit externen Programmen und Skripten im Zusammenhang mit KiCad]&lt;br /&gt;
&lt;br /&gt;
* Verschiedenes im Zusammenhang mit KiCad&lt;br /&gt;
** [https://github.com/KiCad/kicad-library/wiki/Kicad-Library-Convention Kicad Library Convention / Regeln für offizielle KiCad Bibliotheken (Englisch)]&lt;br /&gt;
** [http://www.compuphase.com/electronics/LibraryFileFormats.pdf Aufbau der unterschiedlichen KiCad Bibliotheks Files (englisch)]&lt;br /&gt;
** [http://www.ohwr.org/projects/cern-kicad/wiki/WorkPackages CERN KiCad development roadmap / Was ist in KiCad Entwicklung geplant? (englisch)]&lt;br /&gt;
** [http://home.web.cern.ch/about/updates/2015/02/kicad-software-gets-cern-treatment Warum das CERN KiCad unterstützt (englisch)]&lt;br /&gt;
** [https://www.youtube.com/watch?v=chejn7dqpfQ Video mit der Leiterbahnlängenanpassen Funktion bzw. der &amp;quot;Differential pair&amp;quot; Funktion in KiCad.]&lt;br /&gt;
** [http://www.youtube.com/watch?v=irqlrVUbjuQ Video mit dem interaktiven Router]&lt;br /&gt;
&lt;br /&gt;
* Plattformen&lt;br /&gt;
&amp;lt;!-- alt -- ** Mac: http://brokentoaster.com/kicad/ --&amp;gt;&lt;br /&gt;
**Ubuntu: [http://www.mikrocontroller.net/topic/257321#2658268 KiCad selber compilieren] (2012)&lt;br /&gt;
** http://wiki.xtronics.com/index.php/Kicad Transtronics site (englisch)&lt;br /&gt;
&lt;br /&gt;
* HowTo von Tom Boyd (englisch)&lt;br /&gt;
** http://kicadhowto.wikidot.com/&lt;br /&gt;
** http://kicadhowto.org/&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:KiCad]]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Part-DB_RW_-_Lagerverwaltung&amp;diff=97581</id>
		<title>Part-DB RW - Lagerverwaltung</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Part-DB_RW_-_Lagerverwaltung&amp;diff=97581"/>
		<updated>2017-10-18T07:52:34Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: /* Aufbau des Servers unter VMware Server 2.0 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Die &amp;quot;Part-DB&amp;quot; (vormals &amp;quot;Part-DB RW - Lagerverwaltung für Elektronikteile&amp;quot;) ist ein Web basierendes System zur Verwaltung elektronischer Bauteile. Das Original stammt von [http://www.cl-projects.de/projects/part-db/ CL-Projekts.de] und wird seit Anfang 2009 von [http://www.grautier.com/ K.J.(Theborg0815)] weitergeführt.&lt;br /&gt;
&lt;br /&gt;
== Überblick ==&lt;br /&gt;
&lt;br /&gt;
=== Lizenzmodell ===&lt;br /&gt;
&lt;br /&gt;
Part-DB steht unter der General Public License Version 2. Zusätzlich dazu werden externe Bibliotheken verwendet die unter anderen Lizenzen stehen . Diese sind aber alle kompatibel mit der GPL, weswegen auch eine kommerzielle Nutzung problemlos möglich sein sollte. Weitere Informationen zu den externen Bibliotheken hier: https://github.com/jbtronics/Part-DB/blob/nextgen/readme/EXTERNAL_LIBS.md.&lt;br /&gt;
&lt;br /&gt;
=== Funktionen ===&lt;br /&gt;
&lt;br /&gt;
* Angabe von Lagerorten, Footprints, Kategorien, Lieferanten, Datenblattern, Preise, Bestellnummern, ...&lt;br /&gt;
* Baugruppenverwaltung&lt;br /&gt;
* Upload von Bauteil Bildern&lt;br /&gt;
* Automatische Anzeige von Footprintbildern&lt;br /&gt;
* Statistik über das gesamte Lager&lt;br /&gt;
* Auflistung von: &amp;quot;Zu bestellende Teile&amp;quot;, &amp;quot;Teile ohne Preis&amp;quot; und &amp;quot;nicht mehr erhältliche Teile&amp;quot;&lt;br /&gt;
* Liste von Hersteller-Logos&lt;br /&gt;
* Informationen zu SMD-Beschriftungen von Widerstände, Kondensatoren und Spulen&lt;br /&gt;
* Widerstandsrechner&lt;br /&gt;
* Barcodegenerator und Scanfunktion für Barcodes&lt;br /&gt;
* Verschiedene mitgelieferte Themes&lt;br /&gt;
* 3D Footprints&lt;br /&gt;
* Unterstützung von BBCode, in den Bauteilen&lt;br /&gt;
* Suche mittels regulärer Ausdrücke&lt;br /&gt;
* Auflistung von Teilen in einem Lagerort, mit einem bestimmten Footprint oder einem bestimmten Hersteller&lt;br /&gt;
* automatische Erzeugung einer Tabelle mit Bauteileigenschaften aus dem Beschreibungsfeld.&lt;br /&gt;
* nutzt HTML5, mobile Ansicht&lt;br /&gt;
* Benutzersystem mit Unterstützung für Gruppen und Berechtigungen.&lt;br /&gt;
&lt;br /&gt;
=== Anforderungen ===&lt;br /&gt;
&lt;br /&gt;
* Webserver mit ca. 10MB Platz (ohne Footprints)&lt;br /&gt;
* PHP &amp;gt;= 5.4.0, mit PDO, mbstring und gettext&lt;br /&gt;
* MySQL/MariaDB Datenbank&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
Die aktuelle Dokumentation (inkl. Installationsanleitung) ist hier verfügbar: https://github.com/jbtronics/Part-DB/wiki&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für Part-DB Version 3.0 findet sich hier eine Dokumentation: http://fthiessen.de/part-db/doku.php?id=start&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
=== Anleitung zum Bau eines PartDB-Servers in einer virtuellen Maschine ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Dieser Abschnitt hat noch Baustellenstatus&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==== Voraussetzungen ====&lt;br /&gt;
&lt;br /&gt;
* VMware Server 2.0 oder ein ähnliches System ist installiert. (Kann von http://downloads.vmware.com/d/info/datacenter_downloads/vmware_server/2_0 kostenlos heruntergeladen werden.)&lt;br /&gt;
&lt;br /&gt;
==== Aufbau des Servers unter VMware Server 2.0 ====&lt;br /&gt;
&lt;br /&gt;
* Herunterladen der TurnKey Core Appliance von http://www.turnkeylinux.org/core&lt;br /&gt;
* Entpacken des Archivs in das Verzeichnis für virtuelle Maschinen&lt;br /&gt;
* Importieren der VM über das Browser-Applet für den VMware Server:&lt;br /&gt;
** &#039;&#039;&#039;Virtual Machine | Add Virtual Machine to Inventory&#039;&#039;&#039; klicken&lt;br /&gt;
** Unter &#039;&#039;&#039;Inventory&#039;&#039;&#039; &#039;&#039;Standard&#039;&#039; klicken&lt;br /&gt;
** Unter &#039;&#039;&#039;Content&#039;&#039;&#039; das Verzeichnis der zu importierenden VM doppelklicken&lt;br /&gt;
** Die .vmx-Datei anklicken und mit OK bestätigen&lt;br /&gt;
* Im &#039;&#039;&#039;Inventory&#039;&#039;&#039;-Bereich des Hauptfensters die neue VM auswählen und warten, bis rechts Daten und Befehle angezeigt werden.&lt;br /&gt;
* Rechts in der Mitte unter &#039;&#039;&#039;Commands&#039;&#039;&#039; den Link &#039;&#039;Power on&#039;&#039; anklicken.&lt;br /&gt;
* Den Reiter &#039;&#039;&#039;Console&#039;&#039;&#039; anklicken. Es öffnet sich ein Fenster mit schwarzem Hintergrund.&lt;br /&gt;
* In das schwarze Fenster klicken und warten, bis das Konsolfenster der VM aufgeht.&lt;br /&gt;
&lt;br /&gt;
Im Konsolfenster wird nach vollständigem Boot ein Dialog angezeigt, der im Wesentlichen die IP-Adresse der VM enthält, die in der Grundeinstellung über DHCP bezogen wird.&lt;br /&gt;
&lt;br /&gt;
Über den einzigen Menüpunkt dieses Dialogs kann &#039;&#039;später&#039;&#039; eine statische IP-Adresse eingestellt werden.&lt;br /&gt;
&lt;br /&gt;
Die virtuelle Maschine kann je nach Host-Betriebsystem mit folgenden Programmen administriert werden:&lt;br /&gt;
&lt;br /&gt;
* Windows&lt;br /&gt;
** puTTY zum Einloggen in die VM&lt;br /&gt;
** WinSCP für den (höchst komfortablen) Dateitransfer&lt;br /&gt;
Beide Programme sind kostenlos auf dem Web zu finden&lt;br /&gt;
* Linux&lt;br /&gt;
** ssh zum Einloggen in die VM&lt;br /&gt;
** sftp für den Dateitransfer&lt;br /&gt;
&lt;br /&gt;
==== Vorbereiten der VM für PartDB ====&lt;br /&gt;
&lt;br /&gt;
* Einloggen in die VM über puTTY/ssh&lt;br /&gt;
** Nachladen der benötigten Zusatzmodule übers Web mit folgenden Befehlen&lt;br /&gt;
*** apt-get update&lt;br /&gt;
*** sudo apt-get install apache2 php7.0 mysql-server php7.0-mysql php7.0-curl libapache2-mod-php7.0 phpmyadmin php7.0-opcache php7.0-gettext&lt;br /&gt;
&lt;br /&gt;
Damit ist apache2, mysql, php5 und phpmyadmin installiert.&lt;br /&gt;
&lt;br /&gt;
Als erstes wird über Webmin der User part-db in der VM angelegt:&lt;br /&gt;
&lt;br /&gt;
* https://&amp;lt;ip-adresse der vm&amp;gt;:12321/&lt;br /&gt;
** &#039;System | Users and Groups&#039;&#039; klicken&lt;br /&gt;
** Den Link &#039;&#039;Create a new user.&#039;&#039; klicken&lt;br /&gt;
*** Username: part-db&lt;br /&gt;
*** User ID: Automatic&lt;br /&gt;
*** Real name: part-db&lt;br /&gt;
*** Create home directory? No  (Steht ganz unten!)&lt;br /&gt;
** Create-Button klicken&lt;br /&gt;
&lt;br /&gt;
Jetzt kann PhpMyAdmin im Browser des Hostsystems aufgerufen werden:&lt;br /&gt;
&lt;br /&gt;
* http://&amp;lt;ip-adresse der vm&amp;gt;/phpmyadmin&lt;br /&gt;
&lt;br /&gt;
Weiter geht es dann wie oben unter [https://github.com/jbtronics/Part-DB/wiki/Installation#anlegen-der-datenbank Anlegen der Datenbank] beschrieben, um die Datenbank anzulegen.&lt;br /&gt;
&lt;br /&gt;
Nach dem Abschnitt &#039;&#039;&#039;Anlegen der Datenbank&#039;&#039;&#039; wird hier fortgesetzt:&lt;br /&gt;
&lt;br /&gt;
Eine fertig konfigurierte virtuelle Maschine kann hier heruntergeladen werden (veraltete Version): [http://www.mikrocontroller.net/attachment/63911/part-db.tar.bz2] Der Download ist mit gut 216 MB allerdings ziemlich fett.&lt;br /&gt;
&lt;br /&gt;
== Online-Demo ==&lt;br /&gt;
Wer Part-DB einmal ausprobieren möchte ohne es installieren zu müssen, findet hier eine Demoinstallation: http://part-db.bplaced.net/startup.php &lt;br /&gt;
Diese ist auch auf Englisch verfügbar: http://part-db.bplaced.net/part-en/startup.php&lt;br /&gt;
&lt;br /&gt;
Um ein Bauteil in der Demo bearbeiten zu können, müssen sie sich oben rechts mit Klick auf das Usericon einloggen: Benutzen sie hierfür den Nutzernamen: &amp;quot;user&amp;quot; und das Password: &amp;quot;user&amp;quot; (Ohne Anführungszeichen).&lt;br /&gt;
&lt;br /&gt;
== Wünsche / Verbesserungsvorschläge / Bugreports ==&lt;br /&gt;
&lt;br /&gt;
Du hast Wünsche, Verbesserungsvorschläge oder einen Bug gefunden? Dann schau bitte zuerst in unsere TODO-Liste, ob nicht schon ein solcher Eintrag vorhanden ist: https://github.com/jbtronics/Part-DB/issues&lt;br /&gt;
&lt;br /&gt;
Ist kein entsprechender Eintrag in der TODO-Liste vorhanden, bitte kurz im Diskusionsthread schreiben worum es geht: https://www.mikrocontroller.net/topic/305023&lt;br /&gt;
&lt;br /&gt;
== Screenshots ==&lt;br /&gt;
Aktuelle Screenshots finden sich hier: https://github.com/jbtronics/Part-DB/wiki/Screenshots&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery caption=&amp;quot;Part-DB nextgen&amp;quot; widths=&amp;quot;150px&amp;quot; perrow=&amp;quot;4&amp;quot;&amp;gt;&lt;br /&gt;
Datei:Startseite.png|Startseite&lt;br /&gt;
Datei:List parts.png|Bauteile mit einer bestimmten Kategorie&lt;br /&gt;
Datei:Parts info.png|Bauteilübersicht&lt;br /&gt;
Datei:Edit part.png|Bauteilbearbeitung&lt;br /&gt;
Datei:Search.png|Suchfunktion&lt;br /&gt;
Datei:System setting.png|Systemeinstellungen&lt;br /&gt;
Datei:Edit storelocations.png|Lagerorte bearbeiten&lt;br /&gt;
Datei:Baugruppenübersicht.png|Baugruppenübersicht&lt;br /&gt;
Datei:Theme1.png|Alternatives Theme 1&lt;br /&gt;
Datei:Theme2.png|Alternatives Theme 2&lt;br /&gt;
Datei:Theme3.png|Alternatives Theme 3&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Version 0.3 ===&lt;br /&gt;
&amp;lt;gallery caption=&amp;quot;Version 0.3&amp;quot; widths=&amp;quot;150px&amp;quot; heights=&amp;quot;150px&amp;quot; perrow=&amp;quot;4&amp;quot;&amp;gt;&lt;br /&gt;
Datei:partdb.png|Index Seite&lt;br /&gt;
Datei:list.png|Liste&lt;br /&gt;
Datei:bestelliste.png|Bestelliste&lt;br /&gt;
Datei:Baugruppe.png|Baugruppe&lt;br /&gt;
Datei:stats.png|Statistik&lt;br /&gt;
Datei:footprints.png|Footprints&lt;br /&gt;
Datei:iclogos.png|IC Logos&lt;br /&gt;
Datei:Labels.png|Labels&lt;br /&gt;
Datei:Widerstandsrechner.png|Widerstandsrechner&lt;br /&gt;
Datei:greenway.png| Anderes Theme (Greenway)&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
* Die Homepage des (veralteten) Org. Projektes finden Sie unter http://www.cl-projects.de/projects/part-db/.&lt;br /&gt;
* PART-DB RW Fork/Weiterentwicklung: http://www.grautier.com/grautier/index.php?/archives/77-Part-DB-V0.1.3-RW.html&lt;br /&gt;
* Diskussion: https://www.mikrocontroller.net/topic/305023&lt;br /&gt;
* Github repository (bis v0.3.1): https://github.com/sandboxgangster/Part-DB&lt;br /&gt;
* Github Fork v0.4.0: https://github.com/jbtronics/Part-DB/&lt;br /&gt;
&lt;br /&gt;
andere Softwareprodukte mit vergleichbarer Funktionalität:&lt;br /&gt;
* Teileverwaltung von Gutmensch (App. basiert): http://www.mikrocontroller.net/topic/89071#new&lt;br /&gt;
* [[Elektronik Lagerverwaltung]] ein anderes Lagerverwaltungsprogramm, EXE für Windows &lt;br /&gt;
* PartKeepr: https://github.com/partkeepr/PartKeepr, [http://demo.partkeepr.org/ Demo]&lt;br /&gt;
&lt;br /&gt;
[[Category:Projekte]]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Schaltplaneditoren&amp;diff=91359</id>
		<title>Schaltplaneditoren</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Schaltplaneditoren&amp;diff=91359"/>
		<updated>2016-01-14T18:50:40Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: /* Kicad */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Grundüberlegungen zum Auswahl eines Layoutprogrammes ==&lt;br /&gt;
&lt;br /&gt;
Sehr häufig wird die Frage gestellt, welches Platinenlayoutprogramm man sich denn nun am besten kaufen soll. Diese Frage ist leider nicht einfach zu beantworten, weil sie von vielen Umständen abhängt, und für jeden individuell beantwortet werden muss.&lt;br /&gt;
&lt;br /&gt;
Daher hier ein paar grundsätzliche Überlegungen, welche in die eigenen Entscheidungen einfliessen könnten.&lt;br /&gt;
&lt;br /&gt;
Grundsätzlich ist der Übergang vom Hobbyanwender über den Studenten oder professionellen Kleingewerbetreibenden in Handwerk und Ingenieurbüro bis zum Vollzeit Platinenentwickler in der Industrie, der nur Großprojekte bearbeitet, stufenlos. Letztere haben im allgemeinen aber schon genaue Vorstellungen über das, was sie benötigen. So sind diese Überlegungen in erster Linie für Hobbyanwender, Studenten und Kleingewerbe betreibende Ingenieurbüros gedacht.&lt;br /&gt;
&lt;br /&gt;
=== Freeware vs. Open Source ===&lt;br /&gt;
&amp;quot;Freeware&amp;quot; im Sinne von nur &amp;quot;kostenlos&amp;quot; kann gerade für Hobbyanwender, Studenten und Kleingewerbetreibende problematisch sein, weil bei den kostenlosen Versionen kommerzieller Programme je nach Lizensierung Probleme bestehen, damit erstellte Projekte zu veröffentlichen. Selbst wenn die Veröffentlichung nichtkommerziell ist, und jemand anders greift die Unterlagen auf und verwertet sie kommerziell, kann der ursprüngliche Lizenznehmer wegen der Verletzung von Lizenzbestimmungen zur Rechenschaft gezogen werden. Hier ist also sehr intensiv das Kleingedruckte der Lizensierung zu beachten. Gleiches gilt für zwar nicht kostenlose, aber stark verbilligte Studenten- oder Hobbyversionen kommerzieller Programme. Oft beinhalten diese kostenlosen oder stark verbilligten Versionen auch recht lästige Beschränkungen in Bezug auf Schaltplangröße, Platinengröße, Anzahl der Verbindungen/Pads und Layer. Testversionen haben oft eine beschränkte Gültigkeitsdauer über wenige Wochen. Sie sind zum Testen vor einer Kaufentscheidung gedacht. Daher sollte man mit solchen zeitbeschränkten Testversionen ausser kleinen Testprojekten auch keine Projekte machen. Läuft die Lizenz aus, und man entscheidet sich, das Programm nicht zu kaufen oder zu mieten, kann man die Daten und somit die investierte Arbeit meist nicht weiter nutzen. Tatsächlich ist es daher oft sinnvoller, sich eine Vollversion eines einfachen Programmes zu kaufen, oder man nimmt &amp;quot;echte&amp;quot; Open Source Software.&lt;br /&gt;
&lt;br /&gt;
Bei diesen echten &amp;quot;open source&amp;quot; Programmen unter der [http://de.wikipedia.org/wiki/GNU_General_Public_License GNU-GPL-Lizenz] bestehen keine Probleme in der Verwertung und Veröffentlichung, sogar für kommerzielle Projekte dürfen sie kostenlos verwendet werden. Diese Programme sind wirklich frei im Sinne von &amp;quot;freier Rede&amp;quot; und nicht nur im Sinne von &amp;quot;Freibier&amp;quot;. Leider gibt es davon nur wenige, z.B. &lt;br /&gt;
[http://www.mikrocontroller.net/articles/Schaltplaneditoren#gEDA gEDA], [http://www.mikrocontroller.net/articles/Schaltplaneditoren#Kicad KiCad] und [http://www.mikrocontroller.net/articles/Schaltplaneditoren#FreePCB FreePCB] . [http://www.mikrocontroller.net/articles/Schaltplaneditoren#Fritzing Fritzing] gehört zwar ebenfalls in diesen Kreis, doch unterscheiden sich die Zielgruppe und demzufolge einige Aspekte der Handhabung extrem von denen gewöhnlicher Layoutprogramme.&lt;br /&gt;
&lt;br /&gt;
=== Einarbeitung ===&lt;br /&gt;
Grundsätzlich gibt es kein Layoutprogramm, in das man sich nicht einarbeiten müsste. Platinenentwicklung ist eine komplexe Angelegenheit, egal mit welcher Philosophie man sie angeht. Daher kommt man ohne Einarbeitung nie davon. Auf der anderen Seite werden jemandem, der mit einem Leiterplattenprogramm umgehen kann, vermutlich zwei Drittel eines anderen  Layoutprogrammes irgendwie bekannt vorkommen. Der Grund ist der, dass es dabei um Leiterplatten, ihre Eigenschaften und Herstellung geht. Dieses ist aber als Kontext, aus dem sich dann vieles ergibt, bei allen gleich. Unterschiede gibt es darum nur in Details der Handhabung.&lt;br /&gt;
&lt;br /&gt;
=== Handlichkeit ===&lt;br /&gt;
Schaltungen und Boards kann man mit allen dieser Layoutprogramme entwickeln. Es hängt an den speziellen Bedürfnissen und dem speziellem Geschmack des konkreten speziellen Anwenders, womit er am besten umgehen kannst. Die Thematik ist zu komplex, um von einer allgemeingültigen &amp;quot;intuitivität&amp;quot; ausgehen zu können. Diese sehr vom kulturellen Hintergrund des Anwenders abhängigen Eigenschaften machen, das hier keine Empfehlungen abgegeben werden können.&lt;br /&gt;
&lt;br /&gt;
Es kann dem Anwender daher lediglich der Rat gegeben werden, sich einige der Programme anzusehen und damit zu experimentieren. Das ist leider der einzige Weg, um sich selber ein Bild zu machen. Dazu können auch durchaus die &amp;quot;kostenlosen&amp;quot; Versionen kommerzieller Programme verwendet werden. Aber Vorsicht: Erst einmal keine größeren Projekte mit Testversionen. Denn wenn die Erprobungsfrist abgelaufen ist, oder wenn man vor eine andere Beschränkung läuft, und dann das Programm doch nicht kaufen will, kann die darin eingebrachte Arbeit nicht mehr in ein anderes Programm übertragen werden.&lt;br /&gt;
&lt;br /&gt;
== AACircuit ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;AACircuit&#039;&#039;&#039; ist ein Schaltplaneditor mit einer Ausgabe als ASCII-Grafik. Das Programm wurde dafür entwickelt, um mal eben eine Frage oder eine Antwort in &#039;&#039;newsgroups&#039;&#039;, Chats oder Foren zu veranschaulichen, wenn keine Upload-Möglichkeit von Bilddateien da ist. AACircuit gibt es bei http://www.tech-chat.de/ ([http://9r1.org/AACircuit1_28_6.zip Download-Mirror])&lt;br /&gt;
&lt;br /&gt;
Für allgemeine ASCII-Skizzen, wie Flussdiagramme oder UML, eignet sich [http://asciiflow.com ASCIIflow.com] ([http://stable.ascii-flow.appspot.com/ →alte Version]) besser.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  .---o----o------o---o---------------o---o----o------------o 12-15V&lt;br /&gt;
  |   |    |  22µF| + |               |   |    |&lt;br /&gt;
 .-.  |   .-.    ###  |              .-.  |    |    .-------o&lt;br /&gt;
 | |&amp;lt;-&#039;   | |    ---  |              | |  |    |    |   .---o&lt;br /&gt;
 | |5k    | |5k6  |   |              | |  |    |    |   |&lt;br /&gt;
 &#039;-&#039;      &#039;-&#039;     |   o--.           &#039;-&#039;  |   _|_   o  /o&lt;br /&gt;
  |        |     ===  |  |            |   |  |_/_|-   /&lt;br /&gt;
 .-.       |     GND  | ---100n   LED V   -    |     /&lt;br /&gt;
 | |       |          | ---           -   ^    |    o&lt;br /&gt;
 | |6k2    |          |  |            |   |    |    |&lt;br /&gt;
 &#039;-&#039;       |          | GND           &#039;---o----o    &#039;-------o&lt;br /&gt;
  |        |       2|\|7                       |&lt;br /&gt;
  o-----------------|-\ LM741      ___       |/&lt;br /&gt;
  |        |        |  &amp;gt;-------o--|___|--o---|&lt;br /&gt;
  |        o---o----|+/ 6      |   22k   |   |&amp;gt;  BC547&lt;br /&gt;
  |        |   |   3|/|4       |         |     |&lt;br /&gt;
 .-.       |   |     ===       o---.    .-.    |&lt;br /&gt;
 | |       |   o---. GND       |   |    | |5k6 |&lt;br /&gt;
 | |2k7   .-.  |   |   ___    _V_  |    | |    |&lt;br /&gt;
 &#039;-&#039;     KTY10 | + &#039;--|___|--|___|-&#039;    &#039;-&#039;    |&lt;br /&gt;
  |       | | ###      47k   220k        |     |&lt;br /&gt;
  |       &#039;-&#039; ---                        |     |&lt;br /&gt;
  |        |   |                         |     |&lt;br /&gt;
  |        |   |                         |     |&lt;br /&gt;
  &#039;--------o---o-------------------------o-----o------------o GND&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Altium Designer ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Altium&#039;&#039;&#039; (aus Protel hervorgegangen) ist eine kommerzielle EDA Suite die umfangreiche Funktionen beinhaltet.&lt;br /&gt;
Neben den Klassikern wie Schaltplan und Layouterzeugung werden auch elektronische Simulationen, FPGA Entwicklungstools, und diverse andere Features per PlugIn vom Hersteller angeboten. Seit 2011 ist der Sitz in China, dort sind auch die Programmierer.&lt;br /&gt;
Leider ist der Produktzyklus momentan sehr kurz, so das fast Jährlich neue Hauptrelease erscheinen (aktuell 15.1) und in Abständen von 2-6 Monaten &amp;quot;Zwischenupdates&amp;quot; veröffentlicht werden.&lt;br /&gt;
&lt;br /&gt;
*Diverse Formate können importiert und exportiert werden, so das man u.A. &amp;quot;fast&amp;quot; nahtlos mit MCAD Systemen kooperieren [https://docs.google.com/viewer?url=http://www.altium.com/files/training/Module%2020%20-%203D%20Mechanical%20CAD.pdf LINK]&lt;br /&gt;
*Diverse Funktionen für HighSpeed Designs [http://fplreflib.findlay.co.uk/articles/37941%5CHiSpeedDesignTutorialforAltiumDesigner_long.pdf LINK]&lt;br /&gt;
&lt;br /&gt;
Leider wurde der Preis in der jüngsten Vergangenheit des öfteren nach oben korrigiert.&amp;lt;BR&amp;gt;&lt;br /&gt;
2014-04-11: Achtung Altium erhöht zum 31.6.2014 schon wieder die Preise und dieses Mal um satte 34% (4000€ auf 5400€!). Das entspricht einer Erhöhung um +68% in 5 Jahren.&lt;br /&gt;
&lt;br /&gt;
== CircuitMaker ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CircuitMaker&#039;&#039;&#039; (aus Altium hervorgegangen) ist eine kostenfreie, Cloudbasierte, EDA Suite die umfangreiche Funktionen beinhaltet.&lt;br /&gt;
&lt;br /&gt;
Der Funktionsumfang ist nicht jener von einem vollwertigen AltiumDesigner, aber viele Aspekte sind gleich.&lt;br /&gt;
So ist es auch möglich, Leiterbahnen mittels Hug &#039;n Shove zu verschieben oder komplexe DesignRules anzuwenden.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cloud&#039;&#039;&#039;&lt;br /&gt;
Die Cloud beschränkt sich darauf, dass die eigenen Files dort abgelegt werden.&lt;br /&gt;
Grundsätzlich wäre die Idee, dass alle Community Mitglieder alle Projekte selbst benutzen und Bearbeiten könnten. Wenn man jedoch das eigene Projekt nie &amp;quot;committed&amp;quot; dann ist es auch nie sichtbar für andere Mitglieder. &lt;br /&gt;
&lt;br /&gt;
Zudem werden sämtliche Daten auch Lokal in einem Ordner abgelegt.&lt;br /&gt;
&lt;br /&gt;
== BAE ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;B&#039;&#039;&#039;artels &#039;&#039;&#039;A&#039;&#039;&#039;uto &#039;&#039;&#039;E&#039;&#039;&#039;ngineer unterstützt die Erstellung von Schaltplänen, Leiterplatten und integrierten Schaltungen und läuft unter Windows, Linux und verschiedenen X11-/Unix-Systemen. Der Schaltplaneditor kann Pläne auf beliebig vielen Blättern erstellen, wobei auch hierarchische Strukturen möglich sind. Der Autorouter erzeugt recht brauchbare Ergebnisse, wobei beliebige Teile mit der Hand vorab geroutet werden können. Ein Autoplacer ist ebenfalls vorhanden.&lt;br /&gt;
&lt;br /&gt;
Eine auf Schaltplaneingabe beschränkte Version und eine kastrierte Evaluierungsversion sind auf der [http://www.bartels.de/bae/bae_de.htm BAE Homepage] downloadbar.&lt;br /&gt;
&lt;br /&gt;
Die [http://www.bartels.de/bae/baeprice_de.htm preiswerteste] kostenpflichtige Version ist das &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;BAE Light&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. Diese Version ist auf Leiterplatten der Groesse 180x120 mm² und auf 2 Lagen beschränkt, eine Beschränkung auf eine bestimmte Pinanzahl gibt es aber nicht.&lt;br /&gt;
&lt;br /&gt;
Ansonsten wird eine Economy-, Professional- und Highendversion angeboten, die jeweiligen Eigenschaften sind im Abschnitt [http://www.bartels.de/baedoc/inst_de.htm Bartels AutoEngineer Softwarekonfigurationen] erklärt. Interessant ist z.&amp;amp;nbsp;B. der Bauteilhöhencheck.&lt;br /&gt;
&lt;br /&gt;
Mit dem &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;BAE IC Design&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; dringt man bis in den Bereich der IC-Entwicklung vor.&lt;br /&gt;
&lt;br /&gt;
[[BAE-Tutorial]]&lt;br /&gt;
&lt;br /&gt;
== Basic Schematic == &lt;br /&gt;
&lt;br /&gt;
[[Bild:Base schematic example.png|right|thumb|Screenshot Base Schematic]]&lt;br /&gt;
&lt;br /&gt;
Basic Schematic (&#039;&#039;&#039;BSch3V&#039;&#039;&#039;) ist ein freier Schaltplaneditor für Windows (98/Me/2000/XP). IN der aktuellen Version läuft es auch unter Windows7. Es enthält einen Component Library Editor, einen Parts List Generator und einen Netlist Generator, sowie eine Automatic Numbering Funktion.&lt;br /&gt;
&lt;br /&gt;
Ein ZIP-Archiv mit engl. Programm, Handbuch und Sourcecode gibt es bei http://www.suigyodo.com/online/e/index.htm.&lt;br /&gt;
&lt;br /&gt;
Ebenso ist dort eine Cross-Plattform Version &#039;&#039;&#039;Qt-BSch3V&#039;&#039;&#039; auf der Basis von Qt-Grafiklibraries erhältlich.&lt;br /&gt;
&lt;br /&gt;
Das Programm ermöglicht den Export der Schaltungsdaten im KIDAD-Format.&lt;br /&gt;
&lt;br /&gt;
Das Programm ist bis dato (Mai 2014) gut gepflegt.&lt;br /&gt;
&lt;br /&gt;
== BlackBoard Circuit Designer == &lt;br /&gt;
&lt;br /&gt;
[[Bild:BlackBoard.png|right|thumb|Screenshot]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;BlackBoard Circuit Designer&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; ist ein freier Editor für Lochrasterplatinen Layouts, der das Planen der Bauteilplazierung sowie der beidseitigen Verdrahtung deutlich vereinfacht und sich u.a. auch für die Dokumentation solcher Prototypenaufbauten eignet.&lt;br /&gt;
&lt;br /&gt;
Er läuft auf allen Plattformen für die eine Java Runtime zur Verfügung steht.&lt;br /&gt;
&lt;br /&gt;
Blackboard steht unter der GPL V2.&lt;br /&gt;
&lt;br /&gt;
Die Entwicklung wird demnächst fortgesetzt. Der Sourcecode steht unter https://github.com/mpue/blackboard zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
Die Installer stehen unter http://pueski.de/?page_id=1929 zum Download.&lt;br /&gt;
&lt;br /&gt;
== DesignSpark PCB ==&lt;br /&gt;
&lt;br /&gt;
Integrierter Schaltplan-Editor mit Autorouter und Leiterplatten-Designer - mittlerweile schon in der Version 7.&amp;lt;br /&amp;gt;&lt;br /&gt;
Freeware für kommerzielle und nichtkommerzielle Nutzung. &amp;lt;br /&amp;gt;&lt;br /&gt;
Bedienung ist etwas gewöhnungsbedürftig - leider z.Zt. nur als englische (u. chinesische) Version verfügbar. &amp;lt;br /&amp;gt;&lt;br /&gt;
Weitere Features: z.B. professionelle 3D-Designsoftware.&amp;lt;br /&amp;gt;&lt;br /&gt;
Import von EAGLE-Datein möglich. &amp;lt;br /&amp;gt;&lt;br /&gt;
Unbegrenzte Leiterplattengrösse, im Prinzip auch unbegrenzte Layer-Anzahl.&amp;lt;br /&amp;gt;&lt;br /&gt;
Kostenloser Download: http://www.rs-online.com/designspark/electronics/deu/page/designspark-pcb-home-page &lt;br /&gt;
bzw. http://www.rs-online.com/designspark/electronics/deu/. &amp;lt;br /&amp;gt;&lt;br /&gt;
Erfahrungsbericht: http://www.ps-blnkd.de/Erfahrungsbericht_Schaltung&amp;amp;Leiterplatte.pdf.&amp;lt;br /&amp;gt;&lt;br /&gt;
Verschiedene Tutorials &amp;quot;DesignSpark Tipps &amp;amp; Tricks&amp;quot; in deutscher Sprache im &amp;quot;Elektor&amp;quot; 2014/2015.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DipTrace ==&lt;br /&gt;
&lt;br /&gt;
Design-Editor für PCB-Leiterplatten für Windows NT, 2000, XP, Server 2003&lt;br /&gt;
- verschiedene kostenpflichtige Versionen erlauben den Export in DXF, Gerber und N/C Drill sowie Leiterplattenlayouts mit mehr als 300 Pins und mehr als 2 Lagen. Die für nicht-kommerzielle Anwendungen gedachte Freeware &amp;quot;DipTrace Lite&amp;quot; ist auf 500 Pins und 2 Lagen beschränkt. 2 Lagen sind für die meisten Hobbyanwendungen ausreichend, obwohl auch da der Trend zu 4 Lagen geht. Aber 200 Pins in der Freeversinon (http://diptrace.com/buy/non-profit/) sind sehr mager, wenn man bedenkt, dass 48 pinnige ICs heute keine Seltenheit sind. Weiter: Die strikte Forderung &amp;quot;non profit&amp;quot; verbietet implizit eine Veröffentlichung.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[http://www.diptrace.com/ DipTrace Homepage]&lt;br /&gt;
&lt;br /&gt;
[http://www.mikrocontroller.net/topic/319636#new Forumsbeitrag über Diptrace]&lt;br /&gt;
&lt;br /&gt;
[http://www.mikrocontroller.net/topic/320897/ Geeignete Schaltplan und Layoutsoftware für Hobbyprojekte]&lt;br /&gt;
&lt;br /&gt;
== Eagle ==&lt;br /&gt;
&lt;br /&gt;
[[Bild:Eagle.png|right|thumb|Screenshot]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Eagle&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; von Cadsoft ist nicht nur ein &amp;lt;b&amp;gt;Schaltplaneditor&amp;lt;/b&amp;gt;, sondern ein komplettes Paket mit &amp;lt;b&amp;gt;Layoutprogramm&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;Autorouter&amp;lt;/b&amp;gt;. Das hat den Vorteil, dass man einen erstellten Schaltplan gleich zur Platine weiterverarbeiten kann.&lt;br /&gt;
&lt;br /&gt;
Mitgeliefert werden umfangreiche Symbol- bzw. Bauteilbibliotheken, von Widerständen in allen Bauformen über Taster bis hin zu [[AVR]]s. Eine Library für viele aktuelle AVRs findet sich im Download-Bereich &lt;br /&gt;
von [http://www.embedit.de http://www.embedit.de].&lt;br /&gt;
&lt;br /&gt;
Eagle läuft unter Linux, Windows (2000/XP/Vista/7) und Mac OS X. Ausgabedateien können direkt an die einschlägigen Hersteller geliefert werden.&lt;br /&gt;
&lt;br /&gt;
Eine für nichtkommerzielle Anwendungen kostenlose Version ist von [http://www.cadsoft.de/ CadSoft] erhältlich. Diese ist auf zweilagige Platinen im halben Euro-Format (80x100mm) sowie Schaltpläne mit nur einer Seite beschränkt.&lt;br /&gt;
&lt;br /&gt;
=== Autorouter ===&lt;br /&gt;
&lt;br /&gt;
Der Autorouter funktioniert nicht in der nichtkommerziellen Version. Man kann aber in diesem kostenlosen Autorouter eagle-brd Dateien importieren und als Eagle-session-script (.scr) wieder in Eagle importieren: [http://www.freerouting.net/ http://www.freerouting.net/]&lt;br /&gt;
&lt;br /&gt;
Auf die richtige Version des Eagle-ULP achten.&lt;br /&gt;
&lt;br /&gt;
=== 3D-Ansicht===&lt;br /&gt;
[[Bild:Stereobild-elektronik-3d.jpg|right|thumb|Rot-Grün-Stereo-Bild]]&lt;br /&gt;
Zum Betrachten des fertigen, bestückten Platinenentwurfs in Form eines 3D-Bilds bietet sich das Paket [http://sourceforge.net/projects/eagle3d.berlios/files/?source=navbar eagle3D] an. Mit Hilfe eines ULP wird eine Beschreibungsdatei für den open source Renderer &amp;lt;i&amp;gt;POVray&amp;lt;/i&amp;gt; erzeugt, welche dann anschließend halbautomatisch generiert werden kann. Auch Bewegungsanimation und Kameraflug sind möglich. Es wird bereits ein große Zahl an Bauteilen unterstützt.&lt;br /&gt;
&lt;br /&gt;
Anwendungshinweise:&lt;br /&gt;
* [[Eagle im Hobbybereich]]&lt;br /&gt;
* [http://gaussmarkov.net/wordpress/category/tools/software/eagle/ Eagle CAD Tutorial] im Blog von gaussmarkov: diy fx (englisch)&lt;br /&gt;
* [[Stereobilder mit EAGLE 3D]]&lt;br /&gt;
&lt;br /&gt;
{{Absatz}}&lt;br /&gt;
&lt;br /&gt;
== FreePCB ==&lt;br /&gt;
&lt;br /&gt;
FreePCB ist ein freier, open-source PCB editor für Microsoft Windows, der unter der GNU General Public License veröffentlicht wurde. Er wurde entwickelt, um ihn einfach erlernen und nutzen zu können und dennoch für professionelles Arbeiten geeignet. Er besitzt keinen eingebauten Auto Router, kann jedoch den web-basierten auto router auf www.freerouting.net verwenden.&lt;br /&gt;
&lt;br /&gt;
*http://en.wikipedia.org/wiki/FreePCB Englischer Wikipedia Eintrag.&lt;br /&gt;
*http://www.freepcb.com/ Offizielle Homepage&lt;br /&gt;
*http://www.freepcb.com/freepcb_user_guide.pdf Users Guide&lt;br /&gt;
&lt;br /&gt;
== Electric ==&lt;br /&gt;
&lt;br /&gt;
Das [http://www.staticfreesoft.com/index.html Electric(TM)] VLSI Design System ist ein Open Source Electronic Design Automation (EDA) System.&lt;br /&gt;
&lt;br /&gt;
== ExpressPCB ==&lt;br /&gt;
&lt;br /&gt;
Die Firma &amp;lt;b&amp;gt;ExpressPCB&amp;lt;/b&amp;gt; bietet den kostenlosen Schaltplaneditor &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;ExpressSCH&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; an. Zusätzlich gibt es das kostenlose Layoutprogramm &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;ExpressPCB&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; zum Erstellen von zwei- und vierlagigen Leiterplatten. Die beiden Programme sind auf Windows (NT, 2000, XP, Vista) beschränkt. Die Firma bietet auf der [http://www.expresspcb.com/ ExpressPCB Homepage] ausserdem einen kommerziellen Service für die Herstellung von zwei- und vierlagigen Leiterplatten an. Auf der Seite finden sich [http://www.expresspcb.com/ExpressPCBHtm/Tips.htm hier] einige Hinweise zum Entwurf von Leiterplatten.&lt;br /&gt;
&lt;br /&gt;
== FidoCadJ ==&lt;br /&gt;
&lt;br /&gt;
[http://davbucci.chez-alice.fr/index.php?argument=elettronica/fidocadj/fidocadj.inc&amp;amp;language=English FidoCadJ] is a very easy to use editor, with a library of electrical symbols and footprints (through hole and SMD). Albeit its ease of use, it is a very immediate and effective EDA tool for the hobbyst. FidoCadJ stores its drawings in a compact text format. This choice is well suited for the copy and paste in newsgroups and forums. This explains the success of FidoCadJ in Usenet groups and in several portals. FidoCadJ is multi-platform Java program and runs on MacOSX, Linux and Windows. FidoCadJ and its manuals are in english, french and italian. Lizenz: Creative Commons 3.0 BY-NC-ND&lt;br /&gt;
&lt;br /&gt;
== Fritzing ==&lt;br /&gt;
&lt;br /&gt;
[[Datei:Fritzing bildschirmfoto.png|miniatur|rechts|Bildschirmfoto]]&lt;br /&gt;
&#039;&#039;&#039;Fritzing&#039;&#039;&#039; verwendet die Metapher eines Breadboards (Steckbretts), auf dem die Benutzer virtuell Bauteile einstecken. Fritzings Zielgruppe sind Künstler, Designer und Hobbyisten aber nicht unbedingt Profielektroniker, und die Software soll speziell auf die Zielgruppe zugeschnitten werden. Dabei wird auf eine niedrige Zugangsschwelle wert gelegt. Versionen für Mac OS X, Linux und Windows (XP/Vista) sind bei http://www.fritzing.org/ erhältlich.&lt;br /&gt;
Nichtsdestotrotz besitzt das Programm 3 Ansichten, von denen die erste am häufigsten gezeigt wird – das o.a. Breadboard oder auch eine Streifenrasterplatte. Weiters wird aus dem Steckbrett in einer zweiten Ansicht ein Schaltplan erstellt und in einer dritten Ansicht lässt sich sogar eine ätzbare Leiterplatte mittels Autorouting entwerfen. Die Bauteilliste enthält bereits fertige Komponenten der [[Arduino]]-Gemeinschaft und ähnlicher Produkte wie die von Sparkfun, Parallaxe oder Picaxe. Ein paar Standardbauteile wie eine rote LED oder ein 220Ohm-Widerstand sind schnell zu finden. Die Bauteilbibliothek lässt sich erweitern.&lt;br /&gt;
Die Bedienung ist einfach zu erlernen und es gibt zwar Tastaturkürzel für die wichtigsten Funktionen, aber der erste Schaltplan ist schnell allein mit der Maus erstellt. Eine Umschaltung zwischen Platzierung der Bauteile und Routing ist nicht notwendig. Einfaches Klicken und Ziehen erstellt eine Kabelbrücke als Luftlinie. Auf Ebenen muss der Nutzer auch nicht verzichten. So lassen sich Bauteile, Kabel und Beschriftungen ein- und ausblenden. Auch wenn die Version noch nicht die 1.0 erreicht hat kann Sie bei bei Schaltungen bis ca. 30 Teilen mit professionellen Programmen mithalten was den Zeitaufwand und die Übersichtlichkeit betrifft.&lt;br /&gt;
&lt;br /&gt;
== gEDA ==&lt;br /&gt;
&lt;br /&gt;
[http://www.mikrocontroller.net/articles/GEDA gEDA] ist eine unter anderem aus [http://www.mikrocontroller.net/articles/Schaltplaneditoren#Gschem Gschem] und [http://www.mikrocontroller.net/articles/Schaltplaneditoren#PCB PCB] bestehende Open Source Programm Suite zur Entwicklung von Schaltplänen und Platinen. &lt;br /&gt;
&lt;br /&gt;
== Gschem ==&lt;br /&gt;
&lt;br /&gt;
[[Bild:Gschem.png|right|thumb|Screenshot]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;gschem&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; ist der Schaltplaneditor aus dem Open Source Projekt gEDA. &amp;lt;i&amp;gt;gschem&amp;lt;/i&amp;gt; wird hauptsächlich auf Linux Rechnern entwickelt, läuft aber auch auf anderen Unix-Betriebssystemen und unter Windows. &amp;lt;i&amp;gt;gschem&amp;lt;/i&amp;gt; ist für die Linuxdistributionen RedHat und Debian als Paket verfügbar, für Windows ist nur eine ältere Version erhältlich und für alle anderen ist selber kompilieren angesagt.&lt;br /&gt;
&lt;br /&gt;
Die Bedienung ist nicht sonderlich anfängerfreundlich. Hat man sich aber mal daran gewöhnt, dass jeder Menupunkt mit 1 oder 2 Tasten erreichbar ist, läßt sich&#039;s mit &amp;lt;i&amp;gt;gschem&amp;lt;/i&amp;gt; prima arbeiten. &lt;br /&gt;
&lt;br /&gt;
In der Symbolbibliothek (die auch online betrachtet werden kann) sind etwas mehr als 1000 Symbole; das Selbsterzeugen von Symbolen ist jedoch problemlos möglich. Insbesondere ist es aufgrund des gut dokumentierten und einfachen Datei-Formates möglich, mit einfachen Perl-Programmen z.&amp;amp;nbsp;B. aus Reports von Xilinx ISE Symbole zu erzeugen und automatisch zu aktualisieren, wenn sich die Pinzuordnung ändert. Das fehlerhafte Eingeben der Pinbelegung von CPLDs und FPGAs von Hand und die Änderung derselben ist damit für &amp;lt;i&amp;gt;gschem&amp;lt;/i&amp;gt; User Geschichte.&lt;br /&gt;
&lt;br /&gt;
Die Schaltpläne lassen sich als png und als Postscript exportieren. &lt;br /&gt;
&lt;br /&gt;
Netzlisten (insgesamt über 20 Formate für PCB, Protel, Eagle, BAE, spice, pads, ... ) lassen sich mit dem Programm &amp;lt;i&amp;gt;gnetlist&amp;lt;/i&amp;gt; generieren. Aus diesem Grund ist man (bis auf die Namen der Footprints) unabhängig von der verwendeten Layout-Software und kann diese auch sehr leicht wechseln.&lt;br /&gt;
&lt;br /&gt;
Gschem bildet zusammen mit PCB und anderen Programmen das [http://www.mikrocontroller.net/articles/GEDA gEDA] Programmpacket.&lt;br /&gt;
&lt;br /&gt;
Ein großer Vorteil der gEDA-Suite sind die Dateiformate, welche alle reiner ASCII-Text sind. Dies macht die Entwicklung von Helper-Tools zur Lösung von speziellen Aufgaben sehr leicht. Außerdem können die Dateien deswegen sehr einfach in Versionsverwaltungssystemen wie CVS verwaltet werden, was insbesondere die Entwickler größerer Projekte zu schätzen wissen.&lt;br /&gt;
&lt;br /&gt;
Nähere Informationen über &amp;lt;i&amp;gt;gschem&amp;lt;/i&amp;gt; (gEDA) gibt es unter [[http://www.geda.seul.org/ http://www.geda.seul.org/]].&lt;br /&gt;
Hier auf der Mikrocontroller.net Seite finden sich Informationen zu Gschem [http://www.mikrocontroller.net/articles/GEDA unter gEDA].&lt;br /&gt;
&lt;br /&gt;
== Inkscape ==&lt;br /&gt;
&lt;br /&gt;
Etwas bekannter noch als Jfig ist [http://inkscape.org/ &#039;&#039;&#039;Inkscape&#039;&#039;&#039;], ebenfalls ein reines Vektorzeichenprogramm, das vor allem (aber nicht nur) SVG-Dateien erstellt, die mit der Wikipedia eine große Verbreitung gefunden haben. Es ist in fast jeder gängigen Linux Distribution enthalten, eine Windowsversion sowie eine [http://portableapps.com/apps/graphics_pictures/inkscape_portable &#039;&#039;&#039;portable Windowsversion&#039;&#039;&#039;] existiert auch. In der Wikipedia findet sich eine Sammlung von Elektroniksymbolen im [http://commons.wikimedia.org/wiki/Category:SVG_electrical_symbols SVG-Format] und [http://commons.wikimedia.org/wiki/File:Electrical_symbols_library.svg hier]. Als Beispiele damit gezeichneter Schaltpläne sei diese [http://commons.wikimedia.org/wiki/Category:Created_with_electrical_symbols_library] genannt.&lt;br /&gt;
&lt;br /&gt;
== Kicad ==&lt;br /&gt;
[[Bild:kicad1.gif|right|thumb|Screenshot]]&lt;br /&gt;
[[Bild:kicad2.gif|right|thumb|Screenshot]]&lt;br /&gt;
&lt;br /&gt;
[[KiCAD]] ([http://www.kicad-pcb.org/display/KICAD/KiCad+EDA+Software+Suite/ Homepage]) und ([http://iut-tice.ujf-grenoble.fr/kicad/ &amp;quot;klassische&amp;quot; Homepage]) ist ein Paket aus Design / Layout / Routing Programmen. Es basiert auf wxWidgets und ist damit plattformübergreifend. Die Progamme sind unter der GPL veröffentlicht und damit Open Source. KiCad darf frei benutzt werden, und die Nutzer haben volle Rechte an ihren damit erstellten Schaltplänen und Layouts, auch für kommerzielle Nutzung. Im deutschsprachigen Raum existiert noch ein Zeichenprogramm für Elektrotechnik, welches auch kicad heißt, aber ein kommerzielles Projekt ist, und mit dem hier behandelten lediglich den Namen gemeinsam hat.&lt;br /&gt;
&lt;br /&gt;
Das KiCAD Projekt wurde von Jean Pierre Charras gestartet und enthält eine Gruppe recht aktiver Entwickler. Es ist auf [http://de.wikipedia.org/wiki/Launchpad Launchpad] angesiedelt. Auch eine Nutzergruppe des [http://de.wikipedia.org/wiki/CERN CERN] beteiligt sich mit einem [https://code.launchpad.net/~cern-kicad/kicad/kicad-gal-orson branch] an der Weiterentwicklung von KiCAD: [http://www.ohwr.org/projects/cern-kicad/wiki/WorkPackages Über die geplante Weiterentwicklung von KiCad (englisch)] und [http://home.web.cern.ch/about/updates/2015/02/kicad-software-gets-cern-treatment warum das CERN KiCad unterstützt (englisch)] . &lt;br /&gt;
&lt;br /&gt;
Eine Kicad User-Group findet sich unter http://groups.yahoo.com/group/kicad-users/. Die Anmeldung erfolgt erst, nachdem man vom Besitzer der User-Group freigeschaltet wurde (wie üblich für die meisten Yahoo-Groups).&lt;br /&gt;
&lt;br /&gt;
Neben der mitgelieferten, bereits umfangreichen Bibliothek, die auch hier extern zugänglich ist (https://github.com/KiCad) gibt es auf vielen anderen Seiten (z.&amp;amp;nbsp;B. http://www.kicadlib.org/) weitere Bibliotheken zum Download, die einfach integriert werden können.&lt;br /&gt;
&lt;br /&gt;
Für Umsteiger von anderen Programmen sollten sich nach wenigen Stunden bereits die gleichen Ergebnisse erzielen lassen. Beim Erlernen kann das Tutorial von http://www.curiousinventor.com/guides/kicad helfen. Ebenso findet sich hier unter http://www.mikrocontroller.net/articles/KiCAD eine unfangreiche FAQ (und Bibliothekssammlung)&lt;br /&gt;
&lt;br /&gt;
Der Schaltplaneditor von Kicad verfügt über Möglichkeiten hierarchische Schaltpläne anzulegen. Etwas, das man nicht mehr missen möchte, nachdem man einmal damit gearbeitet hat. Obwohl ursprünglich nicht dafür gedacht, lässt sich dieses System nutzen, um aus vorgefertigten Teilschaltplänen einen Hauptschaltplan modular zusammenzusetzten. Eine Anleitung dazu findet sich hier: [[Media:HierarchischeSchaltplaeneAlsBausteineInKicad_RevC_23Dec2013.pdf]]&lt;br /&gt;
&lt;br /&gt;
Kicad liefert eine schöne 3D-Ansicht des fertigen Layouts einschließlich der bestückten Bauteile, so dass man an dieser Stelle schon einmal einen Überblick bekommt, ob vielleicht nicht doch etwas vergessen wurde. Es gibt zwar nicht für alle Bauformen ein 3D-Modell, allerdings lassen sich diese selbst erstellen.&lt;br /&gt;
&lt;br /&gt;
Kicad ist mittlerweile soweit verbreitet, das viele Leiterplattenhersteller die Kicad-Board Daten direkt verarbeiten können.&lt;br /&gt;
&lt;br /&gt;
Kicad enthält eine Autoplacement und eine Autorouterfunktion, die aber leider nicht sehr effizient sind. Ausserdem sind sie schlecht dokumentiert. Es lassen sich aber Netzlisten zum Export in mehrere verschiedene externe Autorouter erzeugen. Desweiteren lässt sich der bekannte Freeroute Autorouter im Netz direkt verwenden. Desweiteren können Netzlisten zum Export in Spice erzeugt werden. Ein weiterer Kritikpunkt wäre, dass die offizielle Symbolbibliothek nur amerikanische, aber keine europäischen Schaltplansymbole enthält. Aber eine aktuelle Version einer europäischen Symbolbibliothek findet sich hier in  Mikrocontroller.de unter http://www.mikrocontroller.net/articles/KiCAD#Bibliotheken&lt;br /&gt;
unter SymbolsSimilarEN60617+oldDIN617-RevE8.lib&lt;br /&gt;
Diese enthält aber nicht nur EN60617 Symbole, sondern auch einige andere Symbole wie Logos für Gefahr, Hochspannung, ESD-Schutz und Dummy Symbole für Platinenumrisse, Fiducials, Messpunkte ec. Eine [http://www.mikrocontroller.net/wikifiles/7/77/Symbols_EN60617_13Mar2013.lib &amp;quot;gereinigte&amp;quot; EN60617 Bibliothek] findet sich am gleichen Ort unter Symbols_EN60617_13Mar2013.lib, zusammen mit einem &lt;br /&gt;
[http://www.mikrocontroller.net/wikifiles/e/e6/Symbols_EN60617_13Mar2013.pdf  PDF-Katalog der enthaltenen Symbole].&lt;br /&gt;
Neuere KiCad Versionen enthalten allerdings einen sehr effizienten interaktiven Router. Dieser kann allerdings nur verwendet werden, wenn die Hardware und das Betriebssystem des Rechners aktuelle openGL Versionen unterstützt. Hier ein Video zur benutzung des interaktiven Routers: https://www.youtube.com/watch?v=CCG4daPvuVI&lt;br /&gt;
Ebenso existiert ein Tool für &amp;quot;Different Pair matching&amp;quot; um Leiterbahnen gleicher Länge (Laufzeit) zu erzeugen.&lt;br /&gt;
Siehe dazu dieses Video: https://www.youtube.com/watch?v=chejn7dqpfQ&lt;br /&gt;
&lt;br /&gt;
Eagle 6 Boarddateien können in Kicad eingelesen werden. Ebenso können Eagle &amp;quot;Packages&amp;quot; als Footprintbibliotheken in KiCAD eingebunden werden. Auch gEDA Footprints können direkt als KiCAD Footprint Bibliothek in PCBnew eingebunden werden. Diese Funktionen sind aber noch als experimentell zu bezeichnen.&lt;br /&gt;
&lt;br /&gt;
Desweiteren existieren eine Reihe von Konvertern, mit denen Daten anderer Platinenlayoutprogramme nach KiCad exportiert werden können. Eine Liste findet sich hier: http://www.mikrocontroller.net/articles/KiCAD#Konverter &lt;br /&gt;
&lt;br /&gt;
Das Kicad Packet enthält ausserdem einen Gerberdatenviewer, der auch eingelesene Gerberdaten als Layout reimportieren kann. Ausserdem zählt zum KiCad Packet ein &amp;quot;Leiterplattenrechner&amp;quot; mit dem z.B. Wellenwiderstände, Leiterbahnbreiten und Isolationsabstände bestimmt werden können.&lt;br /&gt;
&lt;br /&gt;
Kicad kann z.Z. Boards mit 16 Kupferlagen und die dazugehörigen Löttstop., Umriss-, Lötpasten-, Kleber-, Silkscreen- ec. Lagen verarbeiten. Die mögliche Leiterplattengröße liegt über 1x1m. Damit ist eine deutlich größere Fläche als die von Einheitstafeln abgedeckt. Wer Platinen im oder über dem Einheitstafelnformat benötigt, wird Mühe aufwenden müssen, einen Hersteller dafür zu finden.&lt;br /&gt;
&lt;br /&gt;
Die Einarbeitung in Kicad ist vergleichbar mit Eagle. Es hängt vermutlich von den individuellen Denkstrukturen ab, welches Programm man handlicher findet. Ein großer Vorteil sind die Dateiformate, welche alle reiner ASCII-Text sind. Dies macht die Entwicklung von externen Skripten zur Lösung von speziellen Aufgaben sehr leicht. Außerdem können die Dateien deswegen sehr einfach in Versionsverwaltungssystemen wie CVS verwaltet werden, was insbesondere die Entwickler größerer Projekte zu schätzen wissen.&lt;br /&gt;
Ein internes Skripting unter Python für KiCad ist in der Entwicklung. z.Z. kann es aber nur unter PCBnew verwendet werden.&lt;br /&gt;
&lt;br /&gt;
[http://www.bigmessowires.com/2014/12/09/eagle-vs-kicad-revisited/ Und hier ein Link auf eine Kritik/Meinung (englisch)]&lt;br /&gt;
&lt;br /&gt;
== Lochmaster ==&lt;br /&gt;
&lt;br /&gt;
[http://www.abacom-online.de/html/lochmaster.html Lochmaster] ist ein Programm zur Erstellung von Layouts speziell auf [[Lochrasterplatine]]n. Schaltplan und Layout sind ein und das selbe.&lt;br /&gt;
&lt;br /&gt;
== PCB ==&lt;br /&gt;
&lt;br /&gt;
[http://pcb.sourceforge.net/index.html PCB] ist ein freies (open source) Layoutprogramm inklusive Autorouter. Zum Zeichnen der Schaltpläne kann [[Schaltplaneditoren#Gschem|Gschem]] verwendet werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;i&amp;gt;PCB&amp;lt;/i&amp;gt; wurde ursprünglich für den Atari ST entwickelt und später nach &lt;br /&gt;
Unix portiert. &amp;lt;i&amp;gt;PCB&amp;lt;/i&amp;gt; läuft meist unter Linux, kann allerdings mit [http://www.cygwin.com/ Cygwin] auch unter Windows betrieben werden.&lt;br /&gt;
&lt;br /&gt;
Als Ausgabeformate stehen [http://de.wikipedia.org/wiki/Postscript Postscript] und Gerber RS-274-X zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
Ein großer Vorteil von &amp;lt;i&amp;gt;PCB&amp;lt;/i&amp;gt; ist, dass alle Funktionen auch über &lt;br /&gt;
Hotkeys gesteuert werden können, was insbesondere nach längerer Einarbeitungszeit ein großer Gewinn gegenüber manchen Windows-Programmen ist.&lt;br /&gt;
&lt;br /&gt;
Zur Einarbeitung ist es meines Erachtens sehr wichtig, sich das [http://www.geda.seul.org/wiki/geda:gsch2pcb_tutorial Tutorial] durchzulesen. &amp;lt;i&amp;gt;PCB&amp;lt;/i&amp;gt; und &amp;lt;i&amp;gt;Gschem&amp;lt;/i&amp;gt; sind nicht besonders einfach zu benutzen. Gerade am Anfang, wenn man sich versucht damit einzuarbeiten. Aber wenn man einmal mit dem Werkzeug arbeiten kann, wird man es nicht mehr missen wollen.&lt;br /&gt;
&lt;br /&gt;
PCB bildet zusammen mit Gschem und anderen Programmen das [http://www.mikrocontroller.net/articles/GEDA gEDA] Programmpacket. Hier auf der Mikrocontroller.net Seite finden sich Informationen zu PCB [http://www.mikrocontroller.net/articles/GEDA unter gEDA].&lt;br /&gt;
&lt;br /&gt;
== PCBWeb ==&lt;br /&gt;
&lt;br /&gt;
Freier Layout- und Schaltplaneditor&lt;br /&gt;
&lt;br /&gt;
[http://www.pcbweb.com/ Webseite zum Download]&lt;br /&gt;
&lt;br /&gt;
== ProtoCAD ==&lt;br /&gt;
&lt;br /&gt;
[http://sourceforge.net/projects/protocad/ ProtoCAD] ist ein Werkzeug, um schnell Schaltpläne zu entwerfen. Es ist für [[Lochrasterplatine]]n entwickelt worden, kann aber auch für andere Methoden genutzt werden. (Java 1.5 kompatibel, Swing GUI, Open Source)&lt;br /&gt;
&lt;br /&gt;
== Pulsonix ==&lt;br /&gt;
[http://www.pulsonix.com PULSONIX] ist ein professionelles Schaltplan- und Layout-Werkzeug mit [http://www.pulsonix.com/downloads/datasheets/Pulsonix%20FPGA.pdf integriertem FPGA-Interface] sowie [http://www.pulsonix.com/downloads/datasheets/Pulsonix%20Spice%20V2.0%20UK.pdf integriertem Schaltungsimulator] auf PSpice-Basis.&lt;br /&gt;
&lt;br /&gt;
== QCAD ==&lt;br /&gt;
&lt;br /&gt;
[http://www.ribbonsoft.de/qcad.html QCAD] gibt es in einer lizenzpflichigen und in einer Open Source Community Version. QCAD ist kein ausschliesslicher Schaltungseditor, sondern kann auch für andere 2D Zeichnungen (Konstruktionen etc.) eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
== Razen PCB ==&lt;br /&gt;
&lt;br /&gt;
[[Datei:Razenpcb.png|miniatur|rechts|Screenshot]]&lt;br /&gt;
&lt;br /&gt;
[http://razencad.com/ Razen CAD] ist zwar noch in der Beta Phase, aber sieht momentan schon recht vielversprechend aus. &lt;br /&gt;
Es setzt auf Mercurial auf und ermöglicht dadurch kolaboratives arbeiten an einem Layout.&lt;br /&gt;
&lt;br /&gt;
== sPlan ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;sPlan&#039;&#039;&#039; ist ein relativ preiswerter Schaltplaneditor für Windows (95,98,ME,NT,2000,XP)&lt;br /&gt;
Infos und eine Demoversion von sPlan gibt es u.a. bei http://www.abacom-online.de/html/splan.html&lt;br /&gt;
&lt;br /&gt;
== TARGET 3001! == &lt;br /&gt;
&lt;br /&gt;
[[Bild:target3001.png|right|thumb|Screenshot]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;TARGET 3001!&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; für Windows (ME/NT4/2000/XP/Vista/Win7) bietet folgende Funktionen&lt;br /&gt;
&lt;br /&gt;
* Schaltplan&lt;br /&gt;
* Bauteilerstellung &lt;br /&gt;
* Schaltungssimulation (PSPICE-Syntax)&lt;br /&gt;
* Platinen-Layout mit Autoplatzierer&lt;br /&gt;
* Autorouter &lt;br /&gt;
* Anzeige der Platine in 3D&lt;br /&gt;
* Frontplattenentwurf direkt an oder über der Platine&lt;br /&gt;
&lt;br /&gt;
Die Platinen-Layout-Software ist in deutscher, englischer oder französischer Sprache. Es gibt eine für nicht kommerzielle Anwendungen kostenlose Version: &amp;lt;b&amp;gt;TARGET 3001! discover&amp;lt;/b&amp;gt; ist beschränkt auf 250 Pins/Pads, 2 Kupferlagen&lt;br /&gt;
und 30 Signale sind simulierbar, die Fläche ist unbeschränkt (1,2m x 1,2m).&lt;br /&gt;
&lt;br /&gt;
Auf der c&#039;t 11/07 CD ist eine &amp;lt;b&amp;gt;SE Version&amp;lt;/b&amp;gt; von TARGET 3001! verfügbar welche 400 Pins/Pads verarbeiten kann. &lt;br /&gt;
&lt;br /&gt;
Die &amp;lt;b&amp;gt;PCB-Pool Edition&amp;lt;/b&amp;gt; hat keine Beschränkungen, speichert aber die Layouts in einem von normalen Target Versionen nicht lesbaren Format. Diese Layouts können dann allerdings nur zum selbst Ätzen ausgedruckt werden oder vom PCB-POOL® produziert werden.&lt;br /&gt;
&lt;br /&gt;
Links:&lt;br /&gt;
* [http://server.ibfriedrich.com/wiki/ibfwikide Target3001 Homepage]&lt;br /&gt;
* [http://www.pcb-pool.com/ppde/service_downloads.html Target3001 PCB-Pool-Edition]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;i&amp;gt;TARGET 3001!&amp;lt;/i&amp;gt; bietet ein typisches Windows Look-And-Feel. Eine einfache Einführung findet sich &#039;&#039;&#039;[http://server.ibfriedrich.com/wiki/ibfwikide/index.php?title=Kurzeinführung2 hier]&#039;&#039;&#039;. Wer sich schon mit Eagle auskennt, kann auch &#039;&#039;&#039;[http://server.ibfriedrich.com/wiki/ibfwikide/index.php?title=Eagle hier]&#039;&#039;&#039; schauen. Es gibt kostenlosen direkten Service durch den Hersteller telefonisch oder per E-Mail auch für Einsteiger oder Demo-User.&lt;br /&gt;
&lt;br /&gt;
== TinyCAD ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TinyCAD&#039;&#039;&#039; ist ein weiterer &#039;&#039;Open Source&#039;&#039; Schaltplaneditor für Windows. Mehr Infos gibt es auf der [http://tinycad.sourceforge.net Projektseite]. TinyCAD kann z.&amp;amp;nbsp;B. mit VeeCAD (s.u.) kombiniert werden.&lt;br /&gt;
&lt;br /&gt;
== VeeCAD ==&lt;br /&gt;
&lt;br /&gt;
[http://veecad.com/ VeeCAD] Stripboard Layout Editor ist ein Werkzeug, um [[Lochrasterplatine]]n zu entwerfen. VeeCAD ist als kommerzielle Version und als eingeschränkte Freiversion erhältlich.&lt;br /&gt;
&lt;br /&gt;
== ZenitPCB Suite ==&lt;br /&gt;
&lt;br /&gt;
[http://www.zenitpcb.com/eng/IndexEng.html ZenitPCB Suite] is directed to all those people who want to make printed circuit board for hobby, or to student and academics from universities or high schools, who want to create their own pcb with a professional approach and particularly without having to pay for expensive licenses. ZenitPCB Layout (part of the ZenitPCB Suite) is completely freeware for personal or semi-professional use, limited to [http://www.zenitpcb.com/images/MainBoard_01_01.gif 800 pins]. (Windows XP, Vista)&lt;br /&gt;
&lt;br /&gt;
Übersetzung: ZenitPCB richtet sich an all diejenigen, welche fürs Hobby, Schule, Studium etc professionelle PCBs erstellen möchten, ohne viel Geld für Lizenzen ausgeben zu müssen. ZenitPCb ist in der eingeschränkten Version mit 800 Pins für den semi-professionellen und privaten Gebrauch kostenfrei benutzbar.&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* [[Schaltungssimulation]]&lt;br /&gt;
* [[Dos and don&#039;ts - Platinenlayout]]&lt;br /&gt;
* [[Lochrasterplatine]]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Schaltplaneditoren| ]]&lt;br /&gt;
[[Kategorie:Listen]]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Richtiges_Designen_von_Platinenlayouts&amp;diff=90080</id>
		<title>Richtiges Designen von Platinenlayouts</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Richtiges_Designen_von_Platinenlayouts&amp;diff=90080"/>
		<updated>2015-10-20T16:52:54Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: kleinen Schreibfehler korrigiert&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Beim Erstellen von Platinenlayouts muss man vieles beachten. Dieser Artikel zählt auf, was man machen sollte (Dos), und was man keinesfalls machen sollte (Don&#039;ts).&lt;br /&gt;
Der Grund hierfür ist, dass die &amp;quot;Regeln&amp;quot; (besser eigentlich &amp;quot;Bedingungen&amp;quot;) sehr umfangreich und komplex sind. Dazu kommt, dass es eigentlich keine Regel ohne Ausnahme gibt, und zusätzlich zu den rein elektrotechnischen Anforderungen noch mechanische und chemische sowie betriebswirtschaftliche Anforderungen bestehen. Siehe dazu diesen [http://www.mikrocontroller.net/topic/305443#3280240 Diskussionsbeitrag (letzter Absatz)].&lt;br /&gt;
&lt;br /&gt;
== Gutes Platinenlayout (Dos) ==&lt;br /&gt;
&lt;br /&gt;
* Berechne nach dem Erstellen des Schaltplans, welche Ströme über die Leiterbahn fließen werden und bestimme anhand dessen deren minimale Breite. Faustformel: 0,35mm können ohne nennenswerte Erwärmung mit einem Ampere belastet werden. Kritische Leitungen sollten als Vorgabe für den Layouter in der Zeichnung vermerkt werden. Weiteres siehe unter [[Leiterbahnbreite]].&lt;br /&gt;
* Halte die Leiterbahn möglichst kurz. Jeder Leiterzug wirkt wie eine Antenne, welche Störungen aussendet und empfängt.&lt;br /&gt;
* Nutze die freien Flächen zwischen den Leiterzügen und verbinde sie mit einer Masse (Polygone). So kann man Strahlung von außen abschirmen und oft Abstrahlung minimieren. Vermeide aber freie Kupferflächen, die nicht an GND angeschlossen sind. &lt;br /&gt;
* Geize nicht mit [[Kondensator#Entkoppelkondensator | Blockkondensatoren]]. Für jeden VCC-Pin o.ä. ist mindestens ein 100nF Kondensator, bei schnelleren Sachen evtl. ein kleinerer (z.&amp;amp;nbsp;B. 10nF) einzusetzen. Ausserdem kann es meist notwendig sein, pro IC noch zusätzlich einen 10µF Kondensator und eine Ferritperle (engl. bead) zur Entkopplung von Vcc zu spendieren.&lt;br /&gt;
* Digitale und analoge Signale getrennt routen und nur in einem Punkt verbinden. Und zwar idealerweise am [[AD-Wandler]], falls dieser vorhanden ist, sonst in der Nähe des Spannungsreglers. Eine Massefläche für analoge und digitale Schaltungsteile sollte durchgängig sein, getrennte Masseflächen sind nur in sehr seltenen Fällen sinnvoll. &lt;br /&gt;
* Nutze die Anschlüsse der bedrahteten Bauelemente für Durchkontaktierungen.&lt;br /&gt;
* Wenn es sich nicht vermeiden lässt 230V (400V) Netzspannung auf die Platine zu führen, so trenne die Bereiche der Kleinspannung und Netzspannung deutlich voneinander und mit vieeel Platz. Dabei unterscheidet man zwischen Luft- und Kriechstrecken. Eine Kriechstrecke ist die Strecke auf der Oberfläche einer Leiterplatte oder eines Bauteils. Die Luftstrecke ist sozusagen die kürzeste Verbindung zwischen den beiden Potentialen. Die Luft- und Kriechstrecken betragen zwischen 3 und 8 mm. Maximale Spannung z.b. 3kV/cm, bei lackierten Platinen 1kv/mm. Der notwendige Abstand hängt von der Gefährdung ab, siehe auch [[Leiterbahnabstände]].&lt;br /&gt;
* Möglichst eine großflächige Ground-Plane für Masseverbindungen.&lt;br /&gt;
&lt;br /&gt;
== Schlechtes Platinenlayout (Don&#039;ts) ==&lt;br /&gt;
&lt;br /&gt;
* Analoge und digitale Schaltungsteile direkt ohne Filter aus der gleichen Stromquelle versorgen.&lt;br /&gt;
* Nicht beachtet, dass Ströme im Kreis fließen und damit empfindliche Signale zusammen mit pulsierenden Versorgungsströmen über die gleichen Bahnen geleitet (Sternförmige Masseführung nicht beachtet)&lt;br /&gt;
* Digitale Signalleitungen in unmittelbarer Nachbarschaft analoger Signale&lt;br /&gt;
* Zu wenig Abstand zwischen Leiterplattenrand und Leiterzügen&lt;br /&gt;
* Spitze Winkel kleiner als ca. 45° beim Routen von Leiterbahnen. Entgegen der weit verbreiteten Annahme hat das nur sehr wenig Auswirkungen auf die HF-Eigenschaften, mehr dazu im Artikel [[Wellenwiderstand#Leitungsf.C3.BChrung_und_Layout | Wellenwiderstand]]. Es sind mehr fertigungstechnische (Ablösung von Ecken, schlechteres Ätzen) und ästhetische Gründe (Aussehen, Packungsdichte der Leitungen). &lt;br /&gt;
* Durchkontaktierungen auf SMD-Pads. Beim maschinellen Löten läuft das Lötzinn in die Bohrung ab (u.a. durch Kapillarwirkung) und fehlt auf dem Pad. Die Fehlerhäufigkeit steigt. Bei speziellen Footprints (große Ball Grid Arrays) oder Thermal Vias geht es aber nicht anders als Vias in Pads unterzubringen. In diesem Falle müssen die Vias verschlossen werden (engl. plugged via, tented via). Eine weitere Möglichkeit ist es, einen Überschuss an Lotpaste auf das Pad aufzubringen (dickere Siebdruckschablone) oder die Vias mit Barrieren aus Lötstopplack zu umgeben, aber nicht abzudecken&lt;br /&gt;
* Durchkontaktierungen von beiden Seiten mit Stopplack verschließen. Es könnten Feuchtigkeit oder gar Ätzrückstände darin zurückbleiben und beim Löten der Stopplack abplatzen oder Korrosion auftreten (ggf. Hersteller fragen)&lt;br /&gt;
* Bestückdruck auf Lötpads platziert&lt;br /&gt;
* Keine Testpunkte, keine Befestigungsbohrungen&lt;br /&gt;
* Zu wenig Durchkontaktierungen bei hohen Strömen&lt;br /&gt;
* Entkoppelkondensatoren über unnötig lange Leiterbahnen angebunden&lt;br /&gt;
* Keine Massefläche (engl. ground plane). Bei vielen zweilagigen Platinen mit hoher Bauteildichte kann man sich keine Massefläche leisten, spätestens ab 4 Lagen ist diese jedoch praktisch immer verfügbar.&lt;br /&gt;
&lt;br /&gt;
== Vorgehen bei der Layouterstellung ==&lt;br /&gt;
* Umrisse der Platine festlegen, dabei Bruchkanten eventueller Nutzen beachten&lt;br /&gt;
* Befestigungsbohrungen festlegen, dabei ausreichend Platz für Schraubenköpfe und Werkzeuge freihalten (Sperrflächen verlegen)&lt;br /&gt;
* Steckverbinder platzieren. Dabei den 3D-Zusammenhang mit anderen Platinen im Bezug auf Kabeldrehung und  -knickung beachten, ggf. Steckverbinder um 180 Grad drehen, um Sonderkabel zu vermeiden. Steckverbinder auch nicht völlig am Rand platzieren, um Biegeradius von Flachbandkabeln und Zwischenraum zur Gehäusewand zu schaffen. Steckverbinder, welche direkt in einer Frontplatte enden, werden natürlich direkt am Rand platziert. &lt;br /&gt;
* Bauteile platzieren. Dabei möglichst zusammengehörige Bauteile nebeneinander platzieren. Die Luftlinien (engl. air wires) möglichst kurz und kreuzungsarm halten. Idealerweise erst die grossen und hohen Bauteile festlegen, dabei Einbaumasse und -raum beachten, auch in Bezug auf die Wärmeentwicklung&lt;br /&gt;
* Stromversorgung der ICs verlegen, dabei Abstand zu Kanten und kritischen Signalen /-eingängen beachten. Ebenso [[Leiterbahnabstände | Kriechstrecken]] beachten&lt;br /&gt;
* Kritische Signale wie Takte, Sensoreingänge etc. möglichst ohne Lagenwechsel verlegen, ggf. guard lines verwenden &lt;br /&gt;
* Restliche Signale verlegen&lt;br /&gt;
* Masseflächen füllen&lt;br /&gt;
** Masseflächen können eine Schaltung deutlich verbessern, wenn sie richtig benutzt werden. Sie können aber auch genau das Gegenteil bewirken, wenn sie als automatisches Wundermittel betrachtet werden.&lt;br /&gt;
** Die Masseverbindung aller ICs muss zunächst direkt verlegt werden.&lt;br /&gt;
** Erst wenn die Masse komplett verlegt ist, kann man die Massefläche auffüllen. Damit verhindert man, dass vielleicht ein IC nur über eine sehr dünne Verbindung angeschlossen wird, welche man in der Massefläche übersieht. Ebenso verhindert man, dass eine Massverbindung von einem schnellen IC sehr lang wird und damit die Wirksamkeit der [[Kondensator#Entkoppelkondensator | Entkoppelkondensatoren]] leidet.&lt;br /&gt;
** Masseflächen sind nur dann wirklich wirksam, wenn sie möglichst durchgängig sind. Wenn sie durch viele Leitungen zerschnitten werden, sinkt ihre Wirksamkeit massiv und sie können sich zu einem [[EMV]]-Problem entwickeln (Abstrahlung von Energie, Streifen- und Schlitzantennen). Bei zweilagigen Platinen ist es aber kaum möglich, dass Masseflächen nicht zerstückelt werden. Auf jeden Fall darauf achten, das KEINE Zipfel oder Streifen Massefläche existieren, die nicht an mindestens beiden Enden mit anderen Masseflächen verbunden sind. Für &amp;quot;Systeme&amp;quot; aus solchen Masseflächen gilt gleiches, d.h. die Masseflächen müssen auch untereinander gut vernetzt werden. Wenn dieses nicht erreicht werden kann, so ist die Massefläche besser wegzulassen.&lt;br /&gt;
** Bei Platinen mit vier oder mehr Lagen wird meist eine Lage für die Masse (GND) verwendet. Hier hat man den Luxus, dass man GND nicht manuell layouten muss sondern einfach die ICs an die Massefläche anschließt. Aber Vorsicht! Bei Schaltreglern und Leistungsstufen für Motoren und Ähnlichem ist es oft besser bzw. notwendig, auf Masseflächen zu verzichten und statt dessen mit dicken Leitungen bzw. kleineren Polygonen die Ströme sternförmig zu führen.&lt;br /&gt;
** Des weiteren ergibt sich bei Platinen mit vier oder mehr Lagen die Möglichkeit, auch die Spannungsversorgung (&amp;quot;+ Leitung&amp;quot;) als Fläche auszuführen. Grundsätzlich gelten hierbei die gleichen Empfehlungen wie für die Masseflächen. Diese beiden Stromversorgungslagen sollten in dem Sinne, dass sie einen großen, verteilten Kondensator darstellen, der extrem impedanzarm ist, möglichst dicht zusammen liegen. Bei einem Multilayeraufbau mit vier Lagen wären das z.B. die beiden inneren Lagen. Zusätzlich sollten die beiden Lagen öfters mit keramischen Kondensatoren verbunden werden, mindestens an jedem IC zur Spannungsversorgung.&lt;br /&gt;
* Für die Bestückung und das Bedrucken mit Lotpaste sind Passermarken (engl. Fiducials) nötig. Diese Passermarken werden normalerweise als Kreuze oder besser als runde Pads (z.B 1mm) ausgeführt und von Kupfer freigestellt (2mm, Nicht in die Masseflächen einbeziehen). Die Passermarken werden dann von Lötstop freigegstellt und in der Lotpastenschablone (engl. stencil) mit eingebracht. Auf jede zu bestückende Seite sollten zwei Passermarken diagonal auf den Boards eingebracht werden. Andere Vorschläge zielen darauf ab, die Passermarken nicht für das komplette Board, sondern immer extra für spezielle &amp;quot;kritische&amp;quot; Footprints einzusetzten. Passermarken zur Platinenfertigung setzten sich die Platinenfertiger selbstständig ausserhalb der Platinen nach ihren eigenen Bedürfnissen. Die Passermarken für die Bestücker werden voraussichtlich von den Bestückern auch noch adaptiert, so dass sie lediglich als Platzhalter zu verstehen sind, damit Raum beim routen dafür ausgespart bleibt.&lt;br /&gt;
*Der Bestückungsdruck wird am Ende ausgerichtet. Dazu sollte man nahezu alle Lagen ausblenden und nur die Lagen für Bestückungsdruck, Umrisse und Lötstopmaske anzeigen lassen. Dann richtet man die Beschriftungen so aus, dass sie neben den Bauteilen aber nicht auf den Flächen der Lötstopmaske liegen, denn dort gehört die Lotpaste und später der Anschluss der Bauteile hin. Bei sehr dicht bestückten Platinen muss man den Bestückungsdruck teilweise oder vollständig weglassen. Dort platziert man die Bauteilbezeichnung direkt auf dem Bauteil. Damit kann man den Bestückungsdruck wenigstens auf Papier drucken und somit indirekt nutzen. Einige Profi-CAD-Programme haben dafür auch getrennte Ebenen (engl. Layer).&lt;br /&gt;
&lt;br /&gt;
== CAM Input und Produktion / Berücksichtigung von Technologiegrenzen ==&lt;br /&gt;
&lt;br /&gt;
Um Platinen fertigungsgerecht zu layouten, ist es sinnvoll, in etwa zu wissen, was in der Leiterplattenfabrik gemacht wird, wie die Daten für die Produktion aufgearbeitet werden müssen, und wo dort Schwachstellen liegen, um diese nach Möglichkeit zu vermeiden, zu verringern oder zu Umgehen. Diese Grenzen der Technologie sind &amp;quot;weich&amp;quot;, das heisst, ab einem Grundlevel, ab dem eine fehlerfrei Produktion machbar ist, steigt mit zunehmenden Anforderungen der Ausschuss. Den kauft man zum einen mit d.H. man muss ihn im Rahmen der Kalkulation mitbezahlen, auch wenn er schon in der Fabrik gegeworfen wird, und er muss mit, im Zweifelsfalle aufwändigen und auch nur begrenzt zuverlässigen Verfahren, aussortiert werden. &lt;br /&gt;
&lt;br /&gt;
Hier sollte man also den Grundsatz verfolgen: So grob und einfach wie möglich und so fein wie nötig.&lt;br /&gt;
&lt;br /&gt;
Im folgenden sollen hier ein paar grobe Richtwerte gegeben werden, die eigentlich jede Leiterplattenfabrik kann, und die somit den konservativ definierten Stand der Technik darstellen (Stand ca. 2012). Trozdem sollte man sich im Vorfeld immer informieren. Es ist deutlich mehr möglich, aber das ist abhängig von den Fertigungsstrassen der einzelnen Fabriken und kostet natürlich auch mehr. Man Behalte im Auge, daß hier um fertigungsmechanische und ätztechnische Gründe bei Herstellung der Platine geht, nicht um elektrotechnische Gründe für die fertige Platine. &lt;br /&gt;
&lt;br /&gt;
*Unterätzungsfaktor/U-Faktor &lt;br /&gt;
&lt;br /&gt;
**Um die Unterätzung zu kompensieren, müssen beim CAM-Input die Kupferlagen durch Zugabe einer Breite (U-Faktor) verbreitert werden. Der U-Faktor ist abhängig von dem Materialstärke, die weggeätzt werden muss. Das ist nicht identisch mit der Kupferlage, weil es ja auch Fälle gibt, wo auf eine dünne Vorlage partiell aufgetragen wird wird, und dann alles komplett um die Vorlage abgeätzt wird. Hier ist nur ein U-Faktor für die Vorlagendicke erforderlich.&lt;br /&gt;
&lt;br /&gt;
***Standard:&lt;br /&gt;
****U-Faktor Aussenlagen (35u): +25u (insgesamt), weil beidseitige Wirkung pro Seite 12,5u)&lt;br /&gt;
****U-Faktor Innenlagen (35u): +50u (insgesamt, weil beidseitige Wirkung pro Seite 25u)&lt;br /&gt;
****Wenn Isolationsbreite weniger als 150u, sollte dort NICHT das komplette Leiterbild bearbeitet werden, sondern nur die Pads um z.B. 15u vergrößert werden.&lt;br /&gt;
****Leiterbahnbreiten die kleiner als 150u sind, sollten dabei auf 165u verbreitert werden, wenn die verbleibende Isolation (aus Äztechnischer Sicht!) dieses zulässt.&lt;br /&gt;
&lt;br /&gt;
**Die Software im CAM-Input stellt dafür im allgemeinen spezielle Funktionen zur Vefügung. Diese beruhen aber auch darauf, dass Flächen als Polygone ausgeführt werden, und nicht durch Leiterbahnzüge &amp;quot;gemalt&amp;quot; werden. Desweiteren sollten Pads und nur Pads im Gerber-Format als &amp;quot;Flashs&amp;quot; bzw. &amp;quot;Blinks&amp;quot; dargestellt werden, und Leiterbahnen und eben nur Leiterbahnen als &amp;quot;Draws&amp;quot;, im Grenzfalle auch mit einem &amp;quot;Draw&amp;quot; der Länge 0. Auch wenn ein &amp;quot;Draw&amp;quot; der Länge 0 genauso wie ein &amp;quot;Flash&amp;quot; gleicher Apertur aussieht, gibt die unterscheidung &amp;quot;Draw&amp;quot; zu &amp;quot;Flash&amp;quot; den Aufbearbeitungsalgorithmen der CAM-Input Software wichtige Hinweise.&lt;br /&gt;
&lt;br /&gt;
*Lücken füllen:&lt;br /&gt;
**Sehr schmale „Isostellen“ in der gleichen Kupferfläche und kleine Löcher in Kupferflächen stellen beim Ätzen ein Problem dar, weil das für die Resistschicht kleine &amp;quot;Inseln&amp;quot; oder &amp;quot;Halbinseln&amp;quot; bedeutet, die u.U. nicht halten, sich ablösen, und sich dafür noch anderswo anlagern können, und somit an der Stelle, wo sie fehlen, Unterbrechungen, und an den Stellen, wo die abgerissenen Stücke sich festsetzten, unerwünschte Verbindungen entstehen können. Darum müssen solche Stellen, bearbeitet werden. Das wird Grundsätzlich nach Leiterbildvergrößerung mit U-Faktor gemacht, weil sich einige Lücken dadurch von selber schliessen. Im allgemeinen wird zum füllen einfach ein kleines Stück Leiterbahn über diese Stelle gelegt. Kritisch sind freistehende Resistflächen von ca. 150u mal 150u Abmessungen und kleiner. Werden sie von einer oder zwei Seiten von größeren Resistflächen gehalten, können auch Streifen von ca. 100u tragbar sein, wenn sie nicht zu lang werden.&lt;br /&gt;
&lt;br /&gt;
*Rekalkulieren der Bohrer:&lt;br /&gt;
**Bohrungen für durchkontaktierte (DK)-Bohrungen müssen größer gebohrt werden, weil sie ja zukupfern (Bohrvorlage typisch 200u). Dadurch wird der verbleibende Restring eventuell zu klein.&lt;br /&gt;
**Via Bohrungen (alle Bohrungen kleiner als 0,5 mm) werden nach dem vorhandenen Lötauge gewählt und eventuell vergrößert/verkleinert. Vergrößert, wenn es möglich ist, weil es fertigungstechnische Vorteile bietet, und verkleinert, wenn es sonst Probleme mit Abständen gibt. Der Kupferquerschnitt wird dadurch im allgemeinen nicht zu auffällig verkleinert, und THT-Anschlüsse dünner als 0,5mm sind unbekannt, es kann also (eigentlich) keiner etwas hindurchstecken wollen.&lt;br /&gt;
**Anzustreben sind Bohrer von größer 0,4mm und ein Restring von 175u Breite. Das ist unproblematisch für Lötaugen von 700u (Original), weil ja 50u Durchmesser vom U-Faktor dazukommen. Die Bohrvorlage kann zur Not auf 150u verringert werden.&lt;br /&gt;
**Bohrungen von größer als 0,4mm sind darum anzustreben, weil damit zwei Leiterplatten auf einmal im Stapel gebohrt werden können. Unter 0,4mm wird die seitliche Abweichung der Bohrung in der unteren Leiterplatte so groß, daß sie eventuell ein Pad von der Leiterbahn abschneiden kann. Bei einer Serienfertigung bedeuten darum Bohrungen kleiner als 0,4mm doppelten Aufwand, was sich auch im Preis niederschlägt.....oder einen Wettbewerbsvorteil für Fertiger, die es besser können.&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* [[EMV]]&lt;br /&gt;
* [[Eagle im Hobbybereich]]&lt;br /&gt;
*[http://www.mikrocontroller.net/forum/read-6-178710.html#254235 Forumsbeitrag]: Regeln beim Platinenentwurf&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/93602#804338 Forumsbeitrag]: Vorschlag für Lötpads bei Hobbyeinsteigerplatinen&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/306233#new Forumsbeitrag]: Über spezielle Padformen (Teardrop, Snowman, Oktogon)&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/231263#new Forumsbeitrag]: Suche gutes Buch über Layout-Techniken (Literaturtipps und Links).&lt;br /&gt;
*[http://www.mikrocontroller.net/topic/305443#3286008 Forumsbeitrag]: Tutorials zu Platinenlayout&lt;br /&gt;
*[http://www.mikrocontroller.net/topic/310971#new Forumsbeitrag]: Tipps zum Routen und Entflechten von Platinen.&lt;br /&gt;
*[http://www.mikrocontroller.net/topic/313990#3393319 Forumsbeitrag]: Das Routen von LVDS Signalen.&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* [http://www.ilfa.de/design-optimierung.html Optimierung von Layouts]&lt;br /&gt;
*[http://www.ilfa.de/designrichtlinien Weitere Dokumente zum Thema professionelle Platinenherstellung]&lt;br /&gt;
* [http://www.analog.com/library/analogDialogue/Anniversary/12.html Grounding (Again)], Ask The Applications Engineer - 12, Fa. Analog Devices, (englisch)&lt;br /&gt;
&amp;lt;!-- * http://edaboard.com --&amp;gt;&lt;br /&gt;
* [http://www.sparkfun.com/commerce/tutorial_info.php?tutorials_id=115 Designing a Better PCB] von Sparkfun (engl.)&lt;br /&gt;
* [http://www.hottconsultants.com/tips.html Tech Tips] von Henry Ott (engl.)&lt;br /&gt;
* [http://www.ultracad.com/articles/90deg.pdf Messung] von verschiedenen Winkeln von Leiterbahnen mit 17ps TDR, keinerlei Unterschiede!&lt;br /&gt;
* [http://www.ilfa.de/absorptivesstromversorgungssysteminleiterplatten.html ILFA], Dämpfung von Resonanzen der Versorgungslagen durch Carbondruck&lt;br /&gt;
* [http://docs.toradex.com/101123-apalis-arm-carrier-board-design-guide.pdf Link]: Tipps zum erstellen von High Speed Platinen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Platinen]]&lt;br /&gt;
[[Kategorie:Schaltplaneditoren]]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=KiCad&amp;diff=89787</id>
		<title>KiCad</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=KiCad&amp;diff=89787"/>
		<updated>2015-09-21T10:06:00Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: kleinere Rechtschreibfehler korrigiert&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;KiCAD&#039;&#039;&#039; ist ein Open Source [[Schaltplaneditoren|Schaltplaneditor]] und PCB Layoutprogramm für Windows, Linux, Mac OSX.&lt;br /&gt;
&lt;br /&gt;
Diese Seite ist zunächst eine Zusammenfassung aus den KiCAD Beiträgen im Forum. Und gleich zu Anfang ein grosses DANKE an alle KiCAD-User aus dem Forum. Ihr seid zu viele, um jeden einzeln zu nennen. Aber wer sich diese Seite durchliest und den Links folgt, wird euch kennenlernen.  &lt;br /&gt;
&lt;br /&gt;
Hier sollen alte und neue KiCAD-Anwender einen Anlaufpunkt finden und neue, insbesondere µC-relevante Aktivitäten stattfinden. &lt;br /&gt;
&lt;br /&gt;
Diese Seite will keine Konkurrenz zum offiziellen KiCAD Wiki sein, d.h. was dort steht soll hier nicht wiederholt werden und was hier steht wird hoffentlich zum offiziellen KiCAD Wiki wandern.&lt;br /&gt;
&lt;br /&gt;
Wenn ihr Kritik oder Fragen zu KiCAD habt, dann nutzt das Forum! Sobald KiCAD im Betreff steht, wird der Beitrag gelesen und nach Möglichkeit beantwortet. Auch Ideen zu dieser Seite sind sehr willkommen! &lt;br /&gt;
&lt;br /&gt;
Da diese Seite hier etwas umfangreich geworden ist, empfehle ich eine Textsuche. Jeder Internetbrowser, der etwas auf sich hält, hat auch eine Suchfunktion, mit der der Text der Seite durchsucht werden kann. Bei Firefox/Iceweasel oben im Pull-down Menue unter &amp;quot;Bearbeiten&amp;quot; &amp;gt; &amp;quot;suchen&amp;quot; oder per Shortcut &amp;lt;Strg-F&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== FAQ ==&lt;br /&gt;
&lt;br /&gt;
Siehe auch die offizielle FAQ: http://kicad.sourceforge.net/wiki/index.php/FAQ&lt;br /&gt;
&lt;br /&gt;
TODO: Strukturierung (Allg., Schaltplan, Netlists, Module, Bibliotheken, Layout, Export, 3D)&lt;br /&gt;
&lt;br /&gt;
=== Allgemein ===&lt;br /&gt;
* Warum gefällt dir KiCAD?&lt;br /&gt;
** http://www.mikrocontroller.net/topic/70905#584639&lt;br /&gt;
** http://www.mikrocontroller.net/topic/81396#680502&lt;br /&gt;
** http://www.mikrocontroller.net/topic/83311#697917&lt;br /&gt;
** http://www.mikrocontroller.net/topic/42614#321502&lt;br /&gt;
* Warum gefällt dir KiCAD nicht?&lt;br /&gt;
** Ich verstehe nicht, was du meinst ;-)&lt;br /&gt;
** http://www.mikrocontroller.net/topic/81396#680502&lt;br /&gt;
** http://www.mikrocontroller.net/topic/83311#697969&lt;br /&gt;
&lt;br /&gt;
* Wo gibt es weitere Infos zu KiCAD?&lt;br /&gt;
** Offizielle Homepage: http://kicad-pcb.org/&lt;br /&gt;
** Die Offizielle Dokumentation: http://bazaar.launchpad.net/~kicad-developers/kicad/doc/files/head:/doc/help/en/&lt;br /&gt;
** Einige allgemeine Notizen zur &#039;&#039;&#039;Installation&#039;&#039;&#039; und zur &#039;&#039;&#039;Arbeitsweise&#039;&#039;&#039; von KiCad finden sich hier: https://docs.google.com/document/d/1M38ByFyqnhwGo8b_jDDyBceyZtEGeaSAuQaP9REzWrU/edit?usp=sharing&lt;br /&gt;
** http://www.mikrocontroller.net/topic/98034#848661 (Von 2008, also seeeehr überholt)&lt;br /&gt;
* Welche Leiterplattenfertiger akzeptieren KiCAD Layouts?&lt;br /&gt;
** http://www.pcb-pool.de KiCAD kann &amp;quot;Extended&amp;quot; Gerber RS-247-X erzeugen. Das wird von PCB-Pool akzeptiert. Dabei http://www.pcb-pool.com/download/spezifikation/deu_cmso020_ext_gerber.pdf beachten! Alternativ, wer KiCAD (noch) nicht traut, diese RS-247-X in deren (PCB-Pools) Tool GC-Prevue  http://www.mikrocontroller.net/topic/120373#1092375 einlesen und als .GWK exportieren. AKTUELL August 2012: Wenn man bei PCB-Pool bestellt, ist deren GC-Prevue NICHT mehr erforderlich, weil PCB-Pool mittlerweile KiCAD *,brd Dateien direkt aktzeptiert. Siehe http://www.pcb-pool.com/ppde/info_dataformat.html &lt;br /&gt;
** http://fischer-leiterplatten.de Ohne Aufpreis für Gerber-Import&lt;br /&gt;
&lt;br /&gt;
* Wie geht man mit KiCAD-Trollen um?&lt;br /&gt;
** Mit gesundem Menschenverstand. Trollregeln wie die US AIR FORCE (http://blog.wired.com/defense/2009/01/usaf-blog-respo.html) brauchen wir nicht ;-)&lt;br /&gt;
* Wie kriege ich raus, welche Leiterbahn welchen Netznamen hat, bzw. ich habe den Überblick verloren und weiss nicht mehr, was aus dem Layout nun was im Schaltplan ist?&lt;br /&gt;
**http://www.mikrocontroller.net/topic/218922#2211644. Zusatz: Funktioniert nur gut, wenn großes Fadenkreuz gewählt ist. Aktueller (zu BZR4513 vom 29. November 2013) ist http://www.mikrocontroller.net/topic/316539#3427724&lt;br /&gt;
** Aber ich hätte gerne noch genauere Informationen, z.b. auch über die Länge einer Leiterbahn ec.&lt;br /&gt;
*** Dazu in PCBnew den gleichen Button rechts wie für das Hinzufügen von Leiterbahnen aktivieren. Oder besser noch rechts den zweiten Button von oben &amp;quot;Netz hervorheben&amp;quot;. Dann mit der rechten Maustaste die fragliche Leiterbahn anklicken. Unten in der Statusleiste werden die Informationen angezeigt. &lt;br /&gt;
* Ich würde gerne kicad OHNE Maus bedienen. Wie geht das?&lt;br /&gt;
**http://www.mikrocontroller.net/topic/267538#new&lt;br /&gt;
* Gibt es Sonderzeichen, die ich für Symbole, Module/Footprints oder Files nicht verwenden sollte2&lt;br /&gt;
** Ja, alles was Sonderzeichen ausser - _ . und keine Zahl ist. Siehe: http://www.mikrocontroller.net/topic/302664#3249204&lt;br /&gt;
&lt;br /&gt;
=== Installation ===&lt;br /&gt;
* Woher beziehe ich KiCad?&lt;br /&gt;
** KiCad hat wegen der schnellen Entwicklung z.Z. ein &amp;quot;rolling release&amp;quot;, d.h. es gibt eigentlich keine &amp;quot;offiziellen&amp;quot; Releases, sondern jeder Anwender ist dazu angehalten, sich selber sin KiCad aus den aktuellen Sourcen selber zu compilieren. Dazu gibt es aber Skripte zur Unterstützung, die dieses automatisieren, so dass man nicht unbedingt C/C++ Kenntnisse braucht. Es ist wirklich recht einfach. Ein offizielles &amp;quot;stable release&amp;quot; ist aber wieder für den Spätsommer/Herbst 2015 geplant. Die meisten gängigen Linux Distributionen enthalten aber &amp;quot;old stable&amp;quot; KiCad Releases in ihren Repositories.&lt;br /&gt;
&lt;br /&gt;
** Offizielle Seite (alle Betriebssysteme): http://kicad-pcb.org/download/&lt;br /&gt;
** Leider recht alt: http://iut-tice.ujf-grenoble.fr/cao/&lt;br /&gt;
** Windows: http://www2.futureware.at/~nickoe/ &lt;br /&gt;
*** Welcher Typ? ...-x86_64.exe oder ...-i686.exe ? Ich brauche x86 32 bit.&lt;br /&gt;
**** Für Windows PC 32 bit die ...-i686.exe, und für Windows PC 64 bit ...-x86_64.exe.&lt;br /&gt;
** Veraltet: http://www71.zippyshare.com/v/28617008/file.html Die Quelle ist hier genannt. https://groups.yahoo.com/neo/groups/kicad-users/conversations/messages/18534&lt;br /&gt;
* Kicad entwickelt sich rasant. Wo finde ich eine Liste der Versionsänderungen?&lt;br /&gt;
** Auf der Kicad Launchpad Seite via bazaar. Siehe: http://www.mikrocontroller.net/topic/298311#3187885&lt;br /&gt;
* Ich habe KiCad unter Linux installiert, aber wenn ich KiCad starten will, passiert einfach nichts, oder ich erhalte eine Fehlermeldung wie: &amp;quot;Datei nicht gefunden&amp;quot;. Siehe: http://www.mikrocontroller.net/topic/307517#new&lt;br /&gt;
** 1) KiCad und seine zugeordneten Programme sollten im Suchpfad stehen. Es wird für Debian und Ableger empfolen, KiCad unter usr/local/bin zu installieren. Anmerkung: Das ist die aktuelle Verfahrensweise. Oktober 2013 wurde aber noch folgende Struktur verwendet:&lt;br /&gt;
*** /usr/bin                            - Binaries (executable files).&lt;br /&gt;
*** /usr/share/doc/kicad/               - Various documentation.&lt;br /&gt;
*** /usr/share/doc/kicad/help           - Interactive help.&lt;br /&gt;
*** /usr/share/kicad/demos              - Sample schematics and printed boards.&lt;br /&gt;
*** /usr/share/kicad/internat           - Dictionaries for interface localization.&lt;br /&gt;
*** /usr/share/kicad/library            - Interface localization files.&lt;br /&gt;
*** /usr/share/kicad/modules            - Module libraries for printed boards.&lt;br /&gt;
*** /usr/share/kicad/modules/packages3d - 3D component models (.wrl and .wings format).&lt;br /&gt;
*** Quelle: http://iut-tice.ujf-grenoble.fr/cao/install.txt Hier sind auch Hinweise für Windows user enthalten.&lt;br /&gt;
&lt;br /&gt;
** 2) User sollten dort Lese- und Ausführungsrechte haben. Aber keine Schreibrechte.&lt;br /&gt;
** 3) Wenn ein fertiges Packgage auf einem 64 bit System verwendet wurde, könnte es daran liegen, das es für 32 bit compiliert wurde, und nicht für 64 bit. Es gibt zwei Möglichkeiten:&lt;br /&gt;
*** a) Selbst aus den Sourcen für sein eigenes System compilieren.&lt;br /&gt;
*** b) Die Runtime Libs für 32 Bit könnten fehlen. Nachinstallieren mit sudo apt-get install ia32-libs. Siehe: http://www.mikrocontroller.net/topic/307517#3307638&lt;br /&gt;
* Ich habe das umgekehrte Problem: 32bit system aber 64bit Binarys.&lt;br /&gt;
** Selbst aus den Sourcen neu compilieren.&lt;br /&gt;
*Ich will/muss mir KiCad selber compilieren. Wie gehe ich vor?&lt;br /&gt;
** Aktuell nach: http://www.kicad-pcb.org/display/DEV/Build+KiCad&lt;br /&gt;
**&lt;br /&gt;
**Veraltet! siehe: http://www.mikrocontroller.net/topic/310766#3351269 Aber Achtung. Diese Anleitung (Oktober 2013) muss nicht aktuell sein.&lt;br /&gt;
&lt;br /&gt;
* Sicherheitseinstellungen von Java sind für PCBnew unter JAVA -&amp;gt; JAVA konfigurieren zu finden.&lt;br /&gt;
&lt;br /&gt;
* Diskussionen zum Thema Installation und compilieren:&lt;br /&gt;
** FEDORA: http://www.mikrocontroller.net/topic/338600#new&lt;br /&gt;
** ARCH Linux: http://www.mikrocontroller.net/topic/339509#new&lt;br /&gt;
* Konfigurationsdateien:&lt;br /&gt;
** Ab BZR5114 (ca. 5. September 2014) hat sich der Ordner für die Files mit den Konfigurationsdaten geändert. Unter Linux sind nun die Konfigurations Dateien in $HOME/.config/kicad (entsprechen der FreeDesktop.org Spezifikation). Um Ihre gegenwärtigen Konfigurierungen zu erhalten, können die KiCAd Konfigurationsfiles aus dem Home-Verzeichnis in den aktuellen Ordner kopiert werden. Es muss allerdings der führende &amp;quot;.&amp;quot; (Punkt) der Datei entfernt werden. Ebenso muss die globale &amp;quot;fp-lib-table&amp;quot; aus dem home-Verzeichnis dorthin kopiert werden. Windows User müssen KiCAD leider reconfigurieren. Es gab keinen einfachen Weg um die Registry-Keys in die Konfigurationsdateien zu extrahieren. Die Konfigurationsdateien unter Windows werden genau wie die fp-lib-table im %APPDATA%\kicad Ordner gespeichert. Es ist angeraten, sämmtliche Reste der KiCAD Installation aus der Registry zu entfernen, wenn nicht KiCAD Versionen vor der BZR5114 verwendet werden. Diese Lösung beseitigt die $home Ordner &amp;quot;verschmutzung&amp;quot; und vermeidet die Benutzung der Windows registry, wie es häufig gewünscht wurde. Für OS X User ergeben sich keine Änderungen. Link auf die Originalnachricht (englisch): https://groups.yahoo.com/neo/groups/kicad-users/conversations/messages/18889 (KiCAD-User Group, 05. September 2014, Titel: Configuration file location changes (#18889) Autor: Wayne Stambaugh)&lt;br /&gt;
&lt;br /&gt;
=== Schaltplan ===&lt;br /&gt;
* Wie stellt man die Blattgrösse beim Schaltplan ein?&lt;br /&gt;
** In Page Settings die Blattgröße verstellen (zB von A4 auf A3) http://www.mikrocontroller.net/topic/33653#974295&lt;br /&gt;
* Wie kann man den Schaltplan auf mehreren Seiten verteilen (hierachical sheets)?&lt;br /&gt;
** http://www.mikrocontroller.net/topic/96060&lt;br /&gt;
** http://www.mikrocontroller.net/topic/117873#1060062&lt;br /&gt;
*Wie geht man mit &amp;quot;Power Pins&amp;quot; in hierachischen Schaltplänen um?&lt;br /&gt;
**http://www.mikrocontroller.net/topic/207905#new&lt;br /&gt;
* Wie kann man die &amp;quot;hierachical sheets&amp;quot; benutzen, um aus vorgefertigten Subschaltplänen mit immer gleichen Bauteilgruppen rationell Schaltpläne zusammenzustellen (Building Blocks)?&lt;br /&gt;
** http://www.mikrocontroller.net/articles/KiCAD#Tipps.26Tricks:_Building_Blocks&lt;br /&gt;
** http://www.mikrocontroller.net/topic/175597#1687653&lt;br /&gt;
** http://www.mikrocontroller.net/topic/178683#1724114&lt;br /&gt;
* Ich habe einen hierarchischen Schaltplan angelegt. Wenn ich ihn ausdrucke, werden die Subschaltpläne in der Reihenfolge ausgedruckt, in der sie oben in der Übersicht stehen. Diese Reihenfolge ist aber in meinem Fall ungünstig. Wie kann ich diese nun ändern?&lt;br /&gt;
** Leider im Programm z.Z. noch nicht. Trozdem ist es machbar. Entweder von Hand oder mit einem Python Skript. Näheres zu beidem findet sich hier: http://www.mikrocontroller.net/topic/288394#3064087 . Ein Python 3 Skript, das den Umgang mit dem Kicad-Schaltplan erleichtert, findet sich hier: [[Media:PyKicadSchematic-ID_Interchanger_RevC.zip]].&lt;br /&gt;
*Wie geht man mit Bussen um?&lt;br /&gt;
**http://www.mikrocontroller.net/topic/208870#new&lt;br /&gt;
** und speziell bei hierachischen Schaltplänen: http://www.mikrocontroller.net/topic/209156#new&lt;br /&gt;
* Wie kann man Schaltplanentwurf (KiCAD) und Schaltungssimulation (Spice) verbinden?&lt;br /&gt;
* Ein Tutorial zum Symboleditor für KiCAD, mit dem die Symbole für das Schaltplanmodul (EEschema) erzeugt bzw. editiert werden, findet sich hier: [[Media:SymboleFuerKiCad318082009-RevC-DE.pdf]]. Zur Erstellung von Schaltplansymbolen in aufgelöster Darstellung (Relais: Kontaktsätze einzeln und getrennt von der Spule; IC: Versorgungsspannung getrennt von den einzelnen Gattern) siehe http://www.mikrocontroller.net/topic/273891#new. Bei Problemen noch mal hier nachlesen: http://www.mikrocontroller.net/topic/294095#3136180&lt;br /&gt;
* Wie kann man im Schaltplan Symbole zum Verschieben gruppieren?&lt;br /&gt;
** Siehe http://www.mikrocontroller.net/topic/170913#&lt;br /&gt;
* Und wenn es darum geht, eine solche Gruppe in einen anderen Schaltplan oder Subschaltplan zu verschieben?&lt;br /&gt;
** Die Gruppe ins &amp;quot;Clipboard&amp;quot; stecken. Dazu nach dem Markieren der Gruppe rechte Maustaste beklicken, und dort &amp;quot;Gruppe speichern&amp;quot; wählen. Nun ist die Gruppe im Clipboard. jetzt in den gewünschten Unterschaltplan gehen und die Gruppe dort mithilfe des Clipboardbuttons (Das Klemmbrett Symbol links neben dem &amp;quot;Undo&amp;quot;-Button) in den Schaltplan einfügen. NICHTS mit der rechten Maustaste versuchen! Siehe auch: http://www.mikrocontroller.net/topic/244836#2499782 Das ganze geht nicht nur mit Subschaltplänen, sondern auch genauso in einen ganz anderen Schaltplan, den man dann halt in Eeschema öffnen muss, hinein. Wenn nach dem Einfügen allerdings nur ein Kästchen mit Fragezeichen erscheint, waren die nötigen Symbolbibliotheken für diese Symbole noch nicht in der Projektdatei eingetragen. Das mus man nun nachholen, indem man unter &amp;quot;Einstellungen&amp;quot; die &amp;quot;Bibliotheken&amp;quot; wählt, und die passenden Bibliotheken einträgt. Wenn man nicht genau weiss, wo diese zu finden sind, kann es sinnvoll sein, die *-cache.lib des Herkunftsschaltplanes einzubinden. &lt;br /&gt;
* Wie wird man den merkwürdigen Rahmen los?&lt;br /&gt;
** 1) Bei neueren KiCad Versionen, ab ca. Mitte 2013 (von mir getestet ab BZR 4513 29 November 2013) kann man sich eine Vorlage ohne Rahmen erstellen. Dazu den pl_editor (der ganz rechte Button im KiCad Hauptfenster) starten, und FAST alles entfernen. Dazu in der linken Spalte nacheinander alles aktivieren, und mit rechts anlicken und dann &amp;quot;entfernen&amp;quot; wählen. Aber vorsicht, wenn alles Entfernt wird, taucht das Original Layout wieder auf. Workaround war bei mir, eine zusätzliche Alibilinie hinzuzufügen, die von X 0,000 Y 0,000 bis  X 0,001 Y 0,000 reicht. Das ist ein &amp;quot;Fliegenschiss&amp;quot; in der linken oberen Ecke. Jetzt kann alles andere gelöscht werden. Den so geleerten Rahmen unter einem beliebigen Namen mit der Endung .kicad_wks wegspeichern. Im geöffneten Schaltplan kann der dann unter Datei &amp;gt; Seite einrichten ganz unten unter &amp;quot;page layout file description&amp;quot; die entsprechende Datei eingebunden werden. Es bleibt aber dem Anwender offen, ob er den Rahmen komplett entfernt, oder noch Felder mit Textbeschreibungen übernimmt. Für gesteigerten Komfort kann diese Datei dann auch in ein Template eingebunden werden. &lt;br /&gt;
** 2) Beim Ausdrucken Frame deaktivieren.&lt;br /&gt;
** 3) Als SVG exportieren. Dort den Frame deaktivieren.&lt;br /&gt;
** Siehe: http://www.mikrocontroller.net/topic/343509#3791448&lt;br /&gt;
* Wie schalte die Footprint-Namen in Eeschema global ab?&lt;br /&gt;
** http://www.mikrocontroller.net/topic/253564#new&lt;br /&gt;
* Ich habe ein Problem mit dem ERC. Ständig kommt die Fehlermeldung: &amp;quot;Pin ist mit anderen Pins verbunden, wird jedoch von keinem angesteuert&amp;quot;&lt;br /&gt;
** Netze, die nicht angesteuert werden, werden von Kicad misstrauische beäugt. Das &amp;quot;nicht ansteuern&amp;quot; kann aber schnell passieren, weil Kicad u.A. erwartet, das irgendwo ein Spannungsversorgung ist. Wenn diese aber z.B. über eine Sicherung oder einen Pull-up Widerstand gehen, so wird das nicht bemerkt, weil Sicherungen und Widerstände (oder auch Entstördrosseln) &amp;quot;passive&amp;quot; Pins haben. Siehe: http://www.mikrocontroller.net/topic/292988#new und http://www.mikrocontroller.net/topic/298401#new&lt;br /&gt;
* Ich habe ein Problerm mit dem ERC. Immer in Verbindung mit GND kommt die Fehlermeldung: &amp;quot;Pin ist mit anderen Pins verbunden, wird jedoch von keinem angesteuert&amp;quot;&lt;br /&gt;
**Siehe: http://www.mikrocontroller.net/topic/284089#new&lt;br /&gt;
* Beim ERC kommt die Fehlermeldung &amp;quot;PIN not connected&amp;quot; an Verbindungen, die per Label angeschlossen sind. Was ist da falsch?&lt;br /&gt;
**Sie sind tatsächlich nicht angeschlossen. Siehe: http://www.mikrocontroller.net/topic/346976#new&lt;br /&gt;
* Wie ist der Zusammenhang zwischen Bauteilen und Netznamen? Wie bekomme ich heraus, an welchem Netz mein Bauteil angeschlossen ist?&lt;br /&gt;
** Eeschema vergibt bzw. aktualisiert erst dann Netznamen, wenn eine Netzliste erzeugt wird. Darauf besteht entweder ein Zugriff über PCBnew, oder aber mit einem Editor. Siehe Beitrag http://www.mikrocontroller.net/topic/316539#new&lt;br /&gt;
* Ich habe einen Schaltplan geöffnet, aber alle oder einige der Symbole zeigen nur Kästen mit Fragezeichen.&lt;br /&gt;
** Es fehlen die passenden Symbolbibliotheken für diese Symbole.&lt;br /&gt;
*** Diese müssen in der Liste der Bibliotheken nachgetragen werden. &lt;br /&gt;
*** Hat man von anderswo einen Schaltplan bekommen, kann dieser auf anderen Symbolbibliotheken beruhen, als man selber verwendet. Aus diesem Grunde existiert zu jeder Schaltplandatei (Dateiname.sch) eine Cache Bibliothek (Dateiname-cache.lib). Diese enthält alle im Schaltplan verwendeten Symbole, und sollte darum mit dem Schaltplan zusammen übergeben werden.&lt;br /&gt;
*** Ab BZR4646 (Jan./Feb. 2014) behandelt KiCad Symbolnamen &amp;quot;Case Sensitive&amp;quot;. Das führt zu Problemen mit älteren Schaltplänen, wo &amp;quot;Mixed Case&amp;quot; Symbolnamen aus den Bibliotheken automatisch in &amp;quot;Upper Case&amp;quot; Symbolnamen konvertiert wurden. Diese werden jetzt nicht mehr erkannt. Näheres siehe: http://www.mikrocontroller.net/articles/KiCAD#Problem:_Case_Senitive_Symbols_ab_BZR4646_.28Jan..2FFeb._2014.29&lt;br /&gt;
*Wieviele Textfelder für Symbole kann ich anlegen und wie groß dürfen diese sein?&lt;br /&gt;
** Mindestens 35 Felder, die mindestens 256 Zeichen (tatsächlich deutlich mehr) beinhalten können. Aber Zeilenumbrüche gehen nicht. Siehe: http://www.mikrocontroller.net/topic/331201#3658695&lt;br /&gt;
* Ich habe ein Symbol im Symboleditor geändert. Aber irgendwie taucht diese Änderung dann in Eeschema trotzdem nicht auf.&lt;br /&gt;
** Die Reihenfolge der Einträge in der Bibliotheksliste ist wichtig. Bei gleichem Namen wird immer das zuerst gefundene Symbol verwendet. Steht die -cache.lib in der Reihenfolge zu oberst, wird immer zuerst das Bauteil aus der -cache.lib verwendet. Beheben: Die -cache.lib aus der Bibliotheksliste von Eeschema austragen und neu eintragen, so dass sie unten angefügt wird, und zuletzt geladen wird. Alternativ: Bei Änderungen einen neuen Namen für das Symbol vergeben. Z.B. durch das Pflegen eines Revisions- oder Datecode im Symbolnamen. Einfach nur die -cache.lib löschen langt möglicherweise nicht, weil diese u.U. mit alten Daten neu geschrieben wird (wenn z.b. Eeschema dabei nicht geschlossen ist). Siehe: http://www.mikrocontroller.net/topic/331201&lt;br /&gt;
&lt;br /&gt;
=== Netlist ===&lt;br /&gt;
* Was genau muss man beim Übergang vom Schaltplan (SCH) zum Layout (BRD) machen?&lt;br /&gt;
** http://www.mikrocontroller.net/topic/33653#898771&lt;br /&gt;
** http://www.mikrocontroller.net/topic/39243#290309&lt;br /&gt;
** http://www.mikrocontroller.net/topic/39243#891530&lt;br /&gt;
* Kann man fertige Netzlisten für Gruppen von Bauteilen einbinden?&lt;br /&gt;
** http://www.mikrocontroller.net/topic/33653#1462871&lt;br /&gt;
* Kann man Daten für automatische Bestückung erzeugen?&lt;br /&gt;
** Ja. aber nicht in CVpcb für die Symbol &amp;gt; Footprint Zuordnung, sondern im Layout Modul PCBnew.&lt;br /&gt;
* In meiner Netlist fehlen Bauteile, die im Schaltplan vorhanden und angeschlossen sind. Der ERC läuft problemlos durch. Die Annotation auch, aber nach Erstellung der Netlist sind die Symbole plötzlich mit einem vorangestellten &amp;quot;#&amp;quot; im Schaltplan bezeichnet.&lt;br /&gt;
** Vermutlich sind sie versehentlich als &amp;quot;virtuelles&amp;quot; Bauteil gekennzeichnet. Siehe http://www.mikrocontroller.net/topic/268626#new&lt;br /&gt;
* Wie exportiere ich eine Netlist NUR für einen Subschaltplan?&lt;br /&gt;
** Das geht, nachdem dieser Schaltplan explizit in EEschema geöffnet wurde. Siehe: http://www.mikrocontroller.net/topic/330740#new&lt;br /&gt;
* Ich finde CVpcb nicht mehr am gewohnten Platz zwischen all den anderen Startbuttons!&lt;br /&gt;
** CVpcb ist inzwischen aus diesen entfernt worden, und durch Startbuttons für den Symboleditor und den Footprinteditor ersetzt worden. Dafür kann CVpcb jetzt direkt aus Eeschema heraus gestartet werden. Es findet sich jetzt im oberen Pulldown Menue unter &amp;quot;Werkzeuge&amp;quot; und dann &amp;quot;Bauteilfootprints zuweisen&amp;quot; oder in der oberen Buttonleiste als dritter Button von rechts (BZR5175 vom 11 Oktober 2014).&lt;br /&gt;
** Sollte KiCad abstürzen, wenn man versucht, CVpcb zu starten, so kann man CVpcb auch direkt aus einem Terminal oder aus der Eingabeaufforderung heraus starten.  &lt;br /&gt;
** Versuchsweise mal 10 Minuten warten.....bei Problemen mit der Erkennung von Symbolnamen und Footprintnamen (beim öffnen ganz alter Projekte mit alten Dateiformaten) kann es manchmal extrem lange dauern.&lt;br /&gt;
* Was bedeuten die Maßangaben in der Netlist?&lt;br /&gt;
* Wie überträgt man Kicad Schaltpläne in QUCS Schaltpläne für Simulation?&lt;br /&gt;
&lt;br /&gt;
=== Layout ===&lt;br /&gt;
* Wie stellt man die Rastergrösse im Layout ein?&lt;br /&gt;
** Mit der Rechten Maustaste in das Board klicken. Es poppt ein Menue auf. Dort Raster wählen..... Geht im Modul-Editor genauso.&lt;br /&gt;
* Wie werden Pads und Leiterbahnen verbunden?&lt;br /&gt;
**Siehe: http://www.mikrocontroller.net/topic/119755#1081455&lt;br /&gt;
**Aktueller: http://www.mikrocontroller.net/topic/220733#new&lt;br /&gt;
* Ich kann keine Leiterbahnen ziehen!&lt;br /&gt;
** Vermutlich hast Du den automatischen DRC (Design rule check) aktiviert. Deaktiviere ihn halt. In PCBnew im linken Buttonbar der oberste Button (Insekt mit Verbotszeichen). http://www.mikrocontroller.net/topic/306476#new&lt;br /&gt;
* Mir fehlen Airwires/Luftlinien/Gummibänder!&lt;br /&gt;
** Vieleicht die falschen Pins als Typ &amp;quot;Spannungsausgang&amp;quot; definiert? Siehe: http://www.mikrocontroller.net/topic/330817#3620918&lt;br /&gt;
* Ich bekomme immer eine Fehlermeldung vom DRC, das ein Pad nicht angeschlossen ist, aber ich habe es angeschlossen.&lt;br /&gt;
**Siehe: http://www.mikrocontroller.net/topic/204717#2018724&lt;br /&gt;
* Ich will ein Bauteil für geringeren Leiterwiderstand sowohl auf der Unterseite- als auch der Oberseite anschliessen. KiCAD löscht aber immer den alten Leiterbahnzug, wenn ich den neuen lege. &lt;br /&gt;
** Deaktiviere unter Einstellungen-&amp;gt;Allgemein das &amp;quot;auto-entfernen-von-Leiterbahnen&amp;quot; (einfachste Lösung). &lt;br /&gt;
** Alternativ: Designe dafür Bauteile mit speziellen Pads. http://www.mikrocontroller.net/topic/187606#1823596 (realistischste u. sauberste Lösung, aber etwas umständlich.)&lt;br /&gt;
* Wie kann man ein Bauteil mit Pads und Leiterbahnen bewegen? &lt;br /&gt;
** http://www.mikrocontroller.net/topic/118539#1067219&lt;br /&gt;
* Wie füllt man eine Fläche aus?&lt;br /&gt;
** Siehe: http://www.mikrocontroller.net/topic/93131#854802&lt;br /&gt;
** Etwas aktueller: http://www.mikrocontroller.net/topic/182271#1772119 Zweiter Teil des Posts.&lt;br /&gt;
** Und wie erzeuge ich konzentrisch ineinanderliegende Flächen?&lt;br /&gt;
*** Siehe: http://www.mikrocontroller.net/topic/327475#new&lt;br /&gt;
** Ja, aber meine Fläche wird nicht gefüllt oder es passiert was ganz merkwürdiges.&lt;br /&gt;
***Siehe: http://www.mikrocontroller.net/topic/298692#new &lt;br /&gt;
***Konkreter: Es sollte darauf geachtet werden, das mindestens ein Endpunkt oder ein Via oder ein Knickpunkt der Leiterbahn, die mit der zu füllenden Fläche verbunden sein soll, innerhalb der als zu füllen definierten Fläche liegen. Siehe http://www.mikrocontroller.net/topic/366199#new&lt;br /&gt;
* Ich habe eine Platine, die von oben und unten bestückt ist. Wenn ich jetzt Bauteile zusammengruppiere, um sie gemeinsam zu verschieben, erwische ich immer alle Bauteile auf Vorder- und Rückseite. Wie bekomme ich das jetzt hin, das ich nur Module auf einer Seite bewege?&lt;br /&gt;
** Indem im Lagenmanager die Seite, die nicht bewegt werden soll, abgeschaltet wird. Siehe: http://www.mikrocontroller.net/topic/311586#new&lt;br /&gt;
* Wie bekommt man ein vernünftiges Boardoutline hin?&lt;br /&gt;
** http://www.mikrocontroller.net/topic/96060#1057511 &lt;br /&gt;
* Wie erstellt man eine Befestigungsbohrung / nichtdurchkontaktierte Bohrung?&lt;br /&gt;
** VERALTET: http://www.mikrocontroller.net/topic/179308#1726990&lt;br /&gt;
** VERALTET:http://www.mikrocontroller.net/topic/120373#1122219 ?????&lt;br /&gt;
** KiCAD kann mittlerweile auch direkt nichtdurchkontaktierte Bohrungen erzeugen. Siehe dazu http://www.mikrocontroller.net/topic/263069#2732405 Enthält auch allgemeine Informationen zum Umgang mit durchkontaktierten und nicht durchkontaktierten Bohrungen.&lt;br /&gt;
* Ich möchte für Passermarken / Fiducials eine deutlich größere Freistellung in der Lötstoppmaske haben. Wie geht das?&lt;br /&gt;
** http://www.mikrocontroller.net/topic/266730#2779498&lt;br /&gt;
* Wie geht das überhaupt mit den Lötstoppmasken?&lt;br /&gt;
** http://www.mikrocontroller.net/topic/283721#new&lt;br /&gt;
* Ja, aber die Lötstoppmaske wird leider nicht angezeigt.&lt;br /&gt;
** http://www.mikrocontroller.net/topic/298028#new&lt;br /&gt;
* Ich möchte Text und Markierungen/Grafik statt im Bestückungsdruck im Lötstopplack erstellen. Geht das überhaupt und wie ist das zu bewerkstelligen?&lt;br /&gt;
** Das geht, und dazu ist der Text oder die grafischen Linien/Kreise direkt in die Lötstoppmaske zu schreiben. Siehe: http://www.mikrocontroller.net/topic/347702#new Die Lötstoppmasken Lagen heissen F.Mask (Bestückungsseite) und B.Mask (Lötseite).&lt;br /&gt;
* Wie kann man Bauteilmaße in den Ansichten (Footprint, Layout, 3D-View) anzeigen?&lt;br /&gt;
** Anzeige im Layout: Layer &amp;quot;Zeichnung&amp;quot; anwählen. In der rechten Menueleiste &amp;quot;Bemaßung hinzufügen&amp;quot; wählen. Das ist der fünfte Button von unten mit der &amp;quot;blauen Bemaßung&amp;quot;. Jetzt an einer Stelle links ins Layout klicken. Maus verschieben und noch einmal links klicken und die Maus seitlich verschieben. Es wird ein Maßpfeilsystem zwischen erstem und und zweitem Mausklick angelegt, deshen höhe man mit der Maus einstellen kan. Ein weiterer linker Mausklick fixiert das System. Das Anklicken der Beschriftung mit der rechten Maustaste erlaubt das Editieren. Das System wird immer in der Einheit angelegt, die in der linken  Menueleiste vorgewählt wurde. Die Rasterung der aktuellen Einstellung wird auch übernommen. Späteres Ändern von Einheit- und Raster ändern die Beschriftung nicht mehr. In 3D und im Footprint geht diese Möglichkeit nicht.&lt;br /&gt;
** Weitere Möglichkeiten: Einen Maßstab als footprint/Modul anfertigen und zum Messen in das Board einfügen.&lt;br /&gt;
** Wenn man im Layout aber direkt etwas ausmessen möchte, so geht das über den relativen Nullpunkt. Unten im Rahmen rechts sind vier Felder. Die beiden linken zeigen die absoluten Koordinaten, an, die beiden rechten die relativen Koordinaten in Bezug auf einen relativen Nullpunkt. Defaultmäßig stimmen absoluter und relativer Nullpunkt ersteinmal überein. Per &amp;quot;Space bar&amp;quot; drücken setzt Du den relativen Nullpunkt an den Ort des Mauszeigers. Wenn Du nun die Maus verfährst, zeigen die relativen Koordinaten nun den vertikalen und horizontalen Abstand zum Nullpunkt. Die Diagonale muss leider über den Pythagoras selber ausgerechnet werden, oder indem man die Polarkoordinateneinstellung wählt (linke Menueleiste). Durch geschicktes setzten des Nullpunktes kann man nun auf der Platine herummessen. Winkel können auch über die Polarkoordinateneinstellung gemessen werden. Im Moduleditor geht das analog. Das 3D-View kann zur Zeit (Jannuar 2011) überhaupt keine Bemaßung.     &lt;br /&gt;
* Wie kann man mit der KiCAD Version 20100314 &#039;&#039;&#039;einseitige&#039;&#039;&#039; Platinen erstellen?&lt;br /&gt;
** http://www.mikrocontroller.net/topic/172015#1651239&lt;br /&gt;
** aktueller: http://www.mikrocontroller.net/topic/172015#1794699&lt;br /&gt;
*Und wie teile ich KiCAD mit, daß der Autorouter nur eine Seite verwenden soll?&lt;br /&gt;
** Auf die doofe Tour: Erst in KiCAD zweiseitig wählen, und dann beide Lagen im Autorouter als &amp;quot;Unterseite&amp;quot; wählen.&lt;br /&gt;
* Wie kann man den Nullpunkt eines Layouts verschieben?&lt;br /&gt;
** http://www.mikrocontroller.net/topic/179680#1730452 für den Layout Editor PCBnew. Im Moduleditor bei Erstellung eines Footprints kann man den Ankerpunkt frei Mithilfe des Anker-Tools aus der rechten Menüleiste (das Ankersymbol) setzten. Gleiches gilt für den Symboleditor.&lt;br /&gt;
* Wie gehen runde Bögen in KiCAD?&lt;br /&gt;
**http://www.mikrocontroller.net/topic/202512#1994063&lt;br /&gt;
* Wie benutze ich den interaktiven Router (Push &amp;amp; Shove) in PCBnew?&lt;br /&gt;
** Dazu muss in PCBnew im Pulldown-Menue unter &amp;quot;Ansicht&amp;quot; die Option &amp;quot;Canvas nach OpenGL umschalten&amp;quot; oder &amp;quot;Canvas nach Cairo umschalten&amp;quot;gewählt werden. Wenn man nun, wie gewohnt, aus der rechten Button Leiste das Verlegen von Leiterbahnen wählt, eine Leiterbahn/Luftlinie wählt und rechts anklickt, erhält man den interaktiven Router. Aber Achtung - wegen des geänderten Kontextmenues kann es sinnvoll sein, für andere Tätigkeiten auf die Voreinstellungen zurückzuschalten.&lt;br /&gt;
* Ich habe mein Board fertig geroutet, stelle aber jetzt fest, das ich noch einige Leiterbahnbreiten ändern muss. Wie geht das am einfachsten?&lt;br /&gt;
**http://www.mikrocontroller.net/topic/205851#new&lt;br /&gt;
*Ich kann Pads nicht anschlissen bzw. ich bekomme vom DRC Fehlermeldungen, daß ich Pads nicht angeschlossen habe, obwohl sie angeschlossen sind.&lt;br /&gt;
**http://www.mikrocontroller.net/topic/204717#new&lt;br /&gt;
*Wie kann ich Daten für automatische Bestückung (Pick&amp;amp;Place) erzeugen?&lt;br /&gt;
** In PCBnew unter Datei &amp;gt; Fertigungsdateien &amp;gt; Bauteile Positionsdatei (.pos). Aber dieses verlangt, das die Footprints auch die richtigen Informationen dazu enthalten. Um diese einzustellen, den Footprint im Moduleditor öffnen und unter dem Button &amp;quot;Bauteileigenschaften&amp;quot; in &amp;quot;Attribute&amp;quot; eine Markierung bei &amp;quot;Normal+Einfügen&amp;quot; machen. Dann wird der Ankerpunkt des Modules für die Positionsdatei verwendet. Damit sinnvolle Daten entstehen, sollte der Ankerpunkt in die Mitte des Footprintes gesetzt worden sein. &lt;br /&gt;
*Und wie erzeuge ich ein Excellon Drillfile?&lt;br /&gt;
** In PCBnew unter Datei &amp;gt; Fertigungsdateien &amp;gt; Bohrdaten. Die Datei enthält auch eine Werkzeugliste. Kicad legt u.U. zwei Drillfiles an, wenn erforderlich. Eines für durchkontaktierte, und eines für nicht durchkontaktierte Bohrungen. Wer eine extra Liste und eine Statistik wünscht, muss auch noch &amp;quot;Bericht über Bohrung&amp;quot; anwählen.&lt;br /&gt;
** Bei mir wird aber nur ein Drillfile erzeugt. Was läuft falsch?&lt;br /&gt;
***Die NPTH Drills müssen im Pad-Editor explizit als solche gekennzeichnet werden. In PCBnew erkennt man sie dann als dicke gelbe Flächen. Siehe: http://www.mikrocontroller.net/topic/322941#3989397 Bei älteren Footprints ist das aber noch nicht komplett umgesetzt. &lt;br /&gt;
* Wenn PCBnew die Netzliste eingelesen hat, liegen alle Bauteile auf einem Haufen. Zum Plazieren eines herausgreifen ist mühsam. Wie geht das am einfachsten?&lt;br /&gt;
** In PCBnew &amp;quot;T&amp;quot; drücken. Es poppt ein Fenster auf, wo man die Bauteilreferenz (den Namen) eingeben kann. Und schon hängt das Bauteil zum Bewegen am Zeiger. Die Bedienung ist letztlich genauso wie das &amp;quot;m&amp;quot; und die Komandozeile in Eagle. Siehe http://www.mikrocontroller.net/topic/293903#3133990&lt;br /&gt;
** &amp;quot;Raef&amp;quot; hat ein Python Script erstellt, das Bauteile automatisch ähnlich der Anordnung im Schaltplan plaziert. Siehe: http://www.mikrocontroller.net/topic/293903#3245990&lt;br /&gt;
* Ich habe ein fertiges Layout. Jetzt möchte ich aber andere Footprints verwenden, und anschliessend nicht neu routen müssen. Wie geht das?&lt;br /&gt;
** Üner CVpcb und Neueinlesen der Netzliste. Siehe: http://www.mikrocontroller.net/topic/297885#new&lt;br /&gt;
* Ich will links herum routen, aber Kicad meint unbedingt rechts herum (...oder umgekehrt). Wie kann ich die Leiterbahnen &amp;quot;flippen&amp;quot;?&lt;br /&gt;
** Mit &amp;quot;/&amp;quot; (Slasch) http://www.mikrocontroller.net/topic/280028#new&lt;br /&gt;
* Ich hätte gerne die Tastenkürzel in kicad so wie in meinem gewohnten Programm. Wie geht das?&lt;br /&gt;
** Siehe http://www.mikrocontroller.net/topic/283959#3007173 . Vieleicht ist einer ja so nett, und stellt Konfigurationsfiles für Leute die aus EAGLE, ORCAD oder so wechseln, bereit.&lt;br /&gt;
* Ich habe ein kleines Board fertig geroutet. Jetzt möchte ich mehrere davon zu einer größeren Platine zusammenführen (sog. Mehrfachnutzen), um sie rationeller fertigen zu können.&lt;br /&gt;
** Siehe http:http://www.mikrocontroller.net/topic/292334#new . Das geht natürlich genauso, wenn man verschiedene Platinen so zu Nutzen zusammenfügen möchte, oder halt kleinere Teillayouts zu einem Gesamtboard.&lt;br /&gt;
* Ich habe einen Schaltplan mit Subschaltplänen, zu denen ich separate Layouts erstellen möchte.&lt;br /&gt;
** Dazu diesen Subschaltplan explizit in EEschema öffnen, und die Netzliste nur für diesen Subschaltplan exportieren.  Weitergehen wie üblich. Siehe: http://www.mikrocontroller.net/topic/330740#new&lt;br /&gt;
* Ich möchte Varianten eines Layouts erstellen. Was ist dazu zu sagen? Siehe: http://www.mikrocontroller.net/topic/330740#3616697&lt;br /&gt;
** Siehe http://www.mikrocontroller.net/topic/292123#new&lt;br /&gt;
* Wie importiere ich DXF-Dateien in PCBnew?&lt;br /&gt;
** Dafür existiert eine Import Funktion in PCBnew: Datei &amp;gt; Importieren &amp;gt; DXF-Datei. Siehe http://www.mikrocontroller.net/topic/327628#new&lt;br /&gt;
* Wie wird man den merkwürdigen Rahmen los?&lt;br /&gt;
** 1) Genauso wie im Schaltplan. Dazu den pl_editor (der ganz rechte Button im KiCad Hauptfenster) starten, und FAST alles entfernen. Dazu in der linken Spalte nacheinander alles aktivieren, und mit rechts anlicken und dann &amp;quot;entfernen&amp;quot; wählen. Aber vorsicht, wenn alles Entfernt wird, taucht das Original Layout wieder auf. Workaround war bei mir, eine zusätzliche Alibilinie hinzuzufügen, die von X 0,000 Y 0,000 bis  X 0,001 Y 0,000 reicht. Das ist ein &amp;quot;Fliegenschiss&amp;quot; in der linken oberen Ecke. Jetzt kann alles andere gelöscht werden. Den so geleerten Rahmen unter einem beliebigen Namen mit der Endung .kicad_wks wegspeichern. Im geöffneten Schaltplan kann der dann unter Datei &amp;gt; Seite einrichten ganz unten unter &amp;quot;page layout file description&amp;quot; die entsprechende Datei eingebunden werden. Es bleibt aber dem Anwender offen, ob er den Rahmen komplett entfernt, oder noch Felder mit Textbeschreibungen übernimmt. Für gesteigerten Komfort kann diese Datei dann auch in ein Template eingebunden werden. &lt;br /&gt;
** 2) Beim Ausdrucken Frame deaktivieren.&lt;br /&gt;
** 3) Als SVG exportieren. Dort den Frame deaktivieren.&lt;br /&gt;
** 4) Beim Plotten (z.B. in Gerber) Frame deaktivieren. Ist eigentlich defaultmäßig eingestellt. &lt;br /&gt;
** Siehe: http://www.mikrocontroller.net/topic/343509#3791448&lt;br /&gt;
* Ich möchte einen bestimmten Footprint verwenden (von dem ich weiss, dass er existiert), kann ihn aber in der Auswahl der Footprints von PCBnew nicht finden.&lt;br /&gt;
**Die Bibliothek, in der er enthalten ist, muss erst in das Verzeichnis der aktiven Bibliotheken in PCBnew eingetragen werden. &lt;br /&gt;
* Ich möchte Footprint-Bibliotheken in das Verzeichnis der verwendeten Bibliotheken von PCBnew eintragen. Wie geht das?&lt;br /&gt;
** https://www.mikrocontroller.net/topic/372123#new  &lt;br /&gt;
* Ich habe Probleme mit den Umgebungsvariablen KISYSMOD, KISYS3DMOD, KIPRJMOD, KIGITHUB beim Eintragen der Bibliothekstabellen.&lt;br /&gt;
** KISYSMOD ist eine Variable, die den Pfad zu den global verwendeten KICAD-Modulen (Footprints) angibt. KIPRJMOD ist das gleiche, für projektspezifische Module. KISYS3DMOD beschreibt den Pfad zu den 3D-Modellen, und KIGITHUB weisst den Pfad ins Internet zu den Githubbibliotheken.&lt;br /&gt;
** Nähere Informationen dazu findet man hier: http://www.mikrocontroller.net/topic/344139#new und hier : http://www.mikrocontroller.net/topic/344029#new&lt;br /&gt;
** Falls alles nichts hilft: Nan kann den Pfad auch komplett am Stück in die Bibliothekstabelle eintragen. Copy&amp;amp;Paste funktioniert dort aber nicht per rechtem Mausklick, sondern per &amp;lt;Str-c&amp;gt; (Kopieren) und &amp;lt;Str-v&amp;gt; (einfügen). Einfacher als die Bibliothekstabelle lässt sich darum die fp-lib-table Datei per Editor bearbeiten. Unter Linux findet sich die Tabelle für globale Bibliotheken bis zur BZR5113 direkt im Homeverzeichnis. Ab BZR5114 (ca. 5. September 2014) fiondet sich die globale fp-lib-table in $HOME/.config/kicad. Die fp-lib-table für projektbezogene Bibliotheken finden sich in den korrespondierenden  Projektverzeichnissen.&lt;br /&gt;
* Ich würde gerne aus den Mikrowellen Tools die Funktion &amp;quot;Polynominales Muster&amp;quot; verwenden. Dabei werde ich nach einem KiCad-Shapefile gefragt, aber ich weiss nicht, wie das File aussehen muss.&lt;br /&gt;
** Einen Hinweis zum Aussehen des Files gibt es hier: https://www.mikrocontroller.net/topic/369330#4166392 Allerdings müssen die Werte der Polynomstruktur anderweitig berechnet werden, und mit einem Editor manuell in diese Form gebracht werden.&lt;br /&gt;
* Wie erstelle ich koplanare Leitungen in KiCad?&lt;br /&gt;
** siehe diese Diskussion: https://www.mikrocontroller.net/topic/370700#new&lt;br /&gt;
* Ich möchte Bauteile im Kreis oder in einem Gittermuster/Array anordnen. Gibt es dafür automatische Hilfestellungen?&lt;br /&gt;
** Ja. Objekt Deiner Wahl rechts anklicken, eventuell Auswahl verfeinern, und dann im aufpoppenden Menue &amp;quot;Array erstellen&amp;quot; wählen. Geht nicht nur für Bauteile, sondern auch für Pads, Leiterbahnen ec. Siehe: http://www.mikrocontroller.net/topic/178816#new&lt;br /&gt;
&lt;br /&gt;
=== Layout: Python Scripting ===&lt;br /&gt;
&lt;br /&gt;
Das Python2-Scripting ist bisher nur in PCBnew implementiert und noch sehr experimentell. Daher ist leider auch der aktuelle Stand der Dokumentation zum Python-Skripting in PCBnew noch etwas dürftig. Trozdem hier Links dazu:&lt;br /&gt;
* http://www.kicad-pcb.org/display/KICAD/KiCad+Scripting+Reference+Manual (Allgemein. Achtung! Kicad braucht beim compilieren spezielle Befehle, um Python-Scripting tauglich zu sein.)&lt;br /&gt;
* http://dev.kicad-pcb.org/doxygen-python/index.html (Definitionen von Namespaces, Classes und Files)&lt;br /&gt;
&lt;br /&gt;
Für Linux-Debian:&lt;br /&gt;
Aktuell (07. Februar 2014) mit  Pcbnew Version: (2014-01-27 BZR 4641)-product Release build auf&lt;br /&gt;
Platform: Linux 3.2.0-4-686-pae i686, 32 bit, Little endian, wxGTK (Debian Wheezy) gilt:&lt;br /&gt;
* Geht aktuell nur für PCBnew.&lt;br /&gt;
* Klassenbibliotheken: Zwei Dateien pcbnew.py und _pcbnew.so auf dem Pfad: /usr/lib/python2.7/dist-packages/&lt;br /&gt;
* Die Klassenbibliothek wird mit den üblichen Python2 Methoden importiert: z.B. &amp;quot;import pcbnew&amp;quot; oder &amp;quot;from pcbnew import *&amp;quot; &lt;br /&gt;
&lt;br /&gt;
Beispielprogramm, das alle Footprints aus einer Legacy-Fotprint Datei auflisted und den Referenzbezeichner dazuschreibt::&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python &lt;br /&gt;
# das war das Shebang.&lt;br /&gt;
&lt;br /&gt;
from pcbnew import * # Import der Bibliothek. &lt;br /&gt;
libpath = &amp;quot;/home/DuUser/KiCad-Daten/Module/ModuleGrosserSampler/KiCadLegacyFottprints.mod&amp;quot; # Übergabe des Pfades.&lt;br /&gt;
lst = FootprintEnumerate(libpath) &lt;br /&gt;
for name in lst:&lt;br /&gt;
    m = FootprintLoad(libpath,name)&lt;br /&gt;
    print name,&amp;quot;-&amp;gt;&amp;quot;, m.GetReference()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Scripting Möglichkeit ist so neu, dass bis jetzt die Scripting Testdateien für das KiCAD interne automatische Qualitätssicherungssystem noch nicht komplett sind.&lt;br /&gt;
Unter http://bazaar.launchpad.net/~kicad-product-committers/kicad/product/files/head:/qa/testcases/ finden sich bereits geprüfte Testskripte, und unter http://bazaar.launchpad.net/~kicad-product-committers/kicad/product/files/head:/pcbnew/scripting/examples/ finden sich ungetestete Testskripte.&lt;br /&gt;
&lt;br /&gt;
Sie alle können als Beispiele genommen werden, wie das mit dem Skripting gemeint ist, und als Vorbild für eigene Skripte dienen.&lt;br /&gt;
&lt;br /&gt;
=== Module Editor ===&lt;br /&gt;
* Wie erstellt man Footprints für Bauteile?&lt;br /&gt;
** Mit dem Footprint Editor. Er ist bei älteren KiCad Versionen nur aus PCBnew heraus zu starten. Bei neueren KiCad Versionen hat er einen eigenen Button im KiCad Start Window.&lt;br /&gt;
** Spezielleres: http://www.mikrocontroller.net/topic/356151#new&lt;br /&gt;
* Wie verbinde kopiere ich etwas aus einem Footprint in einen anderen hinein, bzw. wie verbinde/merge ich zwei Footprints?&lt;br /&gt;
** http://www.mikrocontroller.net/topic/288167#3061997&lt;br /&gt;
* Kann man im Module Editor die Eigenschaften aller Pads gleichzeitig ändern?&lt;br /&gt;
** http://www.mikrocontroller.net/topic/93131#799550 &lt;br /&gt;
* Ich brauche einen Footprint, bei dem mehrere Pads verbunden sind, will aber nicht im Schaltplan zig Pins aufführen und anschliessen müssen.&lt;br /&gt;
**http://www.mikrocontroller.net/topic/208982#new&lt;br /&gt;
**http://www.mikrocontroller.net/topic/204717#new&lt;br /&gt;
* Wie erzeugt man thermal Vias in Kicad?&lt;br /&gt;
** Leider bisher nur experimentell: http://www.mikrocontroller.net/topic/298028#3187259&lt;br /&gt;
* Wie kann man Bauteilmaße in in den Ansichten (Footprint, Layout, 3D-View) anzeigen?&lt;br /&gt;
* Wie verwalte ich Footprint Bibliotheken?&lt;br /&gt;
** Indem man sich ein Board erstellt, alle Footprints, die man zusammenfassen möchte, auf das Board stellt, und dann untet Dateien &amp;gt; Footprints archivieren &amp;gt; Footprint Archiv erstellen wählt. Das so erstellte Board kann auch zu Dokumentationszwecken geplottet werden. Eventuell möchte man einige Footprints, die zu Hilfszwecken (z.B. Skalen) auf dem Board sind, anschliessend mit dem Bibliothekseditor daraus löschen.&lt;br /&gt;
** Alternativ, im dem &amp;quot;neuen&amp;quot; *.pretty Format, mit einem Dateiverwaltungsprogramm Deiner Wahl. Siehe http://www.mikrocontroller.net/topic/320301#new&lt;br /&gt;
* Wie werden die Parameter für Lötpaste/Lötstopmaske vergeben?&lt;br /&gt;
**http://www.mikrocontroller.net/topic/356151&lt;br /&gt;
* Ich möchte für einen Footprint Pads in einem Gittermuster/Array oder im Kreis anordnen. Gibt es dafür automatische Hilfestellungen?&lt;br /&gt;
** Ja. Pad rechts anklicken. Eventuell erfolgt noch eine Feinauswahl. Dann im aufpoppenden Menue &amp;quot;Array erstellen&amp;quot; wählen.&lt;br /&gt;
&lt;br /&gt;
=== 3D-Ansicht ===&lt;br /&gt;
* Die 3D-Ansicht funktioniert bei mir nicht.&lt;br /&gt;
** http://www.mikrocontroller.net/topic/289075#new&lt;br /&gt;
* Kann man die 3D-Ansicht in ein 3D-CAD Programm exportieren? &lt;br /&gt;
**http://www.mikrocontroller.net/topic/203388#new&lt;br /&gt;
* Wie kann man Bauteilmaße in in den Ansichten (Footprint, Layout, 3D-View) anzeigen?&lt;br /&gt;
&lt;br /&gt;
Da KiCAD in Punkto 3D-Ansicht komplett auf Wings3D beruht, und die 3D Modelle der Bauteile wrl-files sind, die mit Wings3D (oder Blender) erstellt werden können, sei hier auf ein Wings3D Handbuch verwiesen: http://www.oortman3d.com/wings3d/TheWings3dHandbook.pdf&lt;br /&gt;
&lt;br /&gt;
Viele Bauteilhersteller (vor allem von eher mechanischen, wie z.B. Stecker, Buchsen, Befestigung...) bieten fertige 3D-Modelle an. Diese sind meistens in den Formaten STEP oder IGES. So kann man diese in das von KiCAD benötigte .wrl (VRML 2.0) konvertieren:&lt;br /&gt;
# STEP oder IGES in [http://gcad3d.org/ gCAD3D] öffnen (File &amp;gt; Open Model)&lt;br /&gt;
# als Wavefront .obj speichern (File &amp;gt; Save Model as &amp;gt; OBJ)&lt;br /&gt;
# Das .obj in [http://www.wings3d.com/ Wings 3D] importieren (File &amp;gt; Import &amp;gt; Wavefront .obj)&lt;br /&gt;
# Als VRML 2 exportieren (File &amp;gt; Export &amp;gt; VRML 2.0 .wrl)&lt;br /&gt;
# Im KiCAD-Moduleditor die .wrl-Datei als 3D-Modell auswählen&lt;br /&gt;
# Eventuell muss man die Skalierung und Positionierung anpassen, die angezeigten Pads und Löcher helfen dabei. Die am meisten benötigten Faktoren dürften dabei 0,3937 und 2,54 sein - bei den Konvertierungen kommt leicht die Einheit Zoll oder cm durcheinander.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Eine andere Möglichkeit .obj oder .stl-Dateien aus STEP und IGES zu erzeugen ist [http://free-cad.sourceforge.net/ FreeCAD]. Obwohl es auch .wrl direkt erzeugen kann, können diese nicht in KiCAD geladen werden. Der Umweg über .obj oder .stl und Wings 3D löst dies aber auch hier.&lt;br /&gt;
&lt;br /&gt;
Wenn man das Board wieder in einem CAD-Programm verwenden will um z.B. ein Gehäuse zu konstruieren, sollte man wieder STEP-Dateien erzeugen. Neuere KiCAD-Versionen können zwar VRML exportieren, doch das beschreibt nur Umrisse und keine Körper (Solids). CAD-Programme zum Gehäusedesign brauchen jedoch letzteres. So geht die Konvertierung:&lt;br /&gt;
# VRML aus KiCAD exportieren (File &amp;gt; Export &amp;gt; VRML)&lt;br /&gt;
# .wrl-Datei mit Hilfe von [http://www.cs.princeton.edu/~min/meshconv/ meshconv] in eine STL-Datei konvertieren: &amp;lt;code&amp;gt;meshconv boardname.wrl -c stl -o boardname.stl&amp;lt;/code&amp;gt;&lt;br /&gt;
# Die STL-Datei mit [http://www.solveering.com/products/products_stl2step.html stl2step] in eine STEP-Datei konvertieren&lt;br /&gt;
&lt;br /&gt;
Man sollte hinterher im CAD nochmal genau die Maße kontrollieren. Denn die Konvertierung von STL nach STEP ist nur eine Approximierung und keine exakte, verlustfreie Konvertierung.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Und wie bedient man Wings3d?&lt;br /&gt;
** Ein (vorläufiger) Merkzettel/Ultrakurzanleitung zur Bedienung von Wings3D findet sich hier: [[Media:Kicad-Wings3D_Merkzettel_29November2012.pdf]]. Wenn man nur mit Wings3d Modelle für Kicad erstellen will, langt das eventuell schon als Tutorial. There is also an English translation of this leaflet about using wings3d for kicad  at [[Media:Kicad-Wings3D_Leaflet_25April2013.pdf]].&lt;br /&gt;
&lt;br /&gt;
=== Drucken/Plotten/Gerber Export/Excellon Drillfiles Export ===&lt;br /&gt;
&lt;br /&gt;
==== Drucken ====&lt;br /&gt;
* Wie exportiert man den Schaltplan oder das Layout als Bild (PNG o.ä.)? &lt;br /&gt;
** Drucken über Postscript-Treiber und Umwandeln mit Ghostscript&lt;br /&gt;
** [http://www.mikrocontroller.net/topic/96060#1061492]&lt;br /&gt;
** Plot to Clipboard [http://www.mikrocontroller.net/topic/117562#1056566]&lt;br /&gt;
* Wie kann ich GENAU ausdrucken? Mein Ausdruck auf ABC ist ca. X % zu klein oder Y% zu groß! &lt;br /&gt;
** So genau sind einfache Drucker bzw. Druckertreiber selten. Aber meistens hilft folgendes: Mache einen 1:1 (100%) Probeausdruck. Messe auf dem Ausdruck nach, wie groß er tatsächlich geworden ist. Berechne die Abweichung und gebe sie in den Drucker bzw. Druckertreiber unter Einstellung ein, vorausgesetzt, der Drucker bzw. Druckertreiber kann das. Mit dem Wert machst Du wieder eine Probeausdruck, messe wieder nach, und wenn es mit der Einstellung funktioniert hat, kannst Du Deine Folie bedrucken. Wenn das nicht klappen kann, weil Du stark abweichende Werte für horizontal und vertikal bräuchtest, aber der Drucker nur einen gleichen Wert für beides kennt, hast Du einen (zu) schlechten Drucker. Trozdem nicht verzweifeln, weil KiCAD beim Drucken oder Plotten in der X- und Y-Achse getrennt skalieren kann. Aber Vorsicht bei Weitergabe der so erzeugten Dateien: Sie sind individuell auf einen Drucker angepasst, und produzieren auf einem anderen Drucker nur falsch skalierte Ausdrucke. Weil der Wert von Drucker zu Drucker unterschiedlich ist, ist es auch sinnvoll, diese Skalierung direkt am speziellen Drucker/Druckertreiber zu machen. Tipp: Wenn Du den Wert erfolgreich ermittelt hast, so kleb Dir einen Zettel auf den Drucker mit dem Wert. Die Werte sind zwar individuell für jeden Drucker, aber meistens für den speziellen Drucker durchaus fix. Und Du hast ihn sofort wieder parat, wenn der Drucker resettet wurde. Dies ist übrigens ein allgemeiner Tipp für das Ausdrucken, der auch für Eagle, Target, Altium usw. gilt.&lt;br /&gt;
** Thema Skalieren - Die aktuelle Situation (August 2013): http://www.mikrocontroller.net/topic/304619#new &lt;br /&gt;
** Und nochmal Thema Skalieren: http://www.mikrocontroller.net/topic/371079#4191106&lt;br /&gt;
* Wie kann man das Layout invers ausdrucken, d.h. alle Leiterbahnen und Pads müssen weiß bleiben, der Rest wird schwarz ausgedruckt?&lt;br /&gt;
** Beim Plotten den Haken bei Negativ-Plot setzen [http://www.mikrocontroller.net/topic/156202#1474507]&lt;br /&gt;
* Ich habe irgendwie Probleme mit dem Ausdrucken.&lt;br /&gt;
** Verzerrt: http://www.mikrocontroller.net/topic/207764#new&lt;br /&gt;
** Sonderzeichen: http://www.mikrocontroller.net/topic/207310#new&lt;br /&gt;
** In der aktuellen Version 2012-01-19 BZR 3256)-stable besteht ein generelles Druckproblem. Aber Plotten geht wunderbar!&lt;br /&gt;
** Aktualisierter Stand 23. Dezember 2012: http://www.mikrocontroller.net/topic/280958#new&lt;br /&gt;
** Aktualisierter Stand vom 21. Juli 2013: http://www.mikrocontroller.net/topic/303043#3249166&lt;br /&gt;
&lt;br /&gt;
* Ich würde gerne PDF Dateien aus meinem Layout erstellen, aber irgendwie ist der Ausdruck defekt.&lt;br /&gt;
** Drucken ist aus Kicad manchmal ein Problem, auch in eine Datei hinein. Aber Plotten und Exportieren in SVG funktioniert gut. Von SVG zu PDF kommt man über Inkscape. Siehe hier: http://www.mikrocontroller.net/topic/303043#3249166&lt;br /&gt;
* Wie kann ich mir einen Bohrplan ausdrucken, um mit der Hand zu bohren?&lt;br /&gt;
**http://www.mikrocontroller.net/topic/266037#new&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== SVG Plotten ====&lt;br /&gt;
&lt;br /&gt;
* Meine erzeugten SVG Plots sind kaputt. Ich erhalte nur Fehlermeldungen, wenn ich sie in Inkscape oder Gimp einlesen will.&lt;br /&gt;
** Es besteht ein Problem mit dem SVG Export, wenn man Schaltpläne oder Boards in SVG exportiert, die ein Ampersand (Kaufmansund, &amp;quot;&amp;amp;&amp;quot;) im Dateinamen haben. Dieser Dateiname tauch dann innerhalb der SVG Datei in einem Titelblock auf, wo das &amp;quot;&amp;amp;&amp;quot; dann ein Problem bedeutet (Es leitet eine Art Escape-Sequenz ein). Sowohl Kicad als auch Inkscape/Gimp aktzeptieren &amp;quot;&amp;amp;&amp;quot; im Dateinamen, und sowol unter Windows als auch Linux ist das &amp;quot;&amp;amp;&amp;quot; im Dateinamen legal....darum bringt auch eine Veränderung des Namens der SVG-Datei keine Lösung. Eine Lösung ist, Grundsätzlich in Kicad keine &amp;quot;&amp;amp;&amp;quot; in Dateinamen zu verwenden, wenn man einen SVG-Export macht. Alternativ kann man mit einem Editor das &amp;quot;&amp;amp;&amp;quot; aus dem Titelblock (Das ist NICHT der Dateiname, sondern in der Datei selber alles zwischen &amp;lt;titel&amp;gt; und &amp;lt;/titel&amp;gt;) der SVG-Datei löschen. Angeblich kommt der Bug aus den verwendeten wx-Bibliotheken. Siehe den Bugreport: https://bugs.launchpad.net/kicad/+bug/1171160&lt;br /&gt;
&lt;br /&gt;
==== Gerber Export ====&lt;br /&gt;
&lt;br /&gt;
* Kann man Gerber-Dateien exportieren?&lt;br /&gt;
** Ja. Es wird extended Gerber 247X exportiert. Einheit ist inch (doppelt sowohl im 247d als auch im 247x Stil definiert). Die Y-Koordinaten sind im allgemeinen negativ. KiCAD verwendet für Flächen das in Gerber spezifizierte Polygon Makro und kein &amp;quot;stroke fill&amp;quot;.&lt;br /&gt;
** Um Gerber Dateien zu erstellen, wählt man aus der oberen Menueleiste ganz links Datei &amp;gt; Plotten und dann oben links unter Plotformat &amp;quot;Gerber&amp;quot; &lt;br /&gt;
** KiCad unterstützt auch die kürzlich eingeführten Gerber-Attribute. Die Anwendung derselben muss aber explizit angewählt werden. Dazu setzt man im Gerber-Plottmenue im Feld &amp;quot;Gerber Optionen&amp;quot; bei &amp;quot;include extended attributes&amp;quot; einen Haken.&lt;br /&gt;
** KiCad kann automatisch die Lötstoppmaske von der Siebdruckmaske (Silk screen - Bestückungsaufdruck) abziehen, damit nicht der Bestückungsaufdruck versehentlich über Pads liegt und dort das Löten verhindert. Dazu muss aber im Gerber-Plottmenue im Feld &amp;quot;Gerber Optionen&amp;quot; bei &amp;quot;Subtrahiere Lötstoppmaske von Siebdruckmaske&amp;quot; ein Haken gesetzt werden.&lt;br /&gt;
* Wie kann man den Gerber-Plot so ausdrucken, dass in der Mitte von Pads und Vias ein Zentrierloch frei bleibt?&lt;br /&gt;
** http://article.gmane.org/gmane.comp.cad.kicad.user/3457&lt;br /&gt;
&lt;br /&gt;
==== Excellon Drillfiles exportieren ====&lt;br /&gt;
&lt;br /&gt;
* Wie erstelle ich mit KiCad Excellon Drillfiles?&lt;br /&gt;
**siehe hier: http://www.mikrocontroller.net/topic/310333#new&lt;br /&gt;
&lt;br /&gt;
==== KiCad Board Dateien direkt zum Hersteller ====&lt;br /&gt;
&lt;br /&gt;
* Bei Bestellungen bei PCB-Pool ist deren GC-Prevue NICHT mehr erforderlich, weil PCB-Pool mittlerweile KiCAD *,brd Dateien direkt aktzeptiert. Siehe http://www.pcb-pool.com/ppde/info_dataformat.html Das gilt auch für viele andere Hersteller. im Zweifel dort einmal nachfragen.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Trotzdem&#039;&#039;&#039; sollte man &#039;&#039;&#039;besser Gerber Dateien&#039;&#039;&#039; zum Platinenhersteller senden. Das gilt &#039;&#039;&#039;grundsätzlich&#039;&#039;&#039; so auch für andere Platinen Layout Programme. Der Grund ist hier angegeben: https://www.mikrocontroller.net/wikisoftware/index.php?title=Gerber-Tools&amp;amp;action=edit&amp;amp;section=8&lt;br /&gt;
&lt;br /&gt;
=== Import ===&lt;br /&gt;
* Kann man EAGLE Dateien importieren? (=&amp;gt; Obacht bei Weitergabe der Daten!)&lt;br /&gt;
** http://www.mikrocontroller.net/topic/70905#797416&lt;br /&gt;
** http://www.mikrocontroller.net/topic/120373#1089933&lt;br /&gt;
** Aktuell: http://www.mikrocontroller.net/articles/KiCAD#Konverter&lt;br /&gt;
* Wie bindet man fremde KiCAD Bibliotheken ein?&lt;br /&gt;
** EESchema (Schaltplaneditor) starten, unter Einstellungen &amp;quot;Bibliothek&amp;quot;  auswählen, auf &amp;quot;Hinzufügen&amp;quot; klicken, neue Bibliothek auswählen dann &amp;quot;öffnen&amp;quot; und in der Projektdatei &amp;quot;Speichern&amp;quot;. Gültig für Version 20090216Final, 2011-04-29-BZR2986-WinXP und Version: (2011-11-27 BZR 3249)-stable unter Platform: Linux 2.6.32-5-686 i686, 32 bit, Little endian, wxGTK.&lt;br /&gt;
&lt;br /&gt;
** VERALTET! Das Verfahren zur Einbindung eigener oder fremder Bibliotheken ist under PCBnew genauso.&lt;br /&gt;
** Aktuell: Siehe http://www.mikrocontroller.net/topic/356855#3988114&lt;br /&gt;
Es empfielt sich dringenst, eigene Bibliotheken NICHT zu den KiCAD Bibliotheken im Ordner kicad/share/library bzw. kicad/share/modules für Footprints zu speichern, weil diese dort bei einem Upgrade gelöscht würden. Stattdessen sollte man sich einen kicad Ordner im eigenen home bzw. Benutzerverzeichnis (oder sonstwo, wo es opportun ist, und man Schreibrechte hat) anlegen, mit einem Ort, um eigene Bibliotheken abzulegen.&lt;br /&gt;
&lt;br /&gt;
=== Neues Projekt ===&lt;br /&gt;
Ein neues Projekt legt kicad automatisch nach der in kicad/share/template hinterlegten Projektdatei an. Möchte man, das kicad ein neues Projekt von vorneherein nur mit ausgewählten eigenen Bibliotheken anlegt, so ist eine entsprechende Projektdatei unter kicad/share/template/kicad.pro abzulegen.&lt;br /&gt;
Dies erfordert dort Schreibrechte. Linux roots müssen diese Datei anschliessend mit chmod 755 Dateiname für user lesbar machen.&lt;br /&gt;
Bei einem upgrade würde kicad.pro gelöscht. Daher sollte man sich davon eine Sicherheitskopie in seinem benutzerverzeichnis hinterlegen.&lt;br /&gt;
&lt;br /&gt;
=== Einstellungen sichern / wiederherstellen===&lt;br /&gt;
* Wo speichert KiCAD die Einstellungen ab und wie lassen sich die originalen Einstellungen wiederherstellen?&lt;br /&gt;
** [[http://kicad.sourceforge.net/wiki/index.php/DE:KiCadHB#Einstellungen_sichern_.2F_wiederherstellen]]&lt;br /&gt;
**Man erstelle ein neues Projekt beliebigen Namens, nehme alle Einstellungen (Bibliotheken, Pfade usw.) vor und speichere diese in der aktuellen Projektdatei &amp;quot;name.pro&amp;quot;. Im Ordner KiCAD Verzeichnis ....../kicad/share/template befindet sich eine Datei &amp;quot;kicad.pro&amp;quot;. Diese Datei &amp;quot;kicad.pro&amp;quot; ist die &amp;quot;Musterprojektdatei&amp;quot;, die für alle neuen Projekte verwendet wird. Man benenne sie um in &amp;quot;kicad-orig.pro, und kopiere die aktuelle Projektdatei &amp;quot;name.pro&amp;quot; nun als &amp;quot;kicad.pro&amp;quot; in diesen Template-Ordner. Leider Funktioniert dieses Verfahren nicht in allen KiCAD Versionen. Den originalen Zustand stellt man wieder her, indem man &amp;quot;kicad.pro&amp;quot; umbenennt, und &amp;quot;kicad-org.pro&amp;quot; wieder in &amp;quot;kicad.pro&amp;quot; zurückumbenennt.&lt;br /&gt;
&lt;br /&gt;
=== Bitmaps als Symbol oder Footprint importieren ===&lt;br /&gt;
Der Programmteil Bitmap2component wandelt Bitmaps wahlweise in Symbole oder in Footprints um. Auf diese Weise können also auch Logos oder spezielle Muster für HF-anwendungen in KiCAD importiert werden, sobald sie als Bitmap vorliegen. Diese Funktion ist allerdings sehr neu (im Frühjahr 2011 eingefügt) und eher als experimentell zu bezeichnen. So funktioniert z.B. der Export in ein Symbol in der Version BZR-2986 NICHT.&lt;br /&gt;
&lt;br /&gt;
== Tipps&amp;amp;Tricks / Eigenheiten / Bugs ==&lt;br /&gt;
&lt;br /&gt;
* Nachbearbeitung mit Skript oder Texteditor (Pin Swapping, Versionskontrolle via SVN, Generierung von Packages aus UCF-Listen) &lt;br /&gt;
** http://www.mikrocontroller.net/topic/120373#1100467&lt;br /&gt;
** http://www.mikrocontroller.net/topic/96860#836967&lt;br /&gt;
** http://stawoo.com/dokuwiki/doku.php?id=ecld:kicad:board&lt;br /&gt;
&lt;br /&gt;
* Veraltet! (2006) Schaltplan: Durchnummerieren von GND und PWR erforderlich http://www.mikrocontroller.net/topic/39243#290309&lt;br /&gt;
&lt;br /&gt;
* Zum Verbinden von Schaltplan und Layout müssen an den Bauteilen die Pinnummern mit den Padnummern der Footprints korrespondieren. Das ist &amp;quot;defaultmäßig&amp;quot; nicht immer zu erreichen, weil es unterschiedliche Nummerierungssysteme gibt. Ausser dem Anlegen eines speziellen Footprints kann diese Anpassung für einzelne Bauteile wärend des Layoutens im Moduleditor vorgenommen werden. http://www.mikrocontroller.net/topic/186121#1805890&lt;br /&gt;
* Ich habe einen hierarchischen Schaltplan angefertigt, indem sich eine Schaltung zig mal wiederholt. Eine dieser Subschaltungen habe ich schon geroutet, und möchte dieses Layout genau wie die hierarchischen Schaltpläne mehrfach auf dem Board verwenden.&lt;br /&gt;
** In PCBnew lassen sich mit &amp;quot;Datei&amp;gt;Platine hinzufügen&amp;quot; auch schon geroutete Gruppen von Bauteilen quasi als Modul einfügen, wenn sie zuvor als Board abgelegt wurden. Ebenso kann eine Bauteilgruppe, die in der Form mehrmals vorkommt, und die die schon einmal geroutet worden ist, gruppiert, kopiert und wiederverwended werden. Die dazu nötige Annotation und das Löschen der überzähligen Bauteile muss aber sorgfältig von Hand gemacht werden. &#039;&#039;&#039;Anmerkung:&#039;&#039;&#039; In neueren Versionen von PCBnew ist diese Funktion ausgegraut, wenn PCBnew &amp;quot;normal&amp;quot; aus dem Menue des KiCad Hauptfensters gestartet wurde. Um diese Funktion zu aktivieren, KiCad schliessen und PCBnew wie ein alleinstehendes Program direkt starten.&lt;br /&gt;
** Wer seinen Subschaltplan separat routen möchte, sollte den Subschaltplan explizit in EEschema öffnen und die Netliste nur dieses Subschaltplanes exportieren. Diese Netlist in ein neues Board in PCBnew einlesen und wie üblich routen.&lt;br /&gt;
* Bibliotheken verwalten, umsortieren bzw. neu strukturieren: http://www.mikrocontroller.net/topic/187107#1817559 &lt;br /&gt;
&lt;br /&gt;
* Layout: Rest-Gummiband an Pins http://www.mikrocontroller.net/topic/120373#1092375&lt;br /&gt;
&lt;br /&gt;
* Produktion: http://www.mikrocontroller.net/topic/98034#848965&lt;br /&gt;
&lt;br /&gt;
* Bug in Version 2010-03-14: Unter Einstellungen lässt sich keine einseitige Platine wählen (wichtig für Autorouter). Lösung: Modifikation des .brd Files mit einem Editor [http://www.mikrocontroller.net/topic/172015#1651239]:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;pre&amp;gt;&lt;br /&gt;
:In der *.brd Datei gleich ganz oben...&lt;br /&gt;
:&lt;br /&gt;
:$GENERAL&lt;br /&gt;
:LayerCount 2                 -&amp;gt; auf 1 setzen&lt;br /&gt;
:&lt;br /&gt;
:$SETUP&lt;br /&gt;
:InternalUnit 0.000100 INCH&lt;br /&gt;
:ZoneGridSize 250&lt;br /&gt;
:Layers 2                     -&amp;gt; auf 1 setzen&lt;br /&gt;
:Layer[0] Rückseite power&lt;br /&gt;
:Layer[15] Vorderseite power  -&amp;gt; hab&#039; ich mal beides so gelassen&lt;br /&gt;
:&amp;lt;/pre&amp;gt;                                                                aktueller: http://www.mikrocontroller.net/topic/172015#1794699&lt;br /&gt;
&lt;br /&gt;
* Das Anlegen von Symbolen/Bauteilen in aufgelöster Darstellung ist etwas stolperig. Siehe: http://www.mikrocontroller.net/topic/294095#3136180&lt;br /&gt;
&lt;br /&gt;
* Es empfielt sich, in Kicad vorläufig KEIN Ampersand (Kaufmansund, &amp;quot;&amp;amp;&amp;quot;) im Namen einer Schaltplan- oder Boarddatei zu Verwenden. Es besteht ein Bug beim Export/Plotten nach SVG. Siehe oben unter &amp;quot;Drucken / Export&amp;quot; und dann &amp;quot;Meine erzeugten SVG Plots sind kaputt.&amp;quot;. Siehe auch: http://tech.groups.yahoo.com/group/kicad-users/message/14952&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Kühlkörper&#039;&#039;&#039; können als Symbol und Footprint (Modul) angelegt werden. Die Befestigungslöcher können im  Modul als Pad ausgeführt werden. Die Padnummer aller Pads sollte gleich sein (gleicher Anschluss / über Kühlkörper verbunden), z.B. &amp;quot;1&amp;quot;. Entsprechend ein Symbol mit Pin und korrespondierender Pinnummer anlegen. Wenn der Kühlkörper elektrisch nirgendwo verbunden sein soll, dann die Anschlusspinne im Schaltplan als &amp;quot;unused&amp;quot; markieren. Als Referenz in Symbol und Footprint habe ich &amp;quot;HS&amp;quot; (HeatSink) gewählt. Es ist zu überlegen, ob &amp;quot;HS&amp;quot; nicht auch als Padnummer besser wäre.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Kartenumrisse/Outlines&#039;&#039;&#039;: Für immer wiederkehrende Platinengrössen, z.B. die beliebte Eurokarte, kann zur Vereinfachung des Zeichnens einmal ein Eurokartenumriss im Layer &amp;quot;outlines&amp;quot; gezeichnet werden, und als Modul abgelegt werden. Um die Zahl der Kollisionen beim Einlesen der Netzliste zu verringern, wird im Schaltplan ein Dummy-Symbol ohne Pinne angelegt. In CVpcb dann dieses Symbol mit dem passenden Kartenumriss Footprint/Modul verbinden, und es wird automatisch in PCBnew eingefügt. Als Referenz in Symbol und Footprint habe ich &amp;quot;Outl&amp;quot; (OUTLine) gewählt.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Sprachanpassung&#039;&#039;&#039;: Ich will mein KiCAD auf Deutsch / Englisch / Französisch / Finnisch oder sonst eine Sprache umstellen. Wie geht das?&lt;br /&gt;
** Siehe : http://www.mikrocontroller.net/topic/262039#2719056&lt;br /&gt;
**Die deutsche Übersetzung der Texte und Hilfetexte/Tooltips ist manchmal etwas unelegant. Wem so etwas auffält, bitte Mitteilung am Ende dieses Threads: http://www.mikrocontroller.net/topic/255932#2641638 (deutschsprachig) oder an die KiCAD user group unter https://groups.yahoo.com/neo/groups/kicad-users/info (englischsprachig, auch bei Fällen wo es um die deutsche Übersetzung geht). Diese Mitteilungen nach Möglichkeit nicht in Launchpad.&lt;br /&gt;
** Ich habe aber keine Möglichkeit, die Sprache umzustellen!&lt;br /&gt;
*** Wenn Debian eine Fehlermeldung &amp;quot;Cannot set locale to &#039;xy_XY&#039;. kommt, ist die entsprechende Umgebung nicht installiert. Unter Debian als root in der Konsole: &amp;quot;dpkg-reconfigure locales&amp;quot; aufrufen. Es öffnet sich eine ncurses-gui, wo die entsprechenden Einstellungen gemacht werden können. Für &amp;quot;Deutsch&amp;quot; wähle ich &amp;quot;de_DE.utf8&amp;quot;.&lt;br /&gt;
*** Wenn nichts passiert, fehlen möglicherweise die localisierungs Dateien. Sie sind NICHT Teil der Sourcen, und finden sich in http://bazaar.launchpad.net/~kicad-developers/kicad/doc/files/head:/internat/. Auf Debian und verwandten Systemen müssen die einzelnen localisationsordner, z. B. &amp;quot;de&amp;quot; nach /usr/local/share/kicad/internat kopiert werden. Dann als root dort Leserechte erteilen mit &amp;quot;chmode -R 755 /usr/local/share/kicad/internat&amp;quot;.&lt;br /&gt;
*** Wenn ein Mischmasch aus Englisch und der gewählten Sprache existiert, sind entweder nicht alle Begriffe übersetzt (siehe oben) oder wegen Umbenennung von Variablen ist eine Inkonsistenz entstanden. Siehe: http://www.mikrocontroller.net/topic/326622#3565178&lt;br /&gt;
** Für die KiCad Localsisation wird &amp;quot;GNU gettext&amp;quot; verwendet. Eine kleine Hilfestellung zur Anpassung der Localisation findet sich hier: http://dev.kicad-pcb.org/docs/GUI_Translation_HOWTO.pdf. Info zu Gnu gettext findet sich hier: http://de.wikipedia.org/wiki/GNU_gettext&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Projektdateien (.pro) Pfadschreibweise&#039;&#039;&#039;: In einer Windowsumgebung ist es anscheinend nötig, relative Pfade speziell zu kennzeichnen. Siehe: http://www.mikrocontroller.net/topic/326869#new&lt;br /&gt;
&lt;br /&gt;
=== Problem: Der Ursprung für die Pic und Place bzw. Drill-Daten wurde verändert und lässt sich nicht zurücksetzten. === &lt;br /&gt;
Siehe: http://www.mikrocontroller.net/topic/363280#new&lt;br /&gt;
&lt;br /&gt;
=== Problem: Case Senitive Symbols ab BZR4646 (Jan./Feb. 2014) ===&lt;br /&gt;
Ab BZR4646 sind die Symbole in Eeschema &amp;quot;Case Sensitive&amp;quot;. Das bedeutet: In alten Schaltplandateien wurden für die Symbolnamen nur Großbuchstaben verwendet, auch wenn die Originalnamen in der Library Kleinbuchstaben enthielten. Ab BZR4646 werden die Symbolnamen in den Schaltplandateien genauso geschrieben wie die Originalnamen in der Library. Leider werden dadurch bei alten Schaltplandateien die großgeschriebenen Symbolnamen nicht mehr in den Bibliotheksdateien erkannt. Auch nicht in den &amp;quot;-cache.lib&amp;quot; Dateien. Ganz so kritisch, wie es sich anhört, ist es wiederum auch nicht, weil KiCad schon seit geraumer Zeit die Schaltpläne in der neuen Version speichert. Jemand, der mit aktuellen KiCad Versionen an aktuellen Schaltplänen arbeitet, wird darum den Übergang vermutlich nicht bemerken. Allerdings tritt das Problem bei alten Schaltplänen auf, die möglicherweise Jahrelang unberührt auf der Festplatte lagen. Um die Symbolnamen in diesen alten Schaltplandateien anzupassen, existiert das Python3 Skript &amp;quot;PyKiCad-CaseSensitiveLibCure_RevD_13Apr2015.zip&amp;quot;. Es ist ein &amp;quot;Stand alone&amp;quot; Python3 skript, das nicht in das KiCad interne Python skripting eingebunden ist. Die Datei kann hier bezogen werden:[[Media:PyKiCad-CaseSensitiveLibCure_RevD_13Apr2015.zip]].&lt;br /&gt;
Autor: Bernd Wiebus, GNU-GPL.&lt;br /&gt;
&lt;br /&gt;
Be einigen Linux Distributionen wird neben Python 3 auch noch das Paket &amp;quot;python3-tk&amp;quot; benötigt.&lt;br /&gt;
Sonst gibt es die Fehlermeldung &amp;quot;ImportError: No module named tkinter&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Manueller Start mit: &amp;quot;python3 PyKiCad-CaseSensitiveLibCure_RevD_13Mar2015.py&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Dieses Skript kann benutzt werden, um Schaltpläne, die mit der Eeschema Version (2013-11-29 BZR 4513) von Ende 2013, die in Linux Repositorys (z.B. Debian 7 &amp;quot;Wheezy&amp;quot;) noch sehr verbreitet ist, auf aktuelle KiCad Versionen anzupassen.&lt;br /&gt;
&lt;br /&gt;
=== Problem: Backporting KiCad-Board Dateien (.kicad_pcb) von Version 5 auf Version 4. 2014/2015) ===&lt;br /&gt;
&lt;br /&gt;
Möchte man z.B mit einer KiCad/PCBnew Version BZR 4027 vom 22 Juni 2014, welche in vielen Repositorys noch weit verbreitet ist, eine Board-Datei ( .kicad_pcb), die mit einer neueren PCBnew Version erstellt wurde, z.B. einer BZR 5513 vom 14. März 2015 (die aktuell kompiliert wurde), öffnen, so stösst man auf Probleme. Aktuell die BZR 5513 verwendet für die Board Dateien Version 5, und die alte BZR 4027 verwendet dort die Version 4. Obwohl das Schema der Boarddateien fast gleich ist, enthält die Version 5 Elemente, die es zur Zeit der Version 4 noch nicht gab, und die darum zu Fehlermeldungen und zum Abbruch des Einlesens der Datei führen. Diese Neuerungen beziehen sich auf den Export von Gerberfiles mit Attributen sowie Platinenlagen, die es vorher noch nicht gab. Diese Fehler sind dank der einfachen, klarschriftlesbaren Filestruktur von KiCad sehr leicht mit einem Texteditor zu beheben. Eine Beschreibung, wie dieses manuell zu machen ist, finden Sie hier: [[Media:KiCad-PCBnewBoardDateienMigrierenVonVersion4Auf5.pdf]]&lt;br /&gt;
&lt;br /&gt;
=== Tipps&amp;amp;Tricks: Building Blocks ===&lt;br /&gt;
* Eine unfertige Dokumentation, wie man das hierarchische Schaltplansystem von KiCAD verwendet, um daraus schnell und rationell Schaltpläne mit vorgefertigten Schaltplänen (Building Blocks) nach dem Baukastensystem aufzubauen. Enthält auch ein Beispielprojekt. Beachte die Liesmich.txt Datei. [[Media:BuildingBlocksKiCAD-EXPERIMENTELL.zip]] Das File  KiCAD-HierarchischeSchaltplaene+buildingBlocksRevA_Vorlaeufig.pdf, enthält eine vorläufige Beschreibung dazu. KiCAD-HierarchischeSchaltplaene+buildingBlocksRevA-EN.pdf is an English description how to use hirarchical schematics as building blocks for a fast and rationel schematic design. Es fehlt noch die Übersetzung und die Bebilderung und ein paar Berichtigungen und Ergänzungen. ;-) . Das echte Hauptbeispielprojekt ist UnderVoltageDetector24V-2Group_Experimental.pro bzw. UnderVoltageDetector24V-2Group_Experimental.sch. Im Ordner Experimentalprojekt23052010 findet sich ein weiterer Ordner BuildingBlocksExperimental. Dieser enthält die Ausgangsbausteine VoltageRegulatorBuildingBlock.sch mit VoltageRegulatorBuildingBlock-cache.lib und  VoltageDetectorBuildingBlock.sch mit VoltageDetectorBuildingBlock-cache.lib. Die Projektdateien der Buildingblocks .pro sind nur der Vollständigkeit und zur leichteren Bearbeitung zugefügt. Aus VoltageDetectorBuildingBlock.sch und VoltageRegulatorBuildingBlock.sch wurde (nach umkopieren, umbenenen und kleiner Änderung) im übergeordneten Ordner das Projekt VoltageRegulatorBuildingBlock.pro unter verwendung des &amp;quot;Zwischenbuildingblocks&amp;quot; UnderVoltageDetectorBuildingBlock.sch zusammengesetzt. NICHT VERGESSEN DIE CACHE.LIB EINZUBINDEN! Sonst gibt es nur Fragezeichen statt Bauteile. Das Beispielprojekt enthält eine 24V Unterspannungsüberwachung für einen Bleiakku, die zwei 12V Gruppen überwacht. Nicht elegant, aber hoffentlich robust. Autor: Bernd Wiebus , GNU-GPL. Der dazubezügliche Beitrag im Forum ist: http://www.mikrocontroller.net/topic/178683#1724114&lt;br /&gt;
*[[Media:HierarchischeSchaltplaeneAlsBausteineInKicad_RevC_23Dec2013.pdf]] VERBESSERTE und AKTUALISIERTE Version von KiCAD-HierarchischeSchaltplaene+buildingBlocksRevA_Vorlaeufig.pdf aus obiger Zip-Datei. Beschreibt, wie mit Hilfe der hierarchischen Schaltplanstruktur aus einzelnen, vorgefertigten Schaltplänen schnell und rationell neue Schaltpläne modular zusammengesetzt werden können. There is also a English translation of this tutorial about using hierarchical schematics as building blocks. You can get it here: [[Media:HierarchicalSchematicsAsBuildingblocksAtKiCad_RevC-EN_06May2015.pdf]]&lt;br /&gt;
* Eine Sammlung von gängigen Schaltungen mit den Längstreglern LM317 /LM78xx /LM79xx und dem Timer 555, die nach dem in obig erwänten Dokument KiCAD_HierarchischeSchaltplaene+buildingBlocksRevA_Vorlaeufig.pdf beschriebenen Vorgehen als Building Blocks in KiCAD verwendet werden können, findet sich unter: http://www.mikrocontroller.net/articles/KiCAD#Building-Blocks&lt;br /&gt;
&lt;br /&gt;
=== Tipps&amp;amp;Tricks: Lochraster Platinen Entwurf mit KiCad ===&lt;br /&gt;
&lt;br /&gt;
Wer viel mit Lochraster Platinen arbeitet, hat gelegentlich auch ein Bedürfnis, diese Tätigkeit mit einem Layoutprogramm zu begleiten. Zum einen um den Platzbedarf besser abschätzen zu können, zum anderen, um dadurch auch eine schnelle und einfache Dokumentation auch für Lochrasterprojekte zu schaffen. Auch dazu kann KiCad verwendet werden.&lt;br /&gt;
* Vorgehensweise: Schaltplan in Eeschema erstellen wie üblich, Netzliste erzeugen, und in CVpcp die Bauteile zuordnen. In PCBnew dann das Raster einblenden und auf 2,54mm (100mil) stellen. Nun geben die Rasterpunkte die Position der Löcher der Lochrasterplatine vor. Nach dem Einlesen der Netzliste bei Lochraster mit Streifenleitungen am besten zweiseitig manuell routen. Auf der Unterseite der Richtung der Streifenleitung in Längstrichtung folgen (z.b. wagerecht). Auf der Oberseite die Brücken dazu quer legen (z.B. senkrecht). Zweipolige Bauteile immer senkrecht oder wagerecht positionieren. Dieses Verfahren geht grundsätzlich mit jedem Layoutprogramm, das ein Raster anzeigen kann.&lt;br /&gt;
** Wer eine Platine erstellen möchte, die nur teilweise ein Lochraster aufweist, dem sei diese Diskussion empfohlen: https://www.mikrocontroller.net/topic/369534#new&lt;br /&gt;
&lt;br /&gt;
=== Tipps&amp;amp;Tricks: KiCad und Freeroute ===&lt;br /&gt;
Leider ist die Freeroute Seite abgeschaltet. Grund:http://www.mikrocontroller.net/topic/337014#new Allerdings gibt es eine Möglichkeit, Freeroute selber zu installieren und zu nutzen: https://github.com/nikropht/FreeRouting und http://freerouting.net/index_de.php &lt;br /&gt;
*Freerouting einseitig bzw. für Lochraster verwenden: http://www.mikrocontroller.net/topic/363335#new&lt;br /&gt;
&lt;br /&gt;
=== Tipps&amp;amp;Tricks: KiCad und Specctra Autorouter ===&lt;br /&gt;
Es treten beim Export der Netzlisten/Designs Fehlermeldungen der Art: &amp;quot;IO_ERROR: Multiple components have identical reference IDs&amp;quot; auf, obwohl offensichtlich keine doppelten Referenzbezeichner vergeben wurden.&lt;br /&gt;
* Die &amp;quot;doppelten Referenzbezeichner&amp;quot; sind doch &amp;quot;irgendwie&amp;quot; versteckt vorhanden. Z.B. dadurch, das Bauteile nicht Referenziert oder Annotiert wurden. Im Zweifel die Files mit einem Texteditor danach durchsuchen, oder die Autoannotation über das Board laufen lassen. Siehe: https://www.mikrocontroller.net/topic/365185#new&lt;br /&gt;
&lt;br /&gt;
== Bibliotheken ==&lt;br /&gt;
&lt;br /&gt;
In diesem Abschnitt sollen unsere Arbeiten an Bibliotheken koordiniert werden. Dabei sollen alle Arbeiten unter der Creative Commons Lizenz stattfinden. Das heisst insbesondere, dass keine Arbeiten mit anderem Copyright unseren Bibliothekspool vergiften sollen z.&amp;amp;nbsp;B. durch unerwünschte Konvertierung von EAGLE-Bibliotheken.  &lt;br /&gt;
&lt;br /&gt;
Unsere Designziele sind:&lt;br /&gt;
* Frei benutzbar (Creative Commons Lizenz) &lt;br /&gt;
* Einheitlich (Richtlinien?)&lt;br /&gt;
** Vorschlag von Marko für Bohrungen und Pads siehe [http://www.mikrocontroller.net/topic/124070#1176177]&lt;br /&gt;
** Die Richtlinien, die die KiCad Librarys selber verwenden: [https://github.com/KiCad/kicad-library/blob/master/KiCad_Library_Convention.txt]&lt;br /&gt;
* Fehlerfrei (Nachkontrolle durch andere User)&lt;br /&gt;
&lt;br /&gt;
=== Wünsche ===&lt;br /&gt;
&lt;br /&gt;
Hier soll eine Strichliste geführt werden, welche neuen Bauteile gesucht sind bzw. welche oder besseren, genaueren Versionen benötigt werden. Bitte gebt an, was bei bestehenden Bauteilen problematisch ist.&lt;br /&gt;
&lt;br /&gt;
Bevor wir Bibliotheken erstellen, sollten auf jeden Fall einige Parameter - insbesondere für die Schaltplansymbole - festgelegt werden: Pinlänge, Pinabstand, Größe der Schriften, Konventionen bzw. Nummerierung (z.B. bei gepolten Bauteilen wie Dioden, Elkos usw.). Sonst entsteht Wildwuchs, weil jeder für sich anderes festlegt.&lt;br /&gt;
&lt;br /&gt;
* Stehende Layouts für 7805 und N-FETs: ||||&lt;br /&gt;
** Passt TO220_VERT ? Natürlich! Nur die Anschlussnumerierung muss ev. passend adaptiert werden. Ist unter &amp;quot;TO-220&amp;quot; in [[Media:KiCAD_Module_Footprints_3D_29Aug2014.zip]] enthalten. In allen Perversionen. Stehend, liegend, rumgedreht von der Rückseite usw....&lt;br /&gt;
* LPC21xx / LPC22xx / LPC23xx |&lt;br /&gt;
* EINE AVR ATmega-Bibliothek, wo ALLE Controller drin sind. |||||||&lt;br /&gt;
* AVR XMegas |&lt;br /&gt;
* AT90CAN128 / allgemein mehr AVRs (MEGA &amp;amp; TINY) ||||||&lt;br /&gt;
*Wegen der AVRs und ATMEGAs: Bitte hier http://www.kicadlib.org/Fichiers/Kerusey_Karyu_Atmel_Library.html mal schauen, und den Wunsch auf den Typ konkretisieren! Der Atmelzoo ist so verwirrend vielfältig.....&lt;br /&gt;
** Leider ist die dazugehörige Bibliothek defekt.&lt;br /&gt;
** Ist aktualisiert worden und in die aktuelle KiCad Symbol Library eingeflossen: [https://github.com/KiCad/kicad-library/blob/master/library/atmel.lib]&lt;br /&gt;
***Weitere Aktualisierungen und Erweiterungen: [https://github.com/KiCad/kicad-library/blob/master/library/atmel.dcm]&lt;br /&gt;
* Schaltregler (u.A. LM257x, LM267x, MC33063, L5973D) |||| Der MC33063 hat gleiches Pinning und Gehäuse wie MC34063! Darum kann der in http://www.mikrocontroller.net/wikifiles/8/84/Symbols_ICs-Diskrete_RevD9.lib verwendet werden.&lt;br /&gt;
* Spulen (z.&amp;amp;nbsp;B. diverse Wuerth) ||&lt;br /&gt;
* Drosseln (B82790 für CAN, Würth 744207) |&lt;br /&gt;
* Transformatoren (allgemein) |&lt;br /&gt;
* Ferrite (7427930 - 32, 742792651, 74279263) |&lt;br /&gt;
** ??? Was genau ist nun Footprint und Referenzmaeßig der Unterschied zwischen Drosseln, Spulen und Ferriten, wenn ich jetzt mal davon ausgehe, das die Teile weder Anzapfung noch mehr als eine Wicklung haben (dann wären es Trafos oder Uebertrager), und die elektrischen Werte in ein Feld eingetragen werden?? Schau mal unten in http://www.mikrocontroller.net/wikifiles/d/da/KiCAD_Module_Footprints_3D_16Sep2013.zip. Kleinere SMD-Entstörferrit Module lassen sich uebrigens aus Footprints für SMD-Widerstaenden zaubern, in dem man sie umbenahmt und mit der Referenz &amp;quot;L&amp;quot; versieht. ;-)&lt;br /&gt;
* STM32 Mikrocontroller Bibliothek (sofern möglich alle) |||&lt;br /&gt;
* Arduinos |&lt;br /&gt;
** Arduino Due ||&lt;br /&gt;
&lt;br /&gt;
=== Entwürfe ===&lt;br /&gt;
&lt;br /&gt;
Neue Bibliotheken oder Änderungen sollen zunächst in diesem Abschnitt &lt;br /&gt;
vorgestellt werden. &lt;br /&gt;
&lt;br /&gt;
==== Symbolbibliotheken ====&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/96460#832961 ATmega3250/TQFP100] von Fred S. (Gast)&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/96460#844741 ATMega3290 im 100Pin-Gehäuse] von Fred S. (Gast)&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/132811#1205130 RFM12-Funkmodul] von Dominik C.&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/133310#1210137 CAN Controller MCP2515 und Transceiver MCP2551] von Dominik C.&lt;br /&gt;
&lt;br /&gt;
* [[Media:SymbolsSimilarEN60617+oldDIN617-RevB-en.lib]] VERALTET! Nur aus Kompatibilitätsgründen behalten. Ersetzt für Neuentwicklungen durch Revision E1. Schaltplan Symbolbibliothek fuer KiCAD mit Symbolen, die denen aus der EN60617 oder der ALTEN DIN 617 ÄHNLICH sind. Von Bernd Wiebus&lt;br /&gt;
&lt;br /&gt;
* [[Media:SymbolsSimilarEN60617+oldDIN617-RevC-en.lib]] VERALTET! Nur aus Kompatibilitätsgründen behalten. Ersetzt für Neuentwicklungen durch Revision E1! Schaltplan Symbolbibliothek für KiCAD mit Symbolen, die denen aus der EN60617 oder der ALTEN DIN 617 ÄHNLICH sind. Aenderung gegenueber Rev.B: Kleinere Symbole hinzugefügt. Mit Vorsicht geniessen! Von Bernd Wiebus.&lt;br /&gt;
 &lt;br /&gt;
* [[Media:SymbolsSimilarEN60617+oldDIN617-RevD3-en.lib]] VERALTET! Nur aus Kompatibilitätsgründen behalten. Ersetzt für Neuentwicklungen durch Revision E1! Schaltplan Symbolbibliothek für KiCAD mit Symbolen, die denen aus der EN60617 oder der ALTEN DIN 617 ÄHNLICH sind.  Aenderung gegenueber Rev.C: Kleinere Fehler beseitigt. CLD Symbol hinzugefuegt. Kuehlkoerper Symbol und Dummy-Symbol fuer Boardoutlines hinzugefuegt. Thyristor und Triac Symbol zugefuegt. Copyright Symbole GNU-GPL und CC zugefuegt. Mit Vorsicht geniessen! Von Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
 &lt;br /&gt;
* [[Media:SymbolsSimilarEN60617+oldDIN617-RevE8.lib]] AKTUELLE Version! Ersetzt die Rev. B, C und die Rev. D sowie Vorgängerversionen E1-E7! Schaltplan Symbolbibliothek für KiCAD mit Symbolen, die denen aus der EN60617 oder der ALTEN DIN 617 ÄHNLICH sind.  Aenderung gegenueber Rev.D: Kleinere Fehler beseitigt. Ankerpunkte in die Nähe der Symetrieachsen verlegt. Verbinder DIN41612 / EN60603-2 &amp;quot;Eurokartenstecker&amp;quot; hinzugefügt. Große &amp;quot;BIG&amp;quot; Symbole entfernt und in der Datei BIG-SymbolsSimilarEN60617+oldDIN617-RevE.lib ausgelagert. Mit Vorsicht geniessen! Von Rene Belau und Bernd Wiebus.  CC-Zero/Public Domain!  Defektes Symbol &amp;quot;RESISTOR_RevE_Date15jun2010&amp;quot; repariert am 02. Maerz 2011. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
   &lt;br /&gt;
* [[Media:BIG-SymbolsSimilarEN60617+oldDIN617-RevE.lib]] Einige EN60617 oder der DIN 617 ÄHNLICHE Symbole in besonders GROSSER Ausführung. Vermutlich werden Sie diese GROSSEN Symbole eher NICHT benutzen wollen. Mit Vorsicht geniessen! Von Rene Belau und Bernd Wiebus. Unter GNU GPL. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[http://www.mikrocontroller.net/attachment/74203/obi.lib]] KiCAD Symbol für einen ATMEGA644. Von obi&lt;br /&gt;
&lt;br /&gt;
* [[Media:Symbols_ICs-Diskrete_RevD10.lib]] KiCAD Symbole für einige diskrete ICs. Enthält L200 (Pentawatt Gehäuse), LM2587 (Pentawatt Gehäuse), Längstregler LM317, LM78xx, LM79xx, Timer NE555, NF-Verstärker LM1875 und TDA2003 (Pentawatt Gehäuse), Schaltregler UC38xx (DIP8/SO8 und DIP14/SO14), LM2587, MC34036, LM78S40 und MCP1640, Treiber MIC4422 (DIP8/SO8 und Pentawatt Gehäuse). Allegro Halleffekt Stromwandler Typ ACS754/ACS755/ACS756 und LEM Halleffekt Stromwandler der Serie &amp;quot;HX&amp;quot;. Programierbarer Oszillator Si570/Si571 sowie Quarzoszillator Typ KXO-200. Dazu Transistor Arrays BC847S und BC857S (in einfacher und in aufgelöster Darstellung) und Supressordioden Array SR05. Schieberegister 74HC4094 . Spannungs-/Laderegler uA723/LM723 in 14 und 20 poligem Gehäuse. HF/ZF Verstärker/Mischer/Demodulator TCA440 alias exDDR A244D, FM Frontend TA7358. Spannungsmonitor ICL7665. Autor Bernd Wiebus.  CC-Zero/Public Domain!  Mit Vorsicht geniessen! Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:Symbols_ICs-Opto_RevB_16Sep2013.lib]] KiCAD Symbole für Optokoppler CNY17, IL300. IL388, TLP250, SFH617A-1, SFH617A-2, SFH617A-3, SFH617A-4, KPC357, LTV35x, und PC357. LWL Empfänger Toshiba TORX170 TORX173 TORX193  und TORX194 (Toslink). LWL Sender Toshiba TOTX170 TOTX173 TOTX193  und TOTX194 (Toslink). LWL Empfänger Agilent HFBR-252x und Sender Agilent HFBR-152x Serie (Versatile Link). 7 Segment Anzeigen HDSM531, HDSM533, LTS6760, LTS6780, SBC18-11EGWA. Autor Rene Belau und Bernd Wiebus. CC-Zero / Public domain. Mit VORSICHT geniessen! Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:Transformer-Diskrete_RevA.lib]] KiCAD Symbole für einige diskrete Transformatoren. Coilcraft Q4434-B = Rhombus T1311 und Myrra-74040 ETD29. Autor: Bernd Wiebus. Mit Vorsicht geniessen! Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:Symbols_DCDC-ACDC-Converter_RevC_29Aug2014.lib]] KiCAD Symbole für einige DCDC/ACDC-Converter. Enthält CINCON EC5BC12, CINCON EC6C11, TRACO TED-1212, TRACO TED-XXXX Dual Output, TRACO TED-XXXX Single Output, TRACO TEN10-1212, TRACO TEN10-XXXX, TRACO TME-XXXX, TRACO TMH-XXXX Single Output, TRACO TMH-XXXX Dual Output, sowie TRACO ACDC-Converter der TMLM Serie. BOTHHAND CF-Serie und DELTA DPS05U09D. Neu seit 29 August 2014: Floeth DCDC-Converter SD14-XXXX und SD18-XXXX. Autor: Bernd Wiebus. GNU-GPL. Mit Vorsicht geniessen! Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:Symbols_Socket-DIN41612_RevA.lib]] KiCAD Symbole für DIN41612 Stecker und Buchsen (Die bekannten Eurokartenstecker). Autor: Bernd Wiebus. GNU-GPL. Mit Vorsicht geniessen! Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:Symbols_EN60617_13Mar2013.lib]] KiCAD Symbole für die EN60617. Strikter als die Symbole aus SymbolsSimilarEN60617+oldDIN617-Rev~~.lib. Autor: Bernd Wiebus. CC-Zero/Public Domain! Mit Vorsicht geniessen! Hierzu gehört der Katalog: [[Media:Symbols_EN60617_13Mar2013.pdf]] Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:Symbols_EN60617-10_HF-Radio_DRAFT_12Sep2013.lib]] HF-Blockschaltbild Symbole für KiCad. EXPERIMENTELL! Autor: Bernd Wiebus. Mit Vorsicht geniessen! Lizenz: CC-Zero / Public domain.  Hierzu gehört der Katalog: [[Media:EN60617-10_HF-Radio_SymbolCatalog_DRAFT.pdf]] Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:Symbols_Microcontroller_Philips-NXP_RevA_06Oct2013.lib]] Symbole der NXP Microcontroller LPC2104, LPC2105 und LPC2106 fuer KiCad.  Autor: Bernd Wiebus. Mit Vorsicht geniessen! Lizenz: CC-Zero / Public domain. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
==== Modulbibliotheken ====&lt;br /&gt;
&lt;br /&gt;
* [[Media:KiCAD_Module_Footprints_3D_29Aug2014.zip]] Eine Sammlung von KiCAD Modulen bzw. Footprints diskreter Bauteile. Neben den obligatorischen Rs, Cs und Ls sind Schrack und Omron Kartenrelais (die Footprints passen auch fuer andere Hersteller), diverse Dioden, Klemmen WAGO 236 (RM 5mm) Serie und WAGO 734 Serie, Sicherungshalter (Schurter und Bulgin) für 5x20 und 6x30, SMD Sicherungen 1206 und Sicherungen/Sicherungshalter TE5/TR5,Flachsicherungen Standard und Mini, Kuehlkoerper und Eurokartenoutlines enthalten. Zusaetzlich TO92, TO220, TO220-5 (Pentawatt) und TO247 Gehaeuse. Ebenso die vermissten PISN und PISR SMD Drosseln. Einige Throughhole C&amp;amp;D Bobin Drosseln, Bourns 3296, Spectrol Type 43 / Econtrim und Piher PT15 Trimmer . Potentiometer Alps RK16 und Spectrol Type 148/149. Transformatoren Coilcraft Q4434-B / Rhombus T1311 sowie ETD29 von Epcos und Myrra sind auch dabei. Eurokartenstecker/-buchsen DIN 41612 Typ B1, B2, C1, C2 und C3. Ebenfalls enthalten: GNU-GPL und Creative Commons  Symbole. Dazu Messpunkte. BNC-Buchse, Quarzoszillator, SMD Widerstände und Kondensatoren.  (0805, 1206, 2512) sowie experimentelle Universalfootprints SMD/Throughole. SMD-Dioden: MELF, Mini-MELF, SMA, SMB und SMC. Halleffekt Stromwandler mit Allegro CB-PFF, CB-PSF und CB-FSS Gehäusen.Dazu Stecker Molex Serie KK, Würth SMD Drosseln und Doppeldrosseln. Neosid Filter und Drosseln. TRACO ACDC-Converter der TMLM Seie und SOT23, SOT143, SOT143R, TSOT-6 / MK06A sowie SC70-6 SMD Footprints für Dioden, Transistoren bzw. Dioden und Transistor Arrays und kleinere ICs. Mini Universal Mate-N-Lock Steckersockel (Tyco/AMP). 2-6 Pin, vertikale und horizontale Typen. Verbesserte Fiducials und Logos. Dazu SMD-Tantalkondensatoren und ETAL NF-Transformatoren. TO50-3 und TO50-4 Gehäuse. 7 Segment Anzeigen. LQFP48/TQFP48 Gehäuse. Hallsonden Stromwandler mit Allegro CB-PFF, CB-PSF und CB-FSS Gehäusen. Halleffekt Stromwandler der Serie &amp;quot;HX&amp;quot; von LEM.  Neu in der Version vom 29. August 2014: Floeth DCDC-Converter SD14 und SD18. Fast alles ohne 3D Modelle, aber manchmal mit PDF-Ausdruck zur leichten Identifikation. Mit Vorsicht geniessen! Ohne Garantie und  CC-Zero/Public Domain!  Von Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:KiCAD-Module_Buzzer_Beeper_RevA_25Oct2010.zip]] Einige Footprints von Summern /Buzzern / Beepern für KiCAD. Enthaelt Kingstate KCG0601, Pro Signal ABI-009-RC, Pro Signal ABI-010-RC, Pro Signal ABT-410-RC, Star Micronics HMB-06/HMB-12 und Projects Unlimited AI-4228-TWT-R. Alles ohne 3D Modelle, aber mit PDF-Ausdruck zur leichten Identifikation. Mit Vorsicht geniessen! Ohne Garantie und  CC-Zero/Public Domain!  Von Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:KiCAD-Module_CommonModeChoke_Wuerth_Type-WE-CMB_RevA_25Oct2010.zip]] Footprints der Gleichtaktdrosseln der Serie Würth WE CMB (through hole) für KiCAD. Enthält die Verschieden Bauformen XS, S, M, L, XL und XXL. Alles ohne 3D Modelle, aber mit PDF-Ausdruck zur leichten Identifikation. Mit Vorsicht geniessen! Ohne Garantie und  CC-Zero/Public Domain!  Von Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:DCDC-ACDC-Converter_RevC_20Jul2012.zip]] Footprints von DCDC/ACDC-Convertern für KiCAD. Enthält CINCON EC5BC12, CINCON EC6C11, TRACO TED-1212, TRACO TED-XXXX Dual Output, TRACO TED-XXXX Single Output, TRACO TEN10-1212, TRACO TEN10-XXXX, TRACO TME-XXXX, TRACO TMH-XXXX Single Output, TRACO TMH-XXXX Dual Output, BOTHHAND CF-Serie und DELTA DPS05U09D. Neu seit 20 Juli: TRACO ACDC-Converter der TMLM Serie. Alles ohne 3D Modelle, aber mit PDF-Ausdruck zur leichten Identifikation. Mit Vorsicht geniessen! Ohne Garantie und  CC-Zero/Public Domain!  Von Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:Opto-Devices_RevC_03Oct2012.zip]] Footprints von Optoelectronischen Bauteilen für KiCAD. Enthält 6 Polige DIL Footprints für CNY17, auch in &amp;quot;wide&amp;quot;, SMD Optokoppler Footprints (1 Kanalig) und Footprints für Toshiba (Toslink) und Agilent (Versatile Link) LWL Ssender und Empfänger. Alles ohne 3D Modelle, aber mit PDF-Ausdruck zur leichten Identifikation. Mit Vorsicht geniessen! Ohne Garantie und unter GNU-GPL. Von Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:Pentawatt_RevB_24Oct2012.zip]] Footprints von Pentawatt Gehäusen für KiCAD. Enthält verschiedene Ausführungen der TO220-5 Gehäuse in gerade und verkröpft, sowie stehend und liegend. Mit 3D-Modellen und mit PDF-Ausdruck zur leichten Identifikation. Mit Vorsicht geniessen! Ohne Garantie und unter GNU-GPL. Von Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
*[[Media:Transistor_TO-220_RevB_03Sep2012.zip]] Footprints von TO220-3 Gehäusen für KiCAD. Enthält verschiedene Ausführungen der TO220 Transistor Gehäuse in  stehend und liegend. Mit 3D-Modellen und mit PDF-Ausdruck zur leichten Identifikation. Mit Vorsicht geniessen! CC-Zero/Public domain! Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
*[[Media:Transistor_TO-247_RevC.zip]] Footprints von TO247 Gehäusen für KiCAD. Enthält verschiedene Ausführungen der Transistor Gehäuse in  stehend und liegend. Mit PDF-Ausdruck zur leichten Identifikation. Mit Vorsicht geniessen! CC-Zero/Public domain! Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[http://www.mikrocontroller.net/topic/176405#new]] KiCAD Modul / Footprint für ein TSSOP38 Gehäuse. Autor Raphael Reu.&lt;br /&gt;
&lt;br /&gt;
* [[http://www.mikrocontroller.net/topic/190088#1856759]] Texas Instruments TPIC8101 Klopfsensor Interface (für Verbrennungsmotoren). Autor Peter Diener.&lt;br /&gt;
&lt;br /&gt;
* [[Media:IR-directFET_Packages_RevB.zip]] Footprints von directFET SMD-Transistor Gehäusen von International Rectifier für KiCAD. Enthält die SH, SJ, SQ, ST, S1, MN, MP, MT, MX, MZ und die L8-Outline. Nähere Informationen in den Datenblättern betroffener Transistoren und in der International Rectifier Applikationsnotiz AN-1035. &amp;quot;directFET&amp;quot; ist übrigens eine Handelsmarke von International Rectifier und die Gehäuse sind proprietär. Also vorsichtig sein und an &amp;quot;second source&amp;quot; denken. Mit 3D Modellen und mit PDF-Ausdruck zur leichten Identifikation. Mit Vorsicht geniessen! Ohne Garantie und unter CC-Zero / Public domain. Von Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:Neosid-Devices_Coils_Filters_25Apr2012.zip]] Footprints von NEOSID Bauteilen. Spulen, Luftspulen, Filter ec. für KiCAD. Through hole und SMD. Alles ohne 3D Modelle, aber mit PDF-Ausdruck zur leichten Identifikation. Mit Vorsicht geniessen! Ohne Garantie und unter GNU-GPL. Von Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:SOT23_SOT143_SOT143R_TSOT6_MK06A_SC70-6_Housing_14Mar2014.zip]] Footprints von SOT23, SOT143, SOT143R, TSOT-6 /MK06A und SC70-6 SMD Gehäusen, wie sie oft für Dioden und Transistoren, aber auch Dioden und Transistor Arrays verwendet werden. Auch ICs findet man in der Bauform. Es sind Standard Footprints und spezielle für Handlötung vorhanden. KiCad Legacy Format und neues .pretty Format. Alles ohne 3D Modelle, aber mit PDF-Ausdruck zur leichten Identifikation. Mit Vorsicht geniessen! Ohne Garantie und unter GNU-GPL. Von Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:MiniUniversalMate-N-LokSockets_13Aug2012.zip]] Footprints von Mini Universal Mate-N-Lok Steckersockeln (Tyco/AMP). 2-6 Pin, verticale und horizontale Typen. Alles ohne 3D Modelle, aber mit PDF-Ausdruck zur leichten Identifikation. Mit Vorsicht geniessen! Ohne Garantie und unter GNU-GPL. Von Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:NF-Transformer_ETAL_RevA_28Aug2012.zip]] Footprints und 3D-Mesh Modelle von NF-Transformatoren der Firma ETAL (http://www.etalgroup.com). SMD und THT Typen. Mit PDF-Ausdruck zur leichteren Identifikation. In der Bibliothek ist auch der bekannte Übertrager ETAL P1200, der von Box73 (http://www.box73.de) vertrieben wird. Mit Vorsicht geniessen! Ohne Garantie und unter GNU-GPL. Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de &lt;br /&gt;
&lt;br /&gt;
* [[Media:TantalCapacitors_SMD_RevA_28Aug2012.zip]] Footprints von Tantal Kondensatoren SMD Größe A bis E (EIA-3216, EIA-3528, EIA-6032, EIA-7343 und EIA-7360). Alles ohne 3D Modelle, aber mit PDF-Ausdruck zur leichten Identifikation. Ohne Garantie und unter GNU-GPL. Mit Vorsicht geniessen! Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:SOT89-3_SOT89-5_Housing_RevA_02Sep2012.zip]] Footprints und 3D-Mesh Modelle von SOT89-3 und SOT89-5 SMD Gehäusen. Mit PDF-Ausdruck zur leichteren Identifikation. Ohne Garantie und unter GNU-GPL.  Mit Vorsicht geniessen! Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:SOT126_SOT32_Housings_RevA_22Oct2012.zip]] Footprints und 3D-Mesh Modelle von SOT126 / SOT32 Gehäusen. Mit PDF-Ausdruck zur leichteren Identifikation. Ohne Garantie und unter GNU-GPL.  Mit Vorsicht geniessen! Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:Allegro_HallSensors_24Oct2012.zip]] Footprints und 3D Modelle von Allegro Hall-Effect Stromsensoren mit PFF, PSF oder PSS Gehäuse (ACS754, ACS755, ACS756).  Mit PDF-Ausdruck zur leichteren Identifikation. Ohne Garantie und unter GNU-GPL.  Mit Vorsicht geniessen! Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:VML0806_Housing_Rohm_27Oct2012.zip]] Footprints und 3D Modell eines Transistors im 0806 Format (VML0806 / Rohm).  Mit PDF-Ausdruck zur leichteren Identifikation. Ohne Garantie und unter GNU-GPL.  Mit Vorsicht geniessen! Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
*[[Media:TO-50_Housings_RevA_21Apr2013.zip]]  Footprints/Module von TO50-3 und TO50-4 Transistor Gehäusen.Mit PDF-Ausdruck zur leichteren Identifikation. Ohne Garantie und unter CC-Zero / Public Domain.  Mit Vorsicht geniessen! Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
*[[Media:OldSowjetAera_Transistor_RevA.zip]] Footprints/Module von Kleinleistungstransistoren aus der Sowjetära.Mit 3D-Modell und PDF-Ausdruck zur leichteren Identifikation. Ohne Garantie und unter CC-Zero / Public Domain.  Mit Vorsicht geniessen! Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
*[[Media:SIP9_Housing_14Jun2013.zip]] Footprints/Module von SIP9 Gehäusen (z.B. TA7358).Mit 3D-Modell und PDF-Ausdruck zur leichteren Identifikation. Ohne Garantie und unter CC-Zero / Public Domain.  Mit Vorsicht geniessen! Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
*[[Media:7Segment_16Sep2013.zip]] Footprints/Module von 7-Segment Anzeigen HDSM531 (SMD), HDSM533 (SMD), LTS6760, LTS6780 undSBC18-11EGWA. Dazu PDF-Ausdruck zur leichteren Identifikation. Ohne Garantie und unter CC-Zero / Public Domain.  Mit Vorsicht geniessen! Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
*[[Media:BNC-Sockets_RevA.zip]] Footprints/Module von TYCO BNC-Buchsen für KiCad. Mit 3D Modellen und PDF Preview. Ohne Garantie und unter CC-Zero / Public Domain.  Mit Vorsicht geniessen! Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
*[[Media:LQFP_TQFP_RevA_06Oct2013.zip]] Footprints/Module von LQDP48/TQFP48 Gehäuseb für KiCad. Ohne 3D Modelle, aber mit PDF Preview. Ohne Garantie und unter CC-Zero / Public Domain.  Mit Vorsicht geniessen! Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
*[[Media:LEM_HallEffectTransducers_RevA_13Oct2012.zip]] Module/Footprints von Halleffekt Stromwandlern der Serien &amp;quot;HX&amp;quot; und &amp;quot;HTFS&amp;quot; von LEM. Mit 3D-Modellen  und PDF Preview. Ohne Garantie und unter CC-Zero / Public Domain.  Mit Vorsicht geniessen! Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
==== 3D-Modelle ====&lt;br /&gt;
&lt;br /&gt;
* [[Media:MeshModells_VRML-Wings3D_13Oct2013.zip]]  3D-Modelle diverser elektronischer Bauteile im wrl 2.0 und wings Format. Enthalten: DD-PAK (TO263AB), D-PAK (TO252AA), SMD Dioden MELF, MiniMELF, SMA, SMB und SMC, Transformatoren ETAL P1165, P1200, P2781, P3000, P3181, PP3188 und P3191, SO126 / SOT32 in horizontal und vertikal, SOT223-3, TO263-3, SOT89-3, SOT89-5, TO220 horizontal und vertikal und reverse. TO220-5 horizontal, vertical, inline und verkröpft, VML0806. SIP9. 7 Segment SMD Anzeige HDSM531/HDSM533 in Grün, gelb, rot und orange. directFET SMD-Transistor Gehäusen von International Rectifier für KiCAD. Enthält die SH, SJ, SQ, ST, S1, MN, MP, MT, MX, MZ und die L8-Outlines. Flachsicherungen Standard und Mini. Halleffekt Stromwandler LEM &amp;quot;HX&amp;quot; Serie und Allegro ACS754/ACS755/ACS756 mit CB-PFF, CB-PSF und CB-FSS Gehäusen. Ohne Garantie und unter CC-Zero / Public Domain Lizenz. Mit Vorsicht geniessen! Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
==== Building-Blocks ====&lt;br /&gt;
*[[Media:BuildingBlocks_16Jun2013.zip]] enthält eine Sammlung von gängigen Schaltungen mit den Längstreglern LM317 /LM78xx /LM79xx und dem Timer 555, die nach dem in diesem [[Media:HierarchischeSchaltplaeneAlsBausteineInKicad_RevC_23Dec2013.pdf]] Dokument beschriebenen Vorgehen als Building Blocks in KiCAD verwendet werden können. Ein Katalog dazu befindet sich hier: [[Media:KatalogUeberKiCadBuildingBlocks_21Apr2013.pdf]]. Autor: Bernd Wiebus, Lizenz: Creative Commons. Experimentell! Ohne Garantie! Mit Vorsicht geniessen!&lt;br /&gt;
&lt;br /&gt;
Wenn mindestens ein weiterer KiCAD User die Bibliothek geprüft hat, kann sie in den folgenden Unterabschnitt verschoben werden.&lt;br /&gt;
&lt;br /&gt;
=== Geprüfte ===&lt;br /&gt;
&lt;br /&gt;
Hier sollen geprüfte Bibliotheken gesammelt werden. Bitte angeben, wer die Prüfung gemacht hat.&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/132288#new STM32F103xx (LQFP64) Schaltplansymbol] erstellt/geprüft: Dominik C.; Marko S.&lt;br /&gt;
&lt;br /&gt;
*Bei der STMF103xx fehlt glaub ich der Portpin PD2 :) Grüße :)&lt;br /&gt;
&lt;br /&gt;
=== Sonstige Bibliotheken im Netz ===&lt;br /&gt;
* https://github.com/KiCad/kicad-library Neues offizielles Repository bei Github.&lt;br /&gt;
* https://github.com/KiCad Allgemeines Repository bei Github.&lt;br /&gt;
**https://github.com/KiCad/kicad-library/blob/master/KiCad_Library_Convention.txt Conventionen für die Github Bibliotheken. Bitte beachten, das noch nicht alle Bibliotheken umgestellt sind.&lt;br /&gt;
**https://github.com/KiCad/kicad-library/blob/master/CONTRIBUTING.txt Wie man selber Bibliotheken in das KiCad Repository einfügen kann.&lt;br /&gt;
* http://www.kicadlib.org/&lt;br /&gt;
* http://per.launay.free.fr/kicad/kicad_php/composant.php &lt;br /&gt;
* http://www.reniemarquet.cjb.net/kicad/libs/o_analog.zip (NE555 u.a.)&lt;br /&gt;
* http://github.com/Inte/kicadlib&lt;br /&gt;
* http://www.df0fkw.datenoase.de/index.php?option=com_content&amp;amp;view=article&amp;amp;id=107:kicad-libraries&amp;amp;catid=36:bastelprojekte&amp;amp;Itemid=67&lt;br /&gt;
* http://bytelabs.ch/kicadlib.html&lt;br /&gt;
* http://library.oshec.org/ Von EAGLE konvertiert, also Vorsicht bei der Verwendung! &lt;br /&gt;
* http://smisioto.no-ip.org/elettronica/kicad/kicad-en.htm&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
&lt;br /&gt;
Da die in KiCad verwendeten Dateien klarschriftlesbar sind, lassen sie sich sehr leicht mit externen Programmen und Skripten bearbeiten, um spezielle Funktionalitäten zu erzeugen. Eine kleine Auswahl an Programmen/Skripten ist hier zusammengestellt:&lt;br /&gt;
&lt;br /&gt;
* [http://kicad.rohrbacher.net/quicklib.php Quick KICAD Library Component Builder]&lt;br /&gt;
* Gerber-Tools sind für KiCAD weniger nötig, da KiCAD mit GerbView seinen eigenen Gerberviewer mitbringt. Dieser ist mächtig genug, die eingelesenen Gerberfiles als Platine in PCBnew zu exportieren, wo sie manipuliert werden können. Dieses geht aber nur mit Gerber-RS274X Daten. Ebensowenig können Gerberfiles zu Nutzen zusammengefügt werden. Hierzu bietet sich &amp;quot;Gerbmerge&amp;quot; http://ruggedcircuits.com/gerbmerge (http://claymore.engineer.gvsu.edu/~steriana/Python/gerbmerge/ Veraltet) an. Wer lediglich aus Sicherheitsgründen die von KiCAD erzeugten Gerberdaten mit einem fremden Gerber-Vierer inspizieren möchte, findet hier Hinweise:http://www.mikrocontroller.net/articles/Gerber-Tools&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/204063#2011138 KiCAD (Multi-)Symbol Tool] von Joghurt3000 zur Erstellung von Symbolen aus einer Textvorlage&lt;br /&gt;
* [http://cyclerecorder.org/footprintbuilder Footprintbuilder] Java-Programm zu Erstellung von Footprints.&lt;br /&gt;
*Wer seine Platine &amp;quot;panelisieren&amp;quot; (d.h. mehrmals nebeneinander anordnen um in einem &amp;quot;Nutzen&amp;quot; gleich mehrere Platinen fertigen zu können) möchte, kann das mit dem Python 2 Skript &amp;quot;panelize.py&amp;quot; tun. Das Programm arbeitet direkt auf den kicad .brd Files, so das das Mehrfachnutzen Board unter PCBnew nachbearbeitet werden kann, für z.B. einen  DRC. &amp;quot;panelize.py&amp;quot; kann hier bezogen werden: http://blog.borg.ch/?p=12&lt;br /&gt;
* &amp;quot;Raef&amp;quot; hat ein Python Script erstellt, das Bauteile automatisch ähnlich der Anordnung im Schaltplan plaziert. Siehe: http://www.mikrocontroller.net/topic/293903#3245990&lt;br /&gt;
*Wer die Reihenfolge der Subschaltpläne ändern will (Wegen Übersichtlichkeit/Bestimmt auch die Reihenfolge beim Ausdrucken), kann dieses Python 3 Skript verwenden (Liesmich/Readme beachten): http://www.mikrocontroller.net/wikifiles/9/90/PyKicadSchematic-ID_Interchanger_RevC.zip Autor: Bernd Wiebus, GNU-GPL. Dieses Skript ist unabhängig von der PCBnew internen Python 2 Schnittstelle.&lt;br /&gt;
* Um ältere Schaltpläne von vor Jan./Feb. 2014 (BZR4646) mit &amp;quot;upper case&amp;quot; Symbolnamen zu konvertieren, kann dieses Python 3 Skript verwendet werden: [[Media:PyKiCad-CaseSensitiveLibCure_RevD_13Apr2015.zip]]. Autor: Bernd Wiebus, GNU-GPL. Dieses Skript ist unabhängig von der PCBnew internen Python 2 Schnittstelle.&lt;br /&gt;
* Wem das Tricksen mit Dateimanager oder Schematic oder Board als Bibliotheksmanager nicht gefällt, findet vieleicht im &amp;quot;KiCad Libarian&amp;quot; ein passendes Tool: http://www.compuphase.com/electronics/kicadlibrarian_en.htm&lt;br /&gt;
* Diverse Skripte, um KiCad Symbole, Footprints oder sonstigen Bibliothekskram zu bearbeiten. [https://github.com/KiCad/kicad-library-utils]&lt;br /&gt;
* Cirillo Bernardo hat einige Programme geschrieben, um VRML 3D Gitter Modelle für Bauteile parametrisch zu erzeugen. Sie finden sich hier: https://github.com/cbernardo/kicad3Dmodels&lt;br /&gt;
* Peter Hofbauer hat einige Windows Programme geschrieben, die zur KiCad Unterstützung dienen: http://www.hcp-hofbauer.de/software.htm Bei den Programmen handelt es sich um &amp;quot;Aufräumprogramme für Bibliotheken, Stücklistenerzeugung, Extraktionsprogramm um eine Verdrahtungsliste aus einer Netzliste zu erzeugen, Ein Programm um Boherdurchmesser zu vereinheitlichen und ein Programm, um zusammen mit &amp;quot;Linegrinder&amp;quot; G-Code aus KiCad Boarddateien zu erzeugen. &lt;br /&gt;
* [http://escalalibre.com/edwt/kicad_sizeConverter.php KiCad Bitmap2Component Skalierer] Erlaubt es, Logos zu skalieren.&lt;br /&gt;
* [http://escalalibre.com/edwt/kicad_modTextChanger.php KiCad Module Text Changer]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Konverter ===&lt;br /&gt;
&lt;br /&gt;
Konverter wandeln KiCad-Daten in die Daten anderer Layoutprogramme bzw. die Daten anderer Layoutprogramme in KiCad-Daten um.&lt;br /&gt;
Nativ kann KiCad gEDA Footprints bzw. neuere Eagle Footprints direkt als Bibliothek einbinden. Das ganze ist aber als noch sehr experimentell zu betrachten.&lt;br /&gt;
&lt;br /&gt;
Desweiteren gibt es einige Programme oder Skripte von dritter Seite, die Daten anderer Layoutprogramme in KiCad Daten umwandeln. Auch diese sind als experimentell einzustufen.&lt;br /&gt;
&lt;br /&gt;
Hier eine Auswahl:&lt;br /&gt;
* https://github.com/thesourcerer8/altium2kicad Wandelt Altium Schaltpläne und Layouts in KiCad Daten um.&lt;br /&gt;
* https://github.com/DanChianucci/Eagle2Kicad Wandelt Eagle 6.0 Layouts in KiCad Layouts.&lt;br /&gt;
* https://github.com/lachlanA/eagle-to-kicad Wandelt Eagle 6.0 Layouts in KiCad Layouts.&lt;br /&gt;
* http://www.cadsoft.de/downloads/file/eagle2kicad-0.9c.ulp Direkt von der Cadsoft Seite, ein ULP das Eagle Daten in KiCad Daten wandelt.&lt;br /&gt;
* http://www.cadsoft.de/downloads/file/eagle2kicad_sch.ulp Ebenfalls direkt von der Cadsoft Seite, ein ULP, das Eagle Schaltpläne in KiCad Schaltpläne wandelt.&lt;br /&gt;
* http://sourceforge.net/projects/pcad2kicad/ Wandelt P-CAD Schaltpläne, Layouts und Bibliotheken in KiCad Daten um.&lt;br /&gt;
&lt;br /&gt;
Erfahrungsberichte willkommen!&lt;br /&gt;
&lt;br /&gt;
== Beispielprojekte ==&lt;br /&gt;
&lt;br /&gt;
* http://www.mikrocontroller.net/topic/33653#963083 JTag-wiggler&lt;br /&gt;
* http://www.mikrocontroller.net/topic/190088#1856757 Klopfsensor von Peter Diener.&lt;br /&gt;
* http://www.mikrocontroller.net/topic/188897 Open-Hardware / Open-Source USB-basierter SPI BIOS-Chip Programmer von Uwe Hermann&lt;br /&gt;
* http://www.mikrocontroller.net/articles/Modellbahn_Servodecoder_f%C3%BCr_Weichen_mit_R%C3%BCckmeldung Modellbahn Servodecoder für Weichen mit Rückmeldung&lt;br /&gt;
* http://www.mikrocontroller.net/articles/RS485_IO_Board_-_ModellBahnLichtSteuerung RS485 IO Board - ModellBahnLichtSteuerung&lt;br /&gt;
* [[Media:UndervoltageProtection_RevD_14Aug2012.zip]] Beispielprojekt eines Tiefentladeschutzes für einen Blei-Gel Akku, der von den Platinenabmessungen her auf einen typischen 12V/7,2Ah Akku passt. Ausserdem bietet er abgesicherten Zugang zu den Akkuklemmen, was auch in vielen Fällen beachtenswert ist. Leider ist das Projekt noch etwas unaufgeräumt, es fehlen noch Bauteilwerte, und in der Form wurde noch keine fertige Platine daraus hergestellt, aufgebaut und getestet. Autor: Bernd Wiebus, GNU-GPL.&lt;br /&gt;
* http://www.mikrocontroller.net/topic/338835#3724591 Universeller Adapter PDI, JTAG, ISP mit KICAD&lt;br /&gt;
* http://n8vem-sbc.pbworks.com/w/page/4200908/FrontPage Eine Seite mit Selbstbaucomputern, teilweise &amp;quot;Retro&amp;quot; mit S100 Bus.&lt;br /&gt;
* [[Media:DC-50Ohm_Terminierung_RevE_25Mar2015.zip]] 50 Ohm DC entkoppelte Terminierung fuer Oszilloskope. [[Bild:DC-50Ohm_Terminierung_Downside.png|thumb|150px|Unterseite des DC-Messadapters mit kapazitiv entkoppelter 50 Ohm Terminierung]] [[Bild:DC-50Ohm_Terminierung_Upside.png|thumb|150px|Oberseite des DC-Messadapters mit kapazitiv entkoppelter 50 Ohm Terminierung]] Dieses Beispiel enthält Board-Dateien Version 5. Möchte man diese mit einem älteren KiCad, welches nur Version 4 kennt, öffnen, so müssen die Dateien angepasst werden. Eine Anleitung findet sich hier: [[Media:KiCad-PCBnewBoardDateienMigrierenVonVersion4Auf5.pdf]]&lt;br /&gt;
* https://www.mikrocontroller.net/attachment/261855/QRP-SWR-Bridge_ModC_RevA-pretty_11Jul2015.zip Resistive SWR-Messbrücke für QRP Kleinleistung auf Kurzwelle. Einer der Vorteile ist hohe Empfindlichkeit und dass sie auch bei Fehlanpassung dem Senderausgang einen bedämpften, halbwegs passenden Abschluss bietet. Anwendungsbeispiel Moqsquita ( http://www.qrpproject.de/Media/pdf/Mosquita40.pdf ) für 40m und weitere Infos, auch zu Bauteilen, finden sich hier im Thread: https://www.mikrocontroller.net/topic/371365#4194810 Dieses Beispiel enthält Board-Dateien Version 5. Möchte man diese mit einem älteren KiCad, welches nur Version 4 kennt, öffnen, so müssen die Dateien angepasst werden. Eine Anleitung findet sich hier: [[Media:KiCad-PCBnewBoardDateienMigrierenVonVersion4Auf5.pdf]]&lt;br /&gt;
&lt;br /&gt;
== Diskussionen (teilweise seeeehr alt) ==&lt;br /&gt;
&lt;br /&gt;
* http://www.mikrocontroller.net/topic/120373#1089075 &lt;br /&gt;
* http://www.mikrocontroller.net/topic/98034#848559&lt;br /&gt;
* http://www.mikrocontroller.net/topic/95864#828660&lt;br /&gt;
* http://www.mikrocontroller.net/topic/77738#647041&lt;br /&gt;
* http://www.mikrocontroller.net/topic/103806#907523&lt;br /&gt;
* http://www.mikrocontroller.net/topic/41999#316195&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
&lt;br /&gt;
* [http://iut-tice.ujf-grenoble.fr/kicad/index.html KiCAD] Homepage 1 und Download&lt;br /&gt;
* [http://www.lis.inpg.fr/realise_au_lis/kicad/ KiCAD] Homepage 2 und Download&lt;br /&gt;
* [http://www.kicad-pcb.org/display/KICAD/KiCad+EDA+Software+Suite KiCAD] Neue Homepage&lt;br /&gt;
* [http://www.kicad-pcb.org/display/KICAD/KiCad+Scripting+Reference+Manual] Speziell Informationen zum Python-Scripting.&lt;br /&gt;
* [http://kicad.sourceforge.net/wiki/index.php/DE:Main_Page KiCAD Wiki]&lt;br /&gt;
* Tutorials: &lt;br /&gt;
** [http://kicad.sourceforge.net/wiki/index.php/DE:Mini_tutorial Mini-Tutorial]&lt;br /&gt;
** [http://timogruss.de/kicad-loesung-fuer-die-leiterplatten-entwicklung/ KiCad Tutorial auf timogruss.de] (deutsch)&lt;br /&gt;
** http://www.curiousinventor.com/guides/kicad&lt;br /&gt;
** http://xtronics.com/reference/kicad.html&lt;br /&gt;
** http://bastler-archiv.de/elektronik/platinenherstellung-platinenlayout-mit-kicad-teil-1/ (deutsch, Teil 1)&lt;br /&gt;
** http://bastler-archiv.de/elektronik/platinenherstellung-platinenlayout-mit-kicad-teil-2/ (deutsch, Teil 2)&lt;br /&gt;
** http://www.kramann.info/73_COACH3/06_Layouting/Layouting_art_Guido_Kramann_12122010.pdf&lt;br /&gt;
** https://contextualelectronics.com/course/kicad-tutorial/ (Video Tutorials auf Englisch)&lt;br /&gt;
&lt;br /&gt;
* Usergroups:&lt;br /&gt;
** [https://groups.yahoo.com/neo/groups/kicad-users/info Yahoo-KiCAD-User-Group (Englischsprachig)]&lt;br /&gt;
** [https://forum.kicad.info/ Endlischsprachiges KiCad Forum]&lt;br /&gt;
** [http://1.cad-kicad-user.cadtalk.us/ Englischsprachige Diskussionen über KiCad im &amp;quot;Cadtalk&amp;quot;-Forum]&lt;br /&gt;
* Tools&lt;br /&gt;
** [http://www.freerouting.net/ Freerouting] Autorouter&lt;br /&gt;
** [http://www.mikrocontroller.net/articles/KiCAD#Tools Liste mit externen Programmen und Skripten im Zusammenhang mit KiCad]&lt;br /&gt;
* Verschiedenes im Zusammenhang mit KiCad&lt;br /&gt;
** [https://github.com/KiCad/kicad-library/wiki/Kicad-Library-Convention Kicad Library Convention / Regeln für offizielle KiCad Bibliotheken (Englisch)]&lt;br /&gt;
** [http://www.compuphase.com/electronics/LibraryFileFormats.pdf Aufbau der unterschiedlichen KiCad Bibliotheks Files (englisch)]&lt;br /&gt;
** [http://www.ohwr.org/projects/cern-kicad/wiki/WorkPackages CERN KiCad development roadmap / Was ist in KiCad Entwicklung geplant? (englisch)]&lt;br /&gt;
** [http://home.web.cern.ch/about/updates/2015/02/kicad-software-gets-cern-treatment Warum das CERN KiCad unterstützt (englisch)]&lt;br /&gt;
** [https://www.youtube.com/watch?v=chejn7dqpfQ Video mit der Leiterbahnlängenanpassen Funktion bzw. der &amp;quot;Differential pair&amp;quot; Funktion in KiCad.]&lt;br /&gt;
** [http://www.youtube.com/watch?v=irqlrVUbjuQ Video mit dem interaktiven Router]&lt;br /&gt;
* Plattformen&lt;br /&gt;
** Mac: http://brokentoaster.com/kicad/&lt;br /&gt;
**Ubuntu: [http://www.mikrocontroller.net/topic/257321#2658268 KiCAD selber compilieren]&lt;br /&gt;
** http://wiki.xtronics.com/index.php/Kicad Transtronics site (englisch)&lt;br /&gt;
* HowTo von Tom Boyd (englisch)&lt;br /&gt;
** http://kicadhowto.wikidot.com/&lt;br /&gt;
** http://kicadhowto.org/&lt;br /&gt;
* Bugreports! Wer einen Bug gefunden hat, bitte [https://bugs.launchpad.net/kicad hier] angeben! Kicad wird laufend verbessert. Hier kann auch schon nach vorhandenen Reports gesucht werden, wenn einem etwas komisch vorkommt.&lt;br /&gt;
&lt;br /&gt;
[[Category:Schaltplaneditoren]]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=83446</id>
		<title>STM32 - Einstieg mit Em::Blocks</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32_-_Einstieg_mit_Em::Blocks&amp;diff=83446"/>
		<updated>2014-07-01T16:24:27Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Tutorial werde ich versuchen, möglichst einfach, die ersten Schritte zur Entwicklung von STM32 Anwendungen mit der Em::Blocks IDE zu erklären. Hier soll nicht so stark auf die einzelnen Peripherie-Module der Controller eingegangen werden, sondern mehr auf die IDE und die verschiedenen Libraries, wie die CMSIS Library, die DSP-Library, die Standard-Peripheral-Library, die USB-Library und vllt. über Ethernet. Ich denke ein Kapitel zu FreeRTOS wird es auch geben. Außerdem stehen im Vordergrund Sachen wie z.B. booten aus dem SRAM, In-Application-Programming, FPU, Core-Coupled-RAM usw. Mal sehn wie weit ich komme ;)&lt;br /&gt;
&lt;br /&gt;
==Die Entwicklungsumgebung==&lt;br /&gt;
===Hardware===&lt;br /&gt;
Zum testen der Anwendungen, benutze ich das STM32F4-Discovery Board, welches einen Debugger, Peripherie und natürlich einen STM32 Controller (STM32F407VGT6) enthält. Deshalb sind alle Beispiele hier für den STM32F407VG Controller ausgelegt, können aber meisten 1:1 auf andere Controller portiert werden. Ich werde auch möglichsts keine STM32F4-Discovery Board spezifischen Libraries verwenden, damit der Portierungs-Vorgang möglichsts einfach bleibt.&lt;br /&gt;
&lt;br /&gt;
===Software===&lt;br /&gt;
In diesem Tutorial verwende ich [http://www.emblocks.org/ Em::Blocks] als IDE. Em::Blocks ist eine kostenlose, uneingeschränkte IDE, die alle STM32 Mikrcontroller unterstützt und sehr einfach zu bedienen ist.&lt;br /&gt;
Nach dem Download kann die IDE per Dialog, sehr einfach, installiert werden. Als Compiler beinhaltet Em::Blocks den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Die IDE unterstützt zurzeit den ST-Link, den J-Link und es gibt eine Generic-Vorlage, durch welche andere Debugger konfiguriert werden können.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss noch der passende Treiber für den Debugger installiert werden. Verwendet man ein Discovery-Board muss der [http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168 ST-Link/V2]-Treiber heruntergeladen und installiert werden. (Die Installation muss evtl. als Administrator ausgeführt werden, da sonst die Installation unvollständig wird.) Nach der Installation des Treibers kann man den Debugger über die entsprechende USB Schnittstelle an den PC anschließen und es sollte die Meldung von Windows kommen, dass der richtige Treiber gefunden wurde.&lt;br /&gt;
&lt;br /&gt;
===Libraries===&lt;br /&gt;
Zum programmieren benötigt man noch die [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php CMSIS] und die Standard-Peripheral-Library (z.B. für die F4 Controller [http://www.st.com/stonline/stappl/productcatalog/app?page=partNumberSearchPage&amp;amp;levelid=SS1577&amp;amp;parentid=1743&amp;amp;resourcetype=SW Standard-Peripheral-Library-F4]), die man am besten in einen Ordner (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) entpackt&lt;br /&gt;
&lt;br /&gt;
==Basis-Wissen zur IDE==&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Dateien zum Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf &amp;lt;ProjektName&amp;gt; -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Enfernen von Dateien aus dem Projekt===&lt;br /&gt;
Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei / mehrere Dateien auswählen -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Die Dateien werden lediglich aus dem Projekt entfernt und nicht von der Festplatte gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von Include-Pfaden===&lt;br /&gt;
Sofern die Include-Datei(en) nicht im standard Include-Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; des Projektes liegen, muss man den Pfad zum Projekt hinzufügen, damit der Compiler die Include-Dateien später auch finden kann. Man geht wie folgt vor: Im Projekt-Manager &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Search Directories -&amp;gt; Add&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Achtung: Es ist standardmäßig im Fenster links &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; ausgewählt. Hier muss darüber das Projekt ausgewählt werden um global die Include-Dateien hinzuzufügen.&lt;br /&gt;
&lt;br /&gt;
===Hinzufügen von globalen Defines zum Build===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; können globale Defines hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Achtung: Hier gilt ebenfalls wie bei den Include-Dateien dass standardmäßig im Fenster links &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; ausgewählt ist. Hier muss darüber das Projekt ausgewählt werden um global die Defines hinzuzufügen.&lt;br /&gt;
&lt;br /&gt;
===Compilieren===&lt;br /&gt;
Entweder über das &#039;&#039;&#039;&#039;&#039;Build&#039;&#039;&#039;&#039;&#039; Menü oder über &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Um eine genau Ausgabe des Compiler-Aufrufes mit allen Argumenten zu bekommen, geht man im &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; Menü auf &#039;&#039;&#039;&#039;&#039;Tools...&#039;&#039;&#039;&#039;&#039; und dann auf &#039;&#039;&#039;&#039;&#039;Toolchain executables&#039;&#039;&#039;&#039;&#039;. Ganz unten, unter &#039;&#039;&#039;&#039;&#039;Logging&#039;&#039;&#039;&#039;&#039; kann man dann &#039;&#039;&#039;&#039;&#039;Full command line&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
====Compiler Optionen====&lt;br /&gt;
=====Optimierung=====&lt;br /&gt;
Standardmäßig verwendet Em::Blocks keine Optimierung. Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Optimization&#039;&#039;&#039;&#039;&#039; kann zwischen verschieden Optimierungen ausgewählt werden.&lt;br /&gt;
&lt;br /&gt;
=====Verschiedene C-Standards=====&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Categories: Language standard&#039;&#039;&#039;&#039;&#039; kann man zwischen verschieden C-Standard auswählen, wie z.B, C99.&lt;br /&gt;
(Mit C99 können auch die Lauf-Variable in der for-Schleife deklariert werden: for(int i;..))&lt;br /&gt;
&lt;br /&gt;
===Debuggen===&lt;br /&gt;
*Als erstes den Debugger starten über das &#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; Menü und &#039;&#039;&#039;&#039;&#039;Start/stop Debug Session&#039;&#039;&#039;&#039;&#039; oder über &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Danach läuft die Anwendung auf dem Controller und warten im &#039;&#039;&#039;&#039;&#039;Reset_Handler&#039;&#039;&#039;&#039;&#039; auf Einzelschritt- bzw. Run- Befehle (&#039;&#039;&#039;&#039;&#039;F5, F10, F11&#039;&#039;&#039;&#039;&#039; usw..(siehe &#039;&#039;&#039;&#039;&#039;Debug-Menü&#039;&#039;&#039;&#039;&#039; für alle Möglichkeiten))&lt;br /&gt;
&lt;br /&gt;
*Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird die Debug-Session auch wieder beendet&lt;br /&gt;
&lt;br /&gt;
*Unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Target settings&#039;&#039;&#039;&#039;&#039; können Eigenschaften, wie z.B &#039;&#039;&#039;&#039;&#039;Run to main()&#039;&#039;&#039;&#039;&#039; aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
====Register View====&lt;br /&gt;
Damit man beim Debuggen sich bequem die Werte der Register (der Peripherie-Register) ansehen kann, bracht man eine, zum Controller passende &#039;&#039;&#039;&#039;&#039;System View Description&#039;&#039;&#039;&#039;&#039;-Datei (*.svd), die die verschiedenen Register beschreibt (Name, Adresse, usw..). In Em::Blocks gibt es dazu ein Tool, womit man solche Dateien herunterladen und verwenden kann.&lt;br /&gt;
&lt;br /&gt;
Um sich die nur die Core-Register anzusehen / zu bearbeiten braucht man keine SVD-Datei.&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;&#039;&#039;Debug&#039;&#039;&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;&#039;&#039;Plugins&#039;&#039;&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;&#039;&#039;SVD repository&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Controller-Hersteller und Cntroller-Reihe auswählen&lt;br /&gt;
*Speicherort auswählen (Standard ist das aktuelle Projekt-Verzeichniss)&lt;br /&gt;
*Wenn das Häkchen bei &#039;&#039;&#039;&#039;&#039;Set and launch target debug configuration&#039;&#039;&#039;&#039;&#039; gesetzt ist, öffnen sich die Debug-Einstellungen automatisch, und das neue SVD-File wird verwenden.&lt;br /&gt;
*Debug-Einstellungen mit &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; schließen&lt;br /&gt;
&lt;br /&gt;
===Projekt als Template abspeichern===&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;File -&amp;gt; Save project as template...&#039;&#039;&#039;&#039;&#039;. Das Template erscheint dann im Projekt-Dialog unter &#039;&#039;&#039;&#039;&#039;User templates&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Das erste Projekt erstellen==&lt;br /&gt;
Hier erkläre ich, wie man am Besten (aus meiner Sicht), ein neues Projekt von Grund auf erstellt, sodass man hinterher, den Controller-Kern über die CMSIS-Library und die Peripherie über die Register steuern kann.&lt;br /&gt;
&lt;br /&gt;
===1. Projekt mit der IDE erstellen===&lt;br /&gt;
Nach der Installation der oben beschriebenen Komponenten erstellt man am besten ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\EmBlocks&#039;&#039;&#039;&#039;&#039;), indem später alle Projekte gespeichert werden. Für Libraries kann man auch noch ein Verzeichnis (z.B. &#039;&#039;&#039;&#039;&#039;Dokumente\STM32&#039;&#039;&#039;&#039;&#039;) erstellen, wo alle Libraries gespeichert werden, die man für die Projekt brauchen.&lt;br /&gt;
&lt;br /&gt;
Als nächstes starten man EmBlocks. Bei dem ersten Start öffnet sich ein Fenster, wo verschiedene Compiler angezeigt werden, die Em::Blocks findet. Dort wählt man den &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; aus und klickt &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039;. Nun sollte sich das Hauptfenster von Em::Blocks öffnen. Über &#039;&#039;&#039;&#039;&#039;Create a new Project&#039;&#039;&#039;&#039;&#039; oder &#039;&#039;&#039;&#039;&#039;File -&amp;gt; New -&amp;gt; Project&#039;&#039;&#039;&#039;&#039; ruft man den Projekt-Dialog auf und kann ein neues Projekt erzeugen.&lt;br /&gt;
&lt;br /&gt;
Auf der Ersten Seite wählen man den &#039;&#039;&#039;&#039;&#039;STmicro-ARM&#039;&#039;&#039;&#039;&#039; Projekt-Typ aus.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_1.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf der nächsten Seite wird man darauf hingewiesen, dass das der entsprechende Projekt-Typ-Dialog ausgeführt wird. Hier kann man ein Häkchen bei &#039;&#039;&#039;&#039;&#039;Skip this page next time&#039;&#039;&#039;&#039;&#039; setzen und auf &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; klicken.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wählen man das zuvor erstellt Verzeichnis unter &#039;&#039;&#039;&#039;&#039;Folder to create Project in&#039;&#039;&#039;&#039;&#039; aus, indem später alle Projekt gespeichert werden. Außerdem geben wir dem Projekt einen Namen (z.B. &#039;&#039;&#039;&#039;&#039;FirstProject&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_2.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach muss man einen Compiler auswählen und bestimmen, welche Projekt-Konfigurationen erszeugt werden sollen. Unter &#039;&#039;&#039;&#039;&#039;Compiler&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;ARM GCC Compiler&#039;&#039;&#039;&#039;&#039; und man kann das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create &amp;quot;Release&amp;quot; configuration&#039;&#039;&#039;&#039;&#039; entfernen, da diese unnötig ist, die Debug-Konfiguration sollte eig. immer ausreichen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_3.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Auf den folgenden Seite wird der Controller ausgewählt. Verwendet man ein STM32F4-Discovery Board müssen folgende Dinge gewählt werden: &#039;&#039;&#039;&#039;&#039;Cortex_M4 (F3xx - F4xx) -&amp;gt; STM32F4xx (Cortex M4 with FPU) -&amp;gt; STM32F407VG&#039;&#039;&#039;&#039;&#039;. Leider sind die Auswahl Möglichkeiten nicht ganz richtig, da auch die F3 Controller einen Cortex M4 Kern und eine FPU haben (Ist aber nicht so wichtig, ist nur eine formale Sache). Außerdem entfernt man das Häkchen bei &#039;&#039;&#039;&#039;&#039;Standard Peripherals Library&#039;&#039;&#039;&#039;&#039; (Wie man die Standard-Peripheral-Library einbindet und verwendet erkläre ich später). Man kann auch das Häkchen bei &#039;&#039;&#039;&#039;&#039;Create hex file for Realease target&#039;&#039;&#039;&#039;&#039; entfernen.&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Stack Size&#039;&#039;&#039;&#039;&#039; und &#039;&#039;&#039;&#039;&#039;Heap Size&#039;&#039;&#039;&#039;&#039; wird die Größe von Stack und Heap festgelegt. Für eine erste Anwendung kann man die Einstellungen so lassen (Stack-Size: 0x0100 =&amp;gt; 256 Byte Stack und Heap-Size: 0x0000 =&amp;gt; kein Heap). Mit &#039;&#039;&#039;&#039;&#039;Finish&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_4.png|Neues Projekt erstellen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollten sich zwei neue Fenster öffnen, um die Debug-Eigenschaften fest zu legen.&lt;br /&gt;
Verwendet man ein Discovery Board/ST-Link müssen die Einstellungen wie auf dem Bild gewählt werden. Über den Button &#039;&#039;&#039;&#039;&#039;Settings&#039;&#039;&#039;&#039;&#039; öffnet sich das zweite Fenster, falls sich dieses nicht schon von alleine öffnen sollte. Nach den Schließen der Fenster über &#039;&#039;&#039;&#039;&#039;OK&#039;&#039;&#039;&#039;&#039; ist der Projekt Dialog beendet und ein neues Projekt steht zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_1.png|Debug Eigenschaften 1. Fenster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_5_2.png|Debug Eigenschaften 2. Fenster]]&lt;br /&gt;
&lt;br /&gt;
===2. CMSIS-Library und Startup-Code hinzufügen===&lt;br /&gt;
Wenn man sich, nachdem man ein neues Projekt in der IDE erstellt hat, die bereits vorhandenen Dateien im Projekt ansieht, stellt man fest, das bereits ein Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039; existiert, der einige wichtige Include-Dateien der CMSIS-Library enthält. Allerdings sind das wirklich nur die wichtigsten Include-Dateien der CMSIS-Library und dazu noch, die aus einer älteren Version. Ich ziehe es deshalb vor die &amp;quot;Mini-CMSIS-Libraray&amp;quot; und die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c/.h&#039;&#039;&#039;&#039;&#039; Dateien des Projektes durch aktuellere Versionen zu ersetzen. So ist später auch die Integration  von anderen Libraries, wie z.B. der CMSIS-DSP-Libarary einfacher.  &lt;br /&gt;
&lt;br /&gt;
Zunächst gehen man in das Projekt-Verzeichnis und löscht:&lt;br /&gt;
*Den Ordner &#039;&#039;&#039;&#039;&#039;cmsis&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Alle Dateien im Include Verzeichnis &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; im &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
Außerdem entfernt man auch alle gelöschten Dateien in der IDE aus dem Projekt mit &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Remove file from project&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es sollte folgende Verzeichnis Struktur überbleiben:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_6.png|Überbleibende Dateien]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt müssen die gelöschten Dateien durch die aktuelleren ersetzt werden.&lt;br /&gt;
&lt;br /&gt;
*Dazu kopieren man den gesamten Ordner &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; aus dem CMSIS Download in das Projekt Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
*Aus dem Standard-Peripheral-Library Download kopiert man von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Include&#039;&#039;&#039;&#039;&#039; alle Dateien in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projekt Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
*Aus der Standard-Peripheral-Library kopieren man ebenfalls von &#039;&#039;&#039;&#039;&#039;Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates&#039;&#039;&#039;&#039;&#039; die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; in den &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner des Projekts&lt;br /&gt;
&lt;br /&gt;
Anschließend müssen die neuen Dateien in der IDE dem Projekt hinzugefügt werden. Dazu benutzt man &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Rechts Klick -&amp;gt; Add files&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
*Aus dem &#039;&#039;&#039;&#039;&#039;CMSIS&#039;&#039;&#039;&#039;&#039; Ordner im Projekt Verzeichnis werden aus den Unterorder &#039;&#039;&#039;&#039;&#039;Include&#039;&#039;&#039;&#039;&#039; folgende Dateien dem Projekt hinzugefügt:&lt;br /&gt;
**arm_common_tables.h&lt;br /&gt;
**arm_const_structs.h&lt;br /&gt;
**arm_math.h&lt;br /&gt;
**core_cm4.h&lt;br /&gt;
**core_cm4_simd.h&lt;br /&gt;
**core_cmFunc.h&lt;br /&gt;
**core_cmInstr.h&lt;br /&gt;
*Alle Dateien aus den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes&lt;br /&gt;
*Die Datei &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; aus dem &#039;&#039;&#039;&#039;&#039;src&#039;&#039;&#039;&#039;&#039; Ordner&lt;br /&gt;
&lt;br /&gt;
So sollte die Struktur dann aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Datei:new_project_7.png|Anwenungs-Grundgerüst]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Da einige Dateien der Libraries später bearbeitet werden müssen und Schreibgeschützt sind, weise ich hier schonmal darauf hin, das der Schreibschutz in der IDE über &#039;&#039;&#039;&#039;&#039;Rechts Klick auf die Datei -&amp;gt; Properties -&amp;gt; Häkchen bei &amp;quot;File is read only&amp;quot; entfernen&#039;&#039;&#039;&#039;&#039; entfert werden kann.&lt;br /&gt;
&lt;br /&gt;
Damit die IDE die Header-Dateien der CMSIS Library auch finden kann, weil diese ja nicht im standard Include Ordner &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; liegen, muss unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Search Directories&#039;&#039;&#039;&#039;&#039; der Pfad &#039;&#039;&#039;&#039;&#039;CMSIS\Include&#039;&#039;&#039;&#039;&#039; hinzugefügt werden.&lt;br /&gt;
&lt;br /&gt;
Compiliert man jetzt das Projekt mit &#039;&#039;&#039;&#039;&#039;F7&#039;&#039;&#039;&#039;&#039; gibt es ein paar Fehler Meldungen, weil keine Controller-Reihe ausgewählt wurde. Ebenfalls unter &#039;&#039;&#039;&#039;&#039;FirstProject -&amp;gt; Build Options -&amp;gt; Compiler Settings -&amp;gt; #defines&#039;&#039;&#039;&#039;&#039; wird der Define &#039;&#039;&#039;&#039;&#039;STM32F40_41xxx&#039;&#039;&#039;&#039;&#039; hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Beim erneuten Compilieren sollten sich nun keine neuen Fehler ergeben.&lt;br /&gt;
&lt;br /&gt;
===3. Das erste Programm===&lt;br /&gt;
Nachdem ein grundsätzliches &amp;quot;Gerüst&amp;quot; fertig ist, kann man den ersten Code schreiben.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC-&amp;gt;AHB1ENR |= RCC_AHB1ENR_GPIODEN;    //Takt für GPIO aktivieren&lt;br /&gt;
    GPIOD-&amp;gt;MODER |= GPIO_MODER_MODER15_0;   //GPIOD Pin15 als Ausgang&lt;br /&gt;
    GPIOD-&amp;gt;BSRRL |= GPIO_BSRR_BS_15;        //GPIOD Pin15 auf High ziehen&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;&#039;&#039;&#039;F8&#039;&#039;&#039;&#039;&#039; wird dann der Debugger gestartet. Hat der Debugger das Projekt erfolgreich übertragen kann die Ausführung mit &#039;&#039;&#039;&#039;&#039;F5&#039;&#039;&#039;&#039;&#039; begonnen werden.&lt;br /&gt;
&lt;br /&gt;
==Libraries einbinden/verwenden==&lt;br /&gt;
Um Libraries, wie hier im Tutorial, einzubinden, wird ein existierendes Projekt, wie ein im Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Das_erste_Projekt_erstellen Das Erste Projekt erstellen] beschrieben wird, vorausgesetzt.&lt;br /&gt;
&lt;br /&gt;
===Einbinden der Standard-Peripheral-Library===&lt;br /&gt;
Um nicht immer die einzelnen Register, wie im ersten &amp;quot;bare-metal&amp;quot; Beispiel, aus dem Reference-Manual zu suchen und zu beschreiben, gibt es von ST die Standard Peripheral Library, die diese Aufgaben übernimmt und mit der sich die &amp;quot;normale/grundlegende&amp;quot; (Alles außer USB und Ethernet) Peripherie recht einfach steuern lässt. Ich kopiere die Standard-Peripheral-Library immer per Hand in das Projekt. Darduch hat man auch gleich die aktuellste Version (in den älteren Version gibt es einige Bugs). &lt;br /&gt;
&lt;br /&gt;
*1. Den Ordner &#039;&#039;&#039;&#039;&#039;Libraries\STM32F4xx_StdPeriph_Driver&#039;&#039;&#039;&#039;&#039; aus dem Standard-Peripheral-Library Download in das Projekt-Verzeichnis kopieren&lt;br /&gt;
*2. Die Datei &#039;&#039;&#039;&#039;&#039;Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h&#039;&#039;&#039;&#039;&#039; ebenfalls aus dem Standard-Peripheral-Library Download in den &#039;&#039;&#039;&#039;&#039;inc&#039;&#039;&#039;&#039;&#039; Ordner des Projektes kopieren.&lt;br /&gt;
*3. In der IDE den Include-Path &#039;&#039;&#039;&#039;&#039;STM32F4xx_StdPeriph_Driver\inc&#039;&#039;&#039;&#039;&#039; hinzufügen&lt;br /&gt;
*4. Und das/den Define &#039;&#039;&#039;&#039;&#039;USE_STDPERIPH_DRIVER&#039;&#039;&#039;&#039;&#039; hinzufügen&lt;br /&gt;
*4. Source- und Include-Dateien zum Projekt hinzufügen&lt;br /&gt;
**Achtung: Es dürfen nur die Dateien hinzugefügt werden, für die der Controller auch die entsprechende Peripherie bereit stellt. Diese Dateien dürfen nicht beim STM32F4-Discovery/STM32F407VG hinzugefügt werden.&lt;br /&gt;
***stm32f4xx_dma2d.c/.h&lt;br /&gt;
***stm32f4xx_fmc.c/.h&lt;br /&gt;
***stm32f4xx_ltdc.c/.h&lt;br /&gt;
***stm32f4xx_sai.c/.h&lt;br /&gt;
&lt;br /&gt;
Daraus resultiert folgende Struktur:&lt;br /&gt;
&lt;br /&gt;
[[Datei:stdperiphlib_2.png|Header-Struktur]] [[Datei:stdperiphlib_1.png|Source-Struktur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschließen kann die Standard-Peripheral-Library benutz werden.&lt;br /&gt;
main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOD_InitStructure;&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Mode = GPIO_Mode_OUT;     //Als Ausgang&lt;br /&gt;
    GPIOD_InitStructure.GPIO_OType = GPIO_OType_PP;    //Push-Pull Betrieb&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Pin = GPIO_Pin_15;        //Pin 15 (STM32F4-Discovery: Blaue LED)&lt;br /&gt;
    GPIOD_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  //Kein Pull-Up oder Pull-Down Widerstand aktiviert&lt;br /&gt;
    GPIOD_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //25MHz Update-Rate&lt;br /&gt;
    GPIO_Init(GPIOD, &amp;amp;GPIOD_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    GPIO_SetBits(GPIOD, GPIO_Pin_15);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier ist noch ein &amp;quot;BasicFramework&amp;quot;, dass die komplette CMSIS- und Standard-Peripheral-Library enthält und kann Quasi als Basis für alle Projekte verwendet werden. Allerdings ist das Framework primär auf die STM32F405/7 und STM32F415/7 ausgelegt. Die neueren STM32F401, STM32F42X und STM32F43X  haben noch etwas andere Peripherie, dass Framework müsste dann entsprechend angepasst werden. Download: [[Datei:StdPeriphDriver_BasicFramework.zip]]&lt;br /&gt;
&lt;br /&gt;
===Einbinden der DSP-Library===&lt;br /&gt;
STM32F3 / STM32F4 Microcontroller haben neben der FPU noch einen Digital-Signal-Processor (DSP). Die DSP dient hauptsächlich dazu, viele Daten schnell zu verarbeiten (z.B. Video- oder Audiosignal). Der CMSIS-Download beinhaltet dazu neben der eigentlichen CMSIS-Library auch noch eine DSP-Library. Diese Library stellt sowohl einfache, mathematische Funktionen wie addieren, multiplizieren usw. als auch komplexe Funktionen, wie z.B  einen IIR-Filter, zur Verfügung. Die DSP-Library ist weiter aufgeteilt in kleinere Module, wie z.B. BasicMathFunctions, FilteringFunctions usw. (siehe &#039;&#039;&#039;&#039;&#039;CMSIS\DSP-Library\Source&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
*1. Source-Dateien des benötigten Moduls zum Projekt hinzufügen. (&#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Add files...&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
*2. &#039;&#039;&#039;&#039;&#039;arm_math.h&#039;&#039;&#039;&#039;&#039; in der &#039;&#039;&#039;&#039;&#039;main.c&#039;&#039;&#039;&#039;&#039; einbinden&lt;br /&gt;
*3. Damit die Warnung &amp;quot;Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)&amp;quot; verschwindet, muss der Define &#039;&#039;&#039;&#039;&#039;__FPU_PRESENT&#039;&#039;&#039;&#039;&#039; hinzugefügt werden. (Keine Ahnung, wieso es die Warnung gibt)&lt;br /&gt;
 &lt;br /&gt;
Jetzt kann die DSP-Library verwedet werden. Das Beispiel multipliziert zwei Buffer miteinander. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
#include &amp;quot;arm_math.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    float32_t x[1024];&lt;br /&gt;
    float32_t y[1024];&lt;br /&gt;
    float32_t z[1024];&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        x[i] = i;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(uint16_t i = 0; i &amp;lt; 1024; i++)&lt;br /&gt;
    {&lt;br /&gt;
        y[i] = PI;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    arm_mult_f32(x, y, z, 1024);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Startup-Code, Linker-Script, Takt, FPU usw.==&lt;br /&gt;
===Startup-Code===&lt;br /&gt;
Em::Blocks fügt standardmäßig einen Startup-Code mit in das Projekt ein. Die wichtigsten Dinge die darin erledigt werden sind folgende:&lt;br /&gt;
&lt;br /&gt;
*Stack und Heap wird angelgt&lt;br /&gt;
*Die Vector-Table wird angelegt&lt;br /&gt;
*Ein Default Reset-Handler wird implementiert, dieser erledigt folgende aufgaben:&lt;br /&gt;
**Kopieren der definierten Daten aus dem Flash in den SRAM&lt;br /&gt;
**&#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; wird aufgerufen, wenn &#039;&#039;&#039;&#039;&#039;__NO_SYSTEM_INIT&#039;&#039;&#039;&#039;&#039; nicht definiert ist&lt;br /&gt;
**Sprung in die &#039;&#039;&#039;&#039;&#039;main()&#039;&#039;&#039;&#039;&#039; Funktion&lt;br /&gt;
*Allen anderen Interrupt-Handler wird eine Default-Funktion &#039;&#039;&#039;&#039;&#039;def_irq_handler&#039;&#039;&#039;&#039;&#039; mit einer &#039;&#039;&#039;&#039;&#039;while(1)&#039;&#039;&#039;&#039;&#039;-Schleife zugewiesen, falls kein anderer Interrupt-Handler existiert.&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss am Startup-Code nichts verändert werden.&lt;br /&gt;
&lt;br /&gt;
===Linker-Script===&lt;br /&gt;
Em::Blocks stellt zwei fertige Linker-Scripts bereit, eins für die Ausführung des Programmes aus dem Flash (&#039;&#039;&#039;&#039;&#039;*_flash.ld&#039;&#039;&#039;&#039;&#039;), das andere für die Ausführung aus dem SRAM (&#039;&#039;&#039;&#039;&#039;*_sram.ld&#039;&#039;&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Normalerweise muss auch hier nichts geändert werden, es sei den Daten sollen in bestimmten Adressbereichen abgelegt werden (z.B. im Core-Coupled RAM), was ich später noch zum Tutorial hinzufüge.&lt;br /&gt;
&lt;br /&gt;
===Der Takt===&lt;br /&gt;
Jeder Controller oder Prozessor braucht einen Takt, indem er die einzelnen Maschinen-Befehle abarbeiten kann.&lt;br /&gt;
Bei den STM32 Mikrocontrollern kann dieser Takt aus verschiedenen Quellen kommen:&lt;br /&gt;
&lt;br /&gt;
1. High Speed Internal Oszillator (HSI)&lt;br /&gt;
&lt;br /&gt;
2. High Speed External Oszillator (HSE)&lt;br /&gt;
&lt;br /&gt;
3. Low Speed Internal Oszillator (LSI)&lt;br /&gt;
&lt;br /&gt;
4. Low Speed External Oszillator (LSE)&lt;br /&gt;
&lt;br /&gt;
5. Phase-Locked Loop (PLL) (generiert den Takt aus den ersten vier Taktquellen durch Teiler und Faktoren)&lt;br /&gt;
&lt;br /&gt;
Nach einem Reset wird der Controller aus der HSI Taktquelle versorgt (16MHz beim STM32F407VG). Um die voll Performance des Controllers zu erreichen muss die PLL verwendet werden, welche den Takt durch geschickte Teiler und Faktoren vervielfältigt, sodass am Ende der Controller mit der maximalen Taktfrequenz läuft. Die notwendige Initialisierung der PLL findet in der Funktion &#039;&#039;&#039;&#039;&#039;SystemInit()&#039;&#039;&#039;&#039;&#039; statt. Die PLL erzeugt zunächst einen Basistakt:&lt;br /&gt;
&lt;br /&gt;
PLL_VCO = (F_HSE / PLL_M) * PLL_N&lt;br /&gt;
&lt;br /&gt;
Aus diesem Takt wird dann der Takt für den Controller-Kern abgeleitet:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = PLL_VCO / PLL_P&lt;br /&gt;
&lt;br /&gt;
Und der Takt für SDIO / USB / RNG (48MHz):&lt;br /&gt;
&lt;br /&gt;
48MHz = PLL_VCO / PLL_Q&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Durch weiter Teiler werden, die Takte für die einzelnen Busse erzeugt, da diese nicht alle beliebig schnell betrieben werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Genaue Angaben findet man zu dem jeweiligen Clock-System des Controllers im Reference Manual.&lt;br /&gt;
&lt;br /&gt;
Ein Blick in den &amp;quot;Kommentar-Header&amp;quot; verrät, dass von einem externen (HSE) Oszillator von 25MHz ausgegangen wird, der die PLL versorgen soll.&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((25MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Allerdings stimmt diese Rechnung natürlich nur, wenn wirklich ein 25MHz Quarz am Controller angeschlossen ist. Auf dem STM32F4-Discovery Board befindet sich aber nur ein 8MHz Quarz. Demnach gilt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(25)) * PLL_N(336)) / PLL_P(2) = 53.76MHz&lt;br /&gt;
&lt;br /&gt;
Der Controller läuft also nur mit 53.76MHz, wenn wie ober beschrieben ein Projekt erstellt wird. Allerdings kann dieses Problem durch ändern von den betroffen Defines behoben werden:&lt;br /&gt;
 &lt;br /&gt;
*Dazu geht man in die &#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Datei und passt zur Vollständigkeit erstmal die zum Controller passende Tabelle im &amp;quot;Kommentar-Header&amp;quot; an (Z.57f):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      HSE Frequency(Hz)                      | 8000000&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
*      PLL_M                                  | 8&lt;br /&gt;
*-----------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Danach passt man den PPL_M Define (Z.254) an:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************* PLL Parameters *************************************/&lt;br /&gt;
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */&lt;br /&gt;
#define PLL_M      8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Außerdem muss man den HSE_VALUE Define in der &#039;&#039;&#039;&#039;&#039;inc/stm32f4xx.h&#039;&#039;&#039;&#039;&#039; angepasst werden (Z.122):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if !defined  (HSE_VALUE)&lt;br /&gt;
  #define HSE_VALUE    ((uint32_t)8000000) /*!&amp;lt; Value of the External oscillator in Hz */&lt;br /&gt;
&lt;br /&gt;
#endif /* HSE_VALUE */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine neue Berechnung zeigt:&lt;br /&gt;
&lt;br /&gt;
SYSCLK = ((8MHz / PLL_M(8)) * PLL_N(336)) / PLL_P(2) = 168MHz&lt;br /&gt;
&lt;br /&gt;
Jetzt läuft der Controller mit maximaler Geschwindigkeit.&lt;br /&gt;
&lt;br /&gt;
Die Theorie wird durch folgendes Programm verifiziert. Der geviertelte System-Takt SYSCLK wir am Pin PC9 ausgegeben. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);&lt;br /&gt;
&lt;br /&gt;
    GPIO_InitTypeDef GPIOC_InitStructure;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Mode = GPIO_Mode_AF;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_OType = GPIO_OType_PP;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Pin = GPIO_Pin_9;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;&lt;br /&gt;
    GPIOC_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;&lt;br /&gt;
    GPIO_Init(GPIOC, &amp;amp;GPIOC_InitStructure);&lt;br /&gt;
&lt;br /&gt;
    RCC_MCO2Config(RCC_MCO2Source_SYSCLK, RCC_MCO2Div_4);&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Die FPU===&lt;br /&gt;
====Allgemeines====&lt;br /&gt;
STM32F3 und STM32F4 Controller haben eine FPU.&lt;br /&gt;
Damit die FPU richtig verwendet wird, müssen normalerweise zwei Bedingungen erfüllt sein:&lt;br /&gt;
&lt;br /&gt;
1. Der Controller muss die FPU Hardware-seitig aktivieren&lt;br /&gt;
&lt;br /&gt;
2. Damit die FPU auch was zu tuen bekommt, müssen vom Compiler FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
Die Em::Blocks IDE verwendet standardmäßig die FPU, wenn eine Vorhanden ist. Hier wird die FPU Hardware-seitig aktiviert (&#039;&#039;&#039;&#039;&#039;system_stm32f4xx.c&#039;&#039;&#039;&#039;&#039; Z.341):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* FPU settings ------------------------------------------------------------*/&lt;br /&gt;
  #if (__FPU_PRESENT == 1) &amp;amp;&amp;amp; (__FPU_USED == 1)&lt;br /&gt;
    SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2));  /* set CP10 and CP11 Full Access */&lt;br /&gt;
  #endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__FPU_PRESENT wird in der &#039;&#039;&#039;&#039;&#039;stm32f4xx.h&#039;&#039;&#039;&#039;&#039; definiert.&lt;br /&gt;
__FPU_USED wird von der IDE übernommen (siehe Build-Log): &#039;&#039;&#039;&#039;&#039;-D__FPU_USED&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Außerdem wird der Compiler von der IDE standardmäßig mit dem Argument &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039; aufgerufen, wodurch FPU-Instructions erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
====FPU abschalten====&lt;br /&gt;
Um die FPU ab zu schalten (Mir würde jetzt nur Strom sparen als Grund einfallen) geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;&amp;lt;ProjektName&amp;gt; -&amp;gt; Rechts Klick -&amp;gt; Build options... -&amp;gt; Device -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; und über nimmt die Einstellungen, die vorher dort eingetragen waren, allerdings lässt man das Feld &#039;&#039;&#039;&#039;&#039;FP-hardware&#039;&#039;&#039;&#039;&#039; frei.&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_1.png|FPU Abschalten Schritt 1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Unter &#039;&#039;&#039;&#039;&#039;Compiler Settings -&amp;gt; Policy&#039;&#039;&#039;&#039;&#039; wählt man dann &#039;&#039;&#039;&#039;&#039;Use target options only&#039;&#039;&#039;&#039;&#039;. Dann kann man unter &#039;&#039;&#039;&#039;&#039;Categories&#039;&#039;&#039;&#039;&#039; die Option &#039;&#039;&#039;&#039;&#039;ARM FPU architecture&#039;&#039;&#039;&#039;&#039; auswählen. Dort stehen dann drei Möglichkeiten für die FPU zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
1. Software-FPU-Library für Gleitkomma-Berechnung verwenden - Keine FPU-Instructions werden generiert (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=soft&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
2. Eine Mischung aus Software- und Hardware-FPU wird verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=softfp&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
3. Hardware-FPU wird für Gleitkomma-Berechnungen verwendet (Compiler-Argument: &#039;&#039;&#039;&#039;&#039;-mfloat-abi=hard&#039;&#039;&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[Datei:fpu_2.png|FPU Abschalten Schritt 2]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um die FPU ab zu schalten wählt man natürlich die erste Möglichkeit.&lt;br /&gt;
Bei der 2. und 3. Möglichkeit fügt die IDE auch den Define &#039;&#039;&#039;&#039;&#039;__FPU_USED&#039;&#039;&#039;&#039;&#039; hinzu. Bei Der ersten Möglichkeit nicht. Der Code muss also nicht verändert / auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
Um die FPU wieder zu aktivieren müssen alle Schritte wieder rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Am besten ist es einfach mal alle Möglichkeiten im Einzelschritt durch zu probieren. Dann stellt man schnell fest, ob die FPU aktiviert wir oder nicht. Ein Blick in den erweiterten &#039;&#039;&#039;&#039;&#039;Build-Log&#039;&#039;&#039;&#039;&#039; gibt auch schnell Aufschluss darüber, wie der Compiler aufgerufen wird (siehe Kapitel [http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks#Compilieren Compilieren]).&lt;br /&gt;
&lt;br /&gt;
====Test Programm für die FPU====&lt;br /&gt;
Hier ein kleines Testprogramm, dass misst wie viele Taktzyklen für eine Gleitkomma-Multiplikation gebraucht werden. main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;stm32f4xx.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define CORE_SysTickEn()    (*((u32*)0xE0001000)) = 0x40000001&lt;br /&gt;
#define CORE_SysTickDis()   (*((u32*)0xE0001000)) = 0x40000000&lt;br /&gt;
#define CORE_GetSysTick()   (*((u32*)0xE0001004))&lt;br /&gt;
&lt;br /&gt;
uint32_t t1, t2, dt;&lt;br /&gt;
float x, y, z;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    x = 53.64f;&lt;br /&gt;
    y = 0.27f;&lt;br /&gt;
&lt;br /&gt;
    CORE_SysTickEn();&lt;br /&gt;
    t1 = CORE_GetSysTick();&lt;br /&gt;
&lt;br /&gt;
    z = x * y;&lt;br /&gt;
&lt;br /&gt;
    t2 = CORE_GetSysTick();&lt;br /&gt;
    CORE_SysTickDis();&lt;br /&gt;
&lt;br /&gt;
    dt = (t2 - t1) - 9; //9 Takt-Zyklen werden für die Messung gebraucht &lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Core-Coupled-RAM verwenden===&lt;br /&gt;
Auf den normale SRAM kann durch den Core und die verschiedenen DMA-Controller zugegriffen werden. Jedoch können Core und DMA nicht gleichzeitig auf den SRAM zugreifen. Deswegen gibt es einen zweiten kleinen RAM, den Core-Coupled-RAM (CCRAM), auf den nur vom Core zugegriffen werden kann und nicht von einem DMA-Controller. Der CCRAM ist über einen anderen Bus an dem Cortex angeschlossen. Daduch wird ermöglicht, dass der Core sinnvoll weiterarbeiten kann, wenn ein DMA-Controller Daten aus den &amp;quot;Haupt&amp;quot;-RAM ließt/schreibt, indem der Core Daten aus dem CCRAM verarbeitet. Um Daten in den CCRAM zu legen, geht man wie folgt vor:&lt;br /&gt;
&lt;br /&gt;
1. Eine neue Section im Linkerscript anlegen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
Sections:&lt;br /&gt;
{&lt;br /&gt;
  ...&lt;br /&gt;
&lt;br /&gt;
  .ccram :&lt;br /&gt;
  {&lt;br /&gt;
    *(.ccram)&lt;br /&gt;
  } &amp;gt; CCRAM&lt;br /&gt;
&lt;br /&gt;
  ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Um die neue Section zu verwenden benutzt man diesen Define:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define CCRAM __attribute__((section(&amp;quot;.ccram&amp;quot;)))&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
int CCRAM dataInCCRAM;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beim Debuggen stellt man fest das die Variable an der Adresse 0x10000000 liegt, der ersten Adresse das CCRAM&#039;s.&lt;br /&gt;
&lt;br /&gt;
==Booten aus dem SRAM==&lt;br /&gt;
STM32 Controller haben die Möglichkeit Code aus dem Flash als auch aus dem SRAM auszuführen. Um eine Anwenung per Debugger in des SRAM zu laden sind nur wenige Schritte erforderlich:&lt;br /&gt;
&lt;br /&gt;
*Um das Linkerscript für den SRAM zu verwenden geht man zu: &#039;&#039;&#039;&#039;&#039;Build options... -&amp;gt; Device&#039;&#039;&#039;&#039;&#039; dort wählt man unter &#039;&#039;&#039;&#039;&#039;Policy&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Use target settings&#039;&#039;&#039;&#039;&#039; aus und übernimmt die vorherigen Einstellungen, nur unter &#039;&#039;&#039;&#039;&#039;Linker script*&#039;&#039;&#039;&#039;&#039; gibt man &#039;&#039;&#039;&#039;&#039;.\stm32f407vg_sram.ld&#039;&#039;&#039;&#039;&#039; an&lt;br /&gt;
&lt;br /&gt;
*Dann muss man noch unter &#039;&#039;&#039;&#039;&#039;Debug -&amp;gt; Interfaces -&amp;gt; Settings&#039;&#039;&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Vector table start&#039;&#039;&#039;&#039;&#039; auf 0x20000000 ändern und &#039;&#039;&#039;&#039;&#039;Execute from RAM&#039;&#039;&#039;&#039;&#039; auswählen.&lt;br /&gt;
&lt;br /&gt;
*Bei Verwendung von Interrupts muss weiterhin das Symbol VECT_TAB_SRAM definiert werden. (&#039;&#039;&#039;&#039;&#039;Project -&amp;gt; Build Options -&amp;gt; Debug -&amp;gt; Compiler Settings -&amp;gt; Reiter #defines -&amp;gt; Dort VECT_TAB_SRAM einfügen)&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Datei:bootsram_1.png Booten aus dem SRAM]] [[Datei:bootsram_2.png Booten aus dem SRAM]]&lt;br /&gt;
&lt;br /&gt;
Anschließend kann man die Anwendung ganz normal debuggen. Nach einem Reset muss die Anwenung erneut mit dem Debugger gestartet werden.&lt;br /&gt;
&lt;br /&gt;
=Fortsetzung folgt..=&lt;br /&gt;
Kritik, Wünsche usw. sind gerne erwünscht, am besten hier in den Thread posten: [http://www.mikrocontroller.net/topic/323750 Neues STM32 Tutorial]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]]&lt;br /&gt;
[[Category:STM32]]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=RFM69&amp;diff=83187</id>
		<title>RFM69</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=RFM69&amp;diff=83187"/>
		<updated>2014-05-29T05:05:16Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: /* FS20 Funksteckdosen schalten */ Schreibfehler korrigiert&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Datei:rf69cw.png|thumb|300px|RFM69CW, Pinkompatibel zum RFM12]]&lt;br /&gt;
Beschreibung des Funkmoduls RFM69 von HopeRF. &lt;br /&gt;
== Ausführungen ==&lt;br /&gt;
* RFM69HCW, mit zusätzlicher PA, 20 dBm&lt;br /&gt;
* RFM69HW, mit zusätzlicher PA, 20 dBm&lt;br /&gt;
* RFM69CW, Pinkompatibel zum RFM12B&lt;br /&gt;
* RFM69W&lt;br /&gt;
&lt;br /&gt;
Die CW-Variante hat 2 Pins weniger (es fehlt der Pin DIO4), und ist Pinkompatibel zum Vorgänger RFM12B.&lt;br /&gt;
Es kann ohne Änderung am Layout oder der Schaltung ausgetauscht werden. Lediglich die Software muss angepasst werden.&lt;br /&gt;
&lt;br /&gt;
== Ausstattung ==&lt;br /&gt;
* Betriebsspannung 1,8 - 3,6 V&lt;br /&gt;
* SPI Schnittstelle&lt;br /&gt;
* FSK und OOK Modulation&lt;br /&gt;
* Eingebauter Manchesterde- und encoder&lt;br /&gt;
* Frequenzbereiche 315, 433, 868, 915 MHz&lt;br /&gt;
* Max. Datenrate 300 kbit/s&lt;br /&gt;
* Ausgangsleistung +13 dBm (rund 20 mW)&lt;br /&gt;
* Stromaufnahme 45 mA senden (13 dBm), 16 mA empfangen, 0,1 µA stand by&lt;br /&gt;
* Integrierte Packetengine für Synchronwort, CRC, Scrambling und AES-Verschlüsselung&lt;br /&gt;
* 66 Byte FIFO&lt;br /&gt;
&lt;br /&gt;
== Vergleich zum RFM12B ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! !! RFM12B !! RFM69(C)W&lt;br /&gt;
|-&lt;br /&gt;
| Versorgungsspannung || 2,2 - 3,8 V || 1,8 - 3,6 V&lt;br /&gt;
|-&lt;br /&gt;
| Max. Datenrate || 115,2 kbit/s || 300 kbit/s&lt;br /&gt;
|-&lt;br /&gt;
| Sendeleistung || 5 dBm || 13 dBm&lt;br /&gt;
|-&lt;br /&gt;
| Empfindlichkeit || -105 dB || -120 dB&lt;br /&gt;
|-&lt;br /&gt;
| Stromaufnahme || 22 mA/11 mA/0,3 µA || 45 mA/16 mA/0,1 µA&lt;br /&gt;
|-&lt;br /&gt;
| FIFO Größe || 16 Bit || 66 Bytes&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Ansteuerung ==&lt;br /&gt;
Das Funkmodul kommuniziert über die SPI Schnittstelle mit dem µC. Im einfachsten Fall werden SCK, MISO, MOSI und NSS benötigt. Am besten führt man auch noch DIO0 zum Prozessor. Dieser Pin kann softwareseitig so konfiguriert werden, dass er anzeigt, wenn ein Packet vollständig gesendet oder ein neues Packet empfangen wurde. Ist das Modul in Minimalkonfiguration angeschlossen, müssen dazu die Statusregister RegIrqFlags1 (0x27) oder RegIrqFlags2 (0x28) ausgelesen werden.&lt;br /&gt;
&lt;br /&gt;
Die SPI-Ansteuerung erfolgt im Modus CPOL=0, CPHA=0, wobei jeweils 16-bit vom µC zum Modul geschickt werden:&lt;br /&gt;
Das erste Bit teilt dem Modul mit, ob es sich um einen Lese- (Bitwert 0) oder Schreibvorgang (Bitwert 1) handelt, die restlichen sieben Bit des ersten Bytes geben die Registeradresse an. Mit den zweiten acht Bit wird im Schreibmodus der zu übertragende Befehl an das Modul übermittelt, im Lesemodus kann eine beliebige Bitfolge gesendet werden. Während des zweite Bit gesendet wird, empfängt der µC sowohl im Lese- als auch im Schreibmodus den Inhalt des angesprochenen Registers vor dem aktuellen Zugriff.&lt;br /&gt;
&lt;br /&gt;
Werden nach dem Adressbyte mehrere Bytes empfangen oder gelesen, wird der Adresszeiger im RFM69 automatisch inkrmentiert, so dass in einem einzigen Burst mehrere Register gelesen werden können. Zu beachten ist dabei dass in Registern die mehr als 8 Bit breit sind (Frequenz, Bitrate, ...) das höchstwertige Byte zu erst geschrieben / gelesen wird (big endian). Wird das FIFO Register gelesen/geschrieben, wird der Adresszeiger nicht inkrementiert, so dass auf das FIFO in einem Burst zugegriffen werden kann.&lt;br /&gt;
&lt;br /&gt;
== Pinbelegung RFM69(H)CW ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Pinnummer !! Name !! Richtung !! Beschreibung !! Pin am RFM12&lt;br /&gt;
|-&lt;br /&gt;
| 1 || ANA || || Antennenanschluss || ANT&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 3.3V || || Versorgungsspannung || VDD&lt;br /&gt;
|-&lt;br /&gt;
| 3 || GND || || || GND&lt;br /&gt;
|-&lt;br /&gt;
| 4 || DIO3 || || FifoFull&amp;amp;nbsp;PllLock&amp;lt;br/&amp;gt;Rssi&amp;lt;br/&amp;gt;SyncAdress&amp;lt;br/&amp;gt;TXReady || nINT/VDI&lt;br /&gt;
|-&lt;br /&gt;
| 5 || MOSI || || SPI Daten Eingang || SDI&lt;br /&gt;
|-&lt;br /&gt;
| 6 || SCK || || SPI Takt || SCK&lt;br /&gt;
|-&lt;br /&gt;
| 7 || NSS || || Chip select || nSEL&lt;br /&gt;
|-&lt;br /&gt;
| 8 || MISO || || SPI Daten Ausgang || SDO&lt;br /&gt;
|-&lt;br /&gt;
| 9 || DIO0 || || PllLock (FS, TX)&amp;lt;br/&amp;gt;CrcOK (RX)&amp;lt;br/&amp;gt;PayloadReady (RX)&amp;lt;br/&amp;gt;SyncAddress (RX)&amp;lt;br/&amp;gt;Rssi (RX)&amp;lt;br/&amp;gt;PacketSent (TX)&amp;lt;br/&amp;gt;TxReady (TX) || nIRQ&lt;br /&gt;
|-&lt;br /&gt;
| 10 || DIO2 || || FifoNotEmpty (Sleep, Stdby, FS, RX, TX)&amp;lt;br/&amp;gt;AutoMode(Sleep, Stdby, FS, RX, TX)&amp;lt;br/&amp;gt;Data (RX, TX) || FSK/DATA/nFFS&lt;br /&gt;
|-&lt;br /&gt;
| 11 || DIO1 || || FifoLevel (Sleep, Stdby, FS, RX, TX)&amp;lt;br/&amp;gt;FifoFull (Sleep, Stdby, FS, RX, TX)&amp;lt;br/&amp;gt;FifoNotEmpty (Sleep, Stdby, FS, RX, TX)&amp;lt;br/&amp;gt;PllLock (FS, TX)&amp;lt;br/&amp;gt;Timeout (RX) || DCLK/CFIL/FFIT&lt;br /&gt;
|-&lt;br /&gt;
| 12 || DIO5 || || ModeReady&amp;lt;br/&amp;gt;ClkOut (Stdby, FS, RX, TX)&amp;lt;br/&amp;gt;Data (RX, TX) || CLK&lt;br /&gt;
|-&lt;br /&gt;
| 13 || RESET || || || nRES&lt;br /&gt;
|-&lt;br /&gt;
| 14 || GND || || || GND&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Register ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Adresse !! Registername !! Beschreibung !! Beispiel&lt;br /&gt;
|-&lt;br /&gt;
| 0x00 || RegFifo || Zugriff auf das FIFO Register&lt;br /&gt;
|-&lt;br /&gt;
| 0x01 || RegOpMode || Betriebsart (senden, empfangen, ...) || 0x04 = Empfangen&lt;br /&gt;
|-&lt;br /&gt;
| 0x02 || RegDataModule || Modulationsart &amp;amp;-shaping, Packetengine || 0x00 = FSK, Packetengine aktiv&lt;br /&gt;
|-&lt;br /&gt;
| 0x03 - 0x04|| RegBitrate || = FXOSC/Bitrate || 0x1A0B = 6667 -&amp;gt; 4,8 kbit/s&lt;br /&gt;
|-&lt;br /&gt;
| 0x05 - 0x06 || RegFdev || Frequenzabweichung (Hub * 2) || 0x52 = 82 -&amp;gt; 5 kHz&lt;br /&gt;
|-&lt;br /&gt;
| 0x07 - 0x09 || RegFrf || Mittenfrequenz || 0xD91333 = 14226227 -&amp;gt; 868,300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| 0x11|| RegPaLevel || Sendeleistung || 0x12 = 18 -&amp;gt; 0 dBm&lt;br /&gt;
|-&lt;br /&gt;
| 0x19|| RegRxBw || Filterbandbreite || 0b01001 -&amp;gt; 200 kHz&lt;br /&gt;
|-&lt;br /&gt;
| 0x25|| RegDioMapping1 || DIO Funktionen ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x27|| RegIrqFlags1 || Statusflags || 0xD0 -&amp;gt; Empfänger bereit zum Datenempfang&lt;br /&gt;
|-&lt;br /&gt;
| 0x28|| RegIrqFlags2 || Statusflags || 0x03 -&amp;gt; Daten mit erfolgreichem CRC empfangen&lt;br /&gt;
|-&lt;br /&gt;
| 0x2C - 0x2D|| RegPreamble || Preamblelänge ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x2E || RegSyncConfig || Synchronworteinstellungen ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x2F - 0x36 || RegSyncValue || Synchronwort || 0x2DD4&lt;br /&gt;
|-&lt;br /&gt;
| 0x37 || RegPacketConfig1 || Einstellungen Packetengine ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x38 || RegPayloadLength || Datenpacketgröße ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Projekte ==&lt;br /&gt;
=== FS20 Funksteckdosen schalten ===&lt;br /&gt;
Da das RFM69 OOK modulieren kann, können damit die FS20 Funksteckdosen geschaltet werden. FS20 verwendet allerdings eine Art Pulsdauermodulation; eine 1 wird mit 600 µS Träger an gefolgt von 600 µS Träger aus, und eine 0 mit 400 µS an gefolgt von 400 µS aus übertragen. Man teilt einfach das Signal in 200 µS Schlitze ein (OOK-Datenrate 5 kbit/s), und sendet für eine 1 die Folge 111000 und für eine 0 die Folge 1100. Im FS20 Protokoll wird ein 13 Bit langer Header (0000000000001) übertragen, diesen kann man umrechnen und im RFM69 als Syncword einstellen. So wird der Header vom RFM69 bei jeder Übertragung automatisch vorweg ausgesendet.&lt;br /&gt;
&lt;br /&gt;
== Bezugsquellen ==&lt;br /&gt;
[http://shop.seegel-systeme.de/Bauelemente/Funkmodul-RFM69CW-REV-V1-0-868-MHz-SMD.html Seegel Systeme]&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
* [http://www.hoperf.com/upload/rf/RFM69CW-V1.1.pdf Datenblatt RFM69CW]&lt;br /&gt;
* [http://www.hoperf.com/upload/rf/RFM69W-V1.3.pdf Datenblatt RFM69W]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/332579 Thread im Forum: Wer verwendet RFM69]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=KiCad&amp;diff=82138</id>
		<title>KiCad</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=KiCad&amp;diff=82138"/>
		<updated>2014-03-21T17:49:54Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: /* Problem: Case Senitive Symbols ab BZR4646 (Jan./Feb. 2014) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;KiCAD&#039;&#039;&#039; ist ein Open Source [[Schaltplaneditoren|Schaltplaneditor]] und PCB Layoutprogramm für Windows, Linux, Mac OSX.&lt;br /&gt;
&lt;br /&gt;
Diese Seite ist zunächst eine Zusammenfassung aus den KiCAD Beiträgen im Forum. Und gleich zu Anfang ein grosses DANKE an alle KiCAD-User aus dem Forum. Ihr seid zu viele, um jeden einzeln zu nennen. Aber wer sich diese Seite durchliest und den Links folgt, wird euch kennenlernen.  &lt;br /&gt;
&lt;br /&gt;
Hier sollen alte und neue KiCAD-Anwender einen Anlaufpunkt finden und neue, insbesondere µC-relevante Aktivitäten stattfinden. &lt;br /&gt;
&lt;br /&gt;
Diese Seite will keine Konkurrenz zum offiziellen KiCAD Wiki sein, d.h. was dort steht soll hier nicht wiederholt werden und was hier steht wird hoffentlich zum offiziellen KiCAD Wiki wandern.&lt;br /&gt;
&lt;br /&gt;
Wenn ihr Kritik oder Fragen zu KiCAD habt, dann nutzt das Forum! Sobald KiCAD im Betreff steht, wird der Beitrag gelesen und nach Möglichkeit beantwortet. Auch Ideen zu dieser Seite sind sehr willkommen! &lt;br /&gt;
&lt;br /&gt;
== FAQ ==&lt;br /&gt;
&lt;br /&gt;
Siehe auch die offizielle FAQ: http://kicad.sourceforge.net/wiki/index.php/FAQ&lt;br /&gt;
&lt;br /&gt;
TODO: Strukturierung (Allg., Schaltplan, Netlists, Module, Bibliotheken, Layout, Export, 3D)&lt;br /&gt;
&lt;br /&gt;
=== Allgemein ===&lt;br /&gt;
* Warum gefällt dir KiCAD?&lt;br /&gt;
** http://www.mikrocontroller.net/topic/70905#584639&lt;br /&gt;
** http://www.mikrocontroller.net/topic/81396#680502&lt;br /&gt;
** http://www.mikrocontroller.net/topic/83311#697917&lt;br /&gt;
** http://www.mikrocontroller.net/topic/42614#321502&lt;br /&gt;
* Warum gefällt dir KiCAD nicht?&lt;br /&gt;
** Ich verstehe nicht, was du meinst ;-)&lt;br /&gt;
** http://www.mikrocontroller.net/topic/81396#680502&lt;br /&gt;
** http://www.mikrocontroller.net/topic/83311#697969&lt;br /&gt;
&lt;br /&gt;
* Wo gibt es weitere Infos zu KiCAD?&lt;br /&gt;
** Die Offizielle Dokumentation: http://bazaar.launchpad.net/~kicad-developers/kicad/doc/files/head:/doc/help/en/&lt;br /&gt;
** http://www.mikrocontroller.net/topic/98034#848661 (Von 2008, also seeeehr überholt)&lt;br /&gt;
* Welche Leiterplattenfertiger akzeptieren KiCAD Layouts?&lt;br /&gt;
** http://www.pcb-pool.de KiCAD kann &amp;quot;Extended&amp;quot; Gerber RS-247-X erzeugen. Das wird von PCB-Pool akzeptiert. Dabei http://www.pcb-pool.com/download/spezifikation/deu_cmso020_ext_gerber.pdf beachten! Alternativ, wer KiCAD (noch) nicht traut, diese RS-247-X in deren (PCB-Pools) Tool GC-Prevue  http://www.mikrocontroller.net/topic/120373#1092375 einlesen und als .GWK exportieren. AKTUELL August 2012: Wenn man bei PCB-Pool bestellt, ist deren GC-Prevue NICHT mehr erforderlich, weil PCB-Pool mittlerweile KiCAD *,brd Dateien direkt aktzeptiert. Siehe http://www.pcb-pool.com/ppde/info_dataformat.html &lt;br /&gt;
** http://fischer-leiterplatten.de Ohne Aufpreis für Gerber-Import&lt;br /&gt;
&lt;br /&gt;
* Wie geht man mit KiCAD-Trollen um?&lt;br /&gt;
** Mit gesundem Menschenverstand. Trollregeln wie die US AIR FORCE (http://blog.wired.com/defense/2009/01/usaf-blog-respo.html) brauchen wir nicht ;-)&lt;br /&gt;
* Wie kriege ich raus, welche Leiterbahn welchen Netznamen hat, bzw. ich habe den Überblick verloren und weiss nicht mehr, was aus dem Layout nun was im Schaltplan ist?&lt;br /&gt;
**http://www.mikrocontroller.net/topic/218922#2211644. Zusatz: Funktioniert nur gut, wenn großes Fadenkreuz gewählt ist. Aktueller (zu BZR4513 vom 29. November 2013) ist http://www.mikrocontroller.net/topic/316539#3427724&lt;br /&gt;
** Aber ich hätte gerne noch genauere Informationen, z.b. auch über die Länge einer Leiterbahn ec.&lt;br /&gt;
*** Dazu in PCBnew den gleichen Button rechts wie für das Hinzufügen von Leiterbahnen aktivieren. Oder besser noch rechts den zweiten Button von oben &amp;quot;Netz hervorheben&amp;quot;. Dann mit der rechten Maustaste die fragliche Leiterbahn anklicken. Unten in der Statusleiste werden die Informationen angezeigt. &lt;br /&gt;
* Ich würde gerne kicad OHNE Maus bedienen. Wie geht das?&lt;br /&gt;
**http://www.mikrocontroller.net/topic/267538#new&lt;br /&gt;
* Gibt es Sonderzeichen, die ich für Symbole, Module/Footprints oder Files nicht verwenden sollte2&lt;br /&gt;
** Ja, alles was Sonderzeichen ausser - _ . und keine Zahl ist. Siehe: http://www.mikrocontroller.net/topic/302664#3249204&lt;br /&gt;
&lt;br /&gt;
=== Installation ===&lt;br /&gt;
* Woher beziehe ich KiCad?&lt;br /&gt;
** fertig kompiliert z.B. von hier: http://kicad.nosoftware.cz/ (nur die binaries) oder &lt;br /&gt;
** hier: http://iut-tice.ujf-grenoble.fr/cao/&lt;br /&gt;
* Kicad entwickelt sich rasant. Wo finde ich eine Liste der Versionsänderungen?&lt;br /&gt;
** Auf der Kicad Launchpad Seite via bazaar. Siehe: http://www.mikrocontroller.net/topic/298311#3187885&lt;br /&gt;
* Ich habe KiCad unter Linux installiert, aber wenn ich KiCad starten will, passiert einfach nichts, oder ich erhalte eine Fehlermeldung wie: &amp;quot;Datei nicht gefunden&amp;quot;. Siehe: http://www.mikrocontroller.net/topic/307517#new&lt;br /&gt;
** 1) KiCad und seine zugeordneten Programme sollten im Suchpfad stehen. Es wird für Debian und Ableger empfolen, KiCad unter usr/local/ zu installieren. Anmerkung: Das ist eine Möglichkeit. Zur Zeit (Oktober 2013) wird folgende Struktur empfohlen:&lt;br /&gt;
*** /usr/bin                            - Binaries (executable files).&lt;br /&gt;
*** /usr/share/doc/kicad/               - Various documentation.&lt;br /&gt;
*** /usr/share/doc/kicad/help           - Interactive help.&lt;br /&gt;
*** /usr/share/kicad/demos              - Sample schematics and printed boards.&lt;br /&gt;
*** /usr/share/kicad/internat           - Dictionaries for interface localization.&lt;br /&gt;
*** /usr/share/kicad/library            - Interface localization files.&lt;br /&gt;
*** /usr/share/kicad/modules            - Module libraries for printed boards.&lt;br /&gt;
*** /usr/share/kicad/modules/packages3d - 3D component models (.wrl and .wings format).&lt;br /&gt;
*** Quelle: http://iut-tice.ujf-grenoble.fr/cao/install.txt Hier sind auch Hinweise für Windows user enthalten.&lt;br /&gt;
&lt;br /&gt;
** 2) User sollten dort Lese- und Ausführungsrechte haben. Aber keine Schreibrechte.&lt;br /&gt;
** 3) Wenn ein fertiges Packgage auf einem 64 bit System verwendet wurde, könnte es daran liegen, das es für 32 bit compiliert wurde, und nicht für 64 bit. Es gibt zwei Möglichkeiten:&lt;br /&gt;
*** a) Selber aus den Sourcen für sein eigenes System compilieren.&lt;br /&gt;
*** b) Die Runtime Libs für 32 Bit könnten fehlen. Nachinstallieren mit sudo apt-get install ia32-libs. Siehe: http://www.mikrocontroller.net/topic/307517#3307638&lt;br /&gt;
* Ich habe das umgekehrte Problem: 32bit system aber 64bit Binarys.&lt;br /&gt;
** Selber aus den Sourcen neu compilieren.&lt;br /&gt;
*Ich will/muss mir KiCad selber compilieren. Wie gehe ich vor?&lt;br /&gt;
** Aktuell nach: http://www.kicad-pcb.org/display/DEV/Build+KiCad&lt;br /&gt;
**Veraltet! siehe: http://www.mikrocontroller.net/topic/310766#3351269 Aber Achtung. Diese Anleitung (Oktober 2013) muss nicht aktuell sein.&lt;br /&gt;
&lt;br /&gt;
=== Schaltplan ===&lt;br /&gt;
* Wie stellt man die Blattgrösse beim Schaltplan ein?&lt;br /&gt;
** In Page Settings die Blattgröße verstellen (zB von A4 auf A3) http://www.mikrocontroller.net/topic/33653#974295&lt;br /&gt;
* Wie kann man den Schaltplan auf mehreren Seiten verteilen (hierachical sheets)?&lt;br /&gt;
** http://www.mikrocontroller.net/topic/96060&lt;br /&gt;
** http://www.mikrocontroller.net/topic/117873#1060062&lt;br /&gt;
*Wie geht man mit &amp;quot;Power Pins&amp;quot; in hierachischen Schaltplänen um?&lt;br /&gt;
**http://www.mikrocontroller.net/topic/207905#new&lt;br /&gt;
* Wie kann man die &amp;quot;hierachical sheets&amp;quot; benutzen, um aus vorgefertigten Subschaltplänen mit immer gleichen Bauteilgruppen rationell Schaltpläne zusammenzustellen (Building Blocks)?&lt;br /&gt;
** http://www.mikrocontroller.net/articles/KiCAD#Tipps.26Tricks:_Building_Blocks&lt;br /&gt;
** http://www.mikrocontroller.net/topic/175597#1687653&lt;br /&gt;
** http://www.mikrocontroller.net/topic/178683#1724114&lt;br /&gt;
* Ich habe einen hierarchischen Schaltplan angelegt. Wenn ich ihn ausdrucke, werden die Subschaltpläne in der Reihenfolge ausgedruckt, in der sie oben in der Übersicht stehen. Diese Reihenfolge ist aber in meinem Fall ungünstig. Wie kann ich diese nun ändern?&lt;br /&gt;
** Leider im Programm z.Z. noch nicht. Trozdem ist es machbar. Entweder von Hand oder mit einem Python Skript. Näheres zu beidem findet sich hier: http://www.mikrocontroller.net/topic/288394#3064087 . Ein Python 3 Skript, das den Umgang mit dem Kicad-Schaltplan erleichtert, findet sich hier: [[Media:PyKicadSchematic-ID_Interchanger_RevC.zip]].&lt;br /&gt;
*Wie geht man mit Bussen um?&lt;br /&gt;
**http://www.mikrocontroller.net/topic/208870#new&lt;br /&gt;
** und speziell bei hierachischen Schaltplänen: http://www.mikrocontroller.net/topic/209156#new&lt;br /&gt;
* Wie kann man Schaltplanentwurf (KiCAD) und Schaltungssimulation (Spice) verbinden?&lt;br /&gt;
* Ein Tutorial zum Symboleditor für KiCAD, mit dem die Symbole für das Schaltplanmodul (EEschema) erzeugt bzw. editiert werden, findet sich hier: [[Media:SymboleFuerKiCad318082009-RevC-DE.pdf]]. Zur Erstellung von Schaltplansymbolen in aufgelöster Darstellung (Relais: Kontaktsätze einzeln und getrennt von der Spule; IC: Versorgungsspannung getrennt von den einzelnen Gattern) siehe http://www.mikrocontroller.net/topic/273891#new. Bei Problemen noch mal hier nachlesen: http://www.mikrocontroller.net/topic/294095#3136180&lt;br /&gt;
* Wie kann man im Schaltplan Symbole zum Verschieben gruppieren?&lt;br /&gt;
** Siehe http://www.mikrocontroller.net/topic/170913#&lt;br /&gt;
* Und wenn es darum geht, eine solche Gruppe in einen anderen Schaltplan oder Subschaltplan zu verschieben?&lt;br /&gt;
** Die Gruppe ins &amp;quot;Clipboard&amp;quot; stecken. Dazu nach dem Markieren der Gruppe rechte Maustaste beklicken, und dort &amp;quot;Gruppe speichern&amp;quot; wählen. Nun ist die Gruppe im Clipboard. jetzt in den gewünschten Unterschaltplan gehen und die Gruppe dort mithilfe des Clipboardbuttons (Das Klemmbrett Symbol links neben dem &amp;quot;Undo&amp;quot;-Button) in den Schaltplan einfügen. NICHTS mit der rechten Maustaste versuchen! Siehe auch: http://www.mikrocontroller.net/topic/244836#2499782 Das ganze geht nicht nur mit Subschaltplänen, sondern auch genauso in einen ganz anderen Schaltplan, den man dann halt in Eeschema öffnen muss, hinein. Wenn nach dem Einfügen allerdings nur ein Kästchen mit Fragezeichen erscheint, waren die nötigen Symbolbibliotheken für diese Symbole noch nicht in der Projektdatei eingetragen. Das mus man nun nachholen, indem man unter &amp;quot;Einstellungen&amp;quot; die &amp;quot;Bibliotheken&amp;quot; wählt, und die passenden Bibliotheken einträgt. Wenn man nicht genau weiss, wo diese zu finden sind, kann es sinnvoll sein, die *-cache.lib des Herkunftsschaltplanes einzubinden. &lt;br /&gt;
* Wie wird man den merkwürdigen Rahmen los?&lt;br /&gt;
** 1) Bei neueren KiCad Versionen, ab ca. Mitte 2013 (von mir getestet ab BZR 4513 29 November 2013) kann man sich eine Vorlage ohne Rahmen erstellen. Dazu den pl_editor (der ganz rechte Button im KiCad Hauptfenster) starten, und FAST alles entfernen. Dazu in der linken Spalte nacheinander alles aktivieren, und mit rechts anlicken und dann &amp;quot;entfernen&amp;quot; wählen. Aber vorsicht, wenn alles Entfernt wird, taucht das Original Layout wieder auf. Workaround war bei mir, eine zusätzliche Alibilinie hinzuzufügen, die von X 0,000 Y 0,000 bis  X 0,001 Y 0,000 reicht. Das ist ein &amp;quot;Fliegenschiss&amp;quot; in der linken oberen Ecke. Jetzt kann alles andere gelöscht werden. Den so geleerten Rahmen unter einem beliebigen Namen mit der Endung .kicad_wks wegspeichern. Im geöffneten Schaltplan kann der dann unter Datei &amp;gt; Seite einrichten ganz unten unter &amp;quot;page layout file description&amp;quot; die entsprechende Datei eingebunden werden. Es bleibt aber dem Anwender offen, ob er den Rahmen komplett entfernt, oder noch Felder mit Textbeschreibungen übernimmt. Für gesteigerten Komfort kann diese Datei dann auch in ein Template eingebunden werden. &lt;br /&gt;
** 2) Beim Ausdrucken Frame deaktivieren.&lt;br /&gt;
** 3) Als SVG exportieren/plotten. Liegt es als SVG vor, mit einem geigneten Grafikprogramm, z.B. Inkscape, den Rahmen löschen.&lt;br /&gt;
* Wie schalte die Footprint-Namen in Eeschema global ab?&lt;br /&gt;
** http://www.mikrocontroller.net/topic/253564#new&lt;br /&gt;
* Ich habe ein Problem mit dem ERC. Ständig kommt die Fehlermeldung: &amp;quot;Pin ist mit anderen Pins verbunden, wird jedoch von keinem angesteuert&amp;quot;&lt;br /&gt;
** Netze, die nicht angesteuert werden, werden von Kicad misstrauische beäugt. Das &amp;quot;nicht ansteuern&amp;quot; kann aber schnell passieren, weil Kicad u.A. erwartet, das irgendwo ein Spannungsversorgung ist. Wenn diese aber z.B. über eine Sicherung oder einen Pull-up Widerstand gehen, so wird das nicht bemerkt, weil Sicherungen und Widerstände (oder auch Entstördrosseln) &amp;quot;passive&amp;quot; Pins haben. Siehe: http://www.mikrocontroller.net/topic/292988#new und http://www.mikrocontroller.net/topic/298401#new&lt;br /&gt;
* Ich habe ein Problerm mit dem ERC. Immer in Verbindung mit GND kommt die Fehlermeldung: &amp;quot;Pin ist mit anderen Pins verbunden, wird jedoch von keinem angesteuert&amp;quot;&lt;br /&gt;
**Siehe: http://www.mikrocontroller.net/topic/284089#new&lt;br /&gt;
* Wie ist der Zusammenhang zwischen Bauteilen und Netznamen? Wie bekomme ich heraus, an welchem Netz mein Bauteil angeschlossen ist?&lt;br /&gt;
** Eeschema vergibt bzw. aktualisiert erst dann Netznamen, wenn eine Netzliste erzeugt wird. Darauf besteht entweder ein Zugriff über PCBnew, oder aber mit einem Editor. Siehe Beitrag http://www.mikrocontroller.net/topic/316539#new&lt;br /&gt;
* Ich habe einen Schaltplan geöffnet, aber alle oder einige der Symbole zeigen nur Kästen mit Fragezeichen.&lt;br /&gt;
** Es fehlen die passenden Symbolbibliotheken für diese Symbole.&lt;br /&gt;
*** Diese müssen in der Liste der Bibliotheken nachgetragen werden. &lt;br /&gt;
*** Hat man von anderswo einen Schaltplan bekommen, kann dieser auf anderen Symbolbibliotheken beruhen, als man selber verwendet. Aus diesem Grunde existiert zu jeder Schaltplandatei (Dateiname.sch) eine Cache Bibliothek (Dateiname-cache.lib). Diese enthält alle im Schaltplan verwendeten Symbole, und sollte darum mit dem Schaltplan zusammen übergeben werden.&lt;br /&gt;
*** Ab BZR4646 (Jan./Feb. 2014) behandelt KiCad Symbolnamen &amp;quot;Case Sensitive&amp;quot;. Das führt zu Problemen mit älteren Schaltplänen, wo &amp;quot;Mixed Case&amp;quot; Symbolnamen aus den Bibliotheken automatisch in &amp;quot;Upper Case&amp;quot; Symbolnamen konvertiert wurden. Diese werden jetzt nicht mehr erkannt. Näheres siehe: http://www.mikrocontroller.net/articles/KiCAD#Problem:_Case_Senitive_Symbols_ab_BZR4646_.28Jan..2FFeb._2014.29&lt;br /&gt;
&lt;br /&gt;
=== Netlist ===&lt;br /&gt;
* Was genau muss man beim Übergang vom Schaltplan (SCH) zum Layout (BRD) machen?&lt;br /&gt;
** http://www.mikrocontroller.net/topic/33653#898771&lt;br /&gt;
** http://www.mikrocontroller.net/topic/39243#290309&lt;br /&gt;
** http://www.mikrocontroller.net/topic/39243#891530&lt;br /&gt;
* Kann man fertige Netzlisten für Gruppen von Bauteilen einbinden?&lt;br /&gt;
** http://www.mikrocontroller.net/topic/33653#1462871&lt;br /&gt;
* Kann man Daten für automatische Bestückung erzeugen?&lt;br /&gt;
** Ja. aber nicht in CVpcb für die Symbol &amp;gt; Footprint Zuordnung, sondern im Layout Modul PCBnew.&lt;br /&gt;
* In meiner Netlist fehlen Bauteile, die im Schaltplan vorhanden und angeschlossen sind. Der ERC läuft problemlos durch. Die Annotation auch, aber nach Erstellung der Netlist sind die Symbole plötzlich mit einem vorangestellten &amp;quot;#&amp;quot; im Schaltplan bezeichnet.&lt;br /&gt;
** Vermutlich sind sie versehentlich als &amp;quot;virtuelles&amp;quot; Bauteil gekennzeichnet. Siehe http://www.mikrocontroller.net/topic/268626#new&lt;br /&gt;
* Was bedeuten die Maßangaben in der Netlist?&lt;br /&gt;
* Wie überträgt man Kicad Schaltpläne in QUCS Schaltpläne für Simulation?&lt;br /&gt;
&lt;br /&gt;
=== Layout ===&lt;br /&gt;
* Wie stellt man die Rastergrösse im Layout ein?&lt;br /&gt;
** Mit der Rechten Maustaste in das Board klicken. Es poppt ein Menue auf. Dort Raster wählen..... Geht im Modul-Editor genauso.&lt;br /&gt;
* Wie füllt man eine Fläche aus?&lt;br /&gt;
** http://www.mikrocontroller.net/topic/93131#854802&lt;br /&gt;
** Etwas aktueller: http://www.mikrocontroller.net/topic/182271#1772119 Zweiter Teil des Posts.&lt;br /&gt;
* Und wie erzeuge ich konzentrisch ineinanderliegende Flächen?&lt;br /&gt;
** http://www.mikrocontroller.net/topic/327475#new&lt;br /&gt;
* Ja, aber meine Fläche wird nicht gefüllt oder es passiert was ganz merkwürdiges.&lt;br /&gt;
**Siehe: http://www.mikrocontroller.net/topic/298692#new &lt;br /&gt;
* Wie werden Pads und Leiterbahnen verbunden?&lt;br /&gt;
** http://www.mikrocontroller.net/topic/119755#1081455&lt;br /&gt;
** aktueller: http://www.mikrocontroller.net/topic/220733#new&lt;br /&gt;
* Ich kann keine Leiterbahnen ziehen!&lt;br /&gt;
** Vermutlich hast Du den automatischen DRC (Design rule check) aktiviert. Deaktiviere ihn halt. In PCBnew im linken Buttonbar der oberste Button (Insekt mit Verbotszeichen). http://www.mikrocontroller.net/topic/306476#new&lt;br /&gt;
* Ich bekomme immer eine Fehlermeldung vom DRC, das ein Pad nicht angeschlossen ist, aber ich habe es angeschlossen.&lt;br /&gt;
** http://www.mikrocontroller.net/topic/204717#2018724&lt;br /&gt;
* Ich will ein Bauteil für geringeren Leiterwiderstand sowohl auf der Unterseite- als auch der Oberseite anschliessen. KiCAD löscht aber immer den alten Leiterbahnzug, wenn ich den neuen lege. &lt;br /&gt;
** Deaktiviere unter Einstellungen-&amp;gt;Allgemein das &amp;quot;auto-entfernen-von-Leiterbahnen&amp;quot; (einfachste Lösung). &lt;br /&gt;
** Alternativ: Designe dafür Bauteile mit speziellen Pads. http://www.mikrocontroller.net/topic/187606#1823596 (realistischste u. sauberste Lösung, aber etwas umständlich.)&lt;br /&gt;
* Wie kann man ein Bauteil mit Pads und Leiterbahnen bewegen? &lt;br /&gt;
** http://www.mikrocontroller.net/topic/118539#1067219&lt;br /&gt;
* Ich habe eine Platine, die von oben und unten bestückt ist. Wenn ich jetzt Bauteile zusammengruppiere, um sie gemeinsam zu verschieben, erwische ich immer alle Bauteile auf Vorder- und Rückseite. Wie bekomme ich das jetzt hin, das ich nur Module auf einer Seite bewege?&lt;br /&gt;
** Indem im Lagenmanager die Seite, die nicht bewegt werden soll, abgeschaltet wird. Siehe: http://www.mikrocontroller.net/topic/311586#new&lt;br /&gt;
* Wie bekommt man ein vernünftiges Boardoutline hin?&lt;br /&gt;
** http://www.mikrocontroller.net/topic/96060#1057511 &lt;br /&gt;
* Wie erstellt man eine Befestigungsbohrung / nichtdurchkontaktierte Bohrung?&lt;br /&gt;
** VERALTET: http://www.mikrocontroller.net/topic/179308#1726990&lt;br /&gt;
** VERALTET:http://www.mikrocontroller.net/topic/120373#1122219 ?????&lt;br /&gt;
** KiCAD kann mittlerweile auch direkt nichtdurchkontaktierte Bohrungen erzeugen. Siehe dazu http://www.mikrocontroller.net/topic/263069#2732405 Enthält auch allgemeine Informationen zum Umgang mit durchkontaktierten und nicht durchkontaktierten Bohrungen.&lt;br /&gt;
* Ich möchte für Passermarken / Fiducials eine deutlich größere Freistellung in der Lötstoppmaske haben. Wie geht das?&lt;br /&gt;
** http://www.mikrocontroller.net/topic/266730#2779498&lt;br /&gt;
* Wie geht das überhaupt mit den Lötstoppmasken?&lt;br /&gt;
** http://www.mikrocontroller.net/topic/283721#new&lt;br /&gt;
* Ja, aber die Lötstoppmaske wird leider nicht angezeigt.&lt;br /&gt;
** http://www.mikrocontroller.net/topic/298028#new&lt;br /&gt;
* Wie kann man Bauteilmaße in den Ansichten (Footprint, Layout, 3D-View) anzeigen?&lt;br /&gt;
** Anzeige im Layout: Layer &amp;quot;Zeichnung&amp;quot; anwählen. In der rechten Menueleiste &amp;quot;Bemaßung hinzufügen&amp;quot; wählen. Das ist der fünfte Button von unten mit der &amp;quot;blauen Bemaßung&amp;quot;. Jetzt an einer Stelle links ins Layout klicken. Maus verschieben und noch einmal links klicken und die Maus seitlich verschieben. Es wird ein Maßpfeilsystem zwischen erstem und und zweitem Mausklick angelegt, deshen höhe man mit der Maus einstellen kan. Ein weiterer linker Mausklick fixiert das System. Das Anklicken der Beschriftung mit der rechten Maustaste erlaubt das Editieren. Das System wird immer in der Einheit angelegt, die in der linken  Menueleiste vorgewählt wurde. Die Rasterung der aktuellen Einstellung wird auch übernommen. Späteres Ändern von Einheit- und Raster ändern die Beschriftung nicht mehr. In 3D und im Footprint geht diese Möglichkeit nicht.&lt;br /&gt;
** Weitere Möglichkeiten: Einen Maßstab als footprint/Modul anfertigen und zum Messen in das Board einfügen.&lt;br /&gt;
** Wenn man im Layout aber direkt etwas ausmessen möchte, so geht das über den relativen Nullpunkt. Unten im Rahmen rechts sind vier Felder. Die beiden linken zeigen die absoluten Koordinaten, an, die beiden rechten die relativen Koordinaten in Bezug auf einen relativen Nullpunkt. Defaultmäßig stimmen absoluter und relativer Nullpunkt ersteinmal überein. Per &amp;quot;Space bar&amp;quot; drücken setzt Du den relativen Nullpunkt an den Ort des Mauszeigers. Wenn Du nun die Maus verfährst, zeigen die relativen Koordinaten nun den vertikalen und horizontalen Abstand zum Nullpunkt. Die Diagonale muss leider über den Pythagoras selber ausgerechnet werden, oder indem man die Polarkoordinateneinstellung wählt (linke Menueleiste). Durch geschicktes setzten des Nullpunktes kann man nun auf der Platine herummessen. Winkel können auch über die Polarkoordinateneinstellung gemessen werden. Im Moduleditor geht das analog. Das 3D-View kann zur Zeit (Jannuar 2011) überhaupt keine Bemaßung.     &lt;br /&gt;
* Wie kann man mit der KiCAD Version 20100314 &#039;&#039;&#039;einseitige&#039;&#039;&#039; Platinen erstellen?&lt;br /&gt;
** http://www.mikrocontroller.net/topic/172015#1651239&lt;br /&gt;
** aktueller: http://www.mikrocontroller.net/topic/172015#1794699&lt;br /&gt;
*Und wie teile ich KiCAD mit, daß der Autorouter nur eine Seite verwenden soll?&lt;br /&gt;
** Auf die doofe Tour: Erst in KiCAD zweiseitig wählen, und dann beide Lagen im Autorouter als &amp;quot;Unterseite&amp;quot; wählen.&lt;br /&gt;
* Wie kann man den Nullpunkt eines Layouts verschieben?&lt;br /&gt;
** http://www.mikrocontroller.net/topic/179680#1730452 für den Layout Editor PCBnew. Im Moduleditor bei Erstellung eines Footprints kann man den Ankerpunkt frei Mithilfe des Anker-Tools aus der rechten Menüleiste (das Ankersymbol) setzten. Gleiches gilt für den Symboleditor.&lt;br /&gt;
* Wie gehen runde Bögen in KiCAD?&lt;br /&gt;
**http://www.mikrocontroller.net/topic/202512#1994063 &lt;br /&gt;
* Ich habe mein Board fertig geroutet, stelle aber jetzt fest, das ich noch einige Leiterbahnbreiten ändern muss. Wie geht das am einfachsten?&lt;br /&gt;
**http://www.mikrocontroller.net/topic/205851#new&lt;br /&gt;
*Ich kann Pads nicht anschlissen bzw. ich bekomme vom DRC Fehlermeldungen, daß ich Pads nicht angeschlossen habe, obwohl sie angeschlossen sind.&lt;br /&gt;
**http://www.mikrocontroller.net/topic/204717#new&lt;br /&gt;
*Wie kann ich Daten für automatische Bestückung (Pick&amp;amp;Place) erzeugen?&lt;br /&gt;
** In PCBnew unter Datei &amp;gt; Fertigungsdateien &amp;gt; Bauteile Positionsdatei (.pos). Aber dieses verlangt, das die Footprints auch die richtigen Informationen dazu enthalten. Um diese einzustellen, den Footprint im Moduleditor öffnen und unter dem Button &amp;quot;Bauteileigenschaften&amp;quot; in &amp;quot;Attribute&amp;quot; eine Markierung bei &amp;quot;Normal+Einfügen&amp;quot; machen. Dann wird der Ankerpunkt des Modules für die Positionsdatei verwendet. Damit sinnvolle Daten entstehen, sollte der Ankerpunkt in die Mitte des Footprintes gesetzt worden sein. &lt;br /&gt;
*Und wie erzeuge ich ein Excellon Drillfile?&lt;br /&gt;
** In PCBnew unter Datei &amp;gt; Fertigungsdateien &amp;gt; Bohrdaten. Die Datei enthält auch eine Werkzeugliste. Kicad legt u.U. zwei Drillfiles an, wenn erforderlich. Eines für durchkontaktierte, und eines für nicht durchkontaktierte Bohrungen. Wer eine extra Liste und eine Statistik wünscht, muss auch noch &amp;quot;Bericht über Bohrung&amp;quot; anwählen.&lt;br /&gt;
* Wenn PCBnew die Netzliste eingelesen hat, liegen alle Bauteile auf einem Haufen. Zum Plazieren eines herausgreifen ist mühsam. Wie geht das am einfachsten?&lt;br /&gt;
** In PCBnew &amp;quot;T&amp;quot; drücken. Es poppt ein Fenster auf, wo man die Bauteilreferenz (den Namen) eingeben kann. Und schon hängt das Bauteil zum Bewegen am Zeiger. Die Bedienung ist letztlich genauso wie das &amp;quot;m&amp;quot; und die Komandozeile in Eagle. Siehe http://www.mikrocontroller.net/topic/293903#3133990&lt;br /&gt;
** &amp;quot;Raef&amp;quot; hat ein Python Script erstellt, das Bauteile automatisch ähnlich der Anordnung im Schaltplan plaziert. Siehe: http://www.mikrocontroller.net/topic/293903#3245990&lt;br /&gt;
* Ich habe ein fertiges Layout. Jetzt möchte ich aber andere Footprints verwenden, und anschliessend nicht neu routen müssen. Wie geht das?&lt;br /&gt;
** Üner CVpcb und Neueinlesen der Netzliste. Siehe: http://www.mikrocontroller.net/topic/297885#new&lt;br /&gt;
* Ich will links herum routen, aber Kicad meint unbedingt rechts herum (...oder umgekehrt). Wie kann ich die Leiterbahnen &amp;quot;flippen&amp;quot;?&lt;br /&gt;
** Mit &amp;quot;/&amp;quot; (Slasch) http://www.mikrocontroller.net/topic/280028#new&lt;br /&gt;
* Ich hätte gerne die Tastenkürzel in kicad so wie in meinem gewohnten Programm. Wie geht das?&lt;br /&gt;
** Siehe http://www.mikrocontroller.net/topic/283959#3007173 . Vieleicht ist einer ja so nett, und stellt Konfigurationsfiles für Leute die aus EAGLE, ORCAD oder so wechseln, bereit.&lt;br /&gt;
* Ich habe ein kleines Board fertig geroutet. Jetzt möchte ich mehrere davon zu einer größeren Platine zusammenführen (sog. Mehrfachnutzen), um sie rationeller fertigen zu können.&lt;br /&gt;
** Siehe http:http://www.mikrocontroller.net/topic/292334#new . Das geht natürlich genauso, wenn man verschiedene Platinen so zu Nutzen zusammenfügen möchte, oder halt kleinere Teillayouts zu einem Gesamtboard.&lt;br /&gt;
* Ich habe einen hierarchischen Schaltplan angefertigt, indem sich eine Schaltung zig mal wiederholt. Eine dieser Subschaltungen habe ich schon geroutet, und möchte dieses Layout genau wie die hierarchischen Schaltpläne mehrfach auf dem Board verwenden.&lt;br /&gt;
** Siehe http://www.mikrocontroller.net/topic/292123#new&lt;br /&gt;
* Wie importiere ich DXF-Dateien in PCBnew?&lt;br /&gt;
** Dafür existiert eine Import Funktion in PCBnew: Datei &amp;gt; Importieren &amp;gt; DXF-Datei. Siehe http://www.mikrocontroller.net/topic/327628#new&lt;br /&gt;
&lt;br /&gt;
=== Layout: Python Scripting ===&lt;br /&gt;
&lt;br /&gt;
Das Python2-Scripting ist bisher nur in PCBnew implementiert und noch sehr experimentell. Daher ist leider auch der aktuelle Stand der Dokumentation zum Python-Skripting in PCBnew noch etwas dürftig. Trozdem hier Links dazu:&lt;br /&gt;
* http://www.kicad-pcb.org/display/KICAD/KiCad+Scripting+Reference+Manual (Allgemein. Achtung! Kicad braucht beim compilieren spezielle Befehle, um Python-Scripting tauglich zu sein.)&lt;br /&gt;
* http://dev.kicad-pcb.org/doxygen-python/index.html (Definitionen von Namespaces, Classes und Files)&lt;br /&gt;
&lt;br /&gt;
Für Linux-Debian:&lt;br /&gt;
Aktuell (07. Februar 2014) mit  Pcbnew Version: (2014-01-27 BZR 4641)-product Release build auf&lt;br /&gt;
Platform: Linux 3.2.0-4-686-pae i686, 32 bit, Little endian, wxGTK (Debian Wheezy) gilt:&lt;br /&gt;
* Geht aktuell nur für PCBnew.&lt;br /&gt;
* Klassenbibliotheken: Zwei Dateien pcbnew.py und _pcbnew.so auf dem Pfad: /usr/lib/python2.7/dist-packages/&lt;br /&gt;
* Die Klassenbibliothek wird mit den üblichen Python2 Methoden importiert: z.B. &amp;quot;import pcbnew&amp;quot; oder &amp;quot;from pcbnew import *&amp;quot; &lt;br /&gt;
&lt;br /&gt;
Beispielprogramm, das alle Footprints aus einer Legacy-Fotprint Datei auflisted und den Referenzbezeichner dazuschreibt::&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python &lt;br /&gt;
# das war das Shebang.&lt;br /&gt;
&lt;br /&gt;
from pcbnew import * # Import der Bibliothek. &lt;br /&gt;
libpath = &amp;quot;/home/DuUser/KiCad-Daten/Module/ModuleGrosserSampler/KiCadLegacyFottprints.mod&amp;quot; # Übergabe des Pfades.&lt;br /&gt;
lst = FootprintEnumerate(libpath) &lt;br /&gt;
for name in lst:&lt;br /&gt;
    m = FootprintLoad(libpath,name)&lt;br /&gt;
    print name,&amp;quot;-&amp;gt;&amp;quot;, m.GetReference()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Scripting Möglichkeit ist so neu, dass bis jetzt die Scripting Testdateien für das KiCAD interne automatische Qualitätssicherungssystem noch nicht komplett sind.&lt;br /&gt;
Unter http://bazaar.launchpad.net/~kicad-product-committers/kicad/product/files/head:/qa/testcases/ finden sich bereits geprüfte Testskripte, und unter http://bazaar.launchpad.net/~kicad-product-committers/kicad/product/files/head:/pcbnew/scripting/examples/ finden sich ungetestete Testskripte.&lt;br /&gt;
&lt;br /&gt;
Sie alle können als Beispiele genommen werden, wie das mit dem Skripting gemeint ist, und als Vorbild für eigene Skripte dienen.&lt;br /&gt;
&lt;br /&gt;
=== Module Editor ===&lt;br /&gt;
* Wie erstellt man Footprints für Bauteile?&lt;br /&gt;
* Wie verbinde kopiere ich etwas aus einem Footprint in einen anderen hinein, bzw. wie verbinde/merge ich zwei Footprints?&lt;br /&gt;
** http://www.mikrocontroller.net/topic/288167#3061997&lt;br /&gt;
* Kann man im Module Editor die Eigenschaften aller Pads gleichzeitig ändern?&lt;br /&gt;
** http://www.mikrocontroller.net/topic/93131#799550 &lt;br /&gt;
* Ich brauche einen Footprint, bei dem mehrere Pads verbunden sind, will aber nicht im Schaltplan zig Pins aufführen und anschliessen müssen.&lt;br /&gt;
**http://www.mikrocontroller.net/topic/208982#new&lt;br /&gt;
**http://www.mikrocontroller.net/topic/204717#new&lt;br /&gt;
* Wie erzeugt man thermal Vias in Kicad?&lt;br /&gt;
** Leider bisher nur experimentell: http://www.mikrocontroller.net/topic/298028#3187259&lt;br /&gt;
* Wie kann man Bauteilmaße in in den Ansichten (Footprint, Layout, 3D-View) anzeigen?&lt;br /&gt;
* Wie verwalte ich Footprint Bibliotheken?&lt;br /&gt;
** Indem man sich ein Board erstellt, alle Footprints, die man zusammenfassen möchte, auf das Board stellt, und dann untet Dateien &amp;gt; Footprints archivieren &amp;gt; Footprint Archiv erstellen wählt. Das so erstellte Board kann auch zu Dokumentationszwecken geplottet werden. Eventuell möchte man einige Footprints, die zu Hilfszwecken (z.B. Skalen) auf dem Board sind, anschliessend mit dem Bibliothekseditor daraus löschen.&lt;br /&gt;
** Alternativ, im dem &amp;quot;neuen&amp;quot; *.pretty Format, mit einem Dateiverwaltungsprogramm Deiner Wahl. Siehe http://www.mikrocontroller.net/topic/320301#new&lt;br /&gt;
&lt;br /&gt;
=== 3D-Ansicht ===&lt;br /&gt;
* Die 3D-Ansicht funktioniert bei mir nicht.&lt;br /&gt;
** http://www.mikrocontroller.net/topic/289075#new&lt;br /&gt;
* Kann man die 3D-Ansicht in ein 3D-CAD Programm exportieren? &lt;br /&gt;
**http://www.mikrocontroller.net/topic/203388#new&lt;br /&gt;
* Wie kann man Bauteilmaße in in den Ansichten (Footprint, Layout, 3D-View) anzeigen?&lt;br /&gt;
&lt;br /&gt;
Da KiCAD in Punkto 3D-Ansicht komplett auf Wings3D beruht, und die 3D Modelle der Bauteile wrl-files sind, die mit Wings3D (oder Blender) erstellt werden können, sei hier auf ein Wings3D Handbuch verwiesen: http://www.oortman3d.com/wings3d/TheWings3dHandbook.pdf&lt;br /&gt;
&lt;br /&gt;
Viele Bauteilhersteller (vor allem von eher mechanischen, wie z.B. Stecker, Buchsen, Befestigung...) bieten fertige 3D-Modelle an. Diese sind meistens in den Formaten STEP oder IGES. So kann man diese in das von KiCAD benötigte .wrl (VRML 2.0) konvertieren:&lt;br /&gt;
# STEP oder IGES in [http://gcad3d.org/ gCAD3D] öffnen (File &amp;gt; Open Model)&lt;br /&gt;
# als Wavefront .obj speichern (File &amp;gt; Save Model as &amp;gt; OBJ)&lt;br /&gt;
# Das .obj in [http://www.wings3d.com/ Wings 3D] importieren (File &amp;gt; Import &amp;gt; Wavefront .obj)&lt;br /&gt;
# Als VRML 2 exportieren (File &amp;gt; Export &amp;gt; VRML 2.0 .wrl)&lt;br /&gt;
# Im KiCAD-Moduleditor die .wrl-Datei als 3D-Modell auswählen&lt;br /&gt;
# Eventuell muss man die Skalierung und Positionierung anpassen, die angezeigten Pads und Löcher helfen dabei. Die am meisten benötigten Faktoren dürften dabei 0,3937 und 2,54 sein - bei den Konvertierungen kommt leicht die Einheit Zoll oder cm durcheinander.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Eine andere Möglichkeit .obj oder .stl-Dateien aus STEP und IGES zu erzeugen ist [http://free-cad.sourceforge.net/ FreeCAD]. Obwohl es auch .wrl direkt erzeugen kann, können diese nicht in KiCAD geladen werden. Der Umweg über .obj oder .stl und Wings 3D löst dies aber auch hier.&lt;br /&gt;
&lt;br /&gt;
Wenn man das Board wieder in einem CAD-Programm verwenden will um z.B. ein Gehäuse zu konstruieren, sollte man wieder STEP-Dateien erzeugen. Neuere KiCAD-Versionen können zwar VRML exportieren, doch das beschreibt nur Umrisse und keine Körper (Solids). CAD-Programme zum Gehäusedesign brauchen jedoch letzteres. So geht die Konvertierung:&lt;br /&gt;
# VRML aus KiCAD exportieren (File &amp;gt; Export &amp;gt; VRML)&lt;br /&gt;
# .wrl-Datei mit Hilfe von [http://www.cs.princeton.edu/~min/meshconv/ meshconv] in eine STL-Datei konvertieren: &amp;lt;code&amp;gt;meshconv boardname.wrl -c stl -o boardname.stl&amp;lt;/code&amp;gt;&lt;br /&gt;
# Die STL-Datei mit [http://www.solveering.com/products/products_stl2step.html stl2step] in eine STEP-Datei konvertieren&lt;br /&gt;
&lt;br /&gt;
Man sollte hinterher im CAD nochmal genau die Maße kontrollieren. Denn die Konvertierung von STL nach STEP ist nur eine Approximierung und keine exakte, verlustfreie Konvertierung.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Und wie bedient man Wings3d?&lt;br /&gt;
** Ein (vorläufiger) Merkzettel/Ultrakurzanleitung zur Bedienung von Wings3D findet sich hier: [[Media:Kicad-Wings3D_Merkzettel_29November2012.pdf]]. Wenn man nur mit Wings3d Modelle für Kicad erstellen will, langt das eventuell schon als Tutorial. There is also an English translation of this leaflet about using wings3d for kicad  at [[Media:Kicad-Wings3D_Leaflet_25April2013.pdf]].&lt;br /&gt;
&lt;br /&gt;
=== Drucken / Export ===&lt;br /&gt;
* Wie exportiert man den Schaltplan oder das Layout als Bild (PNG o.ä.)? &lt;br /&gt;
** Drucken über Postscript-Treiber und Umwandeln mit Ghostscript&lt;br /&gt;
** [http://www.mikrocontroller.net/topic/96060#1061492]&lt;br /&gt;
** Plot to Clipboard [http://www.mikrocontroller.net/topic/117562#1056566]&lt;br /&gt;
* Wie kann ich GENAU ausdrucken? Mein Ausdruck auf ABC ist ca. X % zu klein oder Y% zu groß! &lt;br /&gt;
** So genau sind einfache Drucker bzw. Druckertreiber selten. Aber meistens hilft folgendes: Mache einen 1:1 (100%) Probeausdruck. Messe auf dem Ausdruck nach, wie groß er tatsächlich geworden ist. Berechne die Abweichung und gebe sie in den Drucker bzw. Druckertreiber unter Einstellung ein, vorausgesetzt, der Drucker bzw. Druckertreiber kann das. Mit dem Wert machst Du wieder eine Probeausdruck, messe wieder nach, und wenn es mit der Einstellung funktioniert hat, kannst Du Deine Folie bedrucken. Wenn das nicht klappen kann, weil Du stark abweichende Werte für horizontal und vertikal bräuchtest, aber der Drucker nur einen gleichen Wert für beides kennt, hast Du einen (zu) schlechten Drucker. Trozdem nicht verzweifeln, weil KiCAD beim Drucken oder Plotten in der X- und Y-Achse getrennt skalieren kann. Aber Vorsicht bei Weitergabe der so erzeugten Dateien: Sie sind individuell auf einen Drucker angepasst, und produzieren auf einem anderen Drucker nur falsch skalierte Ausdrucke. Weil der Wert von Drucker zu Drucker unterschiedlich ist, ist es auch sinnvoll, diese Skalierung direkt am speziellen Drucker/Druckertreiber zu machen. Tipp: Wenn Du den Wert erfolgreich ermittelt hast, so kleb Dir einen Zettel auf den Drucker mit dem Wert. Die Werte sind zwar individuell für jeden Drucker, aber meistens für den speziellen Drucker durchaus fix. Und Du hast ihn sofort wieder parat, wenn der Drucker resettet wurde. Dies ist übrigens ein allgemeiner Tipp für das Ausdrucken, der auch für Eagle, Target, Altium usw. gilt.&lt;br /&gt;
** Thema Skalieren - Die aktuelle Situation (August 2013): http://www.mikrocontroller.net/topic/304619#new &lt;br /&gt;
* Kann man Gerber-Dateien exportieren?&lt;br /&gt;
** Ja. Es wird Gerber 247X exportiert. Einheit ist inch (doppelt sowohl im 247d als auch im 247x Stil definiert). Die Y-Koordinaten sind im allgemeinen negativ. KiCAD verwendet für Flächen das in Gerber spezifizierte Polygon Makro und kein &amp;quot;stroke fill&amp;quot;.&lt;br /&gt;
** Bei Bestellungen bei PCB-Pool ist deren GC-Prevue NICHT mehr erforderlich, weil PCB-Pool mittlerweile KiCAD *,brd Dateien direkt aktzeptiert. Siehe http://www.pcb-pool.com/ppde/info_dataformat.html &lt;br /&gt;
* Wie kann man den Gerber-Plot so ausdrucken, dass in der Mitte von Pads und Vias ein Zentrierloch frei bleibt?&lt;br /&gt;
** http://article.gmane.org/gmane.comp.cad.kicad.user/3457&lt;br /&gt;
* Wie kann man das Layout invers ausdrucken, d.h. alle Leiterbahnen und Pads müssen weiß bleiben, der Rest wird schwarz ausgedruckt?&lt;br /&gt;
** Beim Plotten den Haken bei Negativ-Plot setzen [http://www.mikrocontroller.net/topic/156202#1474507]&lt;br /&gt;
* Ich habe irgendwie Probleme mit dem Ausdrucken.&lt;br /&gt;
** Verzerrt: http://www.mikrocontroller.net/topic/207764#new&lt;br /&gt;
** Sonderzeichen: http://www.mikrocontroller.net/topic/207310#new&lt;br /&gt;
** In der aktuellen Version 2012-01-19 BZR 3256)-stable besteht ein generelles Druckproblem. Aber Plotten geht wunderbar!&lt;br /&gt;
** Aktualisierter Stand 23. Dezember 2012: http://www.mikrocontroller.net/topic/280958#new&lt;br /&gt;
** Aktualisierter Stand vom 21. Juli 2013: http://www.mikrocontroller.net/topic/303043#3249166&lt;br /&gt;
* Meine erzeugten SVG Plots sind kaputt. Ich erhalte nur Fehlermeldungen, wenn ich sie in Inkscape oder Gimp einlesen will.&lt;br /&gt;
** Es besteht ein Problem mit dem SVG Export, wenn man Schaltpläne oder Boards in SVG exportiert, die ein Ampersand (Kaufmansund, &amp;quot;&amp;amp;&amp;quot;) im Dateinamen haben. Dieser Dateiname tauch dann innerhalb der SVG Datei in einem Titelblock auf, wo das &amp;quot;&amp;amp;&amp;quot; dann ein Problem bedeutet. Sowohl Kicad als auch Inkscape/Gimp aktzeptieren &amp;quot;&amp;amp;&amp;quot; im Dateinamen, und sowol unter Windows als auch Linux ist das &amp;quot;&amp;amp;&amp;quot; im Dateinamen legal....darum bringt auch eine Veränderung des Namens der SVG-Datei keine Lösung. Eine Lösung ist, Grundsätzlich in Kicad keine &amp;quot;&amp;amp;&amp;quot; in Dateinamen zu verwenden, wenn man einen SVG-Export macht. Alternativ kann man mit einem Editor das &amp;quot;&amp;amp;&amp;quot; aus dem Titelblock (Das ist NICHT der Dateiname, sondern in der Datei selber alles zwischen &amp;lt;titel&amp;gt; und &amp;lt;/titel&amp;gt;) der SVG-Datei löschen. Angeblich kommt der Bug aus den verwendeten wx-Bibliotheken. Siehe den Bugreport: https://bugs.launchpad.net/kicad/+bug/1171160&lt;br /&gt;
* Ich würde gerne PDF Dateien aus meinem Layout erstellen, aber irgendwie ist der Ausdruck defekt.&lt;br /&gt;
** Drucken ist aus Kicad manchmal ein Problem, auch in eine Datei hinein. Aber Plotten und Exportieren in SVG funktioniert gut. Von SVG zu PDF kommt man über Inkscape. Siehe hier: http://www.mikrocontroller.net/topic/303043#3249166&lt;br /&gt;
* Wie kann ich mir einen Bohrplan ausdrucken, um mit der Hand zu bohren?&lt;br /&gt;
**http://www.mikrocontroller.net/topic/266037#new&lt;br /&gt;
* Wie erstelle ich mit KiCad Excellon Drillfiles?&lt;br /&gt;
**siehe hier: http://www.mikrocontroller.net/topic/310333#new&lt;br /&gt;
&lt;br /&gt;
=== Import ===&lt;br /&gt;
* Kann man EAGLE Dateien importieren? (=&amp;gt; Obacht bei Weitergabe der Daten!)&lt;br /&gt;
** http://www.mikrocontroller.net/topic/70905#797416&lt;br /&gt;
** http://www.mikrocontroller.net/topic/120373#1089933&lt;br /&gt;
* Wie bindet man fremde KiCAD Bibliotheken ein?&lt;br /&gt;
** EESchema (Schaltplaneditor) starten, unter Einstellungen &amp;quot;Bibliothek&amp;quot;  auswählen, auf &amp;quot;Hinzufügen&amp;quot; klicken, neue Bibliothek auswählen dann &amp;quot;öffnen&amp;quot; und in der Projektdatei &amp;quot;Speichern&amp;quot;. Gültig für Version 20090216Final, 2011-04-29-BZR2986-WinXP und Version: (2011-11-27 BZR 3249)-stable unter Platform: Linux 2.6.32-5-686 i686, 32 bit, Little endian, wxGTK.&lt;br /&gt;
Das Verfahren zur Einbindung eigener oder fremder Bibliotheken ist under PCBnew genauso.&lt;br /&gt;
Es empfielt sich dringenst, eigene Bibliotheken NICHT zu den KiCAD Bibliotheken im Ordner kicad/share/library bzw. kicad/share/modules für Footprints zu speichern, weil diese dort bei einem Upgrade gelöscht würden. Stattdessen sollte man sich einen kicad Ordner im eigenen home bzw. Benutzerverzeichnis (oder sonstwo, wo es opportun ist, und man Schreibrechte hat) anlegen, mit einem Ort, um eigene Bibliotheken abzulegen.&lt;br /&gt;
&lt;br /&gt;
=== Neues Projekt ===&lt;br /&gt;
Ein neues Projekt legt kicad automatisch nach der in kicad/share/template hinterlegten Projektdatei an. Möchte man, das kicad ein neues Projekt von vorneherein nur mit ausgewählten eigenen Bibliotheken anlegt, so ist eine entsprechende Projektdatei unter kicad/share/template/kicad.pro abzulegen.&lt;br /&gt;
Dies erfordert dort Schreibrechte. Linux roots müssen diese Datei anschliessend mit chmod 755 Dateiname für user lesbar machen.&lt;br /&gt;
Bei einem upgrade würde kicad.pro gelöscht. Daher sollte man sich davon eine Sicherheitskopie in seinem benutzerverzeichnis hinterlegen.&lt;br /&gt;
&lt;br /&gt;
=== Einstellungen sichern / wiederherstellen===&lt;br /&gt;
* Wo speichert KiCAD die Einstellungen ab und wie lassen sich die originalen Einstellungen wiederherstellen?&lt;br /&gt;
** [[http://kicad.sourceforge.net/wiki/index.php/DE:KiCadHB#Einstellungen_sichern_.2F_wiederherstellen]]&lt;br /&gt;
**Man erstelle ein neues Projekt beliebigen Namens, nehme alle Einstellungen (Bibliotheken, Pfade usw.) vor und speichere diese in der aktuellen Projektdatei &amp;quot;name.pro&amp;quot;. Im Ordner KiCAD Verzeichnis ....../kicad/share/template befindet sich eine Datei &amp;quot;kicad.pro&amp;quot;. Diese Datei &amp;quot;kicad.pro&amp;quot; ist die &amp;quot;Musterprojektdatei&amp;quot;, die für alle neuen Projekte verwendet wird. Man benenne sie um in &amp;quot;kicad-orig.pro, und kopiere die aktuelle Projektdatei &amp;quot;name.pro&amp;quot; nun als &amp;quot;kicad.pro&amp;quot; in diesen Template-Ordner. Leider Funktioniert dieses Verfahren nicht in allen KiCAD Versionen. Den originalen Zustand stellt man wieder her, indem man &amp;quot;kicad.pro&amp;quot; umbenennt, und &amp;quot;kicad-org.pro&amp;quot; wieder in &amp;quot;kicad.pro&amp;quot; zurückumbenennt.&lt;br /&gt;
&lt;br /&gt;
=== Bitmaps als Symbol oder Footprint importieren ===&lt;br /&gt;
Der Programmteil Bitmap2component wandelt Bitmaps wahlweise in Symbole oder in Footprints um. Auf diese Weise können also auch Logos oder spezielle Muster für HF-anwendungen in KiCAD importiert werden, sobald sie als Bitmap vorliegen. Diese Funktion ist allerdings sehr neu (im Frühjahr 2011 eingefügt) und eher als experimentell zu bezeichnen. So funktioniert z.B. der Export in ein Symbol in der Version BZR-2986 NICHT.&lt;br /&gt;
&lt;br /&gt;
== Tipps&amp;amp;Tricks / Eigenheiten / Bugs ==&lt;br /&gt;
&lt;br /&gt;
* Nachbearbeitung mit Skript oder Texteditor (Pin Swapping, Versionskontrolle via SVN, Generierung von Packages aus UCF-Listen) &lt;br /&gt;
** http://www.mikrocontroller.net/topic/120373#1100467&lt;br /&gt;
** http://www.mikrocontroller.net/topic/96860#836967&lt;br /&gt;
** http://stawoo.com/dokuwiki/doku.php?id=ecld:kicad:board&lt;br /&gt;
&lt;br /&gt;
* Schaltplan: Durchnummerieren von GND und PWR erforderlich http://www.mikrocontroller.net/topic/39243#290309&lt;br /&gt;
&lt;br /&gt;
* Zum Verbinden von Schaltplan und Layout müssen an den Bauteilen die Pinnummern mit den Padnummern der Footprints korrespondieren. Das ist &amp;quot;defaultmäßig&amp;quot; nicht immer zu erreichen, weil es unterschiedliche Nummerierungssysteme gibt. Ausser dem Anlegen eines speziellen Footprints kann diese Anpassung für einzelne Bauteile wärend des Layoutens im Moduleditor vorgenommen werden. http://www.mikrocontroller.net/topic/186121#1805890&lt;br /&gt;
&lt;br /&gt;
* In PCBnew lassen sich mit &amp;quot;Datei&amp;gt;Platine hinzufügen&amp;quot; auch schon geroutete Gruppen von Bauteilen quasi als Modul einfügen, wenn sie zuvor als Board abgelegt wurden. Ebenso kann eine Bauteilgruppe, die in der Form mehrmals vorkommt, und die die schon einmal geroutet worden ist, gruppiert, kopiert und wiederverwended werden. Die dazu nötige Annotation und das Löschen der überzähligen Bauteile muss aber sorgfältig von Hand gemacht werden. &lt;br /&gt;
&lt;br /&gt;
* Bibliotheken verwalten, umsortieren bzw. neu strukturieren: http://www.mikrocontroller.net/topic/187107#1817559 &lt;br /&gt;
&lt;br /&gt;
* Layout: Rest-Gummiband an Pins http://www.mikrocontroller.net/topic/120373#1092375&lt;br /&gt;
&lt;br /&gt;
* Produktion: http://www.mikrocontroller.net/topic/98034#848965&lt;br /&gt;
&lt;br /&gt;
* Bug in Version 2010-03-14: Unter Einstellungen lässt sich keine einseitige Platine wählen (wichtig für Autorouter). Lösung: Modifikation des .brd Files mit einem Editor [http://www.mikrocontroller.net/topic/172015#1651239]:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;pre&amp;gt;&lt;br /&gt;
:In der *.brd Datei gleich ganz oben...&lt;br /&gt;
:&lt;br /&gt;
:$GENERAL&lt;br /&gt;
:LayerCount 2                 -&amp;gt; auf 1 setzen&lt;br /&gt;
:&lt;br /&gt;
:$SETUP&lt;br /&gt;
:InternalUnit 0.000100 INCH&lt;br /&gt;
:ZoneGridSize 250&lt;br /&gt;
:Layers 2                     -&amp;gt; auf 1 setzen&lt;br /&gt;
:Layer[0] Rückseite power&lt;br /&gt;
:Layer[15] Vorderseite power  -&amp;gt; hab&#039; ich mal beides so gelassen&lt;br /&gt;
:&amp;lt;/pre&amp;gt;                                                                aktueller: http://www.mikrocontroller.net/topic/172015#1794699&lt;br /&gt;
&lt;br /&gt;
* Das Anlegen von Symbolen/Bauteilen in aufgelöster Darstellung ist etwas stolperig. Siehe: http://www.mikrocontroller.net/topic/294095#3136180&lt;br /&gt;
&lt;br /&gt;
* Es empfielt sich, in Kicad vorläufig KEIN Ampersand (Kaufmansund, &amp;quot;&amp;amp;&amp;quot;) im Namen einer Schaltplan- oder Boarddatei zu Verwenden. Es besteht ein Bug beim Export/Plotten nach SVG. Siehe oben unter &amp;quot;Drucken / Export&amp;quot; und dann &amp;quot;Meine erzeugten SVG Plots sind kaputt.&amp;quot;. Siehe auch: http://tech.groups.yahoo.com/group/kicad-users/message/14952&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Kühlkörper&#039;&#039;&#039; können als Symbol und Footprint (Modul) angelegt werden. Die Befestigungslöcher können im  Modul als Pad ausgeführt werden. Die Padnummer aller Pads sollte gleich sein (gleicher Anschluss / über Kühlkörper verbunden), z.B. &amp;quot;1&amp;quot;. Entsprechend ein Symbol mit Pin und korrespondierender Pinnummer anlegen. Wenn der Kühlkörper elektrisch nirgendwo verbunden sein soll, dann die Anschlusspinne im Schaltplan als &amp;quot;unused&amp;quot; markieren. Als Referenz in Symbol und Footprint habe ich &amp;quot;HS&amp;quot; (HeatSink) gewählt. Es ist zu überlegen, ob &amp;quot;HS&amp;quot; nicht auch als Padnummer besser wäre.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Kartenumrisse/Outlines&#039;&#039;&#039;: Für immer wiederkehrende Platinengrössen, z.B. die beliebte Eurokarte, kann zur Vereinfachung des Zeichnens einmal ein Eurokartenumriss im Layer &amp;quot;outlines&amp;quot; gezeichnet werden, und als Modul abgelegt werden. Um die Zahl der Kollisionen beim Einlesen der Netzliste zu verringern, wird im Schaltplan ein Dummy-Symbol ohne Pinne angelegt. In CVpcb dann dieses Symbol mit dem passenden Kartenumriss Footprint/Modul verbinden, und es wird automatisch in PCBnew eingefügt. Als Referenz in Symbol und Footprint habe ich &amp;quot;Outl&amp;quot; (OUTLine) gewählt.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Sprachanpassung&#039;&#039;&#039;: Ich will mein KiCAD auf Deutsch / Englisch / Französisch / Finnisch oder sonst eine Sprache umstellen. Wie geht das?&lt;br /&gt;
** Siehe : http://www.mikrocontroller.net/topic/262039#2719056&lt;br /&gt;
**Die deutsche Übersetzung der Texte und Hilfetexte/Tooltips ist manchmal etwas unelegant. Wem so etwas auffält, bitte Mitteilung am Ende dieses Threads: http://www.mikrocontroller.net/topic/255932#2641638 (deutschsprachig) oder an die KiCAD user group unter http://tech.groups.yahoo.com/group/kicad-users/ (englischsprachig, auch bei Fällen wo es um die deutsche Übersetzung geht). Diese Mitteilungen nach Möglichkeit nicht in Launchpad.&lt;br /&gt;
** Ich habe aber keine Möglichkeit, die Sprache umzustellen!&lt;br /&gt;
*** Wenn Debian eine Fehlermeldung &amp;quot;Cannot set locale to &#039;xy_XY&#039;. kommt, ist die entsprechende Umgebung nicht installiert. Unter Debian als root in der Konsole: &amp;quot;dpkg-reconfigure locales&amp;quot; aufrufen. Es öffnet sich eine ncurses-gui, wo die entsprechenden Einstellungen gemacht werden können. Für &amp;quot;Deutsch&amp;quot; wähle ich &amp;quot;de_DE.utf8&amp;quot;.&lt;br /&gt;
*** Wenn nichts passiert, fehlen möglicherweise die localisierungs Dateien. Sie sind NICHT Teil der Sourcen, und finden sich in http://bazaar.launchpad.net/~kicad-developers/kicad/doc/files/head:/internat/. Auf Debian und verwandten Systemen müssen die einzelnen localisationsordner, z. B. &amp;quot;de&amp;quot; nach /usr/local/share/kicad/internat kopiert werden. Dann als root dort Leserechte erteilen mit &amp;quot;chmode -R 755 /usr/local/share/kicad/internat&amp;quot;.&lt;br /&gt;
*** Wenn ein Mischmasch aus Englisch und der gewählten Sprache existiert, sind entweder nicht alle Begriffe übersetzt (siehe oben) oder wegen Umbenennung von Variablen ist eine Inkonsistenz entstanden. Siehe: http://www.mikrocontroller.net/topic/326622#3565178&lt;br /&gt;
** Für die KiCad Localsisation wird &amp;quot;GNU gettext&amp;quot; verwendet. Eine kleine Hilfestellung zur Anpassung der Localisation findet sich hier: http://dev.kicad-pcb.org/docs/GUI_Translation_HOWTO.pdf. Info zu Gnu gettext findet sich hier: http://de.wikipedia.org/wiki/GNU_gettext&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Projektdateien (.pro) Pfadschreibweise&#039;&#039;&#039;: In einer Windowsumgebung ist es anscheinend nötig, relative Pfade speziell zu kennzeichnen. Siehe: http://www.mikrocontroller.net/topic/326869#new&lt;br /&gt;
&lt;br /&gt;
=== Problem: Case Senitive Symbols ab BZR4646 (Jan./Feb. 2014) ===&lt;br /&gt;
Ab BZR4646 sind die Symbole in Eeschema &amp;quot;Case Sensitive&amp;quot;. Das bedeutet: In alten Schaltplandateien wurden für die Symbolnamen nur Großbuchstaben verwendet, auch wenn die Originalnamen in der Library Kleinbuchstaben enthielten. Ab BZR4646 werden die Symbolnamen in den Schaltplandateien genauso geschrieben wie die Originalnamen in der Library. Leider werden dadurch bei alten Schaltplandateien die großgeschriebenen Symbolnamen nicht mehr in den Bibliotheksdateien erkannt. Auch nicht in den &amp;quot;-cache.lib&amp;quot; Dateien. Ganz so kritisch, wie es sich anhört, ist es wiederum auch nicht, weil KiCad schon seit geraumer Zeit die Schaltpläne in der neuen Version speichert. Jemand, der mit aktuellen KiCad Versionen an aktuellen Schaltplänen arbeitet, wird darum den Übergang vermutlich nicht bemerken. Allerdings tritt das Problem bei alten Schaltplänen auf, die möglicherweise Jahrelang unberührt auf der Festplatte lagen. Um die Symbolnamen in diesen alten Schaltplandateien anzupassen, existiert das Python3 Skript &amp;quot;PyKiCad-CaseSensitiveLibCure_RevC_21Mar2014.py&amp;quot;. Es ist ein &amp;quot;Stand alone&amp;quot; Python3 skript, das nicht in das KiCad interne Python skripting eingebunden ist. Die Datei kann hier bezogen werden:[[Media:PyKiCad-CaseSensitiveLibCure_RevC_21Mar2014.zip]].&lt;br /&gt;
Autor: Bernd Wiebus, GNU-GPL.&lt;br /&gt;
&lt;br /&gt;
=== Tipps&amp;amp;Tricks: Building Blocks ===&lt;br /&gt;
* Eine unfertige Dokumentation, wie man das hierarchische Schaltplansystem von KiCAD verwendet, um daraus schnell und rationell Schaltpläne mit vorgefertigten Schaltplänen (Building Blocks) nach dem Baukastensystem aufzubauen. Enthält auch ein Beispielprojekt. Beachte die Liesmich.txt Datei. [[Media:BuildingBlocksKiCAD-EXPERIMENTELL.zip]] Das File  KiCAD-HierarchischeSchaltplaene+buildingBlocksRevA_Vorlaeufig.pdf, enthält eine vorläufige Beschreibung dazu. KiCAD-HierarchischeSchaltplaene+buildingBlocksRevA-EN.pdf is an English description how to use hirarchical schematics as building blocks for a fast and rationel schematic design. Es fehlt noch die Übersetzung und die Bebilderung und ein paar Berichtigungen und Ergänzungen. ;-) . Das echte Hauptbeispielprojekt ist UnderVoltageDetector24V-2Group_Experimental.pro bzw. UnderVoltageDetector24V-2Group_Experimental.sch. Im Ordner Experimentalprojekt23052010 findet sich ein weiterer Ordner BuildingBlocksExperimental. Dieser enthält die Ausgangsbausteine VoltageRegulatorBuildingBlock.sch mit VoltageRegulatorBuildingBlock-cache.lib und  VoltageDetectorBuildingBlock.sch mit VoltageDetectorBuildingBlock-cache.lib. Die Projektdateien der Buildingblocks .pro sind nur der Vollständigkeit und zur leichteren Bearbeitung zugefügt. Aus VoltageDetectorBuildingBlock.sch und VoltageRegulatorBuildingBlock.sch wurde (nach umkopieren, umbenenen und kleiner Änderung) im übergeordneten Ordner das Projekt VoltageRegulatorBuildingBlock.pro unter verwendung des &amp;quot;Zwischenbuildingblocks&amp;quot; UnderVoltageDetectorBuildingBlock.sch zusammengesetzt. NICHT VERGESSEN DIE CACHE.LIB EINZUBINDEN! Sonst gibt es nur Fragezeichen statt Bauteile. Das Beispielprojekt enthält eine 24V Unterspannungsüberwachung für einen Bleiakku, die zwei 12V Gruppen überwacht. Nicht elegant, aber hoffentlich robust. Autor: Bernd Wiebus , GNU-GPL. Der dazubezügliche Beitrag im Forum ist: http://www.mikrocontroller.net/topic/178683#1724114&lt;br /&gt;
*[[Media:HierarchischeSchaltplaeneAlsBausteineInKicad_RevC_23Dec2013.pdf]] VERBESSERTE und AKTUALISIERTE Version von KiCAD-HierarchischeSchaltplaene+buildingBlocksRevA_Vorlaeufig.pdf aus obiger Zip-Datei. Beschreibt, wie mit Hilfe der hierarchischen Schaltplanstruktur aus einzelnen, vorgefertigten Schaltplänen schnell und rationell neue Schaltpläne modular zusammengesetzt werden können.&lt;br /&gt;
* Eine Sammlung von gängigen Schaltungen mit den Längstreglern LM317 /LM78xx /LM79xx und dem Timer 555, die nach dem in obig erwänten Dokument KiCAD_HierarchischeSchaltplaene+buildingBlocksRevA_Vorlaeufig.pdf beschriebenen Vorgehen als Building Blocks in KiCAD verwendet werden können, findet sich unter: http://www.mikrocontroller.net/articles/KiCAD#Building-Blocks&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Tipps&amp;amp;Tricks: Lochraster Platinen Entwurf mit KiCad ===&lt;br /&gt;
&lt;br /&gt;
Wer viel mit Lochraster Platinen arbeitet, hat gelegentlich auch ein Bedürfnis, diese Tätigkeit mit einem Layoutprogramm zu begleiten. Zum einen um den Platzbedarf besser abschätzen zu können, zum anderen, um dadurch auch eine schnelle und einfache Dokumentation auch für Lochrasterprojekte zu schaffen. Auch dazu kann KiCad verwendet werden.&lt;br /&gt;
* Vorgehensweise: Schaltplan in Eeschema erstellen wie üblich, Netzliste erzeugen, und in CVpcp die Bauteile zuordnen. In PCBnew dann das Raster einblenden und auf 2,54mm (100mil) stellen. Nun geben die Rasterpunkte die Position der Löcher der Lochrasterplatine vor. Nach dem Einlesen der Netzliste bei Lochraster mit Streifenleitungen am besten zweiseitig manuell routen. Auf der Unterseite der Richtung der Streifenleitung in Längstrichtung folgen (z.b. wagerecht). Auf der Oberseite die Brücken dazu quer legen (z.B. senkrecht). Zweipolige Bauteile immer senkrecht oder wagerecht positionieren. Dieses Verfahren geht grundsätzlich mit jedem Layoutprogramm, das ein Raster anzeigen kann.&lt;br /&gt;
&lt;br /&gt;
== Bibliotheken ==&lt;br /&gt;
&lt;br /&gt;
In diesem Abschnitt sollen unsere Arbeiten an Bibliotheken koordiniert werden. Dabei sollen alle Arbeiten unter der Creative Commons Lizenz stattfinden. Das heisst insbesondere, dass keine Arbeiten mit anderem Copyright unseren Bibliothekspool vergiften sollen z.&amp;amp;nbsp;B. durch unerwünschte Konvertierung von EAGLE-Bibliotheken.  &lt;br /&gt;
&lt;br /&gt;
Unsere Designziele sind:&lt;br /&gt;
* Frei benutzbar (Creative Commons Lizenz) &lt;br /&gt;
* Einheitlich (Richtlinien?)&lt;br /&gt;
** Vorschlag von Marko für Bohrungen und Pads siehe [http://www.mikrocontroller.net/topic/124070#1176177]&lt;br /&gt;
* Fehlerfrei (Nachkontrolle durch andere User)&lt;br /&gt;
&lt;br /&gt;
=== Wünsche ===&lt;br /&gt;
&lt;br /&gt;
Hier soll eine Strichliste geführt werden, welche neuen Bauteile gesucht sind bzw. welche oder besseren, genaueren Versionen benötigt werden. Bitte gebt an, was bei bestehenden Bauteilen problematisch ist.&lt;br /&gt;
&lt;br /&gt;
Bevor wir Bibliotheken erstellen, sollten auf jeden Fall einige Parameter - insbesondere für die Schaltplansymbole - festgelegt werden: Pinlänge, Pinabstand, Größe der Schriften, Konventionen bzw. Nummerierung (z.B. bei gepolten Bauteilen wie Dioden, Elkos usw.). Sonst entsteht Wildwuchs, weil jeder für sich anderes festlegt.&lt;br /&gt;
&lt;br /&gt;
* Stehende Layouts für 7805 und N-FETs: ||||&lt;br /&gt;
** Passt TO220_VERT ? Natürlich! Nur die Anschlussnumerierung muss ev. passend adaptiert werden. Ist unter &amp;quot;TO-220&amp;quot; in http://www.mikrocontroller.net/wikifiles/7/70/Transistor_TO-220_RevB_03Sep2012.zip enthalten. In allen Perversionen. Stehend, liegend, rumgedreht von der Rückseite usw....&lt;br /&gt;
* LPC21xx / LPC22xx / LPC23xx |&lt;br /&gt;
* EINE AVR ATmega-Bibliothek, wo ALLE Controller drin sind. |||||||&lt;br /&gt;
* AVR XMegas |&lt;br /&gt;
* AT90CAN128 / allgemein mehr AVRs (MEGA &amp;amp; TINY) ||||||&lt;br /&gt;
*Wegen der AVRs und ATMEGAs: Bitte hier http://www.kicadlib.org/Fichiers/Kerusey_Karyu_Atmel_Library.html mal schauen, und den Wunsch auf den Typ konkretisieren! Der Atmelzoo ist so verwirrend vielfältig.....&lt;br /&gt;
** Leider ist die dazugehörige Bibliothek defekt.&lt;br /&gt;
* Schaltregler (u.A. LM257x, LM267x, MC33063, L5973D) |||| Der MC33063 hat gleiches Pinning und Gehäuse wie MC34063! Darum kann der in http://www.mikrocontroller.net/wikifiles/8/84/Symbols_ICs-Diskrete_RevD9.lib verwendet werden.&lt;br /&gt;
* Spulen (z.&amp;amp;nbsp;B. diverse Wuerth) |&lt;br /&gt;
* Drosseln (B82790 für CAN, Würth 744207) |&lt;br /&gt;
* Ferrite (7427930 - 32, 742792651, 74279263) |&lt;br /&gt;
** ??? Was genau ist nun Footprint und Referenzmaeßig der Unterschied zwischen Drosseln, Spulen und Ferriten, wenn ich jetzt mal davon ausgehe, das die Teile weder Anzapfung noch mehr als eine Wicklung haben (dann wären es Trafos oder Uebertrager), und die elektrischen Werte in ein Feld eingetragen werden?? Schau mal unten in http://www.mikrocontroller.net/wikifiles/d/da/KiCAD_Module_Footprints_3D_16Sep2013.zip. Kleinere SMD-Entstörferrit Module lassen sich uebrigens aus Footprints für SMD-Widerstaenden zaubern, in dem man sie umbenahmt und mit der Referenz &amp;quot;L&amp;quot; versieht. ;-)&lt;br /&gt;
* STM32 Mikrocontroller Bibliothek (sofern möglich alle) |||&lt;br /&gt;
* Arduinos |&lt;br /&gt;
** Arduino Due ||&lt;br /&gt;
&lt;br /&gt;
=== Entwürfe ===&lt;br /&gt;
&lt;br /&gt;
Neue Bibliotheken oder Änderungen sollen zunächst in diesem Abschnitt &lt;br /&gt;
vorgestellt werden. &lt;br /&gt;
&lt;br /&gt;
==== Symbolbibliotheken ====&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/96460#832961 ATmega3250/TQFP100] von Fred S. (Gast)&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/96460#844741 ATMega3290 im 100Pin-Gehäuse] von Fred S. (Gast)&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/132811#1205130 RFM12-Funkmodul] von Dominik C.&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/133310#1210137 CAN Controller MCP2515 und Transceiver MCP2551] von Dominik C.&lt;br /&gt;
&lt;br /&gt;
* [[Media:SymbolsSimilarEN60617+oldDIN617-RevB-en.lib]] VERALTET! Nur aus Kompatibilitätsgründen behalten. Ersetzt für Neuentwicklungen durch Revision E1. Schaltplan Symbolbibliothek fuer KiCAD mit Symbolen, die denen aus der EN60617 oder der ALTEN DIN 617 ÄHNLICH sind. Von Bernd Wiebus&lt;br /&gt;
&lt;br /&gt;
* [[Media:SymbolsSimilarEN60617+oldDIN617-RevC-en.lib]] VERALTET! Nur aus Kompatibilitätsgründen behalten. Ersetzt für Neuentwicklungen durch Revision E1! Schaltplan Symbolbibliothek für KiCAD mit Symbolen, die denen aus der EN60617 oder der ALTEN DIN 617 ÄHNLICH sind. Aenderung gegenueber Rev.B: Kleinere Symbole hinzugefügt. Mit Vorsicht geniessen! Von Bernd Wiebus.&lt;br /&gt;
 &lt;br /&gt;
* [[Media:SymbolsSimilarEN60617+oldDIN617-RevD3-en.lib]] VERALTET! Nur aus Kompatibilitätsgründen behalten. Ersetzt für Neuentwicklungen durch Revision E1! Schaltplan Symbolbibliothek für KiCAD mit Symbolen, die denen aus der EN60617 oder der ALTEN DIN 617 ÄHNLICH sind.  Aenderung gegenueber Rev.C: Kleinere Fehler beseitigt. CLD Symbol hinzugefuegt. Kuehlkoerper Symbol und Dummy-Symbol fuer Boardoutlines hinzugefuegt. Thyristor und Triac Symbol zugefuegt. Copyright Symbole GNU-GPL und CC zugefuegt. Mit Vorsicht geniessen! Von Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
 &lt;br /&gt;
* [[Media:SymbolsSimilarEN60617+oldDIN617-RevE8.lib]] AKTUELLE Version! Ersetzt die Rev. B, C und die Rev. D sowie Vorgängerversionen E1-E7! Schaltplan Symbolbibliothek für KiCAD mit Symbolen, die denen aus der EN60617 oder der ALTEN DIN 617 ÄHNLICH sind.  Aenderung gegenueber Rev.D: Kleinere Fehler beseitigt. Ankerpunkte in die Nähe der Symetrieachsen verlegt. Verbinder DIN41612 / EN60603-2 &amp;quot;Eurokartenstecker&amp;quot; hinzugefügt. Große &amp;quot;BIG&amp;quot; Symbole entfernt und in der Datei BIG-SymbolsSimilarEN60617+oldDIN617-RevE.lib ausgelagert. Mit Vorsicht geniessen! Von Rene Belau und Bernd Wiebus.  CC-Zero/Public Domain!  Defektes Symbol &amp;quot;RESISTOR_RevE_Date15jun2010&amp;quot; repariert am 02. Maerz 2011. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
   &lt;br /&gt;
* [[Media:BIG-SymbolsSimilarEN60617+oldDIN617-RevE.lib]] Einige EN60617 oder der DIN 617 ÄHNLICHE Symbole in besonders GROSSER Ausführung. Vermutlich werden Sie diese GROSSEN Symbole eher NICHT benutzen wollen. Mit Vorsicht geniessen! Von Rene Belau und Bernd Wiebus. Unter GNU GPL. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[http://www.mikrocontroller.net/attachment/74203/obi.lib]] KiCAD Symbol für einen ATMEGA644. Von obi&lt;br /&gt;
&lt;br /&gt;
* [[Media:Symbols_ICs-Diskrete_RevD10.lib]] KiCAD Symbole für einige diskrete ICs. Enthält L200 (Pentawatt Gehäuse), LM2587 (Pentawatt Gehäuse), Längstregler LM317, LM78xx, LM79xx, Timer NE555, NF-Verstärker LM1875 und TDA2003 (Pentawatt Gehäuse), Schaltregler UC38xx (DIP8/SO8 und DIP14/SO14), LM2587, MC34036, LM78S40 und MCP1640, Treiber MIC4422 (DIP8/SO8 und Pentawatt Gehäuse). Allegro Halleffekt Stromwandler Typ ACS754/ACS755/ACS756 und LEM Halleffekt Stromwandler der Serie &amp;quot;HX&amp;quot;. Programierbarer Oszillator Si570/Si571 sowie Quarzoszillator Typ KXO-200. Dazu Transistor Arrays BC847S und BC857S (in einfacher und in aufgelöster Darstellung) und Supressordioden Array SR05. Schieberegister 74HC4094 . Spannungs-/Laderegler uA723/LM723 in 14 und 20 poligem Gehäuse. HF/ZF Verstärker/Mischer/Demodulator TCA440 alias exDDR A244D, FM Frontend TA7358. Spannungsmonitor ICL7665. Autor Bernd Wiebus.  CC-Zero/Public Domain!  Mit Vorsicht geniessen! Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:Symbols_ICs-Opto_RevB_16Sep2013.lib]] KiCAD Symbole für Optokoppler CNY17, IL300. IL388, TLP250, SFH617A-1, SFH617A-2, SFH617A-3, SFH617A-4, KPC357, LTV35x, und PC357. LWL Empfänger Toshiba TORX170 TORX173 TORX193  und TORX194 (Toslink). LWL Sender Toshiba TOTX170 TOTX173 TOTX193  und TOTX194 (Toslink). LWL Empfänger Agilent HFBR-252x und Sender Agilent HFBR-152x Serie (Versatile Link). 7 Segment Anzeigen HDSM531, HDSM533, LTS6760, LTS6780, SBC18-11EGWA. Autor Rene Belau und Bernd Wiebus. CC-Zero / Public domain. Mit VORSICHT geniessen! Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:Transformer-Diskrete_RevA.lib]] KiCAD Symbole für einige diskrete Transformatoren. Coilcraft Q4434-B = Rhombus T1311 und Myrra-74040 ETD29. Autor: Bernd Wiebus. Mit Vorsicht geniessen! Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:Symbols_DCDC-ACDC-Converter_RevC_20Jul2012.lib]] KiCAD Symbole für einige DCDC/ACDC-Converter. Enthält CINCON EC5BC12, CINCON EC6C11, TRACO TED-1212, TRACO TED-XXXX Dual Output, TRACO TED-XXXX Single Output, TRACO TEN10-1212, TRACO TEN10-XXXX, TRACO TME-XXXX, TRACO TMH-XXXX Single Output, TRACO TMH-XXXX Dual Output, BOTHHAND CF-Serie und DELTA DPS05U09D. Neu seit 20 Juli 2012: TRACO ACDC-Converter der TMLM Serie. Autor: Bernd Wiebus. GNU-GPL. Mit Vorsicht geniessen! Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:Symbols_Socket-DIN41612_RevA.lib]] KiCAD Symbole für DIN41612 Stecker und Buchsen (Die bekannten Eurokartenstecker). Autor: Bernd Wiebus. GNU-GPL. Mit Vorsicht geniessen! Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:Symbols_EN60617_13Mar2013.lib]] KiCAD Symbole für die EN60617. Strikter als die Symbole aus SymbolsSimilarEN60617+oldDIN617-Rev~~.lib. Autor: Bernd Wiebus. CC-Zero/Public Domain! Mit Vorsicht geniessen! Hierzu gehört der Katalog: [[Media:Symbols_EN60617_13Mar2013.pdf]] Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:Symbols_EN60617-10_HF-Radio_DRAFT_12Sep2013.lib]] HF-Blockschaltbild Symbole für KiCad. EXPERIMENTELL! Autor: Bernd Wiebus. Mit Vorsicht geniessen! Lizenz: CC-Zero / Public domain.  Hierzu gehört der Katalog: [[Media:EN60617-10_HF-Radio_SymbolCatalog_DRAFT.pdf]] Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:Symbols_Microcontroller_Philips-NXP_RevA_06Oct2013.lib]] Symbole der NXP Microcontroller LPC2104, LPC2105 und LPC2106 fuer KiCad.  Autor: Bernd Wiebus. Mit Vorsicht geniessen! Lizenz: CC-Zero / Public domain. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
==== Modulbibliotheken ====&lt;br /&gt;
&lt;br /&gt;
* [[Media:KiCAD_Module_Footprints_3D_14Mar2014.zip]] Eine Sammlung von KiCAD Modulen bzw. Footprints diskreter Bauteile. Neben den obligatorischen Rs, Cs und Ls sind Schrack und Omron Kartenrelais (die Footprints passen auch fuer andere Hersteller), diverse Dioden, Klemmen WAGO 236 (RM 5mm) Serie und WAGO 734 Serie, Sicherungshalter (Schurter und Bulgin) für 5x20 und 6x30, SMD Sicherungen 1206 und Sicherungen/Sicherungshalter TE5/TR5,Flachsicherungen Standard und Mini, Kuehlkoerper und Eurokartenoutlines enthalten. Zusaetzlich TO92, TO220, TO220-5 (Pentawatt) und TO247 Gehaeuse. Ebenso die vermissten PISN und PISR SMD Drosseln. Einige Throughhole C&amp;amp;D Bobin Drosseln, Bourns 3296, Spectrol Type 43 / Econtrim und Piher PT15 Trimmer . Potentiometer Alps RK16 und Spectrol Type 148/149. Transformatoren Coilcraft Q4434-B / Rhombus T1311 sowie ETD29 von Epcos und Myrra sind auch dabei. Eurokartenstecker/-buchsen DIN 41612 Typ B1, B2, C1, C2 und C3. Ebenfalls enthalten: GNU-GPL und Creative Commons  Symbole. Dazu Messpunkte. BNC-Buchse, Quarzoszillator, SMD Widerstände und Kondensatoren.  (0805, 1206, 2512) sowie experimentelle Universalfootprints SMD/Throughole. SMD-Dioden: MELF, Mini-MELF, SMA, SMB und SMC. Halleffekt Stromwandler mit Allegro CB-PFF, CB-PSF und CB-FSS Gehäusen.Dazu Stecker Molex Serie KK, Würth SMD Drosseln und Doppeldrosseln. Neosid Filter und Drosseln. TRACO ACDC-Converter der TMLM Seie und SOT23, SOT143, SOT143R, TSOT-6 / MK06A sowie SC70-6 SMD Footprints für Dioden, Transistoren bzw. Dioden und Transistor Arrays und kleinere ICs. Mini Universal Mate-N-Lock Steckersockel (Tyco/AMP). 2-6 Pin, vertikale und horizontale Typen. Verbesserte Fiducials und Logos. Dazu SMD-Tantalkondensatoren und ETAL NF-Transformatoren. TO50-3 und TO50-4 Gehäuse. 7 Segment Anzeigen. LQFP48/TQFP48 Gehäuse. Hallsonden Stromwandler mit Allegro CB-PFF, CB-PSF und CB-FSS Gehäusen. Halleffekt Stromwandler der Serie &amp;quot;HX&amp;quot; von LEM.  Neu in der Version vom 14. Oktober 2013: Berichtigte SOT23 Footprints. Fast alles ohne 3D Modelle, aber manchmal mit PDF-Ausdruck zur leichten Identifikation. Mit Vorsicht geniessen! Ohne Garantie und  CC-Zero/Public Domain!  Von Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:KiCAD-Module_Buzzer_Beeper_RevA_25Oct2010.zip]] Einige Footprints von Summern /Buzzern / Beepern für KiCAD. Enthaelt Kingstate KCG0601, Pro Signal ABI-009-RC, Pro Signal ABI-010-RC, Pro Signal ABT-410-RC, Star Micronics HMB-06/HMB-12 und Projects Unlimited AI-4228-TWT-R. Alles ohne 3D Modelle, aber mit PDF-Ausdruck zur leichten Identifikation. Mit Vorsicht geniessen! Ohne Garantie und  CC-Zero/Public Domain!  Von Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:KiCAD-Module_CommonModeChoke_Wuerth_Type-WE-CMB_RevA_25Oct2010.zip]] Footprints der Gleichtaktdrosseln der Serie Würth WE CMB (through hole) für KiCAD. Enthält die Verschieden Bauformen XS, S, M, L, XL und XXL. Alles ohne 3D Modelle, aber mit PDF-Ausdruck zur leichten Identifikation. Mit Vorsicht geniessen! Ohne Garantie und  CC-Zero/Public Domain!  Von Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:DCDC-ACDC-Converter_RevC_20Jul2012.zip]] Footprints von DCDC/ACDC-Convertern für KiCAD. Enthält CINCON EC5BC12, CINCON EC6C11, TRACO TED-1212, TRACO TED-XXXX Dual Output, TRACO TED-XXXX Single Output, TRACO TEN10-1212, TRACO TEN10-XXXX, TRACO TME-XXXX, TRACO TMH-XXXX Single Output, TRACO TMH-XXXX Dual Output, BOTHHAND CF-Serie und DELTA DPS05U09D. Neu seit 20 Juli: TRACO ACDC-Converter der TMLM Serie. Alles ohne 3D Modelle, aber mit PDF-Ausdruck zur leichten Identifikation. Mit Vorsicht geniessen! Ohne Garantie und  CC-Zero/Public Domain!  Von Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:Opto-Devices_RevC_03Oct2012.zip]] Footprints von Optoelectronischen Bauteilen für KiCAD. Enthält 6 Polige DIL Footprints für CNY17, auch in &amp;quot;wide&amp;quot;, SMD Optokoppler Footprints (1 Kanalig) und Footprints für Toshiba (Toslink) und Agilent (Versatile Link) LWL Ssender und Empfänger. Alles ohne 3D Modelle, aber mit PDF-Ausdruck zur leichten Identifikation. Mit Vorsicht geniessen! Ohne Garantie und unter GNU-GPL. Von Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:Pentawatt_RevB_24Oct2012.zip]] Footprints von Pentawatt Gehäusen für KiCAD. Enthält verschiedene Ausführungen der TO220-5 Gehäuse in gerade und verkröpft, sowie stehend und liegend. Mit 3D-Modellen und mit PDF-Ausdruck zur leichten Identifikation. Mit Vorsicht geniessen! Ohne Garantie und unter GNU-GPL. Von Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
*[[Media:Transistor_TO-220_RevB_03Sep2012.zip]] Footprints von TO220-3 Gehäusen für KiCAD. Enthält verschiedene Ausführungen der TO220 Transistor Gehäuse in  stehend und liegend. Mit 3D-Modellen und mit PDF-Ausdruck zur leichten Identifikation. Mit Vorsicht geniessen! CC-Zero/Public domain! Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
*[[Media:Transistor_TO-247_RevC.zip]] Footprints von TO247 Gehäusen für KiCAD. Enthält verschiedene Ausführungen der Transistor Gehäuse in  stehend und liegend. Mit PDF-Ausdruck zur leichten Identifikation. Mit Vorsicht geniessen! CC-Zero/Public domain! Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[http://www.mikrocontroller.net/topic/176405#new]] KiCAD Modul / Footprint für ein TSSOP38 Gehäuse. Autor Raphael Reu.&lt;br /&gt;
&lt;br /&gt;
* [[http://www.mikrocontroller.net/topic/190088#1856759]] Texas Instruments TPIC8101 Klopfsensor Interface (für Verbrennungsmotoren). Autor Peter Diener.&lt;br /&gt;
&lt;br /&gt;
* [[Media:IR-directFET_Packages_RevB.zip]] Footprints von directFET SMD-Transistor Gehäusen von International Rectifier für KiCAD. Enthält die SH, SJ, SQ, ST, S1, MN, MP, MT, MX, MZ und die L8-Outline. Nähere Informationen in den Datenblättern betroffener Transistoren und in der International Rectifier Applikationsnotiz AN-1035. &amp;quot;directFET&amp;quot; ist übrigens eine Handelsmarke von International Rectifier und die Gehäuse sind proprietär. Also vorsichtig sein und an &amp;quot;second source&amp;quot; denken. Mit 3D Modellen und mit PDF-Ausdruck zur leichten Identifikation. Mit Vorsicht geniessen! Ohne Garantie und unter CC-Zero / Public domain. Von Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:Neosid-Devices_Coils_Filters_25Apr2012.zip]] Footprints von NEOSID Bauteilen. Spulen, Luftspulen, Filter ec. für KiCAD. Through hole und SMD. Alles ohne 3D Modelle, aber mit PDF-Ausdruck zur leichten Identifikation. Mit Vorsicht geniessen! Ohne Garantie und unter GNU-GPL. Von Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:SOT23_SOT143_SOT143R_TSOT6_MK06A_SC70-6_Housing_14Mar2014.zip]] Footprints von SOT23, SOT143, SOT143R, TSOT-6 /MK06A und SC70-6 SMD Gehäusen, wie sie oft für Dioden und Transistoren, aber auch Dioden und Transistor Arrays verwendet werden. Auch ICs findet man in der Bauform. Es sind Standard Footprints und spezielle für Handlötung vorhanden. KiCad Legacy Format und neues .pretty Format. Alles ohne 3D Modelle, aber mit PDF-Ausdruck zur leichten Identifikation. Mit Vorsicht geniessen! Ohne Garantie und unter GNU-GPL. Von Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:MiniUniversalMate-N-LokSockets_13Aug2012.zip]] Footprints von Mini Universal Mate-N-Lok Steckersockeln (Tyco/AMP). 2-6 Pin, verticale und horizontale Typen. Alles ohne 3D Modelle, aber mit PDF-Ausdruck zur leichten Identifikation. Mit Vorsicht geniessen! Ohne Garantie und unter GNU-GPL. Von Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:NF-Transformer_ETAL_RevA_28Aug2012.zip]] Footprints und 3D-Mesh Modelle von NF-Transformatoren der Firma ETAL (http://www.etalgroup.com). SMD und THT Typen. Mit PDF-Ausdruck zur leichteren Identifikation. In der Bibliothek ist auch der bekannte Übertrager ETAL P1200, der von Box73 (http://www.box73.de) vertrieben wird. Mit Vorsicht geniessen! Ohne Garantie und unter GNU-GPL. Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de &lt;br /&gt;
&lt;br /&gt;
* [[Media:TantalCapacitors_SMD_RevA_28Aug2012.zip]] Footprints von Tantal Kondensatoren SMD Größe A bis E (EIA-3216, EIA-3528, EIA-6032, EIA-7343 und EIA-7360). Alles ohne 3D Modelle, aber mit PDF-Ausdruck zur leichten Identifikation. Ohne Garantie und unter GNU-GPL. Mit Vorsicht geniessen! Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:SOT89-3_SOT89-5_Housing_RevA_02Sep2012.zip]] Footprints und 3D-Mesh Modelle von SOT89-3 und SOT89-5 SMD Gehäusen. Mit PDF-Ausdruck zur leichteren Identifikation. Ohne Garantie und unter GNU-GPL.  Mit Vorsicht geniessen! Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:SOT126_SOT32_Housings_RevA_22Oct2012.zip]] Footprints und 3D-Mesh Modelle von SOT126 / SOT32 Gehäusen. Mit PDF-Ausdruck zur leichteren Identifikation. Ohne Garantie und unter GNU-GPL.  Mit Vorsicht geniessen! Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:Allegro_HallSensors_24Oct2012.zip]] Footprints und 3D Modelle von Allegro Hall-Effect Stromsensoren mit PFF, PSF oder PSS Gehäuse (ACS754, ACS755, ACS756).  Mit PDF-Ausdruck zur leichteren Identifikation. Ohne Garantie und unter GNU-GPL.  Mit Vorsicht geniessen! Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
* [[Media:VML0806_Housing_Rohm_27Oct2012.zip]] Footprints und 3D Modell eines Transistors im 0806 Format (VML0806 / Rohm).  Mit PDF-Ausdruck zur leichteren Identifikation. Ohne Garantie und unter GNU-GPL.  Mit Vorsicht geniessen! Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
*[[Media:TO-50_Housings_RevA_21Apr2013.zip]]  Footprints/Module von TO50-3 und TO50-4 Transistor Gehäusen.Mit PDF-Ausdruck zur leichteren Identifikation. Ohne Garantie und unter CC-Zero / Public Domain.  Mit Vorsicht geniessen! Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
*[[Media:OldSowjetAera_Transistor_RevA.zip]] Footprints/Module von Kleinleistungstransistoren aus der Sowjetära.Mit 3D-Modell und PDF-Ausdruck zur leichteren Identifikation. Ohne Garantie und unter CC-Zero / Public Domain.  Mit Vorsicht geniessen! Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
*[[Media:SIP9_Housing_14Jun2013.zip]] Footprints/Module von SIP9 Gehäusen (z.B. TA7358).Mit 3D-Modell und PDF-Ausdruck zur leichteren Identifikation. Ohne Garantie und unter CC-Zero / Public Domain.  Mit Vorsicht geniessen! Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
*[[Media:7Segment_16Sep2013.zip]] Footprints/Module von 7-Segment Anzeigen HDSM531 (SMD), HDSM533 (SMD), LTS6760, LTS6780 undSBC18-11EGWA. Dazu PDF-Ausdruck zur leichteren Identifikation. Ohne Garantie und unter CC-Zero / Public Domain.  Mit Vorsicht geniessen! Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
*[[Media:BNC-Sockets_RevA.zip]] Footprints/Module von TYCO BNC-Buchsen für KiCad. Mit 3D Modellen und PDF Preview. Ohne Garantie und unter CC-Zero / Public Domain.  Mit Vorsicht geniessen! Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
*[[Media:LQFP_TQFP_RevA_06Oct2013.zip]] Footprints/Module von LQDP48/TQFP48 Gehäuseb für KiCad. Ohne 3D Modelle, aber mit PDF Preview. Ohne Garantie und unter CC-Zero / Public Domain.  Mit Vorsicht geniessen! Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
*[[Media:LEM_HallEffectTransducers_RevA_13Oct2012.zip]] Module/Footprints von Halleffekt Stromwandlern der Serien &amp;quot;HX&amp;quot; und &amp;quot;HTFS&amp;quot; von LEM. Mit 3D-Modellen  und PDF Preview. Ohne Garantie und unter CC-Zero / Public Domain.  Mit Vorsicht geniessen! Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
==== 3D-Modelle ====&lt;br /&gt;
&lt;br /&gt;
* [[Media:MeshModells_VRML-Wings3D_13Oct2013.zip]]  3D-Modelle diverser elektronischer Bauteile im wrl 2.0 und wings Format. Enthalten: DD-PAK (TO263AB), D-PAK (TO252AA), SMD Dioden MELF, MiniMELF, SMA, SMB und SMC, Transformatoren ETAL P1165, P1200, P2781, P3000, P3181, PP3188 und P3191, SO126 / SOT32 in horizontal und vertikal, SOT223-3, TO263-3, SOT89-3, SOT89-5, TO220 horizontal und vertikal und reverse. TO220-5 horizontal, vertical, inline und verkröpft, VML0806. SIP9. 7 Segment SMD Anzeige HDSM531/HDSM533 in Grün, gelb, rot und orange. directFET SMD-Transistor Gehäusen von International Rectifier für KiCAD. Enthält die SH, SJ, SQ, ST, S1, MN, MP, MT, MX, MZ und die L8-Outlines. Flachsicherungen Standard und Mini. Halleffekt Stromwandler LEM &amp;quot;HX&amp;quot; Serie und Allegro ACS754/ACS755/ACS756 mit CB-PFF, CB-PSF und CB-FSS Gehäusen. Ohne Garantie und unter CC-Zero / Public Domain Lizenz. Mit Vorsicht geniessen! Autor: Bernd Wiebus. Verbesserungsvorschläge willkommen an bernd.wiebus@gmx.de&lt;br /&gt;
&lt;br /&gt;
==== Building-Blocks ====&lt;br /&gt;
*[[Media:BuildingBlocks_16Jun2013.zip]] enthält eine Sammlung von gängigen Schaltungen mit den Längstreglern LM317 /LM78xx /LM79xx und dem Timer 555, die nach dem in diesem [[Media:HierarchischeSchaltplaeneAlsBausteineInKicad_RevC_23Dec2013.pdf]] Dokument beschriebenen Vorgehen als Building Blocks in KiCAD verwendet werden können. Ein Katalog dazu befindet sich hier: [[Media:KatalogUeberKiCadBuildingBlocks_21Apr2013.pdf]]. Autor: Bernd Wiebus, Lizenz: Creative Commons. Experimentell! Ohne Garantie! Mit Vorsicht geniessen!&lt;br /&gt;
&lt;br /&gt;
Wenn mindestens ein weiterer KiCAD User die Bibliothek geprüft hat, kann sie in den folgenden Unterabschnitt verschoben werden.&lt;br /&gt;
&lt;br /&gt;
=== Geprüfte ===&lt;br /&gt;
&lt;br /&gt;
Hier sollen geprüfte Bibliotheken gesammelt werden. Bitte angeben, wer die Prüfung gemacht hat.&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/132288#new STM32F103xx (LQFP64) Schaltplansymbol] erstellt/geprüft: Dominik C.; Marko S.&lt;br /&gt;
&lt;br /&gt;
*Bei der STMF103xx fehlt glaub ich der Portpin PD2 :) Grüße :)&lt;br /&gt;
&lt;br /&gt;
=== Sonstige Bibliotheken im Netz ===&lt;br /&gt;
* https://github.com/KiCad/kicad-library Neues offizielles Repository bei Github.&lt;br /&gt;
* https://github.com/KiCad Neues Repository bei Github.&lt;br /&gt;
* http://www.kicadlib.org/&lt;br /&gt;
* http://per.launay.free.fr/kicad/kicad_php/composant.php &lt;br /&gt;
* http://www.reniemarquet.cjb.net/kicad/libs/o_analog.zip (NE555 u.a.)&lt;br /&gt;
* http://github.com/Inte/kicadlib&lt;br /&gt;
* http://www.df0fkw.datenoase.de/index.php?option=com_content&amp;amp;view=article&amp;amp;id=107:kicad-libraries&amp;amp;catid=36:bastelprojekte&amp;amp;Itemid=67&lt;br /&gt;
* http://open-project.ch/kicadlib&lt;br /&gt;
* http://library.oshec.org/ Von EAGLE konvertiert, also Vorsicht bei der Verwendung! &lt;br /&gt;
* http://smisioto.no-ip.org/elettronica/kicad/kicad-en.htm&lt;br /&gt;
&lt;br /&gt;
=== Tools ===&lt;br /&gt;
&lt;br /&gt;
Da die in KiCad verwendeten Dateien klarschriftlesbar sind, lassen sie sich sehr leicht mit externen Programmen und Skripten bearbeiten, um spezielle Funktionalitäten zu erzeugen. Eine kleine Auswahl an Programmen/Skripten ist hier zusammengestellt:&lt;br /&gt;
&lt;br /&gt;
* [http://kicad.rohrbacher.net/quicklib.php Quick KICAD Library Component Builder]&lt;br /&gt;
* Gerber-Tools sind für KiCAD weniger nötig, da KiCAD mit GerbView seinen eigenen Gerberviewer mitbringt. Dieser ist mächtig genug, die eingelesenen Gerberfiles als Platine in PCBnew zu exportieren, wo sie manipuliert werden können. Dieses geht aber nur mit Gerber-RS274X Daten. Ebensowenig können Gerberfiles zu Nutzen zusammengefügt werden. Hierzu bietet sich &amp;quot;Gerbmerge&amp;quot; http://claymore.engineer.gvsu.edu/~steriana/Python/gerbmerge/ an. Wer lediglich aus Sicherheitsgründen die von KiCAD erzeugten Gerberdaten mit einem fremden Gerber-Vierer inspizieren möchte, findet hier Hinweise:http://www.mikrocontroller.net/articles/Gerber-Tools&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/204063#2011138 KiCAD (Multi-)Symbol Tool] von Joghurt3000 zur Erstellung von Symbolen aus einer Textvorlage&lt;br /&gt;
* [http://cyclerecorder.org/footprintbuilder Footprintbuilder] Java-Programm zu Erstellung von Footprints.&lt;br /&gt;
*Wer seine Platine &amp;quot;panelisieren&amp;quot; (d.h. mehrmals nebeneinander anordnen um in einem &amp;quot;Nutzen&amp;quot; gleich mehrere Platinen fertigen zu können) möchte, kann das mit dem Python 2 Skript &amp;quot;panelize.py&amp;quot; tun. Das Programm arbeitet direkt auf den kicad .brd Files, so das das Mehrfachnutzen Board unter PCBnew nachbearbeitet werden kann, für z.B. einen  DRC. &amp;quot;panelize.py&amp;quot; kann hier bezogen werden: http://blog.borg.ch/?p=12&lt;br /&gt;
* &amp;quot;Raef&amp;quot; hat ein Python Script erstellt, das Bauteile automatisch ähnlich der Anordnung im Schaltplan plaziert. Siehe: http://www.mikrocontroller.net/topic/293903#3245990&lt;br /&gt;
*Wer die Reihenfolge der Subschaltpläne ändern will (Wegen Übersichtlichkeit/Bestimmt auch die Reihenfolge beim Ausdrucken), kann dieses Python 3 Skript verwenden (Liesmich/Readme beachten): http://www.mikrocontroller.net/wikifiles/9/90/PyKicadSchematic-ID_Interchanger_RevC.zip Autor: Bernd Wiebus, GNU-GPL.&lt;br /&gt;
* Um ältere Schaltpläne vor BZR4646 mit &amp;quot;upper case&amp;quot; Symbolnamen zu konvertieren, kann dieses Python 3 Skript verwendet werden: [[Media:PyKiCad-CaseSensitiveLibCure_RevA_25Feb2014.zip]]. Autor: Bernd Wiebus, GNU-GPL.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Diese Skripte sind unabhängig von der PCBnew internen Python 2 Schnittstelle.&lt;br /&gt;
&lt;br /&gt;
== Beispielprojekte ==&lt;br /&gt;
&lt;br /&gt;
* http://www.mikrocontroller.net/topic/33653#963083 JTag-wiggler&lt;br /&gt;
* http://www.mikrocontroller.net/topic/190088#1856757 Klopfsensor von Peter Diener.&lt;br /&gt;
* http://www.mikrocontroller.net/topic/188897 Open-Hardware / Open-Source USB-basierter SPI BIOS-Chip Programmer von Uwe Hermann&lt;br /&gt;
* http://www.mikrocontroller.net/articles/Modellbahn_Servodecoder_f%C3%BCr_Weichen_mit_R%C3%BCckmeldung Modellbahn Servodecoder für Weichen mit Rückmeldung&lt;br /&gt;
* http://www.mikrocontroller.net/articles/RS485_IO_Board_-_ModellBahnLichtSteuerung RS485 IO Board - ModellBahnLichtSteuerung&lt;br /&gt;
* [[Media:UndervoltageProtection_RevD_14Aug2012.zip]] Beispielprojekt eines Tiefentladeschutzes für einen Blei-Gel Akku, der von den Platinenabmessungen her auf einen typischen 12V/7,2Ah Akku passt. Ausserdem bietet er abgesicherten Zugang zu den Akkuklemmen, was auch in vielen Fällen beachtenswert ist. Leider ist das Projekt noch etwas unaufgeräumt, es fehlen noch Bauteilwerte, und in der Form wurde noch keine fertige Platine daraus hergestellt, aufgebaut und getestet. Autor: Bernd Wiebus, GNU-GPL.&lt;br /&gt;
&lt;br /&gt;
== Diskussionen (teilweise seeeehr alt) ==&lt;br /&gt;
&lt;br /&gt;
* http://www.mikrocontroller.net/topic/120373#1089075 &lt;br /&gt;
* http://www.mikrocontroller.net/topic/98034#848559&lt;br /&gt;
* http://www.mikrocontroller.net/topic/95864#828660&lt;br /&gt;
* http://www.mikrocontroller.net/topic/77738#647041&lt;br /&gt;
* http://www.mikrocontroller.net/topic/103806#907523&lt;br /&gt;
* http://www.mikrocontroller.net/topic/41999#316195&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
&lt;br /&gt;
* [http://iut-tice.ujf-grenoble.fr/kicad/index.html KiCAD] Homepage 1 und Download&lt;br /&gt;
* [http://www.lis.inpg.fr/realise_au_lis/kicad/ KiCAD] Homepage 2 und Download&lt;br /&gt;
* [http://www.kicad-pcb.org/display/KICAD/KiCad+EDA+Software+Suite KiCAD] Neue Homepage&lt;br /&gt;
* [http://www.kicad-pcb.org/display/KICAD/KiCad+Scripting+Reference+Manual] Speziell Informationen zum Python-Scripting.&lt;br /&gt;
* [http://kicad.sourceforge.net/wiki/index.php/DE:Main_Page KiCAD Wiki]&lt;br /&gt;
* Tutorials: &lt;br /&gt;
** [http://kicad.sourceforge.net/wiki/index.php/DE:Mini_tutorial Mini-Tutorial]&lt;br /&gt;
** [http://timogruss.de/kicad-loesung-fuer-die-leiterplatten-entwicklung/ KiCad Tutorial auf timogruss.de] (deutsch)&lt;br /&gt;
** http://www.curiousinventor.com/guides/kicad&lt;br /&gt;
** http://xtronics.com/reference/kicad.html&lt;br /&gt;
** http://bastler-archiv.de/elektronik/platinenherstellung-platinenlayout-mit-kicad-teil-1/ (deutsch, Teil 1)&lt;br /&gt;
** http://bastler-archiv.de/elektronik/platinenherstellung-platinenlayout-mit-kicad-teil-2/ (deutsch, Teil 2)&lt;br /&gt;
* Usergroups:&lt;br /&gt;
** [http://tech.groups.yahoo.com/group/kicad-users/ Yahoo-KiCAD-Group]&lt;br /&gt;
* Tools&lt;br /&gt;
** [http://www.freerouting.net/ Freerouting] Autorouter&lt;br /&gt;
** Script, um in hierarchischen Schaltplänen die Reihenfolge zu verändern:http://www.mikrocontroller.net/wikifiles/9/90/PyKicadSchematic-ID_Interchanger_RevC.zip&lt;br /&gt;
* Plattformen&lt;br /&gt;
** Mac: http://brokentoaster.com/kicad/&lt;br /&gt;
**Ubuntu: [http://www.mikrocontroller.net/topic/257321#2658268 KiCAD selber compilieren]&lt;br /&gt;
** http://wiki.xtronics.com/index.php/Kicad Transtronics site (englisch)&lt;br /&gt;
* HowTo von Tom Boyd (englisch)&lt;br /&gt;
** http://kicadhowto.org/&lt;br /&gt;
* Bugreports! Wer einen Bug gefunden hat, bitte [https://bugs.launchpad.net/kicad hier] angeben! Kicad wird laufend verbessert.&lt;br /&gt;
&lt;br /&gt;
[[Category:Schaltplaneditoren]]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=NRF24L01_Tutorial&amp;diff=82019</id>
		<title>NRF24L01 Tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=NRF24L01_Tutorial&amp;diff=82019"/>
		<updated>2014-03-11T21:04:16Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: /* Der Empfänger */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
Das Tutorial soll den Einstieg, eine Funkstrecke mit dem &lt;br /&gt;
[http://www.nordicsemi.com/eng/Products/2.4GHz-RF/nRF24L01P nRF24L01+] aufzubauen, erleichtern.&lt;br /&gt;
&lt;br /&gt;
Beim nRF24L01+ handelt es sich um einen single Chip Transceiver von Nordic Semiconductor. Dieser Chip kann also sowohl als Sender (TX) als auch als Empfänger (RX) arbeiten und bietet eine Reihe von sehr praktischen Features wie Ultra Low Power (nur 900nA in Power Down Modus), 6 Data Pipes beim Betrieb als MultiCeiver, Enhanced Shockburst (dazu später mehr), Automatic Packet Handling, 5V tolerante Eingänge, SPI Schnittstelle und noch einiges mehr. &lt;br /&gt;
&lt;br /&gt;
Um mit dem nRF24L01+ eine Funkstrecke zu realisieren braucht man nicht mehr als einen µC sowie ein nRF24L01+ Funkmodul. Das ganze natürlich zwei mal. &lt;br /&gt;
In dem Tutorial wird der AVR Atmega8 verwendet sowie nRF24L01+ Module die sehr günstig über das Internet (Ebay derzeit unter 2€) in verschiedenen Ausführungen bezogen werden können. Für Testaufbauten reichen einfache Steckbretter um die Hardware aufzubauen. &lt;br /&gt;
Bei der Hand sollte unbedingt das Datenblatt des nRF24L01+ sein und natürlich das Datenblatt des jeweils verwendeten µC. Das Datenblatt des nRF24L01+ kann von Nordic Semiconductor runtergeladen werden: &lt;br /&gt;
&lt;br /&gt;
[http://www.nordicsemi.com/kor/nordic/download_resource/8765/2/8827113 nRF24L01 Datenblatt]&lt;br /&gt;
&lt;br /&gt;
Vieles in diesem Tutorial basiert auf der Vorarbeit von Stefan Engelke und Brennan Ball denen mein Dank dafür gilt.&lt;br /&gt;
&lt;br /&gt;
== Das nRF24L01+ Modul ==&lt;br /&gt;
Ein Funkmodul mit dem nRF24L01+ hat zumindest 8 Anschlüsse: &lt;br /&gt;
[[Datei:Foto_nrf24L01+Modul.jpg|miniatur|rechts|Handelsübliche nRF24L01+ Module]]&lt;br /&gt;
Vcc, GND, IRQ, CE, und die vier SPI bezogenen Anschlüsse CSN, SCK, MISO, und MOSI.&lt;br /&gt;
&lt;br /&gt;
Je nach Datenblatt des verwendeten Moduls ist die Spannung zu wählen, manche Module verfügen über eigene Spannungsregler, der nRF24L01+ selbst verträgt Spannungen von 1,9V bis 3,6V. Auf dem von mir verwendeten Modul befindet sich kein weiterer Spannungsregler somit muß man aufpassen den Chip nicht durch Überspannung zu ruinieren. Als Spannung habe ich 3,3V verwendet. &lt;br /&gt;
&lt;br /&gt;
Die Anschlüsse SCK, MISO, und MOSI werden mit den entsprechenden Pins des µC verbunden. Der CSN (chip select not) Pin ist active low und normalerweise auf high-Level gehalten. Wenn CSN low geschaltet wird beginnt der nRF24L01+ am SPI Port zu horchen oder anders gesagt, jedes Kommando an den Chip wird mit einem high to low schalten von CSN eingeleitet. Im Falle des Atmega8 werden SCK mit SCK, MISO mit MISO und MOSI mit MOSI verbunden. Für den CSN wurde Pin PB1 gewählt. &lt;br /&gt;
[[Datei:Stromlaufplan.png|miniatur|rechts|Stromlaufplan für den Anschluß an einen ATmega8]]&lt;br /&gt;
Was uns noch bleibt ist CE und IRQ. CE wird im RX und TX Modus verwendet für die Datenübertragung. In dem Beispiel an Pin PB0 angeschlossen. IRQ ist der Interrupt-Pin des Funkmoduls und ist active-low. Es gibt drei interne Interrupts im nRF24L01+ die den IRQ Pin low schalten wobei man sämtliche Interrupts ausmaskieren kann wenn man möchte. Am Atmega8 wurde IRQ mit Pin PD2 (INT0) verbunden um auf die externen Interrupts reagieren zu können.&lt;br /&gt;
&lt;br /&gt;
== Die SPI-Routine ==&lt;br /&gt;
Als SPI-Routine habe ich die Routine von Stefan Engelke unverändert übernommen die er dankenswerter Weise zur allgemeinen Verwendung zur Verfügung gestellt hat. [http://www.tinkerer.eu/AVRLib/SPI siehe Tinkerer.eu]&lt;br /&gt;
&lt;br /&gt;
spi.h&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#ifndef _SPI_H_&lt;br /&gt;
#define _SPI_H_&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
extern void spi_init();&lt;br /&gt;
extern void spi_transfer_sync (uint8_t * dataout, uint8_t * datain, uint8_t len);&lt;br /&gt;
extern void spi_transmit_sync (uint8_t * dataout, uint8_t len);&lt;br /&gt;
extern uint8_t spi_fast_shift (uint8_t data);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
spi.c&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;spi.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define PORT_SPI    PORTB&lt;br /&gt;
#define DDR_SPI     DDRB&lt;br /&gt;
#define DD_MISO     DDB4&lt;br /&gt;
#define DD_MOSI     DDB3&lt;br /&gt;
#define DD_SS       DDB2&lt;br /&gt;
#define DD_SCK      DDB5&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void spi_init()&lt;br /&gt;
// Initialize pins for spi communication&lt;br /&gt;
{&lt;br /&gt;
    DDR_SPI &amp;amp;= ~((1&amp;lt;&amp;lt;DD_MOSI)|(1&amp;lt;&amp;lt;DD_MISO)|(1&amp;lt;&amp;lt;DD_SS)|(1&amp;lt;&amp;lt;DD_SCK));&lt;br /&gt;
    // Define the following pins as output&lt;br /&gt;
    DDR_SPI |= ((1&amp;lt;&amp;lt;DD_MOSI)|(1&amp;lt;&amp;lt;DD_SS)|(1&amp;lt;&amp;lt;DD_SCK));&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    SPCR = ((1&amp;lt;&amp;lt;SPE)|               // SPI Enable&lt;br /&gt;
            (0&amp;lt;&amp;lt;SPIE)|              // SPI Interrupt Enable&lt;br /&gt;
            (0&amp;lt;&amp;lt;DORD)|              // Data Order (0:MSB first / 1:LSB first)&lt;br /&gt;
            (1&amp;lt;&amp;lt;MSTR)|              // Master/Slave select   &lt;br /&gt;
            (0&amp;lt;&amp;lt;SPR1)|(1&amp;lt;&amp;lt;SPR0)|    // SPI Clock Rate&lt;br /&gt;
            (0&amp;lt;&amp;lt;CPOL)|              // Clock Polarity (0:SCK low / 1:SCK hi when idle)&lt;br /&gt;
            (0&amp;lt;&amp;lt;CPHA));             // Clock Phase (0:leading / 1:trailing edge sampling)&lt;br /&gt;
&lt;br /&gt;
    SPSR = (1&amp;lt;&amp;lt;SPI2X);              // Double Clock Rate&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void spi_transfer_sync (uint8_t * dataout, uint8_t * datain, uint8_t len)&lt;br /&gt;
// Shift full array through target device&lt;br /&gt;
{&lt;br /&gt;
       uint8_t i;      &lt;br /&gt;
       for (i = 0; i &amp;lt; len; i++) {&lt;br /&gt;
             SPDR = dataout[i];&lt;br /&gt;
             while((SPSR &amp;amp; (1&amp;lt;&amp;lt;SPIF))==0);&lt;br /&gt;
             datain[i] = SPDR;&lt;br /&gt;
       }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void spi_transmit_sync (uint8_t * dataout, uint8_t len)&lt;br /&gt;
// Shift full array to target device without receiving any byte&lt;br /&gt;
{&lt;br /&gt;
       uint8_t i;      &lt;br /&gt;
       for (i = 0; i &amp;lt; len; i++) {&lt;br /&gt;
             SPDR = dataout[i];&lt;br /&gt;
             while((SPSR &amp;amp; (1&amp;lt;&amp;lt;SPIF))==0);&lt;br /&gt;
       }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
uint8_t spi_fast_shift (uint8_t data)&lt;br /&gt;
// Clocks only one byte to target device and returns the received one&lt;br /&gt;
{&lt;br /&gt;
    SPDR = data;&lt;br /&gt;
    while((SPSR &amp;amp; (1&amp;lt;&amp;lt;SPIF))==0);&lt;br /&gt;
    return SPDR;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Der SPI Befehlssatz ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Command name !! Command word (binary) !! # Data bytes !! Operation&lt;br /&gt;
|-&lt;br /&gt;
| R_REGISTER || 000A AAAA || 1 to 5 &amp;lt;br /&amp;gt; LSByte first || Read command and STATUS registers. AAAAA = 5 bit Register Map Address&lt;br /&gt;
|-&lt;br /&gt;
| W_REGISTER || 001A AAAA || 1 to 5 &amp;lt;br /&amp;gt; LSByte first || Write command and status registers. AAAAA = 5 bit Register Map Address &amp;lt;br /&amp;gt; Executable in power down or standby modes only.&lt;br /&gt;
|-&lt;br /&gt;
| R_RX_PAYLOAD || 0110 0001 || 1 to 32 &amp;lt;br /&amp;gt; LSByte first || Read RX-payload: 1 – 32 bytes. A read operation always starts at byte 0. Payload is deleted from FIFO after it is read. Used in RX mode.&lt;br /&gt;
|-&lt;br /&gt;
| W_TX_PAYLOAD || 1010 0000 || 1 to 32 &amp;lt;br /&amp;gt; LSByte first || Write TX-payload: 1 – 32 bytes. A write operation always starts at byte 0 used in TX payload.&lt;br /&gt;
|-&lt;br /&gt;
| FLUSH_TX || 1110 0001 || 0 || Flush TX FIFO, used in TX mode&lt;br /&gt;
|-&lt;br /&gt;
| FLUSH_RX || 1110 0010 || 0 || Flush RX FIFO, used in RX mode &amp;lt;br /&amp;gt; Should not be executed during transmission of acknowledge, that is, acknowledge package will not be completed.&lt;br /&gt;
|-&lt;br /&gt;
| REUSE_TX_PL || 1110 0011 || 0 || Used for a PTX device&lt;br /&gt;
Reuse last transmitted payload. &amp;lt;br /&amp;gt; TX payload reuse is active until W_TX_PAYLOAD or FLUSH TX is executed. TX payload reuse must not be activated or deactivated during package transmission.&lt;br /&gt;
|-&lt;br /&gt;
| R_RX_PL_WID* || 0110 0000 || 1 || Read RX payload width for the top R_RX_PAYLOAD in the RX FIFO. &amp;lt;br /&amp;gt; &amp;lt;b&amp;gt;Note:&amp;lt;/b&amp;gt; Flush RX FIFO if the read value is larger than 32 bytes.&lt;br /&gt;
|-&lt;br /&gt;
| W_ACK_PAYLOAD* || 1010 1PPP || 1 to 32 &amp;lt;br /&amp;gt; LSByte first || Used in RX mode. &amp;lt;br /&amp;gt; Write Payload to be transmitted together with ACK packet on PIPE PPP. (PPP valid in the range from 000 to 101). Maximum three ACK packet payloads can be pending. Payloads with same PPP are handled using first in - first out principle. Write payload: 1– 32 bytes. A write operation always starts at byte 0.&lt;br /&gt;
|-&lt;br /&gt;
| W_TX_PAYLOAD_NOACK* || 1011 0000 || 1 to 32 &amp;lt;br /&amp;gt;LSByte first || Used in TX mode. Disables AUTOACK on this specific packet.&lt;br /&gt;
|-&lt;br /&gt;
| NOP || 1111 1111 || 0 || No Operation. Might be used to read the STATUS register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;*&amp;lt;/b&amp;gt;=The bits in the FEATURE register shown in Table 28. on page 63 have to be set.&lt;br /&gt;
&lt;br /&gt;
Zu finden natürlich auch im Datasheet auf Seite 51. &lt;br /&gt;
&lt;br /&gt;
Es gibt ein paar Dinge die zu beachten sind. Bevor die Kommunikation mit dem Chip begonnen wird muß der CSN Pin high sein. Zum Start der Kommunikation wird der CSN Pin auf Low geschaltet und muß auch Low bleiben während der gesamten Dauer der Kommunikation. &lt;br /&gt;
&lt;br /&gt;
Dann wird der Befehl gesendet. Wenn man Daten vom nRF24L01+ empfangen möchte muß für jedes Byte an Daten auch ein Byte gesendet werden. Wenn man nur seine eigenen Daten an den Chip senden möchte kümmert man sich nicht weiter darum was der Chip zurücksendet. Auf jeden Fall wird parallel zu den Daten die man schickt der STATUS des Chips zurückgegeben. Ist die Unterhaltung (mit dem nRF24L01+ - es geht noch nicht um die Funkstrecke) abgeschlossen, wird CSN wieder auf High geschaltet. &lt;br /&gt;
&lt;br /&gt;
Als Beispiel: Wir wollen den R_REGISTER Befehl senden um den Inhalt des Registers TX_ADDR zu lesen. Das TX_ADDR Register enthält maximal 5 Bytes an Daten/Information. Als erstes CSN auf Low. Dann &amp;quot;0001 0000&amp;quot; an den Chip senden. Das weist den nRF24L01+ an das Register TX_ADDR auszugeben. Dann werden fünf Dummy-Bytes gesendet und für jedes Dummy-Byte erhält man ein Byte aus dem TX_ADDR Register zurück. (Der Inhalt der Dummy-Bytes ist ganz egal) Danach CSN wieder auf High. Insgesamt erhält man vom Chip sechs Bytes: Egal welches Command Byte man sendet antwortet der Chip mit dem STATUS-Register.&lt;br /&gt;
&lt;br /&gt;
Mit dem R_REGISTER können also alle Registerinhalte gelesen werden die zwischen 1 Byte und 5 Byte groß sind. &lt;br /&gt;
&lt;br /&gt;
Mit dem W_REGISTER können wir beliebig unsere Werte in die Register schreiben. Das Prinzip ist das gleiche, es wird der Befehl 001AAAAA gesendet wobei AAAAA für die Adresse des Registers steht. Danach werden - je nach Register - bis zu fünf Bytes an Daten gesendet die in das Register geschrieben werden sollen. &lt;br /&gt;
&lt;br /&gt;
R_RX_PAYLOAD ist einer der beiden Befehle die mit dem FIFO zu tun haben. R_RX_PAYLOAD liest den Inhalt des FIFO sollten Daten empfangen werden. Der Empfang von Daten wird mit dem RX_DR Interrupt angezeigt. Bei diesem Befehl ist das Vorgehen ein wenig anders. Wenn man Daten per Funkstrecke empfängt ist CE high. Sobald man ein Paket empfangen hat muß man CE low schalten um den Empfang auszuschalten und danach kann R_RX_PAYLOAD ausgeführt werden. Gefolgt von so vielen Dummy-Bytes wie Payload definiert wurde. Gelesene Pakete werden automatisch aus dem FIFO gelöscht. Sollten weitere Pakete im FIFO warten sollten die auch gleich gelesen werden. Sobald der FIFO leer ist wird der RX_DR Interrupt gelöscht und CE wieder auf High geschaltet. Der FIFO kann maximal 3 Pakete (PAYLOADS) halten. Ein Paket ist maximal 32 Bytes groß. &lt;br /&gt;
&lt;br /&gt;
Der zweite dieser Befehle ist W_TX_PAYLOAD. Er wird verwendet wenn man sich im TX-Modus befindet und Daten senden möchte. Im TX-Modus ist CE low. Nachdem man den Befehl gesendet hat werden so viele Bytes ins FIFO geladen wie man für den Empfänger auch defniniert hat. D. h. Payload Größe muß beim Sender und Empfänger gleich groß sein solange man das FEATURE-Register nicht verwendet. Nachdem die Daten in den FIFO geladen wurden muß man den CE Pin toggeln (mind. 10µs high) damit die Daten gesendet werden. Man kann auch zuerst drei Pakete in den FIFO laden und dann erst wegschicken. &lt;br /&gt;
&lt;br /&gt;
FLUSH_TX und FLUSH_RX löschen die Daten im TX_FIFO bzw. RX_FIFO. &lt;br /&gt;
&lt;br /&gt;
NOP kann sehr gut dafür verwendet werden das STATUS Register zu lesen da es - wie der Name schon sagt - sonst nichts tut.&lt;br /&gt;
&lt;br /&gt;
== Die nRF24L01+ Register ==&lt;br /&gt;
&lt;br /&gt;
Hier ist es nötig das Datenblatt ab Seite 57 zur Hand zu nehmen da die Menge an Registern das Tutorial sprengen würde, würden alle hier besprochen. &lt;br /&gt;
&lt;br /&gt;
Mit Hilfe der Register wird das Modul per SPI konfiguriert und auch kontrolliert. Die meisten Register sind 1Byte groß, in vielen Registern werden aber nicht alle Bytes verwendet. Eine Ausnahme bilden die Register RX_ADDR_P0, RX_ADDR_P1 sowie TX_ADDR die jeweils bis zu 5 Byte groß sind. (Abhängig von der Konfiguration). Die drei 32Byte großen Register werden mit eigenen SPI Befehlen gesteuert. Sie dienen dazu die Datenpakete in den nRF24L01+ zu schreiben bzw. empfangene auszulesen. &lt;br /&gt;
&lt;br /&gt;
Innerhalb der Register belegen die Informationen eine unterschiedliche Anzahl an Bits. Als Beispiel das STATUS Register. Bit 1 bis 3 geben hier zum Beispiel Auskunft über die verwendete Pipe. Während alle anderen Informationen nur 1 Bit groß sind in dem Register. Es muß also immer entsprechend maskiert werden um die gewünschten Infos zu lesen oder auch zu schreiben.&lt;br /&gt;
&lt;br /&gt;
== Die ersten Schritte ==&lt;br /&gt;
&lt;br /&gt;
So, nach dem kurzen theoretischen Überblick ist es an der Zeit die ersten Schritte zu wagen. Sollte es noch nicht der Fall sein sollten spätestens jetzt die beiden nRF24L01+ Module mit dem µC verkabelt sein. Der ATmega8 sollte für dieses Beispiel mit mind. 8Mhz laufen, ob externer Quarz oder interner Takt ist dabei egal. Nochmals zur Erinnerung: Das nRF-Modul darf mit maximal 3,6V betrieben werden, die Eingänge verkraften aber 5V Signale solange die Versorgungsspannung zwischen 2,7V und 3,3V liegt. Werft sicherheitshalber einen Blick ins Datenblatt betreffend dieser Dinge. &lt;br /&gt;
&lt;br /&gt;
Worüber man sich auch Gedanken machen muß ist, wie man die Funktion bzw. die Daten die man hin und her schickt, visualisiert. Ohne Visualisierung kann es natürlich auch funktionieren doch für das Tutorial wollen wir sicher sehen ob, und wenn ja, welche Daten hin und hergeschickt werden oder auch mal einen Registerinhalt anzeigen. In welcher Form das passiert bleibt jedem selbst überlassen. Man kann die Daten auf einem LCD ausgeben oder auch per UART an den PC liefern lassen. Hier sollte jeder das wählen womit er am Besten zurecht kommt. Theoretisch könnte man auch das Auslangen mit LEDs finden und sich die Registerinhalte oder Datenpakete mittels 8 LEDs anzeigen lassen. Allerdings wäre das nicht sehr komfortabel. &lt;br /&gt;
&lt;br /&gt;
=== Konfigurieren des nRF24L01+ ===&lt;br /&gt;
&lt;br /&gt;
Als erstes müssen wir das Modul mal initialisieren bzw. die verwendeten Anschlüsse des µC einrichten. Am besten packen wir das ganze in eine Routine die ziemlich zeitig beim Start des µC aufgerufen wird. Weiter unten findet sich dann die Header-Datei die hier verwendet wird.&lt;br /&gt;
&lt;br /&gt;
Als erstes setzen wir die beiden verwendeten Pins als Ausgänge und schalten sie in den default-Status.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void wl_module_init() &lt;br /&gt;
{&lt;br /&gt;
    DDRB |= ((1&amp;lt;&amp;lt;CSN)|(1&amp;lt;&amp;lt;CE));&lt;br /&gt;
    wl_module_CE_lo;&lt;br /&gt;
    wl_module_CSN_hi;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dann werden die beiden (eigentlich reicht INT0) externen Interrupteingänge des ATmega8 auf fallende Flanke gestellt und der Interrupt für INT0 aktiviert. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    MCUCR = ((1&amp;lt;&amp;lt;ISC11)|(0&amp;lt;&amp;lt;ISC10)|(1&amp;lt;&amp;lt;ISC01)|(0&amp;lt;&amp;lt;ISC00));&lt;br /&gt;
    GICR  = ((0&amp;lt;&amp;lt;INT1)|(1&amp;lt;&amp;lt;INT0));					&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
und zum Schluß noch SPI (siehe oben unter SPI) initialisiert:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;	    &lt;br /&gt;
    spi_init();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anbei noch die Header-Datei für das Modul: &lt;br /&gt;
[[Datei:wl_module.h]] (aus irgendeinem Grund forciert das Wiki hier große Anfangsbuchstaben, die Datei sollte als &amp;quot;wl_module.h&amp;quot; abgespeichert werden.)&lt;br /&gt;
&lt;br /&gt;
In dieser Header-Datei werden die wesentlichen Zuordnungen und Einstellungen getroffen wie Pin-Definitionen, Größe des Payloads, Interruptmaskierung für das Modul, CRC-Größe, etc. Außderdem die public functions deklariert. Im Moment noch nicht schrecken, es sind eine ganze Reihe von Funktionen die in einer wl_module.c Datei zusammengefaßt sind. Aufmerksame Leser werden feststellen, daß auch obige Funktion, die wl_module_init() dort erstellt wurde. &lt;br /&gt;
&lt;br /&gt;
In dem Projekt wird noch eine weitere Header-Datei für das Modul verwendet in dem die Mnemonics des Moduls abgebildet sind. Doch dazu gleich. &lt;br /&gt;
&lt;br /&gt;
=== Grundsätzliche Konfiguration ===&lt;br /&gt;
&lt;br /&gt;
Konfigurieren läßt sich eine ganze Menge beim nRF24L01+. Aber wir haben das Glück, daß es auch funktioniert wenn man wenig konfiguriert und die Standardwerte eingestellt läßt. &lt;br /&gt;
&lt;br /&gt;
Für unsere ersten Tests stellen wir nur das notwendigste ein. Um uns die Arbeit mit den vielen Registern zu erleichtern ist es jetzt Zeit die schon angesprochene Header-Datei vorzustellen und in weiterer Folge einzubinden. &lt;br /&gt;
&lt;br /&gt;
[[Datei:NRF24L01.h]]&lt;br /&gt;
&lt;br /&gt;
In dieser Header-Datei finden wir alle Mnemonics um auf die entsprechenden Befehle, Register und Registerinhalte zuzugreifen. Ja, es ist eine ziemlich lange Liste aber davon nicht schrecken lassen. &lt;br /&gt;
&lt;br /&gt;
Gut, dann setzen wir mal die ersten Werte im nRF24L01+. Als erstes wollen wir den Funkkanal einstellen. Dazu haben wir im wl_module.h schon wl_module_CH definiert. Ein Blick ins Datenblatt verrät uns, daß wir das Kommando W_REGISTER brauchen und der Kanal im Register RF_CH eingestellt wird. Die grundsätzliche Funktionsweise der Kommandos wurde schon weiter oben erklärt doch wie setzen wir das jetzt um? &lt;br /&gt;
&lt;br /&gt;
Wir bedienen uns dazu einer Funktion die genau ein Byte in ein gewähltes Register schreibt. reg ist das gewählte Register und value der Wert der geschrieben werden soll. Mit dieser Funktion können wir schon fast alle Register des Moduls beschreiben.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void wl_module_config_register(uint8_t reg, uint8_t value)&lt;br /&gt;
// Clocks only one byte into the given wl-module register&lt;br /&gt;
{&lt;br /&gt;
    wl_module_CSN_lo;&lt;br /&gt;
    spi_fast_shift(W_REGISTER | (REGISTER_MASK &amp;amp; reg));&lt;br /&gt;
    spi_fast_shift(value);&lt;br /&gt;
    wl_module_CSN_hi;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Um den Kanal zu setzen wird &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Set RF channel&lt;br /&gt;
    wl_module_config_register(RF_CH,wl_module_CH);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
aufgerufen.&lt;br /&gt;
&lt;br /&gt;
Fein, damit ist es uns ein leichtes den Payload zu konfigurieren. Der Payload sind die Anzahl an Bytes die auf einmal übertragen werden. Der Sender muß (solange nicht die dynamic payload length aktiviert ist) genau so viele Bytes senden wie am Empfänger als Payload-Länge eingestellt ist. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Set length of incoming payload &lt;br /&gt;
wl_module_config_register(RX_PW_P0, wl_module_PAYLOAD);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für die ersten Tests werden wir uns um keine Pipes kümmern daher reicht es erstmal wenn wir nur den Payload für die Pipe0 festlegen.&lt;br /&gt;
&lt;br /&gt;
Ich mag das Augenmerk auf folgende Zeile in der wl_config.h legen: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define wl_module_CONFIG		( (1&amp;lt;&amp;lt;MASK_RX_DR) | (1&amp;lt;&amp;lt;EN_CRC) | (0&amp;lt;&amp;lt;CRCO) )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In der Zeile wird einiges für das CONFIG Register eingestellt. Im CONFIG Register können etwa die drei Interrupts maskiert werden, es wird eingestellt ob CRC verwendet wird und ob CRC aus einem oder zwei Bytes besteht. Und dann gibt es noch zwei ganz wesentliche Dinge darin. Einerseits PWR_UP und dann auch noch PRIM_RX. PRIM_RX legt fest ob sich das Modul im TX oder im RX Modus befindet. &lt;br /&gt;
&lt;br /&gt;
Über&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Defines for setting the wl_module registers for transmitting or receiving mode&lt;br /&gt;
#define TX_POWERUP wl_module_config_register(CONFIG, wl_module_CONFIG | ( (1&amp;lt;&amp;lt;PWR_UP) | (0&amp;lt;&amp;lt;PRIM_RX) ) )&lt;br /&gt;
#define RX_POWERUP wl_module_config_register(CONFIG, wl_module_CONFIG | ( (1&amp;lt;&amp;lt;PWR_UP) | (1&amp;lt;&amp;lt;PRIM_RX) ) )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
können wir das Modul entweder im TX oder RX Modus aktivieren. &lt;br /&gt;
&lt;br /&gt;
Fürs erste können wir die restlichen Register so lassen wie eingestellt.&lt;br /&gt;
&lt;br /&gt;
Wie schaut es jetzt aus wenn wir ein Register beschreiben wollen das mehr als ein Byte an Daten enthält? Als Paradebeispiel ist dafür natürlich das schreiben des Payloads in den TX-FIFO geeignet da wir hier bis zu 32 Bytes schreiben. &lt;br /&gt;
&lt;br /&gt;
Aber auch andere Register brauchen mehr als 1 Byte, so zum Beispiel die Adressregister die bis zu 5 Bytes breit sind. &lt;br /&gt;
&lt;br /&gt;
Auch dafür können wir uns einer kleinen aber feinen Routine bedienen: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void wl_module_write_register(uint8_t reg, uint8_t * value, uint8_t len) &lt;br /&gt;
// Writes an array of bytes into inte the wl-module registers.&lt;br /&gt;
{&lt;br /&gt;
    wl_module_CSN_lo;&lt;br /&gt;
    spi_fast_shift(W_REGISTER | (REGISTER_MASK &amp;amp; reg));&lt;br /&gt;
    spi_transmit_sync(value,len);&lt;br /&gt;
    wl_module_CSN_hi;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An die Routine übergeben wird das Register das beschrieben werden soll, ein Zeiger auf das Array mit den Daten und die Größe dieses Arrays.&lt;br /&gt;
&lt;br /&gt;
=== Register wieder auslesen ===&lt;br /&gt;
&lt;br /&gt;
Eine Frage die sich sehr bald stellen wird: Wie lese ich Register wieder aus? Sei es um die Einstellungen zu  kontrollieren oder auf Bits die darin automatisch gesetzt werden zu reagieren. &lt;br /&gt;
&lt;br /&gt;
Wie wir wissen reagiert der nRF24L01+ auf jeden Befehl den wir schicken automatisch und parallel auf unseren Befehl mit der Antwort des STATUS Registers. Das STATUS Register ist ein wichtiges weil es einiges an wesentlichen Informationen enthält auf die wir reagieren müssen. So werden alle drei Interrupts in dem Register durch setzen eines entsprechenden Bits abgebildet. Dieses Bit muß durch schreiben einer 1 auch wieder gelöscht werden. Es läßt sich außerdem die Pipe auslesen die die Daten gesendet hat sowie, auch ganz wichtig, das TX_FULL Flag auslesen. Dieses Flag wird gesetzt wenn der Sende-Fifo voll ist. &lt;br /&gt;
&lt;br /&gt;
Um den Status auszulesen und sonst nix weiter zu machen können wir eine kleine Funktion einsetzen: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
//return the value of the status register&lt;br /&gt;
extern uint8_t wl_module_get_status()&lt;br /&gt;
{&lt;br /&gt;
	return wl_module_get_one_byte(NOP);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Aber nicht vergessen, egal was wir an den nRF24L01+ schicken, er antwortet jedes mal mit dem Inhalt des Status-Registers. Das können wir uns später zu  nutze machen.&lt;br /&gt;
&lt;br /&gt;
In dem Beispiel wird die Funktion wl_module_get_one_byte() verwendet: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
extern uint8_t wl_module_get_one_byte(uint8_t command)&lt;br /&gt;
{&lt;br /&gt;
uint8_t status;&lt;br /&gt;
&lt;br /&gt;
wl_module_CSN_lo;&lt;br /&gt;
status = spi_fast_shift(command);&lt;br /&gt;
wl_module_CSN_hi;&lt;br /&gt;
&lt;br /&gt;
return status;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Genau betrachtet liefert die Funktion wl_module_get_one_byte() schon den Inhalt des Status Registers. Nachdem die Funktion aber die Grundlage für den Zugriff auf einzelne Teile des Status-Registers ist die in weiteren Funktionen verwendet wird wurde für die bessere Übersichtlichkeit eine eigene Status-Abfrage Funktion implementiert.&lt;br /&gt;
&lt;br /&gt;
Wenn andere Inhalte als der Status abgefragt werden sollen etwa der Inhalt des FIFO wo ja unsere empfangenen Daten liegen bedienen wir uns einer weiteren Funktion. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void wl_module_read_register(uint8_t reg, uint8_t * value, uint8_t len)&lt;br /&gt;
// Reads an array of bytes from the given start position in the wl-module registers.&lt;br /&gt;
{&lt;br /&gt;
    wl_module_CSN_lo;&lt;br /&gt;
    spi_fast_shift(R_REGISTER | (REGISTER_MASK &amp;amp; reg));&lt;br /&gt;
    spi_transfer_sync(value,value,len);&lt;br /&gt;
    wl_module_CSN_hi;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Funktion leistet uns für einige weitere Funktionen die darauf zugreifen gute Dienste. Wollen wir als Beispiel den gewählten Funkkanal auslesen so können wir das mit dieser Funktion: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
//returns the current RF channel in RF_CH register&lt;br /&gt;
extern uint8_t wl_module_get_rf_ch()&lt;br /&gt;
{&lt;br /&gt;
	uint8_t data;&lt;br /&gt;
	&lt;br /&gt;
	wl_module_read_register(RF_CH, &amp;amp;data, 1);&lt;br /&gt;
	&lt;br /&gt;
	return data;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie man sieht greift die Funktion wl_module_get_rf_ch() auf die Funktion wl_module_read_register zu, übergibt die notwendigen Parameter und liefert uns dann das Byte zurück das in RF_CH gespeichert ist.&lt;br /&gt;
&lt;br /&gt;
=== Erster praktischer Test ===&lt;br /&gt;
&lt;br /&gt;
So, genug der Grundlagen, schauen wir uns einen ersten praktischen Test mit den Modulen an.&lt;br /&gt;
&lt;br /&gt;
Der Aufbau ist verdrahtet und mit den richtigen Spannungen versorgt, der µC läuft mit mind. 8 MHz (niedrigere Frequenzen gehen auch aber wurden von mir nicht getestet, achtet auf den passenden SPI-Vorteiler), als Optimierungsmethode ist -Os eingestellt und dem Compiler wurde auch die richtige Frequenz mitgeteilt. &lt;br /&gt;
&lt;br /&gt;
Als erstes werden wir beim Sender einen Zähler hochzählen und die Zahlen an den Empfänger übermitteln. Dadurch sehen wir, ob die Funkstrecke funktioniert. Welche Bytes tatsächlich übertragen werden ist schlußendlich egal. &lt;br /&gt;
&lt;br /&gt;
==== Der Sender ====&lt;br /&gt;
&lt;br /&gt;
Hier die kurze Main-Routine für den Sender, verwendete Funktionen werden im Anschluß besprochen. Nach belieben könnt ihr an freie Pins noch LED anschließen um bestimmte Ereignisse optisch zu überwachen. Im Code selbst wird darauf verzichtet. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * nRF24L01_Tutorial_Sender.c&lt;br /&gt;
 *&lt;br /&gt;
 * Created: 06.01.2012 20:15:04&lt;br /&gt;
 *  Author: Ernst Buchmann&lt;br /&gt;
 */ &lt;br /&gt;
&lt;br /&gt;
#ifndef F_CPU				//Define F_CPU if not done &lt;br /&gt;
#define F_CPU 8000000UL&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
#include &amp;lt;util/delay.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;spi.h&amp;quot;&lt;br /&gt;
#include &amp;quot;wl_module.h&amp;quot;&lt;br /&gt;
#include &amp;quot;nRF24L01.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
volatile uint8_t timercounter;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
	uint8_t payload[wl_module_PAYLOAD];		//Array for Payload&lt;br /&gt;
	uint8_t maincounter =0;&lt;br /&gt;
	uint8_t k;&lt;br /&gt;
	&lt;br /&gt;
	wl_module_init();	//initialise nRF24L01+ Module&lt;br /&gt;
	_delay_ms(50);		//wait for nRF24L01+ Module&lt;br /&gt;
	sei();&lt;br /&gt;
	&lt;br /&gt;
	wl_module_tx_config(wl_module_TX_NR_0);		//Config Module&lt;br /&gt;
		&lt;br /&gt;
	//Timer aktivieren ATMEGA8&lt;br /&gt;
	#if defined(__AVR_ATmega8__)&lt;br /&gt;
	TCCR0 |= ( (1&amp;lt;&amp;lt;CS02) | (1&amp;lt;&amp;lt;CS00));		//Prescaler auf 1024 ATMEGA8&lt;br /&gt;
	TIMSK |= ( (1&amp;lt;&amp;lt;TOIE0));					//enable TOVF ATMEGA8&lt;br /&gt;
	#endif // __AVR_ATmega8__&lt;br /&gt;
	&lt;br /&gt;
	//Timer aktivieren ATMEGA88A&lt;br /&gt;
	#if defined(__AVR_ATmega88A__)&lt;br /&gt;
	TCCR0B |= ( (1&amp;lt;&amp;lt;CS02) | (1&amp;lt;&amp;lt;CS00));&lt;br /&gt;
	TIMSK0 |= ( (1&amp;lt;&amp;lt;TOIE0));&lt;br /&gt;
	#endif // __AVR_ATmega88A__&lt;br /&gt;
		&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
		if (timercounter &amp;gt;= 30)			//30 entspricht ~1 Sekunde bei 8MHz&lt;br /&gt;
			{&lt;br /&gt;
				timercounter = 0;&lt;br /&gt;
			&lt;br /&gt;
				&lt;br /&gt;
				for (k=0; k&amp;lt;=wl_module_PAYLOAD-1; k++)&lt;br /&gt;
				{&lt;br /&gt;
					payload[k] = k;&lt;br /&gt;
				}&lt;br /&gt;
			&lt;br /&gt;
				payload[0] = maincounter;&lt;br /&gt;
				payload[1] = maincounter+1;				&lt;br /&gt;
			&lt;br /&gt;
				wl_module_send(payload,wl_module_PAYLOAD);&lt;br /&gt;
				&lt;br /&gt;
				maincounter++;&lt;br /&gt;
				if (maincounter &amp;gt;250)&lt;br /&gt;
				{&lt;br /&gt;
					maincounter = 0; &lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER0_OVF_vect)&lt;br /&gt;
{&lt;br /&gt;
	timercounter++;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//Unterscheidung je nach verwendeten µC&lt;br /&gt;
#if defined(__AVR_ATmega8__)&lt;br /&gt;
ISR(INT0_vect)&lt;br /&gt;
#endif // __AVR_ATmega8__&lt;br /&gt;
#if defined(__AVR_ATmega88A__)&lt;br /&gt;
ISR(INT0_vect)&lt;br /&gt;
#endif // __AVR_ATmega88A__&lt;br /&gt;
#if defined(__AVR_ATmega168__)&lt;br /&gt;
ISR(PCINT2_vect) &lt;br /&gt;
#endif // __AVR_ATmega168__  &lt;br /&gt;
// Interrupt handler &lt;br /&gt;
{&lt;br /&gt;
    uint8_t status;   &lt;br /&gt;
    &lt;br /&gt;
        // Read wl_module status &lt;br /&gt;
        wl_module_CSN_lo;                               // Pull down chip select&lt;br /&gt;
        status = spi_fast_shift(NOP);					// Read status register&lt;br /&gt;
        wl_module_CSN_hi;                               // Pull up chip select&lt;br /&gt;
		&lt;br /&gt;
		&lt;br /&gt;
		if (status &amp;amp; (1&amp;lt;&amp;lt;TX_DS))							// IRQ: Package has been sent&lt;br /&gt;
		{&lt;br /&gt;
			wl_module_config_register(STATUS, (1&amp;lt;&amp;lt;TX_DS));	//Clear Interrupt Bit&lt;br /&gt;
			PTX=0;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		if (status &amp;amp; (1&amp;lt;&amp;lt;MAX_RT))							// IRQ: Package has not been sent, send again&lt;br /&gt;
		{&lt;br /&gt;
			wl_module_config_register(STATUS, (1&amp;lt;&amp;lt;MAX_RT));	// Clear Interrupt Bit&lt;br /&gt;
			wl_module_CE_hi;								// Start transmission&lt;br /&gt;
			_delay_us(10);								&lt;br /&gt;
			wl_module_CE_lo;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		if (status &amp;amp; (1&amp;lt;&amp;lt;TX_FULL))							//TX_FIFO Full &amp;lt;-- this is not an IRQ&lt;br /&gt;
		{&lt;br /&gt;
			wl_module_CSN_lo;                               // Pull down chip select&lt;br /&gt;
			spi_fast_shift(FLUSH_TX);						// Flush TX-FIFO&lt;br /&gt;
			wl_module_CSN_hi;                               // Pull up chip select&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So, Teile wie Timer oder Timerinterrupt sollten bekannt sein. Schauen wir uns die Funktionen an die aufgerufen werden. &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
wl_module_init();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
ist die bereits bekannte Initialisierungsfunktion wie oben besprochen. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
wl_module_tx_config(wl_module_TX_NR_0);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Müssen wir uns genauer ansehen. In dieser Funktion werden alle wesentlichen Register eingestellt die wir brauchen um das Modul als Sender zu nutzen. Alle verwendeten Funktionen sollten in einer wl_module.c Datei zusammengefasst werden. Obwohl wir es in diesem Beispiel noch nicht nutzen übergeben wir an wl_module_tx_config als Argument die Pipe auf der der Sender senden soll. Das Argument wird dazu  verwendet die entsprechende Adresse für den Sender festzulegen. Diese Routine ist also schon dafür eingerichtet um später einen Multi-Ceiver Betrieb mit 6 Sendern zu ermöglichen. (Beim Empfänger weiter unten wird eine einfache Konfigurationsroutine verwendet mit der kein Multi-Ceiver Betrieb möglich ist!)&lt;br /&gt;
&lt;br /&gt;
Die Variable PTX wird als globale Variable definiert und dazu verwendet um festzustellen ob gerade gesendet wird. Wird gesendet wird sie im Code auf 1 geschaltet, sonst auf 0. &lt;br /&gt;
&lt;br /&gt;
Zum Schluß wird mittels TX_POWERUP (siehe oben) das Modul als Sender aktiviert. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
extern void wl_module_tx_config(uint8_t tx_nr) &lt;br /&gt;
{&lt;br /&gt;
    uint8_t tx_addr[5];&lt;br /&gt;
	&lt;br /&gt;
    // Set RF channel&lt;br /&gt;
    wl_module_config_register(RF_CH,wl_module_CH);&lt;br /&gt;
    // Set data speed &amp;amp; Output Power configured in wl_module.h&lt;br /&gt;
    wl_module_config_register(RF_SETUP,wl_module_RF_SETUP);&lt;br /&gt;
    //Config the CONFIG Register (Mask IRQ, CRC, etc)&lt;br /&gt;
    wl_module_config_register(CONFIG, wl_module_CONFIG);&lt;br /&gt;
    &lt;br /&gt;
    wl_module_config_register(SETUP_RETR,(SETUP_RETR_ARD_750 | SETUP_RETR_ARC_15));&lt;br /&gt;
	&lt;br /&gt;
	//set the TX address for the pipe with the same number as the iteration&lt;br /&gt;
			switch(tx_nr)			&lt;br /&gt;
			{&lt;br /&gt;
				case 0: //setup TX address as default RX address for pipe 0 (E7:E7:E7:E7:E7)&lt;br /&gt;
					tx_addr[0] = tx_addr[1] = tx_addr[2] = tx_addr[3] = tx_addr[4] = RX_ADDR_P0_B0_DEFAULT_VAL;&lt;br /&gt;
					wl_module_set_TADDR(tx_addr);&lt;br /&gt;
					wl_module_set_RADDR(tx_addr);&lt;br /&gt;
					break;&lt;br /&gt;
				case 1: //setup TX address as default RX address for pipe 1 (C2:C2:C2:C2:C2)&lt;br /&gt;
					tx_addr[0] = tx_addr[1] = tx_addr[2] = tx_addr[3] = tx_addr[4] = RX_ADDR_P1_B0_DEFAULT_VAL;&lt;br /&gt;
					wl_module_set_TADDR(tx_addr);&lt;br /&gt;
					wl_module_set_RADDR(tx_addr);&lt;br /&gt;
					break;&lt;br /&gt;
				case 2: //setup TX address as default RX address for pipe 2 (C2:C2:C2:C2:C3)&lt;br /&gt;
					tx_addr[1] = tx_addr[2] = tx_addr[3] = tx_addr[4] = RX_ADDR_P1_B0_DEFAULT_VAL;&lt;br /&gt;
					tx_addr[0] = RX_ADDR_P2_DEFAULT_VAL;&lt;br /&gt;
					wl_module_set_TADDR(tx_addr);&lt;br /&gt;
					wl_module_set_RADDR(tx_addr);&lt;br /&gt;
					break;&lt;br /&gt;
				case 3: //setup TX address as default RX address for pipe 3 (C2:C2:C2:C2:C4)&lt;br /&gt;
					tx_addr[1] = tx_addr[2] = tx_addr[3] = tx_addr[4] = RX_ADDR_P1_B0_DEFAULT_VAL;&lt;br /&gt;
					tx_addr[0] = RX_ADDR_P3_DEFAULT_VAL;&lt;br /&gt;
					wl_module_set_TADDR(tx_addr);&lt;br /&gt;
					wl_module_set_RADDR(tx_addr);&lt;br /&gt;
					break;&lt;br /&gt;
				case 4: //setup TX address as default RX address for pipe 4 (C2:C2:C2:C2:C5)&lt;br /&gt;
					tx_addr[1] = tx_addr[2] = tx_addr[3] = tx_addr[4] = RX_ADDR_P1_B0_DEFAULT_VAL;&lt;br /&gt;
					tx_addr[0] = RX_ADDR_P4_DEFAULT_VAL;&lt;br /&gt;
					wl_module_set_TADDR(tx_addr);&lt;br /&gt;
					wl_module_set_RADDR(tx_addr);&lt;br /&gt;
					break;&lt;br /&gt;
				case 5: //setup TX address as default RX address for pipe 5 (C2:C2:C2:C2:C6)&lt;br /&gt;
					tx_addr[1] = tx_addr[2] = tx_addr[3] = tx_addr[4] = RX_ADDR_P1_B0_DEFAULT_VAL;&lt;br /&gt;
					tx_addr[0] = RX_ADDR_P5_DEFAULT_VAL;&lt;br /&gt;
					wl_module_set_TADDR(tx_addr);&lt;br /&gt;
					wl_module_set_RADDR(tx_addr);&lt;br /&gt;
					break;&lt;br /&gt;
			}&lt;br /&gt;
	&lt;br /&gt;
	PTX =0;&lt;br /&gt;
	TX_POWERUP;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In der Main-Routine wird ein Timer dazu verwendet ca. jede Sekunde einen Zähler (maincounter) hinauf zu zählen (bis max. 250) und im Array payload wird das erste Element mit dem Wert des maincounters belegt. &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
payload[0] = maincounter;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Schleife dient nur dazu das Array mit irgendwelchen Werten zu belegen die am Empfänger auch abgerufen werden können um damit zu &amp;quot;spielen&amp;quot;. Dann wird die Funktion aufgerufen die das Array ins Modul überträgt und die Sendung der Daten beginnt. &lt;br /&gt;
&lt;br /&gt;
wl_module_send(payload,wl_module_PAYLOAD); kümmert sich darum. &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void wl_module_send(uint8_t * value, uint8_t len) &lt;br /&gt;
// Sends a data package to the default address. Be sure to send the correct&lt;br /&gt;
// amount of bytes as configured as payload on the receiver.&lt;br /&gt;
{&lt;br /&gt;
    while (PTX) {}                  // Wait until last paket is send&lt;br /&gt;
&lt;br /&gt;
    wl_module_CE_lo;&lt;br /&gt;
&lt;br /&gt;
    PTX = 1;							// Set to transmitter mode&lt;br /&gt;
    TX_POWERUP;							// Power up&lt;br /&gt;
    &lt;br /&gt;
    wl_module_CSN_lo;                   // Pull down chip select&lt;br /&gt;
    spi_fast_shift( FLUSH_TX );			// Write cmd to flush tx fifo&lt;br /&gt;
    wl_module_CSN_hi;                   // Pull up chip select&lt;br /&gt;
    &lt;br /&gt;
    wl_module_CSN_lo;                   // Pull down chip select&lt;br /&gt;
    spi_fast_shift( W_TX_PAYLOAD );		// Write cmd to write payload&lt;br /&gt;
    spi_transmit_sync(value,len);		// Write payload&lt;br /&gt;
    wl_module_CSN_hi;                   // Pull up chip select&lt;br /&gt;
    &lt;br /&gt;
    wl_module_CE_hi;                    // Start transmission&lt;br /&gt;
	_delay_us(10);						// Grünes Modul funktioniert nicht mit 10µs delay&lt;br /&gt;
	wl_module_CE_lo;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zum Schluß werfen wir noch einen Blick auf die Interrupt-Routine ISR(INT0_vect). Wir wissen, daß es drei Zustände gibt die einen Interrupt auslösen können: RX_DR der Auftritt wenn neue Daten empfangen wurden, TX_DS der Auftritt wenn Daten gesendet wurden und MAX_RT der Auftritt wenn die maximale Anzahl an Sendungswiederholungen ohne Erfolg stattgefunden haben. Sobald einer der Zustände auftritt wird auch das passende Bit im STATUS-Register gesetzt. Um das Bit zu löschen muß eine 1 geschrieben werden. Jeder dieser drei Zustände kann ausmaskiert werden und löst dann keinen Interrupt aus. Man kann so entweder per Interrupt-Routine auf ein Ereignis reagieren oder aber auch mittels polling auf das interessierende Bit auf ein Ereignis reagieren. &lt;br /&gt;
&lt;br /&gt;
In der ISR(INT0_vect) wird zum Beispiel auf TX_DS reagiert und auf MAX_RT. Soblad das Paket gesendet wurde wird TX_DS wieder zurückgesetzt und die Variable PTX auf 0 gesetzt. MAX_RT wird genutzt um die Daten noch einmal zu senden. Der TX-FIFO Speicher wird ja nicht gelöscht wenn eine Datenübertragung fehlgeschlagen hat.&lt;br /&gt;
&lt;br /&gt;
==== Der Empfänger ====&lt;br /&gt;
&lt;br /&gt;
So, ein nRF24L01+ Modul sollte mal funken. Um das zu kontrollieren brauchen wir jetzt unser zweites nRF24L01+ Modul mit dem wir die Daten empfangen. Ich verwende in dem Beispiel eine LCD-Anzeige um die Daten anzuzeigen auf das aber nicht weiter eingegangen wird. Wie die Daten angezeigt werden ist jedem selbst überlassen, genau so gut kann man mittels UART die Daten am PC anzeigen lassen oder was immer Euch zur Verfügung steht. Auch beim Empfänger nicht darauf vergessen die üblichen Stolpersteine wie -Os, µC-Frequenz etc. einzustellen. &lt;br /&gt;
&lt;br /&gt;
Wie schon angekündigt können empfangene Daten mittels Polling abgefragt werden oder über IRQ. In dem Beispiel wird mittels Polling kontrolliert ob neue Daten angekommen sind. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * nRF24L01_Tutorial_RX.c&lt;br /&gt;
 *&lt;br /&gt;
 * Created: 06.01.2012 22:51:57&lt;br /&gt;
 *  Author: Ernst Buchmann&lt;br /&gt;
 */ &lt;br /&gt;
&lt;br /&gt;
#ifndef F_CPU				//define F_CPU if not done &lt;br /&gt;
#define F_CPU 20000000UL&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
#include &amp;lt;util/delay.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;quot;spi.h&amp;quot;&lt;br /&gt;
#include &amp;quot;lcd-routines.h&amp;quot;&lt;br /&gt;
#include &amp;quot;wl_module.h&amp;quot;&lt;br /&gt;
#include &amp;quot;nRF24L01.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
//Variablen&lt;br /&gt;
volatile uint8_t PTX;			//Global Variable&lt;br /&gt;
char itoabuffer[20];&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
	uint8_t payload[wl_module_PAYLOAD];		//holds the payload&lt;br /&gt;
	uint8_t nRF_status;						//STATUS information of nRF24L01+&lt;br /&gt;
	uint8_t zaehler = 0;&lt;br /&gt;
	&lt;br /&gt;
	lcd_init();&lt;br /&gt;
	lcd_clear();&lt;br /&gt;
	wl_module_init();		//Init nRF Module&lt;br /&gt;
	_delay_ms(50);			//wait for Module&lt;br /&gt;
	sei();					//activate Interrupts&lt;br /&gt;
	wl_module_config();		//config nRF as RX Module, simple Version&lt;br /&gt;
	&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
		while (!wl_module_data_ready());			//waits for RX_DR Flag in STATUS&lt;br /&gt;
		nRF_status = wl_module_get_data(payload);	//reads the incoming Data to Array payload&lt;br /&gt;
		zaehler = payload[0];&lt;br /&gt;
		lcd_clear();&lt;br /&gt;
		lcd_home();&lt;br /&gt;
		itoa(zaehler, itoabuffer, 10);				//conversion into String&lt;br /&gt;
		lcd_string(itoabuffer);&lt;br /&gt;
		&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ist die ziemlich kurze main-Routine zum Abfragen der Daten die im Empfänger angekommen sind. Geübten Augen wird sofort auffallen, daß die Abfrage über Polling in diesem Beispiel den µC solange in einer while-Schleife fest hält bis neue Daten angekommen sind. Das ist natürlich nicht praktikabel wenn der µC noch andere Dinge zu erledigen hätte. Für ein erstes Übungsbeispiel wo der Fokus nur darauf liegt die Funkstrecke einzurichten soll uns das nicht stören. Schauen wir und das Programm im Detail an: &lt;br /&gt;
&lt;br /&gt;
Achtung: F_CPU an die eigenen Gegebenheiten anpassen!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
wl_module_init();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
kennen wir schon von den Sender Einstellungen. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
wl_module_config&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
Konfiguriert das nRF Modul mit den wesentlichen Registerinhalten und stellt das Modul auf Empfang. Es wurde hier absichtlich sehr kurz gehalten und nur die wesentlichsten Einstellungen getroffen. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void wl_module_config() &lt;br /&gt;
// Sets the important registers in the wl-module and powers the module&lt;br /&gt;
// in receiving mode&lt;br /&gt;
{&lt;br /&gt;
    // Set RF channel&lt;br /&gt;
    wl_module_config_register(RF_CH,wl_module_CH);&lt;br /&gt;
	// Set data speed &amp;amp; Output Power configured in wl_module.h&lt;br /&gt;
	wl_module_config_register(RF_SETUP,wl_module_RF_SETUP);&lt;br /&gt;
	// Set length of incoming payload &lt;br /&gt;
    wl_module_config_register(RX_PW_P0, wl_module_PAYLOAD);&lt;br /&gt;
	&lt;br /&gt;
    // Start receiver &lt;br /&gt;
    PTX = 0;        // Start in receiving mode&lt;br /&gt;
    RX_POWERUP;     // Power up in receiving mode&lt;br /&gt;
    wl_module_CE_hi;     // Listening for pakets&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wie man sieht wurde hier nur die Payload-Größe für Pipe0 eingestellt und keine weiteren Empfangsadressen gesetzt. Das funktioniert weil beim Sender zwar Adressen konfiguriert wurden aber die Default-Adressen verwendet wurden. Man könnte sich für dieses Beispiel die Definition der Adressen beim Sender sparen und auch dort eine sehr verkürzte Konfiguration verwenden. Als Empfangskanal und -Geschwindigkeit müssen natürlich die gleichen Werte verwendet werden wie beim Sender. Auch die Payload-Größe muß im Empfänger zu  der Anzahl an Bytes passen die der Sender schickt. &lt;br /&gt;
&lt;br /&gt;
In dieser Zeile while (!wl_module_data_ready()); prüft das Programm ob im Empfangsmodul Daten angekommen sind die ausgelesen werden können und bleibt solange in dieser while-Schleife bis RX_DR gesetzt wurde. &lt;br /&gt;
&lt;br /&gt;
Diese Funktion macht nichts weiter als das STATUS Register auszulesen und den Wert von RX_DR zurück zu geben: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
extern uint8_t wl_module_data_ready() &lt;br /&gt;
// Checks if data is available for reading&lt;br /&gt;
{&lt;br /&gt;
    if (PTX) return 0;&lt;br /&gt;
    uint8_t status;&lt;br /&gt;
    // Read wl_module status &lt;br /&gt;
    wl_module_CSN_lo;                                // Pull down chip select&lt;br /&gt;
    status = spi_fast_shift(NOP);               // Read status register&lt;br /&gt;
    wl_module_CSN_hi;                                // Pull up chip select&lt;br /&gt;
    return status &amp;amp; (1&amp;lt;&amp;lt;RX_DR);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sobald RX_DR 1 ist und damit anzeigt, daß Daten angekommen sind wird die while Schleife verlassen und &amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;nRF_status = wl_module_get_data(payload);&amp;lt;/syntaxhighlight&amp;gt; ausgeführt. &lt;br /&gt;
&lt;br /&gt;
Diese Funktion liest den Inhalt des RX-FIFO Speichers aus und gibt den Inhalt des STATUS Registers zurück. Anschließend wird noch das RX_DR Bit gelöscht um den nächsten Datenempfang detektieren zu können: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
extern uint8_t wl_module_get_data(uint8_t * data) &lt;br /&gt;
// Reads wl_module_PAYLOAD bytes into data array&lt;br /&gt;
{&lt;br /&gt;
	uint8_t status;&lt;br /&gt;
    wl_module_CSN_lo;                               // Pull down chip select&lt;br /&gt;
    status = spi_fast_shift( R_RX_PAYLOAD );            // Send cmd to read rx payload&lt;br /&gt;
    spi_transfer_sync(data,data,wl_module_PAYLOAD); // Read payload&lt;br /&gt;
    wl_module_CSN_hi;                               // Pull up chip select&lt;br /&gt;
    wl_module_config_register(STATUS,(1&amp;lt;&amp;lt;RX_DR));   // Reset status register&lt;br /&gt;
	return status;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Rest der main-Routine kümmert sich dann nur noch um die Ausgabe der Daten.&lt;br /&gt;
&lt;br /&gt;
Zum Schluß noch eine kleine Aufgabe: &lt;br /&gt;
Warum wird beim Empfänger keine Interruptfunktion ISR(INT0_vect) verwendet? Und löst  RX_DR überhaupt einen Interrupt aus?&lt;br /&gt;
&lt;br /&gt;
== Beispieldateien ==&lt;br /&gt;
&lt;br /&gt;
Hier finden sich die Dateien die in diesem Beispiel verwendet wurden: &lt;br /&gt;
&lt;br /&gt;
[[Datei: nrf24L01_Tutorial.zip]]&lt;br /&gt;
&lt;br /&gt;
In wl_module.c finden sich alle Routinen die im Tutorial verwendet wurden und auch noch viel, viel mehr. Es sind alle Routinen vorhanden um sehr schnell einen Multi-Ceiver mit 6 Data-Pipes aufzubauen oder verschiedene interessante Daten auszulesen. Das Prinzip sollte nach diesem Tutorial, so hoffe ich, klar sein um diese Routinen zu durchschauen und selbst anzuwenden oder anzupassen.&lt;br /&gt;
&lt;br /&gt;
== Zusammenfassung ==&lt;br /&gt;
&lt;br /&gt;
Noch ein paar wesentliche Punkte zu den Funkmodulen und ersten Schritten hier im Tutorial: &lt;br /&gt;
&lt;br /&gt;
1. Achtung mit der Spannung, die Module vertragen wirklich keine höhere Spannung als im Datenblatt angegeben wie ich leider feststellen durfte. &lt;br /&gt;
&lt;br /&gt;
2. Wie schon angesprochen eignet sich die Polling-Variante im Empfänger-Beispiel nur bedingt für die Umsetzung in eigenen Projekten da sie den µC bis zum nächsten Dateneingang lahm legt. Und sollten keine Daten kommen, dann ist der µC in dieser Zeile ad infinitum gefangen. &lt;br /&gt;
&lt;br /&gt;
3. Es kann sein, wenn die Daten sehr schnell kommen, daß man ein RX_DR versäumt. Der FIFO hat ja Platz für 3xPayload. Man sollte also durchaus auch abfragen ob noch weitere Daten im FIFO vorhanden sind. Insbesondere wenn mit Multi-Ceivern gearbeitet wird. &lt;br /&gt;
&lt;br /&gt;
4. Für kurze Distanzen funktioniert die Datenübertragung mit 2Mbps sehr gut. Wenn längere Distanzen überwunden werden sollen, dann sollte man auf 250kbps zurückgehen, das erhöht die Empfindlichkeit des Empfängers. Der Sender sollte mit maximaler Leistung senden. Außerdem sollte der Payload nur so groß sein wie auch wirklich benötigt. Je weniger Bytes übertragen werden desto größer die Chance auf erfolgreiche Datenübertragung. Bei Bedarf gibt es auch Module die den Anschluß einer externen Antenne ermöglichen. &lt;br /&gt;
&lt;br /&gt;
5. Man sollte die Möglichkeiten nutzen die Enhanced Shockburst bietet. Das TX_DS Bit wird dann nur gesetzt wenn auch wirklich ein ACK vom Empfänger eingetroffen ist. (Im Tutorial wird übrigens Enhanced Shockburst verwendet. Details dazu hätten aber das Tutorial gesprengt)&lt;br /&gt;
&lt;br /&gt;
6. Beim Multi-Ceiver Betrieb sollte für jeden Sender ein, sich von den anderen Sendern unterscheidendes, AUTO RETRANSMIT DELAY (ARD) eingestellt werden. Das erhöht die Chancen, daß sich die Sender nicht gegenseitig stören. &lt;br /&gt;
&lt;br /&gt;
7. Aufpassen beim AUTO RETRANSMIT DELAY wenn mit 250kpbs gesendet wird. Der Default-Wert von 250µS ist zu kurz um eine funktionierende Datenübertragung zu gewährleisten. Für Details siehe Datenblatt. &lt;br /&gt;
&lt;br /&gt;
Nachrichten an den Autor: [http://www.mikrocontroller.net/user/show/Puravida PuraVida]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Funk]]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=NRF24L01_Tutorial&amp;diff=82017</id>
		<title>NRF24L01 Tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=NRF24L01_Tutorial&amp;diff=82017"/>
		<updated>2014-03-11T20:16:53Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: /* Der SPI Befehlssatz */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
Das Tutorial soll den Einstieg, eine Funkstrecke mit dem &lt;br /&gt;
[http://www.nordicsemi.com/eng/Products/2.4GHz-RF/nRF24L01P nRF24L01+] aufzubauen, erleichtern.&lt;br /&gt;
&lt;br /&gt;
Beim nRF24L01+ handelt es sich um einen single Chip Transceiver von Nordic Semiconductor. Dieser Chip kann also sowohl als Sender (TX) als auch als Empfänger (RX) arbeiten und bietet eine Reihe von sehr praktischen Features wie Ultra Low Power (nur 900nA in Power Down Modus), 6 Data Pipes beim Betrieb als MultiCeiver, Enhanced Shockburst (dazu später mehr), Automatic Packet Handling, 5V tolerante Eingänge, SPI Schnittstelle und noch einiges mehr. &lt;br /&gt;
&lt;br /&gt;
Um mit dem nRF24L01+ eine Funkstrecke zu realisieren braucht man nicht mehr als einen µC sowie ein nRF24L01+ Funkmodul. Das ganze natürlich zwei mal. &lt;br /&gt;
In dem Tutorial wird der AVR Atmega8 verwendet sowie nRF24L01+ Module die sehr günstig über das Internet (Ebay derzeit unter 2€) in verschiedenen Ausführungen bezogen werden können. Für Testaufbauten reichen einfache Steckbretter um die Hardware aufzubauen. &lt;br /&gt;
Bei der Hand sollte unbedingt das Datenblatt des nRF24L01+ sein und natürlich das Datenblatt des jeweils verwendeten µC. Das Datenblatt des nRF24L01+ kann von Nordic Semiconductor runtergeladen werden: &lt;br /&gt;
&lt;br /&gt;
[http://www.nordicsemi.com/kor/nordic/download_resource/8765/2/8827113 nRF24L01 Datenblatt]&lt;br /&gt;
&lt;br /&gt;
Vieles in diesem Tutorial basiert auf der Vorarbeit von Stefan Engelke und Brennan Ball denen mein Dank dafür gilt.&lt;br /&gt;
&lt;br /&gt;
== Das nRF24L01+ Modul ==&lt;br /&gt;
Ein Funkmodul mit dem nRF24L01+ hat zumindest 8 Anschlüsse: &lt;br /&gt;
[[Datei:Foto_nrf24L01+Modul.jpg|miniatur|rechts|Handelsübliche nRF24L01+ Module]]&lt;br /&gt;
Vcc, GND, IRQ, CE, und die vier SPI bezogenen Anschlüsse CSN, SCK, MISO, und MOSI.&lt;br /&gt;
&lt;br /&gt;
Je nach Datenblatt des verwendeten Moduls ist die Spannung zu wählen, manche Module verfügen über eigene Spannungsregler, der nRF24L01+ selbst verträgt Spannungen von 1,9V bis 3,6V. Auf dem von mir verwendeten Modul befindet sich kein weiterer Spannungsregler somit muß man aufpassen den Chip nicht durch Überspannung zu ruinieren. Als Spannung habe ich 3,3V verwendet. &lt;br /&gt;
&lt;br /&gt;
Die Anschlüsse SCK, MISO, und MOSI werden mit den entsprechenden Pins des µC verbunden. Der CSN (chip select not) Pin ist active low und normalerweise auf high-Level gehalten. Wenn CSN low geschaltet wird beginnt der nRF24L01+ am SPI Port zu horchen oder anders gesagt, jedes Kommando an den Chip wird mit einem high to low schalten von CSN eingeleitet. Im Falle des Atmega8 werden SCK mit SCK, MISO mit MISO und MOSI mit MOSI verbunden. Für den CSN wurde Pin PB1 gewählt. &lt;br /&gt;
[[Datei:Stromlaufplan.png|miniatur|rechts|Stromlaufplan für den Anschluß an einen ATmega8]]&lt;br /&gt;
Was uns noch bleibt ist CE und IRQ. CE wird im RX und TX Modus verwendet für die Datenübertragung. In dem Beispiel an Pin PB0 angeschlossen. IRQ ist der Interrupt-Pin des Funkmoduls und ist active-low. Es gibt drei interne Interrupts im nRF24L01+ die den IRQ Pin low schalten wobei man sämtliche Interrupts ausmaskieren kann wenn man möchte. Am Atmega8 wurde IRQ mit Pin PD2 (INT0) verbunden um auf die externen Interrupts reagieren zu können.&lt;br /&gt;
&lt;br /&gt;
== Die SPI-Routine ==&lt;br /&gt;
Als SPI-Routine habe ich die Routine von Stefan Engelke unverändert übernommen die er dankenswerter Weise zur allgemeinen Verwendung zur Verfügung gestellt hat. [http://www.tinkerer.eu/AVRLib/SPI siehe Tinkerer.eu]&lt;br /&gt;
&lt;br /&gt;
spi.h&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#ifndef _SPI_H_&lt;br /&gt;
#define _SPI_H_&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
extern void spi_init();&lt;br /&gt;
extern void spi_transfer_sync (uint8_t * dataout, uint8_t * datain, uint8_t len);&lt;br /&gt;
extern void spi_transmit_sync (uint8_t * dataout, uint8_t len);&lt;br /&gt;
extern uint8_t spi_fast_shift (uint8_t data);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
spi.c&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;spi.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define PORT_SPI    PORTB&lt;br /&gt;
#define DDR_SPI     DDRB&lt;br /&gt;
#define DD_MISO     DDB4&lt;br /&gt;
#define DD_MOSI     DDB3&lt;br /&gt;
#define DD_SS       DDB2&lt;br /&gt;
#define DD_SCK      DDB5&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void spi_init()&lt;br /&gt;
// Initialize pins for spi communication&lt;br /&gt;
{&lt;br /&gt;
    DDR_SPI &amp;amp;= ~((1&amp;lt;&amp;lt;DD_MOSI)|(1&amp;lt;&amp;lt;DD_MISO)|(1&amp;lt;&amp;lt;DD_SS)|(1&amp;lt;&amp;lt;DD_SCK));&lt;br /&gt;
    // Define the following pins as output&lt;br /&gt;
    DDR_SPI |= ((1&amp;lt;&amp;lt;DD_MOSI)|(1&amp;lt;&amp;lt;DD_SS)|(1&amp;lt;&amp;lt;DD_SCK));&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    SPCR = ((1&amp;lt;&amp;lt;SPE)|               // SPI Enable&lt;br /&gt;
            (0&amp;lt;&amp;lt;SPIE)|              // SPI Interrupt Enable&lt;br /&gt;
            (0&amp;lt;&amp;lt;DORD)|              // Data Order (0:MSB first / 1:LSB first)&lt;br /&gt;
            (1&amp;lt;&amp;lt;MSTR)|              // Master/Slave select   &lt;br /&gt;
            (0&amp;lt;&amp;lt;SPR1)|(1&amp;lt;&amp;lt;SPR0)|    // SPI Clock Rate&lt;br /&gt;
            (0&amp;lt;&amp;lt;CPOL)|              // Clock Polarity (0:SCK low / 1:SCK hi when idle)&lt;br /&gt;
            (0&amp;lt;&amp;lt;CPHA));             // Clock Phase (0:leading / 1:trailing edge sampling)&lt;br /&gt;
&lt;br /&gt;
    SPSR = (1&amp;lt;&amp;lt;SPI2X);              // Double Clock Rate&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void spi_transfer_sync (uint8_t * dataout, uint8_t * datain, uint8_t len)&lt;br /&gt;
// Shift full array through target device&lt;br /&gt;
{&lt;br /&gt;
       uint8_t i;      &lt;br /&gt;
       for (i = 0; i &amp;lt; len; i++) {&lt;br /&gt;
             SPDR = dataout[i];&lt;br /&gt;
             while((SPSR &amp;amp; (1&amp;lt;&amp;lt;SPIF))==0);&lt;br /&gt;
             datain[i] = SPDR;&lt;br /&gt;
       }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void spi_transmit_sync (uint8_t * dataout, uint8_t len)&lt;br /&gt;
// Shift full array to target device without receiving any byte&lt;br /&gt;
{&lt;br /&gt;
       uint8_t i;      &lt;br /&gt;
       for (i = 0; i &amp;lt; len; i++) {&lt;br /&gt;
             SPDR = dataout[i];&lt;br /&gt;
             while((SPSR &amp;amp; (1&amp;lt;&amp;lt;SPIF))==0);&lt;br /&gt;
       }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
uint8_t spi_fast_shift (uint8_t data)&lt;br /&gt;
// Clocks only one byte to target device and returns the received one&lt;br /&gt;
{&lt;br /&gt;
    SPDR = data;&lt;br /&gt;
    while((SPSR &amp;amp; (1&amp;lt;&amp;lt;SPIF))==0);&lt;br /&gt;
    return SPDR;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Der SPI Befehlssatz ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Command name !! Command word (binary) !! # Data bytes !! Operation&lt;br /&gt;
|-&lt;br /&gt;
| R_REGISTER || 000A AAAA || 1 to 5 &amp;lt;br /&amp;gt; LSByte first || Read command and STATUS registers. AAAAA = 5 bit Register Map Address&lt;br /&gt;
|-&lt;br /&gt;
| W_REGISTER || 001A AAAA || 1 to 5 &amp;lt;br /&amp;gt; LSByte first || Write command and status registers. AAAAA = 5 bit Register Map Address &amp;lt;br /&amp;gt; Executable in power down or standby modes only.&lt;br /&gt;
|-&lt;br /&gt;
| R_RX_PAYLOAD || 0110 0001 || 1 to 32 &amp;lt;br /&amp;gt; LSByte first || Read RX-payload: 1 – 32 bytes. A read operation always starts at byte 0. Payload is deleted from FIFO after it is read. Used in RX mode.&lt;br /&gt;
|-&lt;br /&gt;
| W_TX_PAYLOAD || 1010 0000 || 1 to 32 &amp;lt;br /&amp;gt; LSByte first || Write TX-payload: 1 – 32 bytes. A write operation always starts at byte 0 used in TX payload.&lt;br /&gt;
|-&lt;br /&gt;
| FLUSH_TX || 1110 0001 || 0 || Flush TX FIFO, used in TX mode&lt;br /&gt;
|-&lt;br /&gt;
| FLUSH_RX || 1110 0010 || 0 || Flush RX FIFO, used in RX mode &amp;lt;br /&amp;gt; Should not be executed during transmission of acknowledge, that is, acknowledge package will not be completed.&lt;br /&gt;
|-&lt;br /&gt;
| REUSE_TX_PL || 1110 0011 || 0 || Used for a PTX device&lt;br /&gt;
Reuse last transmitted payload. &amp;lt;br /&amp;gt; TX payload reuse is active until W_TX_PAYLOAD or FLUSH TX is executed. TX payload reuse must not be activated or deactivated during package transmission.&lt;br /&gt;
|-&lt;br /&gt;
| R_RX_PL_WID* || 0110 0000 || 1 || Read RX payload width for the top R_RX_PAYLOAD in the RX FIFO. &amp;lt;br /&amp;gt; &amp;lt;b&amp;gt;Note:&amp;lt;/b&amp;gt; Flush RX FIFO if the read value is larger than 32 bytes.&lt;br /&gt;
|-&lt;br /&gt;
| W_ACK_PAYLOAD* || 1010 1PPP || 1 to 32 &amp;lt;br /&amp;gt; LSByte first || Used in RX mode. &amp;lt;br /&amp;gt; Write Payload to be transmitted together with ACK packet on PIPE PPP. (PPP valid in the range from 000 to 101). Maximum three ACK packet payloads can be pending. Payloads with same PPP are handled using first in - first out principle. Write payload: 1– 32 bytes. A write operation always starts at byte 0.&lt;br /&gt;
|-&lt;br /&gt;
| W_TX_PAYLOAD_NOACK* || 1011 0000 || 1 to 32 &amp;lt;br /&amp;gt;LSByte first || Used in TX mode. Disables AUTOACK on this specific packet.&lt;br /&gt;
|-&lt;br /&gt;
| NOP || 1111 1111 || 0 || No Operation. Might be used to read the STATUS register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;*&amp;lt;/b&amp;gt;=The bits in the FEATURE register shown in Table 28. on page 63 have to be set.&lt;br /&gt;
&lt;br /&gt;
Zu finden natürlich auch im Datasheet auf Seite 51. &lt;br /&gt;
&lt;br /&gt;
Es gibt ein paar Dinge die zu beachten sind. Bevor die Kommunikation mit dem Chip begonnen wird muß der CSN Pin high sein. Zum Start der Kommunikation wird der CSN Pin auf Low geschaltet und muß auch Low bleiben während der gesamten Dauer der Kommunikation. &lt;br /&gt;
&lt;br /&gt;
Dann wird der Befehl gesendet. Wenn man Daten vom nRF24L01+ empfangen möchte muß für jedes Byte an Daten auch ein Byte gesendet werden. Wenn man nur seine eigenen Daten an den Chip senden möchte kümmert man sich nicht weiter darum was der Chip zurücksendet. Auf jeden Fall wird parallel zu den Daten die man schickt der STATUS des Chips zurückgegeben. Ist die Unterhaltung (mit dem nRF24L01+ - es geht noch nicht um die Funkstrecke) abgeschlossen, wird CSN wieder auf High geschaltet. &lt;br /&gt;
&lt;br /&gt;
Als Beispiel: Wir wollen den R_REGISTER Befehl senden um den Inhalt des Registers TX_ADDR zu lesen. Das TX_ADDR Register enthält maximal 5 Bytes an Daten/Information. Als erstes CSN auf Low. Dann &amp;quot;0001 0000&amp;quot; an den Chip senden. Das weist den nRF24L01+ an das Register TX_ADDR auszugeben. Dann werden fünf Dummy-Bytes gesendet und für jedes Dummy-Byte erhält man ein Byte aus dem TX_ADDR Register zurück. (Der Inhalt der Dummy-Bytes ist ganz egal) Danach CSN wieder auf High. Insgesamt erhält man vom Chip sechs Bytes: Egal welches Command Byte man sendet antwortet der Chip mit dem STATUS-Register.&lt;br /&gt;
&lt;br /&gt;
Mit dem R_REGISTER können also alle Registerinhalte gelesen werden die zwischen 1 Byte und 5 Byte groß sind. &lt;br /&gt;
&lt;br /&gt;
Mit dem W_REGISTER können wir beliebig unsere Werte in die Register schreiben. Das Prinzip ist das gleiche, es wird der Befehl 001AAAAA gesendet wobei AAAAA für die Adresse des Registers steht. Danach werden - je nach Register - bis zu fünf Bytes an Daten gesendet die in das Register geschrieben werden sollen. &lt;br /&gt;
&lt;br /&gt;
R_RX_PAYLOAD ist einer der beiden Befehle die mit dem FIFO zu tun haben. R_RX_PAYLOAD liest den Inhalt des FIFO sollten Daten empfangen werden. Der Empfang von Daten wird mit dem RX_DR Interrupt angezeigt. Bei diesem Befehl ist das Vorgehen ein wenig anders. Wenn man Daten per Funkstrecke empfängt ist CE high. Sobald man ein Paket empfangen hat muß man CE low schalten um den Empfang auszuschalten und danach kann R_RX_PAYLOAD ausgeführt werden. Gefolgt von so vielen Dummy-Bytes wie Payload definiert wurde. Gelesene Pakete werden automatisch aus dem FIFO gelöscht. Sollten weitere Pakete im FIFO warten sollten die auch gleich gelesen werden. Sobald der FIFO leer ist wird der RX_DR Interrupt gelöscht und CE wieder auf High geschaltet. Der FIFO kann maximal 3 Pakete (PAYLOADS) halten. Ein Paket ist maximal 32 Bytes groß. &lt;br /&gt;
&lt;br /&gt;
Der zweite dieser Befehle ist W_TX_PAYLOAD. Er wird verwendet wenn man sich im TX-Modus befindet und Daten senden möchte. Im TX-Modus ist CE low. Nachdem man den Befehl gesendet hat werden so viele Bytes ins FIFO geladen wie man für den Empfänger auch defniniert hat. D. h. Payload Größe muß beim Sender und Empfänger gleich groß sein solange man das FEATURE-Register nicht verwendet. Nachdem die Daten in den FIFO geladen wurden muß man den CE Pin toggeln (mind. 10µs high) damit die Daten gesendet werden. Man kann auch zuerst drei Pakete in den FIFO laden und dann erst wegschicken. &lt;br /&gt;
&lt;br /&gt;
FLUSH_TX und FLUSH_RX löschen die Daten im TX_FIFO bzw. RX_FIFO. &lt;br /&gt;
&lt;br /&gt;
NOP kann sehr gut dafür verwendet werden das STATUS Register zu lesen da es - wie der Name schon sagt - sonst nichts tut.&lt;br /&gt;
&lt;br /&gt;
== Die nRF24L01+ Register ==&lt;br /&gt;
&lt;br /&gt;
Hier ist es nötig das Datenblatt ab Seite 57 zur Hand zu nehmen da die Menge an Registern das Tutorial sprengen würde, würden alle hier besprochen. &lt;br /&gt;
&lt;br /&gt;
Mit Hilfe der Register wird das Modul per SPI konfiguriert und auch kontrolliert. Die meisten Register sind 1Byte groß, in vielen Registern werden aber nicht alle Bytes verwendet. Eine Ausnahme bilden die Register RX_ADDR_P0, RX_ADDR_P1 sowie TX_ADDR die jeweils bis zu 5 Byte groß sind. (Abhängig von der Konfiguration). Die drei 32Byte großen Register werden mit eigenen SPI Befehlen gesteuert. Sie dienen dazu die Datenpakete in den nRF24L01+ zu schreiben bzw. empfangene auszulesen. &lt;br /&gt;
&lt;br /&gt;
Innerhalb der Register belegen die Informationen eine unterschiedliche Anzahl an Bits. Als Beispiel das STATUS Register. Bit 1 bis 3 geben hier zum Beispiel Auskunft über die verwendete Pipe. Während alle anderen Informationen nur 1 Bit groß sind in dem Register. Es muß also immer entsprechend maskiert werden um die gewünschten Infos zu lesen oder auch zu schreiben.&lt;br /&gt;
&lt;br /&gt;
== Die ersten Schritte ==&lt;br /&gt;
&lt;br /&gt;
So, nach dem kurzen theoretischen Überblick ist es an der Zeit die ersten Schritte zu wagen. Sollte es noch nicht der Fall sein sollten spätestens jetzt die beiden nRF24L01+ Module mit dem µC verkabelt sein. Der ATmega8 sollte für dieses Beispiel mit mind. 8Mhz laufen, ob externer Quarz oder interner Takt ist dabei egal. Nochmals zur Erinnerung: Das nRF-Modul darf mit maximal 3,6V betrieben werden, die Eingänge verkraften aber 5V Signale solange die Versorgungsspannung zwischen 2,7V und 3,3V liegt. Werft sicherheitshalber einen Blick ins Datenblatt betreffend dieser Dinge. &lt;br /&gt;
&lt;br /&gt;
Worüber man sich auch Gedanken machen muß ist, wie man die Funktion bzw. die Daten die man hin und her schickt, visualisiert. Ohne Visualisierung kann es natürlich auch funktionieren doch für das Tutorial wollen wir sicher sehen ob, und wenn ja, welche Daten hin und hergeschickt werden oder auch mal einen Registerinhalt anzeigen. In welcher Form das passiert bleibt jedem selbst überlassen. Man kann die Daten auf einem LCD ausgeben oder auch per UART an den PC liefern lassen. Hier sollte jeder das wählen womit er am Besten zurecht kommt. Theoretisch könnte man auch das Auslangen mit LEDs finden und sich die Registerinhalte oder Datenpakete mittels 8 LEDs anzeigen lassen. Allerdings wäre das nicht sehr komfortabel. &lt;br /&gt;
&lt;br /&gt;
=== Konfigurieren des nRF24L01+ ===&lt;br /&gt;
&lt;br /&gt;
Als erstes müssen wir das Modul mal initialisieren bzw. die verwendeten Anschlüsse des µC einrichten. Am besten packen wir das ganze in eine Routine die ziemlich zeitig beim Start des µC aufgerufen wird. Weiter unten findet sich dann die Header-Datei die hier verwendet wird.&lt;br /&gt;
&lt;br /&gt;
Als erstes setzen wir die beiden verwendeten Pins als Ausgänge und schalten sie in den default-Status.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void wl_module_init() &lt;br /&gt;
{&lt;br /&gt;
    DDRB |= ((1&amp;lt;&amp;lt;CSN)|(1&amp;lt;&amp;lt;CE));&lt;br /&gt;
    wl_module_CE_lo;&lt;br /&gt;
    wl_module_CSN_hi;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dann werden die beiden (eigentlich reicht INT0) externen Interrupteingänge des ATmega8 auf fallende Flanke gestellt und der Interrupt für INT0 aktiviert. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    MCUCR = ((1&amp;lt;&amp;lt;ISC11)|(0&amp;lt;&amp;lt;ISC10)|(1&amp;lt;&amp;lt;ISC01)|(0&amp;lt;&amp;lt;ISC00));&lt;br /&gt;
    GICR  = ((0&amp;lt;&amp;lt;INT1)|(1&amp;lt;&amp;lt;INT0));					&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
und zum Schluß noch SPI (siehe oben unter SPI) initialisiert:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;	    &lt;br /&gt;
    spi_init();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anbei noch die Header-Datei für das Modul: &lt;br /&gt;
[[Datei:wl_module.h]] (aus irgendeinem Grund forciert das Wiki hier große Anfangsbuchstaben, die Datei sollte als &amp;quot;wl_module.h&amp;quot; abgespeichert werden.)&lt;br /&gt;
&lt;br /&gt;
In dieser Header-Datei werden die wesentlichen Zuordnungen und Einstellungen getroffen wie Pin-Definitionen, Größe des Payloads, Interruptmaskierung für das Modul, CRC-Größe, etc. Außderdem die public functions deklariert. Im Moment noch nicht schrecken, es sind eine ganze Reihe von Funktionen die in einer wl_module.c Datei zusammengefaßt sind. Aufmerksame Leser werden feststellen, daß auch obige Funktion, die wl_module_init() dort erstellt wurde. &lt;br /&gt;
&lt;br /&gt;
In dem Projekt wird noch eine weitere Header-Datei für das Modul verwendet in dem die Mnemonics des Moduls abgebildet sind. Doch dazu gleich. &lt;br /&gt;
&lt;br /&gt;
=== Grundsätzliche Konfiguration ===&lt;br /&gt;
&lt;br /&gt;
Konfigurieren läßt sich eine ganze Menge beim nRF24L01+. Aber wir haben das Glück, daß es auch funktioniert wenn man wenig konfiguriert und die Standardwerte eingestellt läßt. &lt;br /&gt;
&lt;br /&gt;
Für unsere ersten Tests stellen wir nur das notwendigste ein. Um uns die Arbeit mit den vielen Registern zu erleichtern ist es jetzt Zeit die schon angesprochene Header-Datei vorzustellen und in weiterer Folge einzubinden. &lt;br /&gt;
&lt;br /&gt;
[[Datei:NRF24L01.h]]&lt;br /&gt;
&lt;br /&gt;
In dieser Header-Datei finden wir alle Mnemonics um auf die entsprechenden Befehle, Register und Registerinhalte zuzugreifen. Ja, es ist eine ziemlich lange Liste aber davon nicht schrecken lassen. &lt;br /&gt;
&lt;br /&gt;
Gut, dann setzen wir mal die ersten Werte im nRF24L01+. Als erstes wollen wir den Funkkanal einstellen. Dazu haben wir im wl_module.h schon wl_module_CH definiert. Ein Blick ins Datenblatt verrät uns, daß wir das Kommando W_REGISTER brauchen und der Kanal im Register RF_CH eingestellt wird. Die grundsätzliche Funktionsweise der Kommandos wurde schon weiter oben erklärt doch wie setzen wir das jetzt um? &lt;br /&gt;
&lt;br /&gt;
Wir bedienen uns dazu einer Funktion die genau ein Byte in ein gewähltes Register schreibt. reg ist das gewählte Register und value der Wert der geschrieben werden soll. Mit dieser Funktion können wir schon fast alle Register des Moduls beschreiben.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void wl_module_config_register(uint8_t reg, uint8_t value)&lt;br /&gt;
// Clocks only one byte into the given wl-module register&lt;br /&gt;
{&lt;br /&gt;
    wl_module_CSN_lo;&lt;br /&gt;
    spi_fast_shift(W_REGISTER | (REGISTER_MASK &amp;amp; reg));&lt;br /&gt;
    spi_fast_shift(value);&lt;br /&gt;
    wl_module_CSN_hi;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Um den Kanal zu setzen wird &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Set RF channel&lt;br /&gt;
    wl_module_config_register(RF_CH,wl_module_CH);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
aufgerufen.&lt;br /&gt;
&lt;br /&gt;
Fein, damit ist es uns ein leichtes den Payload zu konfigurieren. Der Payload sind die Anzahl an Bytes die auf einmal übertragen werden. Der Sender muß (solange nicht die dynamic payload length aktiviert ist) genau so viele Bytes senden wie am Empfänger als Payload-Länge eingestellt ist. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Set length of incoming payload &lt;br /&gt;
wl_module_config_register(RX_PW_P0, wl_module_PAYLOAD);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für die ersten Tests werden wir uns um keine Pipes kümmern daher reicht es erstmal wenn wir nur den Payload für die Pipe0 festlegen.&lt;br /&gt;
&lt;br /&gt;
Ich mag das Augenmerk auf folgende Zeile in der wl_config.h legen: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define wl_module_CONFIG		( (1&amp;lt;&amp;lt;MASK_RX_DR) | (1&amp;lt;&amp;lt;EN_CRC) | (0&amp;lt;&amp;lt;CRCO) )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In der Zeile wird einiges für das CONFIG Register eingestellt. Im CONFIG Register können etwa die drei Interrupts maskiert werden, es wird eingestellt ob CRC verwendet wird und ob CRC aus einem oder zwei Bytes besteht. Und dann gibt es noch zwei ganz wesentliche Dinge darin. Einerseits PWR_UP und dann auch noch PRIM_RX. PRIM_RX legt fest ob sich das Modul im TX oder im RX Modus befindet. &lt;br /&gt;
&lt;br /&gt;
Über&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Defines for setting the wl_module registers for transmitting or receiving mode&lt;br /&gt;
#define TX_POWERUP wl_module_config_register(CONFIG, wl_module_CONFIG | ( (1&amp;lt;&amp;lt;PWR_UP) | (0&amp;lt;&amp;lt;PRIM_RX) ) )&lt;br /&gt;
#define RX_POWERUP wl_module_config_register(CONFIG, wl_module_CONFIG | ( (1&amp;lt;&amp;lt;PWR_UP) | (1&amp;lt;&amp;lt;PRIM_RX) ) )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
können wir das Modul entweder im TX oder RX Modus aktivieren. &lt;br /&gt;
&lt;br /&gt;
Fürs erste können wir die restlichen Register so lassen wie eingestellt.&lt;br /&gt;
&lt;br /&gt;
Wie schaut es jetzt aus wenn wir ein Register beschreiben wollen das mehr als ein Byte an Daten enthält? Als Paradebeispiel ist dafür natürlich das schreiben des Payloads in den TX-FIFO geeignet da wir hier bis zu 32 Bytes schreiben. &lt;br /&gt;
&lt;br /&gt;
Aber auch andere Register brauchen mehr als 1 Byte, so zum Beispiel die Adressregister die bis zu 5 Bytes breit sind. &lt;br /&gt;
&lt;br /&gt;
Auch dafür können wir uns einer kleinen aber feinen Routine bedienen: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void wl_module_write_register(uint8_t reg, uint8_t * value, uint8_t len) &lt;br /&gt;
// Writes an array of bytes into inte the wl-module registers.&lt;br /&gt;
{&lt;br /&gt;
    wl_module_CSN_lo;&lt;br /&gt;
    spi_fast_shift(W_REGISTER | (REGISTER_MASK &amp;amp; reg));&lt;br /&gt;
    spi_transmit_sync(value,len);&lt;br /&gt;
    wl_module_CSN_hi;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An die Routine übergeben wird das Register das beschrieben werden soll, ein Zeiger auf das Array mit den Daten und die Größe dieses Arrays.&lt;br /&gt;
&lt;br /&gt;
=== Register wieder auslesen ===&lt;br /&gt;
&lt;br /&gt;
Eine Frage die sich sehr bald stellen wird: Wie lese ich Register wieder aus? Sei es um die Einstellungen zu  kontrollieren oder auf Bits die darin automatisch gesetzt werden zu reagieren. &lt;br /&gt;
&lt;br /&gt;
Wie wir wissen reagiert der nRF24L01+ auf jeden Befehl den wir schicken automatisch und parallel auf unseren Befehl mit der Antwort des STATUS Registers. Das STATUS Register ist ein wichtiges weil es einiges an wesentlichen Informationen enthält auf die wir reagieren müssen. So werden alle drei Interrupts in dem Register durch setzen eines entsprechenden Bits abgebildet. Dieses Bit muß durch schreiben einer 1 auch wieder gelöscht werden. Es läßt sich außerdem die Pipe auslesen die die Daten gesendet hat sowie, auch ganz wichtig, das TX_FULL Flag auslesen. Dieses Flag wird gesetzt wenn der Sende-Fifo voll ist. &lt;br /&gt;
&lt;br /&gt;
Um den Status auszulesen und sonst nix weiter zu machen können wir eine kleine Funktion einsetzen: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
//return the value of the status register&lt;br /&gt;
extern uint8_t wl_module_get_status()&lt;br /&gt;
{&lt;br /&gt;
	return wl_module_get_one_byte(NOP);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Aber nicht vergessen, egal was wir an den nRF24L01+ schicken, er antwortet jedes mal mit dem Inhalt des Status-Registers. Das können wir uns später zu  nutze machen.&lt;br /&gt;
&lt;br /&gt;
In dem Beispiel wird die Funktion wl_module_get_one_byte() verwendet: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
extern uint8_t wl_module_get_one_byte(uint8_t command)&lt;br /&gt;
{&lt;br /&gt;
uint8_t status;&lt;br /&gt;
&lt;br /&gt;
wl_module_CSN_lo;&lt;br /&gt;
status = spi_fast_shift(command);&lt;br /&gt;
wl_module_CSN_hi;&lt;br /&gt;
&lt;br /&gt;
return status;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Genau betrachtet liefert die Funktion wl_module_get_one_byte() schon den Inhalt des Status Registers. Nachdem die Funktion aber die Grundlage für den Zugriff auf einzelne Teile des Status-Registers ist die in weiteren Funktionen verwendet wird wurde für die bessere Übersichtlichkeit eine eigene Status-Abfrage Funktion implementiert.&lt;br /&gt;
&lt;br /&gt;
Wenn andere Inhalte als der Status abgefragt werden sollen etwa der Inhalt des FIFO wo ja unsere empfangenen Daten liegen bedienen wir uns einer weiteren Funktion. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void wl_module_read_register(uint8_t reg, uint8_t * value, uint8_t len)&lt;br /&gt;
// Reads an array of bytes from the given start position in the wl-module registers.&lt;br /&gt;
{&lt;br /&gt;
    wl_module_CSN_lo;&lt;br /&gt;
    spi_fast_shift(R_REGISTER | (REGISTER_MASK &amp;amp; reg));&lt;br /&gt;
    spi_transfer_sync(value,value,len);&lt;br /&gt;
    wl_module_CSN_hi;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Funktion leistet uns für einige weitere Funktionen die darauf zugreifen gute Dienste. Wollen wir als Beispiel den gewählten Funkkanal auslesen so können wir das mit dieser Funktion: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
//returns the current RF channel in RF_CH register&lt;br /&gt;
extern uint8_t wl_module_get_rf_ch()&lt;br /&gt;
{&lt;br /&gt;
	uint8_t data;&lt;br /&gt;
	&lt;br /&gt;
	wl_module_read_register(RF_CH, &amp;amp;data, 1);&lt;br /&gt;
	&lt;br /&gt;
	return data;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie man sieht greift die Funktion wl_module_get_rf_ch() auf die Funktion wl_module_read_register zu, übergibt die notwendigen Parameter und liefert uns dann das Byte zurück das in RF_CH gespeichert ist.&lt;br /&gt;
&lt;br /&gt;
=== Erster praktischer Test ===&lt;br /&gt;
&lt;br /&gt;
So, genug der Grundlagen, schauen wir uns einen ersten praktischen Test mit den Modulen an.&lt;br /&gt;
&lt;br /&gt;
Der Aufbau ist verdrahtet und mit den richtigen Spannungen versorgt, der µC läuft mit mind. 8 MHz (niedrigere Frequenzen gehen auch aber wurden von mir nicht getestet, achtet auf den passenden SPI-Vorteiler), als Optimierungsmethode ist -Os eingestellt und dem Compiler wurde auch die richtige Frequenz mitgeteilt. &lt;br /&gt;
&lt;br /&gt;
Als erstes werden wir beim Sender einen Zähler hochzählen und die Zahlen an den Empfänger übermitteln. Dadurch sehen wir, ob die Funkstrecke funktioniert. Welche Bytes tatsächlich übertragen werden ist schlußendlich egal. &lt;br /&gt;
&lt;br /&gt;
==== Der Sender ====&lt;br /&gt;
&lt;br /&gt;
Hier die kurze Main-Routine für den Sender, verwendete Funktionen werden im Anschluß besprochen. Nach belieben könnt ihr an freie Pins noch LED anschließen um bestimmte Ereignisse optisch zu überwachen. Im Code selbst wird darauf verzichtet. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * nRF24L01_Tutorial_Sender.c&lt;br /&gt;
 *&lt;br /&gt;
 * Created: 06.01.2012 20:15:04&lt;br /&gt;
 *  Author: Ernst Buchmann&lt;br /&gt;
 */ &lt;br /&gt;
&lt;br /&gt;
#ifndef F_CPU				//Define F_CPU if not done &lt;br /&gt;
#define F_CPU 8000000UL&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
#include &amp;lt;util/delay.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;spi.h&amp;quot;&lt;br /&gt;
#include &amp;quot;wl_module.h&amp;quot;&lt;br /&gt;
#include &amp;quot;nRF24L01.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
volatile uint8_t timercounter;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
	uint8_t payload[wl_module_PAYLOAD];		//Array for Payload&lt;br /&gt;
	uint8_t maincounter =0;&lt;br /&gt;
	uint8_t k;&lt;br /&gt;
	&lt;br /&gt;
	wl_module_init();	//initialise nRF24L01+ Module&lt;br /&gt;
	_delay_ms(50);		//wait for nRF24L01+ Module&lt;br /&gt;
	sei();&lt;br /&gt;
	&lt;br /&gt;
	wl_module_tx_config(wl_module_TX_NR_0);		//Config Module&lt;br /&gt;
		&lt;br /&gt;
	//Timer aktivieren ATMEGA8&lt;br /&gt;
	#if defined(__AVR_ATmega8__)&lt;br /&gt;
	TCCR0 |= ( (1&amp;lt;&amp;lt;CS02) | (1&amp;lt;&amp;lt;CS00));		//Prescaler auf 1024 ATMEGA8&lt;br /&gt;
	TIMSK |= ( (1&amp;lt;&amp;lt;TOIE0));					//enable TOVF ATMEGA8&lt;br /&gt;
	#endif // __AVR_ATmega8__&lt;br /&gt;
	&lt;br /&gt;
	//Timer aktivieren ATMEGA88A&lt;br /&gt;
	#if defined(__AVR_ATmega88A__)&lt;br /&gt;
	TCCR0B |= ( (1&amp;lt;&amp;lt;CS02) | (1&amp;lt;&amp;lt;CS00));&lt;br /&gt;
	TIMSK0 |= ( (1&amp;lt;&amp;lt;TOIE0));&lt;br /&gt;
	#endif // __AVR_ATmega88A__&lt;br /&gt;
		&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
		if (timercounter &amp;gt;= 30)			//30 entspricht ~1 Sekunde bei 8MHz&lt;br /&gt;
			{&lt;br /&gt;
				timercounter = 0;&lt;br /&gt;
			&lt;br /&gt;
				&lt;br /&gt;
				for (k=0; k&amp;lt;=wl_module_PAYLOAD-1; k++)&lt;br /&gt;
				{&lt;br /&gt;
					payload[k] = k;&lt;br /&gt;
				}&lt;br /&gt;
			&lt;br /&gt;
				payload[0] = maincounter;&lt;br /&gt;
				payload[1] = maincounter+1;				&lt;br /&gt;
			&lt;br /&gt;
				wl_module_send(payload,wl_module_PAYLOAD);&lt;br /&gt;
				&lt;br /&gt;
				maincounter++;&lt;br /&gt;
				if (maincounter &amp;gt;250)&lt;br /&gt;
				{&lt;br /&gt;
					maincounter = 0; &lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER0_OVF_vect)&lt;br /&gt;
{&lt;br /&gt;
	timercounter++;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//Unterscheidung je nach verwendeten µC&lt;br /&gt;
#if defined(__AVR_ATmega8__)&lt;br /&gt;
ISR(INT0_vect)&lt;br /&gt;
#endif // __AVR_ATmega8__&lt;br /&gt;
#if defined(__AVR_ATmega88A__)&lt;br /&gt;
ISR(INT0_vect)&lt;br /&gt;
#endif // __AVR_ATmega88A__&lt;br /&gt;
#if defined(__AVR_ATmega168__)&lt;br /&gt;
ISR(PCINT2_vect) &lt;br /&gt;
#endif // __AVR_ATmega168__  &lt;br /&gt;
// Interrupt handler &lt;br /&gt;
{&lt;br /&gt;
    uint8_t status;   &lt;br /&gt;
    &lt;br /&gt;
        // Read wl_module status &lt;br /&gt;
        wl_module_CSN_lo;                               // Pull down chip select&lt;br /&gt;
        status = spi_fast_shift(NOP);					// Read status register&lt;br /&gt;
        wl_module_CSN_hi;                               // Pull up chip select&lt;br /&gt;
		&lt;br /&gt;
		&lt;br /&gt;
		if (status &amp;amp; (1&amp;lt;&amp;lt;TX_DS))							// IRQ: Package has been sent&lt;br /&gt;
		{&lt;br /&gt;
			wl_module_config_register(STATUS, (1&amp;lt;&amp;lt;TX_DS));	//Clear Interrupt Bit&lt;br /&gt;
			PTX=0;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		if (status &amp;amp; (1&amp;lt;&amp;lt;MAX_RT))							// IRQ: Package has not been sent, send again&lt;br /&gt;
		{&lt;br /&gt;
			wl_module_config_register(STATUS, (1&amp;lt;&amp;lt;MAX_RT));	// Clear Interrupt Bit&lt;br /&gt;
			wl_module_CE_hi;								// Start transmission&lt;br /&gt;
			_delay_us(10);								&lt;br /&gt;
			wl_module_CE_lo;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		if (status &amp;amp; (1&amp;lt;&amp;lt;TX_FULL))							//TX_FIFO Full &amp;lt;-- this is not an IRQ&lt;br /&gt;
		{&lt;br /&gt;
			wl_module_CSN_lo;                               // Pull down chip select&lt;br /&gt;
			spi_fast_shift(FLUSH_TX);						// Flush TX-FIFO&lt;br /&gt;
			wl_module_CSN_hi;                               // Pull up chip select&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So, Teile wie Timer oder Timerinterrupt sollten bekannt sein. Schauen wir uns die Funktionen an die aufgerufen werden. &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
wl_module_init();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
ist die bereits bekannte Initialisierungsfunktion wie oben besprochen. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
wl_module_tx_config(wl_module_TX_NR_0);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Müssen wir uns genauer ansehen. In dieser Funktion werden alle wesentlichen Register eingestellt die wir brauchen um das Modul als Sender zu nutzen. Alle verwendeten Funktionen sollten in einer wl_module.c Datei zusammengefasst werden. Obwohl wir es in diesem Beispiel noch nicht nutzen übergeben wir an wl_module_tx_config als Argument die Pipe auf der der Sender senden soll. Das Argument wird dazu  verwendet die entsprechende Adresse für den Sender festzulegen. Diese Routine ist also schon dafür eingerichtet um später einen Multi-Ceiver Betrieb mit 6 Sendern zu ermöglichen. (Beim Empfänger weiter unten wird eine einfache Konfigurationsroutine verwendet mit der kein Multi-Ceiver Betrieb möglich ist!)&lt;br /&gt;
&lt;br /&gt;
Die Variable PTX wird als globale Variable definiert und dazu verwendet um festzustellen ob gerade gesendet wird. Wird gesendet wird sie im Code auf 1 geschaltet, sonst auf 0. &lt;br /&gt;
&lt;br /&gt;
Zum Schluß wird mittels TX_POWERUP (siehe oben) das Modul als Sender aktiviert. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
extern void wl_module_tx_config(uint8_t tx_nr) &lt;br /&gt;
{&lt;br /&gt;
    uint8_t tx_addr[5];&lt;br /&gt;
	&lt;br /&gt;
    // Set RF channel&lt;br /&gt;
    wl_module_config_register(RF_CH,wl_module_CH);&lt;br /&gt;
    // Set data speed &amp;amp; Output Power configured in wl_module.h&lt;br /&gt;
    wl_module_config_register(RF_SETUP,wl_module_RF_SETUP);&lt;br /&gt;
    //Config the CONFIG Register (Mask IRQ, CRC, etc)&lt;br /&gt;
    wl_module_config_register(CONFIG, wl_module_CONFIG);&lt;br /&gt;
    &lt;br /&gt;
    wl_module_config_register(SETUP_RETR,(SETUP_RETR_ARD_750 | SETUP_RETR_ARC_15));&lt;br /&gt;
	&lt;br /&gt;
	//set the TX address for the pipe with the same number as the iteration&lt;br /&gt;
			switch(tx_nr)			&lt;br /&gt;
			{&lt;br /&gt;
				case 0: //setup TX address as default RX address for pipe 0 (E7:E7:E7:E7:E7)&lt;br /&gt;
					tx_addr[0] = tx_addr[1] = tx_addr[2] = tx_addr[3] = tx_addr[4] = RX_ADDR_P0_B0_DEFAULT_VAL;&lt;br /&gt;
					wl_module_set_TADDR(tx_addr);&lt;br /&gt;
					wl_module_set_RADDR(tx_addr);&lt;br /&gt;
					break;&lt;br /&gt;
				case 1: //setup TX address as default RX address for pipe 1 (C2:C2:C2:C2:C2)&lt;br /&gt;
					tx_addr[0] = tx_addr[1] = tx_addr[2] = tx_addr[3] = tx_addr[4] = RX_ADDR_P1_B0_DEFAULT_VAL;&lt;br /&gt;
					wl_module_set_TADDR(tx_addr);&lt;br /&gt;
					wl_module_set_RADDR(tx_addr);&lt;br /&gt;
					break;&lt;br /&gt;
				case 2: //setup TX address as default RX address for pipe 2 (C2:C2:C2:C2:C3)&lt;br /&gt;
					tx_addr[1] = tx_addr[2] = tx_addr[3] = tx_addr[4] = RX_ADDR_P1_B0_DEFAULT_VAL;&lt;br /&gt;
					tx_addr[0] = RX_ADDR_P2_DEFAULT_VAL;&lt;br /&gt;
					wl_module_set_TADDR(tx_addr);&lt;br /&gt;
					wl_module_set_RADDR(tx_addr);&lt;br /&gt;
					break;&lt;br /&gt;
				case 3: //setup TX address as default RX address for pipe 3 (C2:C2:C2:C2:C4)&lt;br /&gt;
					tx_addr[1] = tx_addr[2] = tx_addr[3] = tx_addr[4] = RX_ADDR_P1_B0_DEFAULT_VAL;&lt;br /&gt;
					tx_addr[0] = RX_ADDR_P3_DEFAULT_VAL;&lt;br /&gt;
					wl_module_set_TADDR(tx_addr);&lt;br /&gt;
					wl_module_set_RADDR(tx_addr);&lt;br /&gt;
					break;&lt;br /&gt;
				case 4: //setup TX address as default RX address for pipe 4 (C2:C2:C2:C2:C5)&lt;br /&gt;
					tx_addr[1] = tx_addr[2] = tx_addr[3] = tx_addr[4] = RX_ADDR_P1_B0_DEFAULT_VAL;&lt;br /&gt;
					tx_addr[0] = RX_ADDR_P4_DEFAULT_VAL;&lt;br /&gt;
					wl_module_set_TADDR(tx_addr);&lt;br /&gt;
					wl_module_set_RADDR(tx_addr);&lt;br /&gt;
					break;&lt;br /&gt;
				case 5: //setup TX address as default RX address for pipe 5 (C2:C2:C2:C2:C6)&lt;br /&gt;
					tx_addr[1] = tx_addr[2] = tx_addr[3] = tx_addr[4] = RX_ADDR_P1_B0_DEFAULT_VAL;&lt;br /&gt;
					tx_addr[0] = RX_ADDR_P5_DEFAULT_VAL;&lt;br /&gt;
					wl_module_set_TADDR(tx_addr);&lt;br /&gt;
					wl_module_set_RADDR(tx_addr);&lt;br /&gt;
					break;&lt;br /&gt;
			}&lt;br /&gt;
	&lt;br /&gt;
	PTX =0;&lt;br /&gt;
	TX_POWERUP;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In der Main-Routine wird ein Timer dazu verwendet ca. jede Sekunde einen Zähler (maincounter) hinauf zu zählen (bis max. 250) und im Array payload wird das erste Element mit dem Wert des maincounters belegt. &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
payload[0] = maincounter;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Schleife dient nur dazu das Array mit irgendwelchen Werten zu belegen die am Empfänger auch abgerufen werden können um damit zu &amp;quot;spielen&amp;quot;. Dann wird die Funktion aufgerufen die das Array ins Modul überträgt und die Sendung der Daten beginnt. &lt;br /&gt;
&lt;br /&gt;
wl_module_send(payload,wl_module_PAYLOAD); kümmert sich darum. &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void wl_module_send(uint8_t * value, uint8_t len) &lt;br /&gt;
// Sends a data package to the default address. Be sure to send the correct&lt;br /&gt;
// amount of bytes as configured as payload on the receiver.&lt;br /&gt;
{&lt;br /&gt;
    while (PTX) {}                  // Wait until last paket is send&lt;br /&gt;
&lt;br /&gt;
    wl_module_CE_lo;&lt;br /&gt;
&lt;br /&gt;
    PTX = 1;							// Set to transmitter mode&lt;br /&gt;
    TX_POWERUP;							// Power up&lt;br /&gt;
    &lt;br /&gt;
    wl_module_CSN_lo;                   // Pull down chip select&lt;br /&gt;
    spi_fast_shift( FLUSH_TX );			// Write cmd to flush tx fifo&lt;br /&gt;
    wl_module_CSN_hi;                   // Pull up chip select&lt;br /&gt;
    &lt;br /&gt;
    wl_module_CSN_lo;                   // Pull down chip select&lt;br /&gt;
    spi_fast_shift( W_TX_PAYLOAD );		// Write cmd to write payload&lt;br /&gt;
    spi_transmit_sync(value,len);		// Write payload&lt;br /&gt;
    wl_module_CSN_hi;                   // Pull up chip select&lt;br /&gt;
    &lt;br /&gt;
    wl_module_CE_hi;                    // Start transmission&lt;br /&gt;
	_delay_us(10);						// Grünes Modul funktioniert nicht mit 10µs delay&lt;br /&gt;
	wl_module_CE_lo;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zum Schluß werfen wir noch einen Blick auf die Interrupt-Routine ISR(INT0_vect). Wir wissen, daß es drei Zustände gibt die einen Interrupt auslösen können: RX_DR der Auftritt wenn neue Daten empfangen wurden, TX_DS der Auftritt wenn Daten gesendet wurden und MAX_RT der Auftritt wenn die maximale Anzahl an Sendungswiederholungen ohne Erfolg stattgefunden haben. Sobald einer der Zustände auftritt wird auch das passende Bit im STATUS-Register gesetzt. Um das Bit zu löschen muß eine 1 geschrieben werden. Jeder dieser drei Zustände kann ausmaskiert werden und löst dann keinen Interrupt aus. Man kann so entweder per Interrupt-Routine auf ein Ereignis reagieren oder aber auch mittels polling auf das interessierende Bit auf ein Ereignis reagieren. &lt;br /&gt;
&lt;br /&gt;
In der ISR(INT0_vect) wird zum Beispiel auf TX_DS reagiert und auf MAX_RT. Soblad das Paket gesendet wurde wird TX_DS wieder zurückgesetzt und die Variable PTX auf 0 gesetzt. MAX_RT wird genutzt um die Daten noch einmal zu senden. Der TX-FIFO Speicher wird ja nicht gelöscht wenn eine Datenübertragung fehlgeschlagen hat.&lt;br /&gt;
&lt;br /&gt;
==== Der Empfänger ====&lt;br /&gt;
&lt;br /&gt;
So, ein nRF24L01+ Modul sollte mal funken. Um das zu kontrollieren brauchen wir jetzt unser zweites nRF24L01+ Modul mit dem wir die Daten empfangen. Ich verwende in dem Beispiel eine LCD-Anzeige um die Daten anzuzeigen auf das aber nicht weiter eingegangen wird. Wie die Daten angezeigt werden ist jedem selbst überlassen, genau so gut kann man mittels UART die Daten am PC anzeigen lassen oder was immer Euch zur Verfügung steht. Auch beim Empfänger nicht darauf vergessen die üblichen Stolpersteine wie -Os, µC-Frequenz etc. einzustellen. &lt;br /&gt;
&lt;br /&gt;
Wie schon angekündigt können empfangene Daten mittels Polling abgefragt werden oder über IRQ. In dem Beispiel wird mittels Polling kontrolliert ob neue Daten angekommen sind. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * nRF24L01_Tutorial_RX.c&lt;br /&gt;
 *&lt;br /&gt;
 * Created: 06.01.2012 22:51:57&lt;br /&gt;
 *  Author: Ernst Buchmann&lt;br /&gt;
 */ &lt;br /&gt;
&lt;br /&gt;
#ifndef F_CPU				//define F_CPU if not done &lt;br /&gt;
#define F_CPU 20000000UL&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
#include &amp;lt;util/delay.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;quot;spi.h&amp;quot;&lt;br /&gt;
#include &amp;quot;lcd-routines.h&amp;quot;&lt;br /&gt;
#include &amp;quot;wl_module.h&amp;quot;&lt;br /&gt;
#include &amp;quot;nRF24L01.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
//Variablen&lt;br /&gt;
volatile uint8_t PTX;			//Global Variable&lt;br /&gt;
char itoabuffer[20];&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
	uint8_t payload[wl_module_PAYLOAD];		//holds the payload&lt;br /&gt;
	uint8_t nRF_status;						//STATUS information of nRF24L01+&lt;br /&gt;
	uint8_t zaehler = 0;&lt;br /&gt;
	&lt;br /&gt;
	lcd_init();&lt;br /&gt;
	lcd_clear();&lt;br /&gt;
	wl_module_init();		//Init nRF Module&lt;br /&gt;
	_delay_ms(50);			//wait for Module&lt;br /&gt;
	sei();					//activate Interrupts&lt;br /&gt;
	wl_module_config();		//config nRF as RX Module, simple Version&lt;br /&gt;
	&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
		while (!wl_module_data_ready());			//waits for RX_DR Flag in STATUS&lt;br /&gt;
		nRF_status = wl_module_get_data(payload);	//reads the incomming Data to Array payload&lt;br /&gt;
		zaehler = payload[0];&lt;br /&gt;
		lcd_clear();&lt;br /&gt;
		lcd_home();&lt;br /&gt;
		itoa(zaehler, itoabuffer, 10);				//conversion into String&lt;br /&gt;
		lcd_string(itoabuffer);&lt;br /&gt;
		&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ist die ziemlich kurze main-Routine zum Abfragen der Daten die im Empfänger angekommen sind. Geübten Augen wird sofort auffallen, daß die Abfrage über Polling in diesem Beispiel den µC solange in einer while-Schleife fest hält bis neue Daten angekommen sind. Das ist natürlich nicht praktikabel wenn der µC noch andere Dinge zu erledigen hätte. Für ein erstes Übungsbeispiel wo der Fokus nur darauf liegt die Funkstrecke einzurichten soll uns das nicht stören. Schauen wir und das Programm im Detail an: &lt;br /&gt;
&lt;br /&gt;
Achtung: F_CPU an die eigenen Gegebenheiten anpassen!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
wl_module_init();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
kennen wir schon von den Sender Einstellungen. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
wl_module_config&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
Konfiguriert das nRF Modul mit den wesentlichen Registerinhalten und stellt das Modul auf Empfang. Es wurde hier absichtlich sehr kurz gehalten und nur die wesentlichsten Einstellungen getroffen. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void wl_module_config() &lt;br /&gt;
// Sets the important registers in the wl-module and powers the module&lt;br /&gt;
// in receiving mode&lt;br /&gt;
{&lt;br /&gt;
    // Set RF channel&lt;br /&gt;
    wl_module_config_register(RF_CH,wl_module_CH);&lt;br /&gt;
	// Set data speed &amp;amp; Output Power configured in wl_module.h&lt;br /&gt;
	wl_module_config_register(RF_SETUP,wl_module_RF_SETUP);&lt;br /&gt;
	// Set length of incoming payload &lt;br /&gt;
    wl_module_config_register(RX_PW_P0, wl_module_PAYLOAD);&lt;br /&gt;
	&lt;br /&gt;
    // Start receiver &lt;br /&gt;
    PTX = 0;        // Start in receiving mode&lt;br /&gt;
    RX_POWERUP;     // Power up in receiving mode&lt;br /&gt;
    wl_module_CE_hi;     // Listening for pakets&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wie man sieht wurde hier nur die Payload-Größe für Pipe0 eingestellt und keine weiteren Empfangsadressen gesetzt. Das funktioniert weil beim Sender zwar Adressen konfiguriert wurden aber die Default-Adressen verwendet wurden. Man könnte sich für dieses Beispiel die Definition der Adressen beim Sender sparen und auch dort eine sehr verkürzte Konfiguration verwenden. Als Empfangskanal und -Geschwindigkeit müssen natürlich die gleichen Werte verwendet werden wie beim Sender. Auch die Payload-Größe muß im Empfänger zu  der Anzahl an Bytes passen die der Sender schickt. &lt;br /&gt;
&lt;br /&gt;
In dieser Zeile while (!wl_module_data_ready()); prüft das Programm ob im Empfangsmodul Daten angekommen sind die ausgelesen werden können und bleibt solange in dieser while-Schleife bis RX_DR gesetzt wurde. &lt;br /&gt;
&lt;br /&gt;
Diese Funktion macht nichts weiter als das STATUS Register auszulesen und den Wert von RX_DR zurück zu geben: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
extern uint8_t wl_module_data_ready() &lt;br /&gt;
// Checks if data is available for reading&lt;br /&gt;
{&lt;br /&gt;
    if (PTX) return 0;&lt;br /&gt;
    uint8_t status;&lt;br /&gt;
    // Read wl_module status &lt;br /&gt;
    wl_module_CSN_lo;                                // Pull down chip select&lt;br /&gt;
    status = spi_fast_shift(NOP);               // Read status register&lt;br /&gt;
    wl_module_CSN_hi;                                // Pull up chip select&lt;br /&gt;
    return status &amp;amp; (1&amp;lt;&amp;lt;RX_DR);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sobald RX_DR 1 ist und damit anzeigt, daß Daten angekommen sind wird die while Schleife verlassen und &amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;nRF_status = wl_module_get_data(payload);&amp;lt;/syntaxhighlight&amp;gt; ausgeführt. &lt;br /&gt;
&lt;br /&gt;
Diese Funktion liest den Inhalt des RX-FIFO Speichers aus und gibt den Inhalt des STATUS Registers zurück. Anschließend wird noch das RX_DR Bit gelöscht um den nächsten Datenempfang detektieren zu können: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
extern uint8_t wl_module_get_data(uint8_t * data) &lt;br /&gt;
// Reads wl_module_PAYLOAD bytes into data array&lt;br /&gt;
{&lt;br /&gt;
	uint8_t status;&lt;br /&gt;
    wl_module_CSN_lo;                               // Pull down chip select&lt;br /&gt;
    status = spi_fast_shift( R_RX_PAYLOAD );            // Send cmd to read rx payload&lt;br /&gt;
    spi_transfer_sync(data,data,wl_module_PAYLOAD); // Read payload&lt;br /&gt;
    wl_module_CSN_hi;                               // Pull up chip select&lt;br /&gt;
    wl_module_config_register(STATUS,(1&amp;lt;&amp;lt;RX_DR));   // Reset status register&lt;br /&gt;
	return status;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Rest der main-Routine kümmert sich dann nur noch um die Ausgabe der Daten.&lt;br /&gt;
&lt;br /&gt;
Zum Schluß noch eine kleine Aufgabe: &lt;br /&gt;
Warum wird beim Empfänger keine Interruptfunktion ISR(INT0_vect) verwendet? Und löst  RX_DR überhaupt einen Interrupt aus?&lt;br /&gt;
&lt;br /&gt;
== Beispieldateien ==&lt;br /&gt;
&lt;br /&gt;
Hier finden sich die Dateien die in diesem Beispiel verwendet wurden: &lt;br /&gt;
&lt;br /&gt;
[[Datei: nrf24L01_Tutorial.zip]]&lt;br /&gt;
&lt;br /&gt;
In wl_module.c finden sich alle Routinen die im Tutorial verwendet wurden und auch noch viel, viel mehr. Es sind alle Routinen vorhanden um sehr schnell einen Multi-Ceiver mit 6 Data-Pipes aufzubauen oder verschiedene interessante Daten auszulesen. Das Prinzip sollte nach diesem Tutorial, so hoffe ich, klar sein um diese Routinen zu durchschauen und selbst anzuwenden oder anzupassen.&lt;br /&gt;
&lt;br /&gt;
== Zusammenfassung ==&lt;br /&gt;
&lt;br /&gt;
Noch ein paar wesentliche Punkte zu den Funkmodulen und ersten Schritten hier im Tutorial: &lt;br /&gt;
&lt;br /&gt;
1. Achtung mit der Spannung, die Module vertragen wirklich keine höhere Spannung als im Datenblatt angegeben wie ich leider feststellen durfte. &lt;br /&gt;
&lt;br /&gt;
2. Wie schon angesprochen eignet sich die Polling-Variante im Empfänger-Beispiel nur bedingt für die Umsetzung in eigenen Projekten da sie den µC bis zum nächsten Dateneingang lahm legt. Und sollten keine Daten kommen, dann ist der µC in dieser Zeile ad infinitum gefangen. &lt;br /&gt;
&lt;br /&gt;
3. Es kann sein, wenn die Daten sehr schnell kommen, daß man ein RX_DR versäumt. Der FIFO hat ja Platz für 3xPayload. Man sollte also durchaus auch abfragen ob noch weitere Daten im FIFO vorhanden sind. Insbesondere wenn mit Multi-Ceivern gearbeitet wird. &lt;br /&gt;
&lt;br /&gt;
4. Für kurze Distanzen funktioniert die Datenübertragung mit 2Mbps sehr gut. Wenn längere Distanzen überwunden werden sollen, dann sollte man auf 250kbps zurückgehen, das erhöht die Empfindlichkeit des Empfängers. Der Sender sollte mit maximaler Leistung senden. Außerdem sollte der Payload nur so groß sein wie auch wirklich benötigt. Je weniger Bytes übertragen werden desto größer die Chance auf erfolgreiche Datenübertragung. Bei Bedarf gibt es auch Module die den Anschluß einer externen Antenne ermöglichen. &lt;br /&gt;
&lt;br /&gt;
5. Man sollte die Möglichkeiten nutzen die Enhanced Shockburst bietet. Das TX_DS Bit wird dann nur gesetzt wenn auch wirklich ein ACK vom Empfänger eingetroffen ist. (Im Tutorial wird übrigens Enhanced Shockburst verwendet. Details dazu hätten aber das Tutorial gesprengt)&lt;br /&gt;
&lt;br /&gt;
6. Beim Multi-Ceiver Betrieb sollte für jeden Sender ein, sich von den anderen Sendern unterscheidendes, AUTO RETRANSMIT DELAY (ARD) eingestellt werden. Das erhöht die Chancen, daß sich die Sender nicht gegenseitig stören. &lt;br /&gt;
&lt;br /&gt;
7. Aufpassen beim AUTO RETRANSMIT DELAY wenn mit 250kpbs gesendet wird. Der Default-Wert von 250µS ist zu kurz um eine funktionierende Datenübertragung zu gewährleisten. Für Details siehe Datenblatt. &lt;br /&gt;
&lt;br /&gt;
Nachrichten an den Autor: [http://www.mikrocontroller.net/user/show/Puravida PuraVida]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Funk]]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=CAN&amp;diff=78463</id>
		<title>CAN</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=CAN&amp;diff=78463"/>
		<updated>2013-09-11T16:20:20Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: Fix link to &amp;quot;CAN Bus HUB&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;C&#039;&#039;&#039;ontroller &#039;&#039;&#039;A&#039;&#039;&#039;rea &#039;&#039;&#039;N&#039;&#039;&#039;etwork - Ein von Bosch entwickeltes, echtzeitfähiges Bussystem für den Automobilbereich, welches u.a. auch Anwendung in der Automatisierungstechnik findet.&lt;br /&gt;
&lt;br /&gt;
==Mikrocontroller mit CAN==&lt;br /&gt;
&lt;br /&gt;
=== Atmel AVR===&lt;br /&gt;
&lt;br /&gt;
==== AT90CAN ====&lt;br /&gt;
&lt;br /&gt;
* Atmel AVR Controller mit CAN-Schnittstelle (ein Kanal)&lt;br /&gt;
* Speicher: (flash,EEPROM,RAM)&lt;br /&gt;
** AT90CAN32  -&amp;gt; 32KB 1KB 2KB&lt;br /&gt;
** AT90CAN64  -&amp;gt; 64KB 2KB 4KB&lt;br /&gt;
** AT90CAN128 -&amp;gt; 128KB 4KB 4KB&lt;br /&gt;
* 15 CAN &amp;quot;Message Objects&amp;quot;, jedes individuell konfigurierbar&lt;br /&gt;
* Bis auf den CAN controller weitestgehend identisch mit den nicht CAN Versionen (siehe [http://www.atmel.com/Images/doc4313.pdf AVR096])&lt;br /&gt;
* Beispielcode inkl. CAN für den IAR-C-Compiler findet sich bei atmel.com. Autobaud-Routinen in Assembler (etwas Aufwand bei der Portierung nach avr-gcc/avr-as).&lt;br /&gt;
* Dieser MC ist für nicht-gewerbliche Endanwender einzeln z.&amp;amp;nbsp;B. bei Reichelt, CSD und Segor erhältlich (ca. 9EUR). Beim Bestellen des MC sollte man einen CAN-BUS-Treiber gleich mitbestellen: z.&amp;amp;nbsp;B. Philips PCA82C250. Jedoch auf vorhandene Versorgungsspannungen achten (AT90CAN128 &amp;quot;kann mit&amp;quot; VCC=2,7...5,5V, PCA82C250 lt. Datenblatt für VCC=4,5...5V).&lt;br /&gt;
* CANopen software protocol stacks at http://www.port.de/Atmel.html&lt;br /&gt;
* Freier CANopen stack: http://www.canfestival.org/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- * Im Auslieferungszustand ist nur der interne RC-Oszillator aktiv (wie üblich bei allen modernen AVRs mit internem R/C-Oszillator vgl. [[AVR Checkliste]]). Umschalten auf externe Taktquelle über die AVR-Fusebits.&lt;br /&gt;
* Für die ISP-Programmierung schliesst man Ihn wie den ATmega128 an. MOSI-2 ; MISO-3 ; SCK-11 ; /Reset-20 ;  GND-22,53,63 ; Vcc-21,52,(62),(64). Auf die übliche &amp;quot;ATmega64/128-Problematik&amp;quot; achten: MISO/MOSI der Programmierschnittstelle sind nicht identisch mit der SPI-Schnittstelle.&lt;br /&gt;
[gehört nicht in den &amp;quot;CAN Artikel&amp;quot;] --&amp;gt;&lt;br /&gt;
&amp;lt;!-- * die aktuelle Hardware-Version (Stand 4/2005) hat einen &amp;quot;silicon bug&amp;quot; (Hardwarefehler, vgl. avrfreaks-Forum): Liegt der Stack im &#039;&#039;externen&#039;&#039; RAM, führt dies zu Fehlern in der Stackverwaltung (push/pop/rcall etc.). Details in aktuellen Fassungen des Datenblatts. Abhilfe/Workaround: Stack im internen RAM (&amp;lt;0x1001) verwalten. Dies ist ohnehin sinnvoll, da der Stackzugriff dann schneller ist.&lt;br /&gt;
[nicht mehr aktuell und errata ist immer zu beachten] --&amp;gt;&lt;br /&gt;
&amp;lt;!-- *Als Programmieradapter braucht man einen, der eine gewisse Intelligenz beinhaltet. Vergebens waren auch bei mir die Versuche,   mit dem &#039;Kanda&#039;-Dongle vom STK200-Board und ähnliche Nachbauten.  -&amp;gt; www.mikrocontroller-projekte.de [- Einzeltest mit Stickprobenumfang 1 - sollte schon funktionieren, auskommentiert bis nochmals belegt - mt] --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== ATmega16M1/32M1/64M1 ====&lt;br /&gt;
* modernisierte Version der AT90CAN128 Serie inkl. LIN, PSC und DAC&lt;br /&gt;
* not sampled&lt;br /&gt;
&lt;br /&gt;
==== AT32UC3C ====&lt;br /&gt;
* 32bit AVR mit zwei CAN controllern&lt;br /&gt;
* bis zu 512k flash, 64k RAM&lt;br /&gt;
* DMA, USB, Ethernet MAC, 2Msmps 12bit ADC, 12bit DAC&lt;br /&gt;
&lt;br /&gt;
=== Atmel ARM ===&lt;br /&gt;
&lt;br /&gt;
==== AT91SAM7X ====&lt;br /&gt;
* ARM7TDMI-Kern mit einem CAN controller&lt;br /&gt;
* bis 512k flash und 128k RAM&lt;br /&gt;
&lt;br /&gt;
==== AT91SAM9X ====&lt;br /&gt;
* ARM926-Kern mit zwei CAN controllern&lt;br /&gt;
* kein onboard flash&lt;br /&gt;
* 32k RAM aber DDR2 support&lt;br /&gt;
&lt;br /&gt;
==== AT91SAM3A ====&lt;br /&gt;
* Cortex M3-Kern mit zwei CAN controllern&lt;br /&gt;
* bis zu 512k flash und 96k RAM&lt;br /&gt;
&lt;br /&gt;
==== AT91SAM3X ====&lt;br /&gt;
* Cortex M3-Kern mit zwei CAN controllern&lt;br /&gt;
* bis zu 512k flash und 96k RAM&lt;br /&gt;
&lt;br /&gt;
=== Luminary Micro Stellaris LM3S8xxx ===&lt;br /&gt;
* ARM Cortex-M3&lt;br /&gt;
* bis 64kByte RAM und 256kByte Flash&lt;br /&gt;
* CAN und Ethernet&lt;br /&gt;
&lt;br /&gt;
=== Microchip PIC18Fxx8 PIC18Fxx8x ===&lt;br /&gt;
* Mikrocontroller mit CAN Schnittstelle&lt;br /&gt;
* [http://www.microchip.com/ParamChartSearch/chart.aspx?branchID=50&amp;amp;mid=10&amp;amp;lang=en&amp;amp;pageId=74 Herstellerseite]&lt;br /&gt;
&lt;br /&gt;
=== Mitsubishi / Renesas R8C / M16C / M32C ===&lt;br /&gt;
&lt;br /&gt;
R8C/23, M16C/6Nx&lt;br /&gt;
&lt;br /&gt;
=== Motorola / Freescale DSP56F8xx ===&lt;br /&gt;
* Clock des CAN-Moduls von PLL speisen, nicht von XTAL, sonst gibt es sporadische Aussetzer&lt;br /&gt;
* Bei hohen Datenraten ist es notwendig die CAN-TX-Leitung vom Controller mit einem PullUp-Widerstand zu beschalten. Sonst stimmt das Bit-Timing nicht, weil die Anstiegszeit des TX-Signals zu schlecht ist.&lt;br /&gt;
&lt;br /&gt;
=== Freescale MC9S08 ===&lt;br /&gt;
* D Serie&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Freescale MC9S12 ===&lt;br /&gt;
* B, C, D, G und H Serie&lt;br /&gt;
&lt;br /&gt;
=== NXP LPC11CXX ===&lt;br /&gt;
* 32-bit ARM Cortex-M0&lt;br /&gt;
* LPC11C12 16KB flash, 8KB SRAM, 1x C_CAN&lt;br /&gt;
* LPC11C14 32KB flash, 8KB SRAM, 1x C_CAN&lt;br /&gt;
* LPC11C22 16KB flash, 8KB SRAM, 1x C_CAN, on-chip CAN transceiver&lt;br /&gt;
* LPC11C24 32KB flash, 8KB SRAM, 1x C_CAN, on-chip CAN transceiver&lt;br /&gt;
* Herstellerseite: [http://ics.nxp.com/products/lpc1000/lpc1100/lpc11cxx/]&lt;br /&gt;
&lt;br /&gt;
=== NXP LPC175X LPC176X ===&lt;br /&gt;
* Mikrocontroller mit Cortex-M3 Kern.&lt;br /&gt;
* 1 - 2 CAN Schnittstellen&lt;br /&gt;
* Herstellerseite: [http://ics.nxp.com/products/lpc1000/lpc17xx/ Philips Semiconductors]&lt;br /&gt;
&lt;br /&gt;
=== NXP (ex. Philips) LPC2129 LPC2194 LPC2290 LPC2292 LPC2294 ===&lt;br /&gt;
* Mikrocontroller mit ARM7TDMI-S-Kern (vgl. [[LPC2000 Philips ARM7TDMI-Familie]])&lt;br /&gt;
* 2 - 4 CAN Schnittstellen&lt;br /&gt;
* CAN-Modul angelehnt an Philips SJA1000 (aber mit recht langer und deftig gewürzter Bug-Liste)&lt;br /&gt;
* Herstellerseite: [http://www.nxp.com Philips Semiconductors]&lt;br /&gt;
* LPC2194 erhältlich bei http://www.microcontroller-starterkits.de und http://de.digikey.com/&lt;br /&gt;
* CANopen software protocol stacks at [http://www.port.de/Philips.html]&lt;br /&gt;
&lt;br /&gt;
=== NXP LPC23xx ===&lt;br /&gt;
* Mikrocontroller mit ARM7TDMI-S-Kern (vgl. [[LPC2000 Philips ARM7TDMI-Familie]])&lt;br /&gt;
* 2 CAN Schnittstellen&lt;br /&gt;
&lt;br /&gt;
=== NXP P80C591 P80C592 P80C598 ===&lt;br /&gt;
* 8-Bit Mikrocontroller mit 8051-Kern&lt;br /&gt;
* P80C591 ist neuer und beherrscht CAN2.0B&lt;br /&gt;
* P80C592: CAN2.0A, P80C598 ist die Automotive-Version vom &#039;592&lt;br /&gt;
&lt;br /&gt;
=== Silicon Labs C8051F04X C8051F06X C8051F5XX ===&lt;br /&gt;
*  8-Bit Mikrocontroller mit 8051-Kern&lt;br /&gt;
*  16K - 128K Flash, 2304 - 8448 RAM&lt;br /&gt;
*  LIN 2.1&lt;br /&gt;
*  25-50 MIPS&lt;br /&gt;
*  bis 5x5 QFN&lt;br /&gt;
&lt;br /&gt;
=== STMicroelectronics STM8S20  ===&lt;br /&gt;
* STM8 Kern [http://www.st.com/stonline/products/literature/ds/14733/stm8s208c6.pdf] DIV/MUL -Befehle &lt;br /&gt;
* SPI mit automatischer CRC Berechnung&lt;br /&gt;
* 1 beCAN Schnittstelle CAN2.0B &lt;br /&gt;
* sehr preiswert (128 kFlash/6K RAM ) 3,30 bis 4,80 &amp;amp;#8364; ([http://search.digikey.com/scripts/DkSearch/dksus.dll?vendor=0&amp;amp;keywords=CAN+STM8]  aber SMD LQFP &lt;br /&gt;
&lt;br /&gt;
=== STMicroelectronics STR730 STR750 ===&lt;br /&gt;
* ARM7TDMI-Kern&lt;br /&gt;
* 1-3 CAN Schnittstellen&lt;br /&gt;
&lt;br /&gt;
=== STMicroelectronics STR910FM32, STR910FW32, STR911FM42, STR911FM44, STR912FW42, STR912FW44 ===&lt;br /&gt;
* 96MHz ARM966E-S CPU Kern&lt;br /&gt;
&lt;br /&gt;
=== [http://www.st.com/internet/mcu/class/1734.jsp STMicroelectronics Cortex M3/M4] ===&lt;br /&gt;
Cortex M3 Core&lt;br /&gt;
 - [http://www.st.com/internet/mcu/subclass/1169.jsp STM32F1 Mainstream]&lt;br /&gt;
* STM32F103   : 1 CAN Schnittstelle&lt;br /&gt;
* STM32F105   : 2 CAN Schnittstellen&lt;br /&gt;
* STM32F107   : 2 CAN Schnittstellen&lt;br /&gt;
 - [http://www.st.com/internet/mcu/subclass/1521.jsp?WT.ac=p2_bn_jun12_stm32f4series STM32F2 Hi-Performance]&lt;br /&gt;
* STM32F205   : 2 CAN Schnittstellen&lt;br /&gt;
* STM32F207   : 2 CAN Schnittstellen&lt;br /&gt;
* STM32F215   : 2 CAN Schnittstellen&lt;br /&gt;
* STM32F217   : 2 CAN Schnittstellen&lt;br /&gt;
Cortex M4 Core&lt;br /&gt;
 - [http://www.st.com/internet/mcu/subclass/1521.jsp?WT.ac=p2_bn_jun12_stm32f4series STM32F4 Hi-Performance and DSP]&lt;br /&gt;
* STM32F405   : 2 CAN Schnittstellen&lt;br /&gt;
* STM32F407   : 2 CAN Schnittstellen&lt;br /&gt;
* STM32F415   : 2 CAN Schnittstellen&lt;br /&gt;
* STM32F417   : 2 CAN Schnittstellen&lt;br /&gt;
&lt;br /&gt;
=== TI TMS470 ===&lt;br /&gt;
* ARM7TDMI-Kern&lt;br /&gt;
&lt;br /&gt;
=== Toshiba TLCS-870/C ===&lt;br /&gt;
&lt;br /&gt;
==CAN Controller==&lt;br /&gt;
&lt;br /&gt;
===MCP2515 ===&lt;br /&gt;
&amp;quot;Stand-alone&amp;quot; CAN-Controller von Microchip. &lt;br /&gt;
* SPI Schnittstelle&lt;br /&gt;
* 2 Empfangs- und 3 Sendepuffer jeweils individuell konfigurierbar (ID, Masken/Filter etc.)&lt;br /&gt;
* ein gemeinsamer Interruptpin (RX)&lt;br /&gt;
* ein Interruptpin pro Empfangspuffer, umkonfigurierbar als GPO&lt;br /&gt;
* ein Triggerpin pro Sendepuffer, umkonfigurierbar als GPI&lt;br /&gt;
* Stromsparmodus&lt;br /&gt;
* auch für 3,3V-Betrieb geeignet.&lt;br /&gt;
* Diverse C- und Assembler Beispielcodes verfügbar (z.&amp;amp;nbsp;B. bei microchip.com und kvaser, Assembler meist für PICs). Auch Software für Direktanschluss an die parallele Schnittstelle eines PC verfügbar (&amp;quot;bit-bang Interface&amp;quot;).&lt;br /&gt;
* erhältlich z.&amp;amp;nbsp;B. bei Reichelt (ca. 2&amp;amp;#8364;)&lt;br /&gt;
&lt;br /&gt;
====Links====&lt;br /&gt;
*[http://www.kreatives-chaos.com/index.php?seite=mcp2515 Ansteuerung eines MCP2515] gcc&lt;br /&gt;
*[http://mcp2510btc.berlios.de/ Bit Timing Calculator für Linux]&lt;br /&gt;
&lt;br /&gt;
===SJA1000===&lt;br /&gt;
&amp;quot;Stand-alone&amp;quot; CAN-Controller von Philips&lt;br /&gt;
* Parallele Schnittstelle ca. 12 Leitungen&lt;br /&gt;
* erhältlich z.&amp;amp;nbsp;B. bei Reichelt (ca. 4 Euro)&lt;br /&gt;
&lt;br /&gt;
===AN82526===&lt;br /&gt;
&amp;quot;Stand-alone&amp;quot; CAN-Controller von Intel (entwickelt von Bosch)&lt;br /&gt;
* Vorgänger des AN82527&lt;br /&gt;
&lt;br /&gt;
===AN82527===&lt;br /&gt;
&amp;quot;Stand-alone&amp;quot; CAN-Controller von Intel (entwickelt von Bosch)&lt;br /&gt;
* Nachfolger des AN82526&lt;br /&gt;
* parallele  UND  SPI-Schnittstelle&lt;br /&gt;
* 8- oder 16-Bit Multiplex Bus, oder 8-Bit Non-Multiplexed Bus&lt;br /&gt;
* 14 Tx/Rx Puffer&lt;br /&gt;
* bis zu 16 IO-Pins (je nach Controlleranbindung)&lt;br /&gt;
* erhältlich z.&amp;amp;nbsp;B. bei Reichelt (ca. 5&amp;amp;#8364;)&lt;br /&gt;
&lt;br /&gt;
===Bosch CC170 / CC750 / CC770===&lt;br /&gt;
* kompatibel zum AN82527&lt;br /&gt;
* mehr Debug-Register&lt;br /&gt;
* CC750 im SOIC16-W Gehäuse ohne Parallel-Interface, nur SPI&lt;br /&gt;
* erhältlich bei Rutronik (ca. 8 Euro)&lt;br /&gt;
&lt;br /&gt;
===SAE81C9x===&lt;br /&gt;
* SPI und Busanschluss möglich.&lt;br /&gt;
* PLCC44 und PLCC28, letzteres allerdings in ungebräuchlicher Bauform&lt;br /&gt;
* Nur CAN 2.0A, beherrscht also keine Extended IDs.&lt;br /&gt;
&lt;br /&gt;
==Bustreiber (CAN-Transceiver)==&lt;br /&gt;
&lt;br /&gt;
=== High-Speed ===&lt;br /&gt;
&lt;br /&gt;
====MCP2551====&lt;br /&gt;
* von Microchip&lt;br /&gt;
* PDIP8 und SOIC&lt;br /&gt;
* VCC = 4,5...5,5V&lt;br /&gt;
* kostet rund 1&amp;amp;#8364;&lt;br /&gt;
* [http://ww1.microchip.com/downloads/en/DeviceDoc/21667f.pdf Datenblatt]&lt;br /&gt;
&lt;br /&gt;
====PCA 82C250====&lt;br /&gt;
* ABGEKÜNDIGT!&lt;br /&gt;
* von NXP (ex. Philips)&lt;br /&gt;
* PDIP8 und SO8&lt;br /&gt;
* VCC = 4,5...5,5V&lt;br /&gt;
* V-CAN: -8V..+18V   -&amp;gt; &amp;quot;TTL-kompatible&amp;quot; Bus-Spannung&lt;br /&gt;
* erhältlich z.&amp;amp;nbsp;B. bei Reichelt (ca. 1,00&amp;amp;#8364;)&lt;br /&gt;
&lt;br /&gt;
====PCA 82C251====&lt;br /&gt;
* von NXP (ex. Philips)&lt;br /&gt;
* PDIP8 und SO8&lt;br /&gt;
* VCC = 4,5...5,5V&lt;br /&gt;
* V-CAN: -40V..+40V   -&amp;gt; +24V Bus-Spannung&lt;br /&gt;
* erhältlich z.&amp;amp;nbsp;B. bei Reichelt (ca. 1,50&amp;amp;#8364;)&lt;br /&gt;
&lt;br /&gt;
====TJA 1041====&lt;br /&gt;
* von NXP (ex. Philips)&lt;br /&gt;
* SO14&lt;br /&gt;
* VCC = 4,75...5,25V&lt;br /&gt;
* Standby, Sleepmode&lt;br /&gt;
* 1 MBit/s&lt;br /&gt;
* -27..+40V&lt;br /&gt;
* Automatische Einstellung der I/O Pegel&lt;br /&gt;
* Erwetierte Diagnosefunktionen&lt;br /&gt;
* &amp;quot;Listen only&amp;quot;-Mode&lt;br /&gt;
* 2. Generation&lt;br /&gt;
* http://www.nxp.com/documents/data_sheet/TJA1041A.pdf&lt;br /&gt;
&lt;br /&gt;
====TJA 1042====&lt;br /&gt;
* von NXP (ex. Philips)&lt;br /&gt;
* SO8&lt;br /&gt;
* VCC = 4,5...5,5V auch als 3V I/O Version&lt;br /&gt;
* Standby&lt;br /&gt;
* -27..+40V&lt;br /&gt;
* +-8kV ESD, verträgt dauerhaft +-58V auf den CAN-BUS&lt;br /&gt;
* 3. Generation (bessere EMC und EMI Daten)&lt;br /&gt;
* http://www.nxp.com/documents/data_sheet/TJA1042.pdf&lt;br /&gt;
&lt;br /&gt;
====TJA 1043====&lt;br /&gt;
* wie TJA1041 (bessere EMC, ESD Eigenschaften und geringerer Ruhestrom)&lt;br /&gt;
* SO14&lt;br /&gt;
* Standby, Sleepmode&lt;br /&gt;
* -58..++58V&lt;br /&gt;
* +-8kV ESD, verträgt dauerhaft +-58V auf den CAN-BUS&lt;br /&gt;
* 3. Generation&lt;br /&gt;
* http://www.nxp.com/documents/data_sheet/TJA1043.pd&lt;br /&gt;
&lt;br /&gt;
==== TJA1051 ====&lt;br /&gt;
* von NXP (ex. Philips)&lt;br /&gt;
* SO8, pinkompatibel zu TJA1050&lt;br /&gt;
* VCC = 4,75...5,25V&lt;br /&gt;
* 3. Generation, Nachfolger der PCA82C25x&lt;br /&gt;
* http://www.nxp.com/products/interface_and_connectivity/transceivers/can_transceivers/TJA1051T.html&lt;br /&gt;
&lt;br /&gt;
====ATA6660====&lt;br /&gt;
* von Atmel&lt;br /&gt;
* SO8&lt;br /&gt;
* VCC = 4,75...5,25V&lt;br /&gt;
&lt;br /&gt;
====SN65HVD23x====&lt;br /&gt;
* von Texas Instruments (auch als Sample erhaeltlich)&lt;br /&gt;
* SO8&lt;br /&gt;
* VCC = 3,0V...3,6V&lt;br /&gt;
* erhältlich z.&amp;amp;nbsp;B. bei Reichelt: SN65HVD230, SN65HVD231 (ca. 3,00 €)&lt;br /&gt;
Datenblatt:&lt;br /&gt;
*[http://www.ti.com/lit/gpn/sn65hvd230 SN65HVD230] &lt;br /&gt;
*[http://www.ti.com/lit/gpn/sn65hvd231 SN65HVD231]&lt;br /&gt;
&lt;br /&gt;
=== Fault-Tolerant / Low-Speed ===&lt;br /&gt;
&lt;br /&gt;
==== TJA1055 ====&lt;br /&gt;
* von NXP (ex. Philips)&lt;br /&gt;
* bis 125 &amp;quot;kBaud&amp;quot;&lt;br /&gt;
* SO14&lt;br /&gt;
* TJA1055/3 unterstützt 3V interfaces&lt;br /&gt;
* 6kV ESD Schutz&lt;br /&gt;
* abgekündigt: ähnliche Funktionen, gleicher Hersteller: TJA1053, TJA1054&lt;br /&gt;
&lt;br /&gt;
== CAN Repeater ==&lt;br /&gt;
&lt;br /&gt;
==== AMIS-42700 ====&lt;br /&gt;
* Dual High-Speed CAN Transceiver&lt;br /&gt;
* High speed (up to 1Mbit/s)&lt;br /&gt;
* SOIC-20&lt;br /&gt;
* vgl. http://www.mikrocontroller.net/topic/53799&lt;br /&gt;
&lt;br /&gt;
==== Alternative ====&lt;br /&gt;
* zwei Transceiver&lt;br /&gt;
* [http://www.mikrocontroller.net/attachment/9353/CANREPEATER.JPG Schaltung]&lt;br /&gt;
* Anmerkung: Diese Schaltung ist Quatsch und funktioniert nicht.&lt;br /&gt;
* -Zum Senden eines Zeichen, muss beim CAN paralell auf dem Bus gelesen werden.&lt;br /&gt;
  -Die TRansceiver tun dies nicht, mach nur der Controller.&lt;br /&gt;
  -Die gelesene Nachricht muss also durch einen Controller erneut gesendet werden, wenn der Bus frei ist...&lt;br /&gt;
&lt;br /&gt;
==== CAN Hub ====&lt;br /&gt;
CAN Hub mit standard Knoten&lt;br /&gt;
* http://www.oschmid.ch/mt/can-hub/can-hub.php&lt;br /&gt;
CAN Hub mit getrennten Rx und Tx Leitungen&lt;br /&gt;
* http://www.oschmid.ch/mt/can-hub4/can-hub4.php&lt;br /&gt;
CAN Hub für sternförmige und busförmige Verdrahtung&lt;br /&gt;
* http://www.oschmid.ch/mt/can-hub5/can-hub5.php&lt;br /&gt;
&lt;br /&gt;
==SLIO-CAN==&lt;br /&gt;
&lt;br /&gt;
Preisgünstigste Bausteine sind die Serial Linked I/O Bausteine (SLIO). Diese Bausteine ermöglichen den Aufbau von Ein- und Ausgabeknoten ohne lokalen Prozessor. Auf der Basis dieser Bausteine lässt sich eine dezentrale Signal-Ein-Ausgabe mit minimalem Kostenaufwand realisieren.&lt;br /&gt;
&lt;br /&gt;
=== Philips P82C150===&lt;br /&gt;
* Single-Chip-I/O-Einheit mit integriertem CAN-Controller&lt;br /&gt;
* mögliche Busdatenrate 20kBd bis 125kBd&lt;br /&gt;
* interner RC-Oszillator wird durch den Bitstrom auf den Bus synchronisiert&lt;br /&gt;
* Kalibrierungsnachricht alle 8000 Bitzeiten erforderlich&lt;br /&gt;
** 4-Bit des Identifiers über Port-Pins einstellbar &lt;br /&gt;
* maximal 16 P82C150 in einem CAN-Segment&lt;br /&gt;
** 16 Port-Pins mit unterschiedlichen Konfigurationsmöglichkeiten&lt;br /&gt;
*** 16 mal als digitale Eingänge&lt;br /&gt;
*** 16 mal als digitale Ausgänge&lt;br /&gt;
*** 2 mal als analoger Ausgang ( 10-Bit, DPM )&lt;br /&gt;
*** 6 mal als analoger Eingang ( 10-Bit, multiplex )&lt;br /&gt;
*** 2 mal als Komparator &lt;br /&gt;
&lt;br /&gt;
* [http://www.htw-dresden.de/fe/labor/mikror/projects/slio_can/ slio-CAN]&lt;br /&gt;
&lt;br /&gt;
Anmerkung: Philips stellt die SLIO nicht mehr her! Es ist auch &amp;quot;nichts&amp;quot; mehr am Markt beschaffbar, wenn, dann zu horrenden Preisen (um die 60,-EUR/Stück zur Zeit). --[[Benutzer:OldBug|Patrick]] 09:08, 25. Jan 2005 (CET)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;obsolete&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===DS 36001M===&lt;br /&gt;
&#039;&#039;&#039;Obsolete&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===MCP2502X/5X===&lt;br /&gt;
&lt;br /&gt;
CAN-IO Erweiterung. Braucht praktisch nur noch Quarz und Transciever. Preise ab 3€&lt;br /&gt;
* bis zu 8 digitale IOs &lt;br /&gt;
* bis zu 2 PWM, 10 Bit&lt;br /&gt;
* bis zu 4 ADC, 10 Bit, externe Ref.&lt;br /&gt;
* SLEEP-Mode etc.&lt;br /&gt;
&lt;br /&gt;
[http://ww1.microchip.com/downloads/en/devicedoc/21664c.pdf Datenblatt]&lt;br /&gt;
&lt;br /&gt;
== Verkabelung ==&lt;br /&gt;
* auf beidseitige Busterminierung achten (typisch 2x 120Ω bei &amp;quot;high-speed&amp;quot;)&lt;br /&gt;
* Standardbelegung für diverse Steckverbindungen vgl. CANOpen-Dokumentation http://www.can-cia.de/index.php?id=440 (CiA 303-1);  erfordert Anmeldung&lt;br /&gt;
* Schaltplan für galvanische Trennung z.&amp;amp;nbsp;B. nach Datenblatt des PCA82C250&lt;br /&gt;
* für einfache Testaufbauten über sehr kurze Strecken oder &amp;quot;on-board-CAN&amp;quot; kann auf die Bustreiber verzichtet werden (vgl. Siemens Application-Note [http://www.mikrocontroller.net/attachment/28831/siemens_AP2921.pdf AP2921])&lt;br /&gt;
&lt;br /&gt;
Es gibt auch CAN mit &lt;br /&gt;
* einpoliger unsymmetrischer Verbindung (SAE J2411 single wire)&lt;br /&gt;
* optischer Verbindung (Faser, Glasfaser)&lt;br /&gt;
&lt;br /&gt;
Für einfache Tests genügt auch eine direkte wired-and-Verbindung ohne Treiber:&lt;br /&gt;
http://www.mikrocontroller.net/forum/read-1-325202.html?reload=yes#325962&lt;br /&gt;
&lt;br /&gt;
== Debugging ==&lt;br /&gt;
Hersteller von Debug-Geräten&lt;br /&gt;
* Vector-Informatik CANscope (Pegeltester) http://www.vector-informatik.de/deutsch/  - ca. 3300EUR&lt;br /&gt;
* Gemac CBT (CanBusTester) testet auch Pegel, Reflexionen ... (Treiber etc. etwas ältlich, von 2002, was ist mit Weiterentwicklung?), auch leihweise http://www.gemac-chemnitz.de/pages/d_html/produkte/bus-tester/new-de-can-bust.html http://www.brandt-data.de/canbus/can_intro.html  - ca. 2400EUR&lt;br /&gt;
* ixxat bietet ebenfalls den Gemac-cbt an, auch leihweise&lt;br /&gt;
*QCANObserver http://qcanobserver.sourceforge.net/ CAN Debugger mit ähnlichen Fähigkeiten. Derzeit läuft die Entwicklung nur noch unter Linux. Freie Software (GPL)&lt;br /&gt;
&lt;br /&gt;
Oszilloskope mit CAN-Analyse (manche auch SPI, LIN, RS232, SATA ...):&lt;br /&gt;
* LeCroy WaveRunner 6040 wird mit Vector-CANcaseXL (externer CAN-Trigger) geliefert (sehr gut, ab ca.9000 EUR)&lt;br /&gt;
* LeCroy WaveSurfer 424 wird mit Vector-CANcaseXL (externer CAN-Trigger) geliefert (sehr gut, ab ca.8000 EUR)&lt;br /&gt;
* Yokogawa DL1640 und DL9040 (CAN-Trigger ist intern)  ähnliche Preise wie LeCroy, Bedienung gewöhnungsbedürftig, geht mit etwas Übung besser&lt;br /&gt;
* Tektronix&lt;br /&gt;
* HP / Agilent&lt;br /&gt;
* LogicPort http://www.pctestinstruments.com/&lt;br /&gt;
&lt;br /&gt;
Triggermöglichkeiten: SOF, CAN-ID, CAN-Data, ErrorFrame, RTR, Ack, NoAck  - alle verknüpfbar (gleich ungleich kleiner größer inRange outofRange)&lt;br /&gt;
&lt;br /&gt;
=Links=&lt;br /&gt;
&lt;br /&gt;
==Intern==&lt;br /&gt;
[[CAN als Hausbus]]&lt;br /&gt;
&lt;br /&gt;
==Allgemein==&lt;br /&gt;
* [http://can-wiki.info CAN-WIKI] - spezielle Wiki Site für CAN bus (Englisch)&lt;br /&gt;
* [http://de.wikipedia.org/wiki/Controller_Area_Network Wikipedia - CAN]&lt;br /&gt;
* [http://www.thomas-wedemeyer.de/elektronik/CAN-Bus/can-bus.html Grundlagen zum CAN-Bus] - Kurze Zusammenfassung der Funktionsweise und Einsatzmöglichkeiten vom CAN-Bus&lt;br /&gt;
* [http://www.canbus.cz CAN] - Controller_Area_Network (Czech)&lt;br /&gt;
* [http://www.embedded.com/design/networking/220900314 CAN in 30 minutes or less] - A quick-and-dirty guide to tuning your CAN interface and simplifying your design by Hassane El-Khoury at www.embedded.com&lt;br /&gt;
* [https://www.vector.com/vl_einfuehrungcan_portal_de.html Einführung in CAN] - kostenloses E-Learning Angebot&lt;br /&gt;
&lt;br /&gt;
===Testboards===&lt;br /&gt;
&lt;br /&gt;
*[http://www.jtronics.de/platinen.html  AT90CAN Testboard by www.jtronics.de (aktualisiert 2010)]&lt;br /&gt;
*[http://www.mikrocontroller.net/topic/176804  universal Testboard - CAN RS232 SPI I2C ]&lt;br /&gt;
*[http://www.kreatives-chaos.com/artikel/can-testboard  ATmega8 CAN Testboard und  MCP2515 Tutorial]&lt;br /&gt;
*[http://thinkembedded.ch/_Hersteller/Olimex/AVR-CAN::41.html Olimex AVR-CAN mit AT90CAN128]&lt;br /&gt;
&lt;br /&gt;
===Dongles===&lt;br /&gt;
&lt;br /&gt;
==== Selbstbau Projekte ====&lt;br /&gt;
*[http://cryptomys.de/horo/CAN200/ Can200 Linux Project von Martin Homuth-Rosemann] CAN Businterface am Parallelport (LPT). Mit SJA1000.&lt;br /&gt;
*[http://www.mictronics.de/projects/usb-can-bus/ USB&amp;lt;&amp;gt;CAN Bus Interface mit AVR ATmega162] Open Source. Mit ATmega162, FT245 und SJA1000.&lt;br /&gt;
*[http://www.oschmid.ch/mt/can-hub/can-hub.php CAN Bus HUB]&lt;br /&gt;
*[http://martinsuniverse.de/projekte/caninterceptor/caninterceptor.html CAN-Interceptor von Martin S.] Mit R8C/23 und FT232R.&lt;br /&gt;
* [http://www.fischl.de/usbtin/ USBtin - Simple USB to CAN interface von Thomas Fischl] Mit PIC18F14K50 und MCP2515. Bausatz verfügbar (24,50 EUR).&lt;br /&gt;
&lt;br /&gt;
==== Fertiggeräte ====&lt;br /&gt;
*[http://www.mhs-elektronik.de/tiny_can.html Tiny-CAN USB-CAN-Adapter von MHS-Elektronik] Ab 60,- EUR. Open Source CAN-Monitor für Windows und Linux.&lt;br /&gt;
*[http://www.cantronik.com/ CANvu - CAN-Display-Produkte von CANtronik]&lt;br /&gt;
*[http://www.kopfweb.de/automobiltechnik.html CAN/LIN nach USB Adapter von KOPF GmbH] Ab 320,- EUR&lt;br /&gt;
*[http://www.ixxat.de/overview-pc-can-interface-board_de.html PC/CAN-Interfaces von IXXAT Automation GmbH] ca. 200 EUR&lt;br /&gt;
*[http://www.peak-system.com/Hardware-Liste.90+M5bc66b17d2f.0.html?&amp;amp;tx_commerce_pi1 CAN-Interfaces von Peak-System]  Ca. 200 EUR&lt;br /&gt;
*[http://www.ems-wuensche.com/product/datasheet/html/can-usb-adapter-converter-interface-cpcusb.html USB to CAN Bus Interface von EMS Dr. Thomas Wünsche]  Ca. 180 EUR&lt;br /&gt;
*[http://www.systec-electronic.com/html/index.pl/en_product_can_interfaces  USB-CANmodul Serie von SYS TEC electronic] mit Unterstützung von 1, 2, 8, oder 16 CAN Kanälen (ab 129,- EUR)&lt;br /&gt;
*[http://www.8devices.com/product/2/usb2can USB2CAN USB to CAN bus galvanic isolated converter von 8devices] Ab 65,- EUR. Open source interface DLL and software.&lt;br /&gt;
*[http://www.canusb.com/ canusb USB&amp;lt;&amp;gt;CAN über V24-Treiber] und [http://www.can232.com/  RS232/V24&amp;lt;&amp;gt;CAN Bus Interface] von Lawicel.&lt;br /&gt;
**[http://www.canusb.com/projects.htm Freie Software für canusb]&lt;br /&gt;
**[http://www.canviausb.com Weitere CAN BUS Monitor Software für canusb]&lt;br /&gt;
*[http://www.port.de/pages/products/can/canopen/hardware/ethercan.php?lang=en CAN-LAN-Bridge von PORT] mit ARM und Linux&lt;br /&gt;
*[http://www.anagate.de/products/can-ethernet-gateways.htm CAN-USB Gateway und CAN-Ethernet Gateways von AnaGate] LowCost Lösung und Professionelle Varianten mit Linux System für eigene Anwendungen mit 1,2 und 4 CAN-Ports (Shop)&lt;br /&gt;
*[http://www.rs.canlab.cz/?q=en/node/69 PP2CAN LPT-CAN Interface], [http://www.rs.canlab.cz/?q=en/node/67 CAN2MMC Datenlogger] (CAN,RS232-GPS) und [http://www.rs.canlab.cz/?q=en/node/68 USB2CAN USB2CAN USB-CAN Interface] 80 EUR von CANLAB&lt;br /&gt;
*[http://www.canhack.de/viewtopic.php?t=137 CANHACK CANUSB Interface] High Speed CAN + OBD2 inkl. CAN Monitor. 79,- EUR. (noch aktuell?)&lt;br /&gt;
&lt;br /&gt;
==Software==&lt;br /&gt;
*[http://rbei-etas.github.com/busmaster/ BUSMASTER - Open Source CAN-Bus Analyzer von ETAS/BOSCH]&lt;br /&gt;
*[http://www.canviausb.com CAN Monitor für Lawicel CANUSB, Zanthic CAN-4-USB-FX/MCP2515 und MHS-Elektronik Tiny-CAN] &lt;br /&gt;
*[http://canhack.de/viewtopic.php?f=25&amp;amp;t=135 CAN Monitor und Tracer für Peak USB, Lawicel CANUSB+CAN232 und kompatible]&lt;br /&gt;
*[http://www.mhs-elektronik.de/tiny_can.html GNU – Open Source CAN Monitor, Makro und Filter Funktion, Plugin fähig, unter GTK+ entwickelt]&lt;br /&gt;
* [http://www.wireshark.org wireshark - Netzwerk Protokoll Analyse Tool, unterstützt via socket-CAN CAN und CANopen]&lt;br /&gt;
&lt;br /&gt;
===Protokolle===&lt;br /&gt;
====CANopen====&lt;br /&gt;
&lt;br /&gt;
*[http://canopen.sourceforge.net/index.html CANopen free software resource center]&lt;br /&gt;
*[http://www.canopen-solutions.com/canopen_caneds_de.html Kostenloser Editor für CANopen EDS-Dateien von Vector]&lt;br /&gt;
*[http://developer.berlios.de/projects/socketcan Official Linux CAN interface]&lt;br /&gt;
*[https://github.com/sebi2k1/restcan Javascript interface to SocketCAN with signal processing (in progress)]&lt;br /&gt;
*[http://www.etas.com/de/products/applications_open_source.php BUSMASTER]&lt;br /&gt;
&lt;br /&gt;
[[Category:CAN| ]]&lt;br /&gt;
[[Kategorie:Bauteile]]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Entwicklungsboard_mit_AT91SAM7Sxxx_-_selbstgemacht&amp;diff=75661</id>
		<title>Entwicklungsboard mit AT91SAM7Sxxx - selbstgemacht</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Entwicklungsboard_mit_AT91SAM7Sxxx_-_selbstgemacht&amp;diff=75661"/>
		<updated>2013-05-16T05:16:31Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: Änderung 75660 von 37.59.151.193 (Diskussion) wurde rückgängig gemacht.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Controller mit ARM7 Kern sind toll. Wirklich.&lt;br /&gt;
&lt;br /&gt;
Der Einarbeitungsaufwand ist nicht so groß wie viele glauben und wenn man den Schritt einmal gewagt hat, wird man von den Möglichkeiten begeistert sein.&lt;br /&gt;
Und dann wäre da auch noch der Preis: 6,25€ bei Reichelt für den AT91SAM7S64 bzw. 9,85€ für die große Variante SAM7S256&lt;br /&gt;
Dafür bekommt man höchstens einen ATMEGA128 mit einem Bruchteil des Speichers, Geschwindigkeit und Peripherie.&lt;br /&gt;
AVRs setze ich nur mehr entweder im DIP-Gehäuse für schnelle Basteleien ein, oder aber wenn es besonders stromsparend sein soll.&lt;br /&gt;
&lt;br /&gt;
Dieser Artikel beschreibt die Fertigung eines Entwicklungsboards zum selbst Ätzen aus leicht erhältlichen Teilen und behandelt auch kurz die Inbetriebnahme und Programmierung mit Gratisprogrammen. &lt;br /&gt;
&lt;br /&gt;
Leider muss ich mich hier auf Windows (XP) beschränken. &lt;br /&gt;
&lt;br /&gt;
Vogel – und Obstfreunde habens leider nicht so leicht und müssen sich auf einschlägigen Seiten informieren. Vista zickt (natürlich?) ebenfalls, es gibt jedoch einen extra Artikel darüber.&lt;br /&gt;
&lt;br /&gt;
[[Bild:ARM_Board.jpg|AT91SAM7S Testboard]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
Die Firma [[ARM]] entwickelt Mikrocontrollerkerne verschiedener Leistungsklassen, stellt jedoch keine Endprodukte her, sondern lizenziert die Architektur an Halbleiterproduzenten.&lt;br /&gt;
Diese ergänzen den Kern mit Peripherieeinheiten und fertigen den Chip.&lt;br /&gt;
ARM – Lizenznehmer sind u.a. TI, Analog Devices, Nintendo, NXP (ex. Philips) und Atmel.&lt;br /&gt;
Diese Hersteller bieten zu sehr aggressiven Preisen Mikrocontroller mit softwarekompatiblem Kern, aber unterschiedlicher Auslegung der Peripherie an. So verfügen die Modelle von Analog Devices beispielsweise über einen sehr schnellen ADC und DAC (ADuC70xx, sehr empfehlenswert wenn man was regeln muss...), NXP hat bei den LPC21xx /LPC23xx Modellen ein schnelles Speicherinterface und Atmel bei der AT91SAM-Reihe einen mächtigen DMA-Controller und viele, hochwertige Schnittstellen. NXP und Atmel implementieren bei einigen Modellen auch einen USB 2.0 Full-Speed Controller (12Mbit/s).&lt;br /&gt;
&lt;br /&gt;
=== Qual der Wahl ===&lt;br /&gt;
&lt;br /&gt;
Meine Wahl fiel zu Gunsten von Atmel aus, da der AT91SAM7S zwar durch den langsameren Speicher nicht die Geschwindigkeit des NXP-Controllers erreichen kann, aber dafür bessere  Hardware-Schnittstellen und weniger Designfehler aufweist. Unter anderem bis zu 55MHz SPI-Takt möglich, damit kann man z.&amp;amp;nbsp;B. einen schnellen seriellen ADC ansteuern. &lt;br /&gt;
&lt;br /&gt;
Datenblätter, in denen die (ganz tolle!) gewünschte Spezifikation heruntergebetet wird sind mir absolut unsympathisch und erhöhen nicht gerade das Vertrauen ins Produkt, wenn dann im fast dickeren Errata-Sheet steht, was sie nicht richtig hinbekommen haben. Ich habe auch auf anderen Gebieten schlechte Erinnerungen an Philips und mir daher, auch aufgrund der positiven Erfahrungen sowohl mit AVRs als auch ATMEL- Mitarbeitern, für AT91SAM7S entschieden. ATMEL schreibt nur Dinge die funktionieren ins Datenblatt rein und lässt andere gleich weg (TWI Master, RTC mit Uhrenquarz etc. waren sicher mal geplant, haben aber nicht funktioniert, also stehen sie auch nicht im Datenblatt) So freut man sich nicht auf Dinge die man dann aber doch nicht nutzen kann.&lt;br /&gt;
&lt;br /&gt;
=== Thumb Mode ===&lt;br /&gt;
&lt;br /&gt;
Die verwendete Controllerfamilie ist die zweitkleinste aus der ARM–Serie AT91SAM von Atmel mit hardwarebasierter USB- Schnittstelle. &lt;br /&gt;
Es handelt sich hierbei um einen Controller mit dem ARM7 TDMI RISC Kern mit 3-stufiger Pipeline und gemeinsamen Instruktions- und Datenbus von ARM.&lt;br /&gt;
Obwohl der Controller 32-bitig ausgeführt ist, kann er auch 16-Bit breiten „THUMB“-Code (Daher das T im Namen) ausführen, welcher zwar weniger mächtig, dafür aber speichersparender ist.&lt;br /&gt;
Da der interne Bus jedoch nur 32Bit breit ist und der Flashspeicher nur mit max. 30MHz ausgelesen werden kann, muss man, um auch bei höheren Taktraten des Controllers nicht auf Befehle aus dem Flash warten zu müssen, diese entweder im 16-Bit Thumb-Modus kompilieren, sodass 2 Instruktionen parallel gelesen werden können, oder aber zeitkritische Routinen (Interruptroutinen, Hauptschleife) vor der Ausführung ins RAM kopieren, wie dies bei PCs üblich ist.&lt;br /&gt;
&lt;br /&gt;
=== Varianten und Speicher ===&lt;br /&gt;
&lt;br /&gt;
Der AT91SAM7S64 verfügt über 64kBytes Flash-Speicher, welcher u.a. mit Hilfe eines Bootloaders über USB oder UART programmiert werden kann, sowie über 16kByte SRAM. Reicht dies nicht aus, kann man auf die pinkompatiblen, größeren Modelle zurückgreifen.&lt;br /&gt;
*AT91SAM7S128 (128k Flash, 32k RAM)&lt;br /&gt;
*AT91SAM7S256 (256k Flash, 64k RAM)&lt;br /&gt;
*AT91SAM7S512 (512k Flash, 64k RAM), das „Flaggschiff“ &lt;br /&gt;
Das Gehäuse ist entweder ein 64-Pad QFN oder ein 64-Pin LQFP.&lt;br /&gt;
Die kleineren Variante (SAM7S16/32/321) im 48-Pin Gehäuse sind schwer erhältlich und kaum bis gar nicht billiger. Darüberhinaus verliert man die Möglichkeit für ein pinkompatibles Upgrade.&lt;br /&gt;
Es gibt auch größere Varianten mit Ethernet – und CAN-Controller (SAM7X) sowie externem Speicherinterface (SAM7SE).&lt;br /&gt;
&lt;br /&gt;
=== Takt- und Stromversorgung ===&lt;br /&gt;
&lt;br /&gt;
Die Taktversorgung übernimmt ein externer Quarz mit 3 bis 20MHz, woraus mittels On-Chip PLL der Haupttakt von max. 55MHz sowie die Hilfstakte für die Peripherieeinheiten gebildet werden. Es kann auch eine externe Taktquelle mit max. 55MHz direkt eingespeist werden. Um den fest installierten USB-Bootloader zu verwenden, wird ein 18,432MHz Quarz benötigt, woraus das 48MHz Signal für den USB-Controller generiert wird. In dieser Konfiguration versorgt derselbe Takt auch den Kern, er läuft also etwas unterhalb der maximal möglichen Geschwindigkeit. Andernfalls arbeitet der Bootloader nur mit RS232.&lt;br /&gt;
Ein integrierter Taktcontroller kann bis zu 3 verschiedene Taktsignale an Pins ausgeben, was bei einigen Projekten ein unschätzbarer Vorteil gegenüber anderen Controllern ist, bei denen man den Takt für andere ICs extra generieren müsste.&lt;br /&gt;
Der Chip benötigt nur eine 3,3V Stromversorgung. Diese sollte jedoch relativ glatt und stabil sein.&lt;br /&gt;
Der ARM-Kern selbst wird mit 1,8V versorgt, welche ein On-Chip Spannungsregler zur Verfügung stellt. Dieser muss aber noch richtig verbunden werden.&lt;br /&gt;
Mit einem zusätzlichen RS232 Levelkonverter und einem Linearregler, um die 3.3V Betriebsspannung zu erzeugen, liegt der gemessene Verbrauch des Mikrocontrollers mit allen benötigten Schnittstellen im vollen Betrieb bei ca. 40mA bei 5V Versorgungsspannung.&lt;br /&gt;
Bei [[Ultra low power| batteriebetriebenen]] Anwendungen ist es ratsam, den eingebauten Längsregler zu deaktivieren und durch einen effizienteren kombinierten 3,3V und 1,8V Schaltregler zu ersetzen und somit den Gesamtverbrauch zu senken sowie nicht benötigte Teile abzuschalten.&lt;br /&gt;
Der Controller verfügt außerdem über einen eingebauten Resetcontroller und Watchdog-Timer, was die notwendige externe Beschaltung weiter vereinfacht. Natürlich ist hier der Hinweis angebracht, das man bei besonderen Anforderungen besser einen externen Supervisor IC anhängen sollte.&lt;br /&gt;
&lt;br /&gt;
=== Ausstattung ===&lt;br /&gt;
&lt;br /&gt;
Die weitere Ausstattung liest sich wie die Wunschliste eines Mikrocontrollerprogrammierers:&lt;br /&gt;
&lt;br /&gt;
*Interruptcontroller mit 8 verschiedenen Prioritäten&lt;br /&gt;
*2 externe Interrupts&lt;br /&gt;
*JTAG Schnittstelle zum Debuggen&lt;br /&gt;
*I/O Controller mit 32 Pins, jeweils mit zuschaltbarem Pull-up Widerstand und Anti-Glitch-Filter zum einfachen Entprellen.&lt;br /&gt;
*Zähler/Timer&lt;br /&gt;
*4-Kanal 16-Bit PWM-Controller&lt;br /&gt;
*3 programmierbare Taktausgänge&lt;br /&gt;
*8-Kanal 10-Bit ADC mit 384ksps.&lt;br /&gt;
&lt;br /&gt;
Die Ein-und Ausgänge sind 5V tolerant, d.h. sie können direkt ohne [[Pegelwandler]] an mit 5V versorgte ICs angeschlossen werden. Es muss jedoch ev. beachtet werden, das nach dem Reset die IO-Pins über einen Pullup – Widerstand von 100-200kΩ auf 3,3V gezogen werden, was beim anlegen von 5V an die Pins zu einem Stromfluss durch den Controller führt.&lt;br /&gt;
Der schon erwähnte [[DMA]] Controller ermöglicht den Empfang von Daten ohne Eingreifen des ARM-Kerns, indem er sie von der externen Schnittstelle direkt in den RAM schreibt bzw. im RAM abgelegte Daten sendet.&lt;br /&gt;
Zur Kommunikation mit anderen ICs sind ein SPI-Interface (max. mit Controllergeschwindigkeit taktbar!), eine I²C-Schnittstelle (von Atmel [[TWI]] genannt), ein [[I2S |I²S]] Interface zur Kommunikation mit Audio – ICs, ein SSC (Synchronous Serial Controller), 2 [[USART]]S mit erweiterten Funktionen und natürlich die allseits bekannte und beliebte (oder auch nicht) 12Mbits/s Full-Speed USB 2.0 Schnittstelle vorhanden.&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
&lt;br /&gt;
=== Selbst ist der Bastler ===&lt;br /&gt;
&lt;br /&gt;
Es gibt zahlreiche günstige Entwicklerboards für die AT91SAM7S Serie. Aber selbermachen ist einfach interessanter und lehrreicher. Bestellen kann ja jeder...&amp;lt;BR&amp;gt;&lt;br /&gt;
Das hier vorgestellte Headerboard passt schön in die billigen Steckbrettchen („STECKBOARD 2K1V“, aber auch in andere) von Reichelt und kann von jedem selbst gebaut werden, der zweiseitige Platinen Ätzen kann. Es ist natürlich nur als Vorschlag gedacht. Ich werde jedoch hier weder auf [[Platinenherstellung mit der Photo-Positiv-Methode | Ätztechniken]] noch auf [[SMD Löten]] eingehen, da es dafür einfach schon zu viele Artikel gibt. Es sei nur gesagt, dass die „Zuerst alle Beinchen mit viel Zinn vollschmieren und danach mit Entlötlitze alles überflüssige entfernen“ Methode bei mir ausgezeichnet funktioniert.&lt;br /&gt;
Leider ist es aber notwendig, Durchkontaktierungen (VIAs) zu setzen. Draht durchstecken und auf beiden Seiten verlöten geht aber hier nicht, da sich bei meinem Layout einige VIAs unter dem Mikrocontroller befinden. Man braucht also Durchkontaktierungsnieten (0,6mm Innendurchmesser) z.&amp;amp;nbsp;B. auch von Reichelt als NIETEN 0,6MM. Die ziemlich teure und trotzdem sehr wackelige Presse ist aber nicht nötig. Mit etwas probieren kann man die Nieten mit einer Pinzette wunderbar durch ein 0,8mm Loch stecken und dann, je nach gewünschtem Perfektionismus, auf der anderen Seite entweder nur festlöten oder vorsichtig mit Hammer und einem ev. leicht konischen und vor allem feinen Stift auch dort flachklopfen.&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
Viel Spass beim Experimentieren.&lt;br /&gt;
&lt;br /&gt;
=== Einfach ist besser ===&lt;br /&gt;
&lt;br /&gt;
Meine Platine wurde nicht auf geringstmöglichen Platzbedarf optimiert, sondern auf leichten Aufbau, Verwendung von Standardbauteilen (alles bei Reichelt zu bekommen) und möglichst großer Flexibilität hin entwickelt.&lt;br /&gt;
Wenn man 3 Löcher bohrt kann man anstelle des vorgesehenen DPACK-Gehäuses z.&amp;amp;nbsp;B. problemlos TO220 Spannungsregler verwenden. Ich habe einen LF33CV verwendet, jeder andere Linearregler welcher bei 4V Eingangsspannung noch 3,3V erzeugen kann geht aber auch.&lt;br /&gt;
Falls man kein Steckbrett verwenden will können die Stiftleisten auch an der Oberseite montiert werden. Die Verbindung zu anderen Teilen kann man dann sehr einfach mit Drahtstücken herstellen.&lt;br /&gt;
&lt;br /&gt;
Im Layout sind die unbedingt empfehlenswerten 100nF Blockkondensatoen nicht eingezeichnet. Man muss daher bei jedem Via, welches die Spannungsversorgungspins des Controllers mit der Rückseite verbindet, einen 100nF Kerko auf Masse löten.&lt;br /&gt;
&lt;br /&gt;
=== Quarz und USB Bootloader ===&lt;br /&gt;
&lt;br /&gt;
Ich habe mich weitgehend an Olimex und Original ATMEL Schaltplänen orientiert. Empfehlenswert ist auch das ATMEL-Dokument „AT91SAM7S Microcontroller Series Schematic Check List“.&lt;br /&gt;
Der Quarz ist ein 18,432MHz [[Baudratenquarz]], welcher vom integrierten Bootloader bevorzugt wird, und mit dem man auch wunderbar die USB- Taktrate erzeugen kann. Die KERKOS beim Quarz müssen zwar eigentlich auf den verwendeten Typ angepasst werden (Datenblatt Quarz + µC). 22pF haben bislang aber noch immer und überall funktioniert...&lt;br /&gt;
Wird ein anderer Quarz verwendet, muss der PLL-Filter angepasst werden. Es gibt hierfür ein Berechnungstool bei ATMEL.&lt;br /&gt;
Der Filter sowie der Quarz sollen möglichst nahe am IC liegen um Störungen zu minimieren.&lt;br /&gt;
Da ein interner Resetcontroller eingebaut ist und dieser auch verwendet wird, muss der /RESET PIN nicht beschaltet werden.&lt;br /&gt;
Es existieren mehrere Varianten der USB-Pullup Schaltung. Die von mir gewählte hat den Vorteil, dass der Widerstand im Normalzustand mit VCC verbunden ist und die Schaltung damit dem PC gleich beim Einstecken den Anmeldewunsch signalisiert, wie es der Bootloader haben möchte. Will man dies nicht, hängt man die Basis des npn-Transistors an einen Pin des Controllers (Olimex verwendet PA16) und kann sich so bei Bedarf anmelden lassen.&lt;br /&gt;
Soll die Schaltung ausschließlich USB-Powered laufen und sich immer an den PC anmelden, kann der Widerstand auch direkt an VCC hängen.&lt;br /&gt;
Es ist auch möglich den Pullup-Widerstand direkt an einen Pin des Controllers zu hängen. Im Ausgangszustand hängt die Datenleitung dann aber über 1,5k + 10-15k vom internen Pullup auf VCC. Dieser Fall ist nicht Spezifikationskonform, aber ich habe schon einige Schaltungen damit gesehen.&lt;br /&gt;
Zusätzlich ist noch ein Spannungsteiler vorgesehen um festzustellen, ob die 5V USB-Spannung anliegen. Aufgrund der 5V-Toleranz der Eingänge wäre dies zwar nicht unbedingt nötig, aber sicher ist sicher, vor allem weil die USB-Spannung ja auch größer sein kann.&lt;br /&gt;
&lt;br /&gt;
== Schaltplan ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/wikifiles/b/b6/ARM_Board_Schematic.pdf Schaltplan als PDF]&lt;br /&gt;
&lt;br /&gt;
Alle nicht bezeichneten Kondensatoren sind 100nF, die Widerstände 10k&lt;br /&gt;
&lt;br /&gt;
== Stückliste ==&lt;br /&gt;
&lt;br /&gt;
Der AT91SAM7S256 empfiehlt sich für die Entwicklung, da er grosse Ressourcen an RAM und FLASH bereitstellt. Man kann aber natürlich auch nur den 64er nehmen, wenn man sicher ist mit 16kB RAM auszukommen.&lt;br /&gt;
*Vias (siehe Text)&lt;br /&gt;
*Spannungsregler incl. der benötigten Kondensatoren. Muss bei 4,5V- Spannungsabfall an der Schutzdiode noch 3,3V liefern können.&lt;br /&gt;
*Schutzdiode (bedrahtet) z.&amp;amp;nbsp;B. 1N4001 oder auch Schottky&lt;br /&gt;
*100nF Kerko SMD 0603 (15x)&lt;br /&gt;
*15pF Kerko SMD 0603 (2x)&lt;br /&gt;
*Quarz 18,432MHz, HC49U-S incl. Kondensatoren&lt;br /&gt;
*15pF Kerko SMD 0603 (2x)&lt;br /&gt;
*1nF + 10nF Kerko SMD 0603 für PLL-Filter&lt;br /&gt;
*Widerstände SMD 0603: 1k5(2x), 15k, 45k, 27Ω (2x), 10k (3x)&lt;br /&gt;
*SMD-LED + Vorwiderstand für 3,3V (2x)&lt;br /&gt;
*2,2µF KERKO oder ELKO&lt;br /&gt;
*Stiftleisten (siehe Text)&lt;br /&gt;
*Wannenstecker 20Pol falls JTAG gewünscht&lt;br /&gt;
*Taster für Reset falls gewünscht&lt;br /&gt;
*USB-B Buchse Print&lt;br /&gt;
*Beschaltung für USB-Pullup-Widerstand nach Wahl (Text!)&lt;br /&gt;
&lt;br /&gt;
== Layout ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/wikifiles/f/f3/ARM_Board_TOP.pdf Oberseite, bereits gespiegelt]&lt;br /&gt;
* [http://www.mikrocontroller.net/wikifiles/7/7b/ARM_Board_Bottom.pdf Unterseite]&lt;br /&gt;
&lt;br /&gt;
== Es werde Licht (Testlauf) ==&lt;br /&gt;
&lt;br /&gt;
Der AT91SAM7S Bootloader ist leider ziemlich unpraktisch (NXP und Analog haben das wesentlich besser hinbekommen!) und daher nur als Notfallmaßnahme einzusetzen. Zum erstmaligen Einrichten und testen ist er aber optimal:&lt;br /&gt;
Zuerst muss SAM-BA heruntergeladen und installiert werden. Achtung: Der Neustart ist tatsächlich notwendig, sonst funktioniert es nicht.&lt;br /&gt;
Dann wird der TST Pin des Controllers mit VCC verbunden (per Jumper) und die Schaltung mit 5V versorgt. Man kann auch den USB-Stecker einstecken. Windows wird dann jedoch jammern, das das USB-Gerät nicht erkannt wurde, außer man hat vorher den Steuerungspin der Pullup-Beschaltung auf GND gehängt Der Transistor sperrt dann und der Widerstand hängt frei.. Nach ca. 10-15sec kann man wieder abstecken und TST entweder offen lassen oder auf GND legen (Jumper umstecken). Nun verbindet man das Board über USB mit dem PC. Es sollte sich als SAM7Sxx Testboard anmelden (Pullup auf VCC?). Ist dies erfolgreich, kann man SAM-BA starten, USB als Connection und den verwendeten Mikrocontrollertyp (+ -EK für Evaluation Kit, Atmel geht davon aus das alle ihr Paket kaufen...) auswählen.&lt;br /&gt;
Man kann nun ein beliebiges Testprogramm, z.&amp;amp;nbsp;B. aus den zahlreichen Beispielen von ATMEL herunterladen. Leider darf ich dieses hier nicht zur Verfügung stellen, aber die Beispielprogramme sollte man sich eh ansehen…&lt;br /&gt;
Die Frage nach dem Unlock beantwortet man mit YES und wenn er dann nachfragt ob die Bereiche wieder Gelockt werden sollten verneint man dies.&lt;br /&gt;
Der Controller ist nun nicht mehr gesperrt und kann einfach über JTAG programmiert werden.&lt;br /&gt;
&lt;br /&gt;
Hat der Test nicht funktioniert sollte man einige Dinge überprüfen:&lt;br /&gt;
*Spannungen 3,3V + 1,8V OK?&lt;br /&gt;
*USB+ mit 1,5KOhm auf VCC gezogen?&lt;br /&gt;
*Schwingt der Quarz? Ev. Wert der KERKOS doch überprüfen&lt;br /&gt;
*Wenn möglich Stromaufname mit gedrücktem RESET-Knopf messen und mit Normalbetrieb vergleichen&lt;br /&gt;
*Die Pins PA0-3 müssen HIGH-Pegel haben (Interne Pullups, Siehe Datenblatt)&lt;br /&gt;
*/RESET muss offen oder höchstens mittels Pullup auf VCC gezogen sein&lt;br /&gt;
*die Pins ERASE und JTAGSEL müssen offen oder auf GND gelegt sein&lt;br /&gt;
*Spannung am TST-Pin in beiden Fällen (VCC + GND) überprüfen&lt;br /&gt;
&lt;br /&gt;
Wenn das Board nun (endlich?) funktioniert, kann man sich dem Programmieren zuwenden.&lt;br /&gt;
&lt;br /&gt;
== Die Softwareseite ==&lt;br /&gt;
&lt;br /&gt;
Die ARM-Prozessorkerne werden von der Gnu Compiler Collection (gcc) voll unterstützt. Der ist gut und gratis, wie hier allgemein bekannt sein sollte.&lt;br /&gt;
Der gcc Compiler ist in der Lage, sowohl 32Bit Code als auch 16-Bit Thumb Code sowie Mischcode zu erzeugen.&lt;br /&gt;
Es gibt zahlreiche Open-Source Entwicklungsumgebungen für ARM Prozessoren.&lt;br /&gt;
Hervorzuheben sind WinARM, ein eher kompaktes Paket, und YAGARTO, welches Eclipse als Entwicklungsumgebung einbindet. Es gibt bei ATMEL auch eine umfangreiche Beschreibung incl. Beispielcode, welche die Einrichtung einer kompletten Entwicklungsumgebung mit JTAG - Debugger erklärt.&lt;br /&gt;
Auf weiterführende Erklärungen soll daher hier verzichtet werden, auch weil die Programme sehr stark weiterentwickelt werden und die Informationen daher bald veraltet wären.&lt;br /&gt;
Empfehlenswert ist auch die Homepage von Atmel mit zahlreichen Beispielen und Application Notes.&lt;br /&gt;
Ganz nett ist auch AT91.com, auch wenn die Informationen dort etwas verstreut liegen und ohne Anmeldung fast nix geht.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Programmierung (nur ganz kurz, versprochen...) ==&lt;br /&gt;
&lt;br /&gt;
=== Allgemeine ARM Programmierung ===&lt;br /&gt;
&lt;br /&gt;
Mikrocontroller werden im Allgemeinen in C programmiert. Assembler macht auf Maschinen dieser Leistungsklasse nur in Ausnahmefällen (Startup-Code, siehe unten) einen Sinn.&lt;br /&gt;
Auf Grundlagen der Sprache wie z.&amp;amp;nbsp;B. Strukturen und Grundlagen der Zeiger wird hier nicht weiter eingegangen. Dafür gibt’s tolle C Tutorials oder sogar Bücher.&lt;br /&gt;
Der verwendete Compiler kennt für die ARM-Architektur folgende Datentypen:&lt;br /&gt;
&lt;br /&gt;
*char	1 Byte&lt;br /&gt;
*short	2 Bytes&lt;br /&gt;
*Int, long	4 Bytes&lt;br /&gt;
*long long	8 Bytes&lt;br /&gt;
*float	4 Bytes&lt;br /&gt;
*double	8 Bytes&lt;br /&gt;
&lt;br /&gt;
Bei float und double handelt es sich um Fließkommazahlen.&lt;br /&gt;
Da ihre Verarbeitung auf dem Mikrocontroller ohne Fließkommaeinheit, wie dem hier verwendeten, sehr rechenaufwändig ist, sollte man wenn möglich auf sie verzichten und auf [[Festkommaarithmetik]] zurückgreifen, da der Speicher auf diesen kleinen Systemen meistens ebenfalls kostbar ist.&lt;br /&gt;
Die Festkommatypen gibt es jeweils vorzeichenlos (unsigned) und vorzeichenbehaftet.&lt;br /&gt;
&lt;br /&gt;
Alle Peripherieeinheiten des Controllers werden durch das Setzen von Werten in bestimmten Registern konfiguriert. Ein Register ist nichts anderes als eine bestimmte Adresse im Adressbereich des Controllers. Bei einem 32Bit Controller ist jedes dieser Register 32Bit breit.&lt;br /&gt;
Atmel liefert für jeden Controller eine header-Datei (.h) in welcher u.a. für jedes Register einfacher merkbare Namen definiert werden. Der weiter unten beschriebene PIO Controller hat z.B seine Basisadresse bei 0xFFFFF400. Da diese Adresse schwer merkbar ist, wird sie mit &lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
	#define AT91C_BASE_PIOA ((AT91PS_PIO) 0xFFFFF400) //Base Address&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
als AT91C_BASE_PIOA definiert. Es ist im Programm also egal ob man 0xFFFFF400 oder  AT91C_BASE_PIOA schreibt.&lt;br /&gt;
Bei AT91PS_PIO handelt es sich um einen unsigned Integer Wert.&lt;br /&gt;
Ab dieser Adresse liegen die einzelnen Konfigurationsregister. &lt;br /&gt;
In der header-Datei ist zum Zugriff auf diese eine Struktur definiert:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
	typedef struct _AT91S_PIO {&lt;br /&gt;
		AT91_REG	 PIO_PER;  // PIO Enable Register&lt;br /&gt;
		AT91_REG	 PIO_PDR;  // PIO Disable Register&lt;br /&gt;
		AT91_REG	 PIO_PSR;  // PIO Status Register&lt;br /&gt;
		...&lt;br /&gt;
	} AT91S_PIO, *AT91PS_PIO;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
Zum Zugriff auf diese Speicherzellen werden Zeiger (Pointer) verwendet. Dies kann auf 2 verschiedene Arten geschehen:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
	AT91PS_PIO pPIO = AT91C_BASE_PIOA;  // Global Pointer to PIO&lt;br /&gt;
//ODER&lt;br /&gt;
	AT91S_PIO *pPIO = AT91C_BASE_PIOA;  // Global Pointer to PIO&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
pPIO ist ein Zeiger welcher auf die Struktur PIO_PER an der Adresse AT91C_BASE_PIOA zeigt.&lt;br /&gt;
Beide Deklarationen sind gleichwertig und ihre Verwendung von persönlichen Vorlieben abhängig.&lt;br /&gt;
Um auf das richtige Register im richtigen Speicherbereich zuzugreifen verwendet man  Zeigeroperationen:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
	pPIO-&amp;gt;PIO_PER = 0xFFFFFFFF;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
setzt alle 32Bit im PIO_PER Register. Das Präfix 0x bedeutet, das die Zahl hexadezimal dargestellt wird und x-&amp;gt;y ist eine Abkürzung für den Befehl (*x).y, also ein Zeiger auf eine in einem Struct liegende Variable.&lt;br /&gt;
Normalerweise weist man Registern jedoch nicht direkt einen Wert zu, sondern setzt einzelne Bits.&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
	#define LED_MASK ( (1&amp;lt;&amp;lt;0)|(1&amp;lt;&amp;lt;1)|(1&amp;lt;&amp;lt;2)|(1&amp;lt;&amp;lt;3) )&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
(1&amp;lt;&amp;lt;n) ist eine Bitschiebeoperation. 1 wird binär um n Bits nach rechts verschoben.&lt;br /&gt;
(1&amp;lt;&amp;lt;3) ergibt binär dargestellt 1000.&lt;br /&gt;
„|“ ist der ODER – Operator. LED_MASK hat also am Ende den binären Wert 1111.&lt;br /&gt;
Die ersten 4 Bits im Register werden nun folgendermaßen gesetzt:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
	pPIO-&amp;gt;PIO_PER = LED_MASK; // Enable PIO for LEDs&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
Eine kleine Besonderheit des AT91SAM7 ist, das die Register kein Löschen von Bits erlauben bzw. benötigen. Man muss/kann dazu das Disable- oder Clear-Register verwenden.&lt;br /&gt;
Das Gegenteil des vorherigen Befehls lautet daher:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
	pPIO-&amp;gt;PIO_PDR = LED_MASK;// Disable PIO for LEDs&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
Dies erlaubt eine sehr einfache, sichere und schnelle Programmierung ohne die sonst bei Mikrocontrollern notwendigen Bitoperationen ( &amp;amp; AND, | OR) beim Schreiben in Register.&lt;br /&gt;
Manchmal benötigt man von einer Zahl nur einen Teil. Um z.&amp;amp;nbsp;B. nur die unteren 8 Bits einer Zahl n zu erhalten, um diese beispielsweise über USB zu versenden, verwendet man ((n) &amp;amp; 0xFF)&lt;br /&gt;
Dieser Befehl führt eine binäre AND Verknüpfung mit binär 11111111 durch. Alle höheren Bits werden damit zu 0.&lt;br /&gt;
Die Bitschiebeoperationen &amp;lt;&amp;lt; und &amp;gt;&amp;gt; kann man auch für eine schnelle Multiplikation bzw. Division durch Potenzen von 2 verwenden. ((n) &amp;gt;&amp;gt; 2) teilt n durch (2^2) = 4 und ((n) &amp;lt;&amp;lt; 3) multipliziert die Zahl mit (2^3) = 8.&lt;br /&gt;
Dies ist jedoch nicht unbedingt notwendig, da der Compiler diese Optimierungen (wenn sinnvoll und möglich) automatisch durchführt. &lt;br /&gt;
Bei der Programmierung von Peripheriecontrollern muss beachtet werden, das diese nach dem Einschalten bzw. nach einem Reset nicht mit einem Taktsignal versorgt werden und man dieses erst einschalten muss, indem man den Power Managment Controller konfiguriert.&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
	*AT91C_PMC_PCER =	(1 &amp;lt;&amp;lt; AT91C_ID_PIOA); // Enable Clock for PIO&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Makefile ===&lt;br /&gt;
&lt;br /&gt;
Das Programm make mit der dazugehörigen Konfigurationsdatei Makefile dient dazu, den Kompiliervorgang zu automatisieren.&lt;br /&gt;
Verwendet werden dabei die Optionen all (kompiliert das gesamte Projekt), clean (löscht alle durch den Compiler erzeugten Dateien) sowie program.&lt;br /&gt;
Diese werden als Parameter beim Aufruf des Programmes make übergeben.&lt;br /&gt;
Die ersten Beiden sind nicht controllerspezifisch und die Optionen werden in der make-Dokumentation erklärt.&lt;br /&gt;
Program dient dem automatischen Übertragen der kompilierten Datei auf den Controller.&lt;br /&gt;
Dazu muss der verwendete Programmieradapter angegeben werden.&lt;br /&gt;
Informationen hierzu findet man bei seinem JTAG-Adapter.&lt;br /&gt;
Die Option OPT mit den Auswahlmöglichkeiten [0, 1, 2, 3, s] stellt den Optimierungsgrad des Compilers ein.&lt;br /&gt;
0 bedeutet keine Optimierung und sollte beim Debuggen verwendet werden.&lt;br /&gt;
Im endgültigen Programm kann man 3 (schnellstmöglicher Code) oder s (kleinstmöglicher Code, in einigen Fällen daher sogar schneller als 3) verwenden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Debuggen ===&lt;br /&gt;
&lt;br /&gt;
Ein Debugger dient dazu, den Programmablauf sowie Variablenwerte während der Programmausführung zu überwachen. &lt;br /&gt;
Aufgrund der beschränkten Ressourcen auf einem Mikrocontroller kann das nicht wie bei einem PC  mit einem nebenher laufenden Programm erfolgen. Man greift daher auf die oben erwähnte JTAG-Schnittstelle zu.&lt;br /&gt;
Ein JTAG-Adapter kommuniziert dabei mit dem Mikrocontroller und das Programm OpenOCD übersetzt zwischen JTAG-Hardware und dem in der Entwicklungsumgebung implementierten Software-Debugger. Da es viele verschiedene Möglichkeiten gibt beschränke ich mich hier auf einen Link auf die Seite von OpenOCD, wo auch verwendbare Hardware aufgezählt wird.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Startvorgang ===&lt;br /&gt;
&lt;br /&gt;
ARM-Mikrocontroller sind nicht gleich nach dem Einschalten der Betriebsspannung bereit, Befehle auszuführen, sondern müssen zuerst konfiguriert werden.&lt;br /&gt;
Atmel stellt für seine Controller sogenannte Startup-Files für verschiedene Konfigurationen zur Verfügung. Diese sind, zumindest teilweise, in Assemblercode geschrieben.&lt;br /&gt;
Sie kümmern sich um die Erzeugung des Haupttaktes mittels PLL aus dem angeschlossenen Quarz, die Platzierung von Interruptroutinen im RAM und die Behandlung von Programmfehlern.&lt;br /&gt;
Werden von einem Befehl ungültige Speicherbereiche überschrieben, kann dies abgefangen und automatisch eine Fehlerbehandlungsroutine bzw. Debugcode aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== PIO ===&lt;br /&gt;
&lt;br /&gt;
Der schon teilweise in der Einleitung erwähnte PIO (Parallel Input Output) Controller kümmert sich   um einen 32-Pin breiten IO-Port (PA0 bis PA31). &lt;br /&gt;
Jeder Pin kann als allgemeiner Ein-oder Ausgang verwendet werden oder einem der beiden Peripheriecontroller (A oder B) zugewiesen werden.&lt;br /&gt;
Konfiguriert man den Pin als Eingang, indem man das betreffende Bit im Konfigurationsregister setzt, kann man einen internen Pullup aktivieren, eine Funktion zum Ausfiltern von Eingangssignalen kürzer als ein halber Taktzyklus aktivieren, was bei angeschlossensen Tastern das gefürchtete Prellen verhindert, oder einen Pin-Change-Interrupt aktivieren, welcher bei jedem Wechsel des Pinzustandes eine Routine aufrufen kann.&lt;br /&gt;
Nach dem Einschalten sind, wie schon bei der Hardwarebeschreibung erwähnt, alle Pins als Eingänge mit aktiviertem Pullup konfiguriert.&lt;br /&gt;
Der folgende Befehl schreibt den Zustand des Ports in die 32Bit breite Variable n.&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
	n = pPIO-&amp;gt;PIO_PDSR;  // Read Pin Data&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
Als Ausgang konfiguriert kann jeder Pin 8mA treiben. Die ersten 4 Pins (High-Drive) sind sogar in der Lage, 16mA zu liefern. Der Ausgang kann auch als Open-Drain konfiguriert werden.&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel konfiguriert die in LED_MASK definierten Pins als Ausgänge und setzt sie auf HIGH und anschließend auf LOW:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
	pPIO-&amp;gt;PIO_PER  = LED_MASK;  // Enable PIO for LEDs&lt;br /&gt;
	pPIO-&amp;gt;PIO_OER  = LED_MASK;  // LED1..4 are Outputs&lt;br /&gt;
	pPIO-&amp;gt;PIO_SODR = LED_MASK;  // Turn on LED&#039;s (&amp;quot;1&amp;quot;)&lt;br /&gt;
	pPIO-&amp;gt;PIO_CODR = LED_MASK;  // Turn off LED&#039;s (&amp;quot;0&amp;quot;)&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
Will man einen Pin nicht als allgemeinen Ein-bzw. Ausgang nutzen, sondern z.&amp;amp;nbsp;B. die SPI-Schnittstelle verwenden, muss man den Pin einem der beiden Peripheriecontroller zuweisen:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
	pPIO-&amp;gt;PIO_ASR = ( AT91C_PA13_MOSI );  //MOSI Pin Controller A zuweisen und den PIO-Controller für diesen Pin deaktivieren:&lt;br /&gt;
	pPIO-&amp;gt;PIO_PDR = ( AT91C_PA13_MOSI );  //PIO für MOSI deaktivieren&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
Im Datenblatt werden die Funktionen der einzelnen Pins aufgelistet.&lt;br /&gt;
&lt;br /&gt;
=== UART ===&lt;br /&gt;
&lt;br /&gt;
Die Verwendung der seriellen Schnittstelle [[USART]] zur Kommunikation mit einem PC wird anhand eines Beispieles erklärt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
//Global Pointer to USART1&lt;br /&gt;
AT91PS_USART * pUSART = AT91C_BASE_US1;&lt;br /&gt;
&lt;br /&gt;
//Initialize Serial Interface&lt;br /&gt;
void uart1_init (void) { &lt;br /&gt;
	&lt;br /&gt;
*AT91C_PMC_PCER = (1 &amp;lt;&amp;lt; AT91C_ID_US1);  // Enable Clock for USART1&lt;br /&gt;
&lt;br /&gt;
//Die Pins 21 und 22 werden dem Peripheriecontroller A zugewiesen. &lt;br /&gt;
//Dieser hat somit die Kontrolle über sie.&lt;br /&gt;
*AT91C_PIOA_PDR = AT91C_PA21_RXD1 |  // Enable RxD1 Pin&lt;br /&gt;
                  AT91C_PA22_TXD1;   // Enable TxD1 Pin&lt;br /&gt;
&lt;br /&gt;
//Dann wird ein Reset der Schnittstelle ausgelöst &lt;br /&gt;
  pUSART-&amp;gt;US_CR = AT91C_US_RSTRX |   // Reset Receiver&lt;br /&gt;
                  AT91C_US_RSTTX |   // Reset Transmitter&lt;br /&gt;
                  AT91C_US_RXDIS |   // Receiver Disable&lt;br /&gt;
                  AT91C_US_TXDIS;    // Transmitter Disable&lt;br /&gt;
&lt;br /&gt;
//Im Mode Register werden alle Einstellungen durchgeführt&lt;br /&gt;
  pUSART-&amp;gt;US_MR = AT91C_US_USMODE_NORMAL |  // Normal Mode&lt;br /&gt;
                  AT91C_US_CLKS_CLOCK    |  // Clock = MCK&lt;br /&gt;
                  AT91C_US_CHRL_8_BITS   |  // 8-bit Data&lt;br /&gt;
                  AT91C_US_PAR_NONE      |  // No Parity&lt;br /&gt;
                  AT91C_US_NBSTOP_1_BIT;    // 1 Stop Bit&lt;br /&gt;
&lt;br /&gt;
//eine Baudrate von 115200Baud wird gesetzt&lt;br /&gt;
  pUSART-&amp;gt;US_BRGR = (MCK/16/115200 );  // Baud Rate Divisor&lt;br /&gt;
&lt;br /&gt;
//und die Schnittstelle aktiviert&lt;br /&gt;
  pUSART-&amp;gt;US_CR = AT91C_US_RXEN  |  // Receiver Enable&lt;br /&gt;
                  AT91C_US_TXEN;    // Transmitter Enable&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//Die Funktion sendet einen 8Bit Wert &lt;br /&gt;
int uart1_putc(int ch) {&lt;br /&gt;
	while (!(pUSART-&amp;gt;US_CSR &amp;amp; AT91C_US_TXRDY)); // Wait for Empty Tx Buffer&lt;br /&gt;
	return (pUSART-&amp;gt;US_THR = ch);               // Transmit Characte&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//warten, bis ein Byte empfangen wurde, und dieses ausgelesen&lt;br /&gt;
int uart1_getc ( void ) {&lt;br /&gt;
	while (!(pUSART-&amp;gt;US_CSR &amp;amp; AT91C_US_RXRDY));  // Wait for Full Rx Buffer&lt;br /&gt;
	return (pUSART-&amp;gt;US_RHR);                     // Read Character&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die serielle Schnittstelle ist sehr einfach zu verwenden und vor allem beim Fehlersuchen sehr praktisch. Zum Anschluss an einen PC benötigt man jedoch einen geeigneten Pegelkonverter, welcher den 0V/3.3V Pegel des Mikrocontrollers auf +-12V shiftet.&lt;br /&gt;
Man muss ebenfalls auf die Taktgeschwindigkeit des Controllers aufpassen, da dieser nicht mit jeder Einstellung einen für schnelle USART-Übertragung geeigneten Takt erzeugen kann.&lt;br /&gt;
&lt;br /&gt;
=== SPI ===&lt;br /&gt;
&lt;br /&gt;
[[SPI]] oder Microwire ist ein von Motorola entwickeltes serielles Bussystem, das in vielen Mikrocontrollern implementiert ist. Es gibt dabei einen Master, welcher maximal 255 Slaves anspricht. Die Slaves dürfen nur nach Aufforderung durch den Master senden. Der Bus besteht aus 3 Leitungen:&lt;br /&gt;
&lt;br /&gt;
*MOSI (Master Out Slave In), auch als SDO (Serial Data Out) bezeichnet&lt;br /&gt;
*MISO (Master In Slave Out) oder SDI (Serial Data In) sowie &lt;br /&gt;
*SCK (System Clock)&lt;br /&gt;
&lt;br /&gt;
Zusätzlich benötigt man zu jedem Slave eine Slave Select (SS) oder Chip Select (CS) Leitung, mit welcher der Master den oder die angesprochenen Slaves selektiert.&lt;br /&gt;
Der Bus benötigt daher relativ viele Leitungen (min. 3 + 1 Select pro Slave für bidirektionale Kommunikation), ist aber recht schnell und sehr flexibel.&lt;br /&gt;
Daher wird er auch oft für Punkt-zu Punkt Hochgeschwindigkeitsverbindungen wie z.&amp;amp;nbsp;B. zwischen Mikrocontroller und externem Speicher oder in modernen PC zur Anbindung des BIOS-Flash-Speichers an die Southbridge verwendet.&lt;br /&gt;
Es gibt kein festgelegtes Übertragungsprotokoll und ebenfalls mehrere Übertragungsmöglichkeiten:&lt;br /&gt;
Daten können entweder „Little Endian“, d.h. das LSB (Least significant Bit, also niederwertigstes Bit) wird zuerst übertragen, oder aber „Big Endian“, wo das MSB (Most significant Bit) zuerst geschickt wird, gesendet werden. Je nach Gerät werden die Daten bei steigender oder fallender Taktflanke übernommen und ob ein HIGH- oder LOW-Pegel am SS Eingang den Slave aktiviert ist ebenfalls unterschiedlich. Der Takt kann im Ruhezustand ebenfalls entweder HIGH oder LOW sein und pro Übertragung können zwischen 8 und 16 Bit geschickt werden.&lt;br /&gt;
Die SPI Implementierung im Controller muss also hochgradig konfigurierbar sein.&lt;br /&gt;
Wie bei allen Peripherieeinheiten des AT91SAM7 muss auch bei SPI zuerst der Takt aktiviert und die Pins dem richtigen Peripheriecontroller zugewiesen werden.&lt;br /&gt;
Um einen Wert (8 bis 16Bit breit, je nach Einstellung) zu senden, schreibt man ihn in das SPI_TDR Register.&lt;br /&gt;
Er wird dann automatisch im Hintergrund übertragen, und sobald der Wert gesendet ist, wird je nach Konfiguration ein Interrupt aufgerufen oder nur das Bit AT91C_SPI_TDRE (Transmit Data Register Empty) im SPI_SR Register gesetzt.&lt;br /&gt;
Ein empfangener Wert landet im SPI_RDR Register. Bei Empfang kann ebenfalls ein Interrupt ausgelöst oder nur das Bit SPI_RDRF (Receive Data Register Full) gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
=== USB ===&lt;br /&gt;
&lt;br /&gt;
Die USB-Schnittstelle des AT91SAM7Sxxx hat eine maximale Bandbreite von 1Mbytes/s und entspricht der USB 2.0 full-speed Spezifikation. Diese sieht einen mit einem Transistor schaltbaren Pullup Widerstand auf 3,3V vor, mit dem das Gerät seinen Anmeldewunsch mitteilen kann. Man kann auf diesen auch verzichten und die Datenleitung über 1,5kOhm direkt mit 3,3V verbinden. Der Controller muss sich dann direkt nach dem Start korrekt am PC anmelden, da dieser sonst nach einer Timeout-zeit meldet, das das USB-Gerät nicht erkannt wurde. Die Einhaltung des Zeitfensters stellte jedoch auf allen getesteten Systemen kein Problem dar.&lt;br /&gt;
Der USB-Controller muss mit 48MHz +-0,25% getaktet werden. Der dazu nötige PLL-Takt von 96MHz (2*48MHz) wird aus dem Quarztakt von 18,432MHz erzeugt und beim Startup-Vorgang eingestellt. &lt;br /&gt;
Empfehlenswert ist das Framework von ATMEL, welches einen virtuellen COM-Port auf dem PC (getestet mit Windows XP + VISTA) zur Verfügung stellt.&lt;br /&gt;
Näheres steht auf der ATMEL-Seite.&lt;br /&gt;
&lt;br /&gt;
== Fazit ==&lt;br /&gt;
&lt;br /&gt;
Natürlich schrecken die enormen Möglichkeiten des Controllers im ersten Moment ab, aber wenn man die Anleitungen Schritt-für-Schritt durchgeht und an einem interessanten Beispielprojekt von ATMEL etwas herum spielt, wird man bald Freude daran finden.&lt;br /&gt;
&lt;br /&gt;
Viel Spaß dabei!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Interessante Seiten + Downloads ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/doc6258.pdf AT91SAM7S Microcontroller Series Schematic Check List]&lt;br /&gt;
* [http://atmel.com/dyn/products/tools_card.asp?tool_id=3883 SAM-BA]&lt;br /&gt;
* [http://atmel.com/dyn/products/tools_card.asp?tool_id=3784 ATMEL Evaluation Kit]  Besonders interessant sind die Bespiele im &amp;quot;AT91SAM7S-EK Software Package&amp;quot; (incl. .bin File!)&lt;br /&gt;
* [http://yagarto.de/ YAGARTO]&lt;br /&gt;
* [http://atmel.com/dyn/products/app_notes.asp?family_id=605 Aplication Notes]&lt;br /&gt;
* [http://atmel.com/dyn/products/tools.asp?family_id=605 ATMEL-Software]&lt;br /&gt;
* [http://openocd.berlios.de/web/ OpenOCDDebugger]&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/ARM_Entwicklung_unter_Windows_Vista ARM Entwicklung unter Windows Vista]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM-Boards]]&lt;br /&gt;
[[Category:1. Wettbewerb]]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Ultimatives_Aquariumsteuerger%C3%A4t&amp;diff=75610</id>
		<title>Ultimatives Aquariumsteuergerät</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Ultimatives_Aquariumsteuerger%C3%A4t&amp;diff=75610"/>
		<updated>2013-05-13T18:27:05Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: Tippfehler korrigiert&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;von Torsten Crull&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
= Einleitung =&lt;br /&gt;
Wie an den zahlreichen Beiträgen zu dem Thema im Internet zu  erkennen ist, scheint der Bedarf durch fertig käufliche Geräte nicht ausreichend gedeckt zu sein. [http://notizblog.wordpress.com/2012/02/12/unser-neues-aquarium/ Ich habe seit einiger Zeit ein Aquarium] und mir sind die fertigen Kauflösungen zu unflexibel und/oder zu teuer.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Fazit: Ein ultimatives Steuergerät ist zu entwickeln; [http://www.mikrocontroller.net/topic/264084 hier geht&#039;s zum Diskussionsthread dieses Projekts]&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Terrarien-Steuerung:&#039;&#039;&#039; Auch wenn die Überschrift es anders vermuten lässt, ist das Gerät auch für Terrarien vorgesehen. Im folgenden Text wird zur besseren Lesbarkeit trotzdem immer von einem Aquarium gesprochen.&lt;br /&gt;
&lt;br /&gt;
Es handelt sich &amp;lt;u&amp;gt;nicht&amp;lt;/u&amp;gt; um ein komerzielles Projekt. Bei Bedarf können wir aber Sammelbestellungen z.B. beim Platinenservice organisieren.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Übergeordnete Anforderungen&#039;&#039;&#039;&lt;br /&gt;
* Das Steuergerät ist erweiterbar, auch um Komponenten die &amp;lt;u&amp;gt;nicht jeder&amp;lt;/u&amp;gt; benötigt.&lt;br /&gt;
* Das Steuergerät ist sehr preiswert, insbesondere in seiner Basisversion.&lt;br /&gt;
* Der Stromverbrauch ist auf „total cost of ownership“ optimiert.&lt;br /&gt;
* Möglichst alle sinnvollen Ideen und Vorschläge sollten durch Erweiterungen realisierbar sein, sofern sie in der Basisversion nicht enthalten sind.&lt;br /&gt;
* Das Steuergerät entspricht allen wichtigen Vorschriften (TÜV-, CE-, …); eine Approbation ist natürlich nicht geplant.&lt;br /&gt;
&lt;br /&gt;
= Beschreibung =&lt;br /&gt;
&lt;br /&gt;
== Bedienung über die integrierte Mini-Bedienung ==&lt;br /&gt;
[[Datei:Aquarium-Satellit.png]]&lt;br /&gt;
&lt;br /&gt;
Die Mini-Bedienung ist die minimal vorgesehene Anzeige- und Bedienmöglichkeit. Gegenüber dem unten beschriebenen &#039;&#039;&#039;Menü-Bedienteil&#039;&#039;&#039; ist sie deutich spartanischer, aber auch preiswerter. Nacholgend sind die Funktionen beschrieben:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Lich ein/ aus&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Duch &amp;lt;u&amp;gt;kurzen&amp;lt;/u&amp;gt; Druck auf die Tasten &#039;&#039;&#039;ein&#039;&#039;&#039; oder &#039;&#039;&#039;aus&#039;&#039;&#039; wir das Aquarium-Licht ein- ode ausgeschaltet.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Licht dimmen&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Duch &amp;lt;u&amp;gt;langen&amp;lt;/u&amp;gt; Druck auf die Tasten &#039;&#039;&#039;ein&#039;&#039;&#039; oder &#039;&#039;&#039;aus&#039;&#039;&#039; wir das Aquarium-Licht heller oder dunkler gedimmt.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Temperatur-Anzeige&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Die zweifarbige LED signalisiert im normalen Betrieb über Blink-Sequen&lt;br /&gt;
die gemessene Temperatur im Aquarium in Schritten von 0,5°C. Es wird angezeigt, ob die Temperatur wärmer oder kälter als Anzeige-Basistemperatur ist. Falls die Anzeige-Basistemperatur vom Anwender nicht anders eingestellt wurde, beträgt sie 22°C. Die Anzeige-Basistemperatur ist &amp;lt;u&amp;gt;nicht&amp;lt;/u&amp;gt; die Soll-Temperatur für den Regler, diese wird gesondert eingestellt (s.u.).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Beispiele&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
! Blinksequenz || Bedeutung || Temperatur &lt;br /&gt;
|-&lt;br /&gt;
| blau - blau - blau - pause || Basis - 1,5° || 20,5°C&lt;br /&gt;
|-&lt;br /&gt;
| blau - blau - pause  || Basis - 1,0° || 21,0°C&lt;br /&gt;
|-&lt;br /&gt;
| blau - pause || Basis - 0,5° || 21,5°C&lt;br /&gt;
|-&lt;br /&gt;
| blau - rot - pause || Basis ± 0,0° || 22,0°C&lt;br /&gt;
|-&lt;br /&gt;
| rot - pause || Basis + 0,5° || 22,5°C&lt;br /&gt;
|-&lt;br /&gt;
| rot - rot - pause || Basis + 1,0° || 23,0°C&lt;br /&gt;
|-&lt;br /&gt;
| rot - rot - rot - pause || Basis + 1,5° || 23,5°C&lt;br /&gt;
|-&lt;br /&gt;
| rot - rot - rot - rot - pause || Basis + 2,0° || 24,0°C&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Zeitautomatik&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Durch Betätigen der Mode-Taste wird der Zeit-Programmier-Modus aktiviert und durch ein dauerhaftes &amp;lt;u&amp;gt;rotes&amp;lt;/u&amp;gt; Leuchten der LED signalisiert.&lt;br /&gt;
&lt;br /&gt;
Durch Drücken der jeweiligen Bedientaste “ein” oder “aus” wird zur gewünschten Zeit die Ein- oder Aus-Funktion programmiert, die sich täglich zur selben Uhrzeit wiederholt. Dabei wird bei installiertem Dimmer (EVG) jeweils ein Sonnen-auf- bzw. -untergang simuliert.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Einstellung der Soll-Temperatur&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Durch mehrfaches Betätigen der Mode-Taste wird der Temperatur-Programmier-Modus aktiviert und durch ein dauerhaftes &amp;lt;u&amp;gt;blaues&amp;lt;/u&amp;gt; Leuchten der LED signalisiert.&lt;br /&gt;
&lt;br /&gt;
Durch Drücken der jeweiligen Bedientaste “ein” oder “aus” wird die Temperatur in Schritten von 0,5°C höher oder tiefer gestellt programmiert. Die eingestellte Temperatur ist dabei an den Blink-Sequenzen (siehe &amp;quot;Temperatur-Anzeige&amp;quot;) erkennbar.&lt;br /&gt;
&lt;br /&gt;
== Bedienung über USB ==&lt;br /&gt;
&lt;br /&gt;
Neben den bereits im Kapitel &amp;quot;Bedienung über den Aquarium-Satellit&amp;quot; beschriebenen Funktionen gibt es über USB weitere Möglichkeiten:&lt;br /&gt;
* Basis-Temperatur für die Anzeige einstellen&lt;br /&gt;
* Dimm-Geschwindigkeit einstellen, also die Dauer des simulierten Sonnen-auf- und -untergangs&lt;br /&gt;
* Untere und obere Grenze für den Temperatur-Alarm einstellen&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Dieses Kapitel ist noch in Arbeit.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
= Hardware =&lt;br /&gt;
&lt;br /&gt;
Die Hardware besteht aus mehreren Modulen, die sich - je nach Bedarf - kombinieren lassen. Zunächachst eine Übersicht:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Module&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
! Bezeichnung || Kommentar || Kosten (ca.) &lt;br /&gt;
|-&lt;br /&gt;
| Zentralrechner  || Wenigstens die Basisversion ist erforderlich  || 12€&lt;br /&gt;
|-&lt;br /&gt;
| Mini-Bedienung || Anzeige- und Bedienteil, optional || 5€&lt;br /&gt;
|-&lt;br /&gt;
| Mondlicht || optional || 4€&lt;br /&gt;
|-&lt;br /&gt;
| Temperaturalarm || optional || 1,60€&lt;br /&gt;
|-&lt;br /&gt;
| 230V Relaisbox || optional, Preis für 3 Kanäle || 25€&lt;br /&gt;
|-&lt;br /&gt;
| Temperatursensor || optional || 2€&lt;br /&gt;
|-&lt;br /&gt;
| EVG-Ansteuerung || optional || 1€&lt;br /&gt;
|-&lt;br /&gt;
| Heizfolie und Ansteuerung || optional || 13€&lt;br /&gt;
|-&lt;br /&gt;
| Menü-Bedienteil || optional || &amp;gt;30€&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Zentralrechner (Basis) ==&lt;br /&gt;
&lt;br /&gt;
In der Basisversion kommt ein [[MSP430]]-Launchpad zum Einsatz. Es bringt einen I²C-Bus, PWM-Ausgänge und einen USB-Anschluss mit und kostet nur ca. 5€.&lt;br /&gt;
&lt;br /&gt;
== Mini-Bedienung (optional) ==&lt;br /&gt;
&lt;br /&gt;
Aquariumsteuergerät läßt sich über den USB-Anschluss von einem PC oder einem geeigneten Tablet oder Handy mit USB-OTG-Schnittstelle bedienen. Man kann jedoch eine einfache Bedieneinheit mit drei Tastern und zwei LEDs zu nutzen. Diese kann man entweder für ca. 5€ über den I²C-Bus anschließen oder für ca. 3,50€ direkt über 5 freie IO-Ports an den Prozessor. &lt;br /&gt;
&lt;br /&gt;
Diese Bedieneinheit ermöglicht es, die wichtigsten Funktionen zu bedienen, siehe Kapitel &amp;quot;Bedienung über die Mini-Bedienung&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Die Mini-Bedienung kann direkt in den Deckel des Aquariums eingebaut werden, wenn man ein paar Löcher für die Taster und die LEDs in den Deckel bohrt.&lt;br /&gt;
&lt;br /&gt;
[[Datei:Dsc_5937.jpg]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Hier noch im Prototypen-Aufbau, links ragt die Abdeckung (spätere Frontplatte) ins Bild.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In der preiswertesten Variante ist die Mini-Bedienung auf der Zentralrechner-Platine integriert, so dass der Zentralrechner ohne (teures) Gehäuse direkt zusammen mit der Mini-Bedienung direkt unter den Deckel des Aquariums verbaut werden kann.&lt;br /&gt;
&lt;br /&gt;
Die Mini-Bedienung kann optional auch über ein Netzwerk-Patchkabel mit einem Zentralrechner verbunden werden, wenn er nicht unter dem Aquaruim-Deckel verbaut werden soll.&lt;br /&gt;
&lt;br /&gt;
Im einachsten Fall reicht ein vieradriges Patch-Kabel, bei dem lediglich die PINs 1, 2, 3 und 6 belegt sind:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Die Pinbelegung:&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
! Pin || Signal || Kommentar&lt;br /&gt;
|-&lt;br /&gt;
| 1  || +5V || Spannungsversorgung für LEDs und PCF8574&lt;br /&gt;
|-&lt;br /&gt;
| 2 || SDA || I²C-Bus Daten&lt;br /&gt;
|-&lt;br /&gt;
| 3 || SCK || I²C-Bus Takt&lt;br /&gt;
|-&lt;br /&gt;
| 4 || PWM 1 || PWM-Signal für das EVG (optional)&lt;br /&gt;
|-&lt;br /&gt;
| 5 || INT || I²C-Bus-Interrupt (optional)&lt;br /&gt;
|-&lt;br /&gt;
| 6 || GND || Signal- und Versorgungs-Masse&lt;br /&gt;
|-&lt;br /&gt;
| 7 || +12V || 12V für Mondlicht (optional)&lt;br /&gt;
|-&lt;br /&gt;
| 8 || PWM 2 || PWM-Signal für Mondlicht (optional)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Mondlicht (optional) ==&lt;br /&gt;
&lt;br /&gt;
Auf der Rückseite der Mini-Bedienung ist optional eine LED (&amp;quot;High Power 1W Emitter&amp;quot;) bestückbar. Wer nachts die Leuchtstofflampen ganz ausschalten möchte, kann dieses Mondlicht aktivieren. Über einen PWM-Ausgang des Mikrokontrollers ist es ebenfalls dimmbar.&lt;br /&gt;
&lt;br /&gt;
Wenn über PIN 7 (s.o.) 12 V eingespeist werden, kann auch eine 12V LED-Leiste angeschlossen werden.&lt;br /&gt;
&lt;br /&gt;
== Menü-Bedienteil (optional) ==&lt;br /&gt;
&lt;br /&gt;
Wem die &#039;&#039;spartanische&#039;&#039; Mini-Bedienung mit drei Tasten und einer LED zu primitiv ist, kann auch ein entsprechnd teureres Bedienteil mit Display und einem Dreh-Drückgeber für eine Menü-Bedienung anschließen. Dazu stehen verschiedene Displays zur Auswahl:&lt;br /&gt;
&lt;br /&gt;
http://www.mikrocontroller.net/attachment/149236/DOG.png&lt;br /&gt;
&lt;br /&gt;
Dieses Bedienteil kann entweder - wie die Mini-Bedienung (s.o.) - in den Kunststoff-Deckel des Aquariums eingebaut werden oder zusammen mit dem Zentralrechner in einem gemeinsamen Gehäuse untergebracht werden, so wie im µQuarium:&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/264084#2748460 Das µQuarium im Forum]&lt;br /&gt;
* Artikel [[Aquariumsteuerung µQuarium]]&lt;br /&gt;
&lt;br /&gt;
Über die bequeme Menü-Bedienung mit Softkeys und Dreh-Drück-Geber sind weitere Funktionen direkt am Gerät bequem bedienbar, ohne dass über USB ein Rechner angeschlossen werden muss. Darüber hinaus werden Temperatur und andere Werte im Klartext angezeigt.&lt;br /&gt;
&lt;br /&gt;
Unter dem Display befinden sich vier sog. &amp;quot;Softkeys&amp;quot; die am unteren Rand des Displays beschriftet sind. Im Bild sind das z.B.&lt;br /&gt;
&lt;br /&gt;
* Tageslicht&lt;br /&gt;
* Mondlicht&lt;br /&gt;
* Wasserpumpe&lt;br /&gt;
* Luftpumpe&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Dieser Hardware-Teil ist noch nicht detaillierter ausgeplant, Diskussionen sind erwünscht.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Temperaturalarm (optional) ==&lt;br /&gt;
&lt;br /&gt;
Optional kann am Zentralrechner ein Piezo-Summer für einen Temperaturalarm angeschlossen werden.&lt;br /&gt;
&lt;br /&gt;
== 230V Relaisbox (optional) ==&lt;br /&gt;
&lt;br /&gt;
Über einen [[Port-Expander_PCF8574]] und Halbleiterrelais ([http://www.mikrocontroller.net/part/S202S02 S202S02]) können Heizungen, Pumpen, Licht usw. geshaltet werden. Durch die Relais und die 230V-Steckverbindungen kommt man bei drei schaltbaren Steckdosen auf etwa 25€. Wer also kein Licht schalten muss und z.B. nur ein EVG für Leuchtstofflampen steuern will und wer eine z.B. eine 12V Heizfolie statt eines 230V Aquarium-Heizers verwendet, kann diese Kosten sparen.&lt;br /&gt;
&lt;br /&gt;
== Temperatursensoren (optional) ==&lt;br /&gt;
&lt;br /&gt;
Zur Messung der Temperaturen im Aquarium, Terrarium und der Umgebunstemperatur können mehrere [http://www.mikrocontroller.net/part/DS18B20 DS18B20] Sensoren angeschlossen werden. Als Steckverbindung kommen Cynch-Stecker zum Einsatz, da diese vergleichsweise preiswert sind (noch zu diskutieren).&lt;br /&gt;
&lt;br /&gt;
Anhand der Temperaturen kann z.B. mit einem 230V-Aquarium-Heizer oder mit 12V-Heizfolien die Temperatur geregelt werden.&lt;br /&gt;
&lt;br /&gt;
== EVG-Ansteuerung ==&lt;br /&gt;
&lt;br /&gt;
Wer sein Aquarium mit Leuchtstofflampen beleuchtet, setzt vielleicht ein elektronisches Vorschaltgerät als Dimmer ein. Diese EVGs haben i.d.R. einen Analog-Eingang von 0..10V, über den sich die Helligkeit in Gewissen Grenzen einstellen läßt. Die EVG-Ansteuerung sorgt über einen Optokoppler und einen Tiefpass dafür, dass such der 0..10V-Eingang über einen PWM-Ausgang des Mikrocontrollers steuern läßt.&lt;br /&gt;
&lt;br /&gt;
[[Datei:Dsc_5939.jpg]]&amp;lt;br/&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Ein EVG (Leuchstofflampen-Dimmer). Die oberen Pins (+DC und -DC) sind die 10V Analog-Eingänge.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Wer die Leuchtstofflampen nachts nicht nur auf ein Minimum abdunkeln, sondern ausschalten will, benötigt entweder ein geeignetes EVG oder nutzt die 230V Relaisbox (s.o.), um das Licht nachts ganz auszuschalten.&lt;br /&gt;
&lt;br /&gt;
== Heizfolie und Ansteuerung (optional) ==&lt;br /&gt;
&lt;br /&gt;
Heizfolie, 12V, 36W, 137x320 mm kostet ca. 6,50€. Mit zwei Heizfolien Mosfet-Transistoren und Steckverbindungen kommte man also auf ca. 13€ für eine 72W-Heizung, natürlich muss noch der Preis für ein entsprechend starkes 12V-Netzteil hinzugerechnet werden. Für den, der auf die teure 230V Relaisbox verzichten möchte, ist die Heizfolie eine interessante Alternative.&lt;br /&gt;
&lt;br /&gt;
= Software&amp;lt;ref name=&amp;quot;Stub&amp;quot; /&amp;gt; =&lt;br /&gt;
&lt;br /&gt;
= Konzeption =&lt;br /&gt;
&lt;br /&gt;
== Ideen, Anforderungen, Vorschläge ==&lt;br /&gt;
&lt;br /&gt;
Die folgenden gesammelten Anforderungen sind noch nicht priorisiert oder bewertet (To do):&lt;br /&gt;
&lt;br /&gt;
=== Funktionen ===&lt;br /&gt;
* Temperaturmessung&amp;lt;ref name=&amp;quot;ref_Aquarium-Steuerung&amp;quot;&amp;gt;Siehe auch [http://www.mikrocontroller.net/articles/Aquarium-Steuerung Artikel &amp;quot;Aquarium-Steuerung&amp;quot; im Wiki]&amp;lt;/ref&amp;gt;&lt;br /&gt;
* Tageshelligkeit abhängig von Sonnenauf- und –untergang&amp;lt;ref name=&amp;quot;ref_Aquarium-Steuerung&amp;quot; /&amp;gt;&lt;br /&gt;
* Nachthelligkeit abhängig von Mondphase&amp;lt;ref name=&amp;quot;ref_Aquarium-Steuerung&amp;quot; /&amp;gt;&lt;br /&gt;
* Ausgaben, Anzeigen und Einstellen von Parametern&amp;lt;ref name=&amp;quot;ref_Aquarium-Steuerung&amp;quot; /&amp;gt; sowie Debugging&amp;lt;ref name=&amp;quot;ref_Aquarium_Controller&amp;quot; /&amp;gt; per USB oder RS232 mit einem PC&lt;br /&gt;
* Grenzwerte für Maximal- und Minimaltemperaturen einstellbar&amp;lt;ref name=&amp;quot;ref_123551&amp;quot; /&amp;gt;&lt;br /&gt;
* PWM-Ansteuerung einer LED-Leiste (12V) für Nachtlicht&amp;lt;ref name=&amp;quot;ref_Aquarium_Controller&amp;quot;&amp;gt;Siehe auch [http://www.mikrocontroller.net/articles/Aquarium_Controller Artikel &amp;quot;Aquarium Controller&amp;quot; im Wiki]&amp;lt;/ref&amp;gt;&lt;br /&gt;
* Messwert einer pH-Elektrode erfassen&amp;lt;ref name=&amp;quot;ref_123551&amp;quot; /&amp;gt;&lt;br /&gt;
* Dimmbare Leuchtstoffröhren für Taglicht ansteuern&amp;lt;ref name=&amp;quot;ref_123551&amp;quot; /&amp;gt;&amp;lt;ref name=&amp;quot;ref_Aquarium_Controller&amp;quot; /&amp;gt;&lt;br /&gt;
* Alarmbeeper z.B. bei Übertemperatur ansteuern&amp;lt;ref name=&amp;quot;ref_123551&amp;quot; /&amp;gt;&lt;br /&gt;
* Alarm-Dauer und –Wiederholzeit einstellbar&amp;lt;ref name=&amp;quot;ref_Aquarium_Controller&amp;quot; /&amp;gt;&lt;br /&gt;
* DCF77 als Zeitreferenz empfangen &amp;lt;ref name=&amp;quot;ref_123551&amp;quot;&amp;gt;Siehe auch [http://www.mikrocontroller.net/topic/123551 Thread &amp;quot;Aquarium Controller&amp;quot; in &amp;quot;Codesammlung&amp;quot;]&amp;lt;/ref&amp;gt;&lt;br /&gt;
* LCD-Anzeige&amp;lt;ref name=&amp;quot;ref_Aquarium-Steuerung&amp;quot; /&amp;gt;&lt;br /&gt;
* CO&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;-Zufuhr ein- bzw. ausschalten, abhängig vom PH-Wert&amp;lt;ref name=&amp;quot;ref_Aquarium_Controller&amp;quot; /&amp;gt;&amp;lt;ref name=&amp;quot;ref_technik&amp;quot; /&amp;gt;&lt;br /&gt;
* Heizung schalten bzw. regeln&amp;lt;ref name=&amp;quot;ref_Aquarium_Controller&amp;quot; /&amp;gt;&lt;br /&gt;
* Luftpumpe schalten bzw. regeln&amp;lt;ref name=&amp;quot;ref_Aquarium_Controller&amp;quot; /&amp;gt;&lt;br /&gt;
* Begradigung der Sensor-Kennlinien und Abgleich&amp;lt;ref name=&amp;quot;ref_Aquarium_Controller&amp;quot; /&amp;gt;(Temperatur, pH, …)&lt;br /&gt;
* Lüfter zur Temperaturabsenkung&lt;br /&gt;
* Haubenöffnung zur Temperaturabsenkung&lt;br /&gt;
* Unterstützung beim Wasserwechsel: Berechnung und Anzeige der erforderlichen Mengen von Warm/Kalt und Regenwasser zum Wasser nachfüllen&amp;lt;ref name=&amp;quot;ref_209240&amp;quot; /&amp;gt; nach dem teilweisen Absaugen&lt;br /&gt;
* Datenaufzeichnung auf SD-Card oder USB-Stick&lt;br /&gt;
* Konfiguration des AqauPIC mit individuellen Einstellungen für das jeweilige Aquarium ohne gesonderte Applikation, z.B. über http&lt;br /&gt;
* Wlan Anbindung&lt;br /&gt;
* Nagios Plugin (snmp, Alarme per snmp trap schicken)&lt;br /&gt;
&lt;br /&gt;
=== offene Punkte ===&lt;br /&gt;
* Welche Temperatursensoren? Z.B. DS18B20&amp;lt;ref name=&amp;quot;ref_Aquarium-Steuerung&amp;quot; /&amp;gt;&amp;lt;ref name=&amp;quot;ref_features&amp;quot;&amp;gt;[http://web.archive.org/web/20080927142817/http://www.diskusportal.de/ratgeber/aquapic/features Siehe auch ehemalige Internetseite &amp;quot;AquaPic - Features&amp;quot;]&amp;lt;/ref&amp;gt;, NTC Epcos B57861S0103&amp;lt;ref name=&amp;quot;ref_123551&amp;quot; /&amp;gt;&amp;lt;ref name=&amp;quot;ref_Aquarium_Controller&amp;quot; /&amp;gt;, Digitale Temperaturfühler&amp;lt;ref name=&amp;quot;ref_technik&amp;quot;&amp;gt;[http://web.archive.org/web/20080927142910/http://www.diskusportal.de/ratgeber/aquapic/technik Siehe auch ehemalige Internetseite &amp;quot;AquaPic - Technische Angaben&amp;quot;]&amp;lt;/ref&amp;gt;, …&lt;br /&gt;
* Wie die Sensoren abdichten? Z.B. Glasrohr &amp;amp; Aquariumsilikon oder Aquarien-Luftschlauch&amp;lt;ref name=&amp;quot;ref_123551&amp;quot; /&amp;gt;&lt;br /&gt;
* Welches Gehäuse? Z.B. PVC-Platten&amp;lt;ref name=&amp;quot;ref_123551&amp;quot; /&amp;gt;, …&lt;br /&gt;
* Welcher Luftdrucksensor? Z.B. z.B. MPX4115A&amp;lt;ref name=&amp;quot;ref_123551&amp;quot; /&amp;gt;&lt;br /&gt;
* Unterschiede zu einer Terrariensteuerung?&amp;lt;ref name=&amp;quot;ref_123551&amp;quot; /&amp;gt;&lt;br /&gt;
* Welche pH-Sonde? &amp;lt;ref name=&amp;quot;ref_Aquarium_Controller&amp;quot; /&amp;gt;&lt;br /&gt;
* Welches Netzteil? Reicht ein USB-Ladegerät? Woher 12V für LED-Leiste oder Niedervolt-Heizung?&lt;br /&gt;
* Wie werden die 230V-Verbraucher angeschlossen? Z.B. über eingebaute Steckdosen?&amp;lt;ref name=&amp;quot;ref_Aquarium_Controller&amp;quot; /&amp;gt;&lt;br /&gt;
* Wie wird DCF77 empfangen? Z.B. mit dem Empfänger aus Elrad 7/8 &#039;85? &amp;lt;ref name=&amp;quot;ref_Aquarium_Controller&amp;quot; /&amp;gt;&lt;br /&gt;
* Welche Enstörmaßnahmen sind z.B. an Schaltkontakten von Relais erforderlich?&amp;lt;ref name=&amp;quot;ref_Aquarium_Controller&amp;quot; /&amp;gt;&lt;br /&gt;
* Wie wird der Füllstand gemessen?&amp;lt;ref name=&amp;quot;ref_209240&amp;quot;&amp;gt;Siehe auch [http://www.mikrocontroller.net/topic/209240 Thread &amp;quot;Füllstandsmessung im Aquarium&amp;quot; in &amp;quot;µC &amp;amp; Elektronik&amp;quot;]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== ToDo ===&lt;br /&gt;
* nach „nach pH 58mV“ googeln&amp;lt;ref name=&amp;quot;ref_123551&amp;quot; /&amp;gt;&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/99605 Thread &amp;quot;Heizfolie …&amp;quot; in &amp;quot;Platinen&amp;quot;] durchlesen&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/123388 Thread &amp;quot;Aquarium Steuerung&amp;quot; in &amp;quot;µC &amp;amp; Elektronik&amp;quot;] durchlesen&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/206432 Thread &amp;quot;… CO2 Regelung …&amp;quot; in &amp;quot;µC &amp;amp; Elektronik&amp;quot;] durchlesen&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/120980 Thread &amp;quot;… Bodenheizung …&amp;quot; in &amp;quot;µC &amp;amp; Elektronik&amp;quot;] durchlesen&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/17707 Thread &amp;quot;Sensoren …&amp;quot; in &amp;quot;µC &amp;amp; Elektronik&amp;quot;] durchlesen&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/148959 Thread &amp;quot;CO2 Messung …&amp;quot; in &amp;quot;µC &amp;amp; Elektronik&amp;quot;] durchlesen&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/67801 Thread &amp;quot;Temperatursteuerung …&amp;quot; in &amp;quot;µC &amp;amp; Elektronik&amp;quot;] durchlesen&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/91702 Thread &amp;quot;Nitrit-Gehalt … ermitteln&amp;quot; in &amp;quot;µC &amp;amp; Elektronik&amp;quot;] durchlesen&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/219796 Thread &amp;quot;… Kühlung …&amp;quot; in &amp;quot;µC &amp;amp; Elektronik&amp;quot;] durchlesen&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/30128 Thread &amp;quot;pH-Wert … erfassen …&amp;quot; in &amp;quot;µC &amp;amp; Elektronik&amp;quot;] durchlesen&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/3512 Thread &amp;quot;Pegelmessung, Idee gesucht&amp;quot; in &amp;quot;µC &amp;amp; Elektronik&amp;quot;] durchlesen&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/152017 Thread &amp;quot;Mondlicht Steuerung&amp;quot; in &amp;quot;µC &amp;amp; Elektronik&amp;quot;] durchlesen&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/131522 Thread &amp;quot;OPV 1:10 PH Elektrode …&amp;quot; in &amp;quot;µC &amp;amp; Elektronik&amp;quot;] durchlesen&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/99828 Thread &amp;quot;Zeitschaltuhr und Temperaturregelung&amp;quot; in &amp;quot;µC &amp;amp; Elektronik&amp;quot;] durchlesen&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/13115 Thread &amp;quot;Aquariensteuerung&amp;quot; in &amp;quot;µC &amp;amp; Elektronik&amp;quot;] durchlesen&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/66321 Thread &amp;quot;Erstes Projket für Studium&amp;quot; in &amp;quot;µC &amp;amp; Elektronik&amp;quot;] durchlesen&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/180966 Thread &amp;quot;MwAquarium LED Beleuchtung&amp;quot; in &amp;quot;µC &amp;amp; Elektronik&amp;quot;] durchlesen&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/191644 Thread &amp;quot;Spulen für Induktionsladung&amp;quot; in &amp;quot;µC &amp;amp; Elektronik&amp;quot;] durchlesen&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/245384 Thread &amp;quot;RGBW-Controller&amp;quot; in &amp;quot;µC &amp;amp; Elektronik&amp;quot;] durchlesen&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/113675 Thread &amp;quot;Allgemeine Probleme mit dem ADC pH-Wert Messen&amp;quot; in &amp;quot;µC &amp;amp; Elektronik&amp;quot;] durchlesen&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/150179 Thread &amp;quot;Eigenbau Füllstandsmesser&amp;quot; in &amp;quot;µC &amp;amp; Elektronik&amp;quot;] durchlesen&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/188123 Thread &amp;quot;12 kanal PWM?&amp;quot; in &amp;quot;µC &amp;amp; Elektronik&amp;quot;] durchlesen&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/233043 Thread &amp;quot;(Aquariencomputer) Zeitschaltuhr mit mehreren Kanälen&amp;quot; in &amp;quot;µC &amp;amp; Elektronik&amp;quot;] durchlesen&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/249309 Thread &amp;quot;Temperatursteuerung für Aquarienanlage&amp;quot; in &amp;quot;µC &amp;amp; Elektronik&amp;quot;] durchlesen&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/96297 Thread &amp;quot;Peltier-Element dimensionieren&amp;quot; in &amp;quot;µC &amp;amp; Elektronik&amp;quot;] durchlesen&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/252438 Thread &amp;quot;Getting Startet - Anfänger Start&amp;quot; in &amp;quot;µC &amp;amp; Elektronik&amp;quot;] durchlesen&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/211641 Thread &amp;quot;LED wasserfest abdichten&amp;quot; in &amp;quot;µC &amp;amp; Elektronik&amp;quot;] durchlesen&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/132565 Thread &amp;quot;Ozonator spinnt&amp;quot; in &amp;quot;µC &amp;amp; Elektronik&amp;quot;] durchlesen&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/Wasser Artikel &amp;quot;Wasser&amp;quot; im Wiki] durchlesen&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/149411 Thread &amp;quot;Anschluss von Unterwasserleuchten&amp;quot; in &amp;quot;µC &amp;amp; Elektronik&amp;quot;] durchlesen&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/99824 Thread &amp;quot;Aquariensteuerung?&amp;quot; in &amp;quot;µC &amp;amp; Elektronik&amp;quot;] durchlesen&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/224436 Thread &amp;quot;Dosieranlage über AVR Mega8&amp;quot; in &amp;quot;µC &amp;amp; Elektronik&amp;quot;] durchlesen&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/243149 Thread &amp;quot;Ledstreifen mit int. Konstantstromquelle per PWM dimmen ?&amp;quot; in &amp;quot;µC &amp;amp; Elektronik&amp;quot;] durchlesen&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/120609 Thread &amp;quot;pH Wert ändert sich bei eingeschalteter Aquarienbeleuchtung&amp;quot; in &amp;quot;µC &amp;amp; Elektronik&amp;quot;] durchlesen&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/198143 Thread &amp;quot;Zeitgesteuerter Aquariumdimmer&amp;quot; in &amp;quot;µC &amp;amp; Elektronik&amp;quot;] durchlesen&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/171434 Thread &amp;quot;Überfüllsicherung für Salzwasseraquarium&amp;quot; in &amp;quot;µC &amp;amp; Elektronik&amp;quot;] durchlesen&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/249674 Thread &amp;quot;PH Elektrode Filterung&amp;quot; in &amp;quot;µC &amp;amp; Elektronik&amp;quot;] durchlesen&lt;br /&gt;
;Versuchen, Unterlagen zum AquaPic zu bekommen:&lt;br /&gt;
* Dokumentation und Bedienungsanleitung&lt;br /&gt;
* Bestückungsplan und Bauteilliste&lt;br /&gt;
* Anleitung für den Umbau der Steckdosenleiste&lt;br /&gt;
* Schaltplan für den AquaPic&lt;br /&gt;
* Schaltplan für die Schaltsteckdosen&lt;br /&gt;
* Beschreibung der AquaPic Hardware&lt;br /&gt;
* Beschaltung der Ausgänge vom AquaPic&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Hardware-Design&amp;lt;ref name=&amp;quot;Stub&amp;quot; /&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
=== Software-Entwicklung&amp;lt;ref name=&amp;quot;Stub&amp;quot; /&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
= Downloads&amp;lt;ref name=&amp;quot;Stub&amp;quot; /&amp;gt; =&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Aquaristik]]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Platinensammler&amp;diff=68996</id>
		<title>Platinensammler</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Platinensammler&amp;diff=68996"/>
		<updated>2012-11-04T21:09:07Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: Tippfehler behoben&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Einleitung &amp;amp; Generelles ==&lt;br /&gt;
Der Traum eines jeden Elektrotechnik-Hobbyisten ist wohl ein selbst entworfenes PCB. Oft scheitert eine saubere Realisierung jedoch an der Fertigung der Leiterplatte. Hobbymittel wie die Direkttonermethode führen oft nur zu unzureichend sauberen Ergebnissen, Doppelseitige Platinen sind nur schwer sauber zu realisieren, ganz zu schweigen von Multilayerplatinen (&amp;gt;2 Layer). Eine vernünftige Ausrüstung zum Belichten ist teuer und so mancher Bastler hat auch schlicht und ergreifend nicht die Möglichkeit zum Umgang mit Entwicklern, Ätzmitteln, usw. Egal ob man nun die Platinen nicht fertigen kann oder möchte besteht immer die Möglichkeit diese bei den Platinenherstellern (professionell) produzieren zu lassen. Das ist allerdings oft mit nicht unerheblichen Kosten und einem Mindestnutzen verbunden, gerade wenn nur einzelne kleine Platinen bernötigt werden.&lt;br /&gt;
&lt;br /&gt;
Aus diesem Grunde bietet ein User hier im Forum freundlicher Weise die Möglichkeit zur Mitbestellung an. Jakob Kleinen alias &amp;quot;jakobk&amp;quot; führt fortlaufend Sammelbestellungen durch, an die sich jeder &amp;quot;anhängen&amp;quot; kann. &lt;br /&gt;
&lt;br /&gt;
Der Preis wird abhängig von der genutzten, genauer gesagt von der im Nutzen benötigten Fläche, berechnet. Denn um die einzelnen Layouts vereinzeln zu können muss ein umlaufender 3mm Fräsgraben zur eigentlichen Leiterkartenkontur zugerechnet werden.&lt;br /&gt;
&lt;br /&gt;
d.h. wenn eine Platine 3x2cm groß ist, wird eine Fläche 3,6cm x 2,6cm also 9,36cm² berechnet.&lt;br /&gt;
&lt;br /&gt;
Das gilt sowohl für 2- als auch für 4-Lagige Layouts.&lt;br /&gt;
&lt;br /&gt;
Beide Nutzen werden immer mit E-Test, HAL-Verzinnung (RoHS), Stoplack auf beiden Seiten und Bestückungsdruck auf der Oberseite bestellt. &lt;br /&gt;
&lt;br /&gt;
Wer keinen Bestückungsdruck haben möchte, kann dies im Bestellformular vermerken. Dann lösche ich die entsprechende Lage aus dem Datensatz. &lt;br /&gt;
&lt;br /&gt;
Der Preis bleibt jedoch der gleiche.&lt;br /&gt;
&lt;br /&gt;
== Der 2lagige Nutzen ==&lt;br /&gt;
Der 2lagige Nutzen wird in 2x 35µm Kupfer auf 1,55 mm FR4 bestellt.&lt;br /&gt;
&lt;br /&gt;
Für diesen Nutzen berechnet sich der Preis gestaffelt. d.h die erste Platine eines Layouts kostet 30ct/cm². Jede weitere des gleichen Layouts kostet noch 20ct/cm² und überproduzierte Platinen nur noch 10ct/cm² (Überproduktion ist zufällig und nicht vorhersagbar)&lt;br /&gt;
&lt;br /&gt;
== Preis ==&lt;br /&gt;
Der Preis berechnet sich immer nach der im Nutzen benötigten Fläche.&lt;br /&gt;
&lt;br /&gt;
Um bei dem o.g. Beispiel der 3cm x 2cm großen Platine zu bleiben:&lt;br /&gt;
&lt;br /&gt;
Die 1. Platine kommt auf 9,36cm² x 0,30€/cm² = 2,81€&lt;br /&gt;
&lt;br /&gt;
Wenn man beispielsweise insgesamt 3 Platinen plus Überproduzierte bestellen würde, kommen die 2. und 3. Platine auf je 9,36cm² x 0,20€/cm² = 1,87€.&lt;br /&gt;
&lt;br /&gt;
Die Überproduzierten gäbe es für 9,36cm² x 0,10€/cm² = 0,94€ dazu. Zu den überproduzierten sei gesagt, dass bei kleinen Platinen bis zu 2x so viele Überproduzierte kommen, wie eigentlich bestellt wurden. Aber darauf verlassen kann man sich halt nicht.&lt;br /&gt;
&lt;br /&gt;
Zu den eigentlichen Platinenkosten kommen dann noch Versandkosten dazu, die ich weiter unten erkläre.&lt;br /&gt;
&lt;br /&gt;
==== Designregeln ====&lt;br /&gt;
Um mit in den Nutzen zu können müssen eure Layouts den folgenden &lt;br /&gt;
Designregeln entsprechen:&lt;br /&gt;
&lt;br /&gt;
* Leitbahnstärke und -abstand     0,15mm&lt;br /&gt;
* mind. Bohrdurchmesser           0,3 mm&lt;br /&gt;
* mind. Abstand Kupfer zu Kontur  0,2 mm&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Eagle Design Rule (*.dru): &lt;br /&gt;
&lt;br /&gt;
http://www.mikrocontroller.net/attachment/132705/platinensammler_02.dru&lt;br /&gt;
&lt;br /&gt;
==== Bestellablauf ====&lt;br /&gt;
Die geprüften Layoutdaten (*.dru File siehe Designregeln oder hier http://www.mikrocontroller.net/attachment/132705/platinensammler_02.dru ) schickt ihr dann bitte zusammen mit dem ausgefüllten Bestellformular ( http://www.mikrocontroller.net/attachment/132047/Bestellformular.txt ) an &#039;&#039;&#039; platinensammler(at)gmail.com &#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Bitte beachtet, dass ich nur vollständige Bestellungspakete &lt;br /&gt;
berücksichten kann (auch die Wiederbesteller bitte). Außerdem solltet &lt;br /&gt;
ihr mir bitte keine &amp;quot;Schnellschüsse&amp;quot; mit &amp;quot;Schönheitsfehlern schicken, &lt;br /&gt;
die ihr dann noch drei mal bis zum Stichtag nachbessert.&lt;br /&gt;
&lt;br /&gt;
Wenn sich jemand nicht sicher ist, ob sein Layout produzierbar ist, &lt;br /&gt;
schaue&lt;br /&gt;
ich gerne vorab unverbindlich drüber. Grade bei Layoutneulingen kann das&lt;br /&gt;
schon mal ganz nützlich sein, um grobe Fehler zu vermeiden und um ggf.&lt;br /&gt;
Unsicherheit entgegen zu wirken.&lt;br /&gt;
&lt;br /&gt;
Sobald ich die Daten geprüft und in den Nutzen übernommen habe, &lt;br /&gt;
bestätige ich die Bestellung per Mail. In dieser Mail steht dann eure &lt;br /&gt;
Adresse sowie Anzahl, Größe und Kosten eurer Platinen. Wenn ich nichts &lt;br /&gt;
von euch höre gehe ich davon aus, dass ich eure Bestellung richtig &lt;br /&gt;
übernommen habe. (Auch wenn ich mich über eine kurze Bestätigung freue)&lt;br /&gt;
&lt;br /&gt;
Ich sammle laufend Layouts und warne im Forum wenn ein Nutzen zu 50%, 80% und 100% voll ist.&lt;br /&gt;
&lt;br /&gt;
Spätestens zu den Warnungen sollte jeder, der mir Daten geschickt hat auch seine Auftragsbestätigung haben. Wenn das nicht der Fall ist, bitte melden.&lt;br /&gt;
&lt;br /&gt;
Sobald ein Nutzen voll ist, gebe ich ihn in die Fertigung und sammle direkt für den neuen Nutzn weiter.&lt;br /&gt;
&lt;br /&gt;
Wenn ein produzierter Nutzen bei mir ist, drösel ich den auseinander, gebe die Teilbestellungen in die Post und verschicke die Rechungen.&lt;br /&gt;
&lt;br /&gt;
Wer mag kann auch per Paypal bezahlen. Dann kommen zwar noch die &lt;br /&gt;
Gebühren in Höhe von 0,35€ + 1,9% des Rechnungswerts mit auf die &lt;br /&gt;
Rechnung, aber grade bei Bestellungen aus dem Ausland kann das evtl. &lt;br /&gt;
günstiger sein als die Auslandsüberweisungsgebühren.&lt;br /&gt;
&lt;br /&gt;
==== Dateiformate ====&lt;br /&gt;
&lt;br /&gt;
Ihr könnt mir eure Layoutdaten in den folgenden Formaten mailen.&lt;br /&gt;
* Eagle brd-file&lt;br /&gt;
* KiCad brd-file&lt;br /&gt;
* RS-274-X (Extended Gerber) / Excellon&lt;br /&gt;
&lt;br /&gt;
Bei den Extended Gerber und Excellon Daten müssen eure Daten die folgenden Endungen für die Lagen zuordnung haben:&lt;br /&gt;
* Kontur                            - *.l00&lt;br /&gt;
* Stoplack Lötseite (Unten)         - *.l02&lt;br /&gt;
* Kupfer Lötseite                   - *.l03&lt;br /&gt;
* Kupfer Bestückungsseite (Oben)    - *.l06&lt;br /&gt;
* Stoplack Bestückungsseite         - *.l07&lt;br /&gt;
* Bestückungsdruck Bestückungsseite - *.l08&lt;br /&gt;
&lt;br /&gt;
* durchkontaktierte Bohrungen       - *.dk&lt;br /&gt;
* nicht durchkontaktierte Bohrungen - *.ndk&lt;br /&gt;
&lt;br /&gt;
Außerdem müssen sie der folgenden Formatierung entsprechen:&lt;br /&gt;
&lt;br /&gt;
Gerber&lt;br /&gt;
* Format          : metric&lt;br /&gt;
* Integer Digits  : 2&lt;br /&gt;
* Decimal Digits  : 4&lt;br /&gt;
* Type            : absolute&lt;br /&gt;
* Zero Suppressing: leading&lt;br /&gt;
&lt;br /&gt;
Excellon&lt;br /&gt;
* Format          : metric&lt;br /&gt;
* Integer Digits  : 2&lt;br /&gt;
* Decimal Digits  : 4&lt;br /&gt;
* Type            : absolute&lt;br /&gt;
* Zero Suppressing: none&lt;br /&gt;
&lt;br /&gt;
=== Multilayerleiterkarten für 60ct/cm² ===&lt;br /&gt;
&lt;br /&gt;
Aber es gibt auch immer mal wieder die Frage nach Multilayern, der ich &lt;br /&gt;
hiermit nun nachkommen möchte.&lt;br /&gt;
&lt;br /&gt;
Ich bestelle den Nutzen mit E-Test, HAL-Verzinnung (RoHS), Stoplack auf beiden Seiten und Bestückungsdruck auf der Oberseite.&lt;br /&gt;
&lt;br /&gt;
==== Designregeln ====&lt;br /&gt;
Technisch gelten die folgenden Designregeln:&lt;br /&gt;
* Leitbahnstärke und -abstand     0,15mm&lt;br /&gt;
* mind. Bohrdurchmesser           0,3 mm&lt;br /&gt;
* mind. Abstand Kupfer zu Kontur  0,2 mm&lt;br /&gt;
&lt;br /&gt;
==== Aufbau der Platine ====&lt;br /&gt;
&lt;br /&gt;
Der Lagenaufbau sieht wie folgt aus: (Für Eagler hängt auch das dru-file &lt;br /&gt;
an)&lt;br /&gt;
&lt;br /&gt;
Top: ---][----   &amp;lt;--  18  µm Cu      &amp;lt;-- *.L06&lt;br /&gt;
&lt;br /&gt;
FR4: ===][====   &amp;lt;-- 355,6µm FR4&lt;br /&gt;
&lt;br /&gt;
IN2: ---][----   &amp;lt;--  35  µm Cu      &amp;lt;-- *.L05&lt;br /&gt;
&lt;br /&gt;
FR4: ===][====   &amp;lt;-- 760  µm FR4&lt;br /&gt;
&lt;br /&gt;
IN1: ---][----   &amp;lt;--  35  µm Cu      &amp;lt;-- *.L04&lt;br /&gt;
&lt;br /&gt;
FR4: ===][====   &amp;lt;-- 355,6µm FR4&lt;br /&gt;
&lt;br /&gt;
Bot: ---][----   &amp;lt;--  18  µm Cu      &amp;lt;-- *.L03&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Also kommt man auf eine LP-Dicke von rund 1,6mm&lt;br /&gt;
&lt;br /&gt;
==== Dateiformate ====&lt;br /&gt;
&lt;br /&gt;
Wer Eagle und KiCad kann ich direkt verhackstücken. Wenn jemand ein &lt;br /&gt;
anderes Layoutprogramm benutzt, brauche ich bitte Gerber und &lt;br /&gt;
Excellonfiles.&lt;br /&gt;
&lt;br /&gt;
Bei den Extended Gerber und Excellon Daten müssen eure Daten die&lt;br /&gt;
folgenden Endungen für die Lagen zuordnung haben:&lt;br /&gt;
* Kontur                            - *.L00&lt;br /&gt;
* Stoplack Lötseite (Unten)         - *.L02&lt;br /&gt;
* Kupfer Lötseite                   - *.L03&lt;br /&gt;
* Kupfer Innen 1 (untere Lage       - *.L04&lt;br /&gt;
* Kupfer Innen 2 (obere Lage        - *.L04&lt;br /&gt;
* Kupfer Bestückungsseite (Oben)    - *.L06&lt;br /&gt;
* Stoplack Bestückungsseite         - *.L07&lt;br /&gt;
* Bestückungsdruck Bestückungsseite - *.L08&lt;br /&gt;
&lt;br /&gt;
* durchkontaktierte Bohrungen       - *.dk&lt;br /&gt;
* nicht durchkontaktierte Bohrungen - *.ndk&lt;br /&gt;
&lt;br /&gt;
Außerdem müssen sie der folgenden Formatierung entsprechen:&lt;br /&gt;
&lt;br /&gt;
Gerber&lt;br /&gt;
* Format          : metric&lt;br /&gt;
* Integer Digits  : 2&lt;br /&gt;
* Decimal Digits  : 4&lt;br /&gt;
* Type            : absolute&lt;br /&gt;
* Zero Suppressing: leading&lt;br /&gt;
&lt;br /&gt;
Excellon&lt;br /&gt;
* Format          : metric&lt;br /&gt;
* Integer Digits  : 2&lt;br /&gt;
* Decimal Digits  : 4&lt;br /&gt;
* Type            : absolute&lt;br /&gt;
* Zero Suppressing: none&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Preise ====&lt;br /&gt;
&lt;br /&gt;
Jeder Quadratzentimeter eines Layouts kostet&lt;br /&gt;
60ct/cm².&lt;br /&gt;
&lt;br /&gt;
Überproduzierte Platinen könnt ihr für 30ct/cm² bekommen.&lt;br /&gt;
&lt;br /&gt;
Basis für die Preisberechnung ist die tatsächliche Platinenfläche&lt;br /&gt;
zzgl. einem 3mm breiten umlaufenden Fräsgraben.&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
Ihr braucht zwei Platine, die 3x2cm groß ist (ungefähr ein DIP28 &lt;br /&gt;
Gehäuse) und nehmt bis zu 2 überproduzierte dazu (&lt;br /&gt;
man kann sich ja mal total beim Bestücken verhauen oder ein Kollege&lt;br /&gt;
findet das Platinchen ganz toll ..)&lt;br /&gt;
&lt;br /&gt;
Dann ergeben sich die Kosten für diese Bestellung wie folgt:&lt;br /&gt;
&lt;br /&gt;
* Berechnete Fläche = (3 + 0,6) cm * (2 + 0,6) cm = 9,36 cm²&lt;br /&gt;
&lt;br /&gt;
*  Die Zwei mindestens benötigenten (Mindestmenge) 9,36 cm² x 0,60 €/cm² &lt;br /&gt;
= 5,62 €/Stk&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Die überproduzierten Platinen kommen dann nur noch auf 9,36 cm² x &lt;br /&gt;
0,30 €/cm² = 2,81€&lt;br /&gt;
&lt;br /&gt;
=&amp;gt; Alle Platinen kommen dann also zusammen auf:&lt;br /&gt;
        2 x 5,62 € : 11,24 €&lt;br /&gt;
        2 x 2,81 € :  5,62 €&lt;br /&gt;
        -------------------&lt;br /&gt;
                     16,86 € (inkl. MwSt. zzgl. Verpackung und Versand)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Bestellablauf &amp;amp; Versand ====&lt;br /&gt;
siehe &amp;quot;normale&amp;quot; Platinen (oben)&lt;br /&gt;
==== Multilayer-FAQ ====&lt;br /&gt;
&lt;br /&gt;
* Sind auch &amp;quot;buried vias&amp;quot;, &amp;quot;blind vias&amp;quot; möglich? - es sind leider keine buried oder blind vias möglich&lt;br /&gt;
&lt;br /&gt;
== FAQ ==&lt;br /&gt;
* Ist der Preis von 60 ct/cm² inkl. Mwst? - Die Preise verstehen sich inkl. Mwst und die wird auch auf einer Rechnung ausgewiesen.&lt;br /&gt;
&lt;br /&gt;
* Lieferung in die Schweiz ist kein Problem. Porto waren glaube ca 3.80€&lt;br /&gt;
&lt;br /&gt;
== Bestellungen ==&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
* http://www.mikrocontroller.net/topic/245590 (30ct)&lt;br /&gt;
* http://www.mikrocontroller.net/topic/273018 (60ct)&lt;br /&gt;
* http://www.mikrocontroller.net/topic/245595 (Feedback)&lt;br /&gt;
* http://www.mikrocontroller.net/topic/245594 (FAQ)&lt;br /&gt;
* http://www.mikrocontroller.net/articles/Platinenhersteller &lt;br /&gt;
* http://www.platinensammler.de/&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Platinen]]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32&amp;diff=68925</id>
		<title>STM32</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32&amp;diff=68925"/>
		<updated>2012-11-01T19:47:02Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: /* Vorteile */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;STM32 ist ein Mikrocontroller-Familie von [http://www.st.com/mcu/inchtml-pages-stm32.html ST] mit einer 32-Bit [http://www.arm.com/products/processors/cortex-m/index.php ARM Cortex-M3/M4] CPU. Diese Architektur ist speziell für den Einsatz in Microcontrollern neu entwickelt und löst damit die bisherigen ARM7-basierten Controller weitestgehend ab. Den STM32 gibt es von ST in unzähligen Varianten mit variabler Peripherie und verschiedenen Gehäusegrößen und -formen. Durch die geringe Chipfläche des Cores ist es ST möglich, eine 32 Bit-CPU für weniger als 1&amp;amp;nbsp;€ anzubieten.&lt;br /&gt;
&lt;br /&gt;
[[Bild:stm32F103xc.png|thumb|right|340px|Blockdiagramm STM32F103xC/D/E]]&lt;br /&gt;
&lt;br /&gt;
== STM32-Familien ==&lt;br /&gt;
&lt;br /&gt;
Bisher gibt es sieben STM32-Familien:&lt;br /&gt;
* [http://www.st.com/internet/mcu/subclass/1588.jsp STM32F0]&lt;br /&gt;
** Cortex M0&lt;br /&gt;
** µC zum Einstieg&lt;br /&gt;
* [http://www.st.com/internet/mcu/subclass/1169.jsp STM32F1]&lt;br /&gt;
** Cortex M3&lt;br /&gt;
**Verschiedene Unterfamilien:&lt;br /&gt;
*** Connectivity line&lt;br /&gt;
*** Performance line&lt;br /&gt;
*** USB Access line&lt;br /&gt;
*** Access Line&lt;br /&gt;
*** Value line &lt;br /&gt;
* [http://www.st.com/internet/mcu/product/250173.jsp STM32F2]&lt;br /&gt;
** Cortex M3&lt;br /&gt;
** Wie die STM32F1 Serie, jedoch 120MHz, Camera-Interface, 32-Bit Timer, Crypto-Engine...&lt;br /&gt;
* [http://www.st.com/internet/mcu/subclass/1605.jsp STM32F3]&lt;br /&gt;
** ARM® Cortex™-M4-based STM32 F3, 72MHz&lt;br /&gt;
** DSP instructions and the floating point unit &lt;br /&gt;
** Fast 12-bit 5 MSPS and precise 16-bit sigma-delta ADCs&lt;br /&gt;
* [http://www.st.com/internet/mcu/subclass/1521.jsp STM32F4]&lt;br /&gt;
** Cortex M4&lt;br /&gt;
** ARM® Cortex™-M4-based STM32 F4, 168MHz&lt;br /&gt;
** DSP instructions and the floating point unit &lt;br /&gt;
* [http://www.st.com/mcu/inchtml-pages-stm32l.html STM32L]&lt;br /&gt;
** Cortex M3&lt;br /&gt;
** Low Power &lt;br /&gt;
** mit LCD Treiber&lt;br /&gt;
* [http://www.st.com/mcu/inchtml-pages-stm32w.html STM32W]&lt;br /&gt;
** Cortex M3&lt;br /&gt;
** RF-MCU &lt;br /&gt;
[http://www.st.com/internet/mcu/class/1734.jsp Hier eine Übersicht zum Auswählen eines STM32Fxxx]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Features&#039;&#039;&#039;&lt;br /&gt;
* Cortex-M0 / Cortex-M3 / Cortex-M4 Kern&lt;br /&gt;
* 16KB ... 1MB  [[Flash-ROM]]&lt;br /&gt;
*  4KB ... 192KB [[Speicher#SRAM|SRAM]]&lt;br /&gt;
* 4KB [[Speicher#EEPROM|EEPROM]] (STM32L)&lt;br /&gt;
* 512 one-time programmable Bytes(STM32F2/4)&lt;br /&gt;
* [[IC-Gehäuseformen | Gehäuse]] 36 ... 176 Pins als QFN, LQFP und BGA&lt;br /&gt;
* Derzeit sind über &#039;&#039;&#039;250&#039;&#039;&#039; STM32 Derivate/Varianten verfügbar&lt;br /&gt;
* Bis 72MHz CPU-Takt, bis 120MHz beim STM32F2xx, bis 168 MHz beim STM32F4xx, wobei eine spezielle prefetch-hardware bis 120/168 MHz eine Geschwindigkeit erzielen soll, die 0 Wait-States entspricht. Der CPU-Takt wird über einen Multiplikator aus dem internen RC-Takt oder einem externen Quarz-Takt abgeleitet.&lt;br /&gt;
* Externes Businterface (nur bei Gehäusen ab 100 Pin und nur bei STM32F4, STM32F2 und STM32F1 Performance line)&lt;br /&gt;
* LCD Treiber für 8x40 Punkte (nicht beim STM32F2xx)&lt;br /&gt;
* Spannungsbereich 1,65 ... 3,6V, nur eine Betriebsspannung nötig&lt;br /&gt;
* Temperaturbereich bis 125 °C&lt;br /&gt;
* Bis zu 140 IOs, viele davon [[Pegelwandler|5V-tolerant]]&lt;br /&gt;
* Interner, kalibrierter RC-Oszillator mit 8MHz (16MHz bei STM32F2/F4xx)&lt;br /&gt;
* Externer Quarz&lt;br /&gt;
* Real Time Clock mit eigenem Quarz und separater Stromversorgung&lt;br /&gt;
* Bis zu 16 [[Timer]], je Timer bis zu 4 IC/OC/PWM Ausgänge. Davon 2x Motion Control Timer (bei STM32F103xF/G)&lt;br /&gt;
* Systick Counter&lt;br /&gt;
* Bis zu 3 12-Bit [[AD-Wandler]] mit insgesamt 24 AD-Eingängen, integrierter [[Temperatursensor]], Referenzspannung Vrefint und VBatt Spannungsmessung (STM32F4xx)&lt;br /&gt;
* Bis zu 2 12-Bit [[DA-Wandler]]&lt;br /&gt;
* Bis zu 2 [[DMA]] Controller mit bis zu 12 Kanälen (16 beim STM32F2/4xx)&lt;br /&gt;
* Bis zu 2x [[I2C|I²C]]&lt;br /&gt;
* Bis zu 5x [[UART|USART]] mit LIN, IrDA und Modem Control (6 beim STM32F2/F4xx)&lt;br /&gt;
* Bis zu 3x [[SPI]]&lt;br /&gt;
* Bis zu 2x [[I2S|I²S]]&lt;br /&gt;
* Bis zu 2x [[CAN]]&lt;br /&gt;
* Unique device ID register (96 Bits)&lt;br /&gt;
* RNG - Random Number Generator (STM32F2/4xx)&lt;br /&gt;
* Cryptographic Processor (CRYP) (STM32F2/4xx)&lt;br /&gt;
* Hash Processor (HASH) (STM32F2/4xx)&lt;br /&gt;
* Kamera-Interface (DCMI) (STM32F2/4xx)&lt;br /&gt;
* [[USB]] 2.0 Full Speed / OTG&lt;br /&gt;
* [[USB]] 2.0 Hi Speed OTG mit extra PHY-Chip (STM32F2/4xx)&lt;br /&gt;
* SDIO Interface (z.B. SD-Card Reader)&lt;br /&gt;
* Ethernet&lt;br /&gt;
* Watchdog mit Window-Mode&lt;br /&gt;
* Jedes Peripheriemodul ist separat einschaltbar, wodurch sich erheblich [[Ultra low power|Strom sparen]] lässt&lt;br /&gt;
* [[JTAG]] und SWD (Serial Wire Debug) Interface&lt;br /&gt;
* Bis zu 6 Hardware-Breakpoints für Debuggen&lt;br /&gt;
* und vieles mehr . . .&lt;br /&gt;
&lt;br /&gt;
== Struktur der Dokumentation: ==&lt;br /&gt;
&lt;br /&gt;
Als Beispiel der Dokumentation soll stellvertretend der [http://www.st.com/mcu/devicedocs-STM32F103RC-110.html STM32F103RC] genannt werden. Die Seite von ST beinhaltet alle nötigen Informationen passend zu diesem Prozessor.&lt;br /&gt;
&lt;br /&gt;
Diese Dokumente von ST beschreiben den Controller:&lt;br /&gt;
&lt;br /&gt;
* [http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/DATASHEET/CD00191185.pdf  Datasheet STM32F103xC/D/E]&lt;br /&gt;
* [http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/REFERENCE_MANUAL/CD00171190.pdf  Reference Manual (RM0008)]&lt;br /&gt;
* [http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/PROGRAMMING_MANUAL/CD00228163.pdf  Cortex-M3 Programming Manual]&lt;br /&gt;
* [http://www.st.com/stonline/products/literature/pm/13259.pdf Flash Programming Reference]&lt;br /&gt;
&lt;br /&gt;
Im Datasheet sind die speziellen Eigenschaften einer bestimmten Modellreihe beschrieben und die exakten Daten und Pinouts aufgeführt. Die Peripheriemodule werden nur aufgeführt, nicht detailliert beschrieben. In der Referenz ist der gesamte Controller mit Peripheriemodulen im Detail beschrieben, gültig für eine STM32-Familie. Details zum Prozessorkern selbst und den nicht STM32-spezifischen mit dem Cortex-M3 Core assoziierten Modulen wie dem Interrupt-Controller und dem Systick-Timer findet man jedoch nicht dort, sondern im Cortex-M3 Manual. Wer nicht die ST Firmware-Library verwendet, der benötigt zusätzlich die Flash Programming Reference für die Betriebsart des Flash-ROMs, d.h. die frequenzabhängige Konfiguration der Waitstates. Hinzu kommen optionale Dokumente von ARM, die den [http://infocenter.arm.com/help/topic/com.arm.doc.ddi0337-/ Cortex-M3 Kern] / [http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0439c/index.html Cortex-M4 Kern] beschreiben. Hier gibt es den Opcode wenn man ihn in [http://infocenter.arm.com/help/topic/com.arm.doc.ddi0403-/ Assembler] programmieren möchte. Zusätzlich sollten auch die [http://www.st.com/stonline/products/literature/es/14732.pdf Errata Sheets] beachtet werden. Empfohlen sei auch die Appnote &amp;quot;[http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/APPLICATION_NOTE/CD00164185.pdf STM32F10xxx hardware development: getting started]&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== ‎STM32F10x Standard Peripherals Library ==&lt;br /&gt;
&lt;br /&gt;
ST bietet eine umfangreiche Firmwarebibliothek, eine einzige Bibliothek für alle STM32 Derivate. Das ist der große Vorteil von ST (gibt es beispielsweise auf den Cortex-M3 Controllern von TI auch, ist teilweise in einem separaten ROM untergebracht). Einmal programmieren und in allen STM32 verwendbar. Alle Funktionen sind gekapselt in einfache Strukturen und Funktionsaufrufe. Somit muss man sich nicht selbst um die Peripherieregister kümmern. Diese Library und ihre Dokumentation setzen das grundlegende Verständnis der Funktion des jeweiligen Peripheriemoduls voraus, wie es die o.A. Referenz und diverse Appnotes vermitteln. Diese FW-Lib (Download von ST) ist ein MUSS für jeden, denn darin sind auch jede Menge Beispiele für alle Peripheriemodule. &lt;br /&gt;
&lt;br /&gt;
Details siehe: [[‎STM32F10x Standard Peripherals Library]].&lt;br /&gt;
&lt;br /&gt;
Mit [http://www.libopencm3.org/wiki/Main_Page libopencm3] ist derzeit auch eine Open-Source Alternative (GPL, Version 3 oder höher) zur ST Library in Entwicklung, die zukünftig auch Cortex-M3 Controller von anderen Herstellern unterstützen soll.&lt;br /&gt;
&lt;br /&gt;
== CMSIS ==&lt;br /&gt;
&lt;br /&gt;
Parallel zur Firmware-Library (FW-Lib) gibt es für die &amp;quot;Selbermacher&amp;quot; die CMSIS (ARM® &#039;&#039;&#039;C&#039;&#039;&#039;ortex™ &#039;&#039;&#039;M&#039;&#039;&#039;icrocontroller &#039;&#039;&#039;S&#039;&#039;&#039;oftware &#039;&#039;&#039;I&#039;&#039;&#039;nterface &#039;&#039;&#039;S&#039;&#039;&#039;tandard), die grundsätzlich nur den herstellerübergreifenden ARM-Core abdeckt. Hierzu gehört bei den Cortex-M4-Cores auch die DSP und Floating-Point Funktionalität. Weiterhin existieren eine Zahl von Helferfunktionen für den NVIC, den Sys-Tick-Counter, sowie eine SystemInit-Funktion, welche sich um die PLL kümmert. &lt;br /&gt;
&lt;br /&gt;
Im Rahmen des CMSIS-Standards ([http://www.onARM.com www.onARM.com]) wurden die Headerdateien standardisiert, der Zugriff auf die Register erfolgt per &#039;&#039;&#039;Peripheral-&amp;gt;Register&#039;&#039;&#039;. Die CMSIS C-Dateien bzw. Header enthalten auch Anpassungen für die verschiedenen Compiler. Die Portierung eines Real-Time-Betriebsystems sollte unter Verwendung der CMSIS, für Chips der verschiedenen Hersteller, stark vereinfacht möglich sein (z.B. einheitliche Adressen für Core-Hardware/Sys-Tick-Counter).&lt;br /&gt;
&lt;br /&gt;
Die CMSIS ist im Download der FW-Lib enthalten. Die Compiler-Hersteller liefern eine jeweils zur ihrer Tool-Version passende bzw. geprüfte FW-Lib (incl. CMSIS) aus. Diese Libs können, gegenüber den Downloads beim Chip-Hersteller, auch ältere Version beinhalten.&lt;br /&gt;
&lt;br /&gt;
== Debug- und Trace-Interface (CoreSight™ Debug and Trace Technologie)==&lt;br /&gt;
&lt;br /&gt;
Übersicht über beide Funktionalitäten und den Schnittstellen:&lt;br /&gt;
http://www.keil.com/support/man/docs/ulink2/ulink2_cs_core_sight.htm&lt;br /&gt;
&lt;br /&gt;
Die Coresight-Debug-Architektur ermöglicht ein nicht-invasives Debugging, d.h. es können während des Betriebes (meistens) ohne Beeinflussung des Prozessors Daten vom Speicher gelesen und in selbigen geschrieben werden.&lt;br /&gt;
&lt;br /&gt;
=== Debugger Funktionen ===&lt;br /&gt;
&lt;br /&gt;
Der Debugger-Teil besitzt drei Funktionen:&lt;br /&gt;
* Run Control: z.B. Programm-Start, Stopp und Einzel-Schritte.&lt;br /&gt;
* (Program) Break Points: Ein Programm hält an, wenn der Programm Counter eine bestimmte Programm-Adresse erreicht.&lt;br /&gt;
** Die maximale Anzahl der gleichzeitig möglichen Break Points ist begrenzt (z.B. 6 bei einem STM32).&lt;br /&gt;
** Die Anzahl der Break Points ist nahezu unbegrenzt, wenn ein Debugger über den Memory Access (s.u.) sogenannte Flash Break Points unterstützt. Dabei wird ein geladenes Programm im Flash umprogrammiert, um den Debugger anzuhalten. Diese Funktionalität ist meistens ein kostenpflichtiges Zusatz-Feature des Debugger-Herstellers. &lt;br /&gt;
** Beinhaltet keine Data Watch Funktionalität, welche im Trace-Teil (DWT) realisiert wird.&lt;br /&gt;
* Memory Access: Lesen und Schreiben von Speicheradressen. &lt;br /&gt;
** Diese Funktionalität beinhaltet keine direkte Flash-Programmierung. Der Programmiervorgang für einen Flash ist herstellerspezifisch und muss von dem verwendeten Debugger unterstützt werden.&lt;br /&gt;
&lt;br /&gt;
=== Trace Funktionen ===&lt;br /&gt;
Die Trace-Funktionalität wird in drei Funktionen aufgeteilt:&lt;br /&gt;
* ETM (Embedded Trace Macrocell): Optional, nicht jede CPU besitzt diese Hardware (Kostenfaktor, Austattung).&lt;br /&gt;
* ITM (Instrumentation Trace Macrocell): Über diesen Kanal kann ein vereinfachtes Trace des Core ermöglicht werden, sowie &amp;quot;printf-ähnlich&amp;quot; Daten über den ITM Channel 0 geschickt und im Debugger ausgegeben werden.&lt;br /&gt;
* DWT (Data Watchpoint &amp;amp; Trace Unit): &lt;br /&gt;
** Data Watch: 4 Access-Break-Points ( z.B. der Debugger bleibt stehen, wenn das Programm auf einen Speicher zugreift oder der Wert einer Variablen einen bestimmten Wert annimmt). &lt;br /&gt;
** Trace Unit: Programmverlauf (durch Lesen des Program Counters) und Interrupt Aufrufe verfolgen, sowie Zeitmessungen.&lt;br /&gt;
&lt;br /&gt;
Einige der Trace-Funktionalitäten können über die JTAG-Schnittstelle angesprochen werden. Die schnelle Trace-Funktionalität (mit 4 bit Parallel-Port) steht nur mit der erweiterten DEBUG + ETM Schnittstelle zur Verfügung. Im Gegensatz zum Debugger-Teil (Run Control, Break Points und Memory Access) werden Trace-Funktionen nicht von allen Debuggern unterstützt. Debugger mit der vollen Trace-Funktionalität kosten deutlich mehr.&lt;br /&gt;
&lt;br /&gt;
* Beispiele für Trace-Port-Aktivierungen für verschiedene Hersteller: http://www.keil.com/support/man/docs/jlink/jlink_capture_tracedata.htm&lt;br /&gt;
&lt;br /&gt;
Die Aktivierung des parallelen Trace-Ports erfordert, je nach CPU Hersteller, zusätzliche Debugger-Makros für die Aktivierung und Port-Freischaltung. Zusätzlich sind die Schnittstellenauswahl und Einstellung (Frequenzen) im Entwicklungs-Tool (IDE) wichtig, um erfolgreich den Programm-Verlauf &amp;quot;tracen&amp;quot; zu können.&lt;br /&gt;
&lt;br /&gt;
=== Debug und Trace-Schnittstellen ===&lt;br /&gt;
Als Debug Interface stehen zwei Varianten zur Auswahl:&lt;br /&gt;
* [[JTAG]]: Dafür sind mindestens 6 Steuerleitungen nötig. Unterstützt Device Chaining: Mehrere verbundene Geräte können mit einem Debugger/Programmer gleichzeitig angesteuert werden.&lt;br /&gt;
* SWD (Serial Wire Debug): Hier mindestens 2  Steuerleitungen (3 mit SWO, zzgl GND und 3,3V). Die SWD Schnittstelle ist in der Regel schneller und kann auch Funktionen aus dem Trace-Teil beinhalten (z.B. ITM, dafür wird der SWO-Pin benötigt). Device Chaining ist mit dieser Schnittstelle nicht möglich.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Standard-JTAG Steckerbelegungen: &lt;br /&gt;
http://www.keil.com/support/man/docs/ulink2/ulink2_hw_connectors.htm&lt;br /&gt;
&lt;br /&gt;
=== Der 10polige JTAG-Stecker von mmvisual ===&lt;br /&gt;
mmvisual hat mit dieser Steckerbelegung die Standard JTAG Schnittstelle erweitert:&lt;br /&gt;
&lt;br /&gt;
Ich habe diesen Part in den Artikel [http://www.mikrocontroller.net/articles/JTAG#Der_10-Polige_JTAG_Stecker_von_mmvisual JTAG] verschoben.&lt;br /&gt;
Hinzu gekommen ist die Adapterplatine 10-Polig auf Standard JTAG 20 Polig mit TTL/V24 Wandler. [http://www.mikrocontroller.net/articles/JTAG#Die_Adapterplatine Siehe hier.]&lt;br /&gt;
&lt;br /&gt;
=== STM32 RS232 (CAN und USB) Programmiertool ===&lt;br /&gt;
&lt;br /&gt;
Auch ohne JTAG lässt sich ein STM32 programmieren (Bootloader-Aktivierung). Dabei stehen, je nach CPU-Typ, verschiedene Möglichkeiten zur Verfügung:&lt;br /&gt;
* RS-232 (bisher alle STMs)&lt;br /&gt;
* USB (nur in bestimmten MCUs mit entsprechender Bootloader-Version und PIN-Anzahl, z.B. STM32F105/107)&lt;br /&gt;
* CAN (wie USB nur in bestimmten MCUs)&lt;br /&gt;
&lt;br /&gt;
3 zusätzliche Verbindungen müssen auf dem Board gepatcht werden. Für einen Test geht es auch mit Tastern für RESET und BOOT0.&amp;lt;br&amp;gt;&lt;br /&gt;
RESET=RTS (L-aktiv)&amp;lt;br&amp;gt;&lt;br /&gt;
BOOT0=DTR (H-aktiv)&amp;lt;br&amp;gt;&lt;br /&gt;
BOOT1=LOW&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Details sind hier im Forum: [http://www.mikrocontroller.net/topic/141711 STM32 Programmiertool]&lt;br /&gt;
&lt;br /&gt;
== Vorteile ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Vorteile gegenüber ARM7:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Interrupt-Controller jetzt Teil des Prozessors (als Core Peripheral), die Vector Table ist jetzt eine echte Vektortabelle, keine Sprungliste wie bei ARM7. Durch Automatismen zwischen Core und NVIC (auto register save r0..r3, lr, sp, pc) bei Interrupt Entry wird eine deutlich schnellere Ausführungszeit bei Interrupts erreicht. Der Interrupt Code muss sich nicht mehr selbst um die Sicherung der o.g. Register kümmern und eine besondere Konfiguration der Handler im Compiler entfällt. Sind vor Beendigung einer ISR (d.h. Rücksprung zum User Code) weitere Interrupts pending, so werden diese ausgeführt, ohne dass eine komplette pop-push-sequenz der Register notwendig ist. Schön beschrieben ist es hier im [http://www.st.com/mcu/files/mcu/1221142709.pdf Insider&#039;s Guide] unter 2.4.5 / Seite 20.&lt;br /&gt;
* Thumb-2 Befehlssatz, deutlich schneller als Thumb-1 und ebenso kompakt&lt;br /&gt;
* Weniger Pins für Debugging benötigt durch SWD&lt;br /&gt;
* Mehr Hardware Breakpoints machen debuggen einfacher&lt;br /&gt;
* Software ist einfacher weil die Umschaltung zwischen ARM Mode und Thumb Mode wegfällt&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Vorteile gegenüber LPC1700 und LPC1300:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Flexiblere Gehäuseformen mit mehr Peripherie bei kleinen Gehäusen&lt;br /&gt;
* FW-Lib für alle STM32 gleich, alle AppNotes/Demos beziehen sich auf diese eine FW-Lib was die Entwicklung der eigenen Applikation sehr beschleunigt.&lt;br /&gt;
* Genauerer und flexiblerer ADC, insbesondere gegenüber LPC1300&lt;br /&gt;
* Flexiblere Varianten der Peripherie &amp;gt;&amp;gt; bei weniger einen deutlichen Preisvorteil&lt;br /&gt;
* ab 0,85 EUR (Stand 2010) Allerdings gibts den LPC1100 mit Cortex-M0 schon ab 0,65 $!&lt;br /&gt;
&#039;&#039;&#039;Nachteil gegenüber LPC1700:&#039;&#039;&#039;&lt;br /&gt;
* STM32F1xx: nur 72 MHz statt 100 MHz (LPC1759: 120 MHz) Taktfrequenz; STM32F2xx hat diesen Nachteil nicht (ebenfalls 120MHz, STM32F4xx mit 168MHz) (Aber NXP hat schon 150MHz angekündigt)&lt;br /&gt;
* Der LPC1700 besitzt deutlich mehr Mechanismen, um die Auswirkung der Waitstates des Flash-ROMs auf Code- und Datenzugriffe zu reduzieren und das bedeutet mehr Performance bei gleicher Taktfrequenz. Beim STM32F2 entfällt dieser Nachteil wohl aufgrund des ART accelerators. &lt;br /&gt;
* Alle LPC1xxx haben 32 Bit Timer. Bei den STM32 haben das nur die STM32F2xx (2 Stück)&lt;br /&gt;
* I2S Einheit von ST hat keinen FIFO und im 24/32Bit Modus müssen 2x16Bit Halbwörter übertragen werden.&lt;br /&gt;
&#039;&#039;&#039;Vorteile gegenüber anderen &amp;quot;Kleinen&amp;quot; wie z.B. PIC, Atmel usw.&#039;&#039;&#039;&lt;br /&gt;
* nahezu gleicher Preis bei Hobby Anwendungen&lt;br /&gt;
* 32 Bit ohne Umwege in Assembler rechenbar&lt;br /&gt;
* bessere Peripherie&lt;br /&gt;
* ... und weitere 1000 Punkte ...&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Nachteil für Hobby-Anwender&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Nicht direkt &amp;quot;Steckbrettauglich&amp;quot;, da kein DIL Gehäuse verfügbar. Der ebay-Shop dipmicro führt jedoch sehr günstige Lötadapter für Umsetzung von LQFP48 auf DIP48. QFP64 in 0.5mm Pinabstand und nicht 0.8mm wie AVR&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Hardware-Beschaltung ==&lt;br /&gt;
&lt;br /&gt;
Der STM32 benötigt für den Betrieb nur (Minimalbeschaltung):&lt;br /&gt;
&lt;br /&gt;
* VCC 2..3,3V (je nach Typ)&lt;br /&gt;
* AVCC 2..3,3V (sehr wichtig, der STM32 lässt sich ohne diese Spannung nicht programmieren)&lt;br /&gt;
* GND&lt;br /&gt;
* Reset Pin 100nF nach GND (ein Pull-Up Widerstand von ca. 40k ist intern vorhanden)&lt;br /&gt;
* Boot-Pins: Boot0 -&amp;gt; GND | Boot1 -&amp;gt; Egal ---&amp;gt; Mit der Konfiguration wird kein Bootloader gestartet&lt;br /&gt;
&lt;br /&gt;
ansonsten nur ein paar einzelne Cs 100nF an VCC/GND.&lt;br /&gt;
&lt;br /&gt;
Um Programmieren zu können wird entweder noch die serielle Schnittstelle (Programmieren über den vorprogrammierten Bootloader) oder JTAG oder die SWD Schnittstelle benötigt.&lt;br /&gt;
&lt;br /&gt;
== Programmierung ==&lt;br /&gt;
&lt;br /&gt;
Als Programmieroberfläche kann eine kostenlose Struktur verwendet werden. Es ist für den Einsteiger schwierig herauszufinden welche Open-Source Programme man braucht damit es funktioniert, daher hier eine Zusammenstellung:&lt;br /&gt;
&lt;br /&gt;
* [http://www.eclipse.org Eclipse]&lt;br /&gt;
* [http://www.yagarto.de Yagarto Tools] oder [http://www.codesourcery.com/sgpp/lite_edition.html Codesourcery Lite Edition] oder [https://launchpad.net/gcc-arm-embedded Launchpad]&lt;br /&gt;
* Programmieradapter OOCD, Turtelizer2 oder andere JTAG Programmieradapter&lt;br /&gt;
* Eclipse Plugin &amp;quot;GDB Hardware Debugging&amp;quot; mit [http://www.firefly-power.de/ARM/debugging.html OpenOCD server]&lt;br /&gt;
* [http://www.st.com/internet/com/software/ides_mcu.jsp#stm32 ST Liste: IDEs, Toolsets and Debug tools for MCUs]&lt;br /&gt;
&lt;br /&gt;
* Zum Starten eine fertige Zusammenstellung: [http://www.mikrocontroller.net/topic/216554 Eclipse+codesourcery+st-link]&lt;br /&gt;
&lt;br /&gt;
* [http://www.coocox.org/ Coocox Eclipse IDE] kostenlose IDE für STM32F0 / F1 / F4 Hilfreiche Infos gibt es im [http://www.mikrocontroller.net/topic/214719?goto=new#2228482 hier] und [http://www.mikrocontroller.net/topic/214719?goto=new#2229943 hier] Forum&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/265600 STM32F4 mit Code::Blocks]&lt;br /&gt;
&lt;br /&gt;
* [http://emide.org/ emIDE] kostenlose IDE die mit dem Segger J-LINK funktioniert.&lt;br /&gt;
&lt;br /&gt;
Sehr nützlich für Linux-Anwender auch diese Seite: [http://fun-tech.se/stm32/index.php STM32/ARM Cortex-M3 HOWTO: Development under Ubuntu.]&lt;br /&gt;
&lt;br /&gt;
Folgende kommerzielle Umgebungen sind verfügbar:&lt;br /&gt;
&lt;br /&gt;
* [http://www.keil.com/arm/mdk.asp Keil µVision] (Demo max. 32KB Code): Die sehr komfortable µVison IDE ist neben dem ARM Compiler per Menue auch für einen beliebigen GNU-Compiler konfigurierbar. Damit besteht das 32k-Limit nur noch für den integrierten Debugger / Simulator. µVison selbst kann kostenlos mit dem MDK-Evaluationkit heruntergeladen werden.&lt;br /&gt;
* [http://www.iar.com IAR] (Demo max. 32KB Code)&lt;br /&gt;
* [http://www.raisonance.com Raisonance Ride7] (GCC Compiler, kostenlose Version auf Debugging von max. 32KB Code limitiert, keine Limitierung beim Complilieren)&lt;br /&gt;
* [http://www.atollic.com Atollic] (Lite Version (bis V2.3.0) ohne Code-Limit, auf GCC basierend. Die neueste Version ab V3 hat fast keine Beschränkungen mehr außer jetzt einen Code-Limit von 32kB. Außerdem werden jetzt die meisten ARM Familien unterstützt. )&lt;br /&gt;
* [http://www.coocox.org CoIDE] (Kostenlose GCC, Eclipse basierende IDE mit einem Code-Generator Tool)&lt;br /&gt;
* [http://www.rowley.co.uk/arm/ Rowley Crossworks] (Demo 30 Tage unbeschränkt, 150$ für nichtkommerzielle Nutzung, auf GCC basierend)&lt;br /&gt;
* [http://www.code-red-tech.com Code Red] (GCC basierend)&lt;br /&gt;
&lt;br /&gt;
Programmieradapter&lt;br /&gt;
* [http://www.segger.com J-Link / J-Trace] Cortex-M3, als [http://www.segger.com/cms/j-link-edu.html NonComercial] J-Link für ca. 60,- zu haben, läuft in µVision, IAR, gdb, Keil&lt;br /&gt;
* [https://www.olimex.com/Products/ARM/JTAG/ Olimex] ARM-USB-OCD (ca. 60.-)&lt;br /&gt;
* Keil [http://www.keil.com/ulinkme/ ULINK-ME], [http://www.keil.com/arm/ulink2/ ULINK2], [http://www.keil.com/arm/ulinkpro/ ULINK pro]&lt;br /&gt;
* [http://www.st.com/internet/evalboard/product/219866.jsp ST-LINK], [http://www.st.com/internet/evalboard/product/251168.jsp ST-LINK/V2]&lt;br /&gt;
*[http://www.st.com/internet/com/press_release/p3065.jsp STM32xx Discovery] jedes STM32 Discovery board hat einen ST-Link für Programmierung/Debugging per SWD on-board, welcher auch für eigene STM32 Target Hardware benutzt werden kann (ca. 12,- bis 19,-€, je nach Typ).&lt;br /&gt;
* [http://www.raisonance.com/~rlink-debugger-programmer__microcontrollers__tool~tool__T018:4cn9ziz4bnx6.html Raisonance RLink]&lt;br /&gt;
* [http://www.amontec.com Amontec]&lt;br /&gt;
* [http://www.hjtag.com H-JTAG] Personal Edition für ca. 60,- zu haben, läuft mit ADS, SDT, IAR, Vision und RVDS &lt;br /&gt;
&lt;br /&gt;
Programmieradapter Open-Source&lt;br /&gt;
* [http://www.oocdlink.com/ OOCDLink]&lt;br /&gt;
* [https://github.com/texane/stlink Stlink]&lt;br /&gt;
* [http://www.randomprojects.org/wiki/Floss-JTAG FLOSS-JTAG]&lt;br /&gt;
* [http://capitanio.org/mlink/ Linux Demo Code für die Discovery&#039;s ST-Link Programmierung]&lt;br /&gt;
&lt;br /&gt;
Der Controller hat auch einen fest eingebauten Boot-Lader. Damit läßt er sich auch über eine gewöhnliche serielle Schnittstelle programmieren, ohne daß man einen JTAG-Adapter benötigt.&lt;br /&gt;
&lt;br /&gt;
Tipps für Installation mit Eclipse können in [http://www.mikrocontroller.net/topic/214719 diesem Thread] gelesen werden.&lt;br /&gt;
&lt;br /&gt;
=== Installation für STM32 (Linux) ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Variante A ====&lt;br /&gt;
&lt;br /&gt;
* Benötigte Hardware&lt;br /&gt;
** Ein Desktop PC oder Laptop mit Linux OS (openSuSE, Ubuntu, ...) alternativ: Ein Windows System mit Linux in einer virtuellen Maschine &lt;br /&gt;
** root Zugang zum Linux OS (superuser Passwort)&lt;br /&gt;
** GNU C Compiler&lt;br /&gt;
** Programmer ARM-USB-TINY-H (optimal) alternativ: OpenOCD kompatiblen Programmer&lt;br /&gt;
** Prototypboard Olimex STM32-P107 (optimal) alternativ: irgendein board mit STM32 uC und JTAG Port&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
* Download + Installation (in einem Terminal)&lt;br /&gt;
  wget http://hlb-labor.de/cortexm3/install_ToolChain_STM32.sh&lt;br /&gt;
  chmod +x install_ToolChain_STM32.sh&lt;br /&gt;
  ./install_ToolChain_STM32.sh&lt;br /&gt;
 &lt;br /&gt;
Die Installation sollte im Idealfall voll automatisch durchlaufen. Anschliessend wird ein Beispielprojekt mit Multitasking OS und LED-Heartbeat kompiliert und auf den uC programmiert.&lt;br /&gt;
Für andere Protoboards/ Programmer muss die ToolChain entsprechend der readme Anleitung umkonfiguriert werden.&lt;br /&gt;
&lt;br /&gt;
Das Projekt kann im QtCreator (http://qt.nokia.com/) geöffnet und bearbeitet werden.&lt;br /&gt;
&lt;br /&gt;
==== Variante B ====&lt;br /&gt;
&lt;br /&gt;
Die Installation einer Toolchain (Make, Flash, Debug via JTAG, IDE) ist in folgendem Manual beschrieben:&lt;br /&gt;
&lt;br /&gt;
&amp;quot;How-to manual - Installing a toolchain for Cortex-M3/STM32 on Ubuntu 10.04&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*http://www.seng.de/downloads/HowTo_ToolChain_STM32_Ubuntu.pdf&lt;br /&gt;
*http://www.seng.de/downloads/HowTo_ToolChain_STM32_Ubuntu.odt&lt;br /&gt;
&lt;br /&gt;
Die Beschreibung im OpenOffice Format erlaubt die Weiterbearbeitung des Textes und das Entnehmen von Quelltexten ohne den Verlust von Formatierungen.&lt;br /&gt;
&lt;br /&gt;
Verwendete Hardware:&lt;br /&gt;
*JTAG device&lt;br /&gt;
**Olimex “ARM-USB-OCD-H”, basierend auf FTDI “FT2232H”&lt;br /&gt;
*Microcontroller&lt;br /&gt;
**Olimex “STM32-H103” basierend auf STM32F103RBT6 mit 128KB Flash, 20KB RAM, 3xUART, ...&lt;br /&gt;
Die Toolchain sollte sich leicht an andere &amp;quot;FT2232&amp;quot; basierte JTAG Probes und &amp;quot;Cortex-M3&amp;quot; Derivate anpassen lassen.&lt;br /&gt;
&lt;br /&gt;
Das Manual umfasst die Installation und Inbetriebnahme sowie Hinweise und Bug-fixes zu folgenden Komponenten:&lt;br /&gt;
*OpenOCD&lt;br /&gt;
*stm32flash&lt;br /&gt;
*Sourcery CodeBench Lite for ARM EABI&lt;br /&gt;
*STM32F10x standard peripheral library&lt;br /&gt;
*Project templates&lt;br /&gt;
*Makefiles&lt;br /&gt;
*Linker Sript&lt;br /&gt;
*Startup Code&lt;br /&gt;
*Doxygen&lt;br /&gt;
*Git&lt;br /&gt;
*Terminal emulation&lt;br /&gt;
*Eclipse IDE&lt;br /&gt;
*Links zu Datenblättern, Manuals und Toools&lt;br /&gt;
&lt;br /&gt;
=== Installation für STM32 (Windows) ===&lt;br /&gt;
&lt;br /&gt;
Hier ist der Anfang des Artikels [[STM32 Eclipse Installation]], hier ist neueres beschrieben als hier aufgeführt. Wenn der Artikel fertig ist, dann wird dieser Teil gelöscht.&lt;br /&gt;
&lt;br /&gt;
* Eclipse &amp;quot;Helios&amp;quot; installieren mit GNU ARM Eclipse Plug-in&lt;br /&gt;
Eclipse IDE for C/C++ Developers&amp;lt;ref&amp;gt;http://www.eclipse.org/downloads/packages/eclipse-ide-cc-developers/heliosr&amp;lt;/ref&amp;gt; downloaden und installieren&lt;br /&gt;
&lt;br /&gt;
* GNU ARM Eclipse Plug-in&amp;lt;ref&amp;gt;http://sourceforge.net/projects/gnuarmeclipse/&amp;lt;/ref&amp;gt; runterladen und installieren. [http://sourceforge.net/apps/mediawiki/gnuarmeclipse/index.php?title=Main_Page Weitere Infos].&lt;br /&gt;
&lt;br /&gt;
Wird CodeSourcery G++ Lite verwendet, so muss die PATH Variable angepasst &lt;br /&gt;
werden, damit das Plugin die CodeSourcery exe-Files findet&amp;lt;ref&amp;gt;für Discovery notwendig&amp;lt;/ref&amp;gt;. Alternativ das eclipse von einem script aus starten und zuerst den PATH erweitern.&lt;br /&gt;
&lt;br /&gt;
Soll das ST-LINK verwendet werden, so kann der Atollic ST-LINK GDBSERVER aus der Atollic free version genutzt werden. Mit dem gdbclient im Eclipse kann damit problemlos geflasht und gedebuggt werden (JTAG und SWD). &lt;br /&gt;
&lt;br /&gt;
Neuere Versionen von OpenOCD können ebenfalls mit STLINK und STLINK2 Kontakt aufnehmen. Bei vorkompilierten OpenOCD-Packeten (z.B. die von Freddy Chopin) mit libusb-Support und installiertem Herstellertreiber von STM ist noch der libusb-Filtertreiber einzurichten (relativ einfach per libusb-win32 filter wizard GUI).&lt;br /&gt;
&lt;br /&gt;
Die Startup- und Linkerscripts der Atollic free version können für ein Projekt in dieser Konstallation genutzt werden.&lt;br /&gt;
&lt;br /&gt;
* Eclipse &amp;quot;Galileo&amp;quot; installation&amp;lt;ref&amp;gt;[http://www.eclipse.org/] → Downloads → &amp;quot;Eclipse IDE for C/C++ Developers (79 MB)&amp;lt;/ref&amp;gt;. Und das Servicepack 1&amp;lt;ref&amp;gt;[http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/galileo/SR1/eclipse-cpp-galileo-SR1-win32.zip Eclipse SR1]&amp;lt;/ref&amp;gt;&lt;br /&gt;
Entpacken der Datei eclipse-cpp-galileo-SR1-win32.zip nach &amp;quot;C:\WinARM\&amp;quot; (Ordner neu erstellen)&lt;br /&gt;
&lt;br /&gt;
* Eclipse PlugIn&amp;lt;ref&amp;gt;http://download.eclipse.org/tools/cdt/releases/galileo&amp;lt;/ref&amp;gt; hinzufügen: Help → Install New Software... → &amp;quot;Eclipse C/C++ Development Tools&amp;quot; + &amp;quot;Eclipse C/C++ GDB Hardware Debugging&amp;quot; installieren&lt;br /&gt;
&lt;br /&gt;
* Yagarto Tools&amp;lt;ref&amp;gt;[http://www.yagarto.de/] &amp;quot;Download (for Windows)&amp;quot; → &amp;quot;YAGARTO Tools&amp;quot; http://www.yagarto.de/download/yagarto/yagarto-tools-20091223-setup.exe Installieren, Auswahl Verzeichnis &amp;quot;C:\WinARM\yagarto-tools&amp;quot;&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CodeSourcery: Achtung! Die Menustruktur ändert sich durchaus mal, dann suchen gehen. http://www.codesourcery.com/ → Products → Sourcery G++ → Editions&amp;gt;Lite Edition → ARM → Downloads. Direkter Download&amp;lt;ref&amp;gt;[http://www.codesourcery.com/sgpp/lite/arm/portal/package6496/public/arm-none-eabi/arm-2010q1-188-arm-none-eabi.exe]&amp;lt;/ref&amp;gt;. Installieren, Auswahl Verzeichnis &amp;quot;C:\WinARM\CodeSourcery&amp;quot;&lt;br /&gt;
&lt;br /&gt;
* OpenOCD: Kompilierte Version für Windows&amp;lt;ref&amp;gt;[http://www.freddiechopin.info/] → Download → Software → OpenOCD&amp;lt;/ref&amp;gt; installieren nach &amp;quot;C:\WinARM\OpenOCD_0_4_0&amp;quot; ist auch auf der Seite&amp;lt;ref&amp;gt;[http://yagarto.de/#ocd Yagarto.de]&amp;lt;/ref&amp;gt; beschrieben. PS: Sollte der Olimex ARM-USB-OCD verwendet werden, dann darf nicht der Treiber von Olimex verwendet werden, sondern der vom OpenOCD Download&amp;lt;ref&amp;gt;[http://www.mikrocontroller.net/topic/173753#1668913]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* ST Firmware: http://www.st.com → Auswahl CPU STM32F103xxx → &amp;quot;Firmware&amp;quot; &amp;quot;STM32F10x_StdPeriph_Lib&amp;quot;&amp;lt;ref&amp;gt;http://www.st.com/mcu/devicedocs-STM32F103RC-110.html&amp;lt;/ref&amp;gt;. Das ZIP &amp;quot;stm32f10x_stdperiph_lib.zip&amp;quot; Entpacken nach &amp;quot;C:\WinARM\examples\stm32_FW3.4.0\&lt;br /&gt;
&lt;br /&gt;
=== Installation für STM32 auf einem zweiten Rechner===&lt;br /&gt;
&lt;br /&gt;
* Kopieren des Verzeichnisses C:\WinARM\ (Zuvor wurden aus diesem Grund alle Setup-Pakete nach C:\WinARM\... installiert)&lt;br /&gt;
* Die PATH-Variable in der Systemsteuerung mit den C:\WinARM\.... Verzeichnissen nachführen&lt;br /&gt;
* Fertig.&lt;br /&gt;
&lt;br /&gt;
=== Installation für STM32 mit AtollicTrueStudio (+Demo) ===&lt;br /&gt;
* Installation + Demo: [[STM32 LEDBlinken AtollicTrueStudio]]&lt;br /&gt;
&lt;br /&gt;
=== Installation für STM32 mit MDK-ARM Lite und STM32F4-Discovery Board ===&lt;br /&gt;
* [https://www.keil.com/demo/eval/arm.htm KEIL MDK-ARM Download]&lt;br /&gt;
* [http://www.youtube.com/watch?v=RXOOxby5nns&amp;amp;yt:cc=on Installations Video]&lt;br /&gt;
&lt;br /&gt;
== Demo-Projekte ==&lt;br /&gt;
&lt;br /&gt;
* [[prog_bsp_timer_1_timer2|Programmbeispiel für die Verwendung von Timer2 zusammen mit dem Interrupt]]&lt;br /&gt;
* [http://www.firefly-power.de/ARM/printf.html Printf() debugging mit minimalem Aufwand]&lt;br /&gt;
* [[STM32_BLDC_Control_with_HALL_Sensor|Programmbeispiel für BLDC Motoransteuerung (Timer 1) mit HALLSensor (Timer 3)]]&lt;br /&gt;
* [[Cortex_M3_OCM3U]]&lt;br /&gt;
* Martin Thomas hat ein umfangreiches Projekt erstellt, in der die Eclipse Einstellungen enthalten sind:&lt;br /&gt;
** [http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/arm_memcards/index.html &amp;quot;ChaN&#039;s FAT-Module with STM32 SPI&amp;quot;]&lt;br /&gt;
* [[STM32 USB-FS-Device Lib]]&lt;br /&gt;
* Modellbau-Sender auf STM32-Basis mit vielen Treibern [http://www.rcos.eu www.rcos.eu]&lt;br /&gt;
* Ausführliches [https://github.com/jkerdels/stm32edu Einstiegs-Tutorial] in Codeform für das [http://www.st.com/internet/evalboard/product/252419.jsp STM32F4 discovery board]&lt;br /&gt;
* [http://www.redacom.ch/keillab/ Schweizer Gondelbahnsteuerung über Webserver auf ETT STM32F ARM KIT Board in Keil RTOS] mit Webcam&lt;br /&gt;
* Die [http://ethernut.svn.sourceforge.net/viewvc/ethernut/trunk/ Ethernut SVN Version] unterstützt inzwischen viele STM32 Typen, viele Devices und einige STM32 Demoboards&lt;br /&gt;
&lt;br /&gt;
== Errata, Tipps und Tricks ==&lt;br /&gt;
&lt;br /&gt;
* AD-Wandler PA0: Im Errata steht, dass hier Fehler in der Wandlung entstehen könnten, also einen anderen Pin verwenden.&lt;br /&gt;
* CAN-Bus PD0/PD1: Remap geht erst ab der 100-Pin-Version. Steht im RM0008 unter 9.3.3.: &amp;quot;CAN1 alternate function remapping&amp;quot;. Alle Infos von RM0008 9.3.x sind interessant&lt;br /&gt;
* CAN und USB sind nur bei der &amp;quot;◦Connectivity-Line&amp;quot; gleichzeitig nutzbar. Siehe Datenblätter.&lt;br /&gt;
* Mit internem RC-Oszillator kann die CPU mit maximal 64MHz betrieben werden. Mit einem externen Quarz sind dann 72MHz möglich.&lt;br /&gt;
* Für USB Betrieb muss die CPU mit 48MHz oder 72MHz betrieben werden (bei STM32F1xx).&lt;br /&gt;
* Der Idle Interrupt vom Usart wird zwar ausgelöst, aber nicht vom entsprechenden Statusflag angezeigt&lt;br /&gt;
* Der DMA fängt beim aktivieren immer von vorn an zu zählen, auch wenn er nur kurz angehalten wurde&lt;br /&gt;
* STM32F2xx hat kein Flash Size Register, bei STM32F4xx ist zwar ein flash Size Register beschrieben, kollidiert aber in der Adresse mit einem anderen Register&lt;br /&gt;
* Derivate mit internem EEPROM und nur einer Speicherbank haben das &amp;quot;Feature&amp;quot; bei write/erase des Data-Flashes (EEPROM) einen kompletten stall der code execution zu verursachen (inkl. ISR&#039;s, DMA). Desgleichen bei write/erase des internen Flash (ISP-routinen, EEPROM-Emulation).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Tipps für Umsteiger von Atmel/PIC/8051 ===&lt;br /&gt;
* Prozessortakt hat unterschiedliche Taktquellen und eine PLL.&lt;br /&gt;
* Alle Peripheriemodule haben einen extra Clock, den man aktivieren muss.&lt;br /&gt;
* Wenn man z.B. einen UART benutzen möchte, so muss man den Clock vom UART, Alternate Function IO (AFIO) und dem GPIO-Port aktivieren.&lt;br /&gt;
* Ansonsten hat man nahezu doppelt so viele Möglichkeiten in den Peripheriemodulen.&lt;br /&gt;
* Interrupt-Flags müssen in der ISR selber gelöscht werden&lt;br /&gt;
* Forum zu [http://www.mikrocontroller.net/topic/175888 Interrupts vs. Events]&lt;br /&gt;
&lt;br /&gt;
=== Tipp FPU von STM32F4xx nutzen ===&lt;br /&gt;
Es benötigt dafür 2 Dinge, zum einen muss die Compileroption gesetzt sein, zum anderen auch die FPU aktiviert werden:&lt;br /&gt;
&lt;br /&gt;
Compileroption:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;COMMON_FLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Code für das Aktivieren der FPU:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;/*FPU settings*/&lt;br /&gt;
__asm volatile (&amp;quot;ldr     r0, =0xE000ED88&amp;quot;);           /* Enable CP10,CP11 */&lt;br /&gt;
__asm volatile (&amp;quot;ldr     r1,[r0]&amp;quot;);&lt;br /&gt;
__asm volatile (&amp;quot;orr     r1,r1,#(0xF &amp;lt;&amp;lt; 20)&amp;quot;);&lt;br /&gt;
__asm volatile (&amp;quot;str     r1,[r0]&amp;quot;);&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ohne Inline-Assembler in C wie in system_stm32f4xx.c aus den Beispielen von ST-Microelectronics:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2)); /* set CP10 and CP11 Full Access */&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Weiterhin sollte die Toolchain auch Laufzeitbibliotheken mit FPU-Unterstützung mitbringen (CodeBench lite wird ohne ausgeleifert, GCC for ARM embedded von launchpad.org mit).&lt;br /&gt;
&lt;br /&gt;
Mehr dazu in diesem Thread: [http://www.mikrocontroller.net/topic/261021 Floating Pointing Unit STM32F4]&lt;br /&gt;
&lt;br /&gt;
=== Errata vom STM32F4xx die nicht im Errata von ST stehen ===&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/267439#2788478 Aktivieren von DMA], wenn mehr als 3 DMA Kanäle aktiviert werden, kann es sein dass die nicht alle korrekt bedient werden. Auch klappt der DMA mit dem FSMC nicht immer zuverlässig. [https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=%2Fpublic%2FSTe2ecommunities%2Fmcu%2FLists%2Fcortex_mx_stm32%2FWarning%20limit%20simultaneous%20DMAs%20to%202&amp;amp;FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&amp;amp;currentviews=811 siehe hier] [http://blog.frankvh.com/2012/01/13/stm32f2xx-stm32f4xx-dma-maximum-transactions/ und hier]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/260637#2700761 Nerviger Bug in &amp;quot;stm32f4xx.h&amp;quot;] Änderung Struktur GPIO_TypeDef&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/261690#2714754 Batterie wird leer gezogen], nur bei manchen Chips mit Rev. A&lt;br /&gt;
&lt;br /&gt;
== Bezugsquellen ==&lt;br /&gt;
&lt;br /&gt;
=== Controller ===&lt;br /&gt;
&lt;br /&gt;
Versandhäuser für Privatpersonen&lt;br /&gt;
* [http://www.reichelt.de/STM-Controller/2/index.html?;ACTION=2;LA=2;GROUPID=2950; Reichelt]&lt;br /&gt;
* [http://darisusgmbh.de/shop/index.php?cat=c2692_ARM-Cortex.html Darisus]&lt;br /&gt;
* [http://www.hbe-shop.de HBE (Farnell Programm für Private)] &lt;br /&gt;
* [http://www.sander-electronic.de/be00069.html Sander]&lt;br /&gt;
*[http://www.tme.eu/de/katalog/index.phtml#cleanParameters%3D1%26search%3DSTM32F10%26bf_szukaj%3D+ TME] &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Gewerblich liefern natürlich viele wie EBV, Mouser, Farnell, Digikey usw...&lt;br /&gt;
&lt;br /&gt;
=== Evaluation Boards ===&lt;br /&gt;
&lt;br /&gt;
* [http://shop.embedded-projects.net/index.php?module=artikel&amp;amp;action=gruppe&amp;amp;id=14 Im Shop von Embedded Projects]&lt;br /&gt;
* [http://www.watterott.com/de/Boards-Kits/ARM/ARM-Cortex-M3 Cortex M3 bei Watterott]&lt;br /&gt;
* [http://www.raisonance.com/~primer-starter-kits__microcontrollers__tool~tool__T018:4enfvamuxbtp.html Primer und Primer2 von Raisonance]&lt;br /&gt;
* [http://www.sander-electronic.de/es0028.html Sander Electronic]&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/MP32F103-Stick:_Ein_Mini-Mikrocontroller-Board_mit_USB_und_bis_zu_4MB_Datenspeicher Artikel im Wiki, ARM mit USB und 4MB Speicher]&lt;br /&gt;
* [http://www.futurlec.com/STM32_Development_Board.shtml Futurlec Evalboard, ebenso Header-Board]&lt;br /&gt;
* [http://www.propox.com/products/t_174.html Propox, Header-Boards für 103R und 103V sowie Trägerplatine dafür]&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/Cortex_M3_OCM3U Cortex M3 Artikel im Wiki]&lt;br /&gt;
* [http://olimex.com/dev/index.html STM32 bei Olimex]&lt;br /&gt;
* [http://de.farnell.com/jsp/displayProduct.jsp?sku=1824325&amp;amp;action=view&amp;amp;CMP=GRHS-1000962 STM32Discovery bei Farnell] Mikrocontroller Board (STM32F100RBT6B) mit onboard USB-Programming Interface für ca. 12,50€&lt;br /&gt;
* [http://www.de.rs-online.com/web/p/products/7458434/ STM32Discovery bei RS-Components] 12,65 € +MwSt.&lt;br /&gt;
* [http://www.segor.de/#Q=STM32 VL DISCOVERY] STM32 Discovery bei Segor&lt;br /&gt;
* [http://www.watterott.com/de/STM32F4Discovery STM32F4DISCOVERY] STM32F4 Cortex M4 Controller mit JTAG-Debugger auf der Platine bei Watterott für 16,66EUR.&lt;br /&gt;
* [http://www.steitec.net/ARM-Boards/ Steitec, STM32F103 Cortex M3 Board 34,80€]&lt;br /&gt;
* [http://www.mcu-raisonance.com/~open4-development-platform__microcontrollers__tool~tool__T018:g65gu6ghg2n.html/ Open 4 oder auch genannt Evo-Primer]&lt;br /&gt;
* [http://www.wayengineer.com/index.php?main_page=index&amp;amp;cPath=50_66&amp;amp;page=1&amp;amp;sort=3a WayEngineer]&lt;br /&gt;
* [http://thinkembedded.ch/ST-STMicroelectronics:::24.html Im Thinkembedded Shop] in der Schweiz / DiscoveryF4, div. ETT und Olimex Boarde ab 20,18 CHF / 16,15 EUR (inkl. MwSt.) zzgl. Versandkosten&lt;br /&gt;
&lt;br /&gt;
== Weblinks, Foren, Communities, Tutorials ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/173753 Diskussion zum Artikel]&lt;br /&gt;
* [http://www.mikrocontroller.net/forum/mikrocontroller-elektronik?filter=ARM*+STM32*+Cortex* Suche im Forum]&lt;br /&gt;
* [https://my.st.com/public/STe2ecommunities/mcu/Lists/ARM%20CortexM3%20STM32/AllItems.aspx Forum auf der ST Homepage] &lt;br /&gt;
* [http://www.stm32circle.com/hom/index.php STM32 Community] &lt;br /&gt;
*[http://www.arm-forum.de Deutsches ARM-Forum]&lt;br /&gt;
*[http://joe-c.de/pages/posts/einstieg_mikrocontroller_stm32f103_101.php Einstieg:  STM32board mit Kamera (deutsch)] &lt;br /&gt;
* [http://www.ebv.com/fileadmin/products/Press_Print/Brochures/Product_Brochures/EBV_Cortex%20Collection_V2.pdf Übersicht der Cortex Prozessoren und deren Hersteller (nicht nur ST, von EBV)]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/258652 Tutorial]&lt;br /&gt;
* [http://diller-technologies.de/stm32_wide.html STM32 Tutorial in Deutsch von Diller Technologies]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
[[Kategorie:ARM]]&lt;br /&gt;
[[Kategorie:STM32| ]]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=AVR_FAT32&amp;diff=66630</id>
		<title>AVR FAT32</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=AVR_FAT32&amp;diff=66630"/>
		<updated>2012-06-01T14:28:14Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: /* Einfaches Code-Beispiel */  kleinen Schreibfehler korrigiert&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Dies ist eine freie FAT 16/32 Bibliothek.&lt;br /&gt;
Die Bibliothek ist modular und besteht aus folgenden Modulen:&lt;br /&gt;
&lt;br /&gt;
;File-Modul: Bietet high-level Datei-Operationen, wie man sie von Dateizugriffen kennt, z.&amp;amp;nbsp;B. ffopen/ffclose um eine Datei zu öffnen/schließen.&lt;br /&gt;
&lt;br /&gt;
;FAT16/32-Modul: Bietet die grundlegenden Funktionen für den FAT-Zugriff und die Initialisierung der FAT. Es dient als Middleware zwischen low-level Karten-Zugriff und high-level Datei-Operationen. Der größte Teil der des FAT-Protokolls ist dort implementiert.&lt;br /&gt;
&lt;br /&gt;
;MMC/SD-Modul: Dafür zuständig, die Kommunikation mit [[MMC- und SD-Karten]] zu managen. Wie z.&amp;amp;nbsp;B. Initialisierung der Karte oder low-level Routinen zum Schreiben auf die Karte. Es ist das einzige hardwareabhängige Modul.&lt;br /&gt;
&lt;br /&gt;
Es gibt die Möglichkeit über Makros in der config.h den Umfang der Lib zu bestimmen, dies wirkt sich auch stark auf die Codegröße aus.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Mod.jpeg|thumb|right|279px|Schichtmodell der FAT-Implementierung]]&lt;br /&gt;
Die Module sind [http://en.wikipedia.org/wiki/C_(programming_language)#C99 C99] Standard-konform.&lt;br /&gt;
&lt;br /&gt;
== Der Status ==&lt;br /&gt;
&lt;br /&gt;
* Aktuelle Version: [http://www.mikrocontroller.net/attachment/116369/AVR-mmc-0.6.4.zip AVR Version 0.6.4]&lt;br /&gt;
* Bekannte Probleme: Bei software SPI läuft die Initialisierung nicht mit 400 KHz, das gibt bei einigen Karten Probleme. Bei der Aktuellen Version ist Multi-block ungetestet.&lt;br /&gt;
* Problem melden, oder sonstige Anfrage: hier [http://www.mikrocontroller.net/topic/105869#new Thread.]&lt;br /&gt;
&lt;br /&gt;
== Funktionalität ==&lt;br /&gt;
&lt;br /&gt;
=== Code einbinden ===&lt;br /&gt;
&lt;br /&gt;
Die Module werden über die *.h Dateien bekannt gemacht. Zudem müssen noch die dazugehörigen *.c Dateien eingebunden werden. Es gibt mehrere Möglichkeiten dies zu tun. Einmal im Makefile im Bereich der &amp;quot;c source files&amp;quot; oder bei &lt;br /&gt;
[http://de.wikipedia.org/wiki/Integrierte_Entwicklungsumgebung IDEs] &lt;br /&gt;
über einen Dialog der das Gleiche macht.&lt;br /&gt;
&lt;br /&gt;
=== Die Funktionalität ===&lt;br /&gt;
&lt;br /&gt;
In der Datei config.h gibt es Möglichkeiten die Bibliothek zu konfigurieren.&amp;lt;br&amp;gt; &lt;br /&gt;
Folgende Funktionen werden unterstützt (FAT16/32):&lt;br /&gt;
* Lesen, Schreiben und Überschreiben von Dateien.&lt;br /&gt;
* Vor- und Rückspulen in Dateien.&lt;br /&gt;
* Anlegen von Ordnern&lt;br /&gt;
* Wechseln von Verzeichnissen&lt;br /&gt;
* Löschen von Dateien und Ordnern, bei Ordnern Rekursiv.&lt;br /&gt;
* Ermitteln der freien Bytes auf der Karte&lt;br /&gt;
* Schnelleres Schreiben und Lesen durch Multi-Block Operationen.&lt;br /&gt;
* Kartenunterstützung für MMC/SD/[http://de.wikipedia.org/wiki/SD_Memory_Card#SDHC_.28SD_2.0.29 SDHC].&lt;br /&gt;
* Falls eine [[AVR_-_Die_genaue_Sekunde_/_RTC|RTC]] vorhanden ist, kann bei den Dateioperationen die Zeitstempel Funktionalität genutzt werden.&lt;br /&gt;
* Anbindung der Karte über Software [[Serial_Peripheral_Interface|SPI]] oder Hardware SPI&lt;br /&gt;
&lt;br /&gt;
==== Die Schalter ====&lt;br /&gt;
&lt;br /&gt;
Hier ein Auszug aus der config.h mit den wichtigsten Parametern: &lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#define MMC_SMALL_FILE_SYSTEM 	TRUE&lt;br /&gt;
#define MMC_WRITE		TRUE	&lt;br /&gt;
#define MMC_OVER_WRITE 		FALSE&lt;br /&gt;
#define MMC_MULTI_BLOCK 	FALSE&lt;br /&gt;
#define MMC_SDHC_SUPPORT	TRUE&lt;br /&gt;
#define MMC_TIME_STAMP 		FALSE&lt;br /&gt;
 &lt;br /&gt;
#define MMC_MAX_SPEED 		TRUE&lt;br /&gt;
&lt;br /&gt;
#define MMC_SOFT_SPI 		FALSE&lt;br /&gt;
&lt;br /&gt;
#define MMC_MAX_CLUSTERS_IN_ROW 256&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Bedeutung der Schalter ====&lt;br /&gt;
&lt;br /&gt;
;MMC_SMALL_FILE_SYSTEM: TRUE, oder FALSE. Bestimmt den Funktionsumfang der Lib. Es fallen folgende Funktionalitäten raus: ffcd(), fat_str(), ffls(), ffcdLower(), ffmkdir() und ffrm() der Teil mit Ordnern rekursiv löschen. (&amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; = Komplette Unterstützung)&lt;br /&gt;
&lt;br /&gt;
;MMC_WRITE: TRUE oder FALSE. Bestimmt, ob Schreibunterstützung einkompiliert wird oder nicht: TRUE = Write an&lt;br /&gt;
&lt;br /&gt;
;MMC_OVER_WRITE: TRUE oder FALSE. Bestimmt, ob ffwrite() mit Überschreiben-Funktionalität compiliert wird oder nicht. Überschreiben von Dateien ist nicht so performant. Siehe auch: [[AVR_FAT32#Interne_Technik|Interne Technik]]. TRUE = Dateien überschreiben&lt;br /&gt;
&lt;br /&gt;
;MMC_MULTI_BLOCK: TRUE oder FALSE. Legt fest, ob mit MultiBlock Read/Write Unterstützung compiliert wird oder nicht. Geht nur, wenn OVER_WRITE FALSE ist! TRUE = MultiBlock Operation&lt;br /&gt;
&lt;br /&gt;
;MMC_MAX_SPEED: TRUE oder FALSE. Legt fest, ob nach der Initialisierung der MMC/SD-Karte mit maximalem Speed geschrieben/gelesen wird oder nicht. Zum Testen, wenn man nicht sicher ist, ob die Hardware die maximale Geschwindigkeit mitmacht, empfiehlt sich FALSE als Wert.&lt;br /&gt;
&lt;br /&gt;
;MMC_MAX_CLUSTERS_IN_ROW: 1-500. Gibt an, wie viele Cluster, leer oder verkettet die zusammenhängen, gesucht werden sollen. Hier muss man den Overhead des Suchens abwägen, gegen die Zeit, die z.&amp;amp;nbsp;B. benötigt wird, 500 Cluster in der FAT zu verketten. Siehe auch: [[AVR_FAT32#Interne_Technik|Interne Technik]]&lt;br /&gt;
&lt;br /&gt;
;MMC_SDHC_SUPPORT: TRUE oder FALSE. Legt fest, ob mit SDHC-Unterstützung compiliert wird oder ohne. Der [http://de.wikipedia.org/wiki/SD_Memory_Card#SDHC_.28SD_2.0.29 SD Standard 2.0] wird damit unterstützt, also Karten bis 32 GB Größe.&lt;br /&gt;
&lt;br /&gt;
;MMC_TIME_STAMP: TRUE oder FALSE. Legt fest, ob die Zeitstempel-Unterstützung mit compiliert wird oder nicht. Wenn TRUE, dann wird das Erstelldatum und die Erstellzeit eingetragen. Bei weiteren Schreibzugriffen auf die Datei wird dann auch das Zugriffsdatum und die Zugriffszeit eingetragen. Es müssen dafür auch 2 Funktionen in der fat.c mit Code gefüllt werden, damit diese das Datum und die Zeit liefern.&lt;br /&gt;
&lt;br /&gt;
;MMC_SOFT_SPI: TRUE oder FALSE. Legt fest, ob mit Software-SPI Unterstützung compiliert wird oder nicht. Wenn TRUE, muss in der mmc.h noch eingetragen werden, welche Pins als SPI-Interface benutzt werden sollen. Es werden nur Pins des selben Ports unterstützt. Also z.&amp;amp;nbsp;B. nur Pins von Port B.&lt;br /&gt;
&lt;br /&gt;
==== Die C-Funktionen ====&lt;br /&gt;
&lt;br /&gt;
Das Modul FILE bietet in der Standard-Konfiguration folgende für den Nutzer interessante Funktionen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
unsigned char ffread(void)&lt;br /&gt;
void          ffwrite(unsigned char c)&lt;br /&gt;
void          ffwrites(unsigned char *s)&lt;br /&gt;
unsigned char ffopen(unsigned char name[])&lt;br /&gt;
unsigned char ffclose(void)&lt;br /&gt;
void          ffseek(unsigned long int offset)&lt;br /&gt;
unsigned char ffcd(unsigned char name[])&lt;br /&gt;
void          ffls(fptr uputs_ptr)&lt;br /&gt;
unsigned char ffcdLower(void)&lt;br /&gt;
unsigned char ffrm(unsigned char name[])&lt;br /&gt;
unsigned char ffmkdir(unsigned char name[])&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Modul MMC/SD bietet für den Nutzer direkt nur eine interessante Funktion:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
unsigned char mmc_init(void)&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Modul FAT bietet für den Nutzer direkt nur zwei interessante Funktionen:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
unsigned char fat_loadFatData(void)&lt;br /&gt;
unsigned long long int fat_getFreeBytes(void)&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für die Anwendungen der Funktionen gibt es Beispiele, Kommentare und Dokumentation in den [[AVR_FAT32#Sourcen|Sourcen]]. Ein einfaches Beispiel gibt es im Abschnitt &#039;&#039;[[AVR_FAT32#Einfaches Code-Beispiel|Einfaches Code-Beispiel]]&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Alle Funktionen, die mit FAT-Namen in Zusammenhang stehen (Datei- und Ordner-Namen), müssen folgende Konvention erfüllen:&lt;br /&gt;
* Die FAT-Namenskonvention ist immer 8.3, das heißt, ein Datei-Name mit maximal 8 Zeichen und eine Datei-Endung maximal 3 Zeichen lang.&lt;br /&gt;
* Ein Dateiname &amp;lt;tt&amp;gt;&amp;quot;test.txt&amp;quot;&amp;lt;/tt&amp;gt; &#039;&#039;muss&#039;&#039; in &amp;lt;tt&amp;gt;&amp;quot;TEST&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;TXT&amp;quot;&amp;lt;/tt&amp;gt; gewandelt werden! Noch ein Beispiel: &amp;lt;tt&amp;gt;&amp;quot;MAIN&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;C&amp;amp;nbsp;&amp;amp;nbsp;&amp;quot;&amp;lt;/tt&amp;gt; = &amp;lt;tt&amp;gt;&amp;quot;main.c&amp;quot;&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nur vFAT unterstützt lange Datei-Namen.&lt;br /&gt;
&lt;br /&gt;
=== Interne Technik ===&lt;br /&gt;
&lt;br /&gt;
In der Regel wird das Schicht-Modell eingehalten. Das heißt, jedes Modul nutzt nur die Funktionen aus der Schicht darunter. Es gibt allerdings Ausnahmen aus Gründen der Code-Größe. Beispiel: ffwrite nutzt direkt die Funktion mmc_write_sector(sector) aus dem Modul mmc.c. Aufgrund der Namenskonvention ist aber leicht zu erkennen, woher die Funktion kommt.&lt;br /&gt;
&lt;br /&gt;
Im Modul fat gibt es &amp;quot;Daten-Ketten&amp;quot;. Die Aufgaben sind atomar aufgeteilt. Zum Lesen von Daten sind beispielsweise die Funktionalitäten, Lesen eines Sektors, Auswerten der Information und weitere Entscheidung (nächsten Sektor Laden usw.) nötig. Die Idee dabei ist, die Funktionen der atomaren Aufgabe nach zu implementieren.&lt;br /&gt;
&lt;br /&gt;
Beispielkette:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
fat_loadSector -&amp;gt; fat_loadRowOfSector -&amp;gt; fat_loadFileDataFromCluster -&amp;gt; fat_loadFileDataFromDir&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
[[Image:FAT-CallTree.png|thumb|right|260px|Funktionsübersicht der FAT-Imple&amp;amp;shy;men&amp;amp;shy;tierung. Viele der Funktionen enden in Schreib&amp;amp;shy;opera&amp;amp;shy;tionen, weil das Diagramm mit der Option MMC_OVER_WRITE TRUE erstellt wurde.]]&lt;br /&gt;
Diese Kette wird beispielsweise beim Öffnen einer Datei durchlaufen. Um die Datei zu öffnen, muss man wissen, ob es die Datei im aktuellen Verzeichnis gibt. Um das herauszufinden, muss man den ersten Sektor des Verzeichnisses laden. Dann muss man die Reihen (immer 32 Byte am Stück), also Datei/Ordner-Einträge des Sektors prüfen. Da ein Cluster aus verschiedenen Sektoren bestehen kann, müssen diese auch geprüft werden. Als letzte logische Einheit müssen jetzt noch die verketteten Cluster geprüft werden, also das ganze Verzeichnis. Ist diese Kette so durchlaufen, weiß man, ob die Datei da ist oder nicht.&lt;br /&gt;
&lt;br /&gt;
==== Lesen ====&lt;br /&gt;
&lt;br /&gt;
Beim Lesen einer Datei wird in der FAT nach verketteten Clustern gesucht. Bei einer unfragmentierten FAT liegen im Idealfall alle Cluster in einer Reihe. Dies wird ausgenutzt:&lt;br /&gt;
&lt;br /&gt;
Es wird der erste Cluster der Datei gesucht und solange gesucht, bis MAX_CLUSTERS_IN_ROW am Stück gefunden wurden oder ein Abbruch der Kette erkannt wird. Wird ein Abbruch erkannt, wird das bekannte Teilstück der kompletten Kette gelesen, danach wird das nächste Teilstück gesucht, bis die ganze Kette durchlaufen wurde.&lt;br /&gt;
&lt;br /&gt;
Bei einer unfragmentierten FAT kann man oft die ganze Datei lesen ohne einen weiteren FAT-Lookup. Das ist sehr effizient.&lt;br /&gt;
&lt;br /&gt;
==== Schreiben ====&lt;br /&gt;
&lt;br /&gt;
Beim Schreiben einer Datei wird in der FAT nach leeren Clustern gesucht. Bei einer unfragmentierten FAT liegen diese im Idealfall alle nebeneinander. Das wird ausgenutzt:&lt;br /&gt;
# Es werden ab Cluster Nr. 2, MAX_CLUSTERS_IN_ROW am Stück gesucht, oder so viele, wie es freie am Stück gibt.&lt;br /&gt;
# Diese (also die Sektoren die mit diesen Clusternummern in Zusammenhang stehen) werden beschrieben. Sind genügend freie Cluster für die Datei-Daten bekannt, werden diese verkettet und man ist fertig.&lt;br /&gt;
# Sind nicht genügend freie Cluster bekannt, wird die erste Teilkette verkettet und die letzte Cluster-Nummer dieser Kette gesichert (file.lastCluster). Danach werden neue Cluster gesucht.&lt;br /&gt;
# Sind immer noch nicht genügend freie Cluster bekannt, werden die beiden Teilketten verkettet (wo die alte aufhört weiß man durch file.lastCluster). Weiter bei 2.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Bei beiden Methoden&#039;&#039; kann es zu größerem [http://de.wikipedia.org/wiki/Overhead_(EDV) Overhead] kommen, wenn die FAT fragmentiert ist. Im Extremfall ist immer nur ein Cluster am Stück frei bzw. verkettet.&lt;br /&gt;
&lt;br /&gt;
=== Die Richtlinien ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Allgemein:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es ist immer darauf zu achten, dass es sich bei MMC/SD-Karten um Flash-Speicher handelt, dieser ist NICHT unendlich oft beschreibbar. Die Schreiben/Anhängen- und Löschen- Funktionalitäten sollten so selten wie möglich benutzt werden! &amp;lt;br&amp;gt;&lt;br /&gt;
Eine SD Karte besitzt einen eigenen Controller in der Karte, der auf den eigentlichen Flash-Speicher schreibt. So können die logischen von den physikalischen Sektoren getrennt werden (Wear Leveling). Also gibt es nicht so viele Schreib Vorgänge auf dem gleichen Sektor, weil der Karten Controller den logischen Sektor auf einen anderen physikalischen schreibt. &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Siehe Auch: [http://de.wikipedia.org/wiki/SD_Memory_Card Wikipedia SD Karten] , und [[MMC- und SD-Karten]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Richtlinien stable-mmc-0.5.x:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Wenn eine Datei zum schreiben geöffnet ist, aber gerade keine Daten zum schreiben vorliegen, bringt es keinen Vorteil (Strom oder Geschwindigkeit) die Datei zu schließen, wenn später noch Daten geschrieben werden sollen. Bei jedem ffclose, wird der Datei Eintrag aktualisiert, also dieser Sektor geschrieben (möglicherweise zusätzlich sogar ein FAT-Sektor).&lt;br /&gt;
&lt;br /&gt;
Oftmaliges anlegen und löschen einer Datei schreibt immer die selben (logischen) Sektoren. Besser nicht löschen und einfach neu anlegen, mit anderem Namen, oder überschreiben, da dabei die schon verketteten FAT-Sektoren nicht nochmals beschrieben werden, sondern nur die Daten Sektoren überschrieben werden.&lt;br /&gt;
&lt;br /&gt;
== Beispiel-Beschaltung==&lt;br /&gt;
&lt;br /&gt;
=== Schaltplan ===&lt;br /&gt;
[[Bild:Schaltplan.jpeg|thumb|right|260px|Schaltplan]]&lt;br /&gt;
&lt;br /&gt;
MMC/SD-Karten brauchen 3,3 Volt. Wenn der Controller mit 5 Volt arbeitet, muss man die Spannungspegel anpassen. Arbeitet der Controller auch mit 3,3 Volt, kann man alle Leitungen direkt mit der Karte verbinden.&lt;br /&gt;
&lt;br /&gt;
Als Beispiel für die mögliche Frequenz des hier verwendeten HC4050 zur Pegelwandlung: bei +125 °C und VCC von 2 V wird das Propagationdelay mit Max 130 ns angegeben. Das macht ungefähr 7,6 MHz maximal mögliche Frequenz. Bis +85 °C und VCC von 2 V geht es bis 9,5 MHz. Da aber hier 3,3 Volt anliegen, wird er in allen Bereichen etwas schneller sein.&lt;br /&gt;
Siehe Datenblatt für mehr Infos oder [[Pegelwandler]].&lt;br /&gt;
&lt;br /&gt;
Benutzt wird der [[Serial Peripheral Interface|SPI]]-Port des Controllers (bis auf Slave Select, hier PB1). Es wäre aber auch Software-basiertes SPI möglich, siehe hierfür auch Abschnitt &#039;&#039;[[AVR_FAT32#Die Funktionalität|Die Funktionalität]]&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Die Kondensatoren C1 und C2 (100nF) dienen nur zum Entstören (möglichst nah an ICs)und sollten an jedes digitale IC in einer Schaltung.&lt;br /&gt;
Die MMC/SD-Leiste kann eine richtige Halterung sein. Was auch sehr gut passt ist ein Stück ISA-Bus Buchse eines alten Mainboards (nur MMC-Karten). Die Abstände passen gut. Einfach vom Board flexen und dann kleine Kabel an den Stecker löten (da wo man unten jetzt das Metall sieht)&lt;br /&gt;
&lt;br /&gt;
Das HC4050 IC ist ein &amp;quot;high to low&amp;quot; Level-Shifter. Es sorgt dafür, dass die 3 abgehenden Signale des µC auf 3.3 Volt gebracht werden. Das abgehende Signal der Karte zum Controller wird auch so als logisch high erkannt.&lt;br /&gt;
&lt;br /&gt;
;Achtung: Die Anschlussart mit einem normalen Pegelwandler wie im Bild rechts birgt jedoch die Gefahr der Zerstörung der SD Karte. Nämlich genau dann, wenn einmal (z.B. falsche Portdeklaration) versehentlich die MISO-Leitung an 5V liegt oder wenn noch ein weiterer 5V-Teilnehmer am SPI-Bus hängt und 5V Signale einspeist. Dann liegen am Datenausgang der SD-Karte nämlich plötzlich 5V an, und das ist fatal. Besser und professioneller sind sog. birektionale Pegelwandler, die alle Datensignale in beide Richtungen von 5V ↔ 3,3V transferieren. Eine Bezugsquelle für ein fertiges Kartenmodul inkl. birektionalem Pegelwandler ist z.B. [http://www.shop.display3000.com/elektronikmodule/sd-kartenmodul/index.html Display3000]. Tipp: ganz an das Ende scrollen, dort gibt es ein paar anschauliche Informationen.&lt;br /&gt;
&lt;br /&gt;
=== Pinbelegung MMC/SD/SDHC ===&lt;br /&gt;
&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
|[[Bild:pinout-mmc.png|thumb|left|260px|Pinout MMC-Karte]]&lt;br /&gt;
|[[Bild:pinout-sd-sdhc.png|thumb|right|260px|Pinout SD/SDHC-Karte]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
:{| {{Tabelle}}&lt;br /&gt;
|- bgcolor=&amp;quot;#e0e0ff&amp;quot;&lt;br /&gt;
!Pin-Nr. Karte || Pin Karte || Funktion || Pin-Nr. µC || Pin µC || Funktion&lt;br /&gt;
|-&lt;br /&gt;
| 1 || CS || Chip Select || 15 || PB1 || Cusom Slave Select&lt;br /&gt;
|-&lt;br /&gt;
| 2 || DI || Data In || 17 || PB3 (MOSI) || Master Out, Slave In&lt;br /&gt;
|-&lt;br /&gt;
| 3 || GND ||  ||  ||  ||  &lt;br /&gt;
|-&lt;br /&gt;
| 4 || VCC ||  ||  ||  ||  &lt;br /&gt;
|-&lt;br /&gt;
| 5 || CLK || Clock || 19 || PB5 (SCK) || Clock&lt;br /&gt;
|-&lt;br /&gt;
| 6 || GND ||  ||  ||  ||  &lt;br /&gt;
|-&lt;br /&gt;
| 7 || DO || Data Out || 18 || PB4 (MISO) || Master In, Slave Out&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Der Code ==&lt;br /&gt;
&lt;br /&gt;
=== Sourcen ===&lt;br /&gt;
&lt;br /&gt;
* Hier immer die Aktuellste Version mit Informationen dazu [http://www.mikrocontroller.net/articles/AVR_FAT32#Der_Status FAT16/32].&lt;br /&gt;
* Achtung! Nur noch alte Version im SVN.&lt;br /&gt;
&lt;br /&gt;
Sourcecode mit Linux Makefile und als AvrStudio-Projekt auf: [http://www.mikrocontroller.net/svnbrowser/avr-fat32 Alte Versionen SVN AVR-Fat32]&lt;br /&gt;
&lt;br /&gt;
=== Einfaches Code-Beispiel ===&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel um in eine Datei zu schreiben/anhängen und wieder zu lesen:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// In mmc_config.h werden alle nötigen Konfigurationen vorgenommen&lt;br /&gt;
#include &amp;quot;mmc_config.h&amp;quot;&lt;br /&gt;
#include &amp;quot;file.h&amp;quot;&lt;br /&gt;
#include &amp;quot;fat.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
// Hardwareabhängig&lt;br /&gt;
#include &amp;quot;mmc.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
// Hardwareabhängig, es kann auch eine eigene eingebunden werden !		&lt;br /&gt;
#include &amp;quot;uart.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//**************************************************************************&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
	// Uart-Initialisierung zu Ausgabe von Daten.&lt;br /&gt;
	uinit();&lt;br /&gt;
&lt;br /&gt;
	uputs (&amp;quot;\nBoot&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	// Versuch Karte zu Initialisieren, bis es klappt.&lt;br /&gt;
	// Unbedingt so, weil die Initialisierung nicht immer&lt;br /&gt;
	// auf Anhieb klappt.&lt;br /&gt;
	while (FALSE == mmc_init())&lt;br /&gt;
	{&lt;br /&gt;
		nop();&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	uputs (&amp;quot;...&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	// Fat initialisieren. Nur wenn das klappt sind weitere&lt;br /&gt;
	// Aktionen sinnvoll, sonst endet das Programm.&lt;br /&gt;
	if (!fat_loadFatData())&lt;br /&gt;
  	    return -1;&lt;br /&gt;
&lt;br /&gt;
	// Wenn auf dem terminal &amp;quot;Boot... OK&amp;quot; zu lesen ist, ist Init OK.&lt;br /&gt;
	// Jetzt kann man Schreiben/Anhängen/Lesen.&lt;br /&gt;
	uputs (&amp;quot;Ok\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	// Dateinamen muessen in diesem Format sein&lt;br /&gt;
	// Man beachte die Größe des Arrays und die Großbuchstaben!&lt;br /&gt;
	unsigned char file_name[] = &amp;quot;test.txt&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	// String zum in die Datei schreiben.&lt;br /&gt;
	char str[] = &amp;quot;Hallo Datei!&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	// Wenn Datei nicht existiert&lt;br /&gt;
	if (FALSE == ffileExsists(file_name))&lt;br /&gt;
	{&lt;br /&gt;
            ffopen(file_name, &#039;c&#039;); //Datei existiert nicht, also anlegen&lt;br /&gt;
	    // Schreibt String auf Karte.&lt;br /&gt;
	    // Nur richtige Strings koennen mit ffwrites geschrieben werden.&lt;br /&gt;
	    ffwrites (str);&lt;br /&gt;
&lt;br /&gt;
	    // Neue Zeile in der Datei.&lt;br /&gt;
            // Schreibt Zeilenumbruch in die Text Datei.&lt;br /&gt;
	    ffwrite (&#039;\n&#039;);&lt;br /&gt;
	    // Für MS-Windows Terminal &#039;\r&#039; anhängen.&lt;br /&gt;
	    ffwrite (&#039;\r&#039;);&lt;br /&gt;
&lt;br /&gt;
	    // Schließt Datei.&lt;br /&gt;
	    ffclose();&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// Datei existiert, also anhaengen !&lt;br /&gt;
	if (TRUE == ffileExsists(file_name))&lt;br /&gt;
	{&lt;br /&gt;
            ffopen (file_name, &#039;c&#039;);&lt;br /&gt;
	    // Spult bis zum Dateiende vor um anzuhaengen.&lt;br /&gt;
	    // Geht auch ohne Option MMC_OVER_WRITE&lt;br /&gt;
	    ffseek (file.length);&lt;br /&gt;
&lt;br /&gt;
	    // Schreibt String.&lt;br /&gt;
	    ffwrites(str);&lt;br /&gt;
&lt;br /&gt;
	    // Neue Zeile in der Datei.&lt;br /&gt;
            // Schreibt Zeilenumbruch in die Textdatei.&lt;br /&gt;
	    ffwrite (&#039;\n&#039;);&lt;br /&gt;
	    // Für MS-Windows Terminal &#039;\r&#039; anhängen.&lt;br /&gt;
	    ffwrite (&#039;\r&#039;);&lt;br /&gt;
&lt;br /&gt;
	    // Schließt Datei.&lt;br /&gt;
	    ffclose();&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// Datei existiert, also lesen.&lt;br /&gt;
	// Gerade angelegt und beschrieben, oder war schon vorhanden&lt;br /&gt;
	// und es wurde was angehaengt?&lt;br /&gt;
	if (TRUE == ffileExsists(file_name))&lt;br /&gt;
	{&lt;br /&gt;
            ffopen (file_name, &#039;r&#039;);&lt;br /&gt;
	    // Setzen einer Variable und dann runterzählen geht&lt;br /&gt;
	    // am schnellsten&lt;br /&gt;
	    unsigned long int seek = file.length;&lt;br /&gt;
&lt;br /&gt;
	    // Lesen eines chars und Ausgabe des chars.&lt;br /&gt;
	    // Solange bis komplette Datei gelesen wurde.&lt;br /&gt;
	    do {&lt;br /&gt;
	        uputc (ffread());&lt;br /&gt;
	    } while (--seek);&lt;br /&gt;
&lt;br /&gt;
	    ffclose();&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== FAT 32 Grundlegendes ==&lt;br /&gt;
&lt;br /&gt;
[[Bild:fat32.png|thumb|right|250px|Grundlegende FAT32-Struktur]]&lt;br /&gt;
&lt;br /&gt;
Ein Dateisystem des Typs FAT besteht aus mehreren Bereichen.&lt;br /&gt;
FAT ist immer [http://de.wikipedia.org/wiki/Byte-Reihenfolge little Endian].&lt;br /&gt;
Ein Dateisystem wie FAT32 ist ein Verwaltungsinstrument. Der FAT16/32 Standard beschreibt die Art und Weise wie die Daten Verwaltet werden.&lt;br /&gt;
&lt;br /&gt;
Im Folgenden werden die Schritte, die nötig sind, um Daten aus dem System zu lesen und in das System zu schreiben, erläutert. Die Zahlenbeispiele und Bilder sollen ein praktisches Beispiel geben. Zum Verständnis empfiehlt es sich, das ganze Kapitel FAT32 durchzulesen.&lt;br /&gt;
 &lt;br /&gt;
* Der erste Teil ist der Sektor 0 oder LBA. In dem Sektor stehen die nötigen Informationen, um mit dem Auslesen beginnen zu können.&lt;br /&gt;
* Dann folgt die FAT selbst, also die Dateizuordnungstabelle.&lt;br /&gt;
* Der dritte Teil ist der Daten-Bereich, in dem beispielsweise Dateieinträge/Ordnereinträge oder Daten stehen.&lt;br /&gt;
&lt;br /&gt;
FAT bedeutet &#039;&#039;File Allocation Table&#039;&#039; (Dateizuordnungstabelle). &#039;&#039;Dateizuordnungstabelle&#039;&#039; beschreibt schon das Prinzip der FAT: &lt;br /&gt;
Kern des Dateisystems ist eine einfach verkettete Liste, in der festgehalten wird, wo sich die Daten befinden: die Dateizuordnungstabelle.&lt;br /&gt;
In dieser Tabelle werden Cluster verkettet. Diese verketteten Cluster können Dateien oder Ordner bilden. Dazu später mehr.&lt;br /&gt;
&lt;br /&gt;
Der Unterschied zwischen FAT32 und FAT16 besteht darin, dass ein FAT16-Dateisystem noch einen speziellen Teil hat. Das Root-Dir ist nicht einfach ein weiterer Ordner wie bei FAT32, sondern ein festgelegter Teil, der Platz für 512 Einträge bietet. FAT-Einträge bei FAT16 sind nur 2 Byte groß. Der Rest ist gleich.&lt;br /&gt;
&lt;br /&gt;
=== Sektor 0 oder LBA ===&lt;br /&gt;
&lt;br /&gt;
[[Bild:sektor0.jpeg|thumb|right|250px|&#039;&#039;&#039;Bild 1:&#039;&#039;&#039; Sektor 0 (512 Byte) bei einer unpartitionierten Karte]]&lt;br /&gt;
Um das Dateisystem lesen zu können, muss man wissen, wo was steht. Die Informationen sind: &lt;br /&gt;
&lt;br /&gt;
* Sektoren pro Cluster (rot)&lt;br /&gt;
* Reservierte Sektoren nach Sektor 0 (orange)&lt;br /&gt;
* Anzahl der FATs (gelb)&lt;br /&gt;
* Wieviele Sektoren von einer FAT belegt werden (grün)&lt;br /&gt;
* Der Root-Dir Cluster (blau)&lt;br /&gt;
&lt;br /&gt;
Aus diesen Daten ergibt sich demnach:&lt;br /&gt;
&lt;br /&gt;
* 1. Sektor der 1. FAT ist Sektor 32 ([[AVR_FAT32#Die_FAT|Bild 2]]), also der erste Sektor nach der Anzahl der Reservierten (orange).&lt;br /&gt;
* Der erste Daten Cluster ist 1003, weil die Anzahl der FATs 1 ist, also einmal die Sektoren, die von einer FAT belegt werden (grün) (00003cb=971) 971 + 32 (orange) = 1003.&lt;br /&gt;
* Das Root-Dir ist Cluster 2, also Sektor 1003.&lt;br /&gt;
* Die Anzahl der Sektoren pro Cluster ist 4 (2048 Bytes/Cluster).&lt;br /&gt;
&lt;br /&gt;
Damit sind alle nötigen Daten vorhanden.&lt;br /&gt;
&lt;br /&gt;
Man weiß jetzt, wo das Root-Dir beginnt. Ab da spannt sich der Verzeichnisbaum auf. So kann man alle Dateieinträge lesen. Es sind also alle Informationen, mit der man das Lesen einer Datei beginnen kann, bekannt, bzw. man weiß, wo man beim Schreiben einen Dateieintrag machen muss. Um eine Datei aber vollständig lesen zu können, muss man alle Cluster kennen, die zu der Datei gehören. Da kommt die FAT-Tabelle ins Spiel, von der man die 1. Sektornummer kennt. Dort stehen ab dem 1. Cluster der Datei, verkettet alle Folgecluster.&lt;br /&gt;
&lt;br /&gt;
Bei FAT-Dateisystemen können mehrere Sektoren (512 Bytes) logisch zu Clustern zusammengeschlossen werden. Ein Cluster ist für eine Datei die kleinste Speichereinheit. Das hat zur Folge, dass eine 100 Byte große Datei eventuell 2048 Bytes im Dateisystem belegt. Die rote Zahl gibt an, wieviele Sektoren einen Cluster bilden. Der Datenbereich wird immer in Clustern angegeben, das macht die Umrechnung von Sektoren zu Clustern nötig. In diesem Fall ist Cluster 2 der absolute Sektor 1003.&lt;br /&gt;
&lt;br /&gt;
=== Die FAT ===&lt;br /&gt;
 &lt;br /&gt;
Folgendes Bild zeigt den ersten FAT-Sektor (512 Bytes) eines FAT32 Dateisystems (nicht den ersten Sektor der Karte). Eingetragen sind: Root-Dir und zwei darin enthaltene Ordner sowie eine Datei mit 60.000 Bytes Größe.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Fat32.jpeg|thumb|right|250px|&#039;&#039;&#039;Bild 2:&#039;&#039;&#039; 1. FAT-Sektor, hier Sektor 32]]&lt;br /&gt;
Die Einträge 0-7 sind immer reserviert (Quasi Cluster 0 und 1)! Also beginnt die FAT ab 8 (rot, Cluster Nummer 2). Der erste Eintrag (rot) ist 4 Byte groß und zu lesen von Stelle 8 zu Stelle 11 weil little Endian, also umgedrehte Wertigkeit. 8 niedrigste Wertigkeit, dann 9 eins höher, 10 noch eine höher und 11 höchste (dazu später noch ein Beispiel).&lt;br /&gt;
Wie von Microsoft empfohlen ist der erste mögliche Cluster das Root-Dir (rot). Welches hier nur einen Cluster lang ist.&lt;br /&gt;
&lt;br /&gt;
An den gelben Einträgen wird die einfach verkettete Liste der FAT deutlich. Der erste gelbe Eintrag steht an der Stelle des Clusters Nummer 5 und hat als Inhalt eine 6. Das bedeutet: Cluster 5 und 6 gehören zusammen. Würde an der Stelle des Clusters Nummer 5 ein FFFFFF0F stehen (little Endian) ist nur der Cluster 5 mit Daten belegt (wie bei rot, blau und grün).&lt;br /&gt;
So tastet man sich vom ersten Cluster einer Datei bis zum Letzten Cluster einer Datei vor. Das ist der einzige Zweck der FAT (mit FAT ist hier die eigentliche Tabelle gemeint).&lt;br /&gt;
&lt;br /&gt;
Woher bekommt man aber den 1. Cluster einer Datei?&lt;br /&gt;
&lt;br /&gt;
=== Daten ===&lt;br /&gt;
&lt;br /&gt;
[[Bild:Data.jpeg|right|thumb|250px|&#039;&#039;&#039;Bild 3:&#039;&#039;&#039; Inhalt eines Ordners/Directories, hier Cluster 4]]&lt;br /&gt;
&lt;br /&gt;
Ein Dateieintrag besteht aus 32 Bytes und liegt in einem Ordner/Dir im Datenbereich des Dateisystems ( 32 Bytes = eine Zeile).&lt;br /&gt;
&lt;br /&gt;
Dies ist der 1. Cluster eines Ordners. Hier sieht man den &amp;quot;.&amp;quot; bzw &amp;quot;..&amp;quot; Eintrag in Zeile 1 bzw. 2. Diese beiden Einträge sind in jedem ersten Cluster eines Ordners vorhanden. Außer im Root-Dir, von dort spannt sich der Verzeichnis Baum ja erst auf. Der &amp;quot;.&amp;quot; Eintrag hat als 1. Cluster Eintrag den eigenen Cluster, hier 4. Der &amp;quot;..&amp;quot; Eintrag ist interessanter, weil er den 1. Cluster des Übergeordneten Ordners enthält, hier 3. Ist der Übergeordnete Ordner das Root-Dir, ist der 1. Cluster Eintrag 0. Diese beiden Einträge werden in der Lib genutzt um rekursiv zu löschen.&lt;br /&gt;
&lt;br /&gt;
Die dritte Zeile des Bilds zeigt eine Datei namens TEST3.TXT (grün) mit 60.000 Bytes Größe (blau) und dem 1. Cluster 5,damit ist immer der 1. Daten Cluster gemeint (rot, Folgecluster siehe [[AVR_FAT32#Die_FAT|Bild 2]]). Speziell ist hier, dass die 4 Bytes des ersten Clusters aufgeteilt sind auf 2 unterschiedliche &amp;quot;Orte&amp;quot; im 32 Byte Eintrag (Wertigkeit: 26:27:20:21).&lt;br /&gt;
&lt;br /&gt;
Um nun die Daten der Datei lesen zu können, muss man die Daten Cluster kennen. Der erste Daten Cluster steht im Datei Eintrag, hier Cluster 5. Für die Folgenden sieht man in der FAT nach. Dort stehen die Folgecluster der Datei. An der Stelle des ersten Clusters der Datei Cluster 5 steht eine 6, d.h. der nächste Cluster ist 6. In dieser Form ist die FAT verkettet. Wenn in der FAT der letzte Cluster erreicht ist, inhalt des Clusters ist FFFFFFF0, liest man den letzten Sektor bis man insgesammt die Größe der Datei (blau) gelesen hat und ist fertig.&lt;br /&gt;
&lt;br /&gt;
=== Root Dir ===&lt;br /&gt;
&lt;br /&gt;
[[Bild:Dir.jpeg|thumb|right|250px|&#039;&#039;&#039;Bild 4:&#039;&#039;&#039; Root des Dateisystems, hier Cluster 2]]&lt;br /&gt;
Die Sektornummer des Root-Dirs, bei FAT32, wird aus Sektor 0 oder dem LBA ausgelesen (siehe [[AVR_FAT32#Sektor_0_oder_LBA|Bild 1]]). Zu Sehen ist hier in der ersten Zeile ein 32 Byte Eintrag eines Ordners. Zu erkennen ist dieser am Datei Attribut 0x10 an Stelle 11 (rot). Für den Ordnernamen ist das gleiche Feld da wie für einen Dateinamen (grün). Der 1. Cluster des Ordners ist 3 (blau, Inhalt des Ordners ist [[AVR_FAT32#Daten|Bild 3]]). Bei Ordnern werden die Felder für die Größe genullt (orange). Das Root-Dir hat keinen &amp;quot;.&amp;quot; bzw. &amp;quot;..&amp;quot; Eintrag. Der erste Cluster des Dirs ist ja über Sektor 0 bekannt und ab dem Root-Dir spannt sich der Verzeichnisbaum erst auf. Das Root-Dir bei FAT32 kann beliebig groß werden.&lt;br /&gt;
&lt;br /&gt;
=== Zusammenfassung ===&lt;br /&gt;
&lt;br /&gt;
Für Dateien und Ordner sind nur zwei Bereiche eines FAT32 Dateisystems wichtig, nämlich die FAT selbst und der Datenbereich. &lt;br /&gt;
Eine Datei wird aufgesplittet, in einen Datei-Eintrag und in die Nutzdaten der Datei (alles im Datenbereich). Ein Ordner ist vom Eintrag im Dateisystem einer Datei sehr ähnlich. Wo bei einer Datei über den 1. Cluster eine Cluster-Chain für die eigentlichen Daten der Datei beginnt, wird bei einem Ordner so eine Cluster-Chain für weitere Datei/Ordner Einträge verkettet. Ein Ordner bietet pro Sektor maximal 16 Einträge (16*32=512).&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* Thread:  http://www.mikrocontroller.net/topic/105869&lt;br /&gt;
* Infos (englisch):  https://www.pjrc.com/tech/8051/ide/fat32.html&lt;br /&gt;
* Fatgen103 von Microsoft (einfach mal nach Fatgen103.pdf suchen..)&lt;br /&gt;
* [[MMC- und SD-Karten]]&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
Weitere Projekte mit FAT MMC/SD Karten:&lt;br /&gt;
&lt;br /&gt;
* [http://www.roland-riegel.de/sd-reader/index.html MMC/SD FAT16 card reader example application (Roland Riegel)]&lt;br /&gt;
* [http://www.ulrichradig.de/home/index.php/avr/mmc-sd MMC/SD FAT16 (Ulrich Radig)]&lt;br /&gt;
* [http://www.holger-klabunde.de/avr/avrboard.htm#FullFAT MMC/SD FAT16/32 auch multi File (Holger Klabunde)]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:AVR-Projekte]]&lt;br /&gt;
[[Kategorie:Speicher und Dateisysteme]]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Motoransteuerung_mit_PWM&amp;diff=62956</id>
		<title>Motoransteuerung mit PWM</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Motoransteuerung_mit_PWM&amp;diff=62956"/>
		<updated>2012-01-02T18:55:52Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: Link zum Kapitel korrigiert (alles Großbuchstatben)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Allgemeines==&lt;br /&gt;
&lt;br /&gt;
Bei der Dimensionierung der Strombelastbarkeit der Bauteile muss man vor allem 2 Werte betrachten:&lt;br /&gt;
* Stromaufnahme des Motors im normalen Betrieb (also mit der Last)&lt;br /&gt;
* Stromaufnahme bei blockiertem Motor, bzw. Anlaufstrom. Hier wird der Strom nur durch den ohmschen Widerstand im Stromkreis begrenzt, er kann also je nach Motor schnell den 2-3 stelligen Amperebereich erreichen.&lt;br /&gt;
&lt;br /&gt;
Die übliche Dimensionierung richtet sich vor allem nach dem ersten Wert und plant entsprechende Reserven ein (für ein paar Sekunden Faktor 2-5 des Stromes), da der zweite Wert in der Praxis aus Kostengründen meist nur schwer realisierbar und unnötig ist. Daher umgeht man das Problem entweder über eine Strombegrenzung oder über einen Sanftanlauf indem man die PWM langsam hoch fährt.&lt;br /&gt;
Dadurch wird der maximale Strom auf einen deutlich niedrigeren Wert begrenzt, so dass die Bauteile schwächer und kostengünstiger ausfallen können. &lt;br /&gt;
&lt;br /&gt;
Die Spannung die der Motor sieht, und somit näherungsweise die Leerlaufdrehzahl ist proportional zu dem Tastverhältnis:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\text{Motorspannung} = \text{Betriebsspannung} \cdot \mathrm{Tastverh\ddot{a}ltnis}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Schaltungsvarianten==&lt;br /&gt;
&lt;br /&gt;
===Mosfet mit Freilaufdiode, 1-Quadrantensteller===&lt;br /&gt;
&lt;br /&gt;
[[Datei:Motor_PWM_1.gif|thumb|300px|1-Quadrantensteller]]&lt;br /&gt;
Die einfachste Schaltung besteht nur aus Transistor T1, dem Motor, der Freilaufdiode D1, dem Kondensator C1, sowie der eigentlichen [[PWM]]-Erzeugung und dem [[MOSFET-Übersicht#Mosfet-Treiber | Mosfettreiber]].&lt;br /&gt;
&lt;br /&gt;
In der Einschaltphase von T1 liegt am Motor die gesamte Betriebsspannung an. Die Differenz zwischen der vom sich drehenden Motor erzeugten Generatorspannung und der Betriebsspannung fällt am Wicklungswiderstand sowie der Wicklungsinduktivität ab. Man hat es also mit einer RL Reihenschaltung zu tun. Da der Wicklungswiderstand recht klein ist, steigt der Strom näherungsweise linear an, bis T1 abschaltet. Dann übernimmt D1 den Stromfluss und schließt den Stromkreis solange kurz, bis der Strom abgeklungen ist. Obwohl keine Energie mehr von außen zugeführt wird, wird der Motor weiterhin durch die in der Wicklung gespeicherten Energie versorgt. Der Strom fällt nun wieder linear ab, bis T1 wieder durchsteuert und wieder Energie zuführt. Der Strom durch die Diode D1 ist von der Spitzenamplitude her genauso groß wie der Strom durch T1, je nach Tastverhältnis ist der Effektivwert aber kleiner als der durch T1 (bei über 50% Tastverhältnis), gleich (bei 50% Tastverhältnis) oder sogar größer (bei einem Tastverhältnis kleiner 50%). Daher muss die Diode genauso stark dimensioniert werden wie der Transistor. Der Kondensator C1 ist notwendig, um den durch die PWM gepulsten Strom zu glätten, da aufgrund der steilen Flanken ansonsten in den Zuleitungen ein Spannungsabfall bzw. Spannungsspitzen auftreten würden.&lt;br /&gt;
&lt;br /&gt;
===Synchrongleichrichtung, 2-Quadrantensteller===&lt;br /&gt;
&lt;br /&gt;
[[Datei:Motor_PWM_2.gif|thumb|300px|2-Quadrantensteller]]&lt;br /&gt;
Um die Verluste in der Freilaufdiode zu verringern kann man diese durch einen zweiten Mosfet ersetzen, der immer dann eingeschaltet wird, wenn der andere abgeschaltet ist.&lt;br /&gt;
&lt;br /&gt;
Da dieser Mosfet, im Gegensatz zu einer Diode, in beide Richtungen leitet, ist es damit möglich den Motor kurz zu schließen und so den Motor zu bremsen.&lt;br /&gt;
Allgemein kann man sagen: Ist die durch die PWM erzeugte Spannung größer als die Generatorspannung des Motors, wird dieser beschleunigt. Ist die Spannung kleiner, wird der Motor abgebremst. Durch T2 wird der Motor dabei kurzgeschlossen, so dass sich durch die Generatorspannung zunächst der Strom in der Motorwicklung ab- und dann in umgekehrter Richtung wieder aufbaut. Beim Abschalten von T2 und Einschalten von T1 fließt dieser Strom über T1 in C1 und somit die Spannungsquelle zurück. Die Energie wird beim Bremsen also nicht vernichtet, sondern wieder in elektrische Energie zurückverwandelt. Dies sollte man bedenken wenn man eine große Masse abbremst, denn die Spannungsquelle muss die Energie aufnehmen können. Sollte die Spannungsquelle z.&amp;amp;nbsp;B. aus einem Transformator mit Gleichrichter bestehen, kann dieser die Energie nicht aufnehmen sondern nur C1, was dazu führt, dass die Betriebsspannung ansteigt bis eventuell einer der Transistoren zerstört wird. Um dies zu verhindern ist eine Überspannungsbegrenzung in Form eines Bremswiderstands vorzusehen (Bremschopper). Besteht die Spannungsquelle z.&amp;amp;nbsp;B. aus einem Akku dann nimmt dieser die Energie auf und wird beim Bremsen wieder etwas geladen.&lt;br /&gt;
Dies funktioniert allerdings nur, wenn das Tastverhältnis nicht 0% beträgt, also T2 und T1 abwechselnd schalten, so dass nicht die gesamte Energie in der Motorwicklung sowie T2 verheizt wird. Man sollte es daher vermeiden das Tastverhältnis schnell in eine der beiden Richtungen zu ändern, da dies zu einem hohen Strom führt.&lt;br /&gt;
&lt;br /&gt;
Die Ansteuerschaltung muss weiterhin verhindern, dass T1 und T2 gleichzeitig leitend werden können, denn dies würde zu einem Kurzschluss führen. Ein fertig aufgebauter Mosfet-Treiber verhindert dies.&lt;br /&gt;
&lt;br /&gt;
===H-Brücke, 4-Quadrantensteller===&lt;br /&gt;
&lt;br /&gt;
[[Datei:Motor_PWM_3.gif|thumb|300px|4-Quadrantensteller]]&lt;br /&gt;
Die H-Brücke, bzw. der 4-Quadrantensteller ist eine Erweiterung des 2-Quadrantensteller durch eine zweite Halbbrücke. Diese ermöglicht neben dem Beschleunigen und Bremsen des Motors auch eine Umkehr der Drehrichtung.&lt;br /&gt;
Dafür gibt es mehrere Ansteuerverfahren&lt;br /&gt;
#Das effizienteste ist, eine Hälfte wie beim 2-Quadrantensteller zu betreiben und mit der anderen den zweiten Motoranschluss an die Betriebsspannung zu legen. Für die andere Drehrichtung wechselt man einfach die Hälften, legt also den anderen Anschluss an die Betriebsspannung und verwendet die andere Hälfte als 2-Quadrantensteller.&lt;br /&gt;
&lt;br /&gt;
#Das andere Verfahren steuert abwechselnd T1 und T4 oder T2 und T3 durch, legt also immer eine Spannung an den Motor. Ist das Tastverhältnis 50% fließt im Mittel ein Strom von 0A, da der Motor für jeweils die Hälfte der Zeit eine positive und eine negative Spannung erhält, der Motor steht also. Je nachdem ob man das Tastverhältnis darüber oder darunter wählt, legt man die Drehrichtung fest. Dieses Verfahren ist Ansteuertechnisch einfacher, erzeugt aber auch im Stillstand Schaltverluste in den Transistoren und Verluste im Motor.&lt;br /&gt;
&lt;br /&gt;
==Beispielschaltungen==&lt;br /&gt;
&lt;br /&gt;
===1-Quadrantensteller mit diskretem Mosfettreiber===&lt;br /&gt;
&lt;br /&gt;
[[Datei:Motor_PWM1_real.gif|thumb|300px|Einfacher 1-Quadrantensteller]]&lt;br /&gt;
Diese Schaltung eignet sich für Motoren bis etwa 35V und 10A Dauerstrom.&lt;br /&gt;
Q1 und Q2 zusammen mit deren Beschaltung dienen als [[Pegelwandler]] von 3,3 oder 5V Digitalsignalen auf 12V für das Mosfet Gate. Die Schaltung arbeitet dabei invertierend, der Mosfet schaltet also bei einem Low am Eingang ein.&lt;br /&gt;
Sperrt Q1, wird Q2 über R1 durchgesteuert und liefert etwa 11-11,5V ans Gate des Mosfets. R2 begrenzt dabei den Strom.&lt;br /&gt;
Das Abschalten des Mosfets geschieht über den Pfad Q1 und D1. Gleichzeitig wird Q2 die Basisspannung weggenommen, so dass dieser sperrt.&lt;br /&gt;
D2 zwischen Basis und Kollektor von Q1 verhindert, dass dieser in die Sättigung kommt, so dass dieser nahezu verzögerungsfrei sperrt, sobald der Eingang auf Low wechselt. Ab ein paar Ampere benötigt die Freilaufdiode D3 einen kleinen [[Kühlkörper]], ebenso Q3. Sollte die Betriebsspannung V+ des Motors bei etwa 10-16V liegen, dann kann diese Spannung auch für die Mosfetansteuerung verwendet werden. Ansonsten sollte dafür eine getrennte Spannung mit etwa 12-15V verwendet werden.&lt;br /&gt;
&lt;br /&gt;
===1-Quadrantensteller mit diskretem Highside-Mosfettreiber===&lt;br /&gt;
&lt;br /&gt;
[[Datei:Motor_PWM1b_real.gif|thumb|300px|Einfacher 1-Quadrantensteller mit P-Kanal Mosfet]]&lt;br /&gt;
&lt;br /&gt;
Diese Schaltung eignet sich für Motoren mit etwa 15-40V Betriebsspannung und mit bis zu 10A Dauerstrom. Schaltungen mit P-Kanal Mosfets sollte man wenn möglich vermeiden, da N-Kanal Mosfets prinzipbedingt um Faktor 3 bessere Werte aufweisen als P-Kanal Mosfets. Allerdings wird manchmal ein auf Masse bezogener Ausgang gefordert, dann ist diese Schaltung hier die richtige. Das Problem bei der Highsideansteuerung ist, dass man die Gate-Sourcespannung irgendwie auf max. 20V begrenzen muss, was hier durch eine zusätzliche Hilfsspannung von 12V wie bei der vorigen Schaltung, nicht so einfach geht. Daher wird hier ein anderer Weg eingeschlagen. Q1 und R2 bilden eine [[Konstantstromquelle]]. Dadurch, dass an der Basis eine feste Logikspannung ansteht, steuert Q1 so stark durch, bis er sich durch den Spannungsabfall an R2 selbst die Basisspannung reduziert. Der fließende Strom beträgt dabei (Logikpegel am Eingang - 0,6V Basis-Emitterspannung)/R2. Ein guter Wert für den Strom sind etwa 10-15mA. Bei der Dimensionierung sollte man auch die Verlustleistung beachten: 40V * 15mA = 0,6W. Dies ist für einen Transistor im TO92 Gehäuse deutlich zu viel. Dadurch, dass Q1 im Linearbetrieb arbeitet, kommt er nicht in die Sättigung, und es kann auf die Diode wie in der vorherigen Schaltung verzichtet werden. Ebenso ist ein Basiswiderstand unnötig bzw. sogar hier fehl am Platz. Da nun bekannt ist, dass im durchgesteuerten Zustand von Q1 bei 5V Logikspannung (5V-0,6V)/330Ω= 13,3mA fließen, kann man damit den Spannungsabfall an R1 berechnen, bzw. aus der gewünschten Spannung R1:&lt;br /&gt;
U(R1)=13,3mA*1kOhm=13,3V. Im eingeschalteten Zustand ist die Spannung am Kollektor von Q1 also um 13,3V negativer als V+ und das unabhängig von der Betriebsspannung! Da diese Spannung durch die als Emitterfolger geschalteten Transistor Q2 und Q3 gepuffert auch an das Gate des Mosfets gelegt werden, bekommt dieser also rund 13V Gatespannung im eingeschalteten Zustand. Dies passt gut, denn für die meisten Mosfets sollte man einen Wert zwischen 10 und 15V verwenden. Durch den Spannungsteiler aus R1 und R2 ergibt sich allerdings auch eine untere Grenze der Betriebsspannung, damit die Schaltung sauber funktioniert: Um die 13,3V über R2 zu erhalten, bzw. die 4,4V über R1 sind mindestens 17,7V für V+ notwendig.&lt;br /&gt;
&lt;br /&gt;
===2-Quadrantensteller mit Halbbrücken Mosfettreiber===&lt;br /&gt;
&lt;br /&gt;
[[Datei:Motor_PWM2_real.gif|thumb|300px|Einfacher 2-Quadrantensteller]]&lt;br /&gt;
&lt;br /&gt;
Diese Schaltung eignet sich für Motoren bis etwa 35V und 20A Dauerstrom.&lt;br /&gt;
Um den Aufwand zu minimieren wird für die Halbbrücke ein fertiger Halbbrückentreiber IR2184 verwendet. Dieser besitzt eine integrierte Totzeit (engl. dead time) von 500ns zwischen dem Umschalten der Mosfets, so dass ein gleichzeitiges Einschalten beider Mosfets ausgeschlossen ist. Da der Mosfet gegen V+ angeschlossen ist, arbeitet auch diese Schaltung invertierend. Der Grund, warum der Motor nicht gegenüber GND angeschlossen ist, ist folgender:&lt;br /&gt;
Für die Ansteuerung des Highside Mosfets Q2 ist eine Spannung von etwa 10V mehr als die Betriebsspannung V+ notwendig. Diese wird über die Bootstrapschaltung aus C2 und D1 erzeugt. Ist Q1 durchgesteuert, läd sich C2 über D1 auf. Schaltet anschließend Q1 ab und Q2 ein, wird dessen Ansteuerspannung aus C2 entnommen. Da Q2 nun VS mit V+ verbindet, steigt auch das Potential an C2 an. An dem VB Pin stehen nun etwa V+ + 12V-0,7V (12V Betriebsspannung-Flusspannung von D1) an. Aufgrund von Leckströmen, entläd sich C2 allerdings innerhalb einiger Millisekunden. Daher ist die maximale Einschaltdauer von Q2 begrenzt. 100% Einschaltdauer wären daher nicht möglich. Um dieses Problem zu umgehen ist der Motor gegen V+ geschaltet, so dass für 100% Einschaltdauer Q1 eingeschaltet werden muss, was kein Problem ist, denn dessen Treiber wird direkt auf den 12V versorgt. Ist Q1 dagegen dauerhaft aus, Q2 also an, bremst der Motor, bzw. er steht, so dass kein Strom durch die Mosfets fließt. Daher ist es auch nicht weiter schlimm, wenn Q2 nach einer kurzen Zeit wieder abschaltet. Das einzige was nicht möglich ist, ist ein dauerhaftes Bremsen des Motors mittels Q2, aber dies wird in der Praxis auch nur in den seltensten Fällen benötigt. Über den IN Pin, wird das invertierte PWM Signal mit Logikpegeln eingespeist. Über den SD\ Pin, lassen sich beide Mosfets gemeinsam abschalten. Damit ist ein ungebremstes Auslaufen lassen des Motors möglich (Freilauf). Ab etwa 5Ampere benötigen die Mosfets einen kleinen [[Kühlkörper]].&lt;br /&gt;
&lt;br /&gt;
==Wahl der PWM-Frequenz==&lt;br /&gt;
&lt;br /&gt;
Bei der Wahl der PWM Frequenz muss man mehrere Faktoren berücksichtigen und einen Kompromiss eingehen:&lt;br /&gt;
* Die Motorinduktivität L glättet den Strom, der Wicklungswiderstand R führt zu einem Abfallen des Stromes, daraus ergibt sich die elektrische Zeitkonstante des Motors &amp;lt;math&amp;gt;t=\frac{L}{R}&amp;lt;/math&amp;gt;. Bei vielen Motoren liegt diese um 1ms. Bei hochwertigen Motoren sollte diese Angabe im Datenblatt zu finden sein. Um den Stromripple gering, also das Drehmoment konstant zu halten, sollte die Periodendauer der PWM diese Zeit nicht überschreiten. Vor allem im 2 bzw. 4-Quadratentebetrieb ist dies wichtig, denn dort kann der Strom auch seine Richtung ändern, was zu einem Abbremsen, somit zu einem deutlichen Ruckeln und zu Vibrationen des Motors und zu unnötigen Verlusten führt. &lt;br /&gt;
* Frequenzen zwischen  100Hz und 10kHz erzeugen hörbare Pfeifgeräusche im Motor&lt;br /&gt;
* Mit zunehmender Frequenz steigen die Schaltverluste in den Transistoren sowie die Verluste in der Ankerwicklung sowie in deren Kern.&lt;br /&gt;
&lt;br /&gt;
Die aus elektrischer Sicht ideale PWM Frequenz liegt daher meist bei 1-2kHz. Allerdings ist dies genau der Bereich, in dem das Gehör am empfindlichsten ist. Wenn das Pfeifen des Motors nicht stört, ist dies also der ideale Bereich.&lt;br /&gt;
Da die untere Frequenz durch die elektrische Zeitkonstante des Motors begrenzt ist, kann man nur nach oben ausweichen. Ein Kompromiss ist daher der Bereich 5-15kHz in dem das Gehör deutlich unempfindlicher ist, sich die Verluste noch in Grenzen halten. Verwendet man die einfache Schaltung mit der Freilaufdiode und legt keinen Wert auf einen runden Lauf, bzw. hat eine hohe Masse am Motor, so dass dieser träge ist, dann kann man als Alternative zu den &amp;gt;5kHz die PWM Frequenz auch bis auf 200Hz reduzieren um das Geräusch erträglicher zu machen. Allerdings reduziert sich dann der Wirkungsgrad aufgrund des hohen Stromripples.&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
*[[PWM]]&lt;br /&gt;
*[[Treiber]]&lt;br /&gt;
*[[MOSFET-Übersicht#MOSFET-Treiber | Mosfet-Treiber]]&lt;br /&gt;
*[[H-Brücken Übersicht]]&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
&lt;br /&gt;
*[http://www.mikrocontroller.net/topic/103116#900247 Forenbeitrag: Highside Mosfetansteuerung mit diskretem Treiber]&lt;br /&gt;
*[http://de.wikipedia.org/wiki/Zweiquadrantensteller Zweiquadrantensteller bei Wikipedia]&lt;br /&gt;
*[http://de.wikipedia.org/wiki/Vierquadrantensteller Vierquadrantensteller bei Wikipedia]&lt;br /&gt;
*[http://homepages.which.net/~paul.hills/SpeedControl/SpeedControllersBody.html Grundlagen zum Thema Motoransteuerung (englisch)]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/191616#1870643 Forenbeitrag zur Erklärung der PWM Steuerung, Bremsen und Unterschied zum Relais]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Leistungselektronik]]&lt;br /&gt;
[[Kategorie:Motoren]]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=LED-Matrix&amp;diff=62812</id>
		<title>LED-Matrix</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=LED-Matrix&amp;diff=62812"/>
		<updated>2011-12-27T20:03:03Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: Rechtschreibfehler korrigiert&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In einer [[LED]]-Matrix sind jeweils die Kathoden und Anoden der LEDs in Zeilen bzw. Spalten verbunden. Der Vorteil besteht darin, dass weniger Kontakte nach außen geführt und angesteuert werden müssen, ebenso sinkt der Verdrahtungsaufwand im Modul bzw. auf der Platine. Die Ansteuerung erfolgt dabei im sogenannten Multiplexbetrieb. Prinzipiell kann man sowohl die Zeilen als auch die Spalten multiplexen. Die nachfolgende Beschreibung bezieht sich auf das Multiplexen von Spalten.&lt;br /&gt;
&lt;br /&gt;
[[Bild:LEDmatrix_5x7.png|right|thumb|220px|Eine 5&amp;amp;times;7 LED-Matrix]]&lt;br /&gt;
&lt;br /&gt;
==Multiplexbetrieb==&lt;br /&gt;
&lt;br /&gt;
[http://de.wikipedia.org/wiki/Multiplexverfahren Multiplexverfahren (Wikipedia)]&lt;br /&gt;
&lt;br /&gt;
Der Trick einer LED-Matrix besteht darin, dass jeweils immer nur eine Spalte wirklich leuchtet. Die anderen sind ausgeschaltet. Wird nun in schneller Folge jede Spalte einmal angeschaltet. So entsteht aufgrund der Trägheit des menschlichen Auges ein scheinbar vollständiges Bild, bei dem alle LEDs gleichzeitig leuchten. Wird dieser Zyklus schnell genug durchlaufen, ist das Bild flimmerfrei, was ab ca. 100Hz erreicht wird. In Ausnahmefällen kann jedoch eine bewegte LED-Matrix auch bei höheren Multiplexfrequenzen als flimmernd erscheinen, z.&amp;amp;nbsp;B. LED-Bremsleuchten, LED-Anzeigen an Zügen oder Strassenbahnen.&lt;br /&gt;
&lt;br /&gt;
Der Ablauf der Steuerung ist recht einfach:&lt;br /&gt;
&lt;br /&gt;
#alle Spalten ausschalten, Muster für Spalte C1 an Zeilen R1..R7 anlegen, Spalte C1 einschalten&lt;br /&gt;
# Spaltenmultiplexzeit warten&lt;br /&gt;
#alle Spalten ausschalten, Muster für Spalte C2 an Zeilen R1..R7 anlegen, Spalte C2 einschalten&lt;br /&gt;
# Spaltenmultiplexzeit warten&lt;br /&gt;
#alle Spalten ausschalten, Muster für Spalte C3 an Zeilen R1..R7 anlegen, Spalte C3 einschalten&lt;br /&gt;
# Spaltenmultiplexzeit warten&lt;br /&gt;
#alle Spalten ausschalten, Muster für Spalte C4 an Zeilen R1..R7 anlegen, Spalte C4 einschalten&lt;br /&gt;
# Spaltenmultiplexzeit warten&lt;br /&gt;
#alle Spalten ausschalten, Muster für Spalte C5 an Zeilen R1..R7 anlegen, Spalte C5 einschalten&lt;br /&gt;
# Spaltenmultiplexzeit warten&lt;br /&gt;
# Zyklus beginnt bei 1.&lt;br /&gt;
&lt;br /&gt;
Praktisch wird man dazu einen [[Timer]] per [[Interrupt]] verwenden, keine Warteschleifen.&lt;br /&gt;
&lt;br /&gt;
[[Bild:LEDmatrix_timing.png|left|thumb|700px|Multiplexzeitdiagramm]]&lt;br /&gt;
&lt;br /&gt;
{{Absatz}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;float:right; margin:1em;&amp;quot;&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!LEDs  ||  IOs  ||  Vorwiderstände &lt;br /&gt;
|-&lt;br /&gt;
|16    ||    8  ||      4      &lt;br /&gt;
|-&lt;br /&gt;
|64    ||   16  ||      8     &lt;br /&gt;
|-&lt;br /&gt;
|1024  ||   64  ||     32     &lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
Durch Einsatz der Multiplexverfahrens können mit relativ wenigen Ansteuerbauteilen (IO-Pins, Transistoren, Stromquellen) sehr viele LEDs gesteuert werden. Während bei direkter Ansteuerung für jede LED ein IO-Pin sowie eine Stromquelle bzw. Vorwiderstand benötig würde,  ist in einer zweiachsigen LED-Matrix der Aufwand für die Bauteile deutlich geringer:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\text{Anzahl der Bauteile} = \sqrt\text{Anzahl der LEDs}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Absatz}}&lt;br /&gt;
&lt;br /&gt;
==Ansteuerung==&lt;br /&gt;
&lt;br /&gt;
Der verringerte Aufwand an Bauteilen kommt jedoch nicht ohne Nachteile. Da jede Spalte in einer Matrix mit N Spalten immer nur für 1/N der Zeit für einen vollen Bildaufbau aktiv ist, muss in dieser Zeit die gleiche Lichtmenge (=Energie) abgegeben werden, damit die genauso hell erscheint, wie wenn sie konstant mit Strom versorgt wird. Dazu muss der N-fache Strom fliessen. Demensprechend müssen die Vorwiderstände bzw. Stromquellen dimensioniert sein. Doch das führt zu zwei Problemen.&lt;br /&gt;
&lt;br /&gt;
# Der Pulsstrom durch eine LED kann nicht beliebig gesteigert werden. Genaue Angaben dazu gibt es im Datenblatt. Als grobe Abschätzung kann man sagen, dass die meisten LEDs bis etwa 1:10 gemuxt werden können, darüberhinaus werden die Pulsströme zu hoch (20mA Betriebsstrom =&amp;gt; 200 mA Pulsstrom!)&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
#Die hohen Pulsströme verkraften die LEDs wirklich nur ganz kurz, sie brauchen die Ausschaltzeit um wieder abzukühlen! D.H. Die Ansteuerung des Multiplex darf NIE stehen bleiben, sonst brennen die LEDs durch! Für die Testphase der Matrix sowie Softwareentwicklung sollte man deshalb die Ströme stark veringern, die LEDs sind dann zwar wesenlich dunkler, überleben aber einen Softwareabsturz der Steuerung. Wenn am Ende alles getestet ist und man sich sicher ist daß die Steuerung funktioniert, kann man den Strom der Matrix wieder auf das volle Niveau erhöhen. Um ganz sicher zu gehen kann man einen Watchdog mit minimaler Laufzeit oder ein [[Monoflop]] verwenden, um im Fehlerfall die Stromversorgung bzw. Ansteuerung der LEDs abzuschalten.&lt;br /&gt;
&lt;br /&gt;
Um die Helligkeit der LEDs im Multiplexbetrieb voll zu nutzen muss meistens ein höherer Strom geschaltet werden, als Mikrocontroller es können. Eine [[LED]] muss aufgrund ihrer Kennlinie an einer Stromquelle betrieben werden. Im einfachsten Fall ist das ein in Reihe geschalteter Widerstand an einer Spannungsquelle. Ob man die Zeilen oder Spalten einer Matrix multiplext ist im Prinzip egal, aber manchmal ist es schlicht logisch sinnvoller. So ist z.B. bei einer LED-Laufschrift mit 8 Zeilen und 40 Spalten es sinnvoll, die Zeilen mit 1:8 zu multiplexen und nicht die Spalten mit 1:40! Generell kann man das in einer Schaltung so erkennen. Die gemultiplexte Dimension hat vor den Leistungsschaltern keine Vorwiderstände bzw. Konstantstromquellen sondern geht direkt an die LEDs. &lt;br /&gt;
&lt;br /&gt;
===Direkt===&lt;br /&gt;
&lt;br /&gt;
In einigen Projekten im Internet sieht man LED-Matritzen direkt per Mikrocontroller angesteuert, ohne Transistoren. Das geht praktisch nur mit Low-Current Bauteilen, sonst sind die LEDs auf Grund des geringen Stroms zu dunkel.&lt;br /&gt;
&lt;br /&gt;
=== Transistoren ===&lt;br /&gt;
&lt;br /&gt;
Das ist der Normalfall. Man kann diskrete [[Transistor|Transistoren]] (z.&amp;amp;nbsp;B. BC846, BC337) benutzen.&lt;br /&gt;
&lt;br /&gt;
Eine praktische Umsetzung kann man hier sehen. Q1-Q8 arbeiten als Emitterfolger ([[Transistor#Kollektorschaltung_(Emitterfolger)|Kollektorschaltung]]), darum gibt es hier auch keine [[Basiswiderstand | Basiswiderstände]]. Q9-Q13 arbeiten ganz einfach in [[Transistor#Emitterschaltung|Emitterschaltung]]. Dadurch braucht man nur NPN Transistoren,  die Schaltung ist dadurch auch relativ schnell. Einziger Nachteil ist ein um ca. 0,5 V höherer Spannungsverlust an Q1-Q8 im Vergleich zu PNP-Transistoren in Emitterschaltung. Das spielt hier aber keine große Rolle.&lt;br /&gt;
&lt;br /&gt;
Ein Schieberegister ist im Prinzip ein Seriell-Parallel-Wandler.&lt;br /&gt;
Das hat mit Multiplexbetrieb eigentlich nichts direkt zu tun, es ist vielmehr eine Erweiterung der IO-Pins (siehe auch [[Porterweiterung mit SPI]] und [[AVR-Tutorial: Schieberegister]]).&lt;br /&gt;
&lt;br /&gt;
Eine weitere Schaltung mit Schieberegistern ist im &amp;quot;Retro-Spiel zum Selberbauen&amp;quot; [http://www.elo-web.de/elo/entwicklung-und-projekte/ping-pong Ping-Pong] von Burkhard Kainka verwendet worden. Hier werden die 10 Zeilen mit Atmega8-Portpins über 100 &amp;amp;Omega; Widerstände [http://www.elo-web.de/elo/mikrocontroller-und-programmierung/ping-pong/ping-pong-selbst-programmieren] gegen 12 Schieberegister-Spalten zweier 4094D CMOS-ICs geschaltet, um eine Matrix aus 120 roten SMD-LEDs zu steuern.&lt;br /&gt;
&lt;br /&gt;
[[Bild:LED_Matrix_8x5.png|thumb|right|250px|Multiplexansteuerung mit Schieberegistern und Transistoren]]&lt;br /&gt;
&lt;br /&gt;
==== Berechnung ====&lt;br /&gt;
&lt;br /&gt;
Will man nun seine Schaltung optimal betreiben, muss man ausrechnen wieviel Strom geschaltet werden muss. Wie oben bereits beschrieben, teilt sich der gemultiplexte Strom im Verhältnis 1:N auf die LEDs auf, in diesem Beispiel hier 1:5. Der Treiber für die Zeilen muss diesen im Extremfall kontinuierlich an jedem Ausgang zur Verfügung stellen, wenn nämlich alle LEDs der Matrix aktiv sind. Der Treiber für die Spalten ist pro Kanal nur 1:N der Multiplexzeit aktiv, muss aber währenddessen den gesamten Nennstrom der Matrix schalten können! Das sind schnell mal ein paar Ampere, wie die nachfolgenden Beispiele zeigen!&lt;br /&gt;
&lt;br /&gt;
Gegeben:&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;math&amp;gt;I_{Nenn}&amp;lt;/math&amp;gt;: Nennstrom der LEDs: 4mA&lt;br /&gt;
*&amp;lt;math&amp;gt;U_{F}&amp;lt;/math&amp;gt;: Flußspannung der LEDs: 2,2V&lt;br /&gt;
*&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;: Multiplexverhältnis (Spalten): 1:5&lt;br /&gt;
*&amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;: Zeilen in der Matrix: 8&lt;br /&gt;
* &amp;lt;math&amp;gt;U_{Sat}&amp;lt;/math&amp;gt;: Sättigungsspannung des Low Side Transistors, hier Q9-Q13 mit ca. 0,7V&lt;br /&gt;
* &amp;lt;math&amp;gt;U_{BE}&amp;lt;/math&amp;gt;: Basis-Emitter-Spannung des High Side Transistors, hier Q1-Q8 ca. 0,7V&lt;br /&gt;
&lt;br /&gt;
Gesucht:&lt;br /&gt;
*&amp;lt;math&amp;gt;I_{Zeil}&amp;lt;/math&amp;gt;: Dauerstrom der Zeilentreiber = Pulsstrom der LEDs&lt;br /&gt;
*&amp;lt;math&amp;gt;I_{Spl}&amp;lt;/math&amp;gt;: Pulsstrom der Spaltentreiber&lt;br /&gt;
*&amp;lt;math&amp;gt;R_V&amp;lt;/math&amp;gt;: Vorwiderstand für LED-Zeilen &lt;br /&gt;
*&amp;lt;math&amp;gt;P_V&amp;lt;/math&amp;gt;: Verlustleistung der Vorwiderstände&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;I_{Zeil} = I_{Nenn} \cdot N = 4mA \cdot 5 = 20mA&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;I_{Spl} = I_{Nenn} \cdot N \cdot S = 4mA \cdot 5 \cdot 8 = 160mA&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;R_V = \frac{U}{I} = \frac{Vcc - U_{Sat} - U_{BE}-U_F}{I_{Nenn} \cdot N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;R_V=\frac{5V-0,7V-0,7V-2,2V}{4mA \cdot 5} \approx 68 \Omega&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;P_V=I_{Zeil}^2 \cdot R = 20mA^2 \cdot 68 \Omega = 27mW&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Absatz}}&lt;br /&gt;
&lt;br /&gt;
=== Treiber ===&lt;br /&gt;
&lt;br /&gt;
Bei grossen Anzeigen mit vielen LEDs werden die Pulsströme bisweilen schon recht hoch. Hier wird man dann mehr auf Treiber (z.&amp;amp;nbsp;B. ULN2803)zurück greifen. Vor allem die Schalter für die gemultiplexte Dimension, hier im Beispiel die Zeilen, müssen sehr große Ströme schalten.&lt;br /&gt;
&lt;br /&gt;
[[bild:LED-Matrix-ULN-UDN.png|thumb|right|250px|Multiplexansteuerung mit integrierten Treibern]]&lt;br /&gt;
&lt;br /&gt;
==== Berechnung ====&lt;br /&gt;
&lt;br /&gt;
Gegeben:&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;math&amp;gt;I_{Nenn}&amp;lt;/math&amp;gt;: Nennstrom der LED-Stränge: 15mA&lt;br /&gt;
*&amp;lt;math&amp;gt;U_{F}&amp;lt;/math&amp;gt;: Flußspannung der LED-Stränge: 7V&lt;br /&gt;
*&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;: Multiplexverhältnis (Zeilen): 1:4&lt;br /&gt;
*&amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;: Spalten in der Matrix 8&lt;br /&gt;
* &amp;lt;math&amp;gt;U_{IC1}&amp;lt;/math&amp;gt;: Sättigungsspannung des Low Side Switch, hier IC1 mit ca. 1V&lt;br /&gt;
* &amp;lt;math&amp;gt;U_{IC2}&amp;lt;/math&amp;gt;: Sättigungsspannung des High Side Switch, hier IC2 mit ca. 2V&lt;br /&gt;
&lt;br /&gt;
Gesucht:&lt;br /&gt;
*&amp;lt;math&amp;gt;I_{Spl}&amp;lt;/math&amp;gt;: Dauerstrom der Spaltentreiber = Pulsstrom der LEDs&lt;br /&gt;
*&amp;lt;math&amp;gt;I_{Zeil}&amp;lt;/math&amp;gt;: Pulsstrom der Zeilentreiber&lt;br /&gt;
*&amp;lt;math&amp;gt;R_V&amp;lt;/math&amp;gt;: Vorwiderstand für LED-Spalten&lt;br /&gt;
*&amp;lt;math&amp;gt;P_V&amp;lt;/math&amp;gt;: Verlustleistung der Vorwiderstände &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;I_{Spl} = I_{Nenn} \cdot N = 15mA \cdot 4 = 60mA&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;I_{Zeil} = I_{Nenn} \cdot N \cdot S = 15mA \cdot 4 \cdot 8 = 480mA&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;R_V = \frac{U}{I} = \frac{Vcc - U_{IC1} - U_{IC2}-U_F}{I_{Nenn} \cdot N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;R_V=\frac{12V-1V-2V-7V}{15mA \cdot 4}=33 \Omega&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;P_V=I_{Spl}^2 \cdot R_V = 60mA^2 \cdot 33 \Omega = 119mW&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
60mA kann IC2 dauerhaft auf jedem Kanal liefern, 500mA Pulsstrom sind für IC1 schon die absolute Grenze laut Datenblatt. Der Spannungsverlust &amp;lt;math&amp;gt;U_{IC1}&amp;lt;/math&amp;gt; und &amp;lt;math&amp;gt;U_{IC2}&amp;lt;/math&amp;gt; ist bei diesen relativ alten ICs recht hoch, mit modernen MOSFETs erreicht man hier deutlich kleinere Werte und damit auch kleinere Verlustleistungen bzw. höhere Ströme.&lt;br /&gt;
&lt;br /&gt;
{{Absatz}}&lt;br /&gt;
&lt;br /&gt;
=== MOSFETs ===&lt;br /&gt;
&lt;br /&gt;
Bei Strömen über 1A nimmt man heute meist [[FET|MOSFETs]].&lt;br /&gt;
&lt;br /&gt;
[[bild:LED-Matrix-MOSFET.png|thumb|right|250px|Multiplexansteuerung mit MOSFETs]]&lt;br /&gt;
&lt;br /&gt;
==== Berechnung ====&lt;br /&gt;
&lt;br /&gt;
Die Berechnung erfolgt analog zum vorherigen Beispiel, nur mit dem Unterschied, daß die MOSFETs deutlich kleinere Spannungsabfälle zu verzeichnen haben. Damit die MOSFETs schnell schalten werden [[MOSFET-Übersicht| MOSFET-Treiber]] eingesetzt. Für die P-Kanal MOSFETs nutzt man hier im Beispiel einen echten [[MOSFET-Übersicht##Mosfet-Treiber | MOSFET-Treiber]], die N-Kanal MOSFETS kann man hier mit einem einfachen CMOS-Inverter ansteuern. Das geht bei kleinen Logic Level MOSFETs mit 1-2nF Gatekapazität noch ausreichend schnell, bei größeren MOSFETs ist auch hier ein echter MOSFET-Treiber nötig. Der berühmt-berüchtigte Gatewiderstand kann hier entfallen, die Ausgänge der CMOS-Inverter sind bereits hochohmig genug, um parasitäre Schwingungen zu dämpfen. Nimmt man für den Inverter einen HCT-Typ, so wirkt der gleichzeitig als [[Pegelwandler]] und die Matrix kann mit 3,3V Signalen angesteuert werden.&lt;br /&gt;
&lt;br /&gt;
Gegeben:&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;math&amp;gt;I_{Nenn}&amp;lt;/math&amp;gt;: Nennstrom der LED-Stränge: 25mA&lt;br /&gt;
*&amp;lt;math&amp;gt;U_{F}&amp;lt;/math&amp;gt;: Flußspannung der LED-Stränge: 9V&lt;br /&gt;
*&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;: Multiplexverhältnis (Zeilen): 1:8&lt;br /&gt;
*&amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;: Spalten in der Matrix: 8&lt;br /&gt;
*&amp;lt;math&amp;gt;R_{DS-ON, high}&amp;lt;/math&amp;gt;: Einschaltwiderstand der High Side MOSFETs : 0,25&lt;br /&gt;
*&amp;lt;math&amp;gt;R_{DS-ON, low}&amp;lt;/math&amp;gt;: Einschaltwiderstand der Low Side MOSFETs: 0,13&lt;br /&gt;
&lt;br /&gt;
Gesucht:&lt;br /&gt;
*&amp;lt;math&amp;gt;I_{Spl}&amp;lt;/math&amp;gt;: Dauerstrom der Spaltentreiber = Pulsstrom der LEDs&lt;br /&gt;
*&amp;lt;math&amp;gt;I_{Zeil}&amp;lt;/math&amp;gt;: Pulsstrom der Zeilentreiber&lt;br /&gt;
*&amp;lt;math&amp;gt;R_V&amp;lt;/math&amp;gt;: Vorwiderstand für LED-Spalten &lt;br /&gt;
*&amp;lt;math&amp;gt;P_V&amp;lt;/math&amp;gt;: Verlustleistung der Vorwiderstände&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;I_{Spl} = I_{Nenn} \cdot N = 25mA \cdot 8 = 200mA&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;I_{Zeil} = I_{Nenn} \cdot N \cdot S = 25mA \cdot 8 \cdot 8 = 1600mA&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;R_V = \frac{U}{I} = \frac{Vcc - I_{Spl} \cdot R_{DS-ON, high} - I_{Zeil} \cdot R_{DS-ON, low} -U_F}{I_{Spl}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;R_V=\frac{12V - 0,2A \cdot 0,25 \Omega - 1,6A \cdot 0,13 \Omega -9V}{0,2A} \approx 13 \Omega&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;P_V=I_{Spl}^2 \cdot R_V = 200mA^2 \cdot 13 \Omega = 520mW&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird der gesparte Spannungsabfall über den MOSFETs genutzt, um LEDs mit höherer Flußspannung in Reihe schalten, womit der Wirkungsgrad ansteigt. Liegt die LED-Betriebsspannung über 15V braucht man einen sogenannten [[Treiber | High Side Driver]], weil dann die Gates der P-Kanal MOSFETs nicht mehr direkt angesteuert werden können. Ein einfaches Beispiel findet man [http://www.mikrocontroller.net/attachment/34752/P_FET.png hier].&lt;br /&gt;
&lt;br /&gt;
===Dimmen===&lt;br /&gt;
&lt;br /&gt;
Multiplexen kann auch mit [[PWM]] kombiniert werden. Dabei ist die Multiplexzeit einer Spalte gleich der PWM-Periodendauer. Allerdings kann hier der Rechenaufwand für die CPU schon recht hoch werden, da die meisten Mikrocontroller nicht so viele PWM-Kanäle in Hardware zur Verfügung stellen und die PWM in Software nachgebildet werden muss ([[Soft-PWM]]).&lt;br /&gt;
&lt;br /&gt;
Falls die Multiplexzeit klein genug gewählt wird, kann man in Grenzen auch per gezieltem Ein- und Abschalten in Grenzen eine Dimmfunktion erreichen. Um hier allerdings noch flimmerfreie Ergebnisse zu erzielen, sollte die Multiplexfrequenz mit den geplanten Dimmstufen multipliziert werden (bspw. 16 Dimmstufen bei 100 Hz Multiplexfrequenz = 1600 Hz angepasste Multiplexfrequenz), was die Rechenzeit wiederum schnell in die Höhe treiben kann. Dimmen selbst erreicht man dann mit entsprechend angepassten Schaltzeiten (bspw. 25% Helligkeit = 4x LED an, 12x LED aus bei insgesamt 16 Dimmstufen, dann von vorne).&lt;br /&gt;
&lt;br /&gt;
=== Spezielle ICs ===&lt;br /&gt;
&lt;br /&gt;
Neben den typischen Treiberbausteinen für möglichst hohe Ströme, die weiter unten aufgeführt sind, gibt es auch noch integrierte Lösungen für das direkte Betreiben einer LED-Matrix an der [[SPI]] oder [[I2C]]-Schnittstelle. Beispiele sind hier MAXIM 7219 und 7221 oder AS1100-08/15-18 für 8x8 LED-Matrizen oder 8x8-Segmentanzeigen. Zwischen beiden Modi wird per Software gewechselt. Die ICs bieten einige Vorteile, wie automatische Dimmung und großzügiges Freischaufeln von CPU-Kapazität auf dem Mikrocontroller. Außerdem können die ICs dank SPI kaskadiert werden wie normale [[AVR-Tutorial: Schieberegister|Schieberegister]] und somit eine nahezu unbegrenzte Zahl an LEDs ansteuern. Allerdings ist der Strom für die integrierten Stromsenken auf etwa 50 mA begrenzt, was bei einigen Displays zu wenig sein kann. Hier muss man wieder Vor- und Nachteile abwägen. Weitere ICs bei [http://www.maxim-ic.com Maxim] umfassen Standardfälle wie 5x7 Matrizen oder 7-, 10-, 14-Segment LED-Anzeigen mit 4 bis 16 Stellen. Diese ICs gibt es dann allerdings leider nicht bei den [[Elektronikversender|Standardversandhändlern]].&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Bauteil                  || Beschreibung                          || Bezugsquelle&lt;br /&gt;
|-&lt;br /&gt;
|ULN2803                  || 8fach NPN-Transistorarray, 500mA      ||&lt;br /&gt;
|-&lt;br /&gt;
|ULN2003                  || 7fach NPN-Transistorarray, 500mA      ||&lt;br /&gt;
|-&lt;br /&gt;
|UDN2981                  || 8fach High Side Treiber, 500mA        ||&lt;br /&gt;
|-&lt;br /&gt;
|TLC5921                  || 16 Bit-Schieberegister plus Latch&amp;lt;BR&amp;gt; mit Konstantstromsenken, max. 80mA pro Ausgang       ||&lt;br /&gt;
|-&lt;br /&gt;
|TLC5922                  &lt;br /&gt;
|| 16 Bit-Schieberegister plus Latch mit Konstantstromsenken, max. 80mA pro Ausgang&amp;lt;BR&amp;gt;Dimmung jedes einzelnen Kanals mit 7 Bit möglich, pinkompatibel zum TLC5921      ||&lt;br /&gt;
|-&lt;br /&gt;
|TLC5940 || 16 Bit-Schieberegister plus Latch mit Konstantstromsenken, max. 120mA pro Ausgang&amp;lt;BR&amp;gt;Dimmung jedes einzelnen Kanals mit 6 Bit plus 12 Bit PWM möglich, kompatibel mit AS1112 || mouser.com&lt;br /&gt;
|-&lt;br /&gt;
|CAT4016&lt;br /&gt;
|| 16 Bit-Schieberegister/Latch mit Konstantstromsenken(max. 100mA), günstig || Farnell&lt;br /&gt;
|-&lt;br /&gt;
|TPIC6B595&lt;br /&gt;
|| 8-Bit Schieberegister + Leistungstreiber, 500mA      ||&lt;br /&gt;
|-&lt;br /&gt;
|IRF7304                  || 2fach P-Kanal MOSFET, 3,5A, SO-8 Gehäuse ||&lt;br /&gt;
|-&lt;br /&gt;
|MAX7219                  || Seriell angesteuerter 8x8 Matrizentreiber, kompatibel mit AS110x ||&lt;br /&gt;
|-&lt;br /&gt;
|MAX7221                  || Seriell angesteuerter 8x8 Matrizentreiber, kompatibel mit AS110x ||&lt;br /&gt;
|-&lt;br /&gt;
|AS1100-08                || Seriell angesteuerter 8x8 Matrizentreiber, kompatibel mit MAX72xx || [http://www.austriamicrosystems.com/AS1106 AS1106]&lt;br /&gt;
|-&lt;br /&gt;
|AS1115/17                || I²C angesteuerter 8x8 Matrizentreiber mit Diagnose &amp;amp; Tastenerkennung|| [http://www.austriamicrosystems.com/AS1115 AS1115]&lt;br /&gt;
|-&lt;br /&gt;
|AS1116/18                || Seriell angesteuerter 8x8 Matrizentreiber mit Diagnose|| [http://www.austriamicrosystems.com/AS1116 AS1116]&lt;br /&gt;
|-&lt;br /&gt;
|AS1119            || I²C angesteuerter 144LEDs Matrizentreiber mit Animationsspeicher, Dignose und ChargePump||[http://www.austriamicrosystems.com/AS1119 AS1119]&lt;br /&gt;
|-&lt;br /&gt;
|AS1130            || I²C angesteuerter 132 LEDs Matrizentreiber mit Animationsspeicher, Scroll Funktion &amp;amp; Dignose||[http://www.austriamicrosystems.com/AS1130 AS1130]&lt;br /&gt;
|-&lt;br /&gt;
|AS1112            || 15V 16Kanal LED Treiber, max. 100mA pro Ausgang&amp;lt;BR&amp;gt;Dimmung jedes einzelnen Kanals mit 6 Bit plus 12 Bit PWM möglich, Diagnosefunktion, kompatibel mit TLC594x ||[http://www.austriamicrosystems.com/AS1112 AS1112]&lt;br /&gt;
|-&lt;br /&gt;
|AS1121            || 30V 16Kanal LED Treiber, max. 40mA pro Ausgang&amp;lt;BR&amp;gt;Dimmung jedes einzelnen Kanals mit 6 Bit plus 12 Bit PWM möglich, Diagnosefunktion ||[http://www.austriamicrosystems.com/AS1121 AS1121]&lt;br /&gt;
|-&lt;br /&gt;
|AS1123            || 5V 16Kanal LED Treiber, max. 40mA pro Ausgang&amp;lt;BR&amp;gt;Low Power, Diagnosefunktion ||[http://www.austriamicrosystems.com/AS1123 AS1123]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[bild:LED-Matrix-TLC5921.png|thumb|right|250px|Multiplexansteuerung mit Special-ICs]]&lt;br /&gt;
&lt;br /&gt;
==== Berechnung ====&lt;br /&gt;
&lt;br /&gt;
Der TLC5921 und seine zahlreichen [http://focus.ti.com/paramsearch/docs/parametricsearch.tsp?family=analog&amp;amp;familyId=480&amp;amp;uiTemplateId=NODE_STRY_PGE_T Kollegen] von [http://www.ti.com Texas Instruments] bieten eine komfortable Möglichkeit zur Ansteuerung von LED-Matrizen. Der TLC5921 besitzt 16 Ausgänge, welche als [[Konstantstromquelle]] arbeiten. Der Konstantstrom wird dabei über einen Widerstand eingestellt. Es entfallen somit die Vorwiderstände. Der Vorteil ist, dass Schwankungen der LED-Flußspannung oder Versorgungsspannung ausgeglichen werden, ohne dass die Helligkeit der LEDs sich dabei ändert. Außerdem erlauben die besseren Typen der Baureihe wie z.B. der TLC5922 eine Dimmung der einzelnen Kanäle. Doch Vorsicht! Die zulässige Verlustleistung des ICs ist groß, ca. 4W mit ausreichender [[Kühlkörper#Die_Platine_als_Kühlkörper |Kühlung]], aber nicht endlos. Denn die Restspannung aus Betriebsspannung und LED-Flußspannung fällt über dem IC ab. Als Minimum gilt je nach Strom 0,5-1V, welches über dem TLC5921 abfallen muss, damit er korrekt arbeitet. Nach oben wird die Grenze durch die Verlustleistung und max. Spannung von 17V gesetzt. Weiterhin ist zu beachten, dass hier das Multiplexing der Zeilen und Spalten vertauscht wurde.&lt;br /&gt;
&lt;br /&gt;
Gegeben&lt;br /&gt;
*&amp;lt;math&amp;gt;I_{Nenn}&amp;lt;/math&amp;gt;: Nennstrom der LED-Stränge: 10mA&lt;br /&gt;
*&amp;lt;math&amp;gt;U_{F}&amp;lt;/math&amp;gt;: Flußspannung der LED-Stränge: 9V&lt;br /&gt;
*&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;: Multiplexverhältnis (Zeilen): 1:8&lt;br /&gt;
*&amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;: Spalten in der Matrix: 8&lt;br /&gt;
*&amp;lt;math&amp;gt;R_{DS-ON, high}&amp;lt;/math&amp;gt;: Einschaltwiderstand der High Side MOSFETs : 0,25&lt;br /&gt;
&lt;br /&gt;
Gesucht:&lt;br /&gt;
*&amp;lt;math&amp;gt;I_{Spl}&amp;lt;/math&amp;gt;: Dauerstrom der Spaltentreiber = Pulsstrom der LEDs&lt;br /&gt;
*&amp;lt;math&amp;gt;I_{Zeil}&amp;lt;/math&amp;gt;: Pulsstrom der Zeilentreiber&lt;br /&gt;
*&amp;lt;math&amp;gt;P_V&amp;lt;/math&amp;gt;: Verlustleistung des TLC5921&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;I_{Spl} = I_{Nenn} \cdot N = 10mA \cdot 8 = 80mA&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;I_{Zeil} = I_{Nenn} \cdot N \cdot S = 10mA \cdot 8 \cdot 8 = 640mA&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;P_V=I_{Spl} \cdot S \cdot U_{Rest} = I_{Spl} \cdot S \cdot (Vcc - U_F - I_{Zeil} \cdot R_{DS-ON, high})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;P_V= 80mA \cdot 8 \cdot (12V - 9V - 1,6A \cdot 0,25 \Omega) = 1{,}66W&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* [[LED cube]]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/209988#new Forenbeitrag]: Nachleuchten beim Multiplexen vermeiden&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/search?query=%2Bled+%2Bmatrix&amp;amp;forums%5B%5D=1&amp;amp;forums%5B%5D=2&amp;amp;forums%5B%5D=4&amp;amp;forums%5B%5D=6 Beiträge zum Thema LED-Matrix im Forum]&lt;br /&gt;
* [http://members.ziggo.nl/electro1/avr/dotmatrix.htm Dotmatrix mit ATtiny2313 ansteuern, engl.]&lt;br /&gt;
* [http://www.braindrum.de/tools/leddotmatrix/leddotmatrix.htm LED-Dotmatrix mit ATmega16 ansteuern]&lt;br /&gt;
* Open Project [http://www.tiletoy.org/ TileToy] is a modular, electronic game prototype for tangible LED game tiles (PIC). [http://www.youtube.com/watch?v=XVmhlLvJNHc Youtube-Video]&lt;br /&gt;
* [http://www.kalanda.com/scroller-de-7x5-leds-basado-en-micro-attiny2313.html Eine 5x7 Matrix mit ATtiny2313 angesteuert, spanisch]&lt;br /&gt;
* [http://www.saccade.com/writing/projects/Puzzlemation/Puzzlemation.html Modulare Dotmatrixanzeige, engl.]&lt;br /&gt;
* [http://spritesmods.com/?art=ledmatrix Dotmatrix, engl.]&lt;br /&gt;
* [http://www.harbaum.org/till/ledmatrix/ Große LED-Matrix mit RS232 Ansteuerung, engl.]&lt;br /&gt;
* [https://www.das-labor.org/wiki/Blinken_Borgs Blinken_Borgs] Diverse Projekte von &#039;&#039;Das Labor&#039;&#039;&lt;br /&gt;
* [http://www.werkzeugh.at/intern/deflatable-led-matrix/ Eine aufblasbare LED-Matrix!]&lt;br /&gt;
* [http://metalab.at/wiki/MetaLEDs 8x48 LED-Matrix]&lt;br /&gt;
* [http://www.das-labor.org/wiki/Blinken_Borgs LED-Würfel mit 5^3 RGB-LEDs]&lt;br /&gt;
* [http://www.ulrichradig.de/home/index.php/avr/avr-mega-dis LED-Matrix bei Ulrich Radig]&lt;br /&gt;
* [http://www.elo-web.de/elo/entwicklung-und-projekte/ping-pong/laufschrift Eine kleine Laufschrift auf der Ping-Pong-Platine] von Sascha Bader (C, Atmega8)&lt;br /&gt;
* [http://www.sparkfun.com/tutorials/47 12 Fuß (3,6m) Wanduhr auf Sparkfun.com]&lt;br /&gt;
* [http://www.decadecounter.com/vta/articleview.php?item=879 Gigantic 5x7 LED Matrix] by AnubisTTP&lt;br /&gt;
* [http://klautesblog.blogspot.com/search/label/LED%20Matrix Mikes LED Matrix (21 x 21 LEDs)] by klaute&lt;br /&gt;
* [http://blinkenlights.net/ Blinkenlights] keine LEDs, aber groß (CCC)!&lt;br /&gt;
* Die riesige LED Tafel am [http://money.howstuffworks.com/nasdaq-marketsite-tower.htm Time Square] in New York, 105m hoch und 1 MW Spitzenverbrauch!&lt;br /&gt;
* Nochmal ein Artikel zur [http://bits.blogs.nytimes.com/2008/11/20/towering-led-sign-will-light-times-square/ Time Square LED-Wand] &lt;br /&gt;
* [http://wiki.niftylight.de niftylight] open-source Software um LED Matrix Ansteuerung zu erleichtern&lt;br /&gt;
* [http://www.dsw-elektronik.de/Dot-mat1.html DSW-Elektronik], Hersteller elektromechanischer Matrixelemente&lt;br /&gt;
* [http://www.crafted.de/photonenbanner.php LULI Photonenbanner 96x24]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Displays und Anzeigen]]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Soft-PWM&amp;diff=62623</id>
		<title>Soft-PWM</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Soft-PWM&amp;diff=62623"/>
		<updated>2011-12-20T23:18:59Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: /* Erster Versuch */ Schreibfehler korrigiert&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[PWM]] ist eine oft verwendete Funktion auf dem Gebiet der Mikrocontroller. Damit lassen sich vielfältige Aufgaben lösen, wie beispielsweise die Leistungssteuerung von Motoren, Helligkeitssteuerung von [[LED-Fading|LEDs]], [[DA-Wandler|Digital-Analog Wandlung]] und vieles mehr. Die meisten Mikrocontroller haben ein oder mehrere PWM-Module eingebaut, womit ohne CPU-Belastung eine PWM generiert werden kann. Jedoch kommt es bisweilen vor, daß die Anzahl der verfügbaren PWM-Kanäle nicht ausreicht. Dann muß eine Softwarelösung gefunden werden, bei der die CPU die PWM-Generierung vornimmt, genannt &#039;&#039;&#039;Soft-PWM&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
;Achtung: Wenn man für eine PWM aussschliesslich 8 Bit breite Datentypen verwendet, dann steht für den Parameter für die Pulsbreite nur der Bereich 0..255 zur Verfügung. Da bei einer vollständigen PWM mit N Schritten aber N+1 mögliche Fälle auftreten können (0/N bis N/0), ist mit dem hier gezeigten Code eine solche PWM nur für N ≤  255 realisierbar.&lt;br /&gt;
&lt;br /&gt;
== Einfacher Lösungsansatz ==&lt;br /&gt;
&lt;br /&gt;
Ein sehr einfacher Lösungsansatz findet sich im [[AVR-Tutorial: PWM]]. Hier wird schon ein [[AVR-Tutorial: Timer | Timer]] benutzt, um in regelmäßigen Abständen die PWM-Generierung durchzuführen. Damit verbleibt noch Rechenzeit für andere Aufgaben, außerdem wird die Programmierung wesentlich vereinfacht. Allerdings ist das Beispiel in ASM, hier soll das ganze in [[C]] gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Es soll nun eine 8 Bit PWM mit 100 Hz (PWM-Zyklus 10ms) und acht Kanälen generiert werden. Der verwendete Controller ist ein [[AVR]] vom Typ ATmega32, welcher mit dem internen RC-Oszillator auf 8 MHz getaktet wird. Das Programm kann jedoch problemlos an so ziemlich jeden anderen AVR angepaßt werden. Die Programme wurden mit dem Optimierungsgrad -Os compiliert.&lt;br /&gt;
&lt;br /&gt;
=== Erster Versuch ===&lt;br /&gt;
&lt;br /&gt;
Das Programm ist recht kurz und übersichtlich. Im Hauptprogramm wird der Timer 1 initialisiert und der Output Compare 1A als variabler Timer verwendet, wobei die Output Compare Funktion nicht mit dem IO-Pin verbunden ist. Im Interrupt, welcher regelmäßig aufgerufen wird, werden nun in einer Schleife alle acht Kanäle geprüft. Alle Kanäle werden auf HIGH gesetzt, welche eine PWM-Einstellung größer als der aktuelle Zykluszähler haben. Sinnvollerweise werden erst alle Kanäle geprüft und das Ergebnis zwischengespeichert, am Ende erfolgt nur ein Zugriff auf den Port.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
    Eine 8-kanalige PWM mit einfachem Lösungsansatz&lt;br /&gt;
&lt;br /&gt;
    ATmega32 @ 8 MHz&lt;br /&gt;
&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
// Defines an den Controller und die Anwendung anpassen&lt;br /&gt;
&lt;br /&gt;
#define F_CPU 8000000L                  // Systemtakt in Hz&lt;br /&gt;
#define F_PWM 100                       // PWM-Frequenz in Hz&lt;br /&gt;
#define PWM_STEPS 255                   // PWM-Schritte pro Zyklus(1..255)&lt;br /&gt;
#define PWM_PORT PORTD                  // Port für PWM&lt;br /&gt;
#define PWM_DDR DDRD                    // Datenrichtungsregister für PWM&lt;br /&gt;
&lt;br /&gt;
// ab hier nichts ändern, wird alles berechnet&lt;br /&gt;
&lt;br /&gt;
#define T_PWM (F_CPU/(F_PWM*PWM_STEPS)) // Systemtakte pro PWM-Takt&lt;br /&gt;
&lt;br /&gt;
#if (T_PWM&amp;lt;(152+5))&lt;br /&gt;
    #error T_PWM zu klein, F_CPU muss vergrössert werden oder F_PWM oder PWM_STEPS verkleinert werden&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
#if PWM_STEPS &amp;gt; 255&lt;br /&gt;
    #error PWM_STEPS zu gross&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// includes&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// globale Variablen&lt;br /&gt;
&lt;br /&gt;
volatile uint8_t pwm_setting[8];                    // Einstellungen für die einzelnen PWM-Kanäle&lt;br /&gt;
&lt;br /&gt;
// Timer 1 Output COMPARE A Interrupt&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect) {&lt;br /&gt;
    static uint8_t pwm_cnt=0;&lt;br /&gt;
    uint8_t tmp=0, i=0, j=1;&lt;br /&gt;
&lt;br /&gt;
    OCR1A += (uint16_t)T_PWM;&lt;br /&gt;
&lt;br /&gt;
    for (; i&amp;lt;8; i++) {    &lt;br /&gt;
    	if (pwm_setting[i] &amp;gt; pwm_cnt) tmp |= j;&lt;br /&gt;
            j&amp;lt;&amp;lt;=1;&lt;br /&gt;
	}&lt;br /&gt;
    PWM_PORT = tmp;                         // PWMs aktualisieren&lt;br /&gt;
    if (pwm_cnt==(uint8_t)(PWM_STEPS-1))&lt;br /&gt;
        pwm_cnt=0;&lt;br /&gt;
    else&lt;br /&gt;
        pwm_cnt++;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
&lt;br /&gt;
    // PWM einstellen&lt;br /&gt;
    &lt;br /&gt;
    PWM_DDR = 0xFF;         // Port als Ausgang&lt;br /&gt;
    &lt;br /&gt;
    // Timer 1 OCRA1, als variablem Timer nutzen&lt;br /&gt;
&lt;br /&gt;
    TCCR1B = 1;             // Timer läuft mit vollem Systemtakt&lt;br /&gt;
    TIMSK |= (1&amp;lt;&amp;lt;OCIE1A);   // Interrupt freischalten&lt;br /&gt;
&lt;br /&gt;
    sei();                  // Interrupts global einschalten&lt;br /&gt;
&lt;br /&gt;
/*********************************************************************/&lt;br /&gt;
// nur zum Testen, im Anwendungsfall löschen&lt;br /&gt;
&lt;br /&gt;
    volatile uint8_t tmp;&lt;br /&gt;
const uint8_t t1[8]={27, 40, 3, 17, 150, 99, 5, 9};&lt;br /&gt;
const uint8_t t2[8]={27, 40, 3, 0, 150, 99, 5, 9};&lt;br /&gt;
const uint8_t t3[8]={27, 40, 3, 17, 3, 99, 3, 0};&lt;br /&gt;
const uint8_t t4[8]={0, 0, 0, 0, 0, 0, 0, 0};&lt;br /&gt;
const uint8_t t5[8]={0, 0, 0, 0, 0, 0, 0, 9};&lt;br /&gt;
const uint8_t t6[8]={33, 33, 33, 33, 33, 33, 33, 33};&lt;br /&gt;
&lt;br /&gt;
// Messung der Interruptdauer&lt;br /&gt;
    tmp =0;&lt;br /&gt;
    tmp =0;&lt;br /&gt;
    tmp =0;&lt;br /&gt;
&lt;br /&gt;
// Debug &lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t1, 8);&lt;br /&gt;
    &lt;br /&gt;
    memcpy(pwm_setting, t2, 8);&lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t3, 8);&lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t4, 8);&lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t5, 8);&lt;br /&gt;
    &lt;br /&gt;
    memcpy(pwm_setting, t6, 8);&lt;br /&gt;
&lt;br /&gt;
/*********************************************************************/&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im [[AVR-Studio]] kann man den Code simulieren. Wichtig ist hier vor allem die Ausführungszeit des Interrupts. Bei 100 Hz PWM-Frequenz und 256 Schritten pro PWM-Zyklus wird diese Funktion immerhin 25600 mal pro Sekunde aufgerufen (PWM-Takt 25,6 kHz),  bei 8MHz Taktfrequenz stehen damit maximal 312 Takte zur Verfügung. Glücklicherweise ist die Funktion relativ kurz und der GCC leistet gute Arbeit. Der Interrupt benötigt hier 152 Takte, es verbleiben also jeweils 160 Takte zur Bearbeitung anderer Aufgaben. Das entspricht einer CPU-Belastung von ~49%. Das Programm benötigt 284 Byte Programmspeicher. Nicht schlecht für den Anfang.&lt;br /&gt;
&lt;br /&gt;
=== Zweiter Versuch ===&lt;br /&gt;
&lt;br /&gt;
Wo gibt es in diesem Programm noch Optimierungsmöglichkeiten? Nur im Interrupt, denn das ganze Programm besteht ja praktisch nur aus der Interruptroutine. Betrachten wir die Schleifen genauer müssen wir feststellen, dass die Indizierung von pwm_setting[] etwas Rechenzeit benötigt. Ebenso die Schiebeoperation von tmp, auch wenn das nur acht mal ein Takt ist. Wir können jetzt per Hand das machen, was der Compiler auch manchmal macht. Die Rede ist vom Loop-Unrolling. Dabei wird die Schleife durch mehrere diskrete Befehle ersetzt (entrollt). Der Vorteil dabei ist, dass die Befehle zur Berechnung und Prüfung der Zählvariable entfallen, außerdem können ggf. Werte im Voraus berechnet werden. Als Ergebnis hat man zwar ein etwas größeres Programm, doch das wird schneller ausgeführt! Außerdem orientiert sich diese Version mehr am Original der Assemblerversion. Dadurch wird sie zusätzlich ein wenig kürzer und schneller.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
    Eine 8-kanalige PWM mit verbessertem Lösungsansatz&lt;br /&gt;
&lt;br /&gt;
    ATmega32 @ 8 MHz&lt;br /&gt;
&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
// Defines an den Controller und die Anwendung anpassen&lt;br /&gt;
&lt;br /&gt;
#define F_CPU 8000000L                  // Systemtakt in Hz&lt;br /&gt;
#define F_PWM 100                       // PWM-Frequenz in Hz&lt;br /&gt;
#define PWM_STEPS 256                   // PWM-Schritte pro Zyklus(1..256)&lt;br /&gt;
#define PWM_PORT PORTD                  // Port für PWM&lt;br /&gt;
#define PWM_DDR DDRD                    // Datenrichtungsregister für PWM&lt;br /&gt;
&lt;br /&gt;
// ab hier nichts ändern, wird alles berechnet&lt;br /&gt;
&lt;br /&gt;
#define T_PWM (F_CPU/(F_PWM*PWM_STEPS)) // Systemtakte pro PWM-Takt&lt;br /&gt;
&lt;br /&gt;
#if (T_PWM&amp;lt;(93+5))&lt;br /&gt;
    #error T_PWM zu klein, F_CPU muss vergrössert werden oder F_PWM oder PWM_STEPS verkleinert werden&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// includes&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// globale Variablen&lt;br /&gt;
&lt;br /&gt;
volatile uint8_t pwm_setting[8];                    // Einstellungen für die einzelnen PWM-Kanäle&lt;br /&gt;
&lt;br /&gt;
// Timer 1 Output COMPARE A Interrupt&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect) {&lt;br /&gt;
    static uint8_t pwm_cnt=0;&lt;br /&gt;
    uint8_t tmp=0;&lt;br /&gt;
&lt;br /&gt;
    OCR1A += (uint16_t)T_PWM;&lt;br /&gt;
        &lt;br /&gt;
    if (pwm_setting[0] &amp;gt; pwm_cnt) tmp |= (1&amp;lt;&amp;lt;0);&lt;br /&gt;
    if (pwm_setting[1] &amp;gt; pwm_cnt) tmp |= (1&amp;lt;&amp;lt;1);&lt;br /&gt;
    if (pwm_setting[2] &amp;gt; pwm_cnt) tmp |= (1&amp;lt;&amp;lt;2);&lt;br /&gt;
    if (pwm_setting[3] &amp;gt; pwm_cnt) tmp |= (1&amp;lt;&amp;lt;3);&lt;br /&gt;
    if (pwm_setting[4] &amp;gt; pwm_cnt) tmp |= (1&amp;lt;&amp;lt;4);&lt;br /&gt;
    if (pwm_setting[5] &amp;gt; pwm_cnt) tmp |= (1&amp;lt;&amp;lt;5);&lt;br /&gt;
    if (pwm_setting[6] &amp;gt; pwm_cnt) tmp |= (1&amp;lt;&amp;lt;6);&lt;br /&gt;
    if (pwm_setting[7] &amp;gt; pwm_cnt) tmp |= (1&amp;lt;&amp;lt;7);&lt;br /&gt;
    PWM_PORT = tmp;                         // PWMs aktualisieren&lt;br /&gt;
    if (pwm_cnt==(uint8_t)(PWM_STEPS-1))&lt;br /&gt;
        pwm_cnt=0;&lt;br /&gt;
    else&lt;br /&gt;
        pwm_cnt++;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
&lt;br /&gt;
    // PWM einstellen&lt;br /&gt;
    &lt;br /&gt;
    PWM_DDR = 0xFF;         // Port als Ausgang&lt;br /&gt;
    &lt;br /&gt;
    // Timer 1 OCRA1, als variablem Timer nutzen&lt;br /&gt;
&lt;br /&gt;
    TCCR1B = 1;             // Timer läuft mit vollem Systemtakt&lt;br /&gt;
    TIMSK |= (1&amp;lt;&amp;lt;OCIE1A);   // Interrupt freischalten&lt;br /&gt;
&lt;br /&gt;
    sei();                  // Interrupts global einschalten&lt;br /&gt;
&lt;br /&gt;
/*********************************************************************/&lt;br /&gt;
// nur zum Testen, im Anwendungsfall löschen&lt;br /&gt;
&lt;br /&gt;
    volatile uint8_t tmp;&lt;br /&gt;
const uint8_t t1[8]={27, 40, 3, 17, 150, 99, 5, 9};&lt;br /&gt;
const uint8_t t2[8]={27, 40, 3, 0, 150, 99, 5, 9};&lt;br /&gt;
const uint8_t t3[8]={27, 40, 3, 17, 3, 99, 3, 0};&lt;br /&gt;
const uint8_t t4[8]={0, 0, 0, 0, 0, 0, 0, 0};&lt;br /&gt;
const uint8_t t5[8]={0, 0, 0, 0, 0, 0, 0, 9};&lt;br /&gt;
const uint8_t t6[8]={33, 33, 33, 33, 33, 33, 33, 33};&lt;br /&gt;
&lt;br /&gt;
// Messung der Interruptdauer&lt;br /&gt;
    tmp =0;&lt;br /&gt;
    tmp =0;&lt;br /&gt;
    tmp =0;&lt;br /&gt;
&lt;br /&gt;
// Debug &lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t1, 8);&lt;br /&gt;
    &lt;br /&gt;
    memcpy(pwm_setting, t2, 8);&lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t3, 8);&lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t4, 8);&lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t5, 8);&lt;br /&gt;
    &lt;br /&gt;
    memcpy(pwm_setting, t6, 8);&lt;br /&gt;
&lt;br /&gt;
/*********************************************************************/&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit dieser Interruptroutine werden nur noch 93 Takte benötigt, die CPU-Belastung verringert sich auf  ~30%. Nicht schlecht. Der Programmcode steigt auf 324 Byte, aber das ist im Angesicht der Leistungsverbesserung zu verschmerzen. Weiter verringern kann man die CPU-Belastung durch eine niedrigere PWM-Frequenz oder eine geringere Anzahl Stufen der PWM. Wenn man beispielsweise mit 64 (6 Bit) statt 256 (8 Bit) Stufen auskommt verringert sich die Belastung um den Faktor 4.&lt;br /&gt;
&lt;br /&gt;
== Intelligenter Lösungsansatz ==&lt;br /&gt;
&lt;br /&gt;
Wenn auch eine CPU-Last von 30% recht akzeptabel erscheint, so hat man doch noch irgendwie das Gefühl, daß es noch besser geht. Aber wie? Mein Mathematikprofessor pflegte in so einem Fall die Anwendung der „Methode des scharfen Blicks“ ™. Was passiert eigentlich während eines gesamten PWM-Zykluses?&lt;br /&gt;
&lt;br /&gt;
*Zu Beginn werden alle IO-Pins gesetzt, deren PWM-Einstellung nicht Null ist.&lt;br /&gt;
*Die jeweiligen IO-Pins werden gelöscht, wenn der PWM-Zähler mit der PWM-Einstellung übereinstimmt&lt;br /&gt;
&lt;br /&gt;
Ja klar, aber da wir nur acht Kanäle haben, gibt es maximal 8 Zeitpunkte, an denen ein Pin gelöscht werden muss. Wenn mehrere Kanäle die gleiche PWM-Einstellung haben sind es sogar noch weniger. Alle anderen Interrupts verursachen keinerlei Änderung der IO-Pins und verbrauchen eigentlich nur sinnlos Rechenzeit. Ein Skandal!&lt;br /&gt;
&lt;br /&gt;
Was ist also zu tun? Wir wissen nun, daß es maximal 9 Ereignisse pro PWM-Zyklus gibt. Was ist damit zu machen?&lt;br /&gt;
&lt;br /&gt;
*Die PWM-Kanäle müssen in aufsteigender Folge sortiert werden.&lt;br /&gt;
*Wenn mehrere PWM-Kanäle den gleichen PWM-Wert haben müssen sie zusammengefaßt werden&lt;br /&gt;
*Die Zeitdifferenzen zwischen den einzelnen Ereignissen müssen berechnet werden&lt;br /&gt;
&lt;br /&gt;
Das ist eigentlich schon alles. Praktisch ist das mit einigen Kniffligkeiten verbunden, aber die sind lösbar. Am Ende steht eine Interruptroutine, welche maximal 9 mal pro PWM-Zyklus aufgerufen wird und die jeweiligen IO-Pins setzt bzw. löscht. Eine normale Funktion wird benutzt, um die PWM-Einstellungen der acht Kanäle in die notwendigen Informationen für die Interruptroutine umzuwandeln. Das hat unter anderem den Vorteil, daß nur dann zusätzlich Rechenzeit benötigt wird, wenn sich die PWM-Einstellungen ändern.&lt;br /&gt;
&lt;br /&gt;
Es sollte jedoch nicht unerwähnt bleiben, dass es sich bei dieser Lösung um keine echte PWM handelt, da sie im Fall, dass ein PWM-Wert 0 ist, den Ausgang nie auf 1 schaltet, und somit auch kein Puls vorhanden ist. Allerdings ist das für die meisten Anwendungen kein Problem.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
    Eine 8-kanalige PWM mit intelligentem Lösungsansatz&lt;br /&gt;
&lt;br /&gt;
    ATmega32 @ 8 MHz&lt;br /&gt;
&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
// Defines an den Controller und die Anwendung anpassen&lt;br /&gt;
&lt;br /&gt;
#define F_CPU         8000000L           // Systemtakt in Hz&lt;br /&gt;
#define F_PWM         100L               // PWM-Frequenz in Hz&lt;br /&gt;
#define PWM_PRESCALER 8                  // Vorteiler für den Timer&lt;br /&gt;
#define PWM_STEPS     256                // PWM-Schritte pro Zyklus(1..256)&lt;br /&gt;
#define PWM_PORT      PORTB              // Port für PWM&lt;br /&gt;
#define PWM_DDR       DDRB               // Datenrichtungsregister für PWM&lt;br /&gt;
#define PWM_CHANNELS  8                  // Anzahl der PWM-Kanäle&lt;br /&gt;
&lt;br /&gt;
// ab hier nichts ändern, wird alles berechnet&lt;br /&gt;
&lt;br /&gt;
#define T_PWM (F_CPU/(PWM_PRESCALER*F_PWM*PWM_STEPS)) // Systemtakte pro PWM-Takt&lt;br /&gt;
//#define T_PWM 1   //TEST&lt;br /&gt;
&lt;br /&gt;
#if ((T_PWM*PWM_PRESCALER)&amp;lt;(111+5))&lt;br /&gt;
    #error T_PWM zu klein, F_CPU muss vergrössert werden oder F_PWM oder PWM_STEPS verkleinert werden&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
#if ((T_PWM*PWM_STEPS)&amp;gt;65535)&lt;br /&gt;
    #error Periodendauer der PWM zu gross! F_PWM oder PWM_PRESCALER erhöhen.   &lt;br /&gt;
#endif&lt;br /&gt;
// includes&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// globale Variablen&lt;br /&gt;
&lt;br /&gt;
uint16_t pwm_timing[PWM_CHANNELS+1];          // Zeitdifferenzen der PWM Werte&lt;br /&gt;
uint16_t pwm_timing_tmp[PWM_CHANNELS+1];      &lt;br /&gt;
&lt;br /&gt;
uint8_t  pwm_mask[PWM_CHANNELS+1];            // Bitmaske für PWM Bits, welche gelöscht werden sollen&lt;br /&gt;
uint8_t  pwm_mask_tmp[PWM_CHANNELS+1];        // ändern uint16_t oder uint32_t für mehr Kanäle&lt;br /&gt;
&lt;br /&gt;
uint8_t  pwm_setting[PWM_CHANNELS];           // Einstellungen für die einzelnen PWM-Kanäle&lt;br /&gt;
uint8_t  pwm_setting_tmp[PWM_CHANNELS+1];     // Einstellungen der PWM Werte, sortiert&lt;br /&gt;
                                              // ändern auf uint16_t für mehr als 8 Bit Auflösung  &lt;br /&gt;
&lt;br /&gt;
volatile uint8_t pwm_cnt_max=1;               // Zählergrenze, Initialisierung mit 1 ist wichtig!&lt;br /&gt;
volatile uint8_t pwm_sync;                    // Update jetzt möglich&lt;br /&gt;
&lt;br /&gt;
// Pointer für wechselseitigen Datenzugriff&lt;br /&gt;
&lt;br /&gt;
uint16_t *isr_ptr_time  = pwm_timing;&lt;br /&gt;
uint16_t *main_ptr_time = pwm_timing_tmp;&lt;br /&gt;
&lt;br /&gt;
uint8_t *isr_ptr_mask  = pwm_mask;              // Bitmasken fuer PWM-Kanäle&lt;br /&gt;
uint8_t *main_ptr_mask = pwm_mask_tmp;          // ändern uint16_t oder uint32_t für mehr Kanäle&lt;br /&gt;
&lt;br /&gt;
// Zeiger austauschen&lt;br /&gt;
// das muss in einem Unterprogramm erfolgen,&lt;br /&gt;
// um eine Zwischenspeicherung durch den Compiler zu verhindern&lt;br /&gt;
&lt;br /&gt;
void tausche_zeiger(void) {&lt;br /&gt;
    uint16_t *tmp_ptr16;&lt;br /&gt;
    uint8_t *tmp_ptr8;                          // ändern uint16_t oder uint32_t für mehr Kanäle&lt;br /&gt;
&lt;br /&gt;
    tmp_ptr16 = isr_ptr_time;&lt;br /&gt;
    isr_ptr_time = main_ptr_time;&lt;br /&gt;
    main_ptr_time = tmp_ptr16;&lt;br /&gt;
    tmp_ptr8 = isr_ptr_mask;&lt;br /&gt;
    isr_ptr_mask = main_ptr_mask;&lt;br /&gt;
    main_ptr_mask = tmp_ptr8;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// PWM Update, berechnet aus den PWM Einstellungen&lt;br /&gt;
// die neuen Werte für die Interruptroutine&lt;br /&gt;
&lt;br /&gt;
void pwm_update(void) {&lt;br /&gt;
    &lt;br /&gt;
    uint8_t i, j, k;&lt;br /&gt;
    uint8_t m1, m2, tmp_mask;                   // ändern uint16_t oder uint32_t für mehr Kanäle    &lt;br /&gt;
    uint8_t min, tmp_set;                       // ändern auf uint16_t für mehr als 8 Bit Auflösung&lt;br /&gt;
&lt;br /&gt;
    // PWM Maske für Start berechnen&lt;br /&gt;
    // gleichzeitig die Bitmasken generieren und PWM Werte kopieren&lt;br /&gt;
&lt;br /&gt;
    m1 = 1;&lt;br /&gt;
    m2 = 0;&lt;br /&gt;
    for(i=1; i&amp;lt;=(PWM_CHANNELS); i++) {&lt;br /&gt;
        main_ptr_mask[i]=~m1;                       // Maske zum Löschen der PWM Ausgänge&lt;br /&gt;
        pwm_setting_tmp[i] = pwm_setting[i-1];&lt;br /&gt;
        if (pwm_setting_tmp[i]!=0) m2 |= m1;        // Maske zum setzen der IOs am PWM Start&lt;br /&gt;
        m1 &amp;lt;&amp;lt;= 1;&lt;br /&gt;
    }&lt;br /&gt;
    main_ptr_mask[0]=m2;                            // PWM Start Daten &lt;br /&gt;
&lt;br /&gt;
    // PWM settings sortieren; Einfügesortieren&lt;br /&gt;
&lt;br /&gt;
    for(i=1; i&amp;lt;=PWM_CHANNELS; i++) {&lt;br /&gt;
        min=PWM_STEPS-1;&lt;br /&gt;
        k=i;&lt;br /&gt;
        for(j=i; j&amp;lt;=PWM_CHANNELS; j++) {&lt;br /&gt;
            if (pwm_setting_tmp[j]&amp;lt;min) {&lt;br /&gt;
                k=j;                                // Index und PWM-setting merken&lt;br /&gt;
                min = pwm_setting_tmp[j];&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        if (k!=i) {&lt;br /&gt;
            // ermitteltes Minimum mit aktueller Sortiertstelle tauschen&lt;br /&gt;
            tmp_set = pwm_setting_tmp[k];&lt;br /&gt;
            pwm_setting_tmp[k] = pwm_setting_tmp[i];&lt;br /&gt;
            pwm_setting_tmp[i] = tmp_set;&lt;br /&gt;
            tmp_mask = main_ptr_mask[k];&lt;br /&gt;
            main_ptr_mask[k] = main_ptr_mask[i];&lt;br /&gt;
            main_ptr_mask[i] = tmp_mask;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Gleiche PWM-Werte vereinigen, ebenso den PWM-Wert 0 löschen falls vorhanden&lt;br /&gt;
&lt;br /&gt;
    k=PWM_CHANNELS;             // PWM_CHANNELS Datensätze&lt;br /&gt;
    i=1;                        // Startindex&lt;br /&gt;
&lt;br /&gt;
    while(k&amp;gt;i) {&lt;br /&gt;
        while ( ((pwm_setting_tmp[i]==pwm_setting_tmp[i+1]) || (pwm_setting_tmp[i]==0))  &amp;amp;&amp;amp; (k&amp;gt;i) ) {&lt;br /&gt;
&lt;br /&gt;
            // aufeinanderfolgende Werte sind gleich und können vereinigt werden&lt;br /&gt;
            // oder PWM Wert ist Null&lt;br /&gt;
            if (pwm_setting_tmp[i]!=0)&lt;br /&gt;
                main_ptr_mask[i+1] &amp;amp;= main_ptr_mask[i];        // Masken vereinigen&lt;br /&gt;
&lt;br /&gt;
            // Datensatz entfernen,&lt;br /&gt;
            // Nachfolger alle eine Stufe hochschieben&lt;br /&gt;
            for(j=i; j&amp;lt;k; j++) {&lt;br /&gt;
                pwm_setting_tmp[j] = pwm_setting_tmp[j+1];&lt;br /&gt;
                main_ptr_mask[j] = main_ptr_mask[j+1];&lt;br /&gt;
            }&lt;br /&gt;
            k--;&lt;br /&gt;
        }&lt;br /&gt;
        i++;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // letzten Datensatz extra behandeln&lt;br /&gt;
    // Vergleich mit dem Nachfolger nicht möglich, nur löschen&lt;br /&gt;
    // gilt nur im Sonderfall, wenn alle Kanäle 0 sind&lt;br /&gt;
    if (pwm_setting_tmp[i]==0) k--;&lt;br /&gt;
&lt;br /&gt;
    // Zeitdifferenzen berechnen&lt;br /&gt;
    &lt;br /&gt;
    if (k==0) { // Sonderfall, wenn alle Kanäle 0 sind&lt;br /&gt;
        main_ptr_time[0]=(uint16_t)T_PWM*PWM_STEPS/2;&lt;br /&gt;
        main_ptr_time[1]=(uint16_t)T_PWM*PWM_STEPS/2;&lt;br /&gt;
        k=1;&lt;br /&gt;
    }&lt;br /&gt;
    else {&lt;br /&gt;
        i=k;&lt;br /&gt;
        main_ptr_time[i]=(uint16_t)T_PWM*(PWM_STEPS-pwm_setting_tmp[i]);&lt;br /&gt;
        tmp_set=pwm_setting_tmp[i];&lt;br /&gt;
        i--;&lt;br /&gt;
        for (; i&amp;gt;0; i--) {&lt;br /&gt;
            main_ptr_time[i]=(uint16_t)T_PWM*(tmp_set-pwm_setting_tmp[i]);&lt;br /&gt;
            tmp_set=pwm_setting_tmp[i];&lt;br /&gt;
        }&lt;br /&gt;
        main_ptr_time[0]=(uint16_t)T_PWM*tmp_set;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // auf Sync warten&lt;br /&gt;
&lt;br /&gt;
    pwm_sync=0;             // Sync wird im Interrupt gesetzt&lt;br /&gt;
    while(pwm_sync==0);&lt;br /&gt;
&lt;br /&gt;
    // Zeiger tauschen&lt;br /&gt;
    cli();&lt;br /&gt;
    tausche_zeiger();&lt;br /&gt;
    pwm_cnt_max = k;&lt;br /&gt;
    sei();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Timer 1 Output COMPARE A Interrupt&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect) {&lt;br /&gt;
    static uint8_t pwm_cnt;                     // ändern auf uint16_t für mehr als 8 Bit Auflösung&lt;br /&gt;
    uint8_t tmp;                                // ändern uint16_t oder uint32_t für mehr Kanäle&lt;br /&gt;
&lt;br /&gt;
    OCR1A += isr_ptr_time[pwm_cnt];&lt;br /&gt;
    tmp    = isr_ptr_mask[pwm_cnt];&lt;br /&gt;
    &lt;br /&gt;
    if (pwm_cnt == 0) {&lt;br /&gt;
        PWM_PORT = tmp;                         // Ports setzen zu Begin der PWM&lt;br /&gt;
                                                // zusätzliche PWM-Ports hier setzen&lt;br /&gt;
        pwm_cnt++;&lt;br /&gt;
    }&lt;br /&gt;
    else {&lt;br /&gt;
        PWM_PORT &amp;amp;= tmp;                        // Ports löschen&lt;br /&gt;
                                                // zusätzliche PWM-Ports hier setzen&lt;br /&gt;
        if (pwm_cnt == pwm_cnt_max) {&lt;br /&gt;
            pwm_sync = 1;                       // Update jetzt möglich&lt;br /&gt;
            pwm_cnt  = 0;&lt;br /&gt;
        }&lt;br /&gt;
        else pwm_cnt++;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
&lt;br /&gt;
    // PWM Port einstellen&lt;br /&gt;
    &lt;br /&gt;
    PWM_DDR = 0xFF;         // Port als Ausgang&lt;br /&gt;
    // zusätzliche PWM-Ports hier setzen&lt;br /&gt;
    &lt;br /&gt;
    // Timer 1 OCRA1, als variablen Timer nutzen&lt;br /&gt;
&lt;br /&gt;
    TCCR1B = 2;             // Timer läuft mit Prescaler 8&lt;br /&gt;
    TIMSK |= (1&amp;lt;&amp;lt;OCIE1A);   // Interrupt freischalten&lt;br /&gt;
&lt;br /&gt;
    sei();                  // Interrupts global einschalten&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/******************************************************************/&lt;br /&gt;
// nur zum testen, in der Anwendung entfernen&lt;br /&gt;
/*&lt;br /&gt;
// Test values&lt;br /&gt;
volatile uint8_t tmp;&lt;br /&gt;
const uint8_t t1[8]={255, 40, 3, 17, 150, 99, 5, 9};&lt;br /&gt;
const uint8_t t2[8]={27, 40, 3, 0, 150, 99, 5, 9};&lt;br /&gt;
const uint8_t t3[8]={27, 40, 3, 17, 3, 99, 3, 0};&lt;br /&gt;
const uint8_t t4[8]={0, 0, 0, 0, 0, 0, 0, 0};&lt;br /&gt;
const uint8_t t5[8]={9, 1, 1, 1, 1, 1, 1, 1};&lt;br /&gt;
const uint8_t t6[8]={33, 33, 33, 33, 33, 33, 33, 33};&lt;br /&gt;
const uint8_t t7[8]={0, 0, 0, 0, 0, 0, 0, 88};&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// Messung der Interruptdauer&lt;br /&gt;
    tmp =1;&lt;br /&gt;
    tmp =2;&lt;br /&gt;
    tmp =3;&lt;br /&gt;
&lt;br /&gt;
// Debug &lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t1, 8);&lt;br /&gt;
    pwm_update();&lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t2, 8);&lt;br /&gt;
    pwm_update();&lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t3, 8);&lt;br /&gt;
    pwm_update();&lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t4, 8);&lt;br /&gt;
    pwm_update();&lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t5, 8);&lt;br /&gt;
    pwm_update();&lt;br /&gt;
    &lt;br /&gt;
    memcpy(pwm_setting, t6, 8);&lt;br /&gt;
    pwm_update();&lt;br /&gt;
    &lt;br /&gt;
    memcpy(pwm_setting, t7, 8);&lt;br /&gt;
    pwm_update();&lt;br /&gt;
*/&lt;br /&gt;
/******************************************************************/&lt;br /&gt;
&lt;br /&gt;
    while(1);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Programm ist schon um einiges länger (968 Byte). Die Interruptroutine benötigt maximal 111 Takte und wird zwischen 2 bis 9 mal pro PWM-Zyklus aufgerufen. Zweimal, wenn alle PWM-Einstellungen gleich sind, 9 mal, wenn alle PWM-Einstellungen verschieden sind. Damit werden zwischen 222 bis 999 Takte benötigt, pro &#039;&#039;&#039;PWM-Zyklus&#039;&#039;&#039;, nicht pro PWM-Takt! Das entspricht einer &#039;&#039;&#039;CPU-Belastung von 0,3..1,2%&#039;&#039;&#039;! [http://de.wikipedia.org/wiki/Beifall Standing Ovations]! Die Funktion pwm_update() benötigt ca. 1500 bis 1800 Takte, das ist geringfügig abhängig von den PWM-Einstellungen, je nach dem ob die Daten schon sortiert sind und ob PWM-Werte mehrfach vorkommen. Bei einer Updaterate von 100 Hz (mehr ist physikalisch sinnlos) entspricht das einer CPU-Belastung von 2,3%, praktisch wird es wahrscheinlich weniger sein. Taktet man den AVR mit vollen 16 MHz halbiert sich die CPU-Belastung noch einmal. Beachtet werden sollte hier die Datenübergabe von der Funktion pwm_update() zur Interruptroutine. Hier werden jeweils zwei Zeiger verwendet, um auf Arrays zu zeigen. In zwei Arrays werden durch die Funktion die Berechnungen der neuen Daten vorgenommen. In den beiden anderen Arrays stehen die aktuellen Daten, mit welchen die ISR arbeitet. Um am Ende der Berechung ein relativ aufwändiges Kopieren der Daten zu vermeiden werden einfach die Zeiger vertauscht. Das ist wesentlich schneller als das Kopieren der Arrays! Im englischen spricht man hier von double buffering, also doppelter Pufferung. Dieses Prinzip wird oft angewendet. Würde man allerdings einfach am Ende die Zeiger tauschen käme es zu einem Crash! Der Interrupt kann jederzeit aktiv werden. Wenn dann die Zeiger nur halb kopiert sind greift die Interruptroutine auf zerstückelte Daten zu und macht Müll. Ebenso würde es zu Fehlfunktionen kommen, wenn während es PWM-Zyklus neue Daten in die Arrays kopiert werden. Das muß verhindert werden. Und zwar dadurch, daß über eine Variable eine Synchronisation durchgeführt wird. Diese wird am Ende des PWM-Zyklus gesetzt und signalisiert, daß neue Daten für den nächsten Zyklus kopiert werden können. Deshalb muss die Funktion pwm_update ggf. bis zu 1 vollen PWM-Zyklus warten, bis die Zeiger getauscht werden können. Wichtig ist dabei, daß die Variable pwm_sync, welche sowohl in der Funktion als auch im Interrupt geschrieben wird, als &#039;&#039;&#039;volatile&#039;&#039;&#039; deklariert wird. Denn sonst würde die Sequenz&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
pwm_sync=0;             // Sync wird im Interrupt gesetzt&lt;br /&gt;
while(pwm_sync==0);&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
zum Stehenbleiben der CPU führen, weil der Compiler erkennt, daß die Variable nie ungleich Null sein kann und damit die Schleife endlos ausgeführt wird. Der Compiler kann prinzipbedingt nicht automatisch erkennen, daß die Variable im Interrupt auf 1 gesetzt wird.&lt;br /&gt;
&lt;br /&gt;
Bei dem schon recht hohen Prozessortakt von 8MHz und der relativ niedrigen PWM Frequenz von 100 Hz haben wir allerdings ein kleines Problem. Wenn beispielsweise nur ein Kanal den PWM-Wert 10 hat, alle anderen aber den Wert Null, dann passiert folgendes. Zum Begin eines PWM-Zyklus wird der eine Kanal aktiviert. Jetzt wird per Timer für 10xT_PWM = 3120 Takte gewartet. Jetzt wird dieser Kanal wieder gelöscht. Bis zum Begin des nächsten PWM-Zyklus muss jedoch noch (256-10)*T_PWM = 76752 Takte gewartet werden. Doch diese Zahl passt nicht mehr in eine 16 Bit Variable! Und damit kann sie auch nicht mit dem Timer verwendet werden. Der Ausweg heisst Vorteiler (engl. Prescaler). Damit kann der Timer langsamer getaktet werden und somit wird die gleiche Wartezeit mit weniger Timertakten erzielt. Zu beachten ist, dass die Einstellung im #define PWM_PRESCALER mit der realen Einstellung in TCCR1B übereinstimmen muss.&lt;br /&gt;
&lt;br /&gt;
Eine Einschränkung gilt allerdings für alle Soft-PWMs. Die PWM-Frequenz muss niedrig genug sein, damit sich die Interrupts nicht überschneiden. D.h. der Wert T_PWM muß immer größer sein als die Anzahl Takte der Interruptroutine. Das wird im Quelltext mit Hilfe von #if  . . #endif geprüft. Die +5 Takte sind eine Reserve. Dazu muß aber die Optimierung -Os eingeschaltet sein, sonst stimmen die Zahlen nicht!&lt;br /&gt;
&lt;br /&gt;
Als Grenze kann mit diesem Programm bei 16 MHz eine 10-Bit PWM in Software generiert werden, was schon sehr respektabel ist und weiches, langsames [[LED-Fading]] mit vielen [[LED]]s ermöglicht. Dazu muss allerdings das Programm an wenigen Stellen angepasst werden, im Speziellen müssen verschiedene Variablen und Arrays von uint8_t auf uint16_t umgestellt werden. Da Gleiche gilt für mehr PWM-Kanäle, praktisch wurden schon bis zu 32 Kanäle realisiert. Der Quelltext ist an den Stellen kommentiert.&lt;br /&gt;
&lt;br /&gt;
== Zusammenfassung ==&lt;br /&gt;
&lt;br /&gt;
Durch kritische Analyse ist es möglich, eine Software-PWM drastisch zu verbessern und die CPU-Belastung auf ein verschwindend geringes Maß zu reduzieren. Zudem zeigt dieses Beispiel ein oft vorkommendes Muster auf, welches gemeinhin als &#039;Time for Space&#039; (Zeit für Platz) bezeichnet wird. Man meint damit, dass es oft möglich ist, dramatische Einsparungen in der Laufzeit zu erreichen, wenn man gewillt ist dafür Speicherplatz zu opfern.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| Version  || Programmspeicher [Byte] || CPU-Belastung [%] &lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 1 || 284   || 49&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 2 || 324   || 30&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 3 || 968   || 0,3..1,2&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* [[AVR-Tutorial: PWM]]&lt;br /&gt;
* [[AVR-GCC-Tutorial#PWM (Pulsweitenmodulation)|AVR-GCC-Tutorial: PWM]]&lt;br /&gt;
* [[LED-Fading]] - LED dimmen mit PWM&lt;br /&gt;
&lt;br /&gt;
[[Category:AVR]]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Soft-PWM&amp;diff=62622</id>
		<title>Soft-PWM</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Soft-PWM&amp;diff=62622"/>
		<updated>2011-12-20T23:18:05Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: /* Intelligenter Lösungsansatz */ Schreibfehler korrigiert&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[PWM]] ist eine oft verwendete Funktion auf dem Gebiet der Mikrocontroller. Damit lassen sich vielfältige Aufgaben lösen, wie beispielsweise die Leistungssteuerung von Motoren, Helligkeitssteuerung von [[LED-Fading|LEDs]], [[DA-Wandler|Digital-Analog Wandlung]] und vieles mehr. Die meisten Mikrocontroller haben ein oder mehrere PWM-Module eingebaut, womit ohne CPU-Belastung eine PWM generiert werden kann. Jedoch kommt es bisweilen vor, daß die Anzahl der verfügbaren PWM-Kanäle nicht ausreicht. Dann muß eine Softwarelösung gefunden werden, bei der die CPU die PWM-Generierung vornimmt, genannt &#039;&#039;&#039;Soft-PWM&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
;Achtung: Wenn man für eine PWM aussschliesslich 8 Bit breite Datentypen verwendet, dann steht für den Parameter für die Pulsbreite nur der Bereich 0..255 zur Verfügung. Da bei einer vollständigen PWM mit N Schritten aber N+1 mögliche Fälle auftreten können (0/N bis N/0), ist mit dem hier gezeigten Code eine solche PWM nur für N ≤  255 realisierbar.&lt;br /&gt;
&lt;br /&gt;
== Einfacher Lösungsansatz ==&lt;br /&gt;
&lt;br /&gt;
Ein sehr einfacher Lösungsansatz findet sich im [[AVR-Tutorial: PWM]]. Hier wird schon ein [[AVR-Tutorial: Timer | Timer]] benutzt, um in regelmäßigen Abständen die PWM-Generierung durchzuführen. Damit verbleibt noch Rechenzeit für andere Aufgaben, außerdem wird die Programmierung wesentlich vereinfacht. Allerdings ist das Beispiel in ASM, hier soll das ganze in [[C]] gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Es soll nun eine 8 Bit PWM mit 100 Hz (PWM-Zyklus 10ms) und acht Kanälen generiert werden. Der verwendete Controller ist ein [[AVR]] vom Typ ATmega32, welcher mit dem internen RC-Oszillator auf 8 MHz getaktet wird. Das Programm kann jedoch problemlos an so ziemlich jeden anderen AVR angepaßt werden. Die Programme wurden mit dem Optimierungsgrad -Os compiliert.&lt;br /&gt;
&lt;br /&gt;
=== Erster Versuch ===&lt;br /&gt;
&lt;br /&gt;
Das Programm ist recht kurz und übersichtlich. Im Hauptprogramm wird der Timer 1 initialisiert und der Output Compare 1A als variabler Timer verwendet, wobei die Output Compare Funktion nicht mit dem IO-Pin verbunden ist. Im Interrupt, welcher regelmäßig aufgerufen wird, werden nun in einer Schleife alle acht Kanäle geprüft. Alle Kanäle werden auf HIGH gesetzt, welche eine PWM-Einstellung größer als der aktuelle Zykluszähler haben. Sinnvollerweise werden erst alle Kanäle geprüft und das Ergebnis zwischengespeichert, am Ende erfolgt nur ein Zugriff auf den Port.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
    Eine 8-kanalige PWM mit einfachem Lösungsansatz&lt;br /&gt;
&lt;br /&gt;
    ATmega32 @ 8 MHz&lt;br /&gt;
&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
// Defines an den Controller und die Anwendung anpassen&lt;br /&gt;
&lt;br /&gt;
#define F_CPU 8000000L                  // Systemtakt in Hz&lt;br /&gt;
#define F_PWM 100                       // PWM-Frequenz in Hz&lt;br /&gt;
#define PWM_STEPS 255                   // PWM-Schritte pro Zyklus(1..255)&lt;br /&gt;
#define PWM_PORT PORTD                  // Port für PWM&lt;br /&gt;
#define PWM_DDR DDRD                    // Datenrichtungsregister für PWM&lt;br /&gt;
&lt;br /&gt;
// ab hier nichts ändern, wird alles berechnet&lt;br /&gt;
&lt;br /&gt;
#define T_PWM (F_CPU/(F_PWM*PWM_STEPS)) // Systemtakte pro PWM-Takt&lt;br /&gt;
&lt;br /&gt;
#if (T_PWM&amp;lt;(152+5))&lt;br /&gt;
    #error T_PWM zu klein, F_CPU muss vergrössert werden oder F_PWM oder PWM_STEPS verkleinert werden&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
#if PWM_STEPS &amp;gt; 255&lt;br /&gt;
    #error PWM_STEPS zu gross&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// includes&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// globale Variablen&lt;br /&gt;
&lt;br /&gt;
volatile uint8_t pwm_setting[8];                    // Einstellungen für die einzelnen PWM-Kanäle&lt;br /&gt;
&lt;br /&gt;
// Timer 1 Output COMPARE A Interrupt&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect) {&lt;br /&gt;
    static uint8_t pwm_cnt=0;&lt;br /&gt;
    uint8_t tmp=0, i=0, j=1;&lt;br /&gt;
&lt;br /&gt;
    OCR1A += (uint16_t)T_PWM;&lt;br /&gt;
&lt;br /&gt;
    for (; i&amp;lt;8; i++) {    &lt;br /&gt;
    	if (pwm_setting[i] &amp;gt; pwm_cnt) tmp |= j;&lt;br /&gt;
            j&amp;lt;&amp;lt;=1;&lt;br /&gt;
	}&lt;br /&gt;
    PWM_PORT = tmp;                         // PWMs aktualisieren&lt;br /&gt;
    if (pwm_cnt==(uint8_t)(PWM_STEPS-1))&lt;br /&gt;
        pwm_cnt=0;&lt;br /&gt;
    else&lt;br /&gt;
        pwm_cnt++;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
&lt;br /&gt;
    // PWM einstellen&lt;br /&gt;
    &lt;br /&gt;
    PWM_DDR = 0xFF;         // Port als Ausgang&lt;br /&gt;
    &lt;br /&gt;
    // Timer 1 OCRA1, als variablem Timer nutzen&lt;br /&gt;
&lt;br /&gt;
    TCCR1B = 1;             // Timer läuft mit vollem Systemtakt&lt;br /&gt;
    TIMSK |= (1&amp;lt;&amp;lt;OCIE1A);   // Interrupt freischalten&lt;br /&gt;
&lt;br /&gt;
    sei();                  // Interrupts gloabl einschalten&lt;br /&gt;
&lt;br /&gt;
/*********************************************************************/&lt;br /&gt;
// nur zum Testen, im Anwendungsfall löschen&lt;br /&gt;
&lt;br /&gt;
    volatile uint8_t tmp;&lt;br /&gt;
const uint8_t t1[8]={27, 40, 3, 17, 150, 99, 5, 9};&lt;br /&gt;
const uint8_t t2[8]={27, 40, 3, 0, 150, 99, 5, 9};&lt;br /&gt;
const uint8_t t3[8]={27, 40, 3, 17, 3, 99, 3, 0};&lt;br /&gt;
const uint8_t t4[8]={0, 0, 0, 0, 0, 0, 0, 0};&lt;br /&gt;
const uint8_t t5[8]={0, 0, 0, 0, 0, 0, 0, 9};&lt;br /&gt;
const uint8_t t6[8]={33, 33, 33, 33, 33, 33, 33, 33};&lt;br /&gt;
&lt;br /&gt;
// Messung der Interruptdauer&lt;br /&gt;
    tmp =0;&lt;br /&gt;
    tmp =0;&lt;br /&gt;
    tmp =0;&lt;br /&gt;
&lt;br /&gt;
// Debug &lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t1, 8);&lt;br /&gt;
    &lt;br /&gt;
    memcpy(pwm_setting, t2, 8);&lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t3, 8);&lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t4, 8);&lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t5, 8);&lt;br /&gt;
    &lt;br /&gt;
    memcpy(pwm_setting, t6, 8);&lt;br /&gt;
&lt;br /&gt;
/*********************************************************************/&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im [[AVR-Studio]] kann man den Code simulieren. Wichtig ist hier vor allem die Ausführungszeit des Interrupts. Bei 100 Hz PWM-Frequenz und 256 Schritten pro PWM-Zyklus wird diese Funktion immerhin 25600 mal pro Sekunde aufgerufen (PWM-Takt 25,6 kHz),  bei 8MHz Taktfrequenz stehen damit maximal 312 Takte zur Verfügung. Glücklicherweise ist die Funktion relativ kurz und der GCC leistet gute Arbeit. Der Interrupt benötigt hier 152 Takte, es verbleiben also jeweils 160 Takte zur Bearbeitung anderer Aufgaben. Das entspricht einer CPU-Belastung von ~49%. Das Programm benötigt 284 Byte Programmspeicher. Nicht schlecht für den Anfang.&lt;br /&gt;
&lt;br /&gt;
=== Zweiter Versuch ===&lt;br /&gt;
&lt;br /&gt;
Wo gibt es in diesem Programm noch Optimierungsmöglichkeiten? Nur im Interrupt, denn das ganze Programm besteht ja praktisch nur aus der Interruptroutine. Betrachten wir die Schleifen genauer müssen wir feststellen, dass die Indizierung von pwm_setting[] etwas Rechenzeit benötigt. Ebenso die Schiebeoperation von tmp, auch wenn das nur acht mal ein Takt ist. Wir können jetzt per Hand das machen, was der Compiler auch manchmal macht. Die Rede ist vom Loop-Unrolling. Dabei wird die Schleife durch mehrere diskrete Befehle ersetzt (entrollt). Der Vorteil dabei ist, dass die Befehle zur Berechnung und Prüfung der Zählvariable entfallen, außerdem können ggf. Werte im Voraus berechnet werden. Als Ergebnis hat man zwar ein etwas größeres Programm, doch das wird schneller ausgeführt! Außerdem orientiert sich diese Version mehr am Original der Assemblerversion. Dadurch wird sie zusätzlich ein wenig kürzer und schneller.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
    Eine 8-kanalige PWM mit verbessertem Lösungsansatz&lt;br /&gt;
&lt;br /&gt;
    ATmega32 @ 8 MHz&lt;br /&gt;
&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
// Defines an den Controller und die Anwendung anpassen&lt;br /&gt;
&lt;br /&gt;
#define F_CPU 8000000L                  // Systemtakt in Hz&lt;br /&gt;
#define F_PWM 100                       // PWM-Frequenz in Hz&lt;br /&gt;
#define PWM_STEPS 256                   // PWM-Schritte pro Zyklus(1..256)&lt;br /&gt;
#define PWM_PORT PORTD                  // Port für PWM&lt;br /&gt;
#define PWM_DDR DDRD                    // Datenrichtungsregister für PWM&lt;br /&gt;
&lt;br /&gt;
// ab hier nichts ändern, wird alles berechnet&lt;br /&gt;
&lt;br /&gt;
#define T_PWM (F_CPU/(F_PWM*PWM_STEPS)) // Systemtakte pro PWM-Takt&lt;br /&gt;
&lt;br /&gt;
#if (T_PWM&amp;lt;(93+5))&lt;br /&gt;
    #error T_PWM zu klein, F_CPU muss vergrössert werden oder F_PWM oder PWM_STEPS verkleinert werden&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// includes&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// globale Variablen&lt;br /&gt;
&lt;br /&gt;
volatile uint8_t pwm_setting[8];                    // Einstellungen für die einzelnen PWM-Kanäle&lt;br /&gt;
&lt;br /&gt;
// Timer 1 Output COMPARE A Interrupt&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect) {&lt;br /&gt;
    static uint8_t pwm_cnt=0;&lt;br /&gt;
    uint8_t tmp=0;&lt;br /&gt;
&lt;br /&gt;
    OCR1A += (uint16_t)T_PWM;&lt;br /&gt;
        &lt;br /&gt;
    if (pwm_setting[0] &amp;gt; pwm_cnt) tmp |= (1&amp;lt;&amp;lt;0);&lt;br /&gt;
    if (pwm_setting[1] &amp;gt; pwm_cnt) tmp |= (1&amp;lt;&amp;lt;1);&lt;br /&gt;
    if (pwm_setting[2] &amp;gt; pwm_cnt) tmp |= (1&amp;lt;&amp;lt;2);&lt;br /&gt;
    if (pwm_setting[3] &amp;gt; pwm_cnt) tmp |= (1&amp;lt;&amp;lt;3);&lt;br /&gt;
    if (pwm_setting[4] &amp;gt; pwm_cnt) tmp |= (1&amp;lt;&amp;lt;4);&lt;br /&gt;
    if (pwm_setting[5] &amp;gt; pwm_cnt) tmp |= (1&amp;lt;&amp;lt;5);&lt;br /&gt;
    if (pwm_setting[6] &amp;gt; pwm_cnt) tmp |= (1&amp;lt;&amp;lt;6);&lt;br /&gt;
    if (pwm_setting[7] &amp;gt; pwm_cnt) tmp |= (1&amp;lt;&amp;lt;7);&lt;br /&gt;
    PWM_PORT = tmp;                         // PWMs aktualisieren&lt;br /&gt;
    if (pwm_cnt==(uint8_t)(PWM_STEPS-1))&lt;br /&gt;
        pwm_cnt=0;&lt;br /&gt;
    else&lt;br /&gt;
        pwm_cnt++;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
&lt;br /&gt;
    // PWM einstellen&lt;br /&gt;
    &lt;br /&gt;
    PWM_DDR = 0xFF;         // Port als Ausgang&lt;br /&gt;
    &lt;br /&gt;
    // Timer 1 OCRA1, als variablem Timer nutzen&lt;br /&gt;
&lt;br /&gt;
    TCCR1B = 1;             // Timer läuft mit vollem Systemtakt&lt;br /&gt;
    TIMSK |= (1&amp;lt;&amp;lt;OCIE1A);   // Interrupt freischalten&lt;br /&gt;
&lt;br /&gt;
    sei();                  // Interrupts global einschalten&lt;br /&gt;
&lt;br /&gt;
/*********************************************************************/&lt;br /&gt;
// nur zum Testen, im Anwendungsfall löschen&lt;br /&gt;
&lt;br /&gt;
    volatile uint8_t tmp;&lt;br /&gt;
const uint8_t t1[8]={27, 40, 3, 17, 150, 99, 5, 9};&lt;br /&gt;
const uint8_t t2[8]={27, 40, 3, 0, 150, 99, 5, 9};&lt;br /&gt;
const uint8_t t3[8]={27, 40, 3, 17, 3, 99, 3, 0};&lt;br /&gt;
const uint8_t t4[8]={0, 0, 0, 0, 0, 0, 0, 0};&lt;br /&gt;
const uint8_t t5[8]={0, 0, 0, 0, 0, 0, 0, 9};&lt;br /&gt;
const uint8_t t6[8]={33, 33, 33, 33, 33, 33, 33, 33};&lt;br /&gt;
&lt;br /&gt;
// Messung der Interruptdauer&lt;br /&gt;
    tmp =0;&lt;br /&gt;
    tmp =0;&lt;br /&gt;
    tmp =0;&lt;br /&gt;
&lt;br /&gt;
// Debug &lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t1, 8);&lt;br /&gt;
    &lt;br /&gt;
    memcpy(pwm_setting, t2, 8);&lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t3, 8);&lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t4, 8);&lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t5, 8);&lt;br /&gt;
    &lt;br /&gt;
    memcpy(pwm_setting, t6, 8);&lt;br /&gt;
&lt;br /&gt;
/*********************************************************************/&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit dieser Interruptroutine werden nur noch 93 Takte benötigt, die CPU-Belastung verringert sich auf  ~30%. Nicht schlecht. Der Programmcode steigt auf 324 Byte, aber das ist im Angesicht der Leistungsverbesserung zu verschmerzen. Weiter verringern kann man die CPU-Belastung durch eine niedrigere PWM-Frequenz oder eine geringere Anzahl Stufen der PWM. Wenn man beispielsweise mit 64 (6 Bit) statt 256 (8 Bit) Stufen auskommt verringert sich die Belastung um den Faktor 4.&lt;br /&gt;
&lt;br /&gt;
== Intelligenter Lösungsansatz ==&lt;br /&gt;
&lt;br /&gt;
Wenn auch eine CPU-Last von 30% recht akzeptabel erscheint, so hat man doch noch irgendwie das Gefühl, daß es noch besser geht. Aber wie? Mein Mathematikprofessor pflegte in so einem Fall die Anwendung der „Methode des scharfen Blicks“ ™. Was passiert eigentlich während eines gesamten PWM-Zykluses?&lt;br /&gt;
&lt;br /&gt;
*Zu Beginn werden alle IO-Pins gesetzt, deren PWM-Einstellung nicht Null ist.&lt;br /&gt;
*Die jeweiligen IO-Pins werden gelöscht, wenn der PWM-Zähler mit der PWM-Einstellung übereinstimmt&lt;br /&gt;
&lt;br /&gt;
Ja klar, aber da wir nur acht Kanäle haben, gibt es maximal 8 Zeitpunkte, an denen ein Pin gelöscht werden muss. Wenn mehrere Kanäle die gleiche PWM-Einstellung haben sind es sogar noch weniger. Alle anderen Interrupts verursachen keinerlei Änderung der IO-Pins und verbrauchen eigentlich nur sinnlos Rechenzeit. Ein Skandal!&lt;br /&gt;
&lt;br /&gt;
Was ist also zu tun? Wir wissen nun, daß es maximal 9 Ereignisse pro PWM-Zyklus gibt. Was ist damit zu machen?&lt;br /&gt;
&lt;br /&gt;
*Die PWM-Kanäle müssen in aufsteigender Folge sortiert werden.&lt;br /&gt;
*Wenn mehrere PWM-Kanäle den gleichen PWM-Wert haben müssen sie zusammengefaßt werden&lt;br /&gt;
*Die Zeitdifferenzen zwischen den einzelnen Ereignissen müssen berechnet werden&lt;br /&gt;
&lt;br /&gt;
Das ist eigentlich schon alles. Praktisch ist das mit einigen Kniffligkeiten verbunden, aber die sind lösbar. Am Ende steht eine Interruptroutine, welche maximal 9 mal pro PWM-Zyklus aufgerufen wird und die jeweiligen IO-Pins setzt bzw. löscht. Eine normale Funktion wird benutzt, um die PWM-Einstellungen der acht Kanäle in die notwendigen Informationen für die Interruptroutine umzuwandeln. Das hat unter anderem den Vorteil, daß nur dann zusätzlich Rechenzeit benötigt wird, wenn sich die PWM-Einstellungen ändern.&lt;br /&gt;
&lt;br /&gt;
Es sollte jedoch nicht unerwähnt bleiben, dass es sich bei dieser Lösung um keine echte PWM handelt, da sie im Fall, dass ein PWM-Wert 0 ist, den Ausgang nie auf 1 schaltet, und somit auch kein Puls vorhanden ist. Allerdings ist das für die meisten Anwendungen kein Problem.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
    Eine 8-kanalige PWM mit intelligentem Lösungsansatz&lt;br /&gt;
&lt;br /&gt;
    ATmega32 @ 8 MHz&lt;br /&gt;
&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
// Defines an den Controller und die Anwendung anpassen&lt;br /&gt;
&lt;br /&gt;
#define F_CPU         8000000L           // Systemtakt in Hz&lt;br /&gt;
#define F_PWM         100L               // PWM-Frequenz in Hz&lt;br /&gt;
#define PWM_PRESCALER 8                  // Vorteiler für den Timer&lt;br /&gt;
#define PWM_STEPS     256                // PWM-Schritte pro Zyklus(1..256)&lt;br /&gt;
#define PWM_PORT      PORTB              // Port für PWM&lt;br /&gt;
#define PWM_DDR       DDRB               // Datenrichtungsregister für PWM&lt;br /&gt;
#define PWM_CHANNELS  8                  // Anzahl der PWM-Kanäle&lt;br /&gt;
&lt;br /&gt;
// ab hier nichts ändern, wird alles berechnet&lt;br /&gt;
&lt;br /&gt;
#define T_PWM (F_CPU/(PWM_PRESCALER*F_PWM*PWM_STEPS)) // Systemtakte pro PWM-Takt&lt;br /&gt;
//#define T_PWM 1   //TEST&lt;br /&gt;
&lt;br /&gt;
#if ((T_PWM*PWM_PRESCALER)&amp;lt;(111+5))&lt;br /&gt;
    #error T_PWM zu klein, F_CPU muss vergrössert werden oder F_PWM oder PWM_STEPS verkleinert werden&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
#if ((T_PWM*PWM_STEPS)&amp;gt;65535)&lt;br /&gt;
    #error Periodendauer der PWM zu gross! F_PWM oder PWM_PRESCALER erhöhen.   &lt;br /&gt;
#endif&lt;br /&gt;
// includes&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// globale Variablen&lt;br /&gt;
&lt;br /&gt;
uint16_t pwm_timing[PWM_CHANNELS+1];          // Zeitdifferenzen der PWM Werte&lt;br /&gt;
uint16_t pwm_timing_tmp[PWM_CHANNELS+1];      &lt;br /&gt;
&lt;br /&gt;
uint8_t  pwm_mask[PWM_CHANNELS+1];            // Bitmaske für PWM Bits, welche gelöscht werden sollen&lt;br /&gt;
uint8_t  pwm_mask_tmp[PWM_CHANNELS+1];        // ändern uint16_t oder uint32_t für mehr Kanäle&lt;br /&gt;
&lt;br /&gt;
uint8_t  pwm_setting[PWM_CHANNELS];           // Einstellungen für die einzelnen PWM-Kanäle&lt;br /&gt;
uint8_t  pwm_setting_tmp[PWM_CHANNELS+1];     // Einstellungen der PWM Werte, sortiert&lt;br /&gt;
                                              // ändern auf uint16_t für mehr als 8 Bit Auflösung  &lt;br /&gt;
&lt;br /&gt;
volatile uint8_t pwm_cnt_max=1;               // Zählergrenze, Initialisierung mit 1 ist wichtig!&lt;br /&gt;
volatile uint8_t pwm_sync;                    // Update jetzt möglich&lt;br /&gt;
&lt;br /&gt;
// Pointer für wechselseitigen Datenzugriff&lt;br /&gt;
&lt;br /&gt;
uint16_t *isr_ptr_time  = pwm_timing;&lt;br /&gt;
uint16_t *main_ptr_time = pwm_timing_tmp;&lt;br /&gt;
&lt;br /&gt;
uint8_t *isr_ptr_mask  = pwm_mask;              // Bitmasken fuer PWM-Kanäle&lt;br /&gt;
uint8_t *main_ptr_mask = pwm_mask_tmp;          // ändern uint16_t oder uint32_t für mehr Kanäle&lt;br /&gt;
&lt;br /&gt;
// Zeiger austauschen&lt;br /&gt;
// das muss in einem Unterprogramm erfolgen,&lt;br /&gt;
// um eine Zwischenspeicherung durch den Compiler zu verhindern&lt;br /&gt;
&lt;br /&gt;
void tausche_zeiger(void) {&lt;br /&gt;
    uint16_t *tmp_ptr16;&lt;br /&gt;
    uint8_t *tmp_ptr8;                          // ändern uint16_t oder uint32_t für mehr Kanäle&lt;br /&gt;
&lt;br /&gt;
    tmp_ptr16 = isr_ptr_time;&lt;br /&gt;
    isr_ptr_time = main_ptr_time;&lt;br /&gt;
    main_ptr_time = tmp_ptr16;&lt;br /&gt;
    tmp_ptr8 = isr_ptr_mask;&lt;br /&gt;
    isr_ptr_mask = main_ptr_mask;&lt;br /&gt;
    main_ptr_mask = tmp_ptr8;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// PWM Update, berechnet aus den PWM Einstellungen&lt;br /&gt;
// die neuen Werte für die Interruptroutine&lt;br /&gt;
&lt;br /&gt;
void pwm_update(void) {&lt;br /&gt;
    &lt;br /&gt;
    uint8_t i, j, k;&lt;br /&gt;
    uint8_t m1, m2, tmp_mask;                   // ändern uint16_t oder uint32_t für mehr Kanäle    &lt;br /&gt;
    uint8_t min, tmp_set;                       // ändern auf uint16_t für mehr als 8 Bit Auflösung&lt;br /&gt;
&lt;br /&gt;
    // PWM Maske für Start berechnen&lt;br /&gt;
    // gleichzeitig die Bitmasken generieren und PWM Werte kopieren&lt;br /&gt;
&lt;br /&gt;
    m1 = 1;&lt;br /&gt;
    m2 = 0;&lt;br /&gt;
    for(i=1; i&amp;lt;=(PWM_CHANNELS); i++) {&lt;br /&gt;
        main_ptr_mask[i]=~m1;                       // Maske zum Löschen der PWM Ausgänge&lt;br /&gt;
        pwm_setting_tmp[i] = pwm_setting[i-1];&lt;br /&gt;
        if (pwm_setting_tmp[i]!=0) m2 |= m1;        // Maske zum setzen der IOs am PWM Start&lt;br /&gt;
        m1 &amp;lt;&amp;lt;= 1;&lt;br /&gt;
    }&lt;br /&gt;
    main_ptr_mask[0]=m2;                            // PWM Start Daten &lt;br /&gt;
&lt;br /&gt;
    // PWM settings sortieren; Einfügesortieren&lt;br /&gt;
&lt;br /&gt;
    for(i=1; i&amp;lt;=PWM_CHANNELS; i++) {&lt;br /&gt;
        min=PWM_STEPS-1;&lt;br /&gt;
        k=i;&lt;br /&gt;
        for(j=i; j&amp;lt;=PWM_CHANNELS; j++) {&lt;br /&gt;
            if (pwm_setting_tmp[j]&amp;lt;min) {&lt;br /&gt;
                k=j;                                // Index und PWM-setting merken&lt;br /&gt;
                min = pwm_setting_tmp[j];&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        if (k!=i) {&lt;br /&gt;
            // ermitteltes Minimum mit aktueller Sortiertstelle tauschen&lt;br /&gt;
            tmp_set = pwm_setting_tmp[k];&lt;br /&gt;
            pwm_setting_tmp[k] = pwm_setting_tmp[i];&lt;br /&gt;
            pwm_setting_tmp[i] = tmp_set;&lt;br /&gt;
            tmp_mask = main_ptr_mask[k];&lt;br /&gt;
            main_ptr_mask[k] = main_ptr_mask[i];&lt;br /&gt;
            main_ptr_mask[i] = tmp_mask;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Gleiche PWM-Werte vereinigen, ebenso den PWM-Wert 0 löschen falls vorhanden&lt;br /&gt;
&lt;br /&gt;
    k=PWM_CHANNELS;             // PWM_CHANNELS Datensätze&lt;br /&gt;
    i=1;                        // Startindex&lt;br /&gt;
&lt;br /&gt;
    while(k&amp;gt;i) {&lt;br /&gt;
        while ( ((pwm_setting_tmp[i]==pwm_setting_tmp[i+1]) || (pwm_setting_tmp[i]==0))  &amp;amp;&amp;amp; (k&amp;gt;i) ) {&lt;br /&gt;
&lt;br /&gt;
            // aufeinanderfolgende Werte sind gleich und können vereinigt werden&lt;br /&gt;
            // oder PWM Wert ist Null&lt;br /&gt;
            if (pwm_setting_tmp[i]!=0)&lt;br /&gt;
                main_ptr_mask[i+1] &amp;amp;= main_ptr_mask[i];        // Masken vereinigen&lt;br /&gt;
&lt;br /&gt;
            // Datensatz entfernen,&lt;br /&gt;
            // Nachfolger alle eine Stufe hochschieben&lt;br /&gt;
            for(j=i; j&amp;lt;k; j++) {&lt;br /&gt;
                pwm_setting_tmp[j] = pwm_setting_tmp[j+1];&lt;br /&gt;
                main_ptr_mask[j] = main_ptr_mask[j+1];&lt;br /&gt;
            }&lt;br /&gt;
            k--;&lt;br /&gt;
        }&lt;br /&gt;
        i++;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // letzten Datensatz extra behandeln&lt;br /&gt;
    // Vergleich mit dem Nachfolger nicht möglich, nur löschen&lt;br /&gt;
    // gilt nur im Sonderfall, wenn alle Kanäle 0 sind&lt;br /&gt;
    if (pwm_setting_tmp[i]==0) k--;&lt;br /&gt;
&lt;br /&gt;
    // Zeitdifferenzen berechnen&lt;br /&gt;
    &lt;br /&gt;
    if (k==0) { // Sonderfall, wenn alle Kanäle 0 sind&lt;br /&gt;
        main_ptr_time[0]=(uint16_t)T_PWM*PWM_STEPS/2;&lt;br /&gt;
        main_ptr_time[1]=(uint16_t)T_PWM*PWM_STEPS/2;&lt;br /&gt;
        k=1;&lt;br /&gt;
    }&lt;br /&gt;
    else {&lt;br /&gt;
        i=k;&lt;br /&gt;
        main_ptr_time[i]=(uint16_t)T_PWM*(PWM_STEPS-pwm_setting_tmp[i]);&lt;br /&gt;
        tmp_set=pwm_setting_tmp[i];&lt;br /&gt;
        i--;&lt;br /&gt;
        for (; i&amp;gt;0; i--) {&lt;br /&gt;
            main_ptr_time[i]=(uint16_t)T_PWM*(tmp_set-pwm_setting_tmp[i]);&lt;br /&gt;
            tmp_set=pwm_setting_tmp[i];&lt;br /&gt;
        }&lt;br /&gt;
        main_ptr_time[0]=(uint16_t)T_PWM*tmp_set;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // auf Sync warten&lt;br /&gt;
&lt;br /&gt;
    pwm_sync=0;             // Sync wird im Interrupt gesetzt&lt;br /&gt;
    while(pwm_sync==0);&lt;br /&gt;
&lt;br /&gt;
    // Zeiger tauschen&lt;br /&gt;
    cli();&lt;br /&gt;
    tausche_zeiger();&lt;br /&gt;
    pwm_cnt_max = k;&lt;br /&gt;
    sei();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Timer 1 Output COMPARE A Interrupt&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect) {&lt;br /&gt;
    static uint8_t pwm_cnt;                     // ändern auf uint16_t für mehr als 8 Bit Auflösung&lt;br /&gt;
    uint8_t tmp;                                // ändern uint16_t oder uint32_t für mehr Kanäle&lt;br /&gt;
&lt;br /&gt;
    OCR1A += isr_ptr_time[pwm_cnt];&lt;br /&gt;
    tmp    = isr_ptr_mask[pwm_cnt];&lt;br /&gt;
    &lt;br /&gt;
    if (pwm_cnt == 0) {&lt;br /&gt;
        PWM_PORT = tmp;                         // Ports setzen zu Begin der PWM&lt;br /&gt;
                                                // zusätzliche PWM-Ports hier setzen&lt;br /&gt;
        pwm_cnt++;&lt;br /&gt;
    }&lt;br /&gt;
    else {&lt;br /&gt;
        PWM_PORT &amp;amp;= tmp;                        // Ports löschen&lt;br /&gt;
                                                // zusätzliche PWM-Ports hier setzen&lt;br /&gt;
        if (pwm_cnt == pwm_cnt_max) {&lt;br /&gt;
            pwm_sync = 1;                       // Update jetzt möglich&lt;br /&gt;
            pwm_cnt  = 0;&lt;br /&gt;
        }&lt;br /&gt;
        else pwm_cnt++;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
&lt;br /&gt;
    // PWM Port einstellen&lt;br /&gt;
    &lt;br /&gt;
    PWM_DDR = 0xFF;         // Port als Ausgang&lt;br /&gt;
    // zusätzliche PWM-Ports hier setzen&lt;br /&gt;
    &lt;br /&gt;
    // Timer 1 OCRA1, als variablen Timer nutzen&lt;br /&gt;
&lt;br /&gt;
    TCCR1B = 2;             // Timer läuft mit Prescaler 8&lt;br /&gt;
    TIMSK |= (1&amp;lt;&amp;lt;OCIE1A);   // Interrupt freischalten&lt;br /&gt;
&lt;br /&gt;
    sei();                  // Interrupts global einschalten&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/******************************************************************/&lt;br /&gt;
// nur zum testen, in der Anwendung entfernen&lt;br /&gt;
/*&lt;br /&gt;
// Test values&lt;br /&gt;
volatile uint8_t tmp;&lt;br /&gt;
const uint8_t t1[8]={255, 40, 3, 17, 150, 99, 5, 9};&lt;br /&gt;
const uint8_t t2[8]={27, 40, 3, 0, 150, 99, 5, 9};&lt;br /&gt;
const uint8_t t3[8]={27, 40, 3, 17, 3, 99, 3, 0};&lt;br /&gt;
const uint8_t t4[8]={0, 0, 0, 0, 0, 0, 0, 0};&lt;br /&gt;
const uint8_t t5[8]={9, 1, 1, 1, 1, 1, 1, 1};&lt;br /&gt;
const uint8_t t6[8]={33, 33, 33, 33, 33, 33, 33, 33};&lt;br /&gt;
const uint8_t t7[8]={0, 0, 0, 0, 0, 0, 0, 88};&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// Messung der Interruptdauer&lt;br /&gt;
    tmp =1;&lt;br /&gt;
    tmp =2;&lt;br /&gt;
    tmp =3;&lt;br /&gt;
&lt;br /&gt;
// Debug &lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t1, 8);&lt;br /&gt;
    pwm_update();&lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t2, 8);&lt;br /&gt;
    pwm_update();&lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t3, 8);&lt;br /&gt;
    pwm_update();&lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t4, 8);&lt;br /&gt;
    pwm_update();&lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t5, 8);&lt;br /&gt;
    pwm_update();&lt;br /&gt;
    &lt;br /&gt;
    memcpy(pwm_setting, t6, 8);&lt;br /&gt;
    pwm_update();&lt;br /&gt;
    &lt;br /&gt;
    memcpy(pwm_setting, t7, 8);&lt;br /&gt;
    pwm_update();&lt;br /&gt;
*/&lt;br /&gt;
/******************************************************************/&lt;br /&gt;
&lt;br /&gt;
    while(1);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Programm ist schon um einiges länger (968 Byte). Die Interruptroutine benötigt maximal 111 Takte und wird zwischen 2 bis 9 mal pro PWM-Zyklus aufgerufen. Zweimal, wenn alle PWM-Einstellungen gleich sind, 9 mal, wenn alle PWM-Einstellungen verschieden sind. Damit werden zwischen 222 bis 999 Takte benötigt, pro &#039;&#039;&#039;PWM-Zyklus&#039;&#039;&#039;, nicht pro PWM-Takt! Das entspricht einer &#039;&#039;&#039;CPU-Belastung von 0,3..1,2%&#039;&#039;&#039;! [http://de.wikipedia.org/wiki/Beifall Standing Ovations]! Die Funktion pwm_update() benötigt ca. 1500 bis 1800 Takte, das ist geringfügig abhängig von den PWM-Einstellungen, je nach dem ob die Daten schon sortiert sind und ob PWM-Werte mehrfach vorkommen. Bei einer Updaterate von 100 Hz (mehr ist physikalisch sinnlos) entspricht das einer CPU-Belastung von 2,3%, praktisch wird es wahrscheinlich weniger sein. Taktet man den AVR mit vollen 16 MHz halbiert sich die CPU-Belastung noch einmal. Beachtet werden sollte hier die Datenübergabe von der Funktion pwm_update() zur Interruptroutine. Hier werden jeweils zwei Zeiger verwendet, um auf Arrays zu zeigen. In zwei Arrays werden durch die Funktion die Berechnungen der neuen Daten vorgenommen. In den beiden anderen Arrays stehen die aktuellen Daten, mit welchen die ISR arbeitet. Um am Ende der Berechung ein relativ aufwändiges Kopieren der Daten zu vermeiden werden einfach die Zeiger vertauscht. Das ist wesentlich schneller als das Kopieren der Arrays! Im englischen spricht man hier von double buffering, also doppelter Pufferung. Dieses Prinzip wird oft angewendet. Würde man allerdings einfach am Ende die Zeiger tauschen käme es zu einem Crash! Der Interrupt kann jederzeit aktiv werden. Wenn dann die Zeiger nur halb kopiert sind greift die Interruptroutine auf zerstückelte Daten zu und macht Müll. Ebenso würde es zu Fehlfunktionen kommen, wenn während es PWM-Zyklus neue Daten in die Arrays kopiert werden. Das muß verhindert werden. Und zwar dadurch, daß über eine Variable eine Synchronisation durchgeführt wird. Diese wird am Ende des PWM-Zyklus gesetzt und signalisiert, daß neue Daten für den nächsten Zyklus kopiert werden können. Deshalb muss die Funktion pwm_update ggf. bis zu 1 vollen PWM-Zyklus warten, bis die Zeiger getauscht werden können. Wichtig ist dabei, daß die Variable pwm_sync, welche sowohl in der Funktion als auch im Interrupt geschrieben wird, als &#039;&#039;&#039;volatile&#039;&#039;&#039; deklariert wird. Denn sonst würde die Sequenz&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
pwm_sync=0;             // Sync wird im Interrupt gesetzt&lt;br /&gt;
while(pwm_sync==0);&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
zum Stehenbleiben der CPU führen, weil der Compiler erkennt, daß die Variable nie ungleich Null sein kann und damit die Schleife endlos ausgeführt wird. Der Compiler kann prinzipbedingt nicht automatisch erkennen, daß die Variable im Interrupt auf 1 gesetzt wird.&lt;br /&gt;
&lt;br /&gt;
Bei dem schon recht hohen Prozessortakt von 8MHz und der relativ niedrigen PWM Frequenz von 100 Hz haben wir allerdings ein kleines Problem. Wenn beispielsweise nur ein Kanal den PWM-Wert 10 hat, alle anderen aber den Wert Null, dann passiert folgendes. Zum Begin eines PWM-Zyklus wird der eine Kanal aktiviert. Jetzt wird per Timer für 10xT_PWM = 3120 Takte gewartet. Jetzt wird dieser Kanal wieder gelöscht. Bis zum Begin des nächsten PWM-Zyklus muss jedoch noch (256-10)*T_PWM = 76752 Takte gewartet werden. Doch diese Zahl passt nicht mehr in eine 16 Bit Variable! Und damit kann sie auch nicht mit dem Timer verwendet werden. Der Ausweg heisst Vorteiler (engl. Prescaler). Damit kann der Timer langsamer getaktet werden und somit wird die gleiche Wartezeit mit weniger Timertakten erzielt. Zu beachten ist, dass die Einstellung im #define PWM_PRESCALER mit der realen Einstellung in TCCR1B übereinstimmen muss.&lt;br /&gt;
&lt;br /&gt;
Eine Einschränkung gilt allerdings für alle Soft-PWMs. Die PWM-Frequenz muss niedrig genug sein, damit sich die Interrupts nicht überschneiden. D.h. der Wert T_PWM muß immer größer sein als die Anzahl Takte der Interruptroutine. Das wird im Quelltext mit Hilfe von #if  . . #endif geprüft. Die +5 Takte sind eine Reserve. Dazu muß aber die Optimierung -Os eingeschaltet sein, sonst stimmen die Zahlen nicht!&lt;br /&gt;
&lt;br /&gt;
Als Grenze kann mit diesem Programm bei 16 MHz eine 10-Bit PWM in Software generiert werden, was schon sehr respektabel ist und weiches, langsames [[LED-Fading]] mit vielen [[LED]]s ermöglicht. Dazu muss allerdings das Programm an wenigen Stellen angepasst werden, im Speziellen müssen verschiedene Variablen und Arrays von uint8_t auf uint16_t umgestellt werden. Da Gleiche gilt für mehr PWM-Kanäle, praktisch wurden schon bis zu 32 Kanäle realisiert. Der Quelltext ist an den Stellen kommentiert.&lt;br /&gt;
&lt;br /&gt;
== Zusammenfassung ==&lt;br /&gt;
&lt;br /&gt;
Durch kritische Analyse ist es möglich, eine Software-PWM drastisch zu verbessern und die CPU-Belastung auf ein verschwindend geringes Maß zu reduzieren. Zudem zeigt dieses Beispiel ein oft vorkommendes Muster auf, welches gemeinhin als &#039;Time for Space&#039; (Zeit für Platz) bezeichnet wird. Man meint damit, dass es oft möglich ist, dramatische Einsparungen in der Laufzeit zu erreichen, wenn man gewillt ist dafür Speicherplatz zu opfern.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| Version  || Programmspeicher [Byte] || CPU-Belastung [%] &lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 1 || 284   || 49&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 2 || 324   || 30&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 3 || 968   || 0,3..1,2&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* [[AVR-Tutorial: PWM]]&lt;br /&gt;
* [[AVR-GCC-Tutorial#PWM (Pulsweitenmodulation)|AVR-GCC-Tutorial: PWM]]&lt;br /&gt;
* [[LED-Fading]] - LED dimmen mit PWM&lt;br /&gt;
&lt;br /&gt;
[[Category:AVR]]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Soft-PWM&amp;diff=62621</id>
		<title>Soft-PWM</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Soft-PWM&amp;diff=62621"/>
		<updated>2011-12-20T23:15:56Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: /* Zweiter Versuch */ Schreibfehler korrigiert&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[PWM]] ist eine oft verwendete Funktion auf dem Gebiet der Mikrocontroller. Damit lassen sich vielfältige Aufgaben lösen, wie beispielsweise die Leistungssteuerung von Motoren, Helligkeitssteuerung von [[LED-Fading|LEDs]], [[DA-Wandler|Digital-Analog Wandlung]] und vieles mehr. Die meisten Mikrocontroller haben ein oder mehrere PWM-Module eingebaut, womit ohne CPU-Belastung eine PWM generiert werden kann. Jedoch kommt es bisweilen vor, daß die Anzahl der verfügbaren PWM-Kanäle nicht ausreicht. Dann muß eine Softwarelösung gefunden werden, bei der die CPU die PWM-Generierung vornimmt, genannt &#039;&#039;&#039;Soft-PWM&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
;Achtung: Wenn man für eine PWM aussschliesslich 8 Bit breite Datentypen verwendet, dann steht für den Parameter für die Pulsbreite nur der Bereich 0..255 zur Verfügung. Da bei einer vollständigen PWM mit N Schritten aber N+1 mögliche Fälle auftreten können (0/N bis N/0), ist mit dem hier gezeigten Code eine solche PWM nur für N ≤  255 realisierbar.&lt;br /&gt;
&lt;br /&gt;
== Einfacher Lösungsansatz ==&lt;br /&gt;
&lt;br /&gt;
Ein sehr einfacher Lösungsansatz findet sich im [[AVR-Tutorial: PWM]]. Hier wird schon ein [[AVR-Tutorial: Timer | Timer]] benutzt, um in regelmäßigen Abständen die PWM-Generierung durchzuführen. Damit verbleibt noch Rechenzeit für andere Aufgaben, außerdem wird die Programmierung wesentlich vereinfacht. Allerdings ist das Beispiel in ASM, hier soll das ganze in [[C]] gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Es soll nun eine 8 Bit PWM mit 100 Hz (PWM-Zyklus 10ms) und acht Kanälen generiert werden. Der verwendete Controller ist ein [[AVR]] vom Typ ATmega32, welcher mit dem internen RC-Oszillator auf 8 MHz getaktet wird. Das Programm kann jedoch problemlos an so ziemlich jeden anderen AVR angepaßt werden. Die Programme wurden mit dem Optimierungsgrad -Os compiliert.&lt;br /&gt;
&lt;br /&gt;
=== Erster Versuch ===&lt;br /&gt;
&lt;br /&gt;
Das Programm ist recht kurz und übersichtlich. Im Hauptprogramm wird der Timer 1 initialisiert und der Output Compare 1A als variabler Timer verwendet, wobei die Output Compare Funktion nicht mit dem IO-Pin verbunden ist. Im Interrupt, welcher regelmäßig aufgerufen wird, werden nun in einer Schleife alle acht Kanäle geprüft. Alle Kanäle werden auf HIGH gesetzt, welche eine PWM-Einstellung größer als der aktuelle Zykluszähler haben. Sinnvollerweise werden erst alle Kanäle geprüft und das Ergebnis zwischengespeichert, am Ende erfolgt nur ein Zugriff auf den Port.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
    Eine 8-kanalige PWM mit einfachem Lösungsansatz&lt;br /&gt;
&lt;br /&gt;
    ATmega32 @ 8 MHz&lt;br /&gt;
&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
// Defines an den Controller und die Anwendung anpassen&lt;br /&gt;
&lt;br /&gt;
#define F_CPU 8000000L                  // Systemtakt in Hz&lt;br /&gt;
#define F_PWM 100                       // PWM-Frequenz in Hz&lt;br /&gt;
#define PWM_STEPS 255                   // PWM-Schritte pro Zyklus(1..255)&lt;br /&gt;
#define PWM_PORT PORTD                  // Port für PWM&lt;br /&gt;
#define PWM_DDR DDRD                    // Datenrichtungsregister für PWM&lt;br /&gt;
&lt;br /&gt;
// ab hier nichts ändern, wird alles berechnet&lt;br /&gt;
&lt;br /&gt;
#define T_PWM (F_CPU/(F_PWM*PWM_STEPS)) // Systemtakte pro PWM-Takt&lt;br /&gt;
&lt;br /&gt;
#if (T_PWM&amp;lt;(152+5))&lt;br /&gt;
    #error T_PWM zu klein, F_CPU muss vergrössert werden oder F_PWM oder PWM_STEPS verkleinert werden&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
#if PWM_STEPS &amp;gt; 255&lt;br /&gt;
    #error PWM_STEPS zu gross&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// includes&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// globale Variablen&lt;br /&gt;
&lt;br /&gt;
volatile uint8_t pwm_setting[8];                    // Einstellungen für die einzelnen PWM-Kanäle&lt;br /&gt;
&lt;br /&gt;
// Timer 1 Output COMPARE A Interrupt&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect) {&lt;br /&gt;
    static uint8_t pwm_cnt=0;&lt;br /&gt;
    uint8_t tmp=0, i=0, j=1;&lt;br /&gt;
&lt;br /&gt;
    OCR1A += (uint16_t)T_PWM;&lt;br /&gt;
&lt;br /&gt;
    for (; i&amp;lt;8; i++) {    &lt;br /&gt;
    	if (pwm_setting[i] &amp;gt; pwm_cnt) tmp |= j;&lt;br /&gt;
            j&amp;lt;&amp;lt;=1;&lt;br /&gt;
	}&lt;br /&gt;
    PWM_PORT = tmp;                         // PWMs aktualisieren&lt;br /&gt;
    if (pwm_cnt==(uint8_t)(PWM_STEPS-1))&lt;br /&gt;
        pwm_cnt=0;&lt;br /&gt;
    else&lt;br /&gt;
        pwm_cnt++;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
&lt;br /&gt;
    // PWM einstellen&lt;br /&gt;
    &lt;br /&gt;
    PWM_DDR = 0xFF;         // Port als Ausgang&lt;br /&gt;
    &lt;br /&gt;
    // Timer 1 OCRA1, als variablem Timer nutzen&lt;br /&gt;
&lt;br /&gt;
    TCCR1B = 1;             // Timer läuft mit vollem Systemtakt&lt;br /&gt;
    TIMSK |= (1&amp;lt;&amp;lt;OCIE1A);   // Interrupt freischalten&lt;br /&gt;
&lt;br /&gt;
    sei();                  // Interrupts gloabl einschalten&lt;br /&gt;
&lt;br /&gt;
/*********************************************************************/&lt;br /&gt;
// nur zum Testen, im Anwendungsfall löschen&lt;br /&gt;
&lt;br /&gt;
    volatile uint8_t tmp;&lt;br /&gt;
const uint8_t t1[8]={27, 40, 3, 17, 150, 99, 5, 9};&lt;br /&gt;
const uint8_t t2[8]={27, 40, 3, 0, 150, 99, 5, 9};&lt;br /&gt;
const uint8_t t3[8]={27, 40, 3, 17, 3, 99, 3, 0};&lt;br /&gt;
const uint8_t t4[8]={0, 0, 0, 0, 0, 0, 0, 0};&lt;br /&gt;
const uint8_t t5[8]={0, 0, 0, 0, 0, 0, 0, 9};&lt;br /&gt;
const uint8_t t6[8]={33, 33, 33, 33, 33, 33, 33, 33};&lt;br /&gt;
&lt;br /&gt;
// Messung der Interruptdauer&lt;br /&gt;
    tmp =0;&lt;br /&gt;
    tmp =0;&lt;br /&gt;
    tmp =0;&lt;br /&gt;
&lt;br /&gt;
// Debug &lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t1, 8);&lt;br /&gt;
    &lt;br /&gt;
    memcpy(pwm_setting, t2, 8);&lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t3, 8);&lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t4, 8);&lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t5, 8);&lt;br /&gt;
    &lt;br /&gt;
    memcpy(pwm_setting, t6, 8);&lt;br /&gt;
&lt;br /&gt;
/*********************************************************************/&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im [[AVR-Studio]] kann man den Code simulieren. Wichtig ist hier vor allem die Ausführungszeit des Interrupts. Bei 100 Hz PWM-Frequenz und 256 Schritten pro PWM-Zyklus wird diese Funktion immerhin 25600 mal pro Sekunde aufgerufen (PWM-Takt 25,6 kHz),  bei 8MHz Taktfrequenz stehen damit maximal 312 Takte zur Verfügung. Glücklicherweise ist die Funktion relativ kurz und der GCC leistet gute Arbeit. Der Interrupt benötigt hier 152 Takte, es verbleiben also jeweils 160 Takte zur Bearbeitung anderer Aufgaben. Das entspricht einer CPU-Belastung von ~49%. Das Programm benötigt 284 Byte Programmspeicher. Nicht schlecht für den Anfang.&lt;br /&gt;
&lt;br /&gt;
=== Zweiter Versuch ===&lt;br /&gt;
&lt;br /&gt;
Wo gibt es in diesem Programm noch Optimierungsmöglichkeiten? Nur im Interrupt, denn das ganze Programm besteht ja praktisch nur aus der Interruptroutine. Betrachten wir die Schleifen genauer müssen wir feststellen, dass die Indizierung von pwm_setting[] etwas Rechenzeit benötigt. Ebenso die Schiebeoperation von tmp, auch wenn das nur acht mal ein Takt ist. Wir können jetzt per Hand das machen, was der Compiler auch manchmal macht. Die Rede ist vom Loop-Unrolling. Dabei wird die Schleife durch mehrere diskrete Befehle ersetzt (entrollt). Der Vorteil dabei ist, dass die Befehle zur Berechnung und Prüfung der Zählvariable entfallen, außerdem können ggf. Werte im Voraus berechnet werden. Als Ergebnis hat man zwar ein etwas größeres Programm, doch das wird schneller ausgeführt! Außerdem orientiert sich diese Version mehr am Original der Assemblerversion. Dadurch wird sie zusätzlich ein wenig kürzer und schneller.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
    Eine 8-kanalige PWM mit verbessertem Lösungsansatz&lt;br /&gt;
&lt;br /&gt;
    ATmega32 @ 8 MHz&lt;br /&gt;
&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
// Defines an den Controller und die Anwendung anpassen&lt;br /&gt;
&lt;br /&gt;
#define F_CPU 8000000L                  // Systemtakt in Hz&lt;br /&gt;
#define F_PWM 100                       // PWM-Frequenz in Hz&lt;br /&gt;
#define PWM_STEPS 256                   // PWM-Schritte pro Zyklus(1..256)&lt;br /&gt;
#define PWM_PORT PORTD                  // Port für PWM&lt;br /&gt;
#define PWM_DDR DDRD                    // Datenrichtungsregister für PWM&lt;br /&gt;
&lt;br /&gt;
// ab hier nichts ändern, wird alles berechnet&lt;br /&gt;
&lt;br /&gt;
#define T_PWM (F_CPU/(F_PWM*PWM_STEPS)) // Systemtakte pro PWM-Takt&lt;br /&gt;
&lt;br /&gt;
#if (T_PWM&amp;lt;(93+5))&lt;br /&gt;
    #error T_PWM zu klein, F_CPU muss vergrössert werden oder F_PWM oder PWM_STEPS verkleinert werden&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// includes&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// globale Variablen&lt;br /&gt;
&lt;br /&gt;
volatile uint8_t pwm_setting[8];                    // Einstellungen für die einzelnen PWM-Kanäle&lt;br /&gt;
&lt;br /&gt;
// Timer 1 Output COMPARE A Interrupt&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect) {&lt;br /&gt;
    static uint8_t pwm_cnt=0;&lt;br /&gt;
    uint8_t tmp=0;&lt;br /&gt;
&lt;br /&gt;
    OCR1A += (uint16_t)T_PWM;&lt;br /&gt;
        &lt;br /&gt;
    if (pwm_setting[0] &amp;gt; pwm_cnt) tmp |= (1&amp;lt;&amp;lt;0);&lt;br /&gt;
    if (pwm_setting[1] &amp;gt; pwm_cnt) tmp |= (1&amp;lt;&amp;lt;1);&lt;br /&gt;
    if (pwm_setting[2] &amp;gt; pwm_cnt) tmp |= (1&amp;lt;&amp;lt;2);&lt;br /&gt;
    if (pwm_setting[3] &amp;gt; pwm_cnt) tmp |= (1&amp;lt;&amp;lt;3);&lt;br /&gt;
    if (pwm_setting[4] &amp;gt; pwm_cnt) tmp |= (1&amp;lt;&amp;lt;4);&lt;br /&gt;
    if (pwm_setting[5] &amp;gt; pwm_cnt) tmp |= (1&amp;lt;&amp;lt;5);&lt;br /&gt;
    if (pwm_setting[6] &amp;gt; pwm_cnt) tmp |= (1&amp;lt;&amp;lt;6);&lt;br /&gt;
    if (pwm_setting[7] &amp;gt; pwm_cnt) tmp |= (1&amp;lt;&amp;lt;7);&lt;br /&gt;
    PWM_PORT = tmp;                         // PWMs aktualisieren&lt;br /&gt;
    if (pwm_cnt==(uint8_t)(PWM_STEPS-1))&lt;br /&gt;
        pwm_cnt=0;&lt;br /&gt;
    else&lt;br /&gt;
        pwm_cnt++;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
&lt;br /&gt;
    // PWM einstellen&lt;br /&gt;
    &lt;br /&gt;
    PWM_DDR = 0xFF;         // Port als Ausgang&lt;br /&gt;
    &lt;br /&gt;
    // Timer 1 OCRA1, als variablem Timer nutzen&lt;br /&gt;
&lt;br /&gt;
    TCCR1B = 1;             // Timer läuft mit vollem Systemtakt&lt;br /&gt;
    TIMSK |= (1&amp;lt;&amp;lt;OCIE1A);   // Interrupt freischalten&lt;br /&gt;
&lt;br /&gt;
    sei();                  // Interrupts global einschalten&lt;br /&gt;
&lt;br /&gt;
/*********************************************************************/&lt;br /&gt;
// nur zum Testen, im Anwendungsfall löschen&lt;br /&gt;
&lt;br /&gt;
    volatile uint8_t tmp;&lt;br /&gt;
const uint8_t t1[8]={27, 40, 3, 17, 150, 99, 5, 9};&lt;br /&gt;
const uint8_t t2[8]={27, 40, 3, 0, 150, 99, 5, 9};&lt;br /&gt;
const uint8_t t3[8]={27, 40, 3, 17, 3, 99, 3, 0};&lt;br /&gt;
const uint8_t t4[8]={0, 0, 0, 0, 0, 0, 0, 0};&lt;br /&gt;
const uint8_t t5[8]={0, 0, 0, 0, 0, 0, 0, 9};&lt;br /&gt;
const uint8_t t6[8]={33, 33, 33, 33, 33, 33, 33, 33};&lt;br /&gt;
&lt;br /&gt;
// Messung der Interruptdauer&lt;br /&gt;
    tmp =0;&lt;br /&gt;
    tmp =0;&lt;br /&gt;
    tmp =0;&lt;br /&gt;
&lt;br /&gt;
// Debug &lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t1, 8);&lt;br /&gt;
    &lt;br /&gt;
    memcpy(pwm_setting, t2, 8);&lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t3, 8);&lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t4, 8);&lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t5, 8);&lt;br /&gt;
    &lt;br /&gt;
    memcpy(pwm_setting, t6, 8);&lt;br /&gt;
&lt;br /&gt;
/*********************************************************************/&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit dieser Interruptroutine werden nur noch 93 Takte benötigt, die CPU-Belastung verringert sich auf  ~30%. Nicht schlecht. Der Programmcode steigt auf 324 Byte, aber das ist im Angesicht der Leistungsverbesserung zu verschmerzen. Weiter verringern kann man die CPU-Belastung durch eine niedrigere PWM-Frequenz oder eine geringere Anzahl Stufen der PWM. Wenn man beispielsweise mit 64 (6 Bit) statt 256 (8 Bit) Stufen auskommt verringert sich die Belastung um den Faktor 4.&lt;br /&gt;
&lt;br /&gt;
== Intelligenter Lösungsansatz ==&lt;br /&gt;
&lt;br /&gt;
Wenn auch eine CPU-Last von 30% recht akzeptabel erscheint, so hat man doch noch irgendwie das Gefühl, daß es noch besser geht. Aber wie? Mein Mathematikprofessor pflegte in so einem Fall die Anwendung der „Methode des scharfen Blicks“ ™. Was passiert eigentlich während eines gesamten PWM-Zykluses?&lt;br /&gt;
&lt;br /&gt;
*Zu Beginn werden alle IO-Pins gesetzt, deren PWM-Einstellung nicht Null ist.&lt;br /&gt;
*Die jeweiligen IO-Pins werden gelöscht, wenn der PWM-Zähler mit der PWM-Einstellung übereinstimmt&lt;br /&gt;
&lt;br /&gt;
Ja klar, aber da wir nur acht Kanäle haben, gibt es maximal 8 Zeitpunkte, an denen ein Pin gelöscht werden muss. Wenn mehrere Kanäle die gleiche PWM-Einstellung haben sind es sogar noch weniger. Alle anderen Interrupts verursachen keinerlei Änderung der IO-Pins und verbrauchen eigentlich nur sinnlos Rechenzeit. Ein Skandal!&lt;br /&gt;
&lt;br /&gt;
Was ist also zu tun? Wir wissen nun, daß es maximal 9 Ereignisse pro PWM-Zyklus gibt. Was ist damit zu machen?&lt;br /&gt;
&lt;br /&gt;
*Die PWM-Kanäle müssen in aufsteigender Folge sortiert werden.&lt;br /&gt;
*Wenn mehrere PWM-Kanäle den gleichen PWM-Wert haben müssen sie zusammengefaßt werden&lt;br /&gt;
*Die Zeitdifferenzen zwischen den einzelnen Ereignissen müssen berechnet werden&lt;br /&gt;
&lt;br /&gt;
Das ist eigentlich schon alles. Praktisch ist das mit einigen Kniffligkeiten verbunden, aber die sind lösbar. Am Ende steht eine Interruptroutine, welche maximal 9 mal pro PWM-Zyklus aufgerufen wird und die jeweiligen IO-Pins setzt bzw. löscht. Eine normale Funktion wird benutzt, um die PWM-Einstellungen der acht Kanäle in die notwendigen Informationen für die Interruptroutine umzuwandeln. Das hat unter anderem den Vorteil, daß nur dann zusätzlich Rechenzeit benötigt wird, wenn sich die PWM-Einstellungen ändern.&lt;br /&gt;
&lt;br /&gt;
Es sollte jedoch nicht unerwähnt bleiben, dass es sich bei dieser Lösung um keine echte PWM handelt, da sie im Fall, dass ein PWM-Wert 0 ist, den Ausgang nie auf 1 schaltet, und somit auch kein Puls vorhanden ist. Allerdings ist das für die meisten Anwendungen kein Problem.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
    Eine 8-kanalige PWM mit intelligentem Lösungsansatz&lt;br /&gt;
&lt;br /&gt;
    ATmega32 @ 8 MHz&lt;br /&gt;
&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
// Defines an den Controller und die Anwendung anpassen&lt;br /&gt;
&lt;br /&gt;
#define F_CPU         8000000L           // Systemtakt in Hz&lt;br /&gt;
#define F_PWM         100L               // PWM-Frequenz in Hz&lt;br /&gt;
#define PWM_PRESCALER 8                  // Vorteiler für den Timer&lt;br /&gt;
#define PWM_STEPS     256                // PWM-Schritte pro Zyklus(1..256)&lt;br /&gt;
#define PWM_PORT      PORTB              // Port für PWM&lt;br /&gt;
#define PWM_DDR       DDRB               // Datenrichtungsregister für PWM&lt;br /&gt;
#define PWM_CHANNELS  8                  // Anzahl der PWM-Kanäle&lt;br /&gt;
&lt;br /&gt;
// ab hier nichts ändern, wird alles berechnet&lt;br /&gt;
&lt;br /&gt;
#define T_PWM (F_CPU/(PWM_PRESCALER*F_PWM*PWM_STEPS)) // Systemtakte pro PWM-Takt&lt;br /&gt;
//#define T_PWM 1   //TEST&lt;br /&gt;
&lt;br /&gt;
#if ((T_PWM*PWM_PRESCALER)&amp;lt;(111+5))&lt;br /&gt;
    #error T_PWM zu klein, F_CPU muss vergrösst werden oder F_PWM oder PWM_STEPS verkleinert werden&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
#if ((T_PWM*PWM_STEPS)&amp;gt;65535)&lt;br /&gt;
    #error Periodendauer der PWM zu gross! F_PWM oder PWM_PRESCALER erhöhen.   &lt;br /&gt;
#endif&lt;br /&gt;
// includes&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// globale Variablen&lt;br /&gt;
&lt;br /&gt;
uint16_t pwm_timing[PWM_CHANNELS+1];          // Zeitdifferenzen der PWM Werte&lt;br /&gt;
uint16_t pwm_timing_tmp[PWM_CHANNELS+1];      &lt;br /&gt;
&lt;br /&gt;
uint8_t  pwm_mask[PWM_CHANNELS+1];            // Bitmaske für PWM Bits, welche gelöscht werden sollen&lt;br /&gt;
uint8_t  pwm_mask_tmp[PWM_CHANNELS+1];        // ändern uint16_t oder uint32_t für mehr Kanäle&lt;br /&gt;
&lt;br /&gt;
uint8_t  pwm_setting[PWM_CHANNELS];           // Einstellungen für die einzelnen PWM-Kanäle&lt;br /&gt;
uint8_t  pwm_setting_tmp[PWM_CHANNELS+1];     // Einstellungen der PWM Werte, sortiert&lt;br /&gt;
                                              // ändern auf uint16_t für mehr als 8 Bit Auflösung  &lt;br /&gt;
&lt;br /&gt;
volatile uint8_t pwm_cnt_max=1;               // Zählergrenze, Initialisierung mit 1 ist wichtig!&lt;br /&gt;
volatile uint8_t pwm_sync;                    // Update jetzt möglich&lt;br /&gt;
&lt;br /&gt;
// Pointer für wechselseitigen Datenzugriff&lt;br /&gt;
&lt;br /&gt;
uint16_t *isr_ptr_time  = pwm_timing;&lt;br /&gt;
uint16_t *main_ptr_time = pwm_timing_tmp;&lt;br /&gt;
&lt;br /&gt;
uint8_t *isr_ptr_mask  = pwm_mask;              // Bitmasken fuer PWM-Kanäle&lt;br /&gt;
uint8_t *main_ptr_mask = pwm_mask_tmp;          // ändern uint16_t oder uint32_t für mehr Kanäle&lt;br /&gt;
&lt;br /&gt;
// Zeiger austauschen&lt;br /&gt;
// das muss in einem Unterprogramm erfolgen,&lt;br /&gt;
// um eine Zwischenspeicherung durch den Compiler zu verhindern&lt;br /&gt;
&lt;br /&gt;
void tausche_zeiger(void) {&lt;br /&gt;
    uint16_t *tmp_ptr16;&lt;br /&gt;
    uint8_t *tmp_ptr8;                          // ändern uint16_t oder uint32_t für mehr Kanäle&lt;br /&gt;
&lt;br /&gt;
    tmp_ptr16 = isr_ptr_time;&lt;br /&gt;
    isr_ptr_time = main_ptr_time;&lt;br /&gt;
    main_ptr_time = tmp_ptr16;&lt;br /&gt;
    tmp_ptr8 = isr_ptr_mask;&lt;br /&gt;
    isr_ptr_mask = main_ptr_mask;&lt;br /&gt;
    main_ptr_mask = tmp_ptr8;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// PWM Update, berechnet aus den PWM Einstellungen&lt;br /&gt;
// die neuen Werte für die Interruptroutine&lt;br /&gt;
&lt;br /&gt;
void pwm_update(void) {&lt;br /&gt;
    &lt;br /&gt;
    uint8_t i, j, k;&lt;br /&gt;
    uint8_t m1, m2, tmp_mask;                   // ändern uint16_t oder uint32_t für mehr Kanäle    &lt;br /&gt;
    uint8_t min, tmp_set;                       // ändern auf uint16_t für mehr als 8 Bit Auflösung&lt;br /&gt;
&lt;br /&gt;
    // PWM Maske für Start berechnen&lt;br /&gt;
    // gleichzeitig die Bitmasken generieren und PWM Werte kopieren&lt;br /&gt;
&lt;br /&gt;
    m1 = 1;&lt;br /&gt;
    m2 = 0;&lt;br /&gt;
    for(i=1; i&amp;lt;=(PWM_CHANNELS); i++) {&lt;br /&gt;
        main_ptr_mask[i]=~m1;                       // Maske zum Löschen der PWM Ausgänge&lt;br /&gt;
        pwm_setting_tmp[i] = pwm_setting[i-1];&lt;br /&gt;
        if (pwm_setting_tmp[i]!=0) m2 |= m1;        // Maske zum setzen der IOs am PWM Start&lt;br /&gt;
        m1 &amp;lt;&amp;lt;= 1;&lt;br /&gt;
    }&lt;br /&gt;
    main_ptr_mask[0]=m2;                            // PWM Start Daten &lt;br /&gt;
&lt;br /&gt;
    // PWM settings sortieren; Einfügesortieren&lt;br /&gt;
&lt;br /&gt;
    for(i=1; i&amp;lt;=PWM_CHANNELS; i++) {&lt;br /&gt;
        min=PWM_STEPS-1;&lt;br /&gt;
        k=i;&lt;br /&gt;
        for(j=i; j&amp;lt;=PWM_CHANNELS; j++) {&lt;br /&gt;
            if (pwm_setting_tmp[j]&amp;lt;min) {&lt;br /&gt;
                k=j;                                // Index und PWM-setting merken&lt;br /&gt;
                min = pwm_setting_tmp[j];&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        if (k!=i) {&lt;br /&gt;
            // ermitteltes Minimum mit aktueller Sortiertstelle tauschen&lt;br /&gt;
            tmp_set = pwm_setting_tmp[k];&lt;br /&gt;
            pwm_setting_tmp[k] = pwm_setting_tmp[i];&lt;br /&gt;
            pwm_setting_tmp[i] = tmp_set;&lt;br /&gt;
            tmp_mask = main_ptr_mask[k];&lt;br /&gt;
            main_ptr_mask[k] = main_ptr_mask[i];&lt;br /&gt;
            main_ptr_mask[i] = tmp_mask;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Gleiche PWM-Werte vereinigen, ebenso den PWM-Wert 0 löschen falls vorhanden&lt;br /&gt;
&lt;br /&gt;
    k=PWM_CHANNELS;             // PWM_CHANNELS Datensätze&lt;br /&gt;
    i=1;                        // Startindex&lt;br /&gt;
&lt;br /&gt;
    while(k&amp;gt;i) {&lt;br /&gt;
        while ( ((pwm_setting_tmp[i]==pwm_setting_tmp[i+1]) || (pwm_setting_tmp[i]==0))  &amp;amp;&amp;amp; (k&amp;gt;i) ) {&lt;br /&gt;
&lt;br /&gt;
            // aufeinanderfolgende Werte sind gleich und können vereinigt werden&lt;br /&gt;
            // oder PWM Wert ist Null&lt;br /&gt;
            if (pwm_setting_tmp[i]!=0)&lt;br /&gt;
                main_ptr_mask[i+1] &amp;amp;= main_ptr_mask[i];        // Masken vereinigen&lt;br /&gt;
&lt;br /&gt;
            // Datensatz entfernen,&lt;br /&gt;
            // Nachfolger alle eine Stufe hochschieben&lt;br /&gt;
            for(j=i; j&amp;lt;k; j++) {&lt;br /&gt;
                pwm_setting_tmp[j] = pwm_setting_tmp[j+1];&lt;br /&gt;
                main_ptr_mask[j] = main_ptr_mask[j+1];&lt;br /&gt;
            }&lt;br /&gt;
            k--;&lt;br /&gt;
        }&lt;br /&gt;
        i++;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // letzten Datensatz extra behandeln&lt;br /&gt;
    // Vergleich mit dem Nachfolger nicht möglich, nur löschen&lt;br /&gt;
    // gilt nur im Sonderfall, wenn alle Kanäle 0 sind&lt;br /&gt;
    if (pwm_setting_tmp[i]==0) k--;&lt;br /&gt;
&lt;br /&gt;
    // Zeitdifferenzen berechnen&lt;br /&gt;
    &lt;br /&gt;
    if (k==0) { // Sonderfall, wenn alle Kanäle 0 sind&lt;br /&gt;
        main_ptr_time[0]=(uint16_t)T_PWM*PWM_STEPS/2;&lt;br /&gt;
        main_ptr_time[1]=(uint16_t)T_PWM*PWM_STEPS/2;&lt;br /&gt;
        k=1;&lt;br /&gt;
    }&lt;br /&gt;
    else {&lt;br /&gt;
        i=k;&lt;br /&gt;
        main_ptr_time[i]=(uint16_t)T_PWM*(PWM_STEPS-pwm_setting_tmp[i]);&lt;br /&gt;
        tmp_set=pwm_setting_tmp[i];&lt;br /&gt;
        i--;&lt;br /&gt;
        for (; i&amp;gt;0; i--) {&lt;br /&gt;
            main_ptr_time[i]=(uint16_t)T_PWM*(tmp_set-pwm_setting_tmp[i]);&lt;br /&gt;
            tmp_set=pwm_setting_tmp[i];&lt;br /&gt;
        }&lt;br /&gt;
        main_ptr_time[0]=(uint16_t)T_PWM*tmp_set;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // auf Sync warten&lt;br /&gt;
&lt;br /&gt;
    pwm_sync=0;             // Sync wird im Interrupt gesetzt&lt;br /&gt;
    while(pwm_sync==0);&lt;br /&gt;
&lt;br /&gt;
    // Zeiger tauschen&lt;br /&gt;
    cli();&lt;br /&gt;
    tausche_zeiger();&lt;br /&gt;
    pwm_cnt_max = k;&lt;br /&gt;
    sei();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Timer 1 Output COMPARE A Interrupt&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect) {&lt;br /&gt;
    static uint8_t pwm_cnt;                     // ändern auf uint16_t für mehr als 8 Bit Auflösung&lt;br /&gt;
    uint8_t tmp;                                // ändern uint16_t oder uint32_t für mehr Kanäle&lt;br /&gt;
&lt;br /&gt;
    OCR1A += isr_ptr_time[pwm_cnt];&lt;br /&gt;
    tmp    = isr_ptr_mask[pwm_cnt];&lt;br /&gt;
    &lt;br /&gt;
    if (pwm_cnt == 0) {&lt;br /&gt;
        PWM_PORT = tmp;                         // Ports setzen zu Begin der PWM&lt;br /&gt;
                                                // zusätzliche PWM-Ports hier setzen&lt;br /&gt;
        pwm_cnt++;&lt;br /&gt;
    }&lt;br /&gt;
    else {&lt;br /&gt;
        PWM_PORT &amp;amp;= tmp;                        // Ports löschen&lt;br /&gt;
                                                // zusätzliche PWM-Ports hier setzen&lt;br /&gt;
        if (pwm_cnt == pwm_cnt_max) {&lt;br /&gt;
            pwm_sync = 1;                       // Update jetzt möglich&lt;br /&gt;
            pwm_cnt  = 0;&lt;br /&gt;
        }&lt;br /&gt;
        else pwm_cnt++;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
&lt;br /&gt;
    // PWM Port einstellen&lt;br /&gt;
    &lt;br /&gt;
    PWM_DDR = 0xFF;         // Port als Ausgang&lt;br /&gt;
    // zusätzliche PWM-Ports hier setzen&lt;br /&gt;
    &lt;br /&gt;
    // Timer 1 OCRA1, als variablen Timer nutzen&lt;br /&gt;
&lt;br /&gt;
    TCCR1B = 2;             // Timer läuft mit Prescaler 8&lt;br /&gt;
    TIMSK |= (1&amp;lt;&amp;lt;OCIE1A);   // Interrupt freischalten&lt;br /&gt;
&lt;br /&gt;
    sei();                  // Interrupts gloabl einschalten&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/******************************************************************/&lt;br /&gt;
// nur zum testen, in der Anwendung entfernen&lt;br /&gt;
/*&lt;br /&gt;
// Test values&lt;br /&gt;
volatile uint8_t tmp;&lt;br /&gt;
const uint8_t t1[8]={255, 40, 3, 17, 150, 99, 5, 9};&lt;br /&gt;
const uint8_t t2[8]={27, 40, 3, 0, 150, 99, 5, 9};&lt;br /&gt;
const uint8_t t3[8]={27, 40, 3, 17, 3, 99, 3, 0};&lt;br /&gt;
const uint8_t t4[8]={0, 0, 0, 0, 0, 0, 0, 0};&lt;br /&gt;
const uint8_t t5[8]={9, 1, 1, 1, 1, 1, 1, 1};&lt;br /&gt;
const uint8_t t6[8]={33, 33, 33, 33, 33, 33, 33, 33};&lt;br /&gt;
const uint8_t t7[8]={0, 0, 0, 0, 0, 0, 0, 88};&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// Messung der Interruptdauer&lt;br /&gt;
    tmp =1;&lt;br /&gt;
    tmp =2;&lt;br /&gt;
    tmp =3;&lt;br /&gt;
&lt;br /&gt;
// Debug &lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t1, 8);&lt;br /&gt;
    pwm_update();&lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t2, 8);&lt;br /&gt;
    pwm_update();&lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t3, 8);&lt;br /&gt;
    pwm_update();&lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t4, 8);&lt;br /&gt;
    pwm_update();&lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t5, 8);&lt;br /&gt;
    pwm_update();&lt;br /&gt;
    &lt;br /&gt;
    memcpy(pwm_setting, t6, 8);&lt;br /&gt;
    pwm_update();&lt;br /&gt;
    &lt;br /&gt;
    memcpy(pwm_setting, t7, 8);&lt;br /&gt;
    pwm_update();&lt;br /&gt;
*/&lt;br /&gt;
/******************************************************************/&lt;br /&gt;
&lt;br /&gt;
    while(1);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Programm ist schon um einiges länger (968 Byte). Die Interruptroutine benötigt maximal 111 Takte und wird zwischen 2 bis 9 mal pro PWM-Zyklus aufgerufen. Zweimal, wenn alle PWM-Einstellungen gleich sind, 9 mal, wenn alle PWM-Einstellungen verschieden sind. Damit werden zwischen 222 bis 999 Takte benötigt, pro &#039;&#039;&#039;PWM-Zyklus&#039;&#039;&#039;, nicht pro PWM-Takt! Das entspricht einer &#039;&#039;&#039;CPU-Belastung von 0,3..1,2%&#039;&#039;&#039;! [http://de.wikipedia.org/wiki/Beifall Standing Ovations]! Die Funktion pwm_update() benötigt ca. 1500 bis 1800 Takte, das ist geringfügig abhängig von den PWM-Einstellungen, je nach dem ob die Daten schon sortiert sind und ob PWM-Werte mehrfach vorkommen. Bei einer Updaterate von 100 Hz (mehr ist physikalisch sinnlos) entspricht das einer CPU-Belastung von 2,3%, praktisch wird es wahrscheinlich weniger sein. Taktet man den AVR mit vollen 16 MHz halbiert sich die CPU-Belastung noch einmal. Beachtet werden sollte hier die Datenübergabe von der Funktion pwm_update() zur Interruptroutine. Hier werden jeweils zwei Zeiger verwendet, um auf Arrays zu zeigen. In zwei Arrays werden durch die Funktion die Berechnungen der neuen Daten vorgenommen. In den beiden anderen Arrays stehen die aktuellen Daten, mit welchen die ISR arbeitet. Um am Ende der Berechung ein relativ aufwändiges Kopieren der Daten zu vermeiden werden einfach die Zeiger vertauscht. Das ist wesentlich schneller als das Kopieren der Arrays! Im englischen spricht man hier von double buffering, also doppelter Pufferung. Dieses Prinzip wird oft angewendet. Würde man allerdings einfach am Ende die Zeiger tauschen käme es zu einem Crash! Der Interrupt kann jederzeit aktiv werden. Wenn dann die Zeiger nur halb kopiert sind greift die Interruptroutine auf zerstückelte Daten zu und macht Müll. Ebenso würde es zu Fehlfunktionen kommen, wenn während es PWM-Zyklus neue Daten in die Arrays kopiert werden. Das muß verhindert werden. Und zwar dadurch, daß über eine Variable eine Synchronisation durchgeführt wird. Diese wird am Ende des PWM-Zyklus gesetzt und signalisiert, daß neue Daten für den nächsten Zyklus kopiert werden können. Deshalb muss die Funktion pwm_update ggf. bis zu 1 vollen PWM-Zyklus warten, bis die Zeiger getauscht werden können. Wichtig ist dabei, daß die Variable pwm_sync, welche sowohl in der Funktion als auch im Interrupt geschrieben wird, als &#039;&#039;&#039;volatile&#039;&#039;&#039; deklariert wird. Denn sonst würde die Sequenz&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
pwm_sync=0;             // Sync wird im Interrupt gesetzt&lt;br /&gt;
while(pwm_sync==0);&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
zum Stehenbleiben der CPU führen, weil der Compiler erkennt, daß die Variable nie ungleich Null sein kann und damit die Schleife endlos ausgeführt wird. Der Compiler kann prinzipbedingt nicht automatisch erkennen, daß die Variable im Interrupt auf 1 gesetzt wird.&lt;br /&gt;
&lt;br /&gt;
Bei dem schon recht hohen Prozessortakt von 8MHz und der relativ niedrigen PWM Frequenz von 100 Hz haben wir allerdings ein kleines Problem. Wenn beispielsweise nur ein Kanal den PWM-Wert 10 hat, alle anderen aber den Wert Null, dann passiert folgendes. Zum Begin eines PWM-Zyklus wird der eine Kanal aktiviert. Jetzt wird per Timer für 10xT_PWM = 3120 Takte gewartet. Jetzt wird dieser Kanal wieder gelöscht. Bis zum Begin des nächsten PWM-Zyklus muss jedoch noch (256-10)*T_PWM = 76752 Takte gewartet werden. Doch diese Zahl passt nicht mehr in eine 16 Bit Variable! Und damit kann sie auch nicht mit dem Timer verwendet werden. Der Ausweg heisst Vorteiler (engl. Prescaler). Damit kann der Timer langsamer getaktet werden und somit wird die gleiche Wartezeit mit weniger Timertakten erzielt. Zu beachten ist, dass die Einstellung im #define PWM_PRESCALER mit der realen Einstellung in TCCR1B übereinstimmen muss.&lt;br /&gt;
&lt;br /&gt;
Eine Einschränkung gilt allerdings für alle Soft-PWMs. Die PWM-Frequenz muss niedrig genug sein, damit sich die Interrupts nicht überschneiden. D.h. der Wert T_PWM muß immer größer sein als die Anzahl Takte der Interruptroutine. Das wird im Quelltext mit Hilfe von #if  . . #endif geprüft. Die +5 Takte sind eine Reserve. Dazu muß aber die Optimierung -Os eingeschaltet sein, sonst stimmen die Zahlen nicht!&lt;br /&gt;
&lt;br /&gt;
Als Grenze kann mit diesem Programm bei 16 MHz eine 10-Bit PWM in Software generiert werden, was schon sehr respektabel ist und weiches, langsames [[LED-Fading]] mit vielen [[LED]]s ermöglicht. Dazu muss allerdings das Programm an wenigen Stellen angepasst werden, im Speziellen müssen verschiedene Variablen und Arrays von uint8_t auf uint16_t umgestellt werden. Da Gleiche gilt für mehr PWM-Kanäle, praktisch wurden schon bis zu 32 Kanäle realisiert. Der Quelltext ist an den Stellen kommentiert.&lt;br /&gt;
&lt;br /&gt;
== Zusammenfassung ==&lt;br /&gt;
&lt;br /&gt;
Durch kritische Analyse ist es möglich, eine Software-PWM drastisch zu verbessern und die CPU-Belastung auf ein verschwindend geringes Maß zu reduzieren. Zudem zeigt dieses Beispiel ein oft vorkommendes Muster auf, welches gemeinhin als &#039;Time for Space&#039; (Zeit für Platz) bezeichnet wird. Man meint damit, dass es oft möglich ist, dramatische Einsparungen in der Laufzeit zu erreichen, wenn man gewillt ist dafür Speicherplatz zu opfern.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| Version  || Programmspeicher [Byte] || CPU-Belastung [%] &lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 1 || 284   || 49&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 2 || 324   || 30&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 3 || 968   || 0,3..1,2&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* [[AVR-Tutorial: PWM]]&lt;br /&gt;
* [[AVR-GCC-Tutorial#PWM (Pulsweitenmodulation)|AVR-GCC-Tutorial: PWM]]&lt;br /&gt;
* [[LED-Fading]] - LED dimmen mit PWM&lt;br /&gt;
&lt;br /&gt;
[[Category:AVR]]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Soft-PWM&amp;diff=62614</id>
		<title>Soft-PWM</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Soft-PWM&amp;diff=62614"/>
		<updated>2011-12-20T11:19:18Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: /* Erster Versuch */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[PWM]] ist eine oft verwendete Funktion auf dem Gebiet der Mikrocontroller. Damit lassen sich vielfältige Aufgaben lösen, wie beispielsweise die Leistungssteuerung von Motoren, Helligkeitssteuerung von [[LED-Fading|LEDs]], [[DA-Wandler|Digital-Analog Wandlung]] und vieles mehr. Die meisten Mikrocontroller haben ein oder mehrere PWM-Module eingebaut, womit ohne CPU-Belastung eine PWM generiert werden kann. Jedoch kommt es bisweilen vor, daß die Anzahl der verfügbaren PWM-Kanäle nicht ausreicht. Dann muß eine Softwarelösung gefunden werden, bei der die CPU die PWM-Generierung vornimmt, genannt &#039;&#039;&#039;Soft-PWM&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
;Achtung: Wenn man für eine PWM aussschliesslich 8 Bit breite Datentypen verwendet, dann steht für den Parameter für die Pulsbreite nur der Bereich 0..255 zur Verfügung. Da bei einer vollständigen PWM mit N Schritten aber N+1 mögliche Fälle auftreten können (0/N bis N/0), ist mit dem hier gezeigten Code eine solche PWM nur für N ≤  255 realisierbar.&lt;br /&gt;
&lt;br /&gt;
== Einfacher Lösungsansatz ==&lt;br /&gt;
&lt;br /&gt;
Ein sehr einfacher Lösungsansatz findet sich im [[AVR-Tutorial: PWM]]. Hier wird schon ein [[AVR-Tutorial: Timer | Timer]] benutzt, um in regelmäßigen Abständen die PWM-Generierung durchzuführen. Damit verbleibt noch Rechenzeit für andere Aufgaben, außerdem wird die Programmierung wesentlich vereinfacht. Allerdings ist das Beispiel in ASM, hier soll das ganze in [[C]] gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Es soll nun eine 8 Bit PWM mit 100 Hz (PWM-Zyklus 10ms) und acht Kanälen generiert werden. Der verwendete Controller ist ein [[AVR]] vom Typ ATmega32, welcher mit dem internen RC-Oszillator auf 8 MHz getaktet wird. Das Programm kann jedoch problemlos an so ziemlich jeden anderen AVR angepaßt werden. Die Programme wurden mit dem Optimierungsgrad -Os compiliert.&lt;br /&gt;
&lt;br /&gt;
=== Erster Versuch ===&lt;br /&gt;
&lt;br /&gt;
Das Programm ist recht kurz und übersichtlich. Im Hauptprogramm wird der Timer 1 initialisiert und der Output Compare 1A als variabler Timer verwendet, wobei die Output Compare Funktion nicht mit dem IO-Pin verbunden ist. Im Interrupt, welcher regelmäßig aufgerufen wird, werden nun in einer Schleife alle acht Kanäle geprüft. Alle Kanäle werden auf HIGH gesetzt, welche eine PWM-Einstellung größer als der aktuelle Zykluszähler haben. Sinnvollerweise werden erst alle Kanäle geprüft und das Ergebnis zwischengespeichert, am Ende erfolgt nur ein Zugriff auf den Port.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
    Eine 8-kanalige PWM mit einfachem Lösungsansatz&lt;br /&gt;
&lt;br /&gt;
    ATmega32 @ 8 MHz&lt;br /&gt;
&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
// Defines an den Controller und die Anwendung anpassen&lt;br /&gt;
&lt;br /&gt;
#define F_CPU 8000000L                  // Systemtakt in Hz&lt;br /&gt;
#define F_PWM 100                       // PWM-Frequenz in Hz&lt;br /&gt;
#define PWM_STEPS 255                   // PWM-Schritte pro Zyklus(1..255)&lt;br /&gt;
#define PWM_PORT PORTD                  // Port für PWM&lt;br /&gt;
#define PWM_DDR DDRD                    // Datenrichtungsregister für PWM&lt;br /&gt;
&lt;br /&gt;
// ab hier nichts ändern, wird alles berechnet&lt;br /&gt;
&lt;br /&gt;
#define T_PWM (F_CPU/(F_PWM*PWM_STEPS)) // Systemtakte pro PWM-Takt&lt;br /&gt;
&lt;br /&gt;
#if (T_PWM&amp;lt;(152+5))&lt;br /&gt;
    #error T_PWM zu klein, F_CPU muss vergrössert werden oder F_PWM oder PWM_STEPS verkleinert werden&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
#if PWM_STEPS &amp;gt; 255&lt;br /&gt;
    #error PWM_STEPS zu gross&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// includes&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// globale Variablen&lt;br /&gt;
&lt;br /&gt;
volatile uint8_t pwm_setting[8];                    // Einstellungen für die einzelnen PWM-Kanäle&lt;br /&gt;
&lt;br /&gt;
// Timer 1 Output COMPARE A Interrupt&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect) {&lt;br /&gt;
    static uint8_t pwm_cnt=0;&lt;br /&gt;
    uint8_t tmp=0, i=0, j=1;&lt;br /&gt;
&lt;br /&gt;
    OCR1A += (uint16_t)T_PWM;&lt;br /&gt;
&lt;br /&gt;
    for (; i&amp;lt;8; i++) {    &lt;br /&gt;
    	if (pwm_setting[i] &amp;gt; pwm_cnt) tmp |= j;&lt;br /&gt;
            j&amp;lt;&amp;lt;=1;&lt;br /&gt;
	}&lt;br /&gt;
    PWM_PORT = tmp;                         // PWMs aktualisieren&lt;br /&gt;
    if (pwm_cnt==(uint8_t)(PWM_STEPS-1))&lt;br /&gt;
        pwm_cnt=0;&lt;br /&gt;
    else&lt;br /&gt;
        pwm_cnt++;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
&lt;br /&gt;
    // PWM einstellen&lt;br /&gt;
    &lt;br /&gt;
    PWM_DDR = 0xFF;         // Port als Ausgang&lt;br /&gt;
    &lt;br /&gt;
    // Timer 1 OCRA1, als variablem Timer nutzen&lt;br /&gt;
&lt;br /&gt;
    TCCR1B = 1;             // Timer läuft mit vollem Systemtakt&lt;br /&gt;
    TIMSK |= (1&amp;lt;&amp;lt;OCIE1A);   // Interrupt freischalten&lt;br /&gt;
&lt;br /&gt;
    sei();                  // Interrupts gloabl einschalten&lt;br /&gt;
&lt;br /&gt;
/*********************************************************************/&lt;br /&gt;
// nur zum Testen, im Anwendungsfall löschen&lt;br /&gt;
&lt;br /&gt;
    volatile uint8_t tmp;&lt;br /&gt;
const uint8_t t1[8]={27, 40, 3, 17, 150, 99, 5, 9};&lt;br /&gt;
const uint8_t t2[8]={27, 40, 3, 0, 150, 99, 5, 9};&lt;br /&gt;
const uint8_t t3[8]={27, 40, 3, 17, 3, 99, 3, 0};&lt;br /&gt;
const uint8_t t4[8]={0, 0, 0, 0, 0, 0, 0, 0};&lt;br /&gt;
const uint8_t t5[8]={0, 0, 0, 0, 0, 0, 0, 9};&lt;br /&gt;
const uint8_t t6[8]={33, 33, 33, 33, 33, 33, 33, 33};&lt;br /&gt;
&lt;br /&gt;
// Messung der Interruptdauer&lt;br /&gt;
    tmp =0;&lt;br /&gt;
    tmp =0;&lt;br /&gt;
    tmp =0;&lt;br /&gt;
&lt;br /&gt;
// Debug &lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t1, 8);&lt;br /&gt;
    &lt;br /&gt;
    memcpy(pwm_setting, t2, 8);&lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t3, 8);&lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t4, 8);&lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t5, 8);&lt;br /&gt;
    &lt;br /&gt;
    memcpy(pwm_setting, t6, 8);&lt;br /&gt;
&lt;br /&gt;
/*********************************************************************/&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im [[AVR-Studio]] kann man den Code simulieren. Wichtig ist hier vor allem die Ausführungszeit des Interrupts. Bei 100 Hz PWM-Frequenz und 256 Schritten pro PWM-Zyklus wird diese Funktion immerhin 25600 mal pro Sekunde aufgerufen (PWM-Takt 25,6 kHz),  bei 8MHz Taktfrequenz stehen damit maximal 312 Takte zur Verfügung. Glücklicherweise ist die Funktion relativ kurz und der GCC leistet gute Arbeit. Der Interrupt benötigt hier 152 Takte, es verbleiben also jeweils 160 Takte zur Bearbeitung anderer Aufgaben. Das entspricht einer CPU-Belastung von ~49%. Das Programm benötigt 284 Byte Programmspeicher. Nicht schlecht für den Anfang.&lt;br /&gt;
&lt;br /&gt;
=== Zweiter Versuch ===&lt;br /&gt;
&lt;br /&gt;
Wo gibt es in diesem Programm noch Optimierungsmöglichkeiten? Nur im Interrupt, denn das ganze Programm besteht ja praktisch nur aus der Interruptroutine. Betrachten wir die Schleifen genauer müssen wir feststellen, daß die Indizierung von pwm_setting[] etwas Rechenzeit benötigt. Ebenso die Schiebeoperation von tmp, auch wenn das nur acht mal ein Takt ist. Wir können jetzt per Hand das machen, was der Compiler auch manchmal macht. Die Rede ist vom Loop-Unrolling. Dabei wird die Schleife durch mehrere diskrete Befehle ersetzt (entrollt). Der Vorteil dabei ist, daß die Befehle zur Berechnung und Prüfung der Zählvariable entfallen, außerdem können ggf. Werte im Voraus berechnet werden. Als Ergebnis hat man zwar ein etwas größeres Programm, doch das wird schneller ausgeführt! Ausserdem orientiert sich diese Version mehr am Original der Assemblerversion. Dadurch wird sie zusätzlich ein wenig kürzer und schneller.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
    Eine 8-kanalige PWM mit verbessertem Lösungsansatz&lt;br /&gt;
&lt;br /&gt;
    ATmega32 @ 8 MHz&lt;br /&gt;
&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
// Defines an den Controller und die Anwendung anpassen&lt;br /&gt;
&lt;br /&gt;
#define F_CPU 8000000L                  // Systemtakt in Hz&lt;br /&gt;
#define F_PWM 100                       // PWM-Frequenz in Hz&lt;br /&gt;
#define PWM_STEPS 256                   // PWM-Schritte pro Zyklus(1..256)&lt;br /&gt;
#define PWM_PORT PORTD                  // Port für PWM&lt;br /&gt;
#define PWM_DDR DDRD                    // Datenrichtungsregister für PWM&lt;br /&gt;
&lt;br /&gt;
// ab hier nichts ändern, wird alles berechnet&lt;br /&gt;
&lt;br /&gt;
#define T_PWM (F_CPU/(F_PWM*PWM_STEPS)) // Systemtakte pro PWM-Takt&lt;br /&gt;
&lt;br /&gt;
#if (T_PWM&amp;lt;(93+5))&lt;br /&gt;
    #error T_PWM zu klein, F_CPU muss vergrösst werden oder F_PWM oder PWM_STEPS verkleinert werden&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// includes&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// globale Variablen&lt;br /&gt;
&lt;br /&gt;
volatile uint8_t pwm_setting[8];                    // Einstellungen für die einzelnen PWM-Kanäle&lt;br /&gt;
&lt;br /&gt;
// Timer 1 Output COMPARE A Interrupt&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect) {&lt;br /&gt;
    static uint8_t pwm_cnt=0;&lt;br /&gt;
    uint8_t tmp=0;&lt;br /&gt;
&lt;br /&gt;
    OCR1A += (uint16_t)T_PWM;&lt;br /&gt;
        &lt;br /&gt;
    if (pwm_setting[0] &amp;gt; pwm_cnt) tmp |= (1&amp;lt;&amp;lt;0);&lt;br /&gt;
    if (pwm_setting[1] &amp;gt; pwm_cnt) tmp |= (1&amp;lt;&amp;lt;1);&lt;br /&gt;
    if (pwm_setting[2] &amp;gt; pwm_cnt) tmp |= (1&amp;lt;&amp;lt;2);&lt;br /&gt;
    if (pwm_setting[3] &amp;gt; pwm_cnt) tmp |= (1&amp;lt;&amp;lt;3);&lt;br /&gt;
    if (pwm_setting[4] &amp;gt; pwm_cnt) tmp |= (1&amp;lt;&amp;lt;4);&lt;br /&gt;
    if (pwm_setting[5] &amp;gt; pwm_cnt) tmp |= (1&amp;lt;&amp;lt;5);&lt;br /&gt;
    if (pwm_setting[6] &amp;gt; pwm_cnt) tmp |= (1&amp;lt;&amp;lt;6);&lt;br /&gt;
    if (pwm_setting[7] &amp;gt; pwm_cnt) tmp |= (1&amp;lt;&amp;lt;7);&lt;br /&gt;
    PWM_PORT = tmp;                         // PWMs aktualisieren&lt;br /&gt;
    if (pwm_cnt==(uint8_t)(PWM_STEPS-1))&lt;br /&gt;
        pwm_cnt=0;&lt;br /&gt;
    else&lt;br /&gt;
        pwm_cnt++;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
&lt;br /&gt;
    // PWM einstellen&lt;br /&gt;
    &lt;br /&gt;
    PWM_DDR = 0xFF;         // Port als Ausgang&lt;br /&gt;
    &lt;br /&gt;
    // Timer 1 OCRA1, als variablem Timer nutzen&lt;br /&gt;
&lt;br /&gt;
    TCCR1B = 1;             // Timer läuft mit vollem Systemtakt&lt;br /&gt;
    TIMSK |= (1&amp;lt;&amp;lt;OCIE1A);   // Interrupt freischalten&lt;br /&gt;
&lt;br /&gt;
    sei();                  // Interrupts gloabl einschalten&lt;br /&gt;
&lt;br /&gt;
/*********************************************************************/&lt;br /&gt;
// nur zum Testen, im Anwendungsfall löschen&lt;br /&gt;
&lt;br /&gt;
    volatile uint8_t tmp;&lt;br /&gt;
const uint8_t t1[8]={27, 40, 3, 17, 150, 99, 5, 9};&lt;br /&gt;
const uint8_t t2[8]={27, 40, 3, 0, 150, 99, 5, 9};&lt;br /&gt;
const uint8_t t3[8]={27, 40, 3, 17, 3, 99, 3, 0};&lt;br /&gt;
const uint8_t t4[8]={0, 0, 0, 0, 0, 0, 0, 0};&lt;br /&gt;
const uint8_t t5[8]={0, 0, 0, 0, 0, 0, 0, 9};&lt;br /&gt;
const uint8_t t6[8]={33, 33, 33, 33, 33, 33, 33, 33};&lt;br /&gt;
&lt;br /&gt;
// Messung der Interruptdauer&lt;br /&gt;
    tmp =0;&lt;br /&gt;
    tmp =0;&lt;br /&gt;
    tmp =0;&lt;br /&gt;
&lt;br /&gt;
// Debug &lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t1, 8);&lt;br /&gt;
    &lt;br /&gt;
    memcpy(pwm_setting, t2, 8);&lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t3, 8);&lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t4, 8);&lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t5, 8);&lt;br /&gt;
    &lt;br /&gt;
    memcpy(pwm_setting, t6, 8);&lt;br /&gt;
&lt;br /&gt;
/*********************************************************************/&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit dieser Interruptroutine werden nur noch 93 Takte benötigt, die CPU-Belastung verringert sich auf  ~30%. Nicht schlecht. Der Programmcode steigt auf 324 Byte, aber das ist im Angesicht der Leistungsverbesserung zu verschmerzen. Weiter verringern kann man die CPU-Belastung durch eine niedrigere PWM-Frequenz oder eine geringere Anzahl Stufen der PWM. Wenn man beispielsweise mit 64 (6 Bit) statt 256 (8 Bit) Stufen auskommt verringert sich die Belastung um den Faktor 4.&lt;br /&gt;
&lt;br /&gt;
== Intelligenter Lösungsansatz ==&lt;br /&gt;
&lt;br /&gt;
Wenn auch eine CPU-Last von 30% recht akzeptabel erscheint, so hat man doch noch irgendwie das Gefühl, daß es noch besser geht. Aber wie? Mein Mathematikprofessor pflegte in so einem Fall die Anwendung der „Methode des scharfen Blicks“ ™. Was passiert eigentlich während eines gesamten PWM-Zykluses?&lt;br /&gt;
&lt;br /&gt;
*Zu Beginn werden alle IO-Pins gesetzt, deren PWM-Einstellung nicht Null ist.&lt;br /&gt;
*Die jeweiligen IO-Pins werden gelöscht, wenn der PWM-Zähler mit der PWM-Einstellung übereinstimmt&lt;br /&gt;
&lt;br /&gt;
Ja klar, aber da wir nur acht Kanäle haben, gibt es maximal 8 Zeitpunkte, an denen ein Pin gelöscht werden muss. Wenn mehrere Kanäle die gleiche PWM-Einstellung haben sind es sogar noch weniger. Alle anderen Interrupts verursachen keinerlei Änderung der IO-Pins und verbrauchen eigentlich nur sinnlos Rechenzeit. Ein Skandal!&lt;br /&gt;
&lt;br /&gt;
Was ist also zu tun? Wir wissen nun, daß es maximal 9 Ereignisse pro PWM-Zyklus gibt. Was ist damit zu machen?&lt;br /&gt;
&lt;br /&gt;
*Die PWM-Kanäle müssen in aufsteigender Folge sortiert werden.&lt;br /&gt;
*Wenn mehrere PWM-Kanäle den gleichen PWM-Wert haben müssen sie zusammengefaßt werden&lt;br /&gt;
*Die Zeitdifferenzen zwischen den einzelnen Ereignissen müssen berechnet werden&lt;br /&gt;
&lt;br /&gt;
Das ist eigentlich schon alles. Praktisch ist das mit einigen Kniffligkeiten verbunden, aber die sind lösbar. Am Ende steht eine Interruptroutine, welche maximal 9 mal pro PWM-Zyklus aufgerufen wird und die jeweiligen IO-Pins setzt bzw. löscht. Eine normale Funktion wird benutzt, um die PWM-Einstellungen der acht Kanäle in die notwendigen Informationen für die Interruptroutine umzuwandeln. Das hat unter anderem den Vorteil, daß nur dann zusätzlich Rechenzeit benötigt wird, wenn sich die PWM-Einstellungen ändern.&lt;br /&gt;
&lt;br /&gt;
Es sollte jedoch nicht unerwähnt bleiben, dass es sich bei dieser Lösung um keine echte PWM handelt, da sie im Fall, dass ein PWM-Wert 0 ist, den Ausgang nie auf 1 schaltet, und somit auch kein Puls vorhanden ist. Allerdings ist das für die meisten Anwendungen kein Problem.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
    Eine 8-kanalige PWM mit intelligentem Lösungsansatz&lt;br /&gt;
&lt;br /&gt;
    ATmega32 @ 8 MHz&lt;br /&gt;
&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
// Defines an den Controller und die Anwendung anpassen&lt;br /&gt;
&lt;br /&gt;
#define F_CPU         8000000L           // Systemtakt in Hz&lt;br /&gt;
#define F_PWM         100L               // PWM-Frequenz in Hz&lt;br /&gt;
#define PWM_PRESCALER 8                  // Vorteiler für den Timer&lt;br /&gt;
#define PWM_STEPS     256                // PWM-Schritte pro Zyklus(1..256)&lt;br /&gt;
#define PWM_PORT      PORTB              // Port für PWM&lt;br /&gt;
#define PWM_DDR       DDRB               // Datenrichtungsregister für PWM&lt;br /&gt;
#define PWM_CHANNELS  8                  // Anzahl der PWM-Kanäle&lt;br /&gt;
&lt;br /&gt;
// ab hier nichts ändern, wird alles berechnet&lt;br /&gt;
&lt;br /&gt;
#define T_PWM (F_CPU/(PWM_PRESCALER*F_PWM*PWM_STEPS)) // Systemtakte pro PWM-Takt&lt;br /&gt;
//#define T_PWM 1   //TEST&lt;br /&gt;
&lt;br /&gt;
#if ((T_PWM*PWM_PRESCALER)&amp;lt;(111+5))&lt;br /&gt;
    #error T_PWM zu klein, F_CPU muss vergrösst werden oder F_PWM oder PWM_STEPS verkleinert werden&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
#if ((T_PWM*PWM_STEPS)&amp;gt;65535)&lt;br /&gt;
    #error Periodendauer der PWM zu gross! F_PWM oder PWM_PRESCALER erhöhen.   &lt;br /&gt;
#endif&lt;br /&gt;
// includes&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// globale Variablen&lt;br /&gt;
&lt;br /&gt;
uint16_t pwm_timing[PWM_CHANNELS+1];          // Zeitdifferenzen der PWM Werte&lt;br /&gt;
uint16_t pwm_timing_tmp[PWM_CHANNELS+1];      &lt;br /&gt;
&lt;br /&gt;
uint8_t  pwm_mask[PWM_CHANNELS+1];            // Bitmaske für PWM Bits, welche gelöscht werden sollen&lt;br /&gt;
uint8_t  pwm_mask_tmp[PWM_CHANNELS+1];        // ändern uint16_t oder uint32_t für mehr Kanäle&lt;br /&gt;
&lt;br /&gt;
uint8_t  pwm_setting[PWM_CHANNELS];           // Einstellungen für die einzelnen PWM-Kanäle&lt;br /&gt;
uint8_t  pwm_setting_tmp[PWM_CHANNELS+1];     // Einstellungen der PWM Werte, sortiert&lt;br /&gt;
                                              // ändern auf uint16_t für mehr als 8 Bit Auflösung  &lt;br /&gt;
&lt;br /&gt;
volatile uint8_t pwm_cnt_max=1;               // Zählergrenze, Initialisierung mit 1 ist wichtig!&lt;br /&gt;
volatile uint8_t pwm_sync;                    // Update jetzt möglich&lt;br /&gt;
&lt;br /&gt;
// Pointer für wechselseitigen Datenzugriff&lt;br /&gt;
&lt;br /&gt;
uint16_t *isr_ptr_time  = pwm_timing;&lt;br /&gt;
uint16_t *main_ptr_time = pwm_timing_tmp;&lt;br /&gt;
&lt;br /&gt;
uint8_t *isr_ptr_mask  = pwm_mask;              // Bitmasken fuer PWM-Kanäle&lt;br /&gt;
uint8_t *main_ptr_mask = pwm_mask_tmp;          // ändern uint16_t oder uint32_t für mehr Kanäle&lt;br /&gt;
&lt;br /&gt;
// Zeiger austauschen&lt;br /&gt;
// das muss in einem Unterprogramm erfolgen,&lt;br /&gt;
// um eine Zwischenspeicherung durch den Compiler zu verhindern&lt;br /&gt;
&lt;br /&gt;
void tausche_zeiger(void) {&lt;br /&gt;
    uint16_t *tmp_ptr16;&lt;br /&gt;
    uint8_t *tmp_ptr8;                          // ändern uint16_t oder uint32_t für mehr Kanäle&lt;br /&gt;
&lt;br /&gt;
    tmp_ptr16 = isr_ptr_time;&lt;br /&gt;
    isr_ptr_time = main_ptr_time;&lt;br /&gt;
    main_ptr_time = tmp_ptr16;&lt;br /&gt;
    tmp_ptr8 = isr_ptr_mask;&lt;br /&gt;
    isr_ptr_mask = main_ptr_mask;&lt;br /&gt;
    main_ptr_mask = tmp_ptr8;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// PWM Update, berechnet aus den PWM Einstellungen&lt;br /&gt;
// die neuen Werte für die Interruptroutine&lt;br /&gt;
&lt;br /&gt;
void pwm_update(void) {&lt;br /&gt;
    &lt;br /&gt;
    uint8_t i, j, k;&lt;br /&gt;
    uint8_t m1, m2, tmp_mask;                   // ändern uint16_t oder uint32_t für mehr Kanäle    &lt;br /&gt;
    uint8_t min, tmp_set;                       // ändern auf uint16_t für mehr als 8 Bit Auflösung&lt;br /&gt;
&lt;br /&gt;
    // PWM Maske für Start berechnen&lt;br /&gt;
    // gleichzeitig die Bitmasken generieren und PWM Werte kopieren&lt;br /&gt;
&lt;br /&gt;
    m1 = 1;&lt;br /&gt;
    m2 = 0;&lt;br /&gt;
    for(i=1; i&amp;lt;=(PWM_CHANNELS); i++) {&lt;br /&gt;
        main_ptr_mask[i]=~m1;                       // Maske zum Löschen der PWM Ausgänge&lt;br /&gt;
        pwm_setting_tmp[i] = pwm_setting[i-1];&lt;br /&gt;
        if (pwm_setting_tmp[i]!=0) m2 |= m1;        // Maske zum setzen der IOs am PWM Start&lt;br /&gt;
        m1 &amp;lt;&amp;lt;= 1;&lt;br /&gt;
    }&lt;br /&gt;
    main_ptr_mask[0]=m2;                            // PWM Start Daten &lt;br /&gt;
&lt;br /&gt;
    // PWM settings sortieren; Einfügesortieren&lt;br /&gt;
&lt;br /&gt;
    for(i=1; i&amp;lt;=PWM_CHANNELS; i++) {&lt;br /&gt;
        min=PWM_STEPS-1;&lt;br /&gt;
        k=i;&lt;br /&gt;
        for(j=i; j&amp;lt;=PWM_CHANNELS; j++) {&lt;br /&gt;
            if (pwm_setting_tmp[j]&amp;lt;min) {&lt;br /&gt;
                k=j;                                // Index und PWM-setting merken&lt;br /&gt;
                min = pwm_setting_tmp[j];&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        if (k!=i) {&lt;br /&gt;
            // ermitteltes Minimum mit aktueller Sortiertstelle tauschen&lt;br /&gt;
            tmp_set = pwm_setting_tmp[k];&lt;br /&gt;
            pwm_setting_tmp[k] = pwm_setting_tmp[i];&lt;br /&gt;
            pwm_setting_tmp[i] = tmp_set;&lt;br /&gt;
            tmp_mask = main_ptr_mask[k];&lt;br /&gt;
            main_ptr_mask[k] = main_ptr_mask[i];&lt;br /&gt;
            main_ptr_mask[i] = tmp_mask;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Gleiche PWM-Werte vereinigen, ebenso den PWM-Wert 0 löschen falls vorhanden&lt;br /&gt;
&lt;br /&gt;
    k=PWM_CHANNELS;             // PWM_CHANNELS Datensätze&lt;br /&gt;
    i=1;                        // Startindex&lt;br /&gt;
&lt;br /&gt;
    while(k&amp;gt;i) {&lt;br /&gt;
        while ( ((pwm_setting_tmp[i]==pwm_setting_tmp[i+1]) || (pwm_setting_tmp[i]==0))  &amp;amp;&amp;amp; (k&amp;gt;i) ) {&lt;br /&gt;
&lt;br /&gt;
            // aufeinanderfolgende Werte sind gleich und können vereinigt werden&lt;br /&gt;
            // oder PWM Wert ist Null&lt;br /&gt;
            if (pwm_setting_tmp[i]!=0)&lt;br /&gt;
                main_ptr_mask[i+1] &amp;amp;= main_ptr_mask[i];        // Masken vereinigen&lt;br /&gt;
&lt;br /&gt;
            // Datensatz entfernen,&lt;br /&gt;
            // Nachfolger alle eine Stufe hochschieben&lt;br /&gt;
            for(j=i; j&amp;lt;k; j++) {&lt;br /&gt;
                pwm_setting_tmp[j] = pwm_setting_tmp[j+1];&lt;br /&gt;
                main_ptr_mask[j] = main_ptr_mask[j+1];&lt;br /&gt;
            }&lt;br /&gt;
            k--;&lt;br /&gt;
        }&lt;br /&gt;
        i++;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // letzten Datensatz extra behandeln&lt;br /&gt;
    // Vergleich mit dem Nachfolger nicht möglich, nur löschen&lt;br /&gt;
    // gilt nur im Sonderfall, wenn alle Kanäle 0 sind&lt;br /&gt;
    if (pwm_setting_tmp[i]==0) k--;&lt;br /&gt;
&lt;br /&gt;
    // Zeitdifferenzen berechnen&lt;br /&gt;
    &lt;br /&gt;
    if (k==0) { // Sonderfall, wenn alle Kanäle 0 sind&lt;br /&gt;
        main_ptr_time[0]=(uint16_t)T_PWM*PWM_STEPS/2;&lt;br /&gt;
        main_ptr_time[1]=(uint16_t)T_PWM*PWM_STEPS/2;&lt;br /&gt;
        k=1;&lt;br /&gt;
    }&lt;br /&gt;
    else {&lt;br /&gt;
        i=k;&lt;br /&gt;
        main_ptr_time[i]=(uint16_t)T_PWM*(PWM_STEPS-pwm_setting_tmp[i]);&lt;br /&gt;
        tmp_set=pwm_setting_tmp[i];&lt;br /&gt;
        i--;&lt;br /&gt;
        for (; i&amp;gt;0; i--) {&lt;br /&gt;
            main_ptr_time[i]=(uint16_t)T_PWM*(tmp_set-pwm_setting_tmp[i]);&lt;br /&gt;
            tmp_set=pwm_setting_tmp[i];&lt;br /&gt;
        }&lt;br /&gt;
        main_ptr_time[0]=(uint16_t)T_PWM*tmp_set;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // auf Sync warten&lt;br /&gt;
&lt;br /&gt;
    pwm_sync=0;             // Sync wird im Interrupt gesetzt&lt;br /&gt;
    while(pwm_sync==0);&lt;br /&gt;
&lt;br /&gt;
    // Zeiger tauschen&lt;br /&gt;
    cli();&lt;br /&gt;
    tausche_zeiger();&lt;br /&gt;
    pwm_cnt_max = k;&lt;br /&gt;
    sei();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Timer 1 Output COMPARE A Interrupt&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect) {&lt;br /&gt;
    static uint8_t pwm_cnt;                     // ändern auf uint16_t für mehr als 8 Bit Auflösung&lt;br /&gt;
    uint8_t tmp;                                // ändern uint16_t oder uint32_t für mehr Kanäle&lt;br /&gt;
&lt;br /&gt;
    OCR1A += isr_ptr_time[pwm_cnt];&lt;br /&gt;
    tmp    = isr_ptr_mask[pwm_cnt];&lt;br /&gt;
    &lt;br /&gt;
    if (pwm_cnt == 0) {&lt;br /&gt;
        PWM_PORT = tmp;                         // Ports setzen zu Begin der PWM&lt;br /&gt;
                                                // zusätzliche PWM-Ports hier setzen&lt;br /&gt;
        pwm_cnt++;&lt;br /&gt;
    }&lt;br /&gt;
    else {&lt;br /&gt;
        PWM_PORT &amp;amp;= tmp;                        // Ports löschen&lt;br /&gt;
                                                // zusätzliche PWM-Ports hier setzen&lt;br /&gt;
        if (pwm_cnt == pwm_cnt_max) {&lt;br /&gt;
            pwm_sync = 1;                       // Update jetzt möglich&lt;br /&gt;
            pwm_cnt  = 0;&lt;br /&gt;
        }&lt;br /&gt;
        else pwm_cnt++;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
&lt;br /&gt;
    // PWM Port einstellen&lt;br /&gt;
    &lt;br /&gt;
    PWM_DDR = 0xFF;         // Port als Ausgang&lt;br /&gt;
    // zusätzliche PWM-Ports hier setzen&lt;br /&gt;
    &lt;br /&gt;
    // Timer 1 OCRA1, als variablen Timer nutzen&lt;br /&gt;
&lt;br /&gt;
    TCCR1B = 2;             // Timer läuft mit Prescaler 8&lt;br /&gt;
    TIMSK |= (1&amp;lt;&amp;lt;OCIE1A);   // Interrupt freischalten&lt;br /&gt;
&lt;br /&gt;
    sei();                  // Interrupts gloabl einschalten&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/******************************************************************/&lt;br /&gt;
// nur zum testen, in der Anwendung entfernen&lt;br /&gt;
/*&lt;br /&gt;
// Test values&lt;br /&gt;
volatile uint8_t tmp;&lt;br /&gt;
const uint8_t t1[8]={255, 40, 3, 17, 150, 99, 5, 9};&lt;br /&gt;
const uint8_t t2[8]={27, 40, 3, 0, 150, 99, 5, 9};&lt;br /&gt;
const uint8_t t3[8]={27, 40, 3, 17, 3, 99, 3, 0};&lt;br /&gt;
const uint8_t t4[8]={0, 0, 0, 0, 0, 0, 0, 0};&lt;br /&gt;
const uint8_t t5[8]={9, 1, 1, 1, 1, 1, 1, 1};&lt;br /&gt;
const uint8_t t6[8]={33, 33, 33, 33, 33, 33, 33, 33};&lt;br /&gt;
const uint8_t t7[8]={0, 0, 0, 0, 0, 0, 0, 88};&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// Messung der Interruptdauer&lt;br /&gt;
    tmp =1;&lt;br /&gt;
    tmp =2;&lt;br /&gt;
    tmp =3;&lt;br /&gt;
&lt;br /&gt;
// Debug &lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t1, 8);&lt;br /&gt;
    pwm_update();&lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t2, 8);&lt;br /&gt;
    pwm_update();&lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t3, 8);&lt;br /&gt;
    pwm_update();&lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t4, 8);&lt;br /&gt;
    pwm_update();&lt;br /&gt;
&lt;br /&gt;
    memcpy(pwm_setting, t5, 8);&lt;br /&gt;
    pwm_update();&lt;br /&gt;
    &lt;br /&gt;
    memcpy(pwm_setting, t6, 8);&lt;br /&gt;
    pwm_update();&lt;br /&gt;
    &lt;br /&gt;
    memcpy(pwm_setting, t7, 8);&lt;br /&gt;
    pwm_update();&lt;br /&gt;
*/&lt;br /&gt;
/******************************************************************/&lt;br /&gt;
&lt;br /&gt;
    while(1);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Programm ist schon um einiges länger (968 Byte). Die Interruptroutine benötigt maximal 111 Takte und wird zwischen 2 bis 9 mal pro PWM-Zyklus aufgerufen. Zweimal, wenn alle PWM-Einstellungen gleich sind, 9 mal, wenn alle PWM-Einstellungen verschieden sind. Damit werden zwischen 222 bis 999 Takte benötigt, pro &#039;&#039;&#039;PWM-Zyklus&#039;&#039;&#039;, nicht pro PWM-Takt! Das entspricht einer &#039;&#039;&#039;CPU-Belastung von 0,3..1,2%&#039;&#039;&#039;! [http://de.wikipedia.org/wiki/Beifall Standing Ovations]! Die Funktion pwm_update() benötigt ca. 1500 bis 1800 Takte, das ist geringfügig abhängig von den PWM-Einstellungen, je nach dem ob die Daten schon sortiert sind und ob PWM-Werte mehrfach vorkommen. Bei einer Updaterate von 100 Hz (mehr ist physikalisch sinnlos) entspricht das einer CPU-Belastung von 2,3%, praktisch wird es wahrscheinlich weniger sein. Taktet man den AVR mit vollen 16 MHz halbiert sich die CPU-Belastung noch einmal. Beachtet werden sollte hier die Datenübergabe von der Funktion pwm_update() zur Interruptroutine. Hier werden jeweils zwei Zeiger verwendet, um auf Arrays zu zeigen. In zwei Arrays werden durch die Funktion die Berechnungen der neuen Daten vorgenommen. In den beiden anderen Arrays stehen die aktuellen Daten, mit welchen die ISR arbeitet. Um am Ende der Berechung ein relativ aufwändiges Kopieren der Daten zu vermeiden werden einfach die Zeiger vertauscht. Das ist wesentlich schneller als das Kopieren der Arrays! Im englischen spricht man hier von double buffering, also doppelter Pufferung. Dieses Prinzip wird oft angewendet. Würde man allerdings einfach am Ende die Zeiger tauschen käme es zu einem Crash! Der Interrupt kann jederzeit aktiv werden. Wenn dann die Zeiger nur halb kopiert sind greift die Interruptroutine auf zerstückelte Daten zu und macht Müll. Ebenso würde es zu Fehlfunktionen kommen, wenn während es PWM-Zyklus neue Daten in die Arrays kopiert werden. Das muß verhindert werden. Und zwar dadurch, daß über eine Variable eine Synchronisation durchgeführt wird. Diese wird am Ende des PWM-Zyklus gesetzt und signalisiert, daß neue Daten für den nächsten Zyklus kopiert werden können. Deshalb muss die Funktion pwm_update ggf. bis zu 1 vollen PWM-Zyklus warten, bis die Zeiger getauscht werden können. Wichtig ist dabei, daß die Variable pwm_sync, welche sowohl in der Funktion als auch im Interrupt geschrieben wird, als &#039;&#039;&#039;volatile&#039;&#039;&#039; deklariert wird. Denn sonst würde die Sequenz&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
pwm_sync=0;             // Sync wird im Interrupt gesetzt&lt;br /&gt;
while(pwm_sync==0);&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
zum Stehenbleiben der CPU führen, weil der Compiler erkennt, daß die Variable nie ungleich Null sein kann und damit die Schleife endlos ausgeführt wird. Der Compiler kann prinzipbedingt nicht automatisch erkennen, daß die Variable im Interrupt auf 1 gesetzt wird.&lt;br /&gt;
&lt;br /&gt;
Bei dem schon recht hohen Prozessortakt von 8MHz und der relativ niedrigen PWM Frequenz von 100 Hz haben wir allerdings ein kleines Problem. Wenn beispielsweise nur ein Kanal den PWM-Wert 10 hat, alle anderen aber den Wert Null, dann passiert folgendes. Zum Begin eines PWM-Zyklus wird der eine Kanal aktiviert. Jetzt wird per Timer für 10xT_PWM = 3120 Takte gewartet. Jetzt wird dieser Kanal wieder gelöscht. Bis zum Begin des nächsten PWM-Zyklus muss jedoch noch (256-10)*T_PWM = 76752 Takte gewartet werden. Doch diese Zahl passt nicht mehr in eine 16 Bit Variable! Und damit kann sie auch nicht mit dem Timer verwendet werden. Der Ausweg heisst Vorteiler (engl. Prescaler). Damit kann der Timer langsamer getaktet werden und somit wird die gleiche Wartezeit mit weniger Timertakten erzielt. Zu beachten ist, dass die Einstellung im #define PWM_PRESCALER mit der realen Einstellung in TCCR1B übereinstimmen muss.&lt;br /&gt;
&lt;br /&gt;
Eine Einschränkung gilt allerdings für alle Soft-PWMs. Die PWM-Frequenz muss niedrig genug sein, damit sich die Interrupts nicht überschneiden. D.h. der Wert T_PWM muß immer größer sein als die Anzahl Takte der Interruptroutine. Das wird im Quelltext mit Hilfe von #if  . . #endif geprüft. Die +5 Takte sind eine Reserve. Dazu muß aber die Optimierung -Os eingeschaltet sein, sonst stimmen die Zahlen nicht!&lt;br /&gt;
&lt;br /&gt;
Als Grenze kann mit diesem Programm bei 16 MHz eine 10-Bit PWM in Software generiert werden, was schon sehr respektabel ist und weiches, langsames [[LED-Fading]] mit vielen [[LED]]s ermöglicht. Dazu muss allerdings das Programm an wenigen Stellen angepasst werden, im Speziellen müssen verschiedene Variablen und Arrays von uint8_t auf uint16_t umgestellt werden. Da Gleiche gilt für mehr PWM-Kanäle, praktisch wurden schon bis zu 32 Kanäle realisiert. Der Quelltext ist an den Stellen kommentiert.&lt;br /&gt;
&lt;br /&gt;
== Zusammenfassung ==&lt;br /&gt;
&lt;br /&gt;
Durch kritische Analyse ist es möglich, eine Software-PWM drastisch zu verbessern und die CPU-Belastung auf ein verschwindend geringes Maß zu reduzieren. Zudem zeigt dieses Beispiel ein oft vorkommendes Muster auf, welches gemeinhin als &#039;Time for Space&#039; (Zeit für Platz) bezeichnet wird. Man meint damit, dass es oft möglich ist, dramatische Einsparungen in der Laufzeit zu erreichen, wenn man gewillt ist dafür Speicherplatz zu opfern.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| Version  || Programmspeicher [Byte] || CPU-Belastung [%] &lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 1 || 284   || 49&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 2 || 324   || 30&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 3 || 968   || 0,3..1,2&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* [[AVR-Tutorial: PWM]]&lt;br /&gt;
* [[AVR-GCC-Tutorial#PWM (Pulsweitenmodulation)|AVR-GCC-Tutorial: PWM]]&lt;br /&gt;
* [[LED-Fading]] - LED dimmen mit PWM&lt;br /&gt;
&lt;br /&gt;
[[Category:AVR]]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32&amp;diff=62171</id>
		<title>STM32</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32&amp;diff=62171"/>
		<updated>2011-12-03T07:59:40Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: /* Demo-Projekte */  Fixed Link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;STM32 ist ein Mikrocontroller-Familie von [http://www.st.com/mcu/inchtml-pages-stm32.html ST] mit einer 32-Bit [http://www.arm.com/products/processors/cortex-m/index.php ARM Cortex-M3] CPU. Diese Architektur ist speziell für den Einsatz in Microcontrollern neu entwickelt und löst damit die bisherigen ARM7-basierten Controller weitestgehend ab. Den STM32 gibt es von ST in unzähligen Varianten mit variabler Peripherie und verschiedenen Gehäusegrößen und -formen. Durch die geringe Chipfläche des Cores ist es ST möglich, eine 32 Bit-CPU für weniger als 1&amp;amp;nbsp;€ anzubieten.&lt;br /&gt;
&lt;br /&gt;
[[Bild:stm32F103xc.png|thumb|right|340px|Blockdiagramm STM32F103xC/D/E]]&lt;br /&gt;
&lt;br /&gt;
== STM32-Familien ==&lt;br /&gt;
&lt;br /&gt;
Bisher gibt es drei STM32-Familien, wobei sich die Größte (STM32F) in weitere Unterfamilien (Linien) aufteilt:&lt;br /&gt;
* [http://www.st.com/internet/mcu/subclass/1169.jsp STM32F1]&lt;br /&gt;
** Connectivity line&lt;br /&gt;
** Performance line&lt;br /&gt;
** USB Access line&lt;br /&gt;
** Access Line&lt;br /&gt;
** Value line &lt;br /&gt;
* [http://www.st.com/internet/mcu/product/250173.jsp STM32F2]&lt;br /&gt;
** Wie die STM32F1 Serie, jedoch 120MHz, Camera-Interface, 32-Bit Timer, ...&lt;br /&gt;
* [http://www.st.com/mcu/inchtml-pages-stm32l.html STM32L] (LowPower) &lt;br /&gt;
** mit LCD Treiber&lt;br /&gt;
* STM32T (Touch)  &lt;br /&gt;
* [http://www.st.com/mcu/inchtml-pages-stm32w.html STM32W] (RF-MCU) &lt;br /&gt;
* [http://www.st.com/internet/mcu/subclass/1521.jsp STM32F4] (CM4)&lt;br /&gt;
** ARM® Cortex™-M4-based STM32 F4&lt;br /&gt;
** DSP instructions and the floating point unit &lt;br /&gt;
** LQFP64, LQFP100, LQFP144, LQFP176 and UFBGA176 packages&lt;br /&gt;
[http://www.st.com/internet/mcu/class/1734.jsp Hier eine Übersicht zum auswählen eines STM32Fxxx]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Features&#039;&#039;&#039;&lt;br /&gt;
* Cortex-M3 bzw. Cortex-M4 Kern in der STM32F4xx Serie&lt;br /&gt;
* 16KB ... 1MB  [[Flash-ROM]]&lt;br /&gt;
*  4KB ... 192KB [[Speicher#SRAM|SRAM]]&lt;br /&gt;
* 4KB [[Speicher#EEPROM|EEPROM]] (STM32L)&lt;br /&gt;
* [[IC-Gehäuseformen | Gehäuse]] 36 ... 176 Pins als QFN, LQFP und BGA&lt;br /&gt;
* Derzeit sind über &#039;&#039;&#039;250&#039;&#039;&#039; STM32 Derivate/Varianten verfügbar&lt;br /&gt;
* Bis 72MHz CPU-Takt, bis 120MHz beim STM32F2xx, bis 168 MHz beim STM32F4xx, wobei eine spezielle prefetch-hardware bis 120/168 MHz eine Geschwindigkeit erzielen soll, die 0 Wait-States entspricht. Der CPU-Takt wird über einen Multiplikator aus dem internen RC-Takt oder einem externen Quarz-Takt abgeleitet.&lt;br /&gt;
* Externes Businterface (nur bei Gehäusen ab 100 Pin und nur bei STM32F4, STM32F2 und STM32F1 Performance line)&lt;br /&gt;
* LCD Treiber für 8x40 Punkte (nicht beim STM32F2xx)&lt;br /&gt;
* Spannungsbereich 1,65 ... 3,6V, nur eine Betriebsspannung nötig&lt;br /&gt;
* Temperaturbereich bis 125 °C&lt;br /&gt;
* Bis zu 140 IOs, viele davon [[Pegelwandler|5V-tolerant]]&lt;br /&gt;
* Interner, kalibrierter RC-Oszillator mit 8MHz (16MHz bei STM32F2xx)&lt;br /&gt;
* Externer Quarz&lt;br /&gt;
* Real Time Clock mit eigenem Quarz und separater Stromversorgung&lt;br /&gt;
* Bis zu 16 [[Timer]], je Timer bis zu 4 IC/OC/PWM Ausgänge. Davon 2x Motion Control Timer (bei STM32F103xF/G)&lt;br /&gt;
* Systick Counter&lt;br /&gt;
* Bis zu 3 12-Bit [[AD-Wandler]] mit insgesamt 24 AD-Eingängen, integrierter [[Temperatursensor]]&lt;br /&gt;
* Bis zu 2 12-Bit [[DA-Wandler]]&lt;br /&gt;
* Bis zu 2 [[DMA]] Controller mit bis zu 12 Kanälen (16 beim STM32F2xx)&lt;br /&gt;
* Bis zu 2x [[I2C|I²C]]&lt;br /&gt;
* Bis zu 5x [[UART|USART]] mit LIN, IrDA und Modem Control (6 beim STM32F2xx)&lt;br /&gt;
* Bis zu 3x [[SPI]]&lt;br /&gt;
* Bis zu 2x [[I2S|I²S]]&lt;br /&gt;
* Bis zu 2x [[CAN]]&lt;br /&gt;
* RNG - Random Number Genrator (STM32F2xx)&lt;br /&gt;
* Cryptographic Processor (CRYP) (STM32F2xx)&lt;br /&gt;
* Hash Processor (HASH) (STM32F2xx)&lt;br /&gt;
* Kamera-Interface (DCMI) (STM32F2xx)&lt;br /&gt;
* [[USB]] 2.0 Full Speed / OTG&lt;br /&gt;
* [[USB]] 2.0 Hi Speed OTG mit extra PHY-Chip (STM32F2xx)&lt;br /&gt;
* SDIO Interface (z.B. SD-Card Reader)&lt;br /&gt;
* Ethernet&lt;br /&gt;
* Watchdog mit Window-Mode&lt;br /&gt;
* Jedes Peripheriemodul ist separat einschaltbar, wodurch sich erheblich [[Ultra low power|Strom sparen]] lässt&lt;br /&gt;
* [[JTAG]] und SWD (Serial Wire Debug) Interface&lt;br /&gt;
* Bis zu 6 Hardware-Breakpoints für Debuggen&lt;br /&gt;
* und vieles mehr . . .&lt;br /&gt;
&lt;br /&gt;
== Struktur der Dokumentation: ==&lt;br /&gt;
&lt;br /&gt;
Als Beispiel der Dokumentation soll stellvertretend der [http://www.st.com/mcu/devicedocs-STM32F103RC-110.html STM32F103RC] genannt werden. Die Seite von ST beinhaltet alle nötigen Informationen passend zu diesem Prozessor.&lt;br /&gt;
&lt;br /&gt;
Diese Dokumente von ST beschreiben den Controller:&lt;br /&gt;
&lt;br /&gt;
* [http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/DATASHEET/CD00191185.pdf  Datasheet STM32F103xC/D/E]&lt;br /&gt;
* [http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/REFERENCE_MANUAL/CD00171190.pdf  Reference Manual (RM0008)]&lt;br /&gt;
* [http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/PROGRAMMING_MANUAL/CD00228163.pdf  Cortex-M3 Programming Manual]&lt;br /&gt;
* [http://www.st.com/stonline/products/literature/pm/13259.pdf Flash Programming Reference]&lt;br /&gt;
&lt;br /&gt;
Im Datasheet sind die speziellen Eigenschaften einer bestimmten Modellreihe beschrieben und die exakten Daten und Pinouts aufgeführt. Die Peripheriemodule werden nur aufgeführt, nicht detailliert beschrieben. In der Referenz ist der gesamte Controller mit Peripheriemodulen im Detail beschrieben, gültig für alle STM32 Controller. Details zum Prozessorkern selbst und den nicht STM32-spezifischen mit dem Cortex-M3 Core assoziierten Modulen wie dem Interrupt-Controller und dem Systick-Timer findet man jedoch nicht dort, sondern im Cortex-M3 Manual. Wer nicht die ST Firmware-Library verwendet, der benötigt zusätzlich die Flash Programming Reference für die Betriebsart des Flash-ROMs, d.h. die frequenzabhängige Konfiguration der Waitstates. Hinzu kommen optionale Dokumente von ARM, die den [http://infocenter.arm.com/help/topic/com.arm.doc.ddi0337-/ Cortex-M3 Kern] beschreiben. Hier gibt es den Opcode wenn man ihn in [http://infocenter.arm.com/help/topic/com.arm.doc.ddi0403-/ Assembler] programmieren möchte. Zusätzlich sollten auch die [http://www.st.com/stonline/products/literature/es/14732.pdf Errata Sheets] beachtet werden. Empfohlen sei auch die Appnote &amp;quot;[http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/APPLICATION_NOTE/CD00164185.pdf STM32F10xxx hardware development: getting started]&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== ‎STM32F10x Standard Peripherals Library ==&lt;br /&gt;
&lt;br /&gt;
ST bietet eine umfangreiche Firmwarebibliothek, eine einzige Bibliothek für alle STM32 Derivate. Das ist der große Vorteil von ST (gibt es beispielsweise auf den Cortex-M3 Controllern von TI auch, ist teilweise in einem separaten ROM untergebracht). Einmal programmieren und in allen STM32 verwendbar. Alle Funktionen sind gekapselt in einfache Strukturen und Funktionsaufrufe. Somit muss man sich nicht selbst um die Peripherieregister kümmern. Diese Library und ihre Dokumentation setzen das grundlegende Verständnis der Funktion des jeweiligen Peripheriemoduls voraus, wie es die o.A. Referenz und diverse Appnotes vermitteln.&lt;br /&gt;
&lt;br /&gt;
Details siehe: [[‎STM32F10x Standard Peripherals Library]].&lt;br /&gt;
&lt;br /&gt;
Mit [https://sourceforge.net/projects/libopenstm32/ libopenstm32] ist derzeit auch eine Open-Source Alternative (GPL, Version 3 oder höher) zur ST Library in Entwicklung.&lt;br /&gt;
&lt;br /&gt;
== CMSIS ==&lt;br /&gt;
&lt;br /&gt;
Parallel zur Firmware-Library gibt es für die &amp;quot;Selbermacher&amp;quot; die CMSIS, die einen Teil der HW und den Core Support abdeckt.&lt;br /&gt;
Im Rahmen des CMSIS-Standards ([http://www.onARM.com www.onARM.com]) wurden die Headerdateien standardisiert, der Zugriff auf die Register erfolgt per &#039;&#039;&#039;Peripheral-&amp;gt;Register&#039;&#039;&#039;. Weiterhin existieren eine Zahl von Helferfunktionen für den NVIC, den Sys-Tick-Counter, sowie eine SystemInit-Funktion, welche sich um die PLL kümmert.&lt;br /&gt;
&lt;br /&gt;
Die CMSIS ist im Download der FW-Lib enthalten.&lt;br /&gt;
&lt;br /&gt;
== Debug-Interface ==&lt;br /&gt;
&lt;br /&gt;
Als Debug Interface stehen zwei Varianten zur Auswahl:&lt;br /&gt;
* [[JTAG]]&lt;br /&gt;
* SWD (Serial Wire Debug)&lt;br /&gt;
&lt;br /&gt;
Für JTAG sind 6 Steuerleitungen nötig, für SWD 2 (zzgl GND/3,3V).&lt;br /&gt;
Die SWD Schnittstelle verfügt außerdem über eine weitere Leitung, SWO. Über diesen Kanal kann ein vereinfachtes Trace des Core ermöglicht werden, sowie &amp;quot;printf-ähnlich&amp;quot; Daten über den ITM Channel 0 geschickt und im Debugger ausgegeben werden.&lt;br /&gt;
&lt;br /&gt;
Die Coresight-Debug-Architektur ermöglicht ein nicht-invasives Debugging, d.h. es können während des Betriebes ohne Beeinflussung des Prozessors Daten vom Speicher gelesen und in selbigen geschrieben werden.&lt;br /&gt;
&lt;br /&gt;
Standard-JTAG Steckerbelegungen: http://www.keil.com/support/man/docs/ulink2/ulink2_hw_connectors.htm&lt;br /&gt;
&lt;br /&gt;
=== Der 10polige JTAG-Stecker von mmvisual ===&lt;br /&gt;
mmvisual hat mit dieser Steckerbelegung die Standard JTAG Schnittstelle erweitert:&lt;br /&gt;
&lt;br /&gt;
Ich habe diesen Part in den Artikel [http://www.mikrocontroller.net/articles/JTAG#Der_10-Polige_JTAG_Stecker_von_mmvisual JTAG] verschoben.&lt;br /&gt;
Hinzu gekommen ist die Adapterplatine 10-Polig auf Standard JTAG 20 Polig mit TTL/V24 Wandler. [http://www.mikrocontroller.net/articles/JTAG#Die_Adapterplatine Siehe hier.]&lt;br /&gt;
&lt;br /&gt;
=== STM32 RS232 Programmiertool ===&lt;br /&gt;
&lt;br /&gt;
Auch ohne JTAG lässt sich ein STM32 über RS232 programmieren. 3 zusätzliche Verbindungen müssen auf dem Board gepatcht werden. Für einen Test geht es auch mit Tastern für RESET und BOOT0.&amp;lt;br&amp;gt;&lt;br /&gt;
RESET=RTS (L-aktiv)&amp;lt;br&amp;gt;&lt;br /&gt;
BOOT0=DTR (H-aktiv)&amp;lt;br&amp;gt;&lt;br /&gt;
BOOT1=LOW&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Details sind hier im Forum: [http://www.mikrocontroller.net/topic/141711 STM32 Programmiertool]&lt;br /&gt;
&lt;br /&gt;
== Vorteile ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Vorteile gegenüber ARM7:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Interrupt-Controller jetzt Teil des Prozessors (als Core Peripheral), die Vector Table ist jetzt eine echte Vektortabelle, keine Sprungliste wie bei ARM7). Durch Automatismen zwischen Core und NVIC (auto register save r0..r3, lr, sp, pc) bei Interrupt Entry wird eine deutlich schnellere Ausführungszeit bei Interrupts erreicht. Der Interrupt Code muss sich nicht mehr selbst um die Sicherung der o.g. Register kümmern und eine besondere Konfiguration der Handler im Compiler entfällt. Sind vor Beendigung einer ISR (d.h. Rücksprung zum User Code) weitere Interrupts pending, so werden diese ausgeführt, ohne dass eine komplette pop-push-sequenz der Register notwendig ist. Schön beschrieben ist es hier im [http://www.st.com/mcu/files/mcu/1221142709.pdf Insider&#039;s Guide] unter 2.4.5 / Seite 20.&lt;br /&gt;
* Thumb-2 Befehlssatz, deutlich schneller als Thumb-1 und ebenso kompakt&lt;br /&gt;
* Weniger Pins für Debugging benötigt durch SWD&lt;br /&gt;
* Mehr Hardware Breakpoints machen debuggen einfacher&lt;br /&gt;
* Software ist einfacher weil die Umschaltung zwischen ARM Mode und Thumb Mode wegfällt&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Vorteile gegenüber LPC1700 und LPC1300:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Flexiblere Gehäuseformen mit mehr Peripherie bei kleinen Gehäusen&lt;br /&gt;
* FW-Lib für alle STM32 gleich, alle AppNotes/Demos beziehen sich auf diese eine FW-Lib was die Entwicklung der eigenen Applikation sehr beschleunigt.&lt;br /&gt;
* Genauerer und flexiblerer ADC, insbesondere gegenüber LPC1300&lt;br /&gt;
* Flexiblere Varianten der Peripherie &amp;gt;&amp;gt; bei weniger einen deutlichen Preisvorteil&lt;br /&gt;
* ab 0,85 EUR (Stand 2010) Allerdings gibts den LPC1100 mit Cortex-M0 schon ab 0,65 $!&lt;br /&gt;
&#039;&#039;&#039;Nachteil gegenüber LPC1700:&#039;&#039;&#039;&lt;br /&gt;
* STM32F1xx: nur 72 MHz statt 100 MHz (LPC1759: 120 MHz) Taktfrequenz; STM32F2xx hat diesen Nachteil nicht (ebenfalls 120MHz) (Aber NXP hat schon 150MHz angekündigt)&lt;br /&gt;
* Der LPC1700 besitzt deutlich mehr Mechanismen, um die Auswirkung der Waitstates des Flash-ROMs auf Code- und Datenzugriffe zu reduzieren und das bedeutet mehr Performance bei gleicher Taktfrequenz. Beim STM32F2 entfällt dieser Nachteil wohl aufgrund des ART accelerators. &lt;br /&gt;
* Alle LPC1xxx haben 32 Bit Timer. Bei den STM32 haben das nur die STM32F2xx (2 Stück)&lt;br /&gt;
* I2S Einheit von ST hat keinen FIFO und im 24/32Bit Modus müssen 2x16Bit Halbwörter übertragen werden.&lt;br /&gt;
&#039;&#039;&#039;Vorteile gegenüber anderen &amp;quot;Kleinen&amp;quot; wie z.B. PIC, Atmel usw.&#039;&#039;&#039;&lt;br /&gt;
* nahezu gleicher Preis bei Hobby Anwendungen&lt;br /&gt;
* 32 Bit ohne Umwege in Assembler rechenbar&lt;br /&gt;
* bessere Peripherie&lt;br /&gt;
* ... und weitere 1000 Punkte ...&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Nachteil für Hobby-Anwender&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Nicht direkt &amp;quot;Steckbrettauglich&amp;quot;, da kein DIL Gehäuse verfügbar. Der ebay-Shop dipmicro führt jedoch sehr günstige Lötadapter für Umsetzung von LQFP48 auf DIP48. QFP64 in 0.5mm Pinabstabd und nicht 0.8mm wie AVR&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== HW-Beschaltung ==&lt;br /&gt;
&lt;br /&gt;
Der STM32 benötigt für den Betrieb nur (Minimalbeschaltung):&lt;br /&gt;
&lt;br /&gt;
* VCC 2..3,3V (je nach Typ)&lt;br /&gt;
* AVCC 2..3,3V (sehr wichtig, der STM32 lässt sich ohne diese Spannung nicht programmieren)&lt;br /&gt;
* GND&lt;br /&gt;
* Reset Pin 100nF nach GND (ein Pull-Up Widerstand von ca. 40k ist intern vorhanden)&lt;br /&gt;
* Boot-Pin(s)&lt;br /&gt;
&lt;br /&gt;
ansonsten nur ein paar einzelne C&#039;s 100nF an VCC/GND.&lt;br /&gt;
&lt;br /&gt;
Um Programmieren zu können werden noch die serielle Schnittstelle oder JTAG oder die SWD Pins benötigt.&lt;br /&gt;
&lt;br /&gt;
== Programmierung ==&lt;br /&gt;
&lt;br /&gt;
Als Programmieroberfläche kann eine kostenlose Struktur verwendet werden. Es ist für den Einsteiger schwierig herauszufinden welche Open-Source Programme man braucht damit es funktioniert, daher hier eine Zusammenstellung:&lt;br /&gt;
&lt;br /&gt;
* [http://www.eclipse.org Eclipse]&lt;br /&gt;
* [http://www.yagarto.de Yagarto Tools] oder [http://www.codesourcery.com/sgpp/lite_edition.html Codesourcery Light]&lt;br /&gt;
* Programmieradapter OpenOCD oder andere JTAG Programmieradapter &lt;br /&gt;
* Eclipse Plugin &amp;quot;GDB Hardware Debugging&amp;quot;&lt;br /&gt;
* [http://www.st.com/internet/com/software/ides_mcu.jsp#stm32 ST Liste: IDEs, Toolsets and Debug tools for MCUs]&lt;br /&gt;
&lt;br /&gt;
* Zum Starten eine fertige Zusammenstellung: [http://www.mikrocontroller.net/topic/216554 Eclipse+codesourcery+st-link]&lt;br /&gt;
&lt;br /&gt;
* [http://www.coocox.org/ Coocox Eclipse IDE] kostenlose IDE für Cortex M0/M3. Hilfreiche Infos gibt es im [http://www.mikrocontroller.net/topic/214719?goto=new#2228482 hier] und [http://www.mikrocontroller.net/topic/214719?goto=new#2229943 hier] Forum&lt;br /&gt;
&lt;br /&gt;
Sehr nützlich für Linux-Anwender auch diese Seite: [http://fun-tech.se/stm32/index.php STM32/ARM Cortex-M3 HOWTO: Development under Ubuntu.]&lt;br /&gt;
&lt;br /&gt;
Folgende kommerzielle Umgebungen sind verfügbar:&lt;br /&gt;
&lt;br /&gt;
* [http://www.keil.com Keil µVision] (Demo max. 32KB Code): Die sehr komfortable µVison IDE ist neben dem ARM Compiler per Menue auch für einen beliebigen GNU-Compiler konfigurierbar. Damit besteht das 32k-Limit nur noch für den integrierten Debugger / Simulator. µVison selbst kann kostenlos mit dem MDK-Evaluationkit heruntergeladen werden.&lt;br /&gt;
* [http://www.iar.com IAR] (Demo max. 32KB Code)&lt;br /&gt;
* [http://www.raisonance.com Raisonance Ride7] (GCC Compiler, kostenlose Version auf Debugging von max. 32KB Code limitiert, keine Limitierung beim Complilieren)&lt;br /&gt;
* [http://www.atollic.com Atollic] (Lite Version ohne Code-Limit, auf GCC basierend)&lt;br /&gt;
* [http://www.coocox.org CoIDE] (Kostenlose GCC, Eclipse basierende IDE mit einem Code-Generator Tool)&lt;br /&gt;
* [http://www.rowley.co.uk/arm/ Rowley Crossworks] (Demo 30 Tage unbeschränkt, 150$ für nichtkommerzielle Nutzung, auf GCC basierend)&lt;br /&gt;
* [http://www.code-red-tech.com Code Red] (GCC basierend)&lt;br /&gt;
&lt;br /&gt;
Programmieradapter&lt;br /&gt;
* [http://www.segger.com J-Link / J-Trace] Cortex-M3, als [http://www.segger.com/cms/j-link-edu.html NonComercial] J-Link für ca. 60,- zu haben, läuft in µVision, IAR, gdb&lt;br /&gt;
* [http://olimex.com/dev/index.html Olimex] ARM-USB-OCD (ca. 60.-)&lt;br /&gt;
* Keil [http://www.keil.com/arm/ulink2/ ULINK2], [http://www.keil.com/arm/ulinkpro/ ULINK pro]&lt;br /&gt;
* [http://www.st.com/internet/evalboard/product/219866.jsp ST-LINK], [http://www.st.com/internet/evalboard/product/251168.jsp ST-LINK/V2]&lt;br /&gt;
* [http://www.raisonance.com/~rlink-debugger-programmer__microcontrollers__tool~tool__T018:4cn9ziz4bnx6.html Raisonance RLink]&lt;br /&gt;
* [http://www.amontec.com Amontec]&lt;br /&gt;
* [http://www.hjtag.com H-JTAG] Personal Edition für ca. 60,- zu haben, läuft mit ADS, SDT, IAR, Vision und RVDS &lt;br /&gt;
&lt;br /&gt;
Programmieradapter Open-Source&lt;br /&gt;
* [http://www.oocdlink.com/ OOCDLink]&lt;br /&gt;
* [http://www.randomprojects.org/wiki/Floss-JTAG FLOSS-JTAG]&lt;br /&gt;
* [http://capitanio.org/mlink/ Linux Demo Code für die Discovery&#039;s ST-Link Programmierung]&lt;br /&gt;
&lt;br /&gt;
Der Controller hat auch einen fest eingebauten Boot-Lader. Damit läßt er sich auch über eine gewöhnliche serielle Schnittstelle programmieren, ohne daß man einen JTAG-Adapter benötigt.&lt;br /&gt;
&lt;br /&gt;
Tipps für Installation mit Eclipse können in [http://www.mikrocontroller.net/topic/214719 diesem Thread] gelesen werden.&lt;br /&gt;
&lt;br /&gt;
=== Installation für STM32 ===&lt;br /&gt;
&lt;br /&gt;
Hier ist der Anfang des Artikels [[STM32 Eclipse Installation]], hier ist neueres beschrieben als hier aufgeführt. Wenn der Artikel fertig ist, dann wird dieser Teil gelöscht.&lt;br /&gt;
&lt;br /&gt;
* Eclipse &amp;quot;Helios&amp;quot; installieren mit GNU ARM Eclipse Plug-in&lt;br /&gt;
Eclipse IDE for C/C++ Developers&amp;lt;ref&amp;gt;http://www.eclipse.org/downloads/packages/eclipse-ide-cc-developers/heliosr&amp;lt;/ref&amp;gt; downloaden und installieren&lt;br /&gt;
&lt;br /&gt;
* GNU ARM Eclipse Plug-in&amp;lt;ref&amp;gt;http://sourceforge.net/projects/gnuarmeclipse/&amp;lt;/ref&amp;gt; runterladen und installieren. [http://sourceforge.net/apps/mediawiki/gnuarmeclipse/index.php?title=Main_Page Weitere Infos].&lt;br /&gt;
&lt;br /&gt;
Wird CodeSourcery G++ Lite verwendet, so muss die PATH Variable angepasst &lt;br /&gt;
werden, damit das Plugin die CodeSourcery exe-Files findet&amp;lt;ref&amp;gt;für Discovery notwendig&amp;lt;/ref&amp;gt;. Alternativ das eclipse von einem script aus starten und zuerst den PATH erweitern.&lt;br /&gt;
&lt;br /&gt;
Soll das ST-LINK verwendet werden, so kann der Atollic ST-LINK GDBSERVER aus der Atollic free version genutzt werden. Mit dem gdbserver im eclipse kann damit problemlos geflasht und gedebuggt werden (JTAG und SWD). Die Startup- und Linkerscripts der Atollic free version können für ein Projekt in dieser Konstallation genutzt werden.&lt;br /&gt;
&lt;br /&gt;
* Eclipse &amp;quot;Galileo&amp;quot; installation&amp;lt;ref&amp;gt;[http://www.eclipse.org/] → Downloads → &amp;quot;Eclipse IDE for C/C++ Developers (79 MB)&amp;lt;/ref&amp;gt;. Und das Servicepack 1&amp;lt;ref&amp;gt;[http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/galileo/SR1/eclipse-cpp-galileo-SR1-win32.zip Eclipse SR1]&amp;lt;/ref&amp;gt;&lt;br /&gt;
Entpacken der Datei eclipse-cpp-galileo-SR1-win32.zip nach &amp;quot;C:\WinARM\&amp;quot; (Ordner neu erstellen)&lt;br /&gt;
&lt;br /&gt;
* Eclipse PlugIn&amp;lt;ref&amp;gt;http://download.eclipse.org/tools/cdt/releases/galileo&amp;lt;/ref&amp;gt; hinzufügen: Help → Install New Software... → &amp;quot;Eclipse C/C++ Development Tools&amp;quot; + &amp;quot;Eclipse C/C++ GDB Hardware Debugging&amp;quot; installieren&lt;br /&gt;
&lt;br /&gt;
* Yagarto Tools&amp;lt;ref&amp;gt;[http://www.yagarto.de/] &amp;quot;Download (for Windows)&amp;quot; → &amp;quot;YAGARTO Tools&amp;quot; http://www.yagarto.de/download/yagarto/yagarto-tools-20091223-setup.exe Installieren, Auswahl Verzeichnis &amp;quot;C:\WinARM\yagarto-tools&amp;quot;&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CodeSourcery: Achtung! Die Menustruktur ändert sich durchaus mal, dann suchen gehen. http://www.codesourcery.com/ → Products → Sourcery G++ → Editions&amp;gt;Lite Edition → ARM → Downloads. Direkter Download&amp;lt;ref&amp;gt;[http://www.codesourcery.com/sgpp/lite/arm/portal/package6496/public/arm-none-eabi/arm-2010q1-188-arm-none-eabi.exe]&amp;lt;/ref&amp;gt;. Installieren, Auswahl Verzeichnis &amp;quot;C:\WinARM\CodeSourcery&amp;quot;&lt;br /&gt;
&lt;br /&gt;
* OpenOCD: Kompilierte Version für Windows&amp;lt;ref&amp;gt;[http://www.freddiechopin.info/] → Download → Software → OpenOCD&amp;lt;/ref&amp;gt; installieren nach &amp;quot;C:\WinARM\OpenOCD_0_4_0&amp;quot; ist auch auf der Seite&amp;lt;ref&amp;gt;[http://yagarto.de/#ocd Yagarto.de]&amp;lt;/ref&amp;gt; beschrieben. PS: Sollte der Olimex ARM-USB-OCD verwendet werden, dann darf nicht der Treiber von Olimex verwendet werden, sondern der vom OpenOCD Download&amp;lt;ref&amp;gt;[http://www.mikrocontroller.net/topic/173753#1668913]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* ST Firmware: http://www.st.com → Auswahl CPU STM32F103xxx → &amp;quot;Firmware&amp;quot; &amp;quot;STM32F10x_StdPeriph_Lib&amp;quot;&amp;lt;ref&amp;gt;http://www.st.com/mcu/devicedocs-STM32F103RC-110.html&amp;lt;/ref&amp;gt;. Das ZIP &amp;quot;stm32f10x_stdperiph_lib.zip&amp;quot; Entpacken nach &amp;quot;C:\WinARM\examples\stm32_FW3.4.0\&lt;br /&gt;
&lt;br /&gt;
=== Installation für STM32 auf einem zweiten Rechner===&lt;br /&gt;
&lt;br /&gt;
* Kopieren des Verzeichnisses C:\WinARM\ (Zuvor wurden aus diesem Grund alle Setup-Pakete nach C:\WinARM\... installiert)&lt;br /&gt;
* Die PATH-Variable in der Systemsteuerung mit den C:\WinARM\.... Verzeichnissen nachführen&lt;br /&gt;
* Fertig.&lt;br /&gt;
&lt;br /&gt;
=== Installation für STM32 mit AtollicTrueStudio (+Demo) ===&lt;br /&gt;
* Installation + Demo: [[STM32 LEDBlinken AtollicTrueStudio]]&lt;br /&gt;
&lt;br /&gt;
== Demo-Projekte ==&lt;br /&gt;
&lt;br /&gt;
* [[prog_bsp_timer_1_timer2|Programmbeispiel für die Verwendung von Timer2 zusammen mit dem Interrupt]]&lt;br /&gt;
* [http://www.firefly-power.de/ARM/printf.html Printf() debugging mit minimalem Aufwand]&lt;br /&gt;
* [[STM32_BLDC_Control_with_HALL_Sensor|Programmbeispiel für BLDC Motoransteuerung (Timer 1) mit HALLSensor (Timer 3)]]&lt;br /&gt;
* [[Cortex_M3_OCM3U]]&lt;br /&gt;
* Martin Thomas hat ein umfangreiches Projekt erstellt, in der die Eclipse Einstellungen enthalten sind:&lt;br /&gt;
** [http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/arm_memcards/index.html &amp;quot;ChaN&#039;s FAT-Module with STM32 SPI&amp;quot;]&lt;br /&gt;
* [[STM32 USB-FS-Device Lib]]&lt;br /&gt;
* Modellbau-Sender auf STM32-Basis mit vielen Treibern [http://www.rcos.eu www.rcos.eu]&lt;br /&gt;
&lt;br /&gt;
== Errata, Tipps und Tricks ==&lt;br /&gt;
&lt;br /&gt;
* AD-Wandler PA0: Im Errata steht, dass hier Fehler in der Wandlung entstehen könnten, also einen anderen Pin verwenden.&lt;br /&gt;
* CAN-Bus PD0/PD1: Remap geht erst ab der 100-Pin-Version. Steht im RM0008 unter 9.3.3.: &amp;quot;CAN1 alternate function remapping&amp;quot;. Alle Infos von RM0008 9.3.x sind interessant&lt;br /&gt;
* CAN und USB sind nur bei der &amp;quot;◦Connectivity-Line&amp;quot; gleichzeitig nutzbar. Siehe Datenblätter.&lt;br /&gt;
* Mit internem RC-Oszillator kann die CPU mit maximal 64MHz betrieben werden. Mit einem externen Quarz sind dann 72MHz möglich.&lt;br /&gt;
* Für USB Betrieb muss die CPU mit 48MHz oder 72MHz betrieben werden (bei STM32F1xx).&lt;br /&gt;
* Der Idle Interrupt vom Usart wird zwar ausgelöst, aber nicht vom entsprechenden Statusflag angezeigt&lt;br /&gt;
* Der DMA fängt beim aktivieren immer von vorn an zu zählen, auch wenn er nur kurz angehalten wurde&lt;br /&gt;
* STM32F2xx hat kein Flash Size Register, bei STM32F4xx ist zwar ein flash Size Register beschrieben, kollidiert aber in der Adresse mit einem Anderen Register&lt;br /&gt;
&lt;br /&gt;
=== Tipps für Umsteiger von Atmel/PIC/8051 ===&lt;br /&gt;
* Prozessortakt hat unterschiedliche Taktquellen und eine PLL.&lt;br /&gt;
* Alle Peripheriemodule haben einen extra Clock, den man aktivieren muss.&lt;br /&gt;
* Wenn man z.B. einen UART benutzen möchte, so muss man den Clock vom UART, Alternate Function IO (AFIO) und dem GPIO-Port aktivieren.&lt;br /&gt;
* Ansonsten hat man nahezu doppelt so viele Möglichkeiten in den Peripheriemodulen.&lt;br /&gt;
* Forum zu [http://www.mikrocontroller.net/topic/175888 Interrupts vs. Events]&lt;br /&gt;
&lt;br /&gt;
== Bezugsquellen ==&lt;br /&gt;
&lt;br /&gt;
=== Controller ===&lt;br /&gt;
&lt;br /&gt;
Versandhäuser für Privatpersonen&lt;br /&gt;
&lt;br /&gt;
* [http://darisusgmbh.de/shop/index.php?cat=c2692_ARM-Cortex.html Darisus]&lt;br /&gt;
* [http://www.hbe-shop.de HBE (Farnell Programm für Private)] &lt;br /&gt;
* [http://www.sander-electronic.de/be00069.html Sander]&lt;br /&gt;
* [http://www.tme.eu/de/katalog/index.phtml#cleanParameters%3D1%26search%3DSTM32F10%26bf_szukaj%3D+ TME] &lt;br /&gt;
* [https://www.distrelec.de/ishopWebFront/catalog/product.do/para/keywords/is/STM32_ARM-Microcontroller/and/language/is/de/and/shop/is/DE/and/series/is/1/and/id/is/01/and/node/is/34910.html Distrelec]&lt;br /&gt;
&lt;br /&gt;
Gewerblich liefern natürlich viele wie Farnell, Digikey usw..&lt;br /&gt;
&lt;br /&gt;
=== Evaluation Boards ===&lt;br /&gt;
&lt;br /&gt;
* [http://shop.embedded-projects.net/index.php?module=artikel&amp;amp;action=gruppe&amp;amp;id=14 Im Shop von Embedded Projects]&lt;br /&gt;
* [http://www.watterott.com/de/Boards-Kits/ARM/ARM-Cortex-M3 Cortex M3 bei Watterott]&lt;br /&gt;
* [http://www.raisonance.com/~primer-starter-kits__microcontrollers__tool~tool__T018:4enfvamuxbtp.html Primer und Primer2 von Raisonance]&lt;br /&gt;
* [http://www.sander-electronic.de/es0028.html Sander Electronic]&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/MP32F103-Stick:_Ein_Mini-Mikrocontroller-Board_mit_USB_und_bis_zu_4MB_Datenspeicher Artikel im Wiki, ARM mit USB und 4MB Speicher]&lt;br /&gt;
* [http://www.futurlec.com/STM32_Development_Board.shtml Futurlec Evalboard, ebenso Header-Board]&lt;br /&gt;
* [http://www.propox.com/products/t_174.html Propox, Header-Boards für 103R und 103V sowie Trägerplatine dafür]&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/Cortex_M3_OCM3U Cortex M3 Artikel im Wiki]&lt;br /&gt;
* [http://olimex.com/dev/index.html STM32 bei Olimex]&lt;br /&gt;
* [http://de.farnell.com/jsp/displayProduct.jsp?sku=1824325&amp;amp;action=view&amp;amp;CMP=GRHS-1000962 STM32Discovery bei Farnell] Mikrocontroller Board (STM32F100RBT6B) mit onboard USB-Programming Interface für ca. 12,50€&lt;br /&gt;
* [http://www.de.rs-online.com/web/p/products/7458434/ STM32Discovery bei RS-Components] 14,73 € +MwSt.&lt;br /&gt;
* [http://www.segor.de/#Q=STM32 VL DISCOVERY] STM32 Discovery bei Segor&lt;br /&gt;
* [http://www.steitec.net/ARM-Boards/ Steitec, STM32F103 Cortex M3 Board 34,80€]&lt;br /&gt;
* [http://www.mcu-raisonance.com/~open4-development-platform__microcontrollers__tool~tool__T018:g65gu6ghg2n.html/ Open 4 oder auch genannt Evo-Primer]&lt;br /&gt;
* [http://www.wayengineer.com/index.php?main_page=index&amp;amp;cPath=50_66&amp;amp;page=1&amp;amp;sort=3a WayEngineer]&lt;br /&gt;
&lt;br /&gt;
== Weblinks, Foren, Communities ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/173753 Diskussion zum Artikel]&lt;br /&gt;
* [http://www.mikrocontroller.net/forum/mikrocontroller-elektronik?filter=ARM*+STM32*+Cortex* Suche im Forum]&lt;br /&gt;
* [https://my.st.com/public/STe2ecommunities/mcu/Lists/ARM%20CortexM3%20STM32/AllItems.aspx Forum auf der ST Homepage] &lt;br /&gt;
* [http://www.stm32circle.com/hom/index.php STM32 Community] &lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
[[Kategorie:ARM]]&lt;br /&gt;
[[Kategorie:STM32| ]]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=P89626&amp;diff=62170</id>
		<title>P89626</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=P89626&amp;diff=62170"/>
		<updated>2011-12-03T07:41:42Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: Änderung 62169 von 84.56.17.101 (Diskussion) wurde rückgängig gemacht.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Alles über den [http://www.medion.com/au/service/start/_product.php?msn=50039627&amp;amp;gid=7 MEDION LIFE P89626 (MD 86407) NAS] den es im Dez.2011 bei Aldi-Süd für 99€ gab.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Beitrag im Forum =&lt;br /&gt;
* [https://www.mikrocontroller.net/topic/240238 Alles Rund um den MEDION LIFE P89626 NAS]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/187115#new 20Euro Embedded System mit ARM, 128MB RAM und 256MB Flash ]&lt;br /&gt;
&lt;br /&gt;
extern:&lt;br /&gt;
* http://forums.whirlpool.net.au/archive/1817691&lt;br /&gt;
&lt;br /&gt;
== Technische Daten ==&lt;br /&gt;
&lt;br /&gt;
* Dual Core ARM [http://www.plxtech.com/products/consumer/nas7820 PLX-NAS7820] 750 MHz&lt;br /&gt;
* 128 MB RAM&lt;br /&gt;
* 1.50 TB (1.36 TiB) Seagate Barracuda Green ST1500DL003-9VT1 SATA-HD&lt;br /&gt;
* 2 x USB 2.0&lt;br /&gt;
* 1 x Gigabit LAN (Realtek RTL8211E)&lt;br /&gt;
&lt;br /&gt;
Netzteil:&lt;br /&gt;
* Eingang: 100-240 V, 50/60 Hz,  0,4 A&lt;br /&gt;
* Ausgang: 12 V,  1,5 A Gleichspannung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Demontage ===&lt;br /&gt;
&lt;br /&gt;
Die Demontage und das Wechseln der S-ATA Festplatte ist sehr einfach für Schrauber möglich: Unter den Gummifussflächen sind zwei Schrauben zu lösen, dann kann man das Gehäuse aus zwei Schalen recht einfach auseinander nehmen. Festplatte/Elektronik sind mit weiteren zwei Schrauben vom Gehäusedeckel zu lösen. Festplatte ist mit drei Schrauben an dem Platinenteil befestigt. Alles ohne große Probleme zu lösen und wieder zusammen zu bauen...&lt;br /&gt;
&lt;br /&gt;
Bilder der Platine gibt es u.a. hier:&lt;br /&gt;
* http://flickr.com/photos/jensdiemer/tags/p89626/&lt;br /&gt;
&lt;br /&gt;
sowie hier: [http://i41.tinypic.com/5leazs.jpg], [http://i43.tinypic.com/11qjvgh.jpg], [http://i44.tinypic.com/2nurcr8.jpg], [http://i42.tinypic.com/25tc576.jpg]&lt;br /&gt;
&lt;br /&gt;
==== cpuinfo ====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
~ # cat /proc/cpuinfo &lt;br /&gt;
Processor       : ARMv6-compatible processor rev 5 (v6l)&lt;br /&gt;
processor       : 0&lt;br /&gt;
BogoMIPS        : 299.00&lt;br /&gt;
&lt;br /&gt;
Features        : swp half thumb fastmult edsp java &lt;br /&gt;
CPU implementer : 0x41&lt;br /&gt;
CPU architecture: 7&lt;br /&gt;
CPU variant     : 0x0&lt;br /&gt;
CPU part        : 0xb02&lt;br /&gt;
CPU revision    : 5&lt;br /&gt;
&lt;br /&gt;
Hardware        : Oxsemi NAS&lt;br /&gt;
Revision        : 0000&lt;br /&gt;
Serial          : 0000000000000000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== /proc/modules ====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ntfs 106132 0 - Live 0xbf015000&lt;br /&gt;
gmac 47336 0 - Live 0xbf004000&lt;br /&gt;
mii 6764 1 gmac, Live 0xbf000000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== mtd ====&lt;br /&gt;
&amp;lt;pre&amp;gt;~ # cat /proc/mtd &lt;br /&gt;
dev:    size   erasesize  name&lt;br /&gt;
mtd0: 08000000 00020000 &amp;quot;NAND 128MiB 3,3V 8-bit&amp;quot;&lt;br /&gt;
mtd1: 00040000 00020000 &amp;quot;stage1&amp;quot;&lt;br /&gt;
mtd2: 00380000 00020000 &amp;quot;uboot&amp;quot;&lt;br /&gt;
mtd3: 00080000 00020000 &amp;quot;uboot_env&amp;quot;&lt;br /&gt;
mtd4: 00a00000 00020000 &amp;quot;kernel&amp;quot;&lt;br /&gt;
mtd5: 00a00000 00020000 &amp;quot;etc&amp;quot;&lt;br /&gt;
mtd6: 00a00000 00020000 &amp;quot;info&amp;quot;&lt;br /&gt;
mtd7: 05dc0000 00020000 &amp;quot;sysdisk&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Speicher info ====&lt;br /&gt;
&amp;lt;pre&amp;gt;~ # mount&lt;br /&gt;
rootfs on / type rootfs (rw)&lt;br /&gt;
/proc on /proc type proc (rw,relatime)&lt;br /&gt;
/sys on /sys type sysfs (rw,relatime)&lt;br /&gt;
none on /proc/bus/usb type usbfs (rw,relatime)&lt;br /&gt;
devpts on /dev/pts type devpts (rw,relatime,mode=600)&lt;br /&gt;
/dev/mtdblock6 on /zyxel/mnt/info type yaffs2 (ro,relatime)&lt;br /&gt;
/dev/mtdblock7 on /zyxel/mnt/sysdisk type yaffs2 (ro,relatime)&lt;br /&gt;
/dev/loop0 on /ram_bin type ext2 (ro,relatime,errors=continue)&lt;br /&gt;
/dev/loop0 on /usr type ext2 (ro,relatime,errors=continue)&lt;br /&gt;
/dev/loop0 on /lib/security type ext2 (ro,relatime,errors=continue)&lt;br /&gt;
/dev/loop0 on /lib/modules type ext2 (ro,relatime,errors=continue)&lt;br /&gt;
/dev/ram0 on /tmp/tmpfs type tmpfs (rw,relatime,size=5120k)&lt;br /&gt;
/dev/ram0 on /usr/local/etc type tmpfs (rw,relatime,size=5120k)&lt;br /&gt;
/dev/ram0 on /usr/local/var type tmpfs (rw,relatime,size=5120k)&lt;br /&gt;
/dev/mtdblock5 on /etc/zyxel type yaffs2 (rw,relatime)&lt;br /&gt;
/dev/md4 on /i-data/6764ac2f type xfs (rw,relatime,nouuid,attr2,nobarrier,usrquota)&lt;br /&gt;
/dev/md4 on /usr/local/zy-pkgs type xfs (rw,relatime,nouuid,attr2,nobarrier,usrquota)&lt;br /&gt;
/dev/md4 on /etc/zyxel/zy-pkgs type xfs (rw,relatime,nouuid,attr2,nobarrier,usrquota)&lt;br /&gt;
/dev/md4 on /usr/local/apache/htdocs/adv,/pkg type xfs (rw,relatime,nouuid,attr2,nobarrier,usrquota)&lt;br /&gt;
/dev/md4 on /usr/local/apache/web_framework/data/cache type xfs (rw,relatime,nouuid,attr2,nobarrier,usrquota)&lt;br /&gt;
/dev/mtdblock5 on /usr/local/apache/web_framework/data/config type yaffs2 (rw,relatime)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ursprungszustand:&lt;br /&gt;
&amp;lt;pre&amp;gt;~ # df -h&lt;br /&gt;
Filesystem                Size      Used Available Use% Mounted on&lt;br /&gt;
/dev/mtdblock6           10.0M    804.0K      9.2M   8% /zyxel/mnt/info&lt;br /&gt;
/dev/mtdblock7           93.8M     86.8M      7.0M  93% /zyxel/mnt/sysdisk&lt;br /&gt;
/dev/loop0               83.3M     75.5M      7.8M  91% /ram_bin&lt;br /&gt;
/dev/loop0               83.3M     75.5M      7.8M  91% /usr&lt;br /&gt;
/dev/loop0               83.3M     75.5M      7.8M  91% /lib/security&lt;br /&gt;
/dev/loop0               83.3M     75.5M      7.8M  91% /lib/modules&lt;br /&gt;
/dev/ram0                 5.0M      4.0K      5.0M   0% /tmp/tmpfs&lt;br /&gt;
/dev/ram0                 5.0M      4.0K      5.0M   0% /usr/local/etc&lt;br /&gt;
/dev/ram0                 5.0M      4.0K      5.0M   0% /usr/local/var&lt;br /&gt;
/dev/mtdblock5           10.0M      1.4M      8.6M  14% /etc/zyxel&lt;br /&gt;
/dev/md4                  1.4T    519.0M      1.4T   0% /i-data/6764ac2f&lt;br /&gt;
/dev/md4                  1.4T    519.0M      1.4T   0% /usr/local/zy-pkgs&lt;br /&gt;
/dev/md4                  1.4T    519.0M      1.4T   0% /etc/zyxel/zy-pkgs&lt;br /&gt;
/dev/md4                  1.4T    519.0M      1.4T   0% /usr/local/apache/htdocs/adv,/pkg&lt;br /&gt;
/dev/md4                  1.4T    519.0M      1.4T   0% /usr/local/apache/web_framework/data/cache&lt;br /&gt;
/dev/mtdblock5           10.0M      1.4M      8.6M  14% /usr/local/apache/web_framework/data/config&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Software ===&lt;br /&gt;
&lt;br /&gt;
Installiert ist die Firmware &#039;&#039;&#039;1.00(UZD.2)&#039;&#039;&#039;. Sie basiert offensichtlich auf der Firmware vom &#039;&#039;&#039;Zyxel NSA-210&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;~ # cat /zyxel/mnt/info/fwversion &lt;br /&gt;
1.00(UZD.2)&lt;br /&gt;
~ # cat /zyxel/mnt/info/modelid &lt;br /&gt;
AB03&lt;br /&gt;
~ # cat /zyxel/mnt/info/revision &lt;br /&gt;
32694&lt;br /&gt;
~ # zysh --version&lt;br /&gt;
zysh: version 2.0.0&lt;br /&gt;
Build: 21:37:19 Oct  5 2011&lt;br /&gt;
# cat /etc/Zy_Private &lt;br /&gt;
52103jeenajevol8290i&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;modelid&#039;&#039; &#039;&#039;&#039;AB03&#039;&#039;&#039; steht für &#039;&#039;&#039;STG212&#039;&#039;&#039; (siehe /etc/init.d/rcS)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Linux nas-server 2.6.31.14_SMP_820 #2 SMP Wed Oct 5 21:54:14 CST 2011 armv6l GNU/Linux&lt;br /&gt;
* cat /proc/version: Linux version 2.6.31.14_SMP_820 (root@Neo) (gcc version 4.3.2 (crosstool-NG-1.8.0) ) #2 SMP Wed Oct 5 21:54:14 CST 2011&lt;br /&gt;
* BusyBox v1.17.2&lt;br /&gt;
&lt;br /&gt;
==== Paketverwaltung ====&lt;br /&gt;
Pakete und Updates der Firmware werden von &#039;&#039;&#039;download.medion.de&#039;&#039;&#039; gezogen. &lt;br /&gt;
&lt;br /&gt;
Pakete werden per &#039;&#039;&#039;ipkg v0.99.163&#039;&#039;&#039; (/usr/bin/ipkg-cl) installiert und landen auf der Festplatte unter &#039;&#039;&#039;/i-data/md0/admin/package/&#039;&#039;&#039; Dies ist anscheinend in der Datei &#039;&#039;&#039;/etc/zyxel/zy-pkg.conf&#039;&#039;&#039; festgelegt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
~ # ipkg-cl print_architecture&lt;br /&gt;
arch all 1&lt;br /&gt;
arch noarch 1&lt;br /&gt;
arch arm 10&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Konfiguration ====&lt;br /&gt;
&lt;br /&gt;
Die meiste Konfigurationen (u.a. Name des NAS, existierende User und Freigaben) findet hier wieder:&lt;br /&gt;
* &#039;&#039;&#039;/etc/zyxel/conf/startup-config.conf&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==== environment ====&lt;br /&gt;
&amp;lt;pre&amp;gt;/ # env&lt;br /&gt;
USER=root&lt;br /&gt;
LD_LIBRARY_PATH=/usr/local/zy-pkgs/lib&lt;br /&gt;
OLDPWD=/usr/local/apache/cgi-bin&lt;br /&gt;
HOME=/root&lt;br /&gt;
LOGNAME=root&lt;br /&gt;
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/zyxel/sbin:/usr/local/zy-pkgs/bin:/zyxel/htp&lt;br /&gt;
SHELL=/bin/sh&lt;br /&gt;
PWD=/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== interessante Dateien/Pfade ====&lt;br /&gt;
&lt;br /&gt;
NAS Speicher:&lt;br /&gt;
* &#039;&#039;&#039;/i-data/md0/&#039;&#039;&#039;&lt;br /&gt;
** &#039;&#039;&#039;/i-data/md0/public&#039;&#039;&#039;&lt;br /&gt;
** &#039;&#039;&#039;/i-data/md0/photo&#039;&#039;&#039;&lt;br /&gt;
** &#039;&#039;&#039;/i-data/md0/music&#039;&#039;&#039;&lt;br /&gt;
** usw.&lt;br /&gt;
&lt;br /&gt;
Allgemeine Konfiguration:&lt;br /&gt;
* /etc/init.d/rcS - System-Start-Skript&lt;br /&gt;
* &#039;&#039;&#039;/usr/local/btn/&#039;&#039;&#039; Spezielle Steuerungs-Skripte&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Apache:&#039;&#039;&#039;&lt;br /&gt;
* /etc/service_conf/httpd.conf&lt;br /&gt;
* /etc/service_conf/httpd_zld.conf&lt;br /&gt;
* /etc/service_conf/httpd_special.conf&lt;br /&gt;
* /usr/local/apache/htdocs&lt;br /&gt;
* /usr/local/apache/cgi-bin&lt;br /&gt;
&lt;br /&gt;
=== Aufspüren ===&lt;br /&gt;
&lt;br /&gt;
Die Box bezieht sich vom vorhandenen DHCP Server eine IP. Meldet sich mit dem Namen &#039;&#039;&#039;nas-server&#039;&#039;&#039;. Somit sollte ein &#039;&#039;&#039;ping nas-server&#039;&#039;&#039; gehen und die IP ausspucken.&lt;br /&gt;
&lt;br /&gt;
Zum Aufspüren kann man auch nmap benutzten. z.B. das ganze Subnetz scannen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;~$ sudo nmap -e eth1 -sP 169.254.xxx.0/24&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dienste ===&lt;br /&gt;
&lt;br /&gt;
Auf der Box laufen einige Dienste im Ursprungszustand:&lt;br /&gt;
&amp;lt;pre&amp;gt;~$ nmap -sT nas-server&lt;br /&gt;
&lt;br /&gt;
PORT      STATE SERVICE&lt;br /&gt;
21/tcp   open  ftp&lt;br /&gt;
80/tcp   open  http&lt;br /&gt;
139/tcp  open  netbios-ssn&lt;br /&gt;
443/tcp  open  https&lt;br /&gt;
631/tcp  open  ipp&lt;br /&gt;
3689/tcp open  rendezvous&lt;br /&gt;
8082/tcp open  blackice-alerts&lt;br /&gt;
9001/tcp open  tor-orport&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dienste:&lt;br /&gt;
* Port 21 - &#039;&#039;&#039;pure-ftpd v1.0.21&#039;&#039;&#039;&lt;br /&gt;
* Port 80 und 8082 - &#039;&#039;&#039;Apache/2.2.9 (Unix) mod_ssl/2.2.9 OpenSSL/0.9.8o mod_wsgi/2.4 Python/2.6.2&#039;&#039;&#039;&lt;br /&gt;
* Port 139 - &#039;&#039;&#039;Samba v3.0.32&#039;&#039;&#039;&lt;br /&gt;
* Port 3689 - &#039;&#039;&#039;mt-daapd: 0.2.4.2&#039;&#039;&#039; &lt;br /&gt;
* Port 9001 - DLNA-Server &#039;&#039;&#039;Twonky Media 5.1.13&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==== Einfacher Web Server ====&lt;br /&gt;
Html-Dateien, die man im Verzeichnis &amp;lt;pre&amp;gt;/usr/local/apache/htdocs/adv,/pkg&amp;lt;/pre&amp;gt; ablegt, können im Browser über &amp;lt;pre&amp;gt;http://nas-server/r32694,/adv,/pkg/&amp;lt;/pre&amp;gt; angezeigt werden. Geht auch secure mit https. Mit entsprechender Port-Freigabe kann man zumindest eine statische Web Site aufbauen.&lt;br /&gt;
&lt;br /&gt;
Die Verzeichnisse unter &amp;lt;pre&amp;gt;/usr/local/apache&amp;lt;/pre&amp;gt; scheinen im nicht beschreibbaren Bereich zu liegen. &amp;lt;pre&amp;gt;/usr/local/apache/htdocs/adv,/pkg&amp;lt;/pre&amp;gt; ist  auf einen beschreibbaren Bereich gemappt.&lt;br /&gt;
&lt;br /&gt;
=== Zugang ===&lt;br /&gt;
&lt;br /&gt;
Wie bei vielen NAS läuft auch hier ein WebServer. Es gibt den User &#039;&#039;&#039;admin&#039;&#039;&#039; mit Passwort &#039;&#039;&#039;1234&#039;&#039;&#039; mit dem man sich einloggen kann.&lt;br /&gt;
&lt;br /&gt;
==== Telnet ====&lt;br /&gt;
&lt;br /&gt;
Telnet kann man mit dieser URL starten (Wichtig ist, dass man sich vorher normal eingeloggt hat!):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;http://nas-server/r32694,/adv,/cgi-bin/remote_help-cgi?type=backdoor&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
bzw.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;http://192.168.xxx.yyy/r32694,/adv,/cgi-bin/remote_help-cgi?type=backdoor&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Per Telnet kann man sich mit &#039;&#039;&#039;root&#039;&#039;&#039; Passwort &#039;&#039;&#039;1234&#039;&#039;&#039; (bzw. das Passwort vom User &#039;&#039;&#039;admin&#039;&#039;&#039;) verbinden.&lt;br /&gt;
&lt;br /&gt;
Nach einem Reboot ist Telnet allerdings wieder aus!&lt;br /&gt;
&lt;br /&gt;
===== Dateien editieren =====&lt;br /&gt;
&lt;br /&gt;
Möchte man Dateien bequem editieren kann man sie über smb zugänglich machen z. B. mit: &#039;&#039;&#039;ln -s /etc /i-data/md0/admin/&#039;&#039;&#039; auf die &#039;admin&#039; Freigabe.&lt;br /&gt;
&lt;br /&gt;
===== Hintergrund =====&lt;br /&gt;
&lt;br /&gt;
Für das Starten von Telnet sind diese Dateien zuständig:&lt;br /&gt;
* /usr/local/apache/cgi-bin/remote_help-cgi&lt;br /&gt;
* /usr/local/btn/open_back_door.sh&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:ARM-Boards]]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Linksammlung&amp;diff=61975</id>
		<title>Linksammlung</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Linksammlung&amp;diff=61975"/>
		<updated>2011-11-27T09:16:24Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: Rückgängig gemacht auf Version vom 16:58, 23. Nov. 2011&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Auf dieser Seite werden Links zu anderen interessanten Mikrocontroller- und Elektronikseiten gesammelt.&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
Die alte Linkseite findet man [http://www.mikrocontroller.net/en/links hier].&lt;br /&gt;
&lt;br /&gt;
Hinzufügen von Links:&lt;br /&gt;
# [http://www.mikrocontroller.net/wikisoftware/index.php?title=Linksammlung&amp;amp;action=edit Bearbeiten] anklicken&lt;br /&gt;
# Link unter der entsprechenden Kategorie eintragen&lt;br /&gt;
# &amp;quot;Artikel speichern&amp;quot; klicken&lt;br /&gt;
&lt;br /&gt;
== Suchen &amp;amp; Finden ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Verkauf einem hungrigen Mann einen Fisch und du hast ein Geschäft gemacht, bring ihm das Angeln bei und du hast einen Kunden verloren! (asmo)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* [http://www.supplyframe.com/ SupplyFrame] - Datasheet and Electronic Spec Search Engine&lt;br /&gt;
* [http://www.globalspec.com/ GlobalSpec] - The Engineering Search Engine&lt;br /&gt;
* [http://www.alldatasheet.com/ alldatasheet] - Datasheet Search&lt;br /&gt;
* [http://www.datasheetarchive.com/ datasheetarchive] - Datasheet Search&lt;br /&gt;
* [http://www.datasheetcatalog.com/ datasheetcatalog] - Datasheet Search&lt;br /&gt;
* [http://www.msarnoff.org/chipdb/ ChipDB] - Pinouts von gängigen µCs.&lt;br /&gt;
&amp;lt;!-- SPAM&lt;br /&gt;
* [http://www.TechTour.net] - Angebote und Technische Beratung von mehreren Anbietern gleichzeitig einholen. Von der Elektronik Entwicklung über Leiterplatten Bestückung, von Leiterplatten über Folientastaturen, Gehäusen bis zur Kabelkonfektion.&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== [[AVR]] ==&lt;br /&gt;
&lt;br /&gt;
=== Herstellerseiten ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.atmel.com/products/avr/ Atmel.com] Herstellerseiten&lt;br /&gt;
* [http://www.atmel.com/dyn/products/product_whatchanged.asp?category_id=163&amp;amp;family_id=607 Atmel.com updates] Liste der letzten Änderungen in Datenblättern und Beispielcode für AVR(8) und AVR32&lt;br /&gt;
* [http://www.msc-ge.com/de/produkte/elekom/mc/atmel/avr_start.html AVR Produktinfos] AVR Infos vom Atmel Distributor MSC Vertriebs GmbH&lt;br /&gt;
&lt;br /&gt;
=== Information (Foren, Mailinglisten, Linksammlungen) ===&lt;br /&gt;
* [http://progforum.com Batronix Elektronik Forum] Gut besuchtes Forum für allgemeine Elektronik, Mikrocontroller und Programmierung&lt;br /&gt;
* [http://www.avrfreaks.net/ AVR Freaks] AVR Forum, Samples, Tutorials, User-Projekte, GCC für AVR (Registrierung empfohlen)&lt;br /&gt;
* [http://avr-asm.tripod.com Atmel AVR ASM Site]&lt;br /&gt;
* [http://www.mikrocontroller.net Mikrocontroller.net] - AVR Tutorials, Examples, LINKS, Forum (D)&lt;br /&gt;
&amp;lt;!-- offline 4/2010&lt;br /&gt;
* [http://www.openavr.org/ Openavr.org] &amp;quot;central repository of information for the various open source tools available for the development of software for Atmel&#039;s AVR family of 8-bit RISC microcontrollers&amp;quot;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;!-- offline 4/2010&lt;br /&gt;
* [http://www.omegav.ntnu.no/avr/resources.php3 Omega V&#039;s AVR Resource List]&lt;br /&gt;
* [http://www.omegav.ntnu.no/avr/newresources.php3 Omega V&#039;s AVR NEW Resource List]&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
* [http://www.ipass.net/hammill/newavr.htm Atmel AVR Embedded Microcontroller Resources]&lt;br /&gt;
* [http://members.tripod.com/Stelios_Cellar/AVR/AVR%20Info.html Stelios Cellar Atmel AVR Info Page] - Samples, Links&lt;br /&gt;
* [http://www.elektronik-projekt.de Elektronik Projekt] - Hauptthemen sind AVR und Roboter&lt;br /&gt;
&amp;lt;!-- offline 4/2010&lt;br /&gt;
* [http://www.microschematic.com/ AVR Microcontroller inside] (nett gemacht, Engl. Seite am 07-09-2008 nicht erreichbar)&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;!-- offline 4/2010&lt;br /&gt;
* [http://electrons.psychogenic.com/avr/ Intro To AVR Microcontrollers] (noch(?) sehr wenig Information)&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
* [http://popularmicrocontrollers.com/ AVR Microcontrollers] - A web site about AVR microcontrollers&lt;br /&gt;
&amp;lt;!-- Dieser Unterabschnitt ist für AVR. Für PIC gibt es einen eigenen Unterabschnitt weiter unten. --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Entwicklungswerkzeuge (Compiler/Assembler/Debugger/Tools/Libraries) ===&lt;br /&gt;
&lt;br /&gt;
==== C ====&lt;br /&gt;
* [http://sourceforge.net/projects/winavr WinAVR] (pronounced &amp;quot;whenever&amp;quot;) is a suite of executable, open source software development tools for the Atmel AVR series [for the] Windows platform&amp;quot; (includes GNU GCC) &lt;br /&gt;
* [http://sourceforge.net/projects/kontrollerlab KontrollerLab] is a free GPL open-source development environment based on KDE, using the avr-gcc, UISP and AVRDUDE&lt;br /&gt;
* [http://www.nongnu.org/avr-libc/ avr-libc] avr-gcc&#039;s &amp;quot;standard&amp;quot;-library&lt;br /&gt;
&amp;lt;!-- * [http://hubbard.engr.scu.edu/embedded/avr/avrlib/ Procyon AVRlib] a lot of device drivers and Visual-Studio link for avr-gcc --&amp;gt;&lt;br /&gt;
* [http://hubbard.engr.scu.edu/embedded/avr/avrlib/ Procyon AVRlib] a lot of device drivers and Visual-Studio link for avr-gcc&lt;br /&gt;
* [http://rod.info/avr.html rod.info on AVR] esp. for AVR GNU development tools setup under Linux&lt;br /&gt;
* [http://www.sisy.de SiSy AVR] - graphische Entwicklungsumgebung mit C/C++ Codegenerierung aus Struktogrammen und Klassendiagrammen&lt;br /&gt;
* [http://shop.embedit.de/product__206.php AtmanAVR C/C++ IDE]&lt;br /&gt;
* [http://www.iar.com IAR Embedded Workbench]&lt;br /&gt;
* [http://www.hpinfotech.com CodeVisionAVR] C-Compiler für AVRs mit Terminal&lt;br /&gt;
* [http://www.myAVR.de myAVRWorkpad] kompakte Entwicklungsumgebung für AVRs mit Terminal&lt;br /&gt;
* [http://www.amctools.com/vmlab.htm VMLab] komplette IDE mit Debugger und Simulator (auch Peripheriehardware)&lt;br /&gt;
* [http://www.forestmoon.com/Software/AvrIoDesigner/ AVR IO Designer] is a utility to generate initialization source code in C/C++ for the various devices, ports and registers of Atmel AVR processors. The intent is to allow the user to explore the devices specific to a selected processor and experiment with settings thru a user interface that assists in understanding the complexities involved. The user can also assign custom variable names to PORT IO pins thereby keeping track of the IO resources in use. These names are emitted in the generated code for use in the user’s program. (Windows .NET 2.0 erforderlich)&lt;br /&gt;
* [http://www.piconomic.co.za/avrlib/index.html Piconomic AVRLIB] is a collection of firmware for Atmel AVR microcontrollers. The aim is to share source code, experience and expertise (in the eye of the beholder) with the community of engineers, scientists and enthusiasts.&lt;br /&gt;
* [http://www.imagecraft.com/devtools_AVR.html Imagecraft] Der ICCAVR C Compiler fuer AVR von Imagecraft.&lt;br /&gt;
&lt;br /&gt;
==== Assembler ====&lt;br /&gt;
&lt;br /&gt;
* [http://avr-asm.tripod.com Atmel AVR ASM Site]&lt;br /&gt;
* [http://www.tavrasm.org/ tavrasm] - Toms Linux (Atmel) AVR Assembler&lt;br /&gt;
* [http://www.avr-asm-tutorial.net/gavrasm/index_de.html gavrasm] - Gerds Linux/Win/DOS AVR Assembler &lt;br /&gt;
* [http://avra.sourceforge.net/ avra] - avra ATMEL AVR Assembler für Linux, FreeBSD, AmigaOS und Win32&lt;br /&gt;
* [http://algrom.net/english.html Algorithm Builder] - graphische Makro-Assembler Entwicklungsumgebung&lt;br /&gt;
* [http://www.sisy.de SiSy AVR] - graphische Entwicklungsumgebung mit Assembler Codegenerierung aus Programmablaufplänen&lt;br /&gt;
* [http://www.sbprojects.com/sbasm/sbasm.htm SB-Assembler] - Freeware Cross-Assembler unter DOS. (6502, 6800, 6801, 6804, 6805, 6809, 68HC08, 68HC11, Z8, Z80, Z180, 8080, 8085, 8021, 8041, 8048, 8051, AVR, PIC1684,...)&lt;br /&gt;
* [http://www.myAVR.de myAVRWorkpad] kompakte Entwicklungsumgebung für AVRs mit Terminal&lt;br /&gt;
* [http://john.ccac.rwth-aachen.de:8000/as/ Macro Assembler AS] - AS is a portable macro cross assembler for a variety of microprocessors and -controllers&lt;br /&gt;
* [http://shop-pdp.kent.edu/ashtml/asxxxx.htm ASxxxx Cross Assemblers] - The ASxxxx assemblers are a series of microprocessor assemblers written in the C programming language. (1802, S2650, C/MP, MSP430, 61860, 6500, 6800(6802/6808), 6801(6803/HD6303), 6804, 6805, 68HC(S)08, 6809, 68HC11, 68HC(S)12, 68HC16, 740, 8048(8041/8022/8021) 8051, 8085(8080), DS8xCxxx, AVR, Z80, F2MC8L/FX, GameBoy(Z80), H8/3xx, Cypress PSoC(M8C), PIC, Rabbit 2000/3000, Z8, Z80(HD64180)) linux &amp;amp; windows, source code&lt;br /&gt;
&lt;br /&gt;
==== Disassembler ====&lt;br /&gt;
&lt;br /&gt;
* [http://www.datarescue.com/idabase/ IDA-Pro] -Disassembler und Debugger für fast alle bekannten Prozessoren. Evaluation Version verfügbar. Tagline: &#039;&#039;The most advanced tool for Hostile Code Analysis, Vulnerability and Software Reverse Engineering&#039;&#039;&lt;br /&gt;
* [http://www.jassenbaum.de/ja-tools/ ReAVR] - Disassembler und ACXutility Binary Tool&lt;br /&gt;
* [http://www.visi.com/~dwinker/revava/ revava] - Disassembler&lt;br /&gt;
* [http://dev.frozeneskimo.com/software_projects/vavrdisasm vAVRdisasm] - Free AVR Disassembler&lt;br /&gt;
* [http://www.johannes-bauer.com/mcus/avrdisas/ avrdisas] - AVR Mikrocontroller Disassembler für Linux (und Win32)&lt;br /&gt;
&amp;lt;!-- * [http://biew.sourceforge.net/en/biew.html BVIEW] is multiplatform portable viewer of binary files with built-in editor in binary, hexadecimal and disassembler modes. It includes &#039;&#039;&#039;AVR&#039;&#039;&#039;/Java/i86-i386-AMD64/ARM-XScale/PPC64 disassemblers, russian codepages convertor, full preview of formats - MZ, NE, PE, NLM, coff32, elf partial - a.out, LE, LX, PharLap; code navigator and more over. (GPL) - 404, 6.9.2010 --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== BASIC ====&lt;br /&gt;
* [http://www.mcselec.com/bascom-avr.htm Bascom AVR]&lt;br /&gt;
* [http://www.fastavr.com FastAVR] - und mit &#039;ASM&#039; Ausgabe, Nokia3310 LCD Unterstützung&lt;br /&gt;
* [http://www.nettypes.de/mbasic mikrocontrollerBASIC Freeware] - mit Simulator für ATmega32, ATmega128 und C-CONTROL.&lt;br /&gt;
* [http://www.mikroe.com/en/compilers/mikrobasic/avr/ mikroBasic] - Comprehensive, stand-alone Basic compiler for AVR microcontrollers&lt;br /&gt;
* [http://home.arcor.de/EDAconsult/Page3/index.html?c~3.1 MCS BASIC-52] - Original-Übersetzung 1988 INTEL MCS BASIC-52 USERS MANUAL 220 Seiten frei Download als PDF&lt;br /&gt;
* [http://www.DieProjektseite.de Beetle-Basic] Leistungsfähiges Basic-Betriebssystem im AVR.&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/AVR_BASIC AVR_BASIC] Open Source Freeware: Minimalistischer Basic-Interpreter  im AVR.&lt;br /&gt;
* [http://gcbasic.sourceforge.net/ Great Cow BASIC] &amp;quot;Open Source BASIC programming tools for Microchip PIC and Atmel AVR microcontrollers&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== Pascal ====&lt;br /&gt;
* [http://www.e-lab.de AVRco Pascal Compiler] - AVR Pascal Compiler mit umfangreicher Funktionslibrary&lt;br /&gt;
* [http://www.mikroe.com/en/compilers/mikropascal/avr/ mikroPascal] - Comprehensive, stand-alone Pascal compiler for AVR microcontrollers&lt;br /&gt;
&lt;br /&gt;
==== Forth ====&lt;br /&gt;
* [http://www.robo-forth.de www.robo-forth.de] - AVR Forth Compiler mit umfangreicher Funktionslibrary für Servos, Motore und Sensoren&lt;br /&gt;
* [http://amforth.sourceforge.net/ amforth] - Forth for Atmel ATmega micro controllers von Matthias Trute. [http://www.mikrocontroller.net/topic/55807#430816 Diskussion]&lt;br /&gt;
&lt;br /&gt;
==== Java ====&lt;br /&gt;
* [http://www.harbaum.org/till/nanovm NanoVM] - Java VM für AVR-Mikrocontroller ([[NanoVM|deutsches Wiki]])&lt;br /&gt;
* [http://www.fam-frenz.de/stefan/compiler.html SJC] - Java-Compiler (erzeugt AVR-Maschinencode) für AVR-Mikrocontroller ([[SJC]])&lt;br /&gt;
&lt;br /&gt;
==== Ada ====&lt;br /&gt;
* [http://avr-ada.sourceforge.net/ AVR-Ada] - Ada Compiler innerhalb von GCC (GNAT) für AVR.  Enthält eine kleine Laufzeitbibliothek ohne Tasking und ohne Exceptions. [http://www.mikrocontroller.net/topic/168823#1614208]&lt;br /&gt;
&lt;br /&gt;
==== Virgil ====&lt;br /&gt;
* [http://compilers.cs.ucla.edu/virgil/index.html The Virgil Programming Language] is designed for building robust, flexible, and scalable software systems on embedded hardware platforms. Virgil builds on ideas from object-oriented, statically typed languages like Java, providing a clean, consistent source language. Its compiler system provides an efficient implementation for resource-constrained environments.&lt;br /&gt;
&lt;br /&gt;
==== LabVIEW ====&lt;br /&gt;
* http://www.ni.com/embedded/ Informationen zu LabVIEW, der graphischen Entwicklungsumgebung von National Instruments&lt;br /&gt;
* http://www.labviewforum.de/ Deutsches Labview-Forum&lt;br /&gt;
* [http://web.me.com/iklln6/automation/LabVIEW.html Communicating Arduino--&amp;gt;LabVIEW]&lt;br /&gt;
&lt;br /&gt;
==== Python ====&lt;br /&gt;
* [http://code.google.com/p/python-on-a-chip/ python-on-a-chip] (pymite). There are two sample projects in the source tree.  One for an 8-bit Atmel ATmega103 (but any AVR/ATmega with 4 KB RAM or more will do) and one for the 32-bit Atmel AT91SAM7S64 running on the AT91SAM7S-EK evaluation board. (GPL Lizenz)&lt;br /&gt;
&lt;br /&gt;
==== Openeye ====&lt;br /&gt;
&lt;br /&gt;
* OpenEye ist eine Kombination aus PC-Programm (Windows, Delphi) und einer Monitor-Routine im AVR. Die Daten aus dem AVR werden mit RS232 übertragen und können fürs Debuggen der laufenden Anwendung benutzt werden. OpenEye wurde vom User Martin Vogel (oldmax) geschrieben [http://www.mikrocontroller.net/topic/143144#1326244].&lt;br /&gt;
&lt;br /&gt;
==== Modkit ====&lt;br /&gt;
&lt;br /&gt;
[http://blog.modk.it/ Modkit] is a new kind of graphical programming environment that makes programming things in the physical world as easy as dragging and dropping little virtual code blocks in a web browser.. Heavily inspired by the Scratch programming environment (from MIT Media Lab&#039;s Lifelong Kindergarten Group), Modkit enables anyone including kids, artists and inventors to build with electronic kits and components including motors, sensors, lights, sound and the popular Arduino and Arduino compatible development boards... (Text vom Makezine)&lt;br /&gt;
&lt;br /&gt;
=== Tutorials und Beispiele ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.meinemullemaus.de/elektronik/avr_workshop/index.html AVR Mikrocontroller] Einfühung in AVR Mikrocontroller mit Nachbau des Spiels &amp;quot;Senso&amp;quot;.&lt;br /&gt;
* [http://www.avrbeginners.net AVRBeginners.net] Beginners Guides to AVRs&lt;br /&gt;
* [http://www.wikidorf.de/reintechnisch/Inhalt/AVRProjekt-9V-LED-Lampe reintechnisch.de] AVR Tutorial: 9V-LED-Lampe&lt;br /&gt;
* [http://www.schaltungsforum.de Das Schaltungsforum] ist eine Seite für Anfänger und Profis welche ständig mit Tutorials erweitert wird. Stellt Eure Projekte online. Die Seite befindet noch im Aufbau und Eure Mithilfe ist erwünscht.&lt;br /&gt;
* [http://www.mikrocontrollerspielwiese.de mikrocontrollerspielwiese.de] ist eine Seite, die an Anfänger gerichtet ist und Experimente und fertige Projekte komplett mit Code und Eagle-Dokumenten zur Verfügung stellt.&lt;br /&gt;
* [http://www.elo-web.de/elo/mikrocontroller-und-programmierung/avr-anwendungen ELO-AVR-Anwendungen] bietet eine wachsende Sammlung kleinerer AVR-Projekte, überwiegend für die ATTiny-Serie.&lt;br /&gt;
* [http://www.schramm-software.de/tipps/ AVR-Tipps] Programmier-Tipps und AVR-Experimente.&lt;br /&gt;
* [http://www.uwe-kerwien.de/pll/pll-synthesizer.htm PLL-Synthesizer Tutorial] kleines praxisorientiertes PLL-Tutorial zur Funktion, Reparatur und Steuerung einer PLL-Schaltung mit AVR ATtiny2313 über 3-Leiter-Bus&lt;br /&gt;
* Arduino&lt;br /&gt;
** [http://tronixstuff.wordpress.com/tutorials/ t r o n i x s t u f f] - Arduino Tutorials (engl.)&lt;br /&gt;
** [http://www.earthshinedesign.co.uk/ASKManual/Site/ASKManual.html The Complete Beginners Guide to the Arduino]&lt;br /&gt;
** [http://www.codeproject.com/KB/system/ArduinoVB.aspx Arduino with Visual Basic] by Carl Morey auf codeproject.com&lt;br /&gt;
&lt;br /&gt;
==== C ====&lt;br /&gt;
* [[AVR-GCC-Tutorial]]&lt;br /&gt;
* [http://www.smileymicros.com/QuickStartGuide.pdf Quick Start Guide for using the WinAVR Compiler with ATMEL&#039;s AVR Butterfly] ([http://www.smileymicros.com www.smileymicros.com], PDF)&lt;br /&gt;
* [http://www.avrtutor.com/tutorial/thermo/contents.htm avrtutor] - an attempt to provide a real tutorial for the ATMEL AVR microcontrollers.&lt;br /&gt;
* [http://www.sparkfun.com/commerce/present.php?p=BEE-1-PowerSupply Spark Fun Electronics] - Beginning Embedded Electronics (Atmega8, englisch)&lt;br /&gt;
* [http://metku.net/index.html?path=articles/microcontroller-part-1/index_eng metku.net] - How to get started with microcontrollers (ATtiny45, Steckbrett)&lt;br /&gt;
* [http://www.stromflo.de/dokuwiki/doku.php?id=xmega-c-tutorial XMEGA-C-Tutorial] - Tutorial über Atxmega&lt;br /&gt;
&lt;br /&gt;
==== Assembler ====&lt;br /&gt;
* [http://avr-asm.tripod.com Atmel AVR ASM Site]&lt;br /&gt;
* [http://www.avr-asm-tutorial.net Atmel AVR Microcontroller Assembler Tutorial] (D)&lt;br /&gt;
* [[AVR-Studio]]&lt;br /&gt;
&lt;br /&gt;
==== Bascom ====&lt;br /&gt;
* [http://www.mcselec.com/ MCS Elektronik] BASCOM AVR Demo zum Download&lt;br /&gt;
&lt;br /&gt;
==== Pascal ====&lt;br /&gt;
* [http://www.elektronik-projekt.de/content/download/avrco_tut2.pdf AVRco Pascal Tutorial] - von Markus&lt;br /&gt;
* [http://www.ibrtses.com/embedded/avr.html ein paar Seiten zum AVR] (ASM und Pascal) von ibrt&lt;br /&gt;
&lt;br /&gt;
==== Ada ====&lt;br /&gt;
* [http://sourceforge.net/apps/mediawiki/avr-ada/index.php?title=Tutorial AVR-Ada Tutorial]&lt;br /&gt;
&lt;br /&gt;
=== Hardware (Prototypen-Platinen-Boards etc.) ===&lt;br /&gt;
&lt;br /&gt;
* [http://retrodan.tripod.com Atmel AVR Butterfly Site]&lt;br /&gt;
* [http://www.kanda.com Kanda] Starter Kits and Development Tools for different Microcontrollers&lt;br /&gt;
* [http://www.dontronics.com Dontronics] Starter Kits and Development Tools for different Microcontrollers, Linkpages for AVR and PIC&lt;br /&gt;
* [http://www.mikrocontroller.com mikrocontroller.com] u.a. Platine AVR-Ctrl, AVR-Webserver (D)&lt;br /&gt;
* [http://mikrocontroller.cco-ev.de/eng/ AVR webserver] RTL8019, 3COM (E) &lt;br /&gt;
* [http://www.microcontroller-starterkits.de Microcontroller-Starterkits] Starter Kits for different Microcontrollers (D)&lt;br /&gt;
* [http://www.olimex.com Olimex Ltd.] DevelopmentBoards and Tools&lt;br /&gt;
* [http://www.krause-robotik.de Krause Robotik] Controller Boards &amp;amp; Zubehör&lt;br /&gt;
* [http://www.robotikhardware.de robotikhardware.de] Controller Boards&lt;br /&gt;
* [http://www.embedded-it.de/microcontroller/microcontroller-module.php Embedded-IT] USB Module auf AVR Basis sowie Ethernut kompatible Embedded Ethernet Mikrocontroller Boards für Industrie und Hobby auf ARM mit Nut/OS Betriebssystem&lt;br /&gt;
* [http://www.ssv-embedded.de SSV Embedded Systems] 32-bit Mikrocontrollermodule und -boards, Starter Kits etc.&lt;br /&gt;
* [http://shop.embedit.de/browse_002_21__.php Embedit] Mikrocontrollermodule und -boards&lt;br /&gt;
* [http://www.display3000.com Display3000] Farbdisplays, Mikrocontrollermodule und -boards mit TFT-Farbdisplays; Experimentierplatinen und Ansteuerplatinen für TFT Farbdisplays&lt;br /&gt;
* [http://www.myavr.de myAVR] Einsteigerboards und Zubehör&lt;br /&gt;
* [http://www.siphec.com/ SIPHEC] Development Boards für AVR, MSP430, USB&lt;br /&gt;
* [http://www.pollin.de/shop/shop.php?cf=detail.php&amp;amp;pg=OA==&amp;amp;a=MTY5OTgxOTk=&amp;amp;w=OTk4OTY4&amp;amp;ts=0 ATMEL Evaluations-Board Bausatz] ([http://www.pollin.de/shop/downloads/D810038B.PDF PDF]) und [http://www.pollin.de/shop/shop.php?cf=detail.php&amp;amp;pg=OA==&amp;amp;a=MzU5OTgxOTk=&amp;amp;w=OTk4OTY4&amp;amp;ts=0 ATMEL Funk-Evaluations-Board Bausatz] ([http://www.pollin.de/shop/downloads/D810046B.PDF PDF]) von Pollin&lt;br /&gt;
* [http://www.lochraster.org/etherrape/ Etherrape] Atmaga 644 mit Ethernet und TCP/IP als Bausatz.&lt;br /&gt;
* [http://www.ic-board.de/index.php?cat=c4_Programmer.html AVR Programmieradapter],[http://www.ic-board.de/index.php?cat=c3_Funkmodule.html ZigBee-ready Funkmodule/Funk-USB-Sticks] und [http://www.ic-board.de/index.php?cat=c13_ICradio-Bundles.html Funk Starterkits] von In-Circuit&lt;br /&gt;
* [http://www.ic-board.de/index.php?cat=c2_ICnova-Module.html AVR32 AP7000 Linux Board] mit 2xEthernet, TFT, Audio, SDCARD, USB-Host/Devive, Funk...&lt;br /&gt;
* [http://www.das-labor.org/wiki/Laborboard Das Laborboard] von das-labor.org (DIY)&lt;br /&gt;
* [http://six.media.mit.edu:8080/6 number six] - Open Source Design, Atmega32. Alle Pins sind auf eine 2x20 Pol Wannenstiftleiste herausgeführt.&lt;br /&gt;
* http://www.maares.de/tools USB Memory Stick am AVR Butterfly. AVR Butterfly Trägerplatine zum Anschluß von VDRIVE, VMUSIC, RFM12.&lt;br /&gt;
* [http://www.wiring.org.co/ Wiring] is an open source programming environment and electronics i/o board for exploring the electronic arts, tangible media, teaching and learning computer programming and prototyping with electronics.&lt;br /&gt;
* [http://www.chip45.com/ chip45] Atmel AVR Module und Boards mit USB, RS232/485, CAN, Ethernet, Funkmodule, sowie ISP Programmieradapter.&lt;br /&gt;
* [http://www.rakers.de/catalog Dr. Rakers] &amp;lt;b&amp;gt;AVR Boards und Experimentierplatinen&amp;lt;/b&amp;gt; mit USB, Ethernet, RS232, CAN, LCD etc. in hochwertiger Qualität zu günstigen Preisen.&lt;br /&gt;
* [http://nibo.nicai-systems.de Roboterbausatz Nibo] - autonomer &amp;lt;b&amp;gt;Roboter&amp;lt;/b&amp;gt; mit einem ATmega128 und einem ATmega88&lt;br /&gt;
* [http://www.aevum-mechatronik.de Modularis] - AVR Mikrocontroller-Boards (z.T. mit Zusatz-Speicher und USB) die über Flachbandkabel erweitert werden können. Es gibt bis jetzt Zubehör-Module mit Taster, Motor H-Brücke, XBee und Winkelsensor.&lt;br /&gt;
* [http://www.schramm-software.de/bausatz/ Schramm-Software] - AVR Mikrocontroller-Bausätze&lt;br /&gt;
* [http://www.alvidi.de/ Alvidi] - Headerboards mit AVR &amp;amp; AVR32 Controllern&lt;br /&gt;
* [http://www.steitec.net/ Steinert Technologies] - Thailändischer Anbieter von Mikrocontroller Boards (AVR, ARM7, ARM9, PIC, dsPIC, PSoC, uvm.)&lt;br /&gt;
* Arduino&lt;br /&gt;
** [http://www.arduino.cc/ Arduino] Homepage&lt;br /&gt;
** [http://www.freeduino.org/ Freeduino.org] - Riesige Linksammlung zu dem &#039;&#039;&#039;Ardunio&#039;&#039;&#039;(R) AVR-Board (Kit) und dessen Clones und Mutanten (DIY oder Kit)&lt;br /&gt;
** [http://www.freeduino.de/ freeduino.de] - Anleitungen und Tutorials, Arduino Wiki, Blog, Tools in Deutsch&lt;br /&gt;
** [http://shieldlist.org/ Arduino Shield List]&lt;br /&gt;
* [http://www.fritzing.org Fritzing] nützliches Programm für viele Betriebsysteme zur Unterstützung eines Brettboard-Aufbaus(ungetestet).&lt;br /&gt;
* [http://www.specialprint.eu Specialprint] InkjetDruck für den digitalen Direktdruck von Ätzmasken, Lötstoppmasken, Frontplatten, Kennzeichnungen&lt;br /&gt;
* [http://www.onlinesteuerung.de Onlinesteuerung.de] USB Bausatz. Technische Geräte per PC, Browser, Netzwerk, Ethernet, TCP/IP, Internet, Excel, Timer oder Sensoren schalten.&lt;br /&gt;
* [http://8devices.com/product/3/wi-fi-4-things Carambola WiFi module] Open hardware Linux friendly (OpenWRT) WiFi 802.11n OEM module&lt;br /&gt;
* [http://www.atxmega-board.de ATxMegaBoard und ATxMegaStick] Entwicklungsboards, zum Einstig in die Welt der ATxMegas&lt;br /&gt;
&lt;br /&gt;
=== Programmierhard- und Software ===&lt;br /&gt;
* [http://www.obdev.at/products/avrusb/avrdoper.html AVR-Doper] Einfach nachzubauender, STK500-kompatibler Programmer mit USB-Anschluss. Beherrscht auch HVSP, nicht jedoch HVPP. Open Source.&lt;br /&gt;
* [http://www.bsdhome.com/avrdude/ AVRDUDE] AVR ISP-Programmerierwerkzeug für Unix/Linux/BSD und Windows. Kommandozeile [http://sourceforge.net/projects/avrdude-gui/ (oder mit GUI)], AVR Butterfly-Unterstützung&lt;br /&gt;
* [http://www.lancos.com/prog.html PonyProg] neben AVR für diverse seriell programmierbare Bauteile (Grafische Nutzeroberfläche und Kommandozeile), siehe auch [[Pony-Prog Tutorial]]&lt;br /&gt;
* [http://savannah.nongnu.org/projects/uisp/ uisp] AVR ISP-Programmierwerkzeug für Unix/Linux/BSD und Windows (Kommandozeile)&lt;br /&gt;
* [http://www.myplace.nu/avr/yaap/ yaap]&lt;br /&gt;
* [http://www.xs4all.nl/~sbolt/e-index.html SP12]&lt;br /&gt;
* [http://www.mikrocontroller-projekte.de/Mikrocontroller/AVR-Prog/AVR-Programmer.html AVR910 kompatibler Programmer] mit aktueller, beschleunigter Firmware.&lt;br /&gt;
* [http://www.der-hammer.info/hvprog STK500 kompatibler Programmer] als Nachbauprojekt. Siehe auch [[STK500]]&lt;br /&gt;
* [http://www.shop.robotikhardware.de/shop/catalog/product_info.php?cPath=73&amp;amp;products_id=41 Preiswerter Standard ISP (STK200 kompatibel)]&lt;br /&gt;
*  [http://www.siwawi.arubi.uni-kl.de/avr_projects/evertool/ Evertool] kombinierter ISP &amp;amp; [[JTAG]] Programmer (kompatibel zum &amp;quot;original&amp;quot; Atmel AVRISP und Atmel JTAGICE) &lt;br /&gt;
* [http://www.olimex.com Olimex] (Bulgarischer Anbieter) Kostengünstig&lt;br /&gt;
* [http://www.avr-projekte.de/isp.htm AVR910-USB Programmer] incl. USB-Modul und USB-&amp;gt;Seriell Wandler&lt;br /&gt;
*[http://www.fischl.de/usbasp/ USBasp] &amp;amp;#8211; USB-Programmer bestehend aus ATmega8 (kein spezieller USB-Chip notwendig)&lt;br /&gt;
* [http://home.arcor.de/bernhard.michelis Amadeus-USB] - Highspeed-Programmer für PIC18, PIC24, dsPIC30, PIC32, dsPIC33 und AVR. Bietet auch Möglichkeiten zur Fehlersuche.&lt;br /&gt;
* [http://www.e-dsp.com Signalgenerator] - Signalgenerator software&lt;br /&gt;
* [http://www.piketec.com/products/tpt.php Time Partition Testing (TPT)] - Test-, und Testauswertewerkzeug für eingebettete Systeme&lt;br /&gt;
* [http://shop.myavr.de/Programmer.htm?sp=artlist_kat.sp.php&amp;amp;katID=16 mySmartUSB] - USB Programmer (ab 15€) kombiniert auch mit USB-UART-Bridge, STK500v2/AVR910/AVR911 kompatibel, ISP HV-seriell, HV-parallel&lt;br /&gt;
* [http://www.shop.robotikhardware.de/shop/catalog/product_info.php?cPath=73&amp;amp;products_id=161 USB-Programmer für Bascom Programmierer]&lt;br /&gt;
* [http://www.virtualserialport.com/ Virtual Serial Port] Software for serial port communication and null-modem emulation&lt;br /&gt;
* [http://www.ic-board.de/index.php?cat=c4_Programmer.html AVR Programmieradapter und JTAGICE MKII]&lt;br /&gt;
* [http://www.helmix.at/hapsim/index.htm HAPSIM graphischer Simulator ] zu graphischen Simulation von Tasten /LED /LCD und Terminal in AVR Studio Freeware !!!&lt;br /&gt;
* [http://www.ic-board.de/index.php?cat=c4_Programmer.html AVR Programmieradapter und JTAGICE MKII]&lt;br /&gt;
* [http://www.myavr.de/download.php?suchwort=ProgTool myAVR ProgTool] nette Programmieroberfläche (free)&lt;br /&gt;
* [http://b9.com/elect/avr/kavrcalc/ KAVRCalc] is a free calculator to assist in programming AVR microcontrollers (Baudrate, Watchdog, Timer, ...)&lt;br /&gt;
* [http://www.chip45.com/CrispAVR-USB CrispAVR-USB] STK500 V2 kompatibler ISP Adapter mit USB Schnittstelle für Atmel AVR Mikrocontroller (1,8V-5,5V).&lt;br /&gt;
* [http://ucom-ir.nicai-systems.de UCOM-IR] - Programmieradapter mit USB Schnittstelle (AT90USB162) und IR-Sender/Empfänger, STK500 V2 kompatibel&lt;br /&gt;
* [http://www.anagate.de/products/programmers.htm AnaGate Programmer] Serielle Programmer mit LAN-Anschluss für I2C und SPI inkl. Programmier-API für Windows/Linux (Shop)&lt;br /&gt;
&lt;br /&gt;
=== Projekte und Quellcodebibliotheken ===&lt;br /&gt;
&lt;br /&gt;
====Bibliotheken====&lt;br /&gt;
* [http://www.nongnu.org/avr-libc/ AVR Libc]&lt;br /&gt;
* [http://hubbard.engr.scu.edu/embedded/avr/avrlib/docs/html/index.html Procyon AVRlib]&lt;br /&gt;
* [http://homepage.hispeed.ch/peterfleury Peter Fleury&#039;s Pages] - UART / LCD (HD44780) / I²C (TWI)/ AVR-GCC Bibliotheken, STK500v2 Bootloader&lt;br /&gt;
*[http://sourceforge.net/projects/avrfix  Fixed Point Library Based on ISO/IEC Standard DTR 18037 for Atmel AVR microcontrollers, u.a. Cordic-Algorithmen] und [http://www.enti.it.uc3m.es/wises07/presentations/session2/05%20-%20Fixed%20Point%20Library%20According%20to%20ISOIEC%20Standard%20DTR%2018037%20for%20Atmel%20AVR%20ProcessorsWISES07-fixedpointlibrary%20-%20Elmenreich.pdf  Kurzbeschreibung dazu als Powerpoint-PDF TU Wien Febr. 2007]&lt;br /&gt;
&lt;br /&gt;
==== Betriebssysteme &amp;amp; Co. ====&lt;br /&gt;
* [http://www.tinyos.net/ TinyOS] - Komponentenbasiertes Betriebssystem für Sensorknoten. Bringt eigene C-ähnliche Hochsprache nesC mit.&lt;br /&gt;
* [http://www.chris.obyrne.com/yavrtos/ YAVRTOS] - Yet Another Atmel® AVR® Real-Time Operating System von Chris O&#039;Byrne (C, Atmega32, GPL3 Lizenz)&lt;br /&gt;
* [http://www.freertos.org/ FreeRTOS] is a portable, open source, mini Real Time Kernel - a free to download and royalty free RTOS that can be used in commercial applications. (AVR, MSP430, PIC, ARM7, ...)&lt;br /&gt;
* [http://www.barello.net/avrx/index.htm AvrX Real Time Kernel] (IAR ASM oder IAR/GCC C, GPL2 Lizenz)&lt;br /&gt;
* [http://scmrtos.sourceforge.net/ scmRTOS] - Single-Chip Microcontroller Real-Time Operating System (C++, AVR, MSP430, Blackfin, ARM7, FR (Fujitsu, [http://www.opensource.org/licenses/mit-license.php MIT Lizenz]).&lt;br /&gt;
* [http://www.circuitcellar.com/avr2004/DA3650.html csRTOS] - cooperative single-stack RTOS aus dem Circuit Cellar AVR 2004 Design Contest.  [http://www.avrfreaks.net/index.php?module=Freaks%20Academy&amp;amp;func=viewItem&amp;amp;item_id=987&amp;amp;item_type=project csRTOS port to ATmega32] und [http://www.avrfreaks.net/index.php?name=PNphpBB2&amp;amp;file=viewtopic&amp;amp;t=50743&amp;amp;start=all&amp;amp;postdays=0&amp;amp;postorder=asc Diskussion] auf www.avrfreaks.net führte zur Weiterentwicklung als [http://www.mtcnet.net/~henryvm/4AvrOS/ 4AvrOS] - cooperative scheduler&lt;br /&gt;
* [http://www.avrfreaks.net/index.php?module=Freaks%20Academy&amp;amp;func=viewItem&amp;amp;item_type=project&amp;amp;item_id=230 OPEX] - freeware cooperative scheduler with lots of calendar and I/O functions von Steve Childress (Download auf www.avrfreaks.net ggf. Registrierung notwendig)&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/12176#79672 Scheduler] von Peter Dannegger&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/25087#186454 RTC-Scheduler] von ape&lt;br /&gt;
* [http://www.sics.se/~adam/pt/ Protothreads] - Lightweight, Stackless Threads in C (open source BSD-style license)&lt;br /&gt;
* [http://www.micrium.com/products/rtos/kernel/rtos.html uC/OS-II] is a real time operating system developed by Jean J. Labrosse. You can obtain the source code for the OS by buying Labrosse&#039;s excellent book &#039;&#039;MicroC/OS-II The Real-Time Kernel (2nd edition)&#039;&#039;. [http://www.ee.lut.fi/staff/Julius.Luukko/ucos-ii/avr/index.shtml Port for AVR (gcc 3.x)] and [http://www.myplace.nu/avr/ucos/index.htm AVR (gcc 2.x)].&lt;br /&gt;
* [http://freshmeat.net/projects/qp/ QP] is a lightweight, portable framework/RTOS for embedded systems (ARM, Cortex-M3, 8051, AVR, MSP430, M16C, HC08, NiosII, and x86). GPL (und kommerzielle Lizenz verfügbar)&lt;br /&gt;
* [http://www.femtoos.org/ Femto OS] von  Ruud Vlaming ist ein preemptives Betriebssystem für die kleinsten Mikrocontroller aus der AVR Serie bis ca. 16 KB ROM und 1 KB RAM. Spezielle Targets sind: ATtiny861/461/261. Geschrieben in C. Freie Software, GPLv3. Artikel in Elektor Februar 2010 &lt;br /&gt;
* [http://www.projects-lab.com/?p=344 kaOS] is a real-time, multithreaded, preemptive operating system for the ATmega32 microcontroller, which loads and executes programs from a Secure Digital or MMC card. Authors Nicholas Clark &amp;amp; Adam Liechty. (Circuit Cellar AVR Wettbewerb 2006)&lt;br /&gt;
* [http://helium.sourceforge.net/ Helium] is a minimalistic real-time kernel for the HC(S)08 core by Freescale and Atmel AVR.&lt;br /&gt;
* [http://dev.bertos.org/ BeRTOS] is a completely free, open source, real time operating system (RTOS) suitable for embedded platforms. Runs on many microprocessors and microcontrollers, ranging from 8 bits to 32 bits CPUs and even PCs.&lt;br /&gt;
* [http://funkos.sourceforge.net/ funkos] Targets: AVR, XMEGA, MSP430, Cortex M3, Open Source&lt;br /&gt;
* Vergleich zwischen [http://antipastohw.blogspot.com/2009/11/4-operating-systems-for-arduino.html 4 Operating Systems for the Arduino] auf [http://antipastohw.blogspot.com Liquidware Antipasto]&lt;br /&gt;
** &#039;&#039;&#039;DuinOS&#039;&#039;&#039; by RobotGroup (FreeRTOS Portierung)&lt;br /&gt;
** [http://www.skewworks.com/pyxis/ Pyxis OS] by ArduinoWill&lt;br /&gt;
** &#039;&#039;&#039;ArduinoMacOS&#039;&#039;&#039; by Mark&lt;br /&gt;
** &#039;&#039;&#039;TaOS&#039;&#039;&#039; by Ziplock&lt;br /&gt;
* [http://atomthreads.com/ Atomthreads] is a free, lightweight, portable, real-time scheduler for embedded systems. (BSD Lizenz)&lt;br /&gt;
* [http://www.shift-right.com/xmk/ XMK] (eXtreme Minimal Kernel) ist ein freies Echtzeitbetriebssystem für Mikrocontroller (AVR, H8, R8C, M16C).&lt;br /&gt;
* [http://irtos.sourceforge.net/index.html.en iRTOS] is an free Real Time Operating System. The iRTOS kernel is free to download and use under the terms of LGPL. It can be used in commercial applications. iRTOS is designed for tiny 8 bit microconroller chips with little RAM usage. OS can be installed also in 16 and 32 bit processor units.&lt;br /&gt;
* [http://sites.google.com/site/cocoosorg/avr-projects/home cocoOS] is a cooperative task scheduler, based on coroutines and it is written in C. (STK500, Atmega16)&lt;br /&gt;
* [http://www.DieProjektseite.de BasicBeetle] Basic-Betriebssystem im AVR&lt;br /&gt;
* Shells für Arduino:&lt;br /&gt;
** [http://biot.com/arsh/ ARSH]&lt;br /&gt;
** [http://www.battledroids.net/downloads/avrsh.html AVRSH]&lt;br /&gt;
** [http://bitlash.net/wiki/start BITLASH]&lt;br /&gt;
** [http://sourceforge.net/projects/fruitshell/ FRUITSHELL]&lt;br /&gt;
** [http://www.gisvold.co.uk/~gisvold/drupal/node/1484 BREAKFAST]&lt;br /&gt;
* [http://nootropicdesign.com/toolduino/ toolduino] is a simple software tool that lets you easily interact with your Arduino hardware so you can test the circuits you create. Toolduino is written in the [http://processing.org/ Processing] languange and is available for Windows, Mac OS X, and Linux. Toolduino uses the the [http://www.arduino.cc/playground/Interfacing/Processing Arduino library for Processing] to communicate with an Arduino board so you can manipulate output pins and read inputs. The Arduino must be running the [http://firmata.org/wiki/Main_Page Firmata] firmware that comes with the Arduino IDE. (LGPL)&lt;br /&gt;
* [http://www.mueller-torres.de/avr.php MOPS] - A small C and Assembly based operating system for the ATMEL AVR® 8-Bit RISC controller family.&lt;br /&gt;
* [http://www.hk-businessconsulting.de/rts.htm RTS(Realtime Tasking System)] - Betriebssystemkern mit Echtzeiteigenschaften, Lizenz: EUPL V. 1.1&lt;br /&gt;
&lt;br /&gt;
==== Projektsammlungen ====&lt;br /&gt;
&lt;br /&gt;
* [http://www.DieProjektseite.de Die Elektronik-Projektseite und Heimat des BasicBeetle] Hauptthema ist der BasicBeetle. Ein modularer, leistungsfähiger, in Basic programmierbarer Mikrorechner speziell für Steuerungen. Mit vielen Programmen, Tiipps und Tricks, Informationen...&lt;br /&gt;
* [http://www.Happy-Micro.de Happy-Micro.de] Die Internetsite für Hobbyelektroniker, Mikrocontroller-Anwender, Programmierer und alle, die Spaß an Computern und Elektronik haben. Bei Happy-Micro.de steht der Spaß am Entwickeln von Programmen und Schaltungen im Vordergrund. Jeder Benutzer hat die Möglichkeit auch als Autor mitzumachen und seine Schaltungen oder Programme zu veröffentlichen. Freier Bilderdownload für die eigene Homepage. &#039;&#039;(Seite wurde geschlossen!)&#039;&#039;&lt;br /&gt;
* [http://iwenzo.de Elektronik und Informationen] Wissenswertes aus der Unterhaltungselektronik..&lt;br /&gt;
* [http://instruct1.cit.cornell.edu/courses/ee476/FinalProjects/ Cornell University ECE 476 Microcontroller Design Final Projects] &lt;br /&gt;
* [http://www.serasidis.gr/ Serasidis Vasilis&#039; AVRsite] u.a. GLCD, SMS, PAL&lt;br /&gt;
* [http://www.riccibitti.com Alberto Ricci Bitti] u.a. PAL Video-Interface&lt;br /&gt;
* [http://www.ulrichradig.de Mikrocontroller and more] AVR - Projekte (Ethernet, LCD, Relaiskarte usw.) und mehr&lt;br /&gt;
* [http://home.arcor.de/burkhard-john/index.html Burkhard John] (D)&lt;br /&gt;
* [http://www.avrprojects.net/ AVRmicrocontrollerprojects] u.a. Text-LCD, Schrittmotor, Thermometer&lt;br /&gt;
* [http://hem.bredband.net/robinstridh/ Robin Stridh] Rotor-Anzeige, Video-Interface&lt;br /&gt;
* [http://www.dertien.dds.nl/content/avrprojects.html dertien.dds.nl AVR-Projects]&lt;br /&gt;
* [http://www.microsps.com MicroSPS.com] Grafische Programmierung des AVR mit EAGLE&lt;br /&gt;
* [http://www.h-mpeg.de h-mpeg Festplatten mp3 Player] IDE Ansteuerung, IDE Filesystem, LCD Ansteuerung etc. in 8K Code. Quelltext unter GPL&lt;br /&gt;
* [http://www.embedtronics.com/ embedtronics.com]&lt;br /&gt;
* [http://www.siwawi.arubi.uni-kl.de/avr_projects  M. Thomas&#039; AVR Projekte] untern Anderem AVR Butterfly avr-gcc-port, DB101 gcc-port, BC100 gcc-port, Bootloader, Programmier- und Debughardware, Software-UART, DS1820-Lib., experimentelle avrdude-Versionen, AVR und CAN mit MCP2515 &amp;lt;!-- Vorsicht &amp;quot;Eigenwerbung&amp;quot; --&amp;gt;&lt;br /&gt;
* [http://www.mictronics.de Michaels Electronic Projects] AVR Projekte (EN) - ua. Sony/Becker CD/MD Wechsler Emulator, RDS-Decoder, GPS Infos, OBD J1850 VPW Interface, USB&amp;lt;&amp;gt;CAN Bus Interface. Informationen zu CD Wechsler Protokollen. MP3stick - MP3 Player mit ATmega128, color LCD, SD/MMC Karte und VS1011b&lt;br /&gt;
* [http://www.stahlbucht.de/elektronik/node13/ node13] modulares AVR 8515 Projekt: eine Controller-Platine, an die sich weitere Ein-Ausgabemodule (Tastenfeld, LEDs, LCD-Modul) anschliessen lassen&lt;br /&gt;
* [http://www.mikrocontroller-projekte.de www.mikrocontroller-projekte.de] Diverse Projekte mit AVR Controllern. AVR910 Programmer, Testboard und Modellbauelektronik&lt;br /&gt;
* [http://www.roboternetz.de/phpBB2 Roboternetz-Mikrocontroller Projekte.de] Diverse Projekte mit AVR und anderen Controllern, insbesondere im Bereich Robotik&lt;br /&gt;
* [http://www.avr-projekte.de AVR-Projekte.de] Belichtungstimer, FT232RL Schaltungen,LED-Fading über Fernbedienung, HD44780-LCD über USB und Seriell, AVR910-USB Programmer, Basteleien: Ätzmaschine,Kompressor.&lt;br /&gt;
* [http://openeeg.sourceforge.net/ openeeg.sourceforge.net] Das OpenEEG Projekt befasst sich mit der Entwicklung eines preiswerten Elektro-Enzephalographie (EEG) Geräts und dessen freier Steuersoftware zur Messung elektrischer Gehirnströme. Sein µPC-Herz ist ein AT90S4433 bzw. ein ATmega8. Ziel sind auch verschiedene EEG Anwendungen z.&amp;amp;nbsp;B. im Bereich mentaler Trainingsmethoden (Neurofeedback).&lt;br /&gt;
* [http://www.amateurfunkbasteln.de/ www.amateurfunkbasteln.de] Seite von Michael Wöste (DL1DMW) u.a. CPU-Board mit AT89C2051, AT89C4051 oder AVR AT90S2313, CPU-Board mit Atmel AT90S8535, Experimentierplatine mit ATmega103, Programmer für AT89C2051/AT89C4051, 32-Kanal-Logik-Analysator bis 40 MHz (Entwurf von David L. Jones)&lt;br /&gt;
* [http://www.atmel.com/dyn/products/app_notes.asp?family_id=607 Atmel - AVR 8-Bit RISC - Application Notes] Anwendungshinweise und Beispiele vom Hersteller&lt;br /&gt;
* [http://www.projects.cappels.org/ Dick Cappels&#039; Project Pages]&lt;br /&gt;
* [http://see-by-touch.sourceforge.net/index.html SeebyTouch - Blinden-Seh-Ersatzsystem] Computerbilder fühlen durch ein einfaches Gerät (Bauanleitung) und freier Software (für 10 Betriebssysteme) - eine neue Erfahrung für alle&lt;br /&gt;
* [http://www.loetstelle.net www.loetstelle.net] Verschiedene kleinere AVR-Projekte rund um LEDs, z.&amp;amp;nbsp;B. RGB Dimmer, Moodlight. Diverse Elektronikprojekte und Grundlagen&lt;br /&gt;
* [http://www.dietmar-weisser.de Selbstbauprojekte Elektronik] kleine Sammlung von Elektronikprojekten zum Thema Leiterplattenfertigung, Hochfrequenztechnik und Mikrocontroller.&lt;br /&gt;
* [http://www.myplace.nu/avr/ Jesper&#039;s AVR pages] Yampp MP3 Player, Yaap Programmer, DDS mit 2313+R2R, Gitarrentuner, Frequenzzähler.&lt;br /&gt;
* [http://www.microsyl.com/ MicroSyl MCU] MP3 Player, MegaLoad, HCLoad, Propeller Clock, Freq Meter, BarCode Reader, Door Bell, OneWire Lib, Text LCD Lib, Graph LCD Lib, Nokia LCD Lib, Led Sign with MMC MemoryCard, Intercom&lt;br /&gt;
* [http://www.jeroen.homeunix.net/ http://www.jeroen.homeunix.net/] Aufbau eines elektronischen Rouletts auf basis eines AVRs&lt;br /&gt;
* [http://thomaspfeifer.net thomaspfeifer.net] Reflow-Ofen, Laminator-Temperaturregelung, USB-Atmel-Programmer, SMD-Tricks u.v.m.&lt;br /&gt;
* [http://www.scienceprog.com Scienceprog - embedded theory and projects] - AVR, ARM theory and projects&lt;br /&gt;
* [http://www.iuse.org Hausautomatisierung] - CAN-Bus mit ATmega32-Controllern und Bedienfeldern, Admin-Tools zum Updaten via CAN, Traffic Dumper etc.&lt;br /&gt;
* [http://www.myevertool.de AVRSAM] - AT91SAM7S Header Board annährend 100% Pinkompatibel zu den folgenden AVR Mikrocontroller: AT90S8535 / ATMEGA8535 / ATMEGA16 / ATMEGA32&lt;br /&gt;
* [http://members.aon.at/hausbus Hausbus Home] - Hausbus-Projekt unter Verwendung von ATmega8, ATtiny13 und ATmega128&lt;br /&gt;
* [http://www.thomas-wedemeyer.de/elektronik/AVR/avr-dcf-clock.html AVR-DCF-Clock] - DCF-Uhr mit bunter LED-Anzeige - ATmega8&lt;br /&gt;
* [http://www.grasbon.de/genuhr.html GenuhR] - DCF-Funkuhr / Wecker/ Timer mit LED-Punktmatrixanzeige. Das Projekt beschreibt den Aufbau des kompletten Gerätes beginnend beim Schaltplan bis hin zur Montage in ein Gehäuse.&lt;br /&gt;
* [http://www.avrguide.com/ AVR Projektsammlung] bei www.avrguide.com&lt;br /&gt;
* AVR Synth http://www.elby-designs.com/avrsynth/avrsyn-about.htm http://www.jarek-synth.strona.pl/&lt;br /&gt;
* [http://elm-chan.org/he_e.html Electronic Lives Manufacturing] - Aufbauten in Fädeldrahttechnik, tlw. auf Japanisch, aber mit englischen Sourcecodes&lt;br /&gt;
* AVR Synthesizer http://www.avrx.se/&lt;br /&gt;
* [http://www.wedis-basteleck.de/ Wedis-Basteleck] - Modellbahn DCC-Servo-Zubehördecoder DCC Servo Decoder mit ATmega8 / Servo Differenzierbaugruppe für Modellbau&lt;br /&gt;
* http://web.archive.org/web/20050415222337/http://www.hebel23.de/ RDS RADIO: ATMega32, TEA5757, T6963C, TDA7330B in C&lt;br /&gt;
* [http://www.gasenzer.dk Analog/Digital and MPU Eletronic Projects] PAL/VGA Terminal, CallerID, Ethernet, Wireless Bridge, LPC2214, AT91RM9200, Sony Unilink Controlled Wireless MP3 Player.&lt;br /&gt;
* [http://www.circuitcellar.com/avr2004/ Circuit Cellar AVR Design Contest 2004] mit Projektbeschreibungen&lt;br /&gt;
* [http://www.circuitcellar.com/avr2006/ Circuit Cellar AVR Design Contest 2006] mit Projektbeschreibungen&lt;br /&gt;
* [http://www.heesch.net/microcontroller.aspx/ Homepage von Stefan Heesch] - AVR Mikrokontroller Projekte, z.B. WLAN und AVR, netzwerkgesteuertes RGB Licht, IDE-Interface, DS1821 Thermometer, Morse-Dekoder u.a.&lt;br /&gt;
* [http://www.schaltungsforum.de Das Schaltungsforum] ist eine Seite für Anfänger und Profis welche ständig mit Tutorials erweitert wird. Stellt Eure Projekte online. Die Seite befindet noch im Aufbau und Eure Mithilfe ist erwünscht.&lt;br /&gt;
* [http://avrprojekte.de/] Viele Projekte mit LEDs(LED-Matrixen) und AVRs&lt;br /&gt;
* [http://arduino.milkcrate.com.au/ little-scale&#039;s arduino page]&lt;br /&gt;
* [http://www.sebastianweidmann.de www.sebastianweidmann.de] Grundlagen zum Thema Platinen ätzen, Bohren, Durchkontaktierungen und Projekte Tipps/Tricks mit Atmel AVR Microcontrollern&lt;br /&gt;
*[http://www.jtronics.de/elektronik-avr.html Junghans Electronic Page] u.a Nokia 3310 LCD Ansteuerung in &amp;quot;C&amp;quot;(aktualisiert 2010), TWI/USI, Quadcopter&lt;br /&gt;
* [http://www.familie-finke.com/ http://www.familie-finke.com/] Die Website von Thomas Finke mit diversen Elektronikprojekten, wie z.B. STK-LAN (AVR im Netzwerk mit HTTPD, SNMP,...), UV-LED-Belichter, HPGL-Plotter.&lt;br /&gt;
* [http://phil-zone.de/ Philips Projektsammlung] Elektronik Projekte (µC,CMOS,Analog,...), Tutorials und nützliche Online-Tools&lt;br /&gt;
* [http://www.iuac.res.in/~elab/phoenix/index.html Phoenix] allows you to develop science experiments  by connecting  sensor / control elements to a computer and access them through software. The project was started by Inter University Accelerator Centre, with the objective of improving the laboratory facilities at Indian Universities, and growing with the support of the user community. Phoenix depends heavily on Python language. The data acquisition, analysis and writing simulation programs to teach science and computation. The hardware design is freely available. The project is based on Free Software tools and the code is distributed under GNU GPL. (Atmega16)&lt;br /&gt;
* [http://code.google.com/p/usb-pwm-generator/ USB PWM Generator] Low Cost PWM Generator, über USB Programmierbar. 1Hz - 120khz Duty Cycle 1 - 99 %.&lt;br /&gt;
&lt;br /&gt;
==== Schnittstellen ====&lt;br /&gt;
===== TCP/IP =====&lt;br /&gt;
* Kostengünstige und schnelle WLAN Anbindung an Mikrocontroller mit Wiz610wi. Bezugsquelle inkl. praktischer Adapterplatine bei: [http://www.shop.display3000.com/elektronikmodule/ethernet-wlan/index.html Display3000]&lt;br /&gt;
* [http://www.laskater.com/projects/uipAVR.htm TCP/IP Stack für AVR] mit Realtek RTL8019AS oder Axis AX88796 Netzwerk-Chips (open source für avr-gcc und Imagecraft). Passende Hardware in [http://www.edtp.com/ diesem online-shop]&lt;br /&gt;
* [http://www.ethernut.de Ethernut] - AVR based Hardware with Ethernet-Interface, Multithreading OS, Software and Hardwaredesign is free&lt;br /&gt;
* [http://www.embedded-it.de/microcontroller/eNet-sam7X.php eNet-sam7X] Embedded Ethernet Modul im DIL64 Format mit kompletten OpenSource Board Support Packake auf Ethernut / Nut/OS Basis. Industrie geeignet&lt;br /&gt;
* [http://www.ethersex.de/index.php/Feature_Liste Ethersex] - Trotz des bescheuerten Namens sehr empfehlenswert. Viele flexibel einbindbare Module für diverse Hardware.&lt;br /&gt;
* [http://wiki.neo-guerillaz.de OpenMCP] Bekanntes Board auf Basis des ATmega2561 und ENC28j60. Läuft auch auf dem AVR-NETIO und dem myAVR.&lt;br /&gt;
* [http://www.cesko.host.sk/IgorPlugUDP/IgorPlug-UDP%20(AVR)_eng.htm IgorPlug-UDP AVR] - Ethernet &amp;amp; UDP/IP in Software implementiert&lt;br /&gt;
* [http://members.home.nl/bzijlstra/software/examples/RTL8019as.htm] RTL8019 Bascom&lt;br /&gt;
* [http://members.home.nl/bzijlstra/software/examples/RTL8019as.htm AVR und RTL8019]&lt;br /&gt;
* [http://avr.auctionant.de/avr-ip-webcam AVR IP Webcam] &lt;br /&gt;
* http://mikrocontroller.cco-ev.de/de/webcam.php&lt;br /&gt;
* [http://avr.auctionant.de/avrETH1/ avrETH1 - Webserver mit enc28j60 und Webcam-Support]&lt;br /&gt;
* [http://www.sics.se/~adam/uip/ uIP-Stack, Teil des Contiki OS]&lt;br /&gt;
* [http://www.sics.se/~adam/lwip/ LwIP-Stack]&lt;br /&gt;
* [http://www.harbaum.org/till/spi2cf/ WLAN-Implementierung auf Basis einer PRISM-CF-Karte und uIP]&lt;br /&gt;
* http://www.circuitcellar.com/AVR2006/winners/DE/AT2581.htm MEGA128(CAN) PCMCIA&lt;br /&gt;
* [http://www.ic-board.de/index.php?cat=c2_ICnova-Module.html AVR32 AP7000 Linux Board] mit 2xEthernet, TFT, Audio, SDCARD, USB-Host/Devive, Funk...&lt;br /&gt;
* [https://berlin.ccc.de/wiki/AVR-Board_mit_Ethernet AVR-Board mit Ethernet mit dem ENC28J60 von Microchip]&lt;br /&gt;
* [http://www.roland-riegel.de/mega-eth/ AVR-Ethernet-Board mit extra SRAM, SD/MMC, USB und zugehöriger Software]&lt;br /&gt;
&lt;br /&gt;
===== CAN =====&lt;br /&gt;
* [http://www.canathome.de/ Can@Home] - CAN als &amp;quot;Installationsbus&amp;quot;, u.a. mit AVRs (D)&lt;br /&gt;
* [http://www.iuse.org/ www.iuse.org] - Hausautomatisierung auf CAN Basis&lt;br /&gt;
* [http://www.port.de/ www.port.de] - Professionelle CAN/CANopen Entwicklungswerkzeuge&lt;br /&gt;
* [http://can-wiki.info CAN-WIKI] - spezielle Wiki Site für CAN bus (Englisch)&lt;br /&gt;
* [[CAN-Bus]] - Eintrag in diesem Wiki&lt;br /&gt;
* [[CAN als Hausbus]] - Eintrag in diesem Wiki&lt;br /&gt;
* [http://www.canhack.de/ www.canhack.de] - Ein Forum, dass sich mit dem CAN bus im Auto beschäftigt&lt;br /&gt;
* [http://www.edevices.lt/  www.edevices.lt ] - USB2CAN inexpensive USB to CAN bus converter&lt;br /&gt;
&lt;br /&gt;
===== USB =====&lt;br /&gt;
* [http://www.embedded-it.de/microcontroller/microcontroller-module.php eUSB-162 und eUSB-LCD] - At90USB162 basiertes universelles USB Prototypen / Mikrocontroller Modul und USB Terminal Interface für HD44780 kompatible LCDs auf Basis der Lufa Library&lt;br /&gt;
* [http://www.cesko.host.sk/IgorPlugUSB/IgorPlug-USB%20(AVR)_eng.htm Igor-Plug] - USB Device interface in AVR Firmware - no extra Interface IC needed, read the License&lt;br /&gt;
* [http://www.obdev.at/products/vusb/index-de.html V-USB] &amp;amp;#8211; USB-Implementation in C nach gleichem Prinzip wie Igor-Plug, aber einfacher zu verwenden, GPL-ähnliche Lizenz (Nutzung des Projekts &#039;&#039;erfordert&#039;&#039; Veröffentlichung), englisch kommentierter Code&lt;br /&gt;
* [http://www.xs4all.nl/~dicks/avr/usbtiny/ USBTiny] &amp;amp;#8211; weitere Software-USB-Implementierung in C; sehr ähnlich AVR-USB; steht aber unter GPL; relativ wenige Beispiele&lt;br /&gt;
* MJoy USB Joystick Controller on AVR ATmega8&lt;br /&gt;
* [http://www.ime.jku.at/tusb/ TUSB3210-Controller, HID, LIBUSB] Ein Projektseminar, in dem es darum ging, die USB-Schnittstelle des TUSB3210 zu aktivieren und die Daten eines ADC an den PC zu senden. USB-Implementierung für µC und PC.&lt;br /&gt;
* [http://www.b-redemann.de Steuern und Messen mit USB - FT232, 245 und 2232] Das aktuelle Buch zu den USB-Controllern von FTDI. Viele Beispielprogramme in C, zwei Projektbeschreibungen: I²C-Bus mit LM75A und ein Web-Projekt. Bauteilesatz und USB-Modul mit dem FT2232 zum schnellen Einstieg in die Thematik. Buch / Teilesatz über Segor oder dieser Seite erhältlich.&lt;br /&gt;
* [http://www.eltima.com/products/usb-over-ethernet/ USB to Ethernet Connector] - Share your USB devices via LAN/Internet&lt;br /&gt;
* [http://www.ixbat.de Viele kleine USB Projekte] Rund um die Bibliothek usbn2mc http://usbn2mc.berlios.de. Dies ist eine einfache Bibliothek für den USBN9604/03 von National Semiconductor&lt;br /&gt;
* [http://www.rahand.eu Mega8D12] - Schritt für Schritt zum virtuellen COM-Port. Ein Einsteiger-Tutorial zur CDC-Klasse mit Schaltung und Firmware (ATmega8 und PDIUSBD12).&lt;br /&gt;
* http://www.maares.de/tools USB_ISO: Isolierter Schnittstellenwandler USB auf RS232 (TTL) mit FT232RL und ADUM1402. Galvanische Trennung für das Zielsystem.&lt;br /&gt;
* [http://www.embedded24.net USB HID Host Treiber] - USB HID Treiber DLL für Windows (Demo Projekte für Visual Studio 2010 C++, C# und VB).&lt;br /&gt;
&lt;br /&gt;
===== DMX512 =====&lt;br /&gt;
* [http://Dworkin-DMX.de Konverter RS232 zum DMX512] Steuerung DMX-fähigen Geräten mit einem PC. Es gibt Low cost Variante zum selber basteln.&lt;br /&gt;
* [http://www.hoelscher-hi.de/hendrik/light/profile.htm Hennes Sites] Bauanleitungen für DMX-Dimmerpacks, DMX-Switchpacks, PWM-Controller, ... Tutorial für Senden und Empfangen von DMX-Daten mit AVRs.&lt;br /&gt;
* [http://www.lj-skinny-development.de/lj2000/ DMX Lichtanlage im Selbstbau] Projekt für den Selbstbau einer kompletten Lichtanlage zur Steuerung über DMX. Projekt beinhaltet alles was man für den Betrieb einer eigenen Lichtanlage benötigt (Mischpult, Steuersoftware, Dimmer, Scanner mit Iris, Shutter-Dimmer, 2 rotierenden Goborädern, 2 Farbrädern, CMY-Farbmischeinheit, Prisma, Fokus ...).&lt;br /&gt;
* [http://digital-enlightenment.de Digital Enlightenment ]Verschiedene DMX-Selbstbauprojekte&lt;br /&gt;
&lt;br /&gt;
===== PS2 =====&lt;br /&gt;
* [http://www.avrfreaks.net/index.php?module=Freaks%20Academy&amp;amp;func=viewItem&amp;amp;item_id=1086&amp;amp;item_type=project&amp;amp;timestamp=2007-09-04%2018:34:41 PC keyboard to an AVR]&lt;br /&gt;
&lt;br /&gt;
===== LANC =====&lt;br /&gt;
* [http://dsc.ijs.si/3dlancmaster/ 3D LANC Master from Damir Vrancic] is a device which keeps in synchronisation some of Sony camcorders by using LANC (CONTROL-L, ACC) protocol. (Open Hardware + Open Source, Atmega8).&lt;br /&gt;
* [http://jochendony.homeip.net/content/view/22/26/ LANC Lib] for AVRGCC. Read and write LANC commands.&lt;br /&gt;
* [http://blog.makezine.com/archive/2008/12/controlling_sony_camcorders_with_th.html Controlling Sony camcorders with the Arduino]&lt;br /&gt;
&lt;br /&gt;
===== MMC/SD-Card =====&lt;br /&gt;
* [http://www.roland-riegel.de/sd-reader/index.html MMC/SD card reader example application] von Roland Riegel (Atmega8, Atmega168 für FAT16)&lt;br /&gt;
* [http://www.captain.at/electronic-atmega-mmc.php MMC Flash] bzw.  [http://www.captain.at/electronic-atmega-sd-card.php SD Flash ] Memory Extension für Atmegas von Captain. (Atmega16, Atmega32)&lt;br /&gt;
* http://arm.hsz-t.ch MMC, SD, SDHC Kartentreiber für ARM7 Mikrocontroller&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/FAT32 Wiki und FAT16/32 Bibliothek für atmega]&lt;br /&gt;
&lt;br /&gt;
==== LC-Displays ====&lt;br /&gt;
&lt;br /&gt;
===== Text (character-mode) HD44870 =====&lt;br /&gt;
* [http://jump.to/fleury P.Fleury]&lt;br /&gt;
* avrfreaks Projekt 59 (Chris E.) und andere&lt;br /&gt;
* Procyon avrlib v. Pascal Slang (GPL)&lt;br /&gt;
* Bray&lt;br /&gt;
* [http://www.sprut.de/electronic/lcd/index.htm Spruts LCD-Seite]&lt;br /&gt;
* [http://elm-chan.org/docs/lcd/lcd3v.html Standard-LCD auf 3V betreiben (eng)]&lt;br /&gt;
* [http://www.harbaum.org/till/lcd2usb LCD2USB, LCD mit AVR am USB betreiben]&lt;br /&gt;
* [http://www.simon-brenner.ch/projekte/lcd-display 4x40 LCD Projekt, Microchip]&lt;br /&gt;
&lt;br /&gt;
===== Grafik T6963C etc. =====&lt;br /&gt;
&lt;br /&gt;
* http://www.holger-klabunde.de/avr/avrboard.htm#t6963&lt;br /&gt;
* [[Projekt T6963-LCD-Ansteuerung]] nur PC, keine Änderung seit Juli 2006&lt;br /&gt;
* avrfreaks.net - TOSHIBA_LCD_T6963C, AVR Graphics&lt;br /&gt;
* http://www.mikrocontroller.net/topic/48456 C&lt;br /&gt;
* http://www.mikrocontroller.net/topic/54563 C&lt;br /&gt;
* http://www.mikrocontroller.net/topic/48584 ASM&lt;br /&gt;
* [http://passworld.co.jp/ForumMSP430/viewtopic.php?t=47 Grafik LCDs] - 128 x 112 Grayscale für MSP430 und andere uCs.&lt;br /&gt;
* http://www.display3000.com/ Farb-TFT-Module inkl. Mikrocontroller (ATMega128; ATMega2561 und AT90CAN128)&lt;br /&gt;
* [http://www.tklinux.de/sed1330.html SED1330 an ATMega]. Library für SED 1330 controller an ATmega&lt;br /&gt;
In der Codesammlung gibt es auch für andere Controller was.&lt;br /&gt;
&lt;br /&gt;
===== Siemens S55/C60 =====&lt;br /&gt;
* [http://www.module.ro/siemens_lcd.html S55-Display Pinbelegung]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/22643 Forumbeitrag]&lt;br /&gt;
&lt;br /&gt;
===== Siemens S65/M65/CX65 =====&lt;br /&gt;
* [http://www.superkranz.de/christian/S65_Display/DisplayIndex.html S65-Display] vom Siemens S65/M65/CX65, 132x176 Pixel, 65536 Farben, günstig als Ersatzteil zu bekommen.&lt;br /&gt;
&lt;br /&gt;
===== Nokia 3210/3310 =====&lt;br /&gt;
* [http://www.jtronics.de/elektronik-avr/lcd-display-nokia3310 Bibliothek für Nokia 3310 Lcd Ansteuerung in &amp;quot;C&amp;quot; von http://www.jtronics.de - sehr gut (aktualisiert 2010)]&lt;br /&gt;
* [http://www.microsyl.com MicroSyl.Com]&lt;br /&gt;
&amp;lt;!-- * [http://www.microsyl.com/nokialcd/shematic.gif Belegung] --&amp;gt;&lt;br /&gt;
* [http://www.deramon.de/nokia3310lcd.php Deramon.de]&lt;br /&gt;
&amp;lt;!-- [[Bild:Beispiel.jpg]] --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Nokia 6100 LCD =====&lt;br /&gt;
&amp;lt;!-- * [http://www.apetech.de/article.php?artId=3&amp;amp;nnId=12 Nokia 6100 LCD Library] für Nokia-Displays 132x132 Pixel, 4096 Farben mit Philips Controller (bei eBay ziemlich preiswert zu ersteigern) --&amp;gt;&lt;br /&gt;
* [http://www.myplace.nu/mp3/download/download.php Yampp 7 Software Download Seite]: Archiv &amp;quot;yampp-7 with colour LCD firmware&amp;quot; enthält avr-gcc/avr-as Routinen für 6100-LCDs mit Philips- oder Epson-Controller (nicht direkt eine &amp;quot;Library&amp;quot;)&lt;br /&gt;
*[http://www.e-dsp.com/controlling-a-color-graphic-lcd-epson-s1d15g10-controller-with-an-atmel-avr-atmega32l/ S1D15G10]: Routine code für den Epson S1D15G10 Controller&lt;br /&gt;
*[http://thomaspfeifer.net/nokia_6100_display.htm Nokia 6100 Display am AVR] Anzeige von RGB-Bildern (für avr-gcc)&lt;br /&gt;
*[http://www.optixx.org/ www.optixx.org] Code zur Ansteuerung von Philips und Epson&lt;br /&gt;
*[http://www.zipfelmaus.com/nokia6100lcd_en/ http://www.zipfelmaus.com/nokia6100lcd_en/] --&amp;gt; unter Download: Tool zum Konvertieren von BMPs in h-Files zum Ausgeben auf dem Display&lt;br /&gt;
&lt;br /&gt;
===== KS0108 =====&lt;br /&gt;
* [http://hubbard.engr.scu.edu/embedded/avr/avrlib Procyon avrlib (GPL)]&lt;br /&gt;
* avrfreaks UP&lt;br /&gt;
* apetech.de nicht mehr erreichbar http://www.mikrocontroller.net/topic/68316&lt;br /&gt;
&lt;br /&gt;
====GPS====&lt;br /&gt;
* http://www.holger-klabunde.de/avr/avrboard.htm#GPSdisplay GPS-Daten auf LCD&lt;br /&gt;
* [http://www.geoclub.de/forum57.html www.geoclub.de] - Elektronik beim Geocaching&lt;br /&gt;
* [http://passworld.co.jp/ForumMSP430/viewtopic.php?t=22 passworld.co.jp] - Do It Yourself GPS&lt;br /&gt;
&lt;br /&gt;
== [[8051|8051 / MCS51]] ==&lt;br /&gt;
* [http://mcu8051ide.sourceforge.net/ MCU 8051 IDE] - MCU 8051 IDE is a new modern graphical IDE for microcontrollers based on 8051. MCU 8051 IDE is noncommercial open-source software for Linux.&lt;br /&gt;
* [http://www.rakers.de/catalog Dr. Rakers] Entwicklungssystem mit C-Compiler, BASIC-Compiler und Makroassembler für alle 8051-Mikrocontroller (80C552, 80C515(C), 80C537). Auch für Hobbyisten bezahlbar.&lt;br /&gt;
* [http://www.progshop.com/versand/software/prog-studio/index.html Prog-Studio] - Moderne Assembler Entwicklungsumgebung für 8051 Mikrocontroller mit Debugger, Edit &amp;amp; Continue, Code-Folding, Intelli-Sense, Monitorung und mehr&lt;br /&gt;
* [http://www.yCModule.de yCModule: µController-Systeme] - Preisgünstige µController-Module, ISP-Programmiertools und Applikationsboards&lt;br /&gt;
* [http://www.erikbuchmann.de/ Erik Buchmanns Mikrocontroller-Seite] - Assemblerkurs und mehrere Projekte&lt;br /&gt;
* [http://www.holger-klabunde.de/projects/8051.htm Experimentierboard für 8051 Controller] von Holger Klabunde.&lt;br /&gt;
* [http://www.woe.de.vu/ World Of Electronics] - Projekte mit den 8051-Controllern von Atmel&lt;br /&gt;
* [http://www.thomas-wedemeyer.de/elektronik/8051/8051.html Controllerplatine mit SAB80C535]&lt;br /&gt;
* [http://www.maxim.ph.tc Selbstbau-Programmer] für 2051er&lt;br /&gt;
* [http://www.nomad.ee/micros/8052bas.html 8052 BASIC Projects] - IDE-Interface&lt;br /&gt;
* [http://home.t-online.de/home/s.holst/sh51/index.html Mikrokontroller sh51] Schaltplan für 80C535-Board&lt;br /&gt;
* 8051-Makroassembler [http://plit.de/asem-51/ ASEM-51] (Freeware)&lt;br /&gt;
* [http://sdcc.sourceforge.net/ SDCC - Small Device C Compiler] - freier ANSI-C compiler für Intel 8051, Maxim DS80C390 und Zilog Z80 kompatible Controller.&lt;br /&gt;
* [http://sdccokr.dl9sec.de/ The SDCC Open Knowledge Resource]&lt;br /&gt;
* [http://www.wickenhaeuser.de/ Wickenhäuser C Compiler] - Preisgünstiger C Compiler&lt;br /&gt;
* [http://home.tiscali.cz:8080/~cz056018/lanc_a.htm LANC-Remote] Projekt von Ji&amp;amp;#345;í &amp;amp;#352;mach zur Steuerung von Videorekordern oder Camcordern über das Control-L (LANC) Protokoll mit Hilfe eines AT89C2051.&lt;br /&gt;
* [http://www.microcontroller-starterkits.de Microcontroller-Starterkits] Starter-Kits für verschiedene Microcontroller (D) preisgünstige Platinen (ab 12,95 Euro für AT89S8252). Beim uC-Dualboard : Das Board ist nutzbar mit AVR-Controllern und 8051-Controllern!&lt;br /&gt;
* [http://turbo51.com Turbo51 - Free Pascal compiler for 8051]&lt;br /&gt;
* [http://self8051.de/ self8051.de] - Dein Nachschlagewerk - Befehlsreferenz, Eigenschaften, Derivate&lt;br /&gt;
* [http://cmon51.sourceforge.net/ CMON51] - freier Onboard Monitor und Debugger, anpassbar an unterschiedliche 8051 kompatible Mikrocontroller&lt;br /&gt;
* [http://et-tutorials.de/632/kostenloser-mikrocontroller-kurs/ Mikrocontroller Video Tutorial] Video-Tutorial für Einsteiger (C-Kurs + Einführung 8051)&lt;br /&gt;
&lt;br /&gt;
== MSP430 ==&lt;br /&gt;
* [http://www.mikekohn.net/micro/naken430asm_msp430_assembler.php naken430msp] -   MSP430 Assembler von Michael Kohn (GPL)&lt;br /&gt;
* [http://www.mathar.com MSP430 Tutorials] - Tutorials, Anleitungen und viele Beispielprojekte mit dem MSP430-Mikrocontroller&lt;br /&gt;
* [http://www.student-zw.fh-kl.de/~stwi0001/imp/msp430/pwm430/index.htm Pulsweitenmodulation mit dem MSP430] - sehr ausführliche Einführung&lt;br /&gt;
* [http://www.thomas-wedemeyer.de/elektronik/msp430/msp430.html Kleine Projekte mit dem MSP430] - Schaltplan und Layout zu einem MSP430F149-Board und einem ADXL-G-Sensor mit MSP430&lt;br /&gt;
* [http://tinymicros.com/embedded/MSP430/ The MSP430 Bugspray Database] - umfangreiche Datenbank für Bugs in MSP430-Controllern&lt;br /&gt;
* [http://msp430.info MSP430.info] - Portalseite für MSP430; Info, Projekte (MIDI, USB)&lt;br /&gt;
* [http://groups.yahoo.com/group/msp430 Yahoo group MSP430] - lebhaftes Forum mit vielen MSP430-Experten&lt;br /&gt;
* [http://homepage.hispeed.ch/py430/mspgcc/ mps430-gdb und Eclipse] - Eine Anleitung von Chris Liechti&lt;br /&gt;
* [http://passworld.co.jp/ForumMSP430 Forum MSP430] - Projekte mit MSP430 (GPS, BlueTooth usw...)&lt;br /&gt;
* TI Design-Wettbewerb: http://www.designmsp430.com/View.aspx (Dateien liegen evtl. in /projects/) [2011-01-24: redirect zum TI Wiki, Projekte nicht mehr vorhanden]&lt;br /&gt;
* [http://www.sics.se/project/mspsim MSPsim] - a Java-based simulator of MSP430 sensor network platforms (BSD License (revised))&lt;br /&gt;
* [http://develissimo.net/de/msp430entwicklung MSPGCC + Eclipse + msp430-gdbproxy / Linux / Debian / Ubuntu] - Anleitung / Tutorial zur Installation der MSPGCC Toolchain + Eclipse + msp430-gdbproxy für Linux / Debian / Ubuntu Lang=Deutsch und Englisch&lt;br /&gt;
* [http://travisgoodspeed.blogspot.com/ Travis Goodspeed&#039;s Blog] - Home of the [http://goodfet.sourceforge.net/ GoodFET] Programmer&lt;br /&gt;
* [http://www.43oh.com/ Four-Three-Oh!]&lt;br /&gt;
&lt;br /&gt;
=== MSP430 Launchpad ===&lt;br /&gt;
* [http://processors.wiki.ti.com/index.php/MSP430_LaunchPad_(MSP-EXP430G2)?DCMP=launchpad&amp;amp;HQS=Other+OT+launchpadwiki MSP430 LaunchPad Wiki] bei TI&lt;br /&gt;
* [http://hackaday.com/2010/08/11/how-to-launchpad-programming-with-linux/ How-to: Launchpad programming with Linux] auf hackaday.com&lt;br /&gt;
* [http://springuin.nl/en/articles/launchpadwindows TI Launchpad programming and debugging with Open Source tools on Windows] (Eclipse, MSPGCC4, Insight, msp430-gdbproxy)&lt;br /&gt;
* [http://osx-launchpad.blogspot.com/ MSP430 LaunchPad toolchain for Mac OS X]&lt;br /&gt;
&lt;br /&gt;
=== EZ430 Chronos ===&lt;br /&gt;
* [http://processors.wiki.ti.com/index.php/EZ430-Chronos?DCMP=Chronos&amp;amp;HQS=Other+OT+chronoswiki EZ Chronos Wiki] bei TI&lt;br /&gt;
&lt;br /&gt;
== ARM ==&lt;br /&gt;
&lt;br /&gt;
=== Herstellerseiten ===&lt;br /&gt;
* [http://www.arm.com ARM] - Entwickler des ARM-Prozessorkerns (kein Hersteller von ICs)&lt;br /&gt;
* [http://infocenter.arm.com ARM Infocenter] Sammlung Technischer Informationen&lt;br /&gt;
&lt;br /&gt;
* [http://www.analog.com/ Analog Devices] ADuC7xxx ARM7TDMI Serie unter &#039;&#039;Analog Microcontrollers&#039;&#039;&lt;br /&gt;
* [http://www.atmel.com/products/AT91/ Atmel AT91 Startseite]&lt;br /&gt;
* [http://www.at91.com AT91.COM] - Atmel ARM Informationsseite (Forum, Beispielcodes etc.)&lt;br /&gt;
* [http://www.cirrus.com/en/products/pro/techs/T7.html Cirrus Logic]&lt;br /&gt;
* [http://www.energymicro.com/ Energy Micro] EFM32 mit Cortex M3 Kern&lt;br /&gt;
* [http://www.freescale.com/mac7100 Freescale MAC7100]&lt;br /&gt;
* [http://www.hilscher.com Hilscher netX] (ARM926 core)&lt;br /&gt;
* [http://www.intel.com/design/intelxscale/ Intel XSCALE Startseite], siehe auch [http://www.marvell.com/ Marvell]&lt;br /&gt;
* [http://www.luminarymicro.com/ Luminiary Micro (TI)] Controller mit Cortex M3 core&lt;br /&gt;
* [http://www.standardics.nxp.com/microcontrollers/ NXP (ehemals Philips) Microcontroller Startseite] für sämtliche Mikrocontroller (ARM7, ARM9, Cortex-M0, -M3, MCS51 etc.), neben LPC2000, LPC3000 auch die LH7xxxx BlueStreak-Serie (ehemals Sharp Microelectronics)&lt;br /&gt;
* [http://www.lpc2000.com lpc2000.com] Infoseite für NXP (ex. Philips) LPC1700 Cortex-M3 basierende Typen, LPC2000, ARM7 basierende Typen und LPC3000, ARM9 basierende Typen. Auch andere Cortex-M3 Bausteine sind erfasst&lt;br /&gt;
* [http://www.okisemi.com/eu/1.Products/ARM32bit.html OKI ARM-Controller Startseite]&lt;br /&gt;
* [http://www.samsung.com/Products/Semiconductor/ Samsung] ARM7/9 unter &#039;&#039;Mobile SoC&#039;&#039;&lt;br /&gt;
* [http://mcu.st.com/mcu/ STMicroelectronics (ST) Microcontroller Startseite] u.a. STR7, STR9, STM32 Support-Forum&lt;br /&gt;
* [http://www.ti.com/ Texas Instruments] TMS470 ARM7TDMI Serie&lt;br /&gt;
* [http://www.toshiba.com/taec/ Toshiba] Controller mit ARM9 und Cortex-M3 core&lt;br /&gt;
&lt;br /&gt;
=== Information (Foren, Mailinglisten, Linksammlungen) ===&lt;br /&gt;
* [http://www.neko.ne.jp/~freewing/cpu/arm_olimex/ Freewing Linksammlung] zu den NXP (ex. Philips) LPC-ARM7-Controllern (Assemblerbeispiele u.a. für Nokia 3310-GLCD)&lt;br /&gt;
* [http://www.open-research.org.uk/ARMuC ARM Microcontroller Wiki]&lt;br /&gt;
* [http://arm.hsz-t.ch arm.hsz-t.ch] Einfühung in ARM7 Mikrocontroller und uClinux.&lt;br /&gt;
* [http://tech.groups.yahoo.com/group/ADuC7000/ ADuC7000 Yahoo-Group]&lt;br /&gt;
* [http://www.at91.com AT91 Forum] (Atmel Rousset)&lt;br /&gt;
* [http://tech.groups.yahoo.com/group/AT91SAM/ AT91SAM Yahoo-Group]&lt;br /&gt;
* [http://en.mikrocontroller.net/forum/17 arm-elf-gcc WinARM Forum] (auch für Yagarto)&lt;br /&gt;
* [http://www.codesourcery.com/archives/arm-gnu/maillist.html Sourcery G++ Lite Edition User Forum/Mailing-List]&lt;br /&gt;
* [http://tech.groups.yahoo.com/group/gnuarm/ GNUARM Yahoo-Group]&lt;br /&gt;
* [http://www.keil.com/forum/ Keil/ARM Forum]&lt;br /&gt;
* [http://groups.yahoo.com/group/lpc2000/ LPC2000 Yahoo-Group]&lt;br /&gt;
* [http://www.mcu-related.com MCU related] Neuigkeiten zu MCUs, überwiegend ARM / Cortex-M3 basierend mit Vergleichen von RTOS und anderen Entwicklungstools&lt;br /&gt;
* [http://forum.sparkfun.com/ Sparkfun Foren]&lt;br /&gt;
* [http://mcu.st.com/mcu/modules.php?name=Splatt_Forums STMicroelectronis Forum]&lt;br /&gt;
* [http://www.stm32circle.com/ Forum for STM32 moderated by Raisonance] Sehr viele Beispielprogramme in Source fuer STM32 und den Primer2 von Raisonance&lt;br /&gt;
&lt;br /&gt;
=== Entwicklungswerkzeuge (Compiler/Assembler/Debugger/Tools) ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.st-angliamicro.com/software.asp Anglia Idealist IDE und Anglia Toolchain] GNU toolchain für Win32-hosts inkl. Beispielen für STR7, STR9 und STM32. IDE kostenlos aber registrierungspflichtig&lt;br /&gt;
* [http://atollic.com/ attolic] TrueSTUDIO&lt;br /&gt;
* [http://www.codesourcery.com/gnu_toolchains/ Codesourcery] GNU Toolchains für ARM (Hosts: Linux, MS Windows, Solaris; Targets: &amp;quot;bare-metal&amp;quot;, arm-linux, SybianOS)&lt;br /&gt;
* [http://devkitpro.org/ devkitPro/devkitARM] GNU-Toolchain für MS-Windows &amp;quot;Hosts&amp;quot;. Vor allem auf GBA abgestimmt aber auch für andere ARM-Controller geeignet&lt;br /&gt;
* [http://www.ghs.com/ Green Hills Software]&lt;br /&gt;
* [http://www.hitex.de Hitex] IDE für diverse Compiler, Debugger&lt;br /&gt;
* [http://www.iar.com IAR] Embedded Workbench, kommerzielle IDE/Compiler, codegrößenbeschränkte Evaluierungsversion verfügbar&lt;br /&gt;
* [http://www.isystem.com/ iSYSTEM] Integrated Development Environment, USB/JTAG interface, OnChip Emulation and Trace&lt;br /&gt;
* [http://www.keil.com Keil/ARM MDK-ARM] kommerzielle IDE/Compiler, unterstützt zwei Compiler (ARM RealView, GNU/gcc), codegrößenbeschränkte Evaluierungsversion verfügbar (IDE/Compiler unbeschränkt für GNU), guter Debugger, sehr guter Simulator, Simulator und Debugger in der Evaluierungsversion auch bei Nutzung der GNU-Toolchain mit Größenbeschränkung&lt;br /&gt;
* [http://mct.de/download.html#free MCT Demoversion C-Compiler für ARM und 68k] ARM C-Compiler basiert auf GCC laut Herstellerinformation jedoch mit Codegrößenbeschränkung &amp;lt;!-- etwas ungewöhnlich: Codegrößenbeschränkung bei GNU-Toolchain --&amp;gt;&lt;br /&gt;
* [http://www.mpeforth.com www.mpeforth.com] - A free Forth system with 125 page manual for all Philips LPC2xxx CPUs with at least 64k Flash and 16k RAM and cystal frequency of 10, 12, or 14.7456 MHz. &lt;br /&gt;
* [http://www.raisonance.com/ Raisonance] Ride, RKit-ARM&lt;br /&gt;
* [http://www.rowley.co.uk/ Rowley] Kommerzielle IDE für GNU-Compiler, eigene libc (nicht newlib), Debugger (inkl. gutem Support für Wiggler)&lt;br /&gt;
* [http://h-storm.tantos.homedns.org/gcc_arm.htm Tantos gcc for ARM Targets] eine weitere ARM-GNU-Toolchain für MS-Windows &amp;quot;Hosts&amp;quot; &lt;br /&gt;
* [http://www.yagarto.de Yagarto] GNU arm-eabi-Toolchain, Eclipse, OpenOCD für Win32 inkl. Setup&lt;br /&gt;
* [http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/index.html#winarm WinARM] eine an WinAVR angelehnte Sammlung von Entwicklungswerkzeugen (binutils, arm-elf-gcc, newlib, &#039;&#039;newlib-lpc&#039;&#039;, Programmers Notepad, &#039;&#039;Beispiel-Makefiles und Beispielcode&#039;&#039;) für alle ARM-Controller. Beispiele für Philips LPC2000 und Atmel AT91SAM7S (ARM7TDMI) u.a.&lt;br /&gt;
* [http://rtlab.tekproj.bth.se/wiki/index.php/Dissy#Architecture_support Dissy] is a disassembler for Linux and UNIX which supports multiple architectures and allows easy navigation through the code. Dissy is implemented in Python and uses objdump for disassembling files.&lt;br /&gt;
* [http://www.sinelabore.com sinelaboreRT] - generiert leicht lesbaren C-Code aus einer Zustandsmaschine. Die Generierung berücksichtig speziell die Bedürfnisse eingebetteter Echtzeitsysteme.&lt;br /&gt;
* http://arm.hsz-t.ch Entwicklungsumgebung für ARM7 Mikrocontroller basierend auf der Knoppix CD. Keine Harddisk installation nötig für uClinux.&lt;br /&gt;
&lt;br /&gt;
* [http://openocd.berlios.de/web/ OpenOCD] Open On-Chip Debugger: Schnittstelle (&amp;quot;gdb-Server&amp;quot;) zwischen verschiedenen JTAG-Interfaces (u.a. auf FTDI2232-Basis, &amp;quot;Wiggler&amp;quot;-ParPort und andere) und GNU-debugger (gdb/Insight-gdb) Flash-Programmierfunktion für LPC2k, AT91SAM7S, LM3S, STM32 und viele andere interne und externe Flashspeicher (Open Source, GPL, unter anderem auf MS Windows und Linux lauffähig)&lt;br /&gt;
* [http://macraigor.com/full_gnu.htm OCDLibRemote] Schnittstelle zwischen WIGGLER-kompatibler JTAG Hardware und dem GNU-Debugger (gdb)&lt;br /&gt;
* [http://gdb-jtag-arm.sourceforge.net/ GDB-JTAG-ARM] GDB JTAG Tools&lt;br /&gt;
* [http://jtagpack.sourceforge.net/ JTAG-Pack] GDB JTAG Tools&lt;br /&gt;
* [http://www.hjtag.com H-JTAG] RDI-Interface für Wiggler, Flash-Funktionen für diverse interne und externe Speicher&lt;br /&gt;
* [http://www.clibb.de/ lpc21isp] Flashutility für LPC21xx, ISP via &amp;quot;Bootloader&amp;quot; (&amp;quot;multiplattform&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
*[http://www.abatron.ch Abatron] BDI1000 &amp;amp; BDI2000, On-Chip Debuggers für ARM, 68k, Coldfire uvm.&lt;br /&gt;
* [http://www.amontec.com Amontec] JTAGkey, JTAGkey2(P): JTAG-Adapter auf Basis des FTDI2232(H) &lt;br /&gt;
* [http://www.hjtag.com/product_intro.html H-JTAG USB Emulator]&lt;br /&gt;
* [http://www.keil.com Keil/ARM ULINK/ULINK2/ULINK-ME] JTAG-Adapter, USB-Anschluss, wird von Keil uVision unterstützt, ULINK2 teilw. auch von Codesourcery G++ (lt. Hestellerangaben)&lt;br /&gt;
* [http://www.kristech.eu Kristech] USB-Scarab, JTAG Adapter, kommt mit eigener Debugger-UI, kompatibel zu Olimex&lt;br /&gt;
* [http://www.lauterbach.de Lauterbach] TRACE32 JTAG-Adapter, USB und Ethernet-Anschluss, eigene Software&lt;br /&gt;
* [http://www.olimex.com Olimex] JTAG-Adapter: Wiggler-Nachbau (ParPort) und  Adapter auf Basis des FTDI2232 (USB)&lt;br /&gt;
* [http://www.ronetix.at/peedi.html Ronetix Peedi]&lt;br /&gt;
* [http://www.segger.de Segger J-Link] JTAG-Adapter, USB-Anschluss, unterstützt z.&amp;amp;nbsp;B. von IAR, Keil uVision (via RDI) (OEM: IAR J-Link, SAM-ICE)&lt;br /&gt;
* [http://www.signalyzer.com/ Signalyzer] Signalyzer Tool, u.a. JTAG-Adapter auf Basis des FTDI2232&lt;br /&gt;
* [http://www.simonqian.com/en/Versaloon/index.html Simon Qians Versaloon]&lt;br /&gt;
&lt;br /&gt;
=== Tutorials und Beispiele ===&lt;br /&gt;
* [http://www.dreamislife.com/arm/ LPC210x ARM7 Microcontroller Tutorial] - Assembler-Beispiele (arm-elf-as) für das Olimex LPC-MT-Board (Philips LPC2106 ARM7TDMI)&lt;br /&gt;
* [http://re-eject.gbadev.org/index.php gcc-Assembler für ARM] - Befehlsübersicht&lt;br /&gt;
* [http://patater.com/gbaguy/gbaasm.htm GBA ASM Tutorial] - ARM7 Assembler Tutorial mit arm-elf-as (&amp;quot;gcc&amp;quot;) (Allgemein und GBA)&lt;br /&gt;
* [http://www.robsite.de/daten/tutorials/devgba/gba_asm1.html GBA Assembler Tutorial] - ARM7TDMI, Schwerpunkt auf GBA&lt;br /&gt;
* [http://www.sparkfun.com/tutorial/ARM/ARM_Cross_Development_with_Eclipse.pdf Eclipse+CDT+gnuarm-Tutorial]&lt;br /&gt;
* [http://mct.de/download/armsamples/map.html Beispiele in C, für ARM7-Controller von Philips und ADI]&lt;br /&gt;
* [http://www.embedded.com/design/opensource/201802580 Embedded.com: Building Bare-Metal ARM Systems with GNU] Teil 10, Links zu den Teilen 1-9 auf der Seite&lt;br /&gt;
* [http://www.sparkfun.com/datasheets/DevTools/SAM7/at91sam7%20serial%20communications.pdf AT91SAM7 Serial Communications] von James P. Lynch (PDF, www.sparkfun.com)&lt;br /&gt;
* [http://www.kaczurba.pl/aduc ADuC7000 Tutorial] von Witold Kaczurba (www.kaczurba.pl)&lt;br /&gt;
&lt;br /&gt;
=== Projekte und Quellcodebibliotheken ===&lt;br /&gt;
* [http://hubbard.engr.scu.edu/embedded/arm/armlib/ Procyon ARMlib-LPC2100] - Treiber, Beispiele (Lizenz: GPL, kaum weiterentwickelt)&lt;br /&gt;
* [http://www.standardics.nxp.com/support/documents/?type=software NXP BlueStreak] Code für LH7xxxx (ehemals Sharp)&lt;br /&gt;
* [http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/index.html M. Thomas&#039; ARM Projekte] &amp;quot;Projectvorlagen&amp;quot; für AT91SAM7 und LPC2000 mit GNU-Toolchain Einsteiger-Projekte für AT91SAM7, LPC2000, ADuC7000 u.a. (u.a. Blinky, UART, Interrupt, C++, GLCD mit KS0108, DS18x20, DCF77, Anpassungen von FAT16/32-Libraries) &amp;lt;!-- noch mehr &amp;quot;Eigenwerbung&amp;quot; --&amp;gt;&lt;br /&gt;
* [http://mcu.st.com/ STMicro] Treiber und Beispiel für STR7, STR9 und STM32&lt;br /&gt;
* [http://wiki.sikken.nl/index.php?title=LPCUSB LPCUSB] - Open-source [[USB]] stack for the built-in USB controller in LPC214x microcontrollers von Bertrik Sikken. [http://lpcusb.cvs.sourceforge.net/lpcusb/host/benchmark/main.c?revision=1.2&amp;amp;view=markup Sample code]&lt;br /&gt;
* [http://www.olimex.com Olimex] Einige Beispiele auf den &amp;quot;Produktseiten&amp;quot; der ARM Boards.&lt;br /&gt;
* [[ARM MP3/AAC Player]]&lt;br /&gt;
* [http://www.jcwren.com/arm/ J.C. Wrens Beispielprojekt] für LPC214x&lt;br /&gt;
* [http://www.keil.com/download/list/arm.htm Beispiele von Keil] abgestimmt auf deren Boards und Realview-Toolchain, Portierung auf andere Boards und Compiler relativ einfach, Lizenz beachten.&lt;br /&gt;
* [http://www.luminarymicro.com/ Luminary Micro Driverlib] für Stellaris Cortex-M3&lt;br /&gt;
* [http://r2d2.stefanm.com/gps-tracker.html GPS-Tracker] mit Navigation auf LPC2103-Basis (Complier: GCC)&lt;br /&gt;
* [http://elua.berlios.de elua] Lua für ARM-controller&lt;br /&gt;
* [http://freemodbus.berlios.de/ FreeMODBUS] &amp;quot;A Modbus ASCII/RTU and TCP implementation&amp;quot; (für STR71x, AT91SAM7, LPC214x, auch: AVR, MSP430 u.a.)&lt;br /&gt;
* [http://bettyhacks.com BettyHacks] Freie Firmware für die &amp;quot;interaktive TV-Fernbedienung&amp;quot; betty-tv (ARM7tdmi, 2MB Flash, 160 x 128 Pixel 2 bit LCD, CC1100, IR, Lautsprecher,..)&lt;br /&gt;
&lt;br /&gt;
=== Betriebssysteme ===&lt;br /&gt;
* [http://agnix.sourceforge.net/ Agnix]&lt;br /&gt;
* [http://www.bertos.org/ BeRTOS] is a completely free, open source, real time operating system (RTOS) suitable for embedded platforms. Runs on many microprocessors and microcontrollers, ranging from 8 bits to 32 bits CPUs and even PCs. &lt;br /&gt;
* [http://chibios.sourceforge.net/ ChibiOS/RT]&lt;br /&gt;
* [http://www.stm32circle.com/resources/upgrade.php Circle-OS for STM32] Kostenloses OS, sehr klein mit Basisfunktionen fuer STM32&lt;br /&gt;
* [http://coocox.org/ CoOS]&lt;br /&gt;
* [http://sources.redhat.com/ecos/ eCos] - &amp;quot;Real-Time-Operating-System&amp;quot; o.a. auch für ARM7&lt;br /&gt;
* [http://www.freertos.org/ FreeRTOS (.org!)] - &amp;quot;Real-Time-Kernel&amp;quot; unter anderem für ARM7 (LPC2xxx) auch AVR, MSP430, &#039;51er&lt;br /&gt;
* [http://sourceforge.net/projects/funkos/ FunkOS]&lt;br /&gt;
* [http://l4ka.org/ L4Ka]&lt;br /&gt;
* [http://www.toradex.com/colibri_downloads/Linux/readme.txt Linux 2.4.29 für Toradex Colibri] basierend auf Intel XScale PXA270&lt;br /&gt;
* [http://www.linux4sam.org Linux4SAM] Informationen, Anleitungen und Code zur Anwendung von Linux auf AT91SAM9xxx&lt;br /&gt;
* [http://www.freertos.com/ NicheTask] (URL ist www.freertos.com aber hat nichts mit FreeRTOS(.org) zu tun)&lt;br /&gt;
* [http://www.ethernut.de/en/software/index.html Nut/OS] Echtzeitbetriebssystem für Mikrocontroller (ARM, AVR, AVR32, Cortex M3 u.A). Multitasking und vollständiger TCP/IP Stack inklusive. Leicht zu erlernen und viele Beispiele&lt;br /&gt;
* [http://nuttx.sourceforge.net/ NuttX RTOS] (ARM7TDMI port for TI TMS320C5471 also called a C5471 or TMS320DM180).&lt;br /&gt;
* [http://www.phoenix-rtos.org/ Phoenix-RTOS]&lt;br /&gt;
* [http://picoos.sourceforge.net/ PicoOS]&lt;br /&gt;
* [http://prex.sourceforge.net Prex] is a portable real-time operating system for embedded systems. The small, reliable, and low power kernel is written in the C language based on microkernel design. The file system, Unix process, and networking features are provided by user mode tasks. (ARM, i386, geplant: MIPS, PowerPC, Hitachi-SH und Win32)&lt;br /&gt;
* [http://www.rtems.org/ RTEMS]&lt;br /&gt;
* [http://code.google.com/p/rt-thread/ rt-thread]&lt;br /&gt;
* [http://sourceforge.net/projects/scmrtos/ scmRTOS]&lt;br /&gt;
* [http://www.tnkernel.com/downloads.html TNKernel] - &amp;quot;Real-Time-Kernel&amp;quot; TNKernel ist ein kompakter und sehr schneller Echtzeitkernel unter anderem für ARM7 (Philips LPC2106/LPC21XX/LPC22xx, Samsung S3C44B0X, Atmel AT91SAM7S128, STMicroelectronics STR711FR2)&lt;br /&gt;
* [http://www.ucos-ii.com/ uC/OS-II RTOS]&lt;br /&gt;
&lt;br /&gt;
=== Hardware (Prototypen-Platinen etc.) ===&lt;br /&gt;
&amp;lt;!-- Veralteter Link; Shop verkauft &amp;quot;nichts&amp;quot; mehr * [http://www.knif-elektronik.de/index.php/cPath/27/category/industrie-module-/-bausaetze.html/ KNIF-elektronik] Preisgünstige Industriemodule und Bausätze z.B GPS, W-Lan, Kamera,Bluetooth uvm. --&amp;gt;&lt;br /&gt;
&amp;lt;!-- Ist KEIN ARM-Board, falsche Rubrik! * [http://www.chip45.com/ chip45] Atmel AVR Module und Boards mit USB, RS232/485, CAN, Ethernet, Funkmodule, sowie ISP Programmieradapter --&amp;gt;&lt;br /&gt;
* [http://www.armkits.com/ Embest] Philips, Samsung und Atmel ARM Boards und Module, JTAG-Hard- und Software&lt;br /&gt;
* [http://www.waveplayer.de/ Embedded-Waveplayer] mit ARM7-Prozessor EP7309 (MIDI- und RS232-Steuerung)&lt;br /&gt;
* [http://www.embeddedartists.com/ Embedded Artists] bietet verschiedene preisgünstige Platinen (ab 25 Euro für LPC213x Familie)&lt;br /&gt;
* [http://www.embedded-it.de/microcontroller/microcontroller-module.php Embedded-IT] eNet-sam7X: Ethernut kompatible Embedded Ethernet Mikrocontroller Boards für Industrie und Hobby auf ARM mit Nut/OS Betriebssystem sowie USB Module auf AVR Basis&lt;br /&gt;
* [http://www.hiteg.com Hiteg] SAMSUNG und Intel XScale basierende boards. (Deutsches Unternehmen in China)&lt;br /&gt;
* [http://www.hitex.de/ Hitex] Starter-Kits für Philips LPC2000, ST STR7, Atmel AT91M&lt;br /&gt;
* [http://www.iar.com/ IAR] Starter-Kits für Atmel, Oki, Philips, ST und TI &lt;br /&gt;
* [http://www.ic-board.de/index.php?cat=c12_ICswift-Module.html ic-board.de] Kommunikationsplattform auf Basis des AT91SAM7X256 mit Ethernet, USB, CAN und Funk Schnittstellen&lt;br /&gt;
* [http://www.keil.com/ Keil] Philips LPC2000 und ST STR7/9 Boards und Starter-Kits&lt;br /&gt;
* [http://www.lpctools.com/ LPCTools] bietet verschiedene Starter Kits für die LPC2000-Familie&lt;br /&gt;
* [http://www.makingthings.com/ MakingThings] Make Controller Kit (AT91SAM7X256)&lt;br /&gt;
* [http://mct.de/index.html MCT Paul und Scherer] Starterkits für ARM7 (NXP LPC2000, ADI ADUC7000)&lt;br /&gt;
* [http://shop.mikrocontroller.net Mikrocontroller.net Shop] Platinen mit AT91SAM7, LPC2xxx, JTAG&lt;br /&gt;
* [http://www.microcontroller-starterkits.de Microcontroller-Starterkits] Starter-Kits für verschiedene Microcontroller (D) preisgünstige Platinen (ab 12,95 Euro für LPC2129 und 2194) sowie Entwicklungsboard komplett bestückt&lt;br /&gt;
* [http://stores.ebay.de/Micro-Research Micro-Research] Development- und Header-Boards für LPC2000 und ADuC7000&lt;br /&gt;
* [http://www.olimex.com Olimex] Bulgarischer Anbieter günstiger ARM Prototypen- und Header-Boards (LPC2000, STR7, AT91SAM, ADI, TI, OKI u.a.)&lt;br /&gt;
* [http://www.propox.com/?lang=en Propox]&lt;br /&gt;
* [http://www.mcu-raisonance.com/~primer-starter-kits__microcontrollers__tool~tool__T018:4enfvamuxbtp.html Primer2 from Raisonance] Focus auf STM32 mit sehr grossem Forum im STM32circle&lt;br /&gt;
* [http://www.revely.com/ Revely] Evaluations- und Demo-Boards mit Sharp ARM Controllern. Teilweise mit SVGA-Anschluss.&lt;br /&gt;
* [http://www.skpang.co.uk/catalog/index.php SKPang electronics] Entwicklungsboards für diverse ARM7/9 (UK)&lt;br /&gt;
* [http://www.dilnetpc.com SSV Embedded Systems] bietet verschiedene Starter Kits für die verschiedenen DIL/NetPC u.a. (A)DNP/9200 SBC mit AT91RM9200&lt;br /&gt;
* [http://www.taskit.de taskit] [https://www.ledato.de/shop_content.php?coID=10 Development- und Header-Boards für AT91SAM7S/X], AT91RM9200, AT91SAM9&lt;br /&gt;
* [http://www.toradex.com/e/products.html Toradex] Colibri: Intel XScale PXA270 DevKit (Schweiz)&lt;br /&gt;
&lt;br /&gt;
== [[PIC]] ==&lt;br /&gt;
&lt;br /&gt;
=== Herstellerseiten ===&lt;br /&gt;
* [http://www.microchip.com Microchip] Hersteller der PIC Microcontroller&lt;br /&gt;
* [http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=1406&amp;amp;dDocName=en010014&amp;amp;part=SW006011 Microchip C18 Student Edition] - die &amp;quot;Student Edition&amp;quot; des Microchip C18 C Compilers für die PIC18 Serie ist kostenlos verfügbar.&lt;br /&gt;
* [http://www.powercontact.de Elektronikentwicklung von Systemtechnik LEBER] Offizieller Microchip Design Partner für professionelles Microcontroller Design und Hersteller von Leistungsstellern, Thyristorstellern und Halbleiterelais...&lt;br /&gt;
&lt;br /&gt;
=== Entwicklungstools / Tutorials / Foren  ===&lt;br /&gt;
* [http://www.osterer.co.at www.osterer.co.at] Entwicklungs-Board mit integrierten Programmer/Debugger für PIC18F4550.&lt;br /&gt;
* [http://www.martins-elektronikwelt.tk www.martins-elektronikwelt.tk] ICD1-Debugger-Nachbau im Kleinstformat u. SMD Technik (so groß wie eine halbe Scheckkarte).&lt;br /&gt;
* [http://www.sprut.de/electronic/pic/index.htm PIC-Microchip-Controller (www.sprut.de)] Diese Seite soll dem Anfänger die ersten Schritte in die Welt der Microcontroller der Firma Microchip erleichtern. Betrachtet werden die 14-Bit-Controller der Serien PIC16Fxxx bzw PIC12Fxxx.&lt;br /&gt;
* [http://pic-projekte.de/ PIC-Projekte.de] Tutorials (u.a. für PIC C) und Projekte mit erklärten Codesnipseln (geeignet für Anfänger), [http://pic-projekte.de/phpBB3/ deutschsprachiges PIC Forum]&lt;br /&gt;
* [http://www.fernando-heitor.de PIC: Programmierung in CCS (www.fernando-heitor.de)] Dies ist eine weitere Seite, die dem Anfänger, der sich mit PICs beschäftigt, auf die Beine hilft. Sie befasst sich hauptsächlich mit dem CCS-Compiler und hat dazu ein sehr gutes Tutorial. Ausserdem bietet die Seite ein Forum speziell für PIC Mikrocontroller.&lt;br /&gt;
* [http://www.cc5x.de CC5X] Programmierkurs für PIC-Mikrocontroller in C (CC5X Compiler)] Programmierkurs mit Beispielen und Schaltplänen, fertige Hardware- und Softwarelösungen. In diesem Kurs sind auch einige Unterprogramme detailliert erklärt.&lt;br /&gt;
* [http://www.microchipc.com/ MicrochipC.com] Programmieren von PIC-Microcontrollern mit C. (Enthält auch Links und Bootloader für diverse PICs.)&lt;br /&gt;
* [http://www.amodio.biz/projects/PIC10BaseT/index.html Internetworking with Microchip Microcontrollers - PIC18F4620+ENC28J60]&lt;br /&gt;
* [http://pic18fusb.online.fr/wiki/wikka.php?wakka=WikiHome Wiki about Microchip USB PIC] (PIC18F2550, PIC18F4550...)&lt;br /&gt;
* [http://members.aon.at/electronics/pic/picpgm/index.html PICPgm - A free and simple PIC Development Programmer Software for Windows and Linux] Einfacher PIC Programmer für Windows und Linux. Unterstützt eine Vielzahl von PIC-Chips und wird ständig erweitert. Derzeit können PIC10F, PIC12F, PIC16F, PIC18F, PIC24H  sowie dsPIC30F und dsPIC33F programmiert werden.&lt;br /&gt;
* [http://www.stolz.de.be InCircuit-Programmer und -Debugger (www.stolz.de.be)] Einfacher Nachbau des Microchip ICD2s. Zum Programmieren und Debuggen.&lt;br /&gt;
* [http://www.winpicprog.co.uk WinPicProg] Programmer und Tutorials für Anfänger von Nigel Goodwin (Englisch)&lt;br /&gt;
* [http://usbpicprog.org/ usbpicprog], an open source Microchip PIC programmer for the USB port. A wxWidgets based (cross platform) application to communicate with the usbpicprog hardware / firmware. This application is known to function well on Linux, Windows (XP or later) and Macosx.&lt;br /&gt;
* [http://www.tigal.com EasyPIC3, EasyPIC4, Easy8051A, EasyAVR, Easy-was-weiss-ich (www.tigal.com)] - Distributor für Produkte von [http://www.mikroelektronika.co.yu mikroelektronika] und weiteren Herstellern&lt;br /&gt;
*[http://www.pro-zukunft.de Pro Zukunft] Evaluation-Board für PIC16F84A, hands-on-training und Print-Lehrgang. Für Schulen, Ausbildungsbetriebe &amp;amp; Hobbyelektroniker.&lt;br /&gt;
* [http://www.wselektronik.at www.wselektronik.at] Bausatz für &amp;quot;Full Speed ICD2&amp;quot; (USB2.0, Debugger, Programmer) oder Fertiggerät erhältlich.&lt;br /&gt;
* [http://www.uchobby.com/index.php/2008/04/19/pic-development-linux-style/ How to setup for PIC microcontroller development on Linux] von Steven Moughan&lt;br /&gt;
* [http://www.dattalo.com/gnupic/gpsim.html#docs gpsim] is a full-featured software simulator for Microchip PIC microcontrollers distributed under the GNU General Public License.&lt;br /&gt;
* [http://www.mtoussaint.de/yapide.html YaPIDE] aims to be a fully featured Microchip PIC simulator for Linux (and probably other UNIXes). YaPIDE is a GUI only application. If you need a commandline based PIC simulator there is the excellent &#039;&#039;&#039;gpsim&#039;&#039;&#039;. The simulator kernel currently supports the PIC 16F628.&lt;br /&gt;
* [http://piklab.sourceforge.net/ Piklab] is an integrated development environment for applications based on Microchip PIC and dsPIC microcontrollers similar to the MPLAB environment. It integrates with several compiler and assembler toolchains (like gputils, sdcc, c18) and with the simulator &#039;&#039;&#039;gpsim&#039;&#039;&#039;. It supports the most common programmers (serial, parallel, ICD2, Pickit2, PicStart+) and debuggers (ICD2).&lt;br /&gt;
* [http://dev.frozeneskimo.com/software_projects:vpicdisasm vPICdisasm] is a Microchip PIC Mid-Range family firmware disassembler. This single-pass disassembler can read Intel HEX and Motorola S-Record formatted files containing valid PIC firmware. (GPL)&lt;br /&gt;
* [http://pikdev.free.fr/ PiKdev] is a simple graphic IDE for the development of PIC-based applications. It currently supports assembly language. C language is also supported for PIC 18 devices. PiKdev is developed in C++ under Linux and is based on the KDE environment.&lt;br /&gt;
* [http://www.yenka.com/en/Yenka_PICs/ Yenka PICs] lets you write routines using simple flowcharts, and test them on-screen, before using them to program real PIC or PICAXE chips. To help spread the news about Yenka, we&#039;re offering free copies of Yenka PICs for use at home or school.&lt;br /&gt;
* [http://gcbasic.sourceforge.net/ Great Cow BASIC] &amp;quot;Open Source BASIC programming tools for Microchip PIC and Atmel AVR microcontrollers&amp;quot;&lt;br /&gt;
* [http://openprog.altervista.org/OP_eng.html Open Programmer] - An open source [[USB]] programmer for [[PIC]] micros, [[I2C]]-[[SPI]]-MicroWire [[EEPROM]]s, some ATMEL [[AVR]] micros, generic I2C/SPI devices and (soon) other devices. Can work as [[ICD]] debugger.&lt;br /&gt;
&lt;br /&gt;
=== Projektsammlungen/Einzelprojekte ===&lt;br /&gt;
* [http://www.martins-elektronikwelt.tk www.martins-elektronikwelt.tk] Viele Projekte mit den PIC Mikrocontrollern, u.a. SMS-Schaltzentrale, SD/MMC-FAT32-MP3-Player, Lichtschranken, Funk-Wetterempfänger, PS/2 am PIC usw.&lt;br /&gt;
* [http://www.Firmware-On-Demand.com Firmware-On-Demand] Umfangreiche Firmware-Bibliothek. &lt;br /&gt;
* [http://pic-projekte.de/hd44780_c18.html XLCD Librarie] Anleitung zum Ansteuern des HD44780 unter Verwendung der C18 XLCD Librarie&lt;br /&gt;
* [http://www.rentron.com www.rentron.com] Anfänger-taugliche Projekte für PIC und [[8051]] von Reynolds Electronics (Englisch)&lt;br /&gt;
* [http://www.circuitcellar.com/microchip2007/ Microchip 16-Bit Embedded Control 2007 Design Contest] bei [http://www.circuitcellar.com/ Circuit cellar]&lt;br /&gt;
* [http://mondo-technology.com/ Mondo Technologiy] Grosse Ansammlung von PIC-Projekten, u.a. SuperProbe: Logic Probe,(Auf der linken Seite ganz oben) Logic pulser, Frequency Counter, Event Counter, Voltmeter, Diode Junction Voltage, Capacitance Measurement, Inductance Measurement, Signal Generator, Video Patern, Serial Ascii, Midi Note, R/C Servo, Square Wave, Pseudo Random Number, ir38, PWM in einem... (PIC16F870)&lt;br /&gt;
* [http://micrognurtos.sourceforge.net uGNU/RTOS] is a microcontroller-targeted serial real time operating system. It has been ported to USART capable Microchip PIC16 devices. It supports I/O operations and some internal registry operations. The user can interact with the chip through the RS-232 serial cable and a shell. The user can type a small list of commands and see the results on the chip&#039;s outputs. (LGPL)&lt;br /&gt;
* [http://pic-projekte.de www.PIC-Projekte.de] Hier finden sich einige interessante Projekte mit PIC Mikrocontrollern (z.B. Anleitung zum Ansteuern eines HD44780 komp. LCD von eA, Ansteuern eines KS0107/8 Controllers in ASM mit PIC) sowie Erklärungen zu den dazugehörigen Programmabschnitten. Außerdem gibt es eine Anleitung zum Herrstellen von Platinen. Besuchen Sie das [http://pic-projekte.de/phpBB3/index.php PIC-Forum] und diskutieren Sie mit bei spannenden Themen. Wenn Sie Fragen zu PIC µC der Firma Micochip haben, dann sind Sie hier richtig aufgehoben!&lt;br /&gt;
* [http://pic16f628a.blogspot.com/ Experiments with PIC16F628A] - PIC Programming in C&lt;br /&gt;
&amp;lt;!-- * [http://www.picguide.org PIC Guide] Eine große Sammlung von PIC-Projekten für den Anfänger 6.9.2010: nur cPanel Standard Seite --&amp;gt;&lt;br /&gt;
*Stevy&#039;s Homepage http://stevy.bplaced.com Pic Projekte die in C geschriebn wurden z.B 3D Engine, Grafik Display Ansteuerungen, Oszilloskip usw&lt;br /&gt;
* [http://www.simon-brenner.ch/projekte/rgb-led-stripe RGB Stripe mit 16bit Bus, realisiert mit PIC12F629]&lt;br /&gt;
* [http://scifi.pages.at/drakesoft/aulem_mypong/ Spiel PONG] auf einer 16x16 LED Matrix mit Ton, realisiert auf einem AVR.&lt;br /&gt;
* [http://hackinglab.org/ Pinguino Webpage] und [http://wiki.pinguino.cc/index.php/Main_Page Pinguino Wiki] ist ein Arduino-ähnliches Open Source und Open Hardware Projekt für 8-Bit (PIC18F2550, PIC18F4550) Mikrocontroller.&lt;br /&gt;
&lt;br /&gt;
== [[Z8]] ==&lt;br /&gt;
* [http://groups.yahoo.com/group/z8encore/ Yahoo! Groups : z8encore] Yahoo-Gruppe, die sich mit den Z8 Encore! Mikrocontrollern beschäftigt (Anmeldung bei Yahoo erforderlich).&lt;br /&gt;
* [[Zilog Encore Experimentierplatine]] (Z8F6421 Familie mit DIP-40 Gehäuse)&lt;br /&gt;
*[http://www.thpeter.net Zilog Projekte] (Ein Z8Encore und ZNEO Projekt und viele Tips zum Programmieren und Debuggen)&lt;br /&gt;
&amp;lt;!-- * [http://www.z8micro.com/forum/ Z8 Encore! Microcontroller Discussion Forum - Dedicated to the ZiLOG Z8 Encore! Microcontroller] Ein der Z8 Encore!-Mikrocontrollerfamilie gewidmetes Diskussionsforum (in Englisch). - Link tot 6.9.2010 --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Programmierbare Logik ([[CPLD]]/[[FPGA]]/[[GAL]]) ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.opencores.org/ OpenCores.org], VHDL Sourcen&lt;br /&gt;
* [http://www.fpga4fun.com/ fpga4fun], umfangreiche Seite mit Einführung und Beispielen, berücksichtigt Xilinx &amp;amp; Altera&lt;br /&gt;
* [http://opencollector.org/history/freecore/ Freecore], unter &#039;Module library&#039; gibt&#039;s einige freie Designs&lt;br /&gt;
* [http://www.cmosexod.com/ CMOSExod], Designs unter &#039;Free IP&#039;&lt;br /&gt;
* [https://digilent.us/ Digilent], Hersteller verschiedener FPGA/CPLD-Boards (u.a. Xilinx Spartan Starter Kit)&lt;br /&gt;
* [http://www.terasic.com.tw/cgi-bin/page/archive.pl?Language=English&amp;amp;CategoryNo=39 Terasic], Anbieter von Altera FPGA-Boards&lt;br /&gt;
* [http://shop.trenz-electronic.de/catalog/ Trenz Elektronik], verkauft verschiedene FPGA/CPLD-Boards&lt;br /&gt;
* [http://www.xess.com/index.html XESS], Anbieter von FPGA-Boards (Xilinx), unter Support gibts es eine Menge Beispiele&lt;br /&gt;
* [http://members.optushome.com.au/jekent/FPGA.htm Private Seite von John Kent], enthält eine Menge Links und auch einige Designs&lt;br /&gt;
* [http://www.openpicide.org openPICIDE], Picoblaze IDE für Windows, Linux und Mac&lt;br /&gt;
* [http://www.mediatronix.com/Tools.htm Mediatronix tools], Picoblaze und DSP tools&lt;br /&gt;
* [http://www.ixo.de/info/usb_jtag/ ixo.de usbjtag] - USB-JTAG Adapter, fast kompatibel zu Altera USB-Blaster, wahlweise basierend auf FT245+CPLD oder Cypress FX2 Controller&lt;br /&gt;
* [http://www.fpgacpu.org/links.html FPGA CPU Links]&lt;br /&gt;
* [http://www.fpga-forum.com/wbb Forum mit allgemeinen Diskussionen zum Thema FPGA und FAQ&#039;s speziell zu den Cesys FPGA Karten]&lt;br /&gt;
* [http://www.cesys.biz Online Shop für Cesys FPGA Karten]&lt;br /&gt;
&lt;br /&gt;
== DSP ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.tetrix-systems.de/embedded.html combined embedded Linux-DSP Solutions]&lt;br /&gt;
* [http://open.neurostechnology.com/node/1020 TI c54x DSP  Compilertools (ohne Debugger)] frei für Open Source Projekte.&lt;br /&gt;
&lt;br /&gt;
== Wettbewerbe (Contests) == &lt;br /&gt;
&lt;br /&gt;
Verschiedene Hersteller veranstalten zur Promotion ihrer Produkte Designwettbewerbe, aus denen teilweise komplette Projektunterlagen hervorgehen (Schaltung, Source).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2011&#039;&#039;&#039;&lt;br /&gt;
*[http://www.555contest.com 555 Contest]&lt;br /&gt;
*[http://www.circuitcellar.com/nxpmbeddesignchallenge/ NXP and ARM/mbed challenge]&lt;br /&gt;
*[http://www.ebv.com/en/products/stm32-design-contest.html STM32 Design Contest] von EBV Elektronik und STMicroelectronics&lt;br /&gt;
* [http://www.renesasrulz.com/community/rx-contest The RX MCU Design Contest] und die Top 3 im [http://www.eevblog.com/2011/06/05/eevblog-174-renesas-rx-design-contest-winners/ Video] bei Dave Jones auf EEVBlog.com&lt;br /&gt;
* [http://www.cypress.com/?id=3298 ARM Cortex-M3 PSoC® 5 Design Challenge]&lt;br /&gt;
* [http://www.instructables.com/contest/micro/ SparkFun Microcontroller Contest] bis 13.02.2011&lt;br /&gt;
* [http://www.elektroniknet.de/bauelemente/news/article/27963/0/Wer_entwickelt_die_beste_Anwendung_mit_dem_EFM32/ EFM32 Design-Wettbewerb] von Elektronik, Avnet-Memec und Energy Micro&lt;br /&gt;
* [http://www.freescale.com/webapp/sps/site/overview.jsp?code=KINETIS_MAKEIT_CHALLENGE&amp;amp;tid=vanKINETIS_MAKEIT_CHALLENGE Make It Challenge: Kinetis MCUs] von Freescale&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2010&#039;&#039;&#039;&lt;br /&gt;
* [http://www.schmartboard.com/index.asp?page=mcu_2010 SchmartBoard 2010 MCU Challenge]&lt;br /&gt;
* [http://www.digilentinc.com/showcase/contests/designcontest.cfm?ContestID=6 Digilent Design Contest 2010]&lt;br /&gt;
* [http://www.parallax.com/go/holidaychallenge Parallax &amp;amp; iGen Student LED Holiday Challenge]&lt;br /&gt;
* [http://www.embeddedspark.com/upcomingchallenge/ The embeddedSPARK 2010 SUMMER Challenge]&lt;br /&gt;
* [http://www.libelium.com/tienda/catalog/contest.php?language=en Libelium Arduino Open Hardware Contest]&lt;br /&gt;
* [http://www.circuitcellar.com/designstellaris2010/index.html Texas Instruments DesignStellaris 2010]&lt;br /&gt;
* [http://www.wizwiki.net/main/ iMCU Design Contest] (WIZnet)&lt;br /&gt;
* [http://www.elo-web.de/elo/entwicklung-und-projekte/ping-pong/elo-programmierwettbewerb-2010 ELO-Programmierwettbewerb 2010] (Atmega8, PingPong-Platine, 31.3.10)&lt;br /&gt;
* [http://www.lpc1100challenge.com/ NXP LPC1100 Design Challenge] (Cortex-M0 based LPC1100)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2009&#039;&#039;&#039;&lt;br /&gt;
* [http://arduinofun.com/blog/2009/11/01/fun-with-arduino-contest/ Fun with Arduino Contest]&lt;br /&gt;
* [https://www.xmos.com/challenge/ XMOS Challenge]&lt;br /&gt;
* [http://www.designmsp430.com/ Design MSP430 Ultra-Low Power Challenge]&lt;br /&gt;
* [http://makezine.com/halloweencontest/ Make: Halloween Contest 2009], sponsored by Microchip Technology!&lt;br /&gt;
* [http://www.bricogeek.com/contest/let-arduino-play/resultados.php Let Arduino Play Contest]&lt;br /&gt;
* [http://www.dlpdesign.com/designcontest/ DLP Design DLP-232PC Design Contest]&lt;br /&gt;
* [http://www.libelium.com/tienda/catalog/contest.php Arduino contest by Libelium]&lt;br /&gt;
* [http://www.expli.de/wettbewerb/coole-avr-microcontroller-elektronik-ideen/ EXPLI Elektronik Wettbewerb]: Die coolsten Elektronik Projekte &amp;amp; AVR Microcontroller Anleitungen&lt;br /&gt;
* [http://www.stm32circle.com/projects/contest.php STM32 Primer2 Design Competition 2009]&lt;br /&gt;
* [http://www.parallax.com/Resources/ApplicationsContests/Contests/200910PropellerContest/tabid/846/Default.aspx 2009/2010 Propeller Design Contest]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2008&#039;&#039;&#039;&lt;br /&gt;
* [http://www.parallax.com/tabid/720/Default.aspx Propeller Design Contest]&lt;br /&gt;
* [http://www.psocidcindia.com/index.php PSoC Innovator Design Challenge India 2008]&lt;br /&gt;
* [http://www.mypic32.com Microchip PIC32 Design Challenge]&lt;br /&gt;
* [http://contest.renesasinteractive.com/ HEW Target Server Design Contest 2008]&lt;br /&gt;
* [http://www.stm32circle.com/projects/result_contest_2008.php STM32 Primer Design Competition 2008]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2007&#039;&#039;&#039;&lt;br /&gt;
* [http://www.circuitcellar.com/wiznet/index.html WIZnet iEthernet Design Contest 2007] &lt;br /&gt;
* [http://www.circuitcellar.com/microchip2007/ Microchip 16-Bit Embedded Control 2007 Design Contest]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2006&#039;&#039;&#039;&lt;br /&gt;
* [http://www.designmsp430.com/View.aspx 2006 MSP430 eZ Design Contest] &lt;br /&gt;
* [http://www.luminarymicro.com/DesignStellaris2006 Luminary Micro DesignStellaris2006]&lt;br /&gt;
* [http://www.circuitcellar.com/avr2006/ Atmel AVR Design Contest 2006] &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2005&#039;&#039;&#039;&lt;br /&gt;
* [http://www.jandspromotions.com/philips2005/index.htm Philips ARM Design Contest 2005] (LPC213x)&lt;br /&gt;
* [http://www.circuitcellar.com/renesas2005m16c/index.htm Renesas M16C Design Contest 2005]&lt;br /&gt;
* [http://www.edn.com/article/CA516007.html Cornelius van Drebbel&#039;s Mad Design Contest] (NEC)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2004&#039;&#039;&#039;&lt;br /&gt;
* [http://www.circuitcellar.com/avr2004/ Atmel AVR 2004 Design Contest]&lt;br /&gt;
* [http://www.circuitcellar.com/psoc2004/ PSoC High Integration Challenge 2004]&lt;br /&gt;
* [http://www.jandspromotions.com/zilog2004/ Zilog 2004 Flash Nets Cash Design Contest] (eZ80Acclaim!)&lt;br /&gt;
* [http://www.jandspromotions.com/wirelesschallenge/index.html 2004 Freescale Wireless Design Challenge] (MC13191/92/93 RF Transceivers, [[Meshnetics Zigbee|ZigBee]])&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2003&#039;&#039;&#039;&lt;br /&gt;
* [http://www.circuitcellar.com/fi2003/ MOTOROLA FLASH INNOVATION 2003 DESIGN CONTEST] (Motorola HC08)&lt;br /&gt;
* [http://www.circuitcellar.com/renesas/ Renesas H8 Design 2003 Contest]&lt;br /&gt;
* [http://www.jandspromotions.com/zilog2003/ ZiLOG Flash for Cash Z8 Encore®! International Design Contest]&lt;br /&gt;
* [http://www.jandspromotions.com/efield203/index.htm 2003 Motorola E-Field Sensor Contest] (MC33794)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2002&#039;&#039;&#039;&lt;br /&gt;
* [http://www.circuitcellar.com/flash2002/ Mad Dash for Flash Cash] (Microchip, PIC)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2001&#039;&#039;&#039;&lt;br /&gt;
* [http://www.circuitcellar.com/dl2001/ Atmel &#039;Design Logic 2001&#039; Design Contest]&lt;br /&gt;
* [http://www.circuitcellar.com/msp430/ MSP430 Design Contest]&lt;br /&gt;
&lt;br /&gt;
== Interfaces &amp;amp; Protokolle ==&lt;br /&gt;
Siehe auch [[Linksammlung#Schnittstellen]]&lt;br /&gt;
&lt;br /&gt;
=== Infrarot (IR) ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.sbprojects.com/knowledge/ir/index.php Übersicht IR-Protokolle] von San Bergmans (engl.): ITT, JVC, NEC, Nokia NRC17, Sharp, Sony SIRC, Philips RC-5, RC-6, RC-MM, RECS80, RCA, X-Sat&lt;br /&gt;
* [http://www.vishay.com/docs/80071/dataform.pdf Data formats for IR controls (PDF)] von Vishay.&lt;br /&gt;
* [http://www.ostan.cz/IR_protocol_analyzer/ IR protocol analyzer] (Freeware)&lt;br /&gt;
&lt;br /&gt;
=== Parallelport ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.projects-lab.com/?p=1139 ECPMON] - ECP Parallel Port Monitor ([[M16C]]/62P) &lt;br /&gt;
&lt;br /&gt;
=== iPod ===&lt;br /&gt;
* [http://ipodlinux.org/IPod_to_T%26A_remotecontrol_adapter IPod to T&amp;amp;A remotecontrol adapter] ([[PIC]]-Projekt)(Link defect)&lt;br /&gt;
* http://jasongarr.wordpress.com/project-pages/ipod-clickwheel-hack/&lt;br /&gt;
&lt;br /&gt;
=== [[RFID]] ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.alexanderguthmann.de/RFIDemulator.html RFIDemulator] - Beschreibung eines RFIDemulators zum klonen von Tags&lt;br /&gt;
* [http://www.mwjournal.com/journal/article.asp?HH_ID=AR_905 Radio Frequency Identification: Evolution of Transponder Circuit Design] - Übersichtsartikel aus dem Microwave Journal&lt;br /&gt;
* [http://www.foebud.org/rfid Die StopRFID-Seiten des FoeBuD e.V.]&lt;br /&gt;
* [http://www.rfzone.org/free-rf-ebooks/ PDF-Bücher (englisch) ]- Bücher über RF, Antennen und elektromagnetische Wellen.&lt;br /&gt;
&lt;br /&gt;
* http://cq.cx/proxmark3.pl Jonathan Westhues RFID Leser/Schreiber/Cloner&lt;br /&gt;
&lt;br /&gt;
http://www.message_bocracco.com/&lt;br /&gt;
&lt;br /&gt;
==== ~ 125 kHz ====&lt;br /&gt;
&lt;br /&gt;
*[http://t4f.org/en/projects/open-rfid-tag Open RFID Tag]&lt;br /&gt;
&lt;br /&gt;
==== 13,56 MHz RFID ====&lt;br /&gt;
* [http://www.openpcd.org/ OpenPCD - a free 13.56MHz RFID reader design] for Proximity Coupling Devices (PCD) based on 13,56MHz communication. This device is able to screen informations from Proximity Integrated Circuit Cards (PICC) conforming to vendor-independent standards such as ISO 14443, ISO 15693 as well as proprietary protocols such as Mifare Classic. (AT91SAM7S128 [[ARM]] Projekt)&lt;br /&gt;
* [http://www.rf-dump.org/ RFDump] is a backend GPL tool to directly interoperate with any RFID ISO-Reader to make the contents stored on RFID tags accessible. (Linux)&lt;br /&gt;
&lt;br /&gt;
==== 2,4 GHz RFID ====&lt;br /&gt;
* [http://www.openbeacon.org/ OpenBeacon] - a free active 2.4GHz beacon design. (Reader: USB oder Ethernet; Tags: RF_Chip: NRF24L01, PIC16F684)&lt;br /&gt;
&lt;br /&gt;
=== [[DMX512]] ===&lt;br /&gt;
* [http://www.soundlight.de/techtips/dmx512/dmx512.htm DMX-512 - was ist das?] Eine Übersicht von SOUNDLIGHT.&lt;br /&gt;
* [http://dworkin-dmx.de/ USB DMX Interface] Bausatz /Fertiggerät USB DMX Interface  &lt;br /&gt;
* [http://www.oksidizer.com/electronic/spp2dmx/index_en.html OksiD DMX 3/1 is a Standard Parallel Port DMX 512 interface for IBM compatible PCs]. Drei Output Universe und ein Input Universe (Universe = 512 channels). Open project. All source code and schematics are available for free. &lt;br /&gt;
* [http://www.usbdmx.com/usb_dmx_interface.html USB DMX Interface revision 1.3] - opto isolated, bus powered, DMX512 from/to [[USB]]interface with both in and out universes. Cheap and simple to build.&lt;br /&gt;
* [http://www.dmx512-online.com/ Ujjal&#039;s DMX512 Seite]&lt;br /&gt;
* [http://llg.cubic.org/dmx4linux/ DMX4Linux 2.6] - A DMX device driver package for Linux (incl. hardware schematics with TI [[MSP430]])&lt;br /&gt;
&lt;br /&gt;
=== Verschiedenes ===&lt;br /&gt;
* [http://www.taelektroakustik.de/deu/index.htm T&amp;amp;A Kommandos] - &#039;&#039;&#039;RC&#039;&#039;&#039; und &#039;&#039;&#039;RCII&#039;&#039;&#039; Kommandoset der Philips PRONTO Familie zur Steuerung von Audiogeräten. Dokumentation siehe unter Downloads.&lt;br /&gt;
* [http://www.marjorie.de/ps2/ps2_protocol.htm Das PS/2 Maus und PS/2- oder AT-Tastatur-Protokoll] (Original auf [http://www.computer-engineering.org/])&lt;br /&gt;
* [http://www.hth.com/snap/ S.N.A.P - Scaleable Node Address Protocol]. S.N.A.P is an free and open network protocol. The protocol was primary developed for PLM-24 based home automation and control systems but it is a generic protocol and not limited to this. S.N.A.P can be used in any type of applications where an easy to learn and light weighted network protocol is needed.&lt;br /&gt;
* [http://www.ulrichradig.de/home/index.php/avr/avr_-_rc PPM / PWM Encoder/Decoder für R/C Funkfernsteuerungen] von Ulrich Radig (AVR, C)&lt;br /&gt;
* [http://www.national.com/analog/interface/lvds_owners_manual LVDS Owner&#039;s Manual - 4th Edition] von National Semiconductor&lt;br /&gt;
* [http://www.mictronics.de/?page=becker Becker Unilink]&lt;br /&gt;
* [http://users.ntplx.net/~andrew/sony/unilink/ Sony UniLink]&lt;br /&gt;
* [http://www.vending.org/technology/MDB_Version_4.pdf Multi-Drop Bus / Internal Communication Protocol (MDB / ICP)]&lt;br /&gt;
&lt;br /&gt;
== Elektronikversender‎ ==&lt;br /&gt;
&lt;br /&gt;
siehe [[Elektronikversender‎]]&lt;br /&gt;
&lt;br /&gt;
== Leiterplattenhersteller ==&lt;br /&gt;
&lt;br /&gt;
siehe [[Platinenhersteller]]&lt;br /&gt;
&lt;br /&gt;
== Schulungen (Online) ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.esacademy.com/myacademy/ www.esacademy.com] (engl.) - C, CAN, I²C, BlueTooth, PWM, USB, 51LPC, ARM (Einführung)&lt;br /&gt;
* [http://www.elprak.ch Elektronik in der Praxis] Präsentationen zu verschiedenen Themen der Elektronik in der Praxis. Lötvideo, das den zeitlichen Ablauf beim Löten anschaulich darstellt.&lt;br /&gt;
* [http://www.national.com/onlineseminar/ www.national.com] - Amplifiers, Audio, Data Acquisition, Die Products, Displays, Interface, Microcontrollers, Military/Aerospace, Power, Thermal Management, Wireless&lt;br /&gt;
* [http://www.circuitrework.com Circuit Technology Center] - Surgeon grade rework and repair, by the book and guaranteed. Deeplink: [http://www.circuitrework.com/guides/guides.shtml Guides]&lt;br /&gt;
* [http://www.onlinetutorials.de/index.htm onlinetutorials.de] - Linksammlung zu Tutorials für höhere Programmiersprachen ([[HLL]]) wie C, C++, Java, BASIC, Perl, PHP, ...&lt;br /&gt;
* [http://www.awce.com/classroom/ AWCE Interactive Classroom] - Embedded Systems (Using the APP-IV with GCC, Getting Started with the PIC 18F Family), Electronics (CLARC/HBSIG DSP Study Group, Basic Circuits), RoadMap to Programmable Logic&lt;br /&gt;
* [http://www.ibiblio.org/kuphaldt/socratic/ Socratic Electronics] (englisch)&lt;br /&gt;
* [http://www.embedded.com/design/multicore/201200638;jsessionid=4T1T0OZQW4PFSQSNDLRSKH0CJUNN2JVN?printable=true The basics of programming embedded processors] von Wayne Wolf. Neun Artikel bei embedded.com (englisch)&lt;br /&gt;
* [http://webcast.berkeley.edu/course_details.php?seriesid=1906978507 EE 42/EE 100 Introduction to Digital Electronics] - Webcast, Spring 2008 (englisch)&lt;br /&gt;
* [http://freevideolectures.com freevideolectures.com] - Webcasts zu  naturwissenschaftlichen Theman (englisch)&lt;br /&gt;
* [http://www.circuitsage.com/ Circuit Sage], a complete source of information to help you design circuits fast. (Linksammlung zu Software, Artikeln Büchern und Websites)&lt;br /&gt;
* [http://www.DieElektronikerseite.de Die Elektronikerseite] Umfangreiche Sammlung von kleinen Lehrgängen und Schaltungen. Ideal für Anfänger aber auch für Fortgeschrittene&lt;br /&gt;
* [http://homepages.internet.lu/absolute3/tronic/ 3D Virtual Development] - Sammlung von vielen Grundschaltungen im Bereich Oszillator, Operationsverstärker, Empfangstechnik. Vereinzelt in Englisch.&lt;br /&gt;
* [http://cws.gtc.edu/programs/objects/electronics.htm Learning Objects for Electronics] des Engineering Tech Wing of Gateway Technical College (Flash erforderlich)&lt;br /&gt;
* [http://ecee.colorado.edu/~bart/book/book/title.htm Principles of Semiconductor Devices] von Bart Van Zeghbroeck&lt;br /&gt;
* [http://itp.nyu.edu/physcomp/Intro/HomePage Introduction to Physical Computing] ([[AVR]], Arduino)&lt;br /&gt;
&lt;br /&gt;
== Skripte ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.janson-soft.de/skripte/index.html Linksammlung von Volker Lange-Janson]&lt;br /&gt;
* [http://wwwex.physik.uni-ulm.de/lehre/physikalischeelektronik/phys_elektr/phys_elektr.html Physikalische Elektronik und Messtechnik] von Othmar Marti und Dr. Alfred Plettl, Universität Ulm&lt;br /&gt;
* [http://openbookproject.net//electricCircuits/index.htm Lessons in Electric Circuits I-VI] von Tony R. Kuphaldt&lt;br /&gt;
&lt;br /&gt;
== Messequipment ==&lt;br /&gt;
* [http://www.filmetrics.com  Filmetrics Inc.] (Filmetrics manufactures affordable thin-film measurement instruments capable of measuring thin films from 3nm to 0.5mm in thickness.)&lt;br /&gt;
* [http://www.pce-instruments.com  PCE Instruments] (Entwicklung und Produktion für Prüfgeräte und Waagen.)&lt;br /&gt;
=== Logikanalyse ===&lt;br /&gt;
* [http://www.pctestinstruments.com Intronix LogicPort], Günstiger, aber sehr leistungsfähiger Logikanalysator mit USB-Anschluß an PC (34Ch, 500MHz Timing, 34 x 2kSa mit Kompression, ca. 295 Euro [http://www.shop.display3000.com/elektronik/messgeraete/index.html hier])&lt;br /&gt;
* Zeroplus LAP-Cxxxx (Familie von LA&#039;s mit unterschiedlichen Daten, 32kBit...2MBit, 16ch oder 32ch, 100MHz..200MHz, Preise von 90,-...1100,- Euro, zu kaufen [http://www.tigal.com/products_category.asp?cid=96 hier])&lt;br /&gt;
* [http://www.tech-tools.com/dv_main.htm TechTools DigiView], Günstiger Logikanalysator mit USB-Anschluß an PC (18Ch, 100MHz Timing, 128kSa mit Kompression,  [http://elmicro.com/de/digiview.html ca. 430Euro])&lt;br /&gt;
* [http://www.tribalmicro.com/logic_an/ Tribalmicro], PC hosted LA (32ch, 40MHz Timing, 128kSa, ca. 1700$)&lt;br /&gt;
* [http://www.nci-usa.com/frame_products_overview.htm NCI GoLogic], Logikanalysator mit USB-Anschluß an PC (34 oder 72Ch, 500MHz Timing, 1 oder 2MSa, ca. 3000..5500$)&lt;br /&gt;
* [http://www.tek.com/products/logic_analyzers/index.html Tektronix], Verschiedene Geräte, standalone oder modular (ab 34ch, 2GHz Timing, ab 512kSa, gut und teuer)&lt;br /&gt;
* [http://www.home.agilent.com/DEger/nav/-536902443.0/pc.html Agilent], Verschiedene Geräte, standalone, modular oder PC-hosted (ab 34ch, ab 800MHz timing, ab 256kSa, gut und teuer)&lt;br /&gt;
* [http://www.sump.org/projects/analyzer/ Sumps LA], günstiges Projekt für einen LA basierend auf einem Digilent Spartan Board (32ch, 100MHz Timing, 256kSa, Kosten Digilent Board ca. 100$ + Versand/Zoll)&lt;br /&gt;
* [http://www.meilhaus.de/produkte/usb-mobile-messtechnik/?user_produkte%5BPATTR%5D=HPG_3-UPG1_3-UPG2_2&amp;amp;user_produkte%5BPR%5D=8&amp;amp;cHash=2c8edb93e2 Meilhaus Electronic - MEphisto Scope UM203] Robustes, mobiles 16 bit Kombi-Instrument 7 Mess-Geräte in einem! (ab 348€)&lt;br /&gt;
* [http://www.hacker-messtechnik.de/13722/59001.html TravelLogic TL2x36], Logikanalysator zum Anschluß an PC über USB, (36ch, 4GHz timing, 200MHz state, Speicher bis 72MBit, Preis ab ca. 500,- netto)&lt;br /&gt;
* [http://www.inovaflex.de/index.html Bus und Logic Analyzer] 100MHz Samplerate und integrierten SPI, I²C, CAN Interpreter, erweiterbar als Oszilloskop&lt;br /&gt;
* [http://www.saleae.com/logic/ logic] - Logik-Analyzer mit 8 Kanälen, mit Software zur Analyse von SPI, I2C, UART, etc... (ca 150$ + Versand/Zoll)&lt;br /&gt;
* [http://www.deditec.de/de/logikanalysatoren/prod/usb-logi-500.html DEDITEC USB-LOGI-500], kostengünstiges Einsteigermodell mit USB-Anschluß und dazugehöriger Software Logi+ (36Ch, Abtastrate 500MHz, 4096 Samples Speichertiefe/Kanal,  ca. 236 Euro)&lt;br /&gt;
&lt;br /&gt;
* Eine Übersicht über verschiedene Selbstbauprojekte: [[Logic_Analyzer]]&lt;br /&gt;
&lt;br /&gt;
* [http://www.timing-diagrams.com TimingAnalyzer] can be used to easily draw timing diagrams and perform timing analysis to find faults in digital logic systems. Written in Java, it runs on any platform that supports the Java Run-time Environment, JRE1.6.0 or Java Development Kit JDK1.6.0 or newer.&lt;br /&gt;
&lt;br /&gt;
=== Oszilloskope ===&lt;br /&gt;
&lt;br /&gt;
siehe die separate [http://www.mikrocontroller.net/articles/Oszilloskop Seite] zum Thema&lt;br /&gt;
&lt;br /&gt;
=== Generatoren ===&lt;br /&gt;
[http://www.meilhaus.de/produkte/mess-und-steuer-karten/?user_produkte%5BPR%5D=23&amp;amp;cHash=64a269a3c6 Meilhaus Electronic - ME-6x00] Waveform-Generator - potentialfrei isolierte 16 bit Analog-Ausgabe-Karte (ab EUR 1138,00)&lt;br /&gt;
&lt;br /&gt;
=== Handbücher für Messgeräte ===&lt;br /&gt;
Für ältere kommerzielle Messgeräte sind viele Handbücher im Web als PDF verfügbar. Hier eine Linkliste für den &amp;lt;u&amp;gt;kostenlosen&amp;lt;/u&amp;gt; Download:&lt;br /&gt;
* [http://www.ko4bb.com/cgi-bin/manuals.pl KO4BB Didier Juges]&lt;br /&gt;
* [http://bama.edebris.com/manuals/ BAMA-Edebris (mirror)]&lt;br /&gt;
* [http://www2.faculty.sbc.edu/kgrimm/boatanchor/index.htm BAMA Originalseite K4XL]&lt;br /&gt;
* [http://www.to-way.com/teqman.html to-way.com (K7MLR)]&lt;br /&gt;
* [ftp://ftp.bluefeathertech.com/pub/electronics/testgear/ Bluefeathertech FTP-Server]&lt;br /&gt;
* [http://www.bitsavers.org/ Bitsavers, vor allem Computermanuals und Software]&lt;br /&gt;
* [https://www.logsa.army.mil/etms/online.cfm Handbücher der US-Army (-&amp;gt;&amp;quot;i accept&amp;quot; -&amp;gt; &amp;quot;Enter the site&amp;quot; -&amp;gt; Suchbegriff z.B &amp;quot;Analyzer&amp;quot; in &amp;quot;Pub Title Text&amp;quot; eingeben -&amp;gt; search)]&lt;br /&gt;
* [http://www.eserviceinfo.com/browse.php eserviceinfo.com]&lt;br /&gt;
* [http://www.one-electron.com/FC_TestEquipment.html one-electron.com]&lt;br /&gt;
* [http://manoman.sqhill.com/ manoman]&lt;br /&gt;
* [http://www.nostalgiaair.org/ Nostalgia Air schematics, manuals, tube data]&lt;br /&gt;
* [http://pages.cthome.net/fwc/ Freds sehr alte (vor allem Militärelektronik-) Geräteliteratur, Röhrentechnik] und hier [http://pages.cthome.net/fwc/TO-DOC.HTM Übersicht zur Nummerierung der Militärhandbücher]&lt;br /&gt;
* [http://www.hpmemory.org/ressources/resrc_home.htm HP-Memory.org, alte Applications und HP-Journals]&lt;br /&gt;
* [http://www.ebaman.com/index.php/home Ebaman Registrierung per e-Mail erforderlich]&lt;br /&gt;
&lt;br /&gt;
Eine [http://www.slack.com/elec.html Linksammlung zu Messgeräten], sehr ausführlich&lt;br /&gt;
&lt;br /&gt;
== Vermischtes == &lt;br /&gt;
&lt;br /&gt;
=== Foren ===&lt;br /&gt;
* [http://forum.sparkfun.com/ Spark Fun Electronics] MicroController Ideas and Support (Englisch) ([[AVR]], [[PIC]], [[MSP]], [[ARM]], OpenOCD)&lt;br /&gt;
* [http://www.edaboard.com/ EDAboard.com] International Electronics Forum Center (Englisch)&lt;br /&gt;
* [http://stsboard.de STS Reparatur Forum] Forum für Radio und Fernsehtechniker&lt;br /&gt;
* [http://formu.iwenzo.de Elektronik Reparatur Forum] Informationselektroniker Reparatur Forum&lt;br /&gt;
* [http://www.elektrikforum.de Elektrik-Forum] Forum zum Thema Elektroinstallationen&lt;br /&gt;
* [http://www.eeweb.com/electronics-forum/ Electronics Forum] Electrical Engineering Community Forum (Englisch)&lt;br /&gt;
&lt;br /&gt;
=== Videocasts und Podcasts ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.eevblog.com/ EEVblog] Electronics Engineering Video Blog von David L. Jones (englisch). &#039;&#039;Anm.: David ist Australier und das hört man. An die Sprechweise kann man sich aber gewöhnen. Und nicht erschrecken, wenn öfter mal ein drastisches Fourletterword auftaucht!&#039;&#039;&lt;br /&gt;
* [http://www.theamphour.com/ The Amp Hour] Podcast mit Chris Gammell und David Jones (englisch)&lt;br /&gt;
&lt;br /&gt;
=== Projektsammlungen ===&lt;br /&gt;
Meist in Englisch. &lt;br /&gt;
* [http://circuitscout.com/ Circuit Scout] - Online Suchmaschine&lt;br /&gt;
* [http://www.epanorama.net ePanorama.net]&lt;br /&gt;
&amp;lt;!-- offline 4/2010&lt;br /&gt;
* [http://www.commlinx.info Electronic Schematics] from CommLinx Solutions Pty Ltd&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
* [http://www.discovercircuits.com Discover Circuits] a collection of 25000+ electronic circuits or schematics&lt;br /&gt;
* [http://www.next.gr/ Next] Electronic Circuit Database&lt;br /&gt;
* [http://www.beyondlogic.org/ BeyondLogic.org] Diverse Mikrocontroller und Interfacing Projekte&lt;br /&gt;
* [http://www.uoguelph.ca/~antoon/circ/circuits.htm Circuits for the Hobbyist] by VA3AVR&lt;br /&gt;
* [http://www.stefpro.de/ StefPro.de] Diverse Projekte und Datenblattsammlung nach Kategorien, Microcontroller, Digital und Analog... Sowie Tutorial &amp;quot;Grundlagen der Bestückung von Platinen&amp;quot; und anderes Wissen&lt;br /&gt;
* [http://www.schaltplaene-online.de/ www.schaltplaene-online.de] Umfangreiche Linksammlung zu Schaltplänen aller Art&lt;br /&gt;
* [http://www.halloweenmonsterlist.info/ MoNsTeRlIsT of Halloween Projects]&lt;br /&gt;
* [http://www.open-innovation-projects.org Open Innovation Projects] - Sammlung von offenen Projekten zu physischen Produkten, darunter etliche Mikrocontroller-Projekte. Man kann selber Projekte hinzufügen.&lt;br /&gt;
&lt;br /&gt;
=== Referenzen, Beschreibungen, Standards ===&lt;br /&gt;
* Extraseite: [[Datenblätter]]&lt;br /&gt;
* [http://www.technick.net Technik.Net] Pinouts, Circuits and Guides&lt;br /&gt;
* [http://pinouts.ru/ pinout.ru] und [http://www.hardwarebook.info/ hardwarebook.info] - Online handbooks of hardware pinouts, cables schemes and connectors layouts&lt;br /&gt;
* [http://www.networktechinc.com/technote.html Keyboard, Monitor &amp;amp; Mouse Pinouts] for PC, SUN, MAC, USB, FireWire, RS232, Digital Flat Panel and EVC configurations&lt;br /&gt;
* [http://www.q1.fcen.uba.ar/materias/iqi/joygus/tvgames.html Special joysticks used in TV games]&lt;br /&gt;
* [http://microsym.com/editor/assets/intelhex.pdf Intel-Hex-Format (PDF)]&lt;br /&gt;
* [http://home.teleport.com/~brainy/fat32.htm FAT32 Structure Information] - Written by Jack Dobiash&lt;br /&gt;
* [http://www.pjrc.com/tech/8051/ide/fat32.html Understanding FAT32 Filesystems] mit Beispielen (engl.)&lt;br /&gt;
* [http://www.rev-ed.co.uk/docs/picaxe_manual3.pdf Microcontroller Interfacing Circuits] - Revolution Education Ltd.&lt;br /&gt;
* [http://www.digchip.com/application-notes/ Datenbank für &#039;&#039;Application Notes&#039;&#039;] bei www.digchip.com&lt;br /&gt;
* [http://www.pavouk.org/hw/lamp/en_index.html#bigluz20w Compact Fluorescent Lamp (CFL)], Schaltungen von Energiesparlampen&lt;br /&gt;
&lt;br /&gt;
=== Online-Bücher ===&lt;br /&gt;
* [http://www.allaboutcircuits.com/ All About Circuits] - Series of online textbooks covering electricity and electronics. The information provided is great for both students and hobbyists who are looking to expand their knowledge in this field. (Englisch)&lt;br /&gt;
* http://www.computer-books.us/ - überwiegend zu höheren Programmiersprachen. Englisch.&lt;br /&gt;
* [http://www.vias.org/feee/index.html FEEE - Fundamentals of Electrical Engineering and Electronics]&lt;br /&gt;
* [http://www.nrbook.com/a/bookcpdf.php Numerical Recipes in C, Second Edition (1992)]&lt;br /&gt;
* [http://www.specamotor.de/freebook.php Electrical drives for precision engineering designs]  Prof.dr.ir. Compter&lt;br /&gt;
* [http://www.joretronik.de/Web_NT_Buch/Vorwort/Vorwort.html Das neue InterNetzteil- und Konverter-Handbuch] Dipl.-Ing. Jörg Rehrmann&lt;br /&gt;
&lt;br /&gt;
=== Bedienungsanleitungen / Manuals ===&lt;br /&gt;
* [http://bama.edebris.com/manuals/ BAMA Archiv] &lt;br /&gt;
* [http://www.big-list.com/ Big-List.com] - This is a directory of over 600 dealers in used high technology equipment. Most deal in used electronic test equipment or semiconductor production equipment. Included are dealers in related high technology items, rental companies, equipment auction sites, test equipment manual dealers, foreign (non-U.S.) used equipment dealers, cal labs, and repair services.&lt;br /&gt;
&lt;br /&gt;
=== Ungewöhnliche Basteleien (Hacks) ===&lt;br /&gt;
Auf eigene Gefahr und nicht immer ganz ernst... Meist in Englisch. &lt;br /&gt;
&lt;br /&gt;
* Metablogs (tägliche News)&lt;br /&gt;
** [http://www.makezine.com/ Makezine]&lt;br /&gt;
** [http://www.hackaday.com/ Hack a Day]&lt;br /&gt;
** [http://www.hackedgadgets.com/ HackedGadgets]&lt;br /&gt;
** [http://www.hacknmod.com/ Hack N&#039; Mod]&lt;br /&gt;
** [http://zedomax.com/blog/category/diy/ Zedomax DIY]&lt;br /&gt;
** [http://digital-diy.com Digital-DIY]&lt;br /&gt;
&lt;br /&gt;
* Foren&lt;br /&gt;
** [http://www.fingers-welt.de/home.htm Fingers elektrische Welt]&lt;br /&gt;
** [http://forum.hackedgadgets.com/ HackedGadgets Forum]&lt;br /&gt;
** [http://stsboard.de Reparatur Forum]&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
domain expired&lt;br /&gt;
** [http://camerahacking.com camerahacking Forum]&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Projektsammlungen&lt;br /&gt;
** Final Projects der Kurse [http://people.ece.cornell.edu/land/courses/ece4760/FinalProjects/ ECE4760] (Designing with Microcontrollers) und [http://people.ece.cornell.edu/land/courses/ece5760/FinalProjects/ ECE5760] (Advanced Microcontrollers) an der Cornell University &lt;br /&gt;
** [http://www.coolcircuit.com/gadgets/ Cool Circuit]&lt;br /&gt;
** [http://www.electronics-lab.com/blog/ Electronics-Lab.com Blog]&lt;br /&gt;
&lt;br /&gt;
* DIY-Anleitungen&lt;br /&gt;
** [http://www.instructables.com/ instructables]&lt;br /&gt;
** [http://www.scitoys.com/ Scitoys] You Can Make With Your Kids&lt;br /&gt;
&lt;br /&gt;
* Mix&lt;br /&gt;
** [http://www.evilmadscientist.com Evil Mad Scientist Laboratories] - u.a. The Flying Spaghetti Monster, on toast ;-)&lt;br /&gt;
** [http://home.earthlink.net/~lenyr/index.html Spark, Bang, Buzz and Other Good Stuff] ([http://www.sparkbangbuzz.com Neue Sachen])&lt;br /&gt;
** [http://www.electricstuff.co.uk/ Mike&#039;s Electric Stuff] - Antique Glass, Tesla coils and high-voltage stuff, Lasers&lt;br /&gt;
** [http://electricity.pbwiki.com/ DHS electricity]&lt;br /&gt;
** [http://www.elephantstaircase.com/wiki/index.php?title=Main_Page Elephant Staircase]&lt;br /&gt;
** [http://mycpu.eu Eine selbstgebaute CPU aus TTL-Gattern]&lt;br /&gt;
** [http://www.knollep.de/ Knolles Bauanleitungen]&lt;br /&gt;
** [http://www.ikalogic.com/index.php ikalogic.com]&lt;br /&gt;
** [http://www.electronicsinfoline.com/ Electronics Infoline]&lt;br /&gt;
** [http://www.uchobby.com/ uC Hobby]&lt;br /&gt;
** [http://elettrolinux.com elettrolinux] - Elektronik und Linux (engl.)&lt;br /&gt;
** [http://electronicfox.at.tf/ electronicfox] - Verschiedene Projekte mit [[AVR]], Fernbedienungen und deren Aufbau sowie Decoder und alten ICs aus dem Recyclinghof&lt;br /&gt;
** [http://www.techfocusmedia.net/archives/fresh-bytes/ Fresh Bytes von Techfocusmedia]&lt;br /&gt;
&lt;br /&gt;
=== Zeitschriften über Elektronik und µC ===&lt;br /&gt;
* [http://www.eue24.net/ E&amp;amp;E Faszination Elektronik] - Magazin für Elektronik-Entwickler und Elektronik-Interessierte&lt;br /&gt;
* [http://www.embedded.com embedded.com] - Hauptaugenmerk auf die Philosophie drumherum&lt;br /&gt;
* [http://www.siliconchip.com.au/ Silicon Chip] - Freie Artikel unter &#039;&#039;Free Preview&#039;&#039;&lt;br /&gt;
* [http://www.circuitcellar.com/ Circuit Cellar] - Freie Artikel unter &#039;&#039;Digital Library&#039;&#039;&lt;br /&gt;
* [http://www.elektronikpraxis.vogel.de/themen/hardwareentwicklung/mikrocontrollerprozessoren/ Elektronikpraxis - Das professionelle Elektronikmagazin]&lt;br /&gt;
* [http://www.funkamateur.de/ FUNKAMATEUR] - Elektronik, Amateurfunk, CB-Funk u. v. a. m.&lt;br /&gt;
* [http://www.edn.com/ EDN] (etwas schwer zu finden, aber lesenswert: die [http://www.edn.com/channel/Design_Ideas.php Design Ideas] und das [http://www.edn.com/archive/ Archiv der Druckausgaben])&lt;br /&gt;
* [http://www.franzis.de/elo-das-magazin ELO - Das Magazin] für Elektronik-Einsteiger&lt;br /&gt;
* [http://techonline.com/ TechOnline]&lt;br /&gt;
* [http://www.elektor.de/ Elektor] &lt;br /&gt;
* [http://www.techbriefs.com/tech-briefs/electronics-techbriefs NASA Tech Briefs] - Electronics &amp;amp; Computers&lt;br /&gt;
* [http://et.nmsu.edu/~etti/ Technology Interface Journal]&lt;br /&gt;
* [http://dev.emcelettronica.com/ Your Electronics Open Source]&lt;br /&gt;
* [http://www.element-14.com element14.com] is an information portal and community specifically built for electronic design engineers.&lt;br /&gt;
* [http://www.itwissen.info ITWissen.info] (gutes Lexikon)&lt;br /&gt;
* [http://www.nutsvolts.com Nuts&#039;n&#039;Volts] Amerikanisches Elektronikmagazin mit Online Blog&lt;br /&gt;
* [http://de.rs-online.com/web/generalDisplay.html?id=eTech eTech] von RS Online&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=ENC28J60&amp;diff=61679</id>
		<title>ENC28J60</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=ENC28J60&amp;diff=61679"/>
		<updated>2011-11-16T21:44:00Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: Link aktualisiert.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Der ENC28J60 ist ein Ethernet-Controller von Microchip. Das besondere ist die handliche Bauform (unter anderem PDIP-28) und das SPI-Interface.&lt;br /&gt;
&lt;br /&gt;
==Projekte==&lt;br /&gt;
*[http://avr.auctionant.de/avrETH1/ winziger Webserver (komplett SMD, mehrseitig) mit enc28j60 und atmega32(avrETH1)] (02.03.2006)&lt;br /&gt;
*[http://home.arcor.de/fuenfundachtzig/me/me.htm E-Mail-Client mit dem ENC 28J60 und dem ATmega32 (ME)] (28.03.2006)&lt;br /&gt;
*[http://www.lochraster.org/etherrape generische Platform (ohne SMD-Teile) für viele Applikationen (&amp;quot;etherrape&amp;quot;), enc28j60 mit atmega644] (29.11.2006)&lt;br /&gt;
* https://berlin.ccc.de/wiki/Mikrocontroller (barebone, kein Zubehör bestückt, ohne SMD)&lt;br /&gt;
* [http://www.ulrichradig.de/home/index.php/avr/eth_m32_ex ATmega32/644 Webserver ohne SMD!] (23.11.2007)&lt;br /&gt;
* [http://www.triplay.de/zeigeprojekt.php?id=22 ATmega644 Webserver und Webcam auf einseitiger SMD Platine. Mit Tipps zur Programmierung des enc28j60] (16.12.2007)&lt;br /&gt;
* [[Miniwebserver]]&lt;br /&gt;
* [http://www.ethersex.de/ Umfassendes Projekt mit IPv6, RFM12 und vieles mehr]&lt;br /&gt;
* [http://wiki.neo-guerillaz.de/mediawiki Kleine Platine mit allem was man braucht. Bis auf den AVR alles DIL/DIP. Komplett GPL/OpenSource] (12.10.2008)&lt;br /&gt;
&lt;br /&gt;
==Bezugsquellen==&lt;br /&gt;
&lt;br /&gt;
=== Reichelt ===&lt;br /&gt;
*  [http://www.reichelt.de/?;ACTION=3;LA=2;GROUPID=2946;ARTICLE=89339;SID=286m1Z4KwQARwAACMOS0g402d9ed30ed809e838679a59c8f75aac ENC 28J60 SO-28] 2,70€&lt;br /&gt;
* [http://www.reichelt.de/?;ACTION=3;LA=2;GROUPID=2946;ARTICLE=89340;SID=286m1Z4KwQARwAACMOS0g402d9ed30ed809e838679a59c8f75aac ENC 28J60 DIL-28] 3,15€&lt;br /&gt;
&lt;br /&gt;
=== Mikrocontroller.net ===&lt;br /&gt;
* [http://shop.embedded-projects.net/index.php?module=artikel&amp;amp;action=artikel&amp;amp;id=89 Adapterplatine mit ENC28J60 und Ethernet-Buchse]&lt;br /&gt;
&lt;br /&gt;
===[[Elektronik-Versender#csd-electronics|csd-electronics]]===&lt;br /&gt;
*ENC28J60 DIP28S 2,79€ (Best.Nr.: 30362)&lt;br /&gt;
*ENC28J60 SOIC28 3,49€ (Best.Nr.: 30363)&lt;br /&gt;
*ENC28J60 SSOP28 3,95€ (Best.Nr.: 30365)&lt;br /&gt;
*ENC28J60 QFN28 5,49€ (Best.Nr.: 30364)&lt;br /&gt;
*MagJack mit 4 Leds 3,49€ (Best.Nr.: 015-54085)&lt;br /&gt;
*MagJack mit 2 Leds 5,69€ (Best.Nr.: 015-54084)&lt;br /&gt;
*PulseJack mit Leds 2,40€ (Best.Nr.: 015-54087)&lt;br /&gt;
*25 MHz-Quarz SMD (Grundton) 0,29€ (Best.Nr.: 14-4S25,000MHZ)&lt;br /&gt;
*25 MHz-Quarz (Grundton) 0,12€ (Best.Nr.: 14-US25,000MHZ)&lt;br /&gt;
*49.9 Ohm 1% Widerstand 0805 100 Stk 1,00€ (Best.Nr.: 10-080049)&lt;br /&gt;
&lt;br /&gt;
===[[Elektronik-Versender#Microcontroller-Starterkits|microcontroller-starterkits]]===&lt;br /&gt;
*ENC28J60 SO28 6,50€ (Best.Nr.: 4019)&lt;br /&gt;
*ENC28J60 DIP28 6,50€ (Best.Nr.: 4031)&lt;br /&gt;
*MagJack mit Leds 5,50€ (Best.Nr.: 4276)&lt;br /&gt;
*25 MHz-Quarz (Grundton) 0,60€ (Best.Nr.: 4182)&lt;br /&gt;
&lt;br /&gt;
===[[Elektronik-Versender#Embedit_Mikrocontrollertechnik|Embedit Mikrocontrollertechnik]]===&lt;br /&gt;
*ENC28J60 DIP28 5,99€&lt;br /&gt;
*ENC28J60 SO28 5,99€&lt;br /&gt;
*ENC28J60 QFN28 5,99€&lt;br /&gt;
*Taimag RJLBC-060TC1 RJ45 Buchse mit Übertrager und LEDs 3,99€&lt;br /&gt;
*25 MHz-Quarz HC49U/S (Grundton) 0,50€&lt;br /&gt;
&lt;br /&gt;
===[[Elektronik-Versender#IT-WNS|IT-WNS]]===&lt;br /&gt;
*ENC28J60 DIP28 2,89€&lt;br /&gt;
*ENC28J60 SO28 3,49€&lt;br /&gt;
*25 MHz-Quarz SMD (Grundton) 0,55€&lt;br /&gt;
*49.9 Ohm 1% Widerstand 0805 Stk 0,03€&lt;br /&gt;
*49.9 Ohm 1% Widerstand bedrahtet Stk 0,09€&lt;br /&gt;
&lt;br /&gt;
===[[Elektronik-Versender#Watterott electronic|Watterott electronic]]===&lt;br /&gt;
*ENC28J60 SOIC28 3,25€&lt;br /&gt;
*ENC28J60 DIL28 3,50€&lt;br /&gt;
*MagJack mit LEDs 2,00€&lt;br /&gt;
*Würth RJ-45 mit Übertrager, 2 Leds und PoE 6,35€&lt;br /&gt;
*Würth RJ-45 mit 2 Leds 1,60€&lt;br /&gt;
*Würth SMD Übertrager für PoE 3,15€&lt;br /&gt;
*25MHz Grundtonquarz HC49 SMD 0,50€&lt;br /&gt;
*25MHz Grundtonquarz CS10 SMD 1,20€&lt;br /&gt;
&lt;br /&gt;
===[[Elektronik-Versender#Pollin_Electronic|Pollin Electronic]]===&lt;br /&gt;
&lt;br /&gt;
* [http://www.pollin.de/shop/shop.php?cf=detail.php&amp;amp;pg=OA==&amp;amp;a=MTQ5OTgxOTk=&amp;amp;w=OTk4OTU4&amp;amp;ts=0  Komplettbausatz AVR-NET-IO] mit Platine, ENC28J60, AVR ATmega32, MagJack usw. 19,95€&lt;br /&gt;
* [http://www.pollin.de/shop/detail.php?pg=NQ==&amp;amp;a=NzQxOTk4OTk= ENC28J60] einzelnes IC DIP28. 3,20€&lt;br /&gt;
* [http://www.pollin.de/shop/detail.php?pg=NQ==&amp;amp;a=ODk5OTQ1OTk= RJ45-Modularbuchse] mit integriertem Impulsübertrager, 2 LEDs, geschirmt, 8 Pins belegt, abgewinkelt. 1,95€&lt;br /&gt;
&lt;br /&gt;
==Forum==&lt;br /&gt;
*[http://www.mikrocontroller.net/forum/read-4-343017.html#new ENC28J60 Basics (Beispielprogramm in AVRGCC für atmega8)] (29.04.2006)&lt;br /&gt;
*[http://www.mikrocontroller.net/forum/read-1-310134.html#new winziger Webserver mit enc28j60+mega32] (26.02.2006)&lt;br /&gt;
*[http://www.mikrocontroller.net/forum/read-1-179365.html#new Handlicher Ethernet-Controller mit SPI von Microchip] (26.04.2005)&lt;br /&gt;
*[http://www.mikrocontroller.net/forum/read-1-291186.html Eagle Platine mit ENC28J60 und AVR Mega8L]&lt;br /&gt;
*[http://www.mikrocontroller.net/forum/read-1-355428.html LPC2138 + ENC28J60] (23.05.2006)&lt;br /&gt;
*[http://www.mikrocontroller.net/forum/read-1-402627.html I/O über Ethernet mit einem ENC28J60] (19.08.2006)&lt;br /&gt;
*[http://www.mikrocontroller.net/topic/82127  Webserver ATmega32/644DIP ENC28J60 (ohne SMD!)] (14.11.2007)&lt;br /&gt;
*[http://www.mikrocontroller.net/topic/100177 Erweiterbares Ethernetboard mit MMC/SD-Slot und USB] (17.05.2008)&lt;br /&gt;
*[http://www.mikrocontroller.net/topic/109988 AVR für wenig Geld im LAN] (03.09.2008)&lt;br /&gt;
*[http://www.mikrocontroller.net/topic/131825 Die andere Firmware für AVR-NET IO] (15.03.2009)&lt;br /&gt;
&lt;br /&gt;
==Hardware==&lt;br /&gt;
*[http://www.olimex.com/dev/images/enc28j60-sch.gif Minimalbeschaltung] (Quelle: Olimex)&lt;br /&gt;
*[http://www.b-redemann.de/produkte-ethernet.shtml Bausatz Ethernetmodul mit ENC28J60] (Ohne smds, www.b-redemann.de)&lt;br /&gt;
* Im [http://shop.mikrocontroller.net/ mikrocontroller.net Shop] das Modul von Olimex (22.04.2008)&lt;br /&gt;
*[http://www.ulrichradig.de/ Ulrich Radig] Ethernet ATmega32/644 Experimentierboard (01.09.2008)&lt;br /&gt;
*[http://www.pollin.de/ Pollin] Bausatz AVR-NET-IO, ArtNr 810 058 (01.09.2008)&lt;br /&gt;
*[http://rz-robotics.de/z-lan.html Z-LAN] bei rz-robotics mit 3,3V-Spannungsregler onboard (26.01.2009).&lt;br /&gt;
&lt;br /&gt;
==Software==&lt;br /&gt;
*[http://www.mil.ufl.edu/~chrisarnold/components/microcontrollerBoard/AVR/avrlib/docs/html/ Procyon AVRlib: Network Library ]&lt;br /&gt;
*[http://www.sics.se/~adam/uip/ uIP TCP/IP Stack for Embedded Microcontrollers]&lt;br /&gt;
*[http://www.ulrichradig.de/ Ulrich Radig] Ethernet ATmega32/644 Experimentierboard (01.09.2008)&lt;br /&gt;
*[http://ww1.microchip.com/downloads/en/DeviceDoc/Microchip%20TCPIP%20Stack%20v4.55%20Installer.zip TCP/IP Stack für PIC] von Microchip (26.01.2009)&lt;br /&gt;
* [http://wiki.neo-guerillaz.de Der &amp;quot;Hurrican&amp;quot; TCP/IP-Stack vom OpenMCP-Projekt] von Dirk Broßwick für den ATmega644/644P/1284P/2561 und ATXmega128A1 (15.03.2009)&lt;br /&gt;
&lt;br /&gt;
==Eagle Lib==&lt;br /&gt;
*[http://www.mikrocontroller.net/topic/51293 Eagle Lib aus dem Forum]&lt;br /&gt;
*[http://www.watterott.com/ENC28J60-SP-DIL28 Eagle Lib von www.watterott.com]&lt;br /&gt;
&lt;br /&gt;
==Datenblatt==&lt;br /&gt;
[http://ww1.microchip.com/downloads/en/DeviceDoc/39662b.pdf Link zum Datenblatt]&lt;br /&gt;
&lt;br /&gt;
==Häufige Fehlerursachen==&lt;br /&gt;
&#039;&#039;&#039;Frage&#039;&#039;&#039;: Mein ENC28J60 baut einen Link auf und empfängt laut RX Activity LED auch Pakete. Allerdings sind PKTIF und EPKTCNT 0x00. Die SPI Kommunikation arbeitet einwandfrei&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Antwort&#039;&#039;&#039;: Die Kondensatoren am Quarz des ENC28J60 spielen eine wichtige Rolle für den Empfang und die Versendung von Paketen. Testweise sollte man den Wert der Kondensatoren verringern (2,2pF haben schon einmal Erfolg gebracht) oder die Kondensatoren komplett entfernen.&lt;br /&gt;
Wenn schnelle HostController eingesetzt werden, muss unbedingt auf das Timing des CS-Anschlusses geachtet werden - beim Zugriff auf PHY und MAC Register muss nach der SPI-Übertragung CS 210ns aktiv bleiben. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Frage&#039;&#039;&#039;: Mein ENC28J60 wird recht warm. Ist er kaputt?&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Antwort&#039;&#039;&#039;: Nein. Schau mal ins Datasheet unter Stromverbrauch. Je nach Gehäusegrösse äussert sich der in &#039;&#039;warm&#039;&#039; bis &#039;&#039;heiss&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Ethernet]]&lt;br /&gt;
[[Kategorie:Bauteile]]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=AVR-GCC-Tutorial&amp;diff=61264</id>
		<title>AVR-GCC-Tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=AVR-GCC-Tutorial&amp;diff=61264"/>
		<updated>2011-10-23T14:21:02Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: /* EEPROM-Speicherabbild in .eep-Datei */  Schreibfehler korrigiert&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Voraussetzungen =&lt;br /&gt;
&lt;br /&gt;
Vorausgesetzt werden Grundkenntnisse der Programmiersprache C. Diese Kenntnisse kann man sich online erarbeiten, z. B. mit dem [http://www.schellong.de/c.htm C Tutorial von Helmut Schellong] ([[C|Liste von C-Tutorials]]). Nicht erforderlich sind Vorkenntnisse in der Programmierung von Mikrocontrollern, weder in Assembler noch in einer anderen Sprache.&lt;br /&gt;
&lt;br /&gt;
= Vorwort =&lt;br /&gt;
&lt;br /&gt;
Dieses Tutorial soll den Einstieg in die Programmierung von Atmel [[AVR]]-Mikrocontrollern in der Programmiersprache [[C]] mit dem freien C-Compiler [[AVR-GCC]] aus der [http://gcc.gnu.org/ GNU Compiler Collection] erleichtern.&lt;br /&gt;
&lt;br /&gt;
In diesem Text wird häufig auf die Standardbibliothek avr-libc verwiesen, für die es eine [http://www.nongnu.org/avr-libc/user-manual/index.html Online-Dokumentation] gibt, in der sich auch viele nützliche Informationen zum Compiler und zur Programmierung von AVR Controllern finden (beim Paket WinAVR gehört die avr-libc Dokumentation zum Lieferumfang und wird mitinstalliert).&lt;br /&gt;
&lt;br /&gt;
Der Compiler und die Standardbibliothek avr-libc werden stetig weiterentwickelt. Einige Unterschiede, die sich im Verlauf der Entwicklung ergeben haben, werden im Haupttext und Anhang zwar erläutert, Anfängern sei jedoch empfohlen, die aktuellen Versionen zu nutzen (für MS-Windows: aktuelle Version des [[WinAVR]]-Pakets; für Linux: siehe Artikel [[AVR und Linux]]).&lt;br /&gt;
&lt;br /&gt;
Das ursprüngliche Tutorial stammt von Christian Schifferle, viele neue Abschnitte und aktuelle Anpassungen von Martin Thomas.&lt;br /&gt;
&lt;br /&gt;
Dieses Tutorial ist in PDF-Form hier erhältlich (nicht immer auf aktuellem Stand):&lt;br /&gt;
[[Media:AVR-GCC-Tutorial.pdf]]&lt;br /&gt;
&lt;br /&gt;
== Weiterführende Kapitel ==&lt;br /&gt;
&lt;br /&gt;
Um dieses riesige Tutorial etwas überschaubarer zu gestalten, wurden einige Kapitel ausgelagert, die nicht unmittelbar mit den Grundlagen von avr-gcc in Verbindung stehen. All diese Seiten gehören zur [[:Kategorie:avr-gcc Tutorial]].&lt;br /&gt;
: &amp;amp;rarr; [[AVR-GCC-Tutorial/Der UART|Der UART]]&lt;br /&gt;
: &amp;amp;rarr; [[AVR-GCC-Tutorial/Der Watchdog|Der Watchdog]]&lt;br /&gt;
: &amp;amp;rarr; [[AVR-GCC-Tutorial/Die Timer und Zähler des AVR|Die Timer und Zähler des AVR]]&lt;br /&gt;
: &amp;amp;rarr; [[AVR-GCC-Tutorial/Exkurs Makefiles|Exkurs Makefiles]]&lt;br /&gt;
: &amp;amp;rarr; [[AVR-GCC-Tutorial/LCD-Ansteuerung|LCD-Ansteuerung]]&lt;br /&gt;
: &amp;amp;rarr; [[AVR-GCC-Tutorial/Alte Quellen|Alte Quellen anpassen]]&lt;br /&gt;
: &amp;amp;rarr; [[AVR-GCC-Tutorial/Assembler und Inline-Assembler|Assembler und Inline-Assembler]]&lt;br /&gt;
&lt;br /&gt;
= Benötigte Werkzeuge =&lt;br /&gt;
&lt;br /&gt;
Um eigene Programme für AVRs mittels avr-gcc/avr-libc zu erstellen und zu testen, wird folgende Hard- und Software benötigt:&lt;br /&gt;
&lt;br /&gt;
* Platine oder Versuchsaufbau für die Aufnahme eines AVR Controllers, der vom avr-gcc Compiler unterstützt wird (alle ATmegas und die meisten AT90, siehe Dokumentation der avr-libc für unterstützte Typen). Dieses Testboard kann durchaus auch selbst gelötet oder auf einem Steckbrett aufgebaut werden. Einige Registerbeschreibungen dieses Tutorials beziehen sich auf den inzwischen veralteten AT90S2313. Der weitaus größte Teil des Textes ist aber für alle Controller der AVR-Familie gültig. Brauchbare Testplattformen sind auch das [[STK500]] und der [[AVR Butterfly]] von Atmel. Weitere Infos findet man in den Artikeln [[AVR#Starterkits|AVR Starterkits]] und [[AVR-Tutorial: Equipment]].&lt;br /&gt;
&lt;br /&gt;
* Der avr-gcc Compiler und die avr-libc. Kostenlos erhältlich für nahezu alle Plattformen und Betriebssysteme. Für MS-Windows im Paket [[WinAVR]]; für Unix/Linux siehe auch Hinweise im Artikel [[AVR-GCC]] und im Artikel [[AVR und Linux]].&lt;br /&gt;
&lt;br /&gt;
* Programmiersoftware und -[[AVR In System Programmer |hardware]] z. B. PonyProg (siehe auch: [[Pony-Prog Tutorial]]) oder [[AVRDUDE]] mit [[STK200]]-Dongle oder die von Atmel verfügbare Hard- und Software ([[STK500]], Atmel AVRISP, [[AVR-Studio]]).&lt;br /&gt;
&lt;br /&gt;
* Nicht unbedingt erforderlich, aber zur Simulation und zum Debuggen unter MS-Windows recht nützlich: [[AVR-Studio]] (siehe Artikel [[AVR-GCC-Tutorial/Exkurs_Makefiles|Exkurs: Makefiles]]).&lt;br /&gt;
&lt;br /&gt;
* Wer unter Windows und Linux gleichermassen entwickeln will, der sollte sich die [http://www.eclipse.org/ IDE Eclipse for C/C++ Developers] und das [http://avr-eclipse.sourceforge.net/wiki/index.php/The_AVR_Eclipse_Plugin AVR-Eclipse Plugin ] ansehen, beide sind unter Windows und Linux einfach zu installieren. Hier gibt es auch einen [[AVR_Eclipse|Artikel AVR Eclipse]] in dieser Wiki. Ebenfalls unter Linux und Windows verfügbar ist die Entwicklungsumgebung [http://www.codeblocks.org/ Code::Blocks] (aktuelle, stabile Versionen sind als Nightly Builds regelmäßig im [http://forums.codeblocks.org/ Forum] verfügbar). Innerhalb dieser Entwicklungsumgebung können ohne die Installation zusätzlicher Plugins &amp;quot;AVR-Projekte&amp;quot; angelegt werden. Für Linux gibt es auch noch das [http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=25220&amp;amp;postdays=0&amp;amp;postorder=asc&amp;amp;start=0 KontrollerLab].&lt;br /&gt;
&lt;br /&gt;
= Was tun, wenn&#039;s nicht &amp;quot;klappt&amp;quot;? =&lt;br /&gt;
&lt;br /&gt;
* Herausfinden, ob es tatsächlich ein avr(-gcc) spezifisches Problem ist oder nur die eigenen C-Kenntnisse einer Auffrischung bedürfen. Allgemeine C-Fragen kann man eventuell &amp;quot;beim freundlichen Programmierer zwei Büro-, Zimmer- oder Haustüren weiter&amp;quot; loswerden. Ansonsten: [[C]]-Buch (gibt&#039;s auch &amp;quot;gratis&amp;quot; online) lesen.&lt;br /&gt;
&lt;br /&gt;
* Die [[AVR Checkliste]] durcharbeiten.&lt;br /&gt;
&lt;br /&gt;
* Die &#039;&#039;&#039;[http://www.nongnu.org/avr-libc/user-manual/index.html Dokumentation der avr-libc]&#039;&#039;&#039; lesen, vor allem (aber nicht nur) den Abschnitt Related Pages/&#039;&#039;&#039;Frequently Asked Questions&#039;&#039;&#039; = Oft gestellte Fragen (und Antworten dazu). Z.Zt leider nur in englischer Sprache verfügbar.&lt;br /&gt;
&lt;br /&gt;
* Den Artikel [[AVR-GCC]] in diesem Wiki lesen.&lt;br /&gt;
&lt;br /&gt;
* Das [http://www.mikrocontroller.net/forum/gcc GCC-Forum auf  www.mikrocontroller.net] nach vergleichbaren Problemen absuchen.&lt;br /&gt;
&lt;br /&gt;
* Das avr-gcc-Forum bei [http://www.avrfreaks.net AVRfreaks] nach vergleichbaren Problemen absuchen.&lt;br /&gt;
&lt;br /&gt;
* Das [http://lists.gnu.org/archive/html/avr-gcc-list/ Archiv der avr-gcc Mailing-Liste] nach vergleichbaren Problemen absuchen.&lt;br /&gt;
&lt;br /&gt;
* Nach Beispielcode suchen. Vor allem im &#039;&#039;Projects&#039;&#039;-Bereich von [http://www.avrfreaks.net AVRfreaks] (anmelden).&lt;br /&gt;
&lt;br /&gt;
* Google oder yahoo befragen schadet nie.&lt;br /&gt;
&lt;br /&gt;
* Bei Problemen mit der Ansteuerung interner AVR-Funktionen mit C-Code: das Datenblatt des Controllers lesen (ganz und am Besten zweimal). Datenblätter sind  auf den [http://www.atmel.com Atmel Webseiten] als pdf-Dateien verfügbar. Das komplette Datenblatt (complete) und nicht die Kurzfassung (summary) verwenden.&lt;br /&gt;
&lt;br /&gt;
* Die Beispielprogramme im [[AVR-Tutorial]] sind zwar in AVR-Assembler verfasst, Erläuterungen und Vorgehensweisen sind aber auch auf C-Programme übertragbar.&lt;br /&gt;
&lt;br /&gt;
* Einen Beitrag in eines der Foren oder eine Mail an die Mailing-Liste schreiben. Dabei möglichst viel Information geben: Controller, Compilerversion, genutzte Bibliotheken, Ausschnitte aus dem Quellcode oder besser ein [http://www.mikrocontroller.net/topic/72767#598986 Testprojekt] mit allen notwendigen Dateien, um das Problem nachzuvollziehen, sowie genaue Fehlermeldungen bzw. Beschreibung des Fehlverhaltens. Bei Ansteuerung externer Geräte die Beschaltung beschreiben oder skizzieren (z. B. mit [http://www.tech-chat.de/ Andys ASCII Circuit]). Siehe dazu auch: &#039;&#039;&#039;[http://www.tty1.net/smart-questions_de.html &amp;quot;Wie man Fragen richtig stellt&amp;quot;]&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
= Erzeugen von Maschinencode =&lt;br /&gt;
&lt;br /&gt;
Aus dem C-Quellcode erzeugt der avr-gcc Compiler (zusammen mit Hilfsprogrammen wie z.&amp;amp;nbsp;B. Präprozessor, Assembler und Linker) Maschinencode für den AVR-Controller. Üblicherweise liegt dieser Code dann im Intel Hex-Format vor (&amp;quot;Hex-Datei&amp;quot;). Die Programmiersoftware (z.&amp;amp;nbsp;B. [[AVRDUDE]], PonyProg oder AVRStudio/STK500-plugin) liest diese Datei ein und überträgt die enthaltene Information (den Maschinencode) in den Speicher des Controllers. Im Prinzip sind also &amp;quot;nur&amp;quot; der avr-gcc-Compiler (und wenige Hilfsprogramme) mit den &amp;quot;richtigen&amp;quot; Optionen aufzurufen, um aus C-Code eine &amp;quot;Hex-Datei&amp;quot; zu erzeugen. Grundsätzlich stehen dazu zwei verschiedene Ansätze zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
* Die Verwendung einer integrierten Entwicklungsumgebung (IDE = &#039;&#039;&#039;I&#039;&#039;&#039;ntegrated &#039;&#039;&#039;D&#039;&#039;&#039;evelopment &#039;&#039;&#039;E&#039;&#039;&#039;nvironment), bei der alle Einstellungen z.&amp;amp;nbsp;B. in Dialogboxen durchgeführt werden können. Unter Anderem kann AVRStudio ab Version 4.12 (kostenlos auf [http://www.atmel.com/ atmel.com]) zusammen mit WinAVR als integrierte Entwicklungsumgebung für den Compiler avr-gcc genutzt werden (dazu müssen AVRStudio und WinAVR auf dem Rechner installiert sein). Weitere IDEs (ohne Anspruch auf Vollständigkeit): [http://www.eclipse.org/ Eclipse for C/C++ Developers] (d.h. inkl. CDT) und das [http://avr-eclipse.sourceforge.net/wiki/index.php/The_AVR_Eclipse_Plugin AVR-Eclipse Plugin] (für diverse Plattformen, u.a. Linux und MS Windows, IDE und Plugin kostenlos), [http://sourceforge.net/projects/kontrollerlab KontrollerLab] (Linux/KDE, kostenlos). [http://www.atmanecl.com/EnglishSite/SoftwareEnglish.htm AtmanAvr] (MS Windows, relativ günstig), KamAVR (MS-Windows, kostenlos, wird augenscheinlich nicht mehr weiterentwickelt), [http://www.amctools.com/vmlab.htm VMLab] (MS Windows, ab Version 3.12 ebenfalls kostenlos). Integrierte Entwicklungsumgebungen unterscheiden sich stark in Ihrer Bedienung und stehen auch nicht für alle Plattformen zur Verfügung, auf denen der Compiler  ausführbar ist (z.&amp;amp;nbsp;B. AVRStudio nur für MS-Windows). Zur Anwendung des avr-gcc Compilers mit IDEs sei hier auf deren Dokumentation verwiesen. &lt;br /&gt;
&lt;br /&gt;
* Die Nutzung des Programms make mit passenden Makefiles. In den folgenden Abschnitten wird die Generierung von Maschinencode für einen AVR (&amp;quot;hex-Datei&amp;quot;) aus C-Quellcode (&amp;quot;c-Dateien&amp;quot;) anhand von &amp;quot;make&amp;quot; und den &amp;quot;Makefiles&amp;quot; näher erläutert. Viele der darin beschriebenen Optionen findet man auch im Konfigurationsdialog des avr-gcc-Plugins von AVRStudio (AVRStudio generiert ein makefile in einem Unterverzeichnis des Projektverzeichnisses). &lt;br /&gt;
&lt;br /&gt;
Beim Wechsel vom makefile-Ansatz nach WinAVR-Vorlage zu AVRStudio ist darauf zu achten, dass AVRStudio (Stand: AVRStudio Version 4.13) bei einem neuen Projekt die Optimierungsoption (vgl. Artikel [[AVR-GCC-Tutorial/Exkurs_Makefiles|AVR-GCC-Tutorial/Exkurs: Makefiles]], typisch: -Os) nicht einstellt und die mathematische Bibliothek der avr-libc (libm.a, Linker-Option -lm) nicht einbindet. (Hinweis: Bei Version 4.16 wird beides bereits gesetzt). Beides ist Standard bei Verwendung von makefiles nach WinAVR-Vorlage und sollte daher auch im Konfigurationsdialog des avr-gcc-Plugins von AVRStudio &amp;quot;manuell&amp;quot; eingestellt werden, um auch mit AVRStudio kompakten Code zu erzeugen.&lt;br /&gt;
&lt;br /&gt;
= Einführungsbeispiel =&lt;br /&gt;
&lt;br /&gt;
Zum Einstieg ein kleines Beispiel, an dem die Nutzung des Compilers und der Hilfsprogramme (der sogenannten &#039;&#039;Toolchain&#039;&#039;) demonstriert wird. Detaillierte Erläuterungen folgen in den weiteren Abschnitten dieses Tutorials.&lt;br /&gt;
&lt;br /&gt;
Das Programm soll auf einem AVR Mikrocontroller einige Ausgänge ein- und andere ausschalten. Das Beispiel ist für einen ATmega16 programmiert ([http://www.atmel.com/dyn/resources/prod_documents/doc2466.pdf Datenblatt]), kann aber sinngemäß für andere Controller der AVR-Familie modifiziert werden. &lt;br /&gt;
&lt;br /&gt;
Ein kurzes Wort zur Hardware: Bei diesem Programm werden alle Pins von PORTB auf Ausgang gesetzt, und einige davon werden auf HIGH andere auf LOW gesetzt. Das kann je nach angeschlossener Hardware an diesen Pins kritisch sein. Am ungefährlichsten ist es, wenn nichts an den Pins angeschlossen ist und man die Funktion des Programmes durch eine Spannungsmessung mit einem Multimeter kontrolliert. Die Spannung wird dabei zwischen GND-Pin und den einzelnen Pins von PORTB gemessen.&lt;br /&gt;
&lt;br /&gt;
Zunächst der Quellcode der Anwendung, der in einer Text-Datei mit dem Namen &#039;&#039;main.c&#039;&#039; abgespeichert wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
/* Alle Zeichen zwischen Schrägstrich-Stern &lt;br /&gt;
   und Stern-Schrägstrich sind Kommentare */&lt;br /&gt;
&lt;br /&gt;
// Zeilenkommentare sind ebenfalls möglich&lt;br /&gt;
// alle auf die beiden Schrägstriche folgenden&lt;br /&gt;
// Zeichen einer Zeile sind Kommentar&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;          // (1)&lt;br /&gt;
&lt;br /&gt;
int main (void) {            // (2)&lt;br /&gt;
&lt;br /&gt;
   DDRB  = 0xFF;             // (3)&lt;br /&gt;
   PORTB = 0x03;             // (4)&lt;br /&gt;
&lt;br /&gt;
   while(1) {                // (5)&lt;br /&gt;
     /* &amp;quot;leere&amp;quot; Schleife*/   // (6)&lt;br /&gt;
   }                         // (7)&lt;br /&gt;
&lt;br /&gt;
   /* wird nie erreicht */&lt;br /&gt;
   return 0;                 // (8)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# In dieser Zeile wird eine sogenannte Header-Datei eingebunden. In &amp;lt;code&amp;gt;avr/io.h&amp;lt;/code&amp;gt; sind die Registernamen definiert, die im späteren Verlauf genutzt werden. Auch unter Windows wird ein&amp;amp;nbsp;&amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt; zur Kennzeichnung von Unterverzeichnissen in Include-Dateinamen verwendet und kein&amp;amp;nbsp;&amp;lt;code&amp;gt;\&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Hier beginnt das eigentliche Programm. Jedes C-Programm beginnt mit den Anweisungen in der Funktion &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Die Anschlüsse eines AVR (&amp;quot;Beinchen&amp;quot;) werden zu Blöcken zusammengefasst, einen solchen Block bezeichnet man als Port. Beim ATmega16 hat jeder Port 8 Anschlüsse, bei kleineren AVRs können einem Port auch weniger als 8 Anschlüsse zugeordnet sein. Da per Definition (Datenblatt) alle gesetzten Bits in einem Datenrichtungsregister den entsprechenden Anschluss auf Ausgang schalten, werden mit DDRB=0xff alle Anschlüsse des Ports B als Ausgänge eingestellt.&lt;br /&gt;
# stellt die Werte der Ausgänge ein. Die den ersten beiden Bits des Ports zugeordneten Anschlüsse (PB0 und PB1) werden 1, alle anderen Anschlüsse des Ports B (PB2-PB7) zu 0. Aktivierte Ausgänge (logisch 1 oder &amp;quot;high&amp;quot;) liegen auf Betriebsspannung (VCC, meist 5 Volt), nicht aktivierte Ausgänge führen 0 Volt (GND, Bezugspotential). Es ist sinnvoll, sich möglichst frühzeitig eine alternative Schreibweise beizubringen, die wegen der leichteren Überprüfbarkeit und Portierbarkeit oft im weiteren Tutorial und in Forenbeiträgen benutzt wird. Die Zuordnung sieht in diesem Fall so aus, Näheres dazu im Artikel [[Bitmanipulation]]:&amp;lt;c&amp;gt;PORTB = (1&amp;lt;&amp;lt;PB1) | (1&amp;lt;&amp;lt;PB0);&amp;lt;/c&amp;gt;&lt;br /&gt;
# ist der Beginn der sogenannte &#039;&#039;Hauptschleife&#039;&#039; (main-loop). Dies ist eine Endlosschleife, welche kontinuierlich wiederkehrende Befehle enthält.&lt;br /&gt;
# In diesem Beispiel ist die Hauptschleife leer. Der Controller durchläuft die Schleife immer wieder, ohne dass etwas passiert. Eine solche Schleife ist notwendig, da es auf dem Controller kein Betriebssystem gibt, das nach Beendigung des Programmes die Kontrolle übernehmen könnte. Ohne diese Schleife kehrt das Programm aus &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt; zurück, alle Interrupts werden deaktiviert und eine Endlosschleife betreten.&lt;br /&gt;
# Ende der Hauptschleife und Sprung zur passenden, öffnenden Klammer, also zu 5.&lt;br /&gt;
# ist das Programmende. Die Zeile ist nur aus Gründen der C-Kompatibilität enthalten: &amp;lt;c&amp;gt;int main(void)&amp;lt;/c&amp;gt; besagt, dass die Funktion einen int-Wert zurückgibt. Die Anweisung wird aber nicht erreicht, da das Programm die Hauptschleife nie verlässt.&lt;br /&gt;
&lt;br /&gt;
Um diesen Quellcode in ein lauffähiges Programm zu übersetzen, wird hier ein Makefile genutzt. Das verwendete Makefile findet sich auf der Seite [[Beispiel Makefile]] und basiert auf der Vorlage, die in WinAVR mitgeliefert wird und wurde bereits angepasst (Controllertyp ATmega16). Man kann das Makefile bearbeiten und an andere Controller anpassen oder sich mit dem Programm MFile menügesteuert ein Makefile &amp;quot;zusammenklicken&amp;quot;. Das Makefile speichert man unter dem Namen &amp;lt;code&amp;gt;Makefile&amp;lt;/code&amp;gt; (ohne Endung) im selben Verzeichnis, in dem auch die Datei &amp;lt;code&amp;gt;main.c&amp;lt;/code&amp;gt; mit dem Programmcode abgelegt ist. Detailliertere Erklärungen zur Funktion von Makefiles finden sich im Artikel [[AVR-GCC-Tutorial/Exkurs_Makefiles|Exkurs: Makefiles]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
D:\beispiel&amp;gt;dir&lt;br /&gt;
&lt;br /&gt;
 Verzeichnis von D:\beispiel&lt;br /&gt;
&lt;br /&gt;
28.11.2006  22:53    &amp;lt;DIR&amp;gt;          .&lt;br /&gt;
28.11.2006  22:53    &amp;lt;DIR&amp;gt;          ..&lt;br /&gt;
28.11.2006  20:06               118 main.c&lt;br /&gt;
28.11.2006  20:03            16.810 Makefile&lt;br /&gt;
               2 Datei(en)         16.928 Bytes&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun gibt man &#039;&#039;make all&#039;&#039; ein. Falls das mit WinAVR installierte Programmers Notepad genutzt wird, gibt es dazu einen Menüpunkt im Tools Menü. Sind alle Einstellungen korrekt, entsteht eine Datei &amp;lt;code&amp;gt;main.hex&amp;lt;/code&amp;gt;, in welcher der Code für den AVR enthalten ist. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
D:\beispiel&amp;gt;make all&lt;br /&gt;
&lt;br /&gt;
-------- begin --------&lt;br /&gt;
avr-gcc (GCC) 3.4.6&lt;br /&gt;
Copyright (C) 2006 Free Software Foundation, Inc.&lt;br /&gt;
This is free software; see the source for copying conditions.  There is NO&lt;br /&gt;
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.&lt;br /&gt;
&lt;br /&gt;
Compiling C: main.c&lt;br /&gt;
avr-gcc -c -mmcu=atmega16 -I. -gdwarf-2 -DF_CPU=1000000UL -Os -funsigned-char -f&lt;br /&gt;
unsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wundef&lt;br /&gt;
 -Wa,-adhlns=obj/main.lst  -std=gnu99 -Wundef -MD -MP -MF .dep/main.o.d main.c -&lt;br /&gt;
o obj/main.o&lt;br /&gt;
&lt;br /&gt;
Linking: main.elf&lt;br /&gt;
avr-gcc -mmcu=atmega16 -I. -gdwarf-2 -DF_CPU=1000000UL -Os -funsigned-char -funs&lt;br /&gt;
igned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wundef -W&lt;br /&gt;
a,-adhlns=obj/main.o  -std=gnu99 -Wundef -MD -MP -MF .dep/main.elf.d obj/main.o&lt;br /&gt;
--output main.elf -Wl,-Map=main.map,--cref    -lm&lt;br /&gt;
&lt;br /&gt;
Creating load file for Flash: main.hex&lt;br /&gt;
avr-objcopy -O ihex -R .eeprom main.elf main.hex&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Inhalt der hex-Datei kann nun zum Controller übertragen werden. Dies kann z.&amp;amp;nbsp;B. über In-System-Programming ([[ISP]]) erfolgen, das im [[AVR-Tutorial: Equipment]] beschrieben ist. Makefiles nach der WinAVR/MFile-Vorlage sind für die Nutzung des Programms [[AVRDUDE]] vorbereitet. Wenn man den Typ und Anschluss des Programmiergerätes richtig eingestellt hat, kann mit &#039;&#039;make program&#039;&#039; die Übertragung mittels AVRDUDE gestartet werden. Jede andere Software, die hex-Dateien lesen und zu einem AVR übertragen kann&amp;lt;ref&amp;gt;z.&amp;amp;nbsp;B. [[Pony-Prog_Tutorial|Ponyprog]], yapp, AVRStudio&amp;lt;/ref&amp;gt;, kann natürlich ebenfalls genutzt werden.&lt;br /&gt;
&lt;br /&gt;
Startet man nun den Controller (Reset-Taster oder Stromzufuhr aus/an), werden vom Programm die Anschlüsse PB0 und PB1 auf 1 gesetzt. Man kann mit einem Messgerät nun an diesem Anschluss die Betriebsspannung messen oder eine [[LED]] leuchten lassen (Anode an den Pin, Vorwiderstand nicht vergessen). An den Anschlüssen PB2-PB7 misst man 0 Volt. Eine mit der Anode mit einem dieser Anschlüsse verbundene LED leuchtet nicht.&lt;br /&gt;
&lt;br /&gt;
= Ganzzahlige (Integer) Datentypen =&lt;br /&gt;
&lt;br /&gt;
Bei der Programmierung von Mikrokontrollern ist die Definition einiger ganzzahliger Datentypen sinnvoll, an denen eindeutig die Bit-Länge abgelesen werden kann.&lt;br /&gt;
&lt;br /&gt;
Standardisierte Datentypen werden in der Header-Datei &amp;lt;code&amp;gt;stdint.h&amp;lt;/code&amp;gt; definiert, die folgendermaßen eingebunden werden kann:&lt;br /&gt;
&amp;lt;c&amp;gt;#include &amp;lt;stdint.h&amp;gt;&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| {{Tabelle}}&lt;br /&gt;
|+ &#039;&#039;&#039;int-Typen aus &amp;lt;code&amp;gt;stdint.h&amp;lt;/code&amp;gt; (C99)&#039;&#039;&#039;&amp;lt;br/&amp;gt;&amp;amp;nbsp;&lt;br /&gt;
|- bgcolor=&amp;quot;#d0d0ff&amp;quot;&lt;br /&gt;
!colspan=&amp;quot;5&amp;quot;| Vorzeichenbehaftete int-Typen&lt;br /&gt;
|- bgcolor=&amp;quot;#e8e8ff&amp;quot;&lt;br /&gt;
! Typname || Bit-Breite ||colspan=&amp;quot;2&amp;quot;| Wertebereich&lt;br /&gt;
|align=&amp;quot;center| &#039;&#039;&#039;C-Entsprechung&#039;&#039;&#039; (avr-gcc)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;int8_t&amp;lt;/code&amp;gt; ||align=&amp;quot;right&amp;quot;| 8 || −128 ⋯ 127 || −2&amp;lt;sup&amp;gt;7&amp;lt;/sup&amp;gt; ⋯ 2&amp;lt;sup&amp;gt;7&amp;lt;/sup&amp;gt;−1 || &amp;lt;code&amp;gt;signed char&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;int16_t&amp;lt;/code&amp;gt; ||align=&amp;quot;right&amp;quot;| 16 || −32768 ⋯ 32767 || −2&amp;lt;sup&amp;gt;15&amp;lt;/sup&amp;gt; ⋯ 2&amp;lt;sup&amp;gt;15&amp;lt;/sup&amp;gt;−1 || &amp;lt;code&amp;gt;signed short&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;signed int&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;int32_t&amp;lt;/code&amp;gt; ||align=&amp;quot;right&amp;quot;| 32 || −2147483648 ⋯ 2147483647 || −2&amp;lt;sup&amp;gt;31&amp;lt;/sup&amp;gt; ⋯ 2&amp;lt;sup&amp;gt;31&amp;lt;/sup&amp;gt;−1 || &amp;lt;code&amp;gt;signed long&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;int64_t&amp;lt;/code&amp;gt; ||align=&amp;quot;right&amp;quot;| 64 || −9223372036854775808 ⋯ 9223372036854775807 || −2&amp;lt;sup&amp;gt;63&amp;lt;/sup&amp;gt; ⋯ 2&amp;lt;sup&amp;gt;63&amp;lt;/sup&amp;gt;−1 || &amp;lt;code&amp;gt;signed long long&amp;lt;/code&amp;gt;&lt;br /&gt;
|- bgcolor=&amp;quot;#d0d0ff&amp;quot;&lt;br /&gt;
!colspan=&amp;quot;5&amp;quot;| Vorzeichenlose int-Typen&lt;br /&gt;
|- bgcolor=&amp;quot;#e8e8ff&amp;quot;&lt;br /&gt;
! Typname || Bit-Breite ||colspan=&amp;quot;2&amp;quot;| Wertebereich&lt;br /&gt;
|align=&amp;quot;center| &#039;&#039;&#039;C-Entsprechung&#039;&#039;&#039; (avr-gcc)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;uint8_t&amp;lt;/code&amp;gt; ||align=&amp;quot;right&amp;quot;| 8 || 0 ⋯ 255 || 0 ⋯ 2&amp;lt;sup&amp;gt;8&amp;lt;/sup&amp;gt;−1 || &amp;lt;code&amp;gt;unsigned char&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;uint16_t&amp;lt;/code&amp;gt; ||align=&amp;quot;right&amp;quot;| 16 || 0 ⋯ 65535 || 0 ⋯ 2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;−1 || &amp;lt;code&amp;gt;unsigned short&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;unsigned int&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;uint32_t&amp;lt;/code&amp;gt; ||align=&amp;quot;right&amp;quot;| 32 || 0 ⋯ 4294967295 || 0 ⋯ 2&amp;lt;sup&amp;gt;32&amp;lt;/sup&amp;gt;−1 || &amp;lt;code&amp;gt;unsigned long&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;uint64_t&amp;lt;/code&amp;gt; ||align=&amp;quot;right&amp;quot;| 64 || 0 ⋯ 18446744073709551615 || 0 ⋯ 2&amp;lt;sup&amp;gt;64&amp;lt;/sup&amp;gt;−1 || &amp;lt;code&amp;gt;unsigned long long&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Neben den Typen gibt es auch Makros für die Bereichsgrenzen wie &amp;lt;code&amp;gt;INT8_MIN&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;UINT16_MAX&amp;lt;/code&amp;gt;. Siehe dazu auch: [http://www.nongnu.org/avr-libc/user-manual/group__avr__stdint.html Dokumentation der avr-libc: Standard Integer Types].&lt;br /&gt;
&lt;br /&gt;
= Bitfelder =&lt;br /&gt;
&lt;br /&gt;
Beim Programmieren von Mikrocontrollern muss auf jedes Byte oder sogar auf&lt;br /&gt;
jedes Bit geachtet werden. Oft müssen wir in einer Variablen lediglich den&lt;br /&gt;
Zustand 0 oder 1 speichern. Wenn wir nun zur Speicherung eines einzelnen Wertes&lt;br /&gt;
den kleinsten bekannten Datentypen, nämlich &#039;&#039;&#039;unsigned char&#039;&#039;&#039;, nehmen, dann&lt;br /&gt;
verschwenden wir 7 Bits, da ein &#039;&#039;&#039;unsigned char&#039;&#039;&#039; ja 8 Bits breit ist.&lt;br /&gt;
&lt;br /&gt;
Hier bietet uns die Programmiersprache C ein mächtiges Werkzeug an, mit dessen&lt;br /&gt;
Hilfe wir 8 Bits in eine einzelne Bytevariable zusammenfassen und (fast) wie&lt;br /&gt;
8 einzelne Variablen ansprechen können. Die Rede ist von sogenannten Bitfeldern. Diese werden als Strukturelemente definiert. Sehen wir uns dazu doch am besten gleich ein Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
struct {&lt;br /&gt;
   unsigned bStatus_1:1; // 1 Bit für bStatus_1&lt;br /&gt;
   unsigned bStatus_2:1; // 1 Bit für bStatus_2&lt;br /&gt;
   unsigned bNochNBit:1; // Und hier noch mal ein Bit&lt;br /&gt;
   unsigned b2Bits:2;    // Dieses Feld ist 2 Bits breit&lt;br /&gt;
   // All das hat in einer einzigen Byte-Variable Platz.&lt;br /&gt;
   // die 3 verbleibenden Bits bleiben ungenutzt&lt;br /&gt;
} x;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Zugriff auf ein solches Feld erfolgt nun, wie beim Strukturzugriff bekannt,&lt;br /&gt;
über den Punkt- oder den Dereferenzierungs-Operator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
x.bStatus_1 = 1;&lt;br /&gt;
x.bStatus_2 = 0;&lt;br /&gt;
x.b2Bits = 3;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bitfelder sparen Platz im RAM, zu Lasten von Platz im Flash, verschlechtern aber unter Umständen die Les- und Wartbarkeit des Codes. Anfängern wird deshalb geraten, ein &amp;quot;ganzes&amp;quot; Byte (uint8_t) zu nutzen, auch wenn nur ein Bitwert gespeichert werden soll.&lt;br /&gt;
&lt;br /&gt;
= Grundsätzlicher Programmaufbau eines µC-Programms =&lt;br /&gt;
&lt;br /&gt;
Wir unterscheiden zwischen 2 verschiedenen Methoden, um ein&lt;br /&gt;
Mikrocontroller-Programm zu schreiben, und zwar völlig unabhängig davon, in&lt;br /&gt;
welcher Programmiersprache das Programm geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
== Sequentieller Programmablauf ==&lt;br /&gt;
&lt;br /&gt;
[[Image:Sequentielle Programme.gif|left]]&lt;br /&gt;
Bei dieser Programmiertechnik wird eine Endlosschleife programmiert, welche im&lt;br /&gt;
Wesentlichen immer den gleichen Aufbau hat. Es wird hier nach dem sogenannten EVA-Prinzip gehandelt. EVA steht für &amp;quot;Eingabe, Verarbeitung, Ausgabe&amp;quot;:&lt;br /&gt;
{{Absatz}}&lt;br /&gt;
&lt;br /&gt;
== Interruptgesteuerter Programmablauf ==&lt;br /&gt;
&lt;br /&gt;
[[Image:Interrupt Programme.gif|left]]&lt;br /&gt;
Bei dieser Methode werden beim Programmstart zuerst die gewünschten Interruptquellen aktiviert und dann in eine Endlosschleife gegangen, in welcher Dinge erledigt werden können, welche nicht zeitkritisch sind. Wenn ein Interrupt ausgelöst wird, so wird automatisch die zugeordnete Interruptfunktion ausgeführt.&lt;br /&gt;
{{Absatz}}&lt;br /&gt;
&lt;br /&gt;
= Zugriff auf Register =&lt;br /&gt;
&lt;br /&gt;
Die AVR-Controller verfügen über eine Vielzahl von Registern. Die meisten&lt;br /&gt;
davon sind sogenannte Schreib-/Leseregister. Das heißt, das Programm kann die&lt;br /&gt;
Inhalte der Register sowohl auslesen als auch beschreiben.&lt;br /&gt;
&lt;br /&gt;
Register haben einen besonderen Stellenwert bei den AVR Controllern. Sie dienen dem Zugriff auf die Ports und die Schnittstellen des Controllers. Wir unterscheiden zwischen 8-Bit und 16-Bit Registern. Vorerst behandeln wir die 8-Bit Register.&lt;br /&gt;
&lt;br /&gt;
Einzelne Register sind bei allen AVRs vorhanden, andere wiederum nur bei bestimmten Typen. So sind beispielsweise die Register, welche für den Zugriff auf den UART notwendig sind, selbstverständlich nur bei denjenigen Modellen vorhanden, welche über einen integrierten Hardware UART bzw. USART verfügen.&lt;br /&gt;
&lt;br /&gt;
Die Namen der Register sind in den Headerdateien zu den entsprechenden AVR-Typen definiert. Dazu muss man den Namen der controllerspezifischen Headerdatei nicht kennen. Es reicht aus, die allgemeine Headerdatei &#039;&#039;avr/io.h&#039;&#039; einzubinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ist im Makefile der MCU-Typ z.&amp;amp;nbsp;B. mit dem Inhalt atmega8 definiert (und wird somit per -mmcu=atmega8 an den Compiler übergeben), wird beim Einlesen der io.h-Datei implizit (&amp;quot;automatisch&amp;quot;) auch die iom8.h-Datei mit den Register-Definitionen für den ATmega8 eingelesen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Wohl besser als Anhang - spaeter... --&amp;gt;&lt;br /&gt;
Intern wird diese &amp;quot;Automatik&amp;quot; wie folgt realisiert: Der Controllertyp wird dem Compiler als Parameter übergeben (vgl. &#039;&#039;avr-gcc -c -mmcu=atmega16 [...]&#039;&#039; im Einführungsbeispiel). Wird ein Makefile nach der WinAVR/mfile-Vorlage verwendet, setzt man die Variable &#039;&#039;MCU&#039;&#039;, der Inhalt dieser Variable wird dann an passender Stelle für die Compilerparameter verwendet. Der Compiler definiert intern eine dem mmcu-Parameter zugeordnete &amp;quot;Variable&amp;quot; (genauer: ein Makro) mit dem Namen des Controllers, vorangestelltem &#039;&#039;__AVR_&#039;&#039; und angehängten Unterstrichen (z.&amp;amp;nbsp;B. wird bei &#039;&#039;-mmcu=atmega16&#039;&#039; das Makro &#039;&#039;__AVR_ATmega16__&#039;&#039; definiert). Beim Einbinden der Header-Datei &#039;&#039;avr/io.h&#039;&#039; wird geprüft, ob das jeweilige Makro definiert ist und die zum Controller passende Definitionsdatei eingelesen. Zur Veranschaulichung einige Ausschnitte aus einem Makefile:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[...]&lt;br /&gt;
# MCU Type (&amp;quot;name&amp;quot;) setzen:&lt;br /&gt;
MCU = atmega16&lt;br /&gt;
[...]&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
## Verwendung des Inhalts von MCU (hier atmega16) fuer die &lt;br /&gt;
## Compiler- und Assembler-Parameter&lt;br /&gt;
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS)&lt;br /&gt;
ALL_CPPFLAGS = -mmcu=$(MCU) -I. -x c++ $(CPPFLAGS) $(GENDEPFLAGS)&lt;br /&gt;
ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)&lt;br /&gt;
[...]&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
## Aufruf des Compilers:&lt;br /&gt;
## mit den Parametern ($(ALL_CFLAGS) ist -mmcu=$(MCU)[...] = -mmcu=atmega16[...]&lt;br /&gt;
$(OBJDIR)/%.o : %.c&lt;br /&gt;
	@echo&lt;br /&gt;
	@echo $(MSG_COMPILING) $&amp;lt;&lt;br /&gt;
	$(CC) -c $(ALL_CFLAGS) $&amp;lt; -o $@ &lt;br /&gt;
[...]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da --mmcu=atmega16 übergeben wurde, wird __AVR_ATmega16__ definiert und kann in avr/io.h zur Fallunterscheidung genutzt werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
// avr/io.h &lt;br /&gt;
// (bei WinAVR-Standardinstallation in C:\WinAVR\avr\include\avr)&lt;br /&gt;
[...]&lt;br /&gt;
#if defined (__AVR_AT94K__)&lt;br /&gt;
#  include &amp;lt;avr/ioat94k.h&amp;gt;&lt;br /&gt;
// [...]&lt;br /&gt;
#elif defined (__AVR_ATmega16__)&lt;br /&gt;
// da __AVR_ATmega16__ definiert ist, wird avr/iom16.h eingebunden:&lt;br /&gt;
#  include &amp;lt;avr/iom16.h&amp;gt;&lt;br /&gt;
// [...]&lt;br /&gt;
#else&lt;br /&gt;
#  if !defined(__COMPILING_AVR_LIBC__)&lt;br /&gt;
#    warning &amp;quot;device type not defined&amp;quot;&lt;br /&gt;
#  endif&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Beispiele in den folgenden Abschnitten demonstrieren den Zugriff auf Register anhand der Register für I/O-Ports (PORTx, DDRx, PINx), die Vorgehensweise ist jedoch für alle Register (z.&amp;amp;nbsp;B. die des UART, ADC, SPI) analog.&lt;br /&gt;
&lt;br /&gt;
== Schreiben in Register ==&lt;br /&gt;
&lt;br /&gt;
Zum Schreiben kann man Register einfach wie eine Variable setzen.&amp;lt;ref&amp;gt;In Quellcodes, die für ältere Versionen des avr-gcc/der avr-libc entwickelt wurden, erfolgt der Schreibzugriff über die Funktion outp(). Aktuelle Versionen des Compilers unterstützen den Zugriff nun direkt, outp() ist nicht mehr erforderlich.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
    /* Setzt das Richtungsregister des Ports A auf 0xff &lt;br /&gt;
       (alle Pins als Ausgang, vgl. Abschnitt Zugriff auf Ports): */&lt;br /&gt;
    DDRA = 0xff;    &lt;br /&gt;
&lt;br /&gt;
    /* Setzt PortA auf 0x03, Bit 0 und 1 &amp;quot;high&amp;quot;, restliche &amp;quot;low&amp;quot;: */&lt;br /&gt;
    PORTA = 0x03;   &lt;br /&gt;
&lt;br /&gt;
    // Setzen der Bits 0,1,2,3 und 4&lt;br /&gt;
    // Binär 00011111 = Hexadezimal 1F&lt;br /&gt;
    DDRB = 0x1F;    /* direkte Zuweisung - unübersichtlich */&lt;br /&gt;
&lt;br /&gt;
    /* Ausführliche Schreibweise: identische Funktionalität, mehr Tipparbeit&lt;br /&gt;
       aber übersichtlicher und selbsterklärend: */&lt;br /&gt;
    DDRB = (1 &amp;lt;&amp;lt; DDB0) | (1 &amp;lt;&amp;lt; DDB1) | (1 &amp;lt;&amp;lt; DDB2) | (1 &amp;lt;&amp;lt; DDB3) | (1 &amp;lt;&amp;lt; DDB4);&lt;br /&gt;
&lt;br /&gt;
    while (1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die ausführliche Schreibweise sollte bevorzugt verwendet werden, da dadurch die Zuweisungen selbsterklärend sind und somit der Code leichter nachvollzogen werden kann. Atmel verwendet sie auch bei Beispielen in Datenblätten und in den allermeisten Quellcodes zu Application-Notes. Mehr zu der Schreibweise mit &amp;quot;|&amp;quot; und &amp;quot;&amp;lt;&amp;lt;&amp;quot; findet man unter [[Bitmanipulation]].&lt;br /&gt;
&lt;br /&gt;
Der gcc C-Compiler unterstützt ab Version 4.3.0 Konstanten im Binärformat, z.&amp;amp;nbsp;B. DDRB&amp;amp;nbsp;=&amp;amp;nbsp;0b00011111. Diese Schreibweise ist jedoch nur in GNU-C verfügbar und nicht in ISO-C definiert. Man sollte sie daher nicht verwenden, wenn Code mit anderen ausgetauscht oder mit anderen Compilern bzw. älteren Versionen des gcc genutzt werden soll.&lt;br /&gt;
&lt;br /&gt;
== Verändern von Registerinhalten ==&lt;br /&gt;
&lt;br /&gt;
Einzelne Bits setzt und löscht man &amp;quot;Standard-C-konform&amp;quot; mittels logischer (Bit-) Operationen. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
 x |= (1 &amp;lt;&amp;lt; Bitnummer);  // Hiermit wird ein Bit in x gesetzt&lt;br /&gt;
 x &amp;amp;= ~(1 &amp;lt;&amp;lt; Bitnummer); // Hiermit wird ein Bit in x geloescht&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es wird jeweils nur der Zustand des angegebenen Bits geändert, der vorherige Zustand der anderen Bits bleibt erhalten. &lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
#define MEINBIT 2&lt;br /&gt;
...&lt;br /&gt;
PORTA |= (1 &amp;lt;&amp;lt; MEINBIT);    /* setzt Bit 2 an PortA auf 1 */&lt;br /&gt;
PORTA &amp;amp;= ~(1 &amp;lt;&amp;lt; MEINBIT);   /* loescht Bit 2 an PortA */&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit dieser Methode lassen sich auch mehrere Bits eines Registers gleichzeitig setzen und löschen.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
DDRA &amp;amp;= ~( (1&amp;lt;&amp;lt;PA0) | (1&amp;lt;&amp;lt;PA3) );  /* PA0 und PA3 als Eingaenge */&lt;br /&gt;
PORTA |= (1&amp;lt;&amp;lt;PA0) | (1&amp;lt;&amp;lt;PA3);      /* Interne Pull-Up fuer beide einschalten */&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In Quellcodes, die für ältere Version den des avr-gcc/der avr-libc entwickelt wurden, werden einzelne Bits mittels der Funktionen sbi und cbi gesetzt bzw. gelöscht. Beide Funktionen sind nicht mehr erforderlich.&lt;br /&gt;
&lt;br /&gt;
Siehe auch:&lt;br /&gt;
* [[Bitmanipulation]]&lt;br /&gt;
* [http://www.nongnu.org/avr-libc/user-manual/index.html Dokumentation der avr-libc] Abschnitt Modules/Special Function Registers&lt;br /&gt;
&lt;br /&gt;
== Lesen aus Registern ==&lt;br /&gt;
&lt;br /&gt;
Zum Lesen kann man auf Register einfach wie auf eine Variable zugreifen. In Quellcodes, die für ältere Versionen des avr-gcc/der avr-libc entwickelt wurden, erfolgt der Lesezugriff über die Funktion inp(). Aktuelle Versionen des Compilers unterstützen den Zugriff nun direkt und inp() ist nicht mehr erforderlich.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
uint8_t foo;&lt;br /&gt;
&lt;br /&gt;
//...&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    /* kopiert den Status der Eingabepins an PortB &lt;br /&gt;
       in die Variable foo: */&lt;br /&gt;
    foo = PINB;    &lt;br /&gt;
    //...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Abfrage der Zustände von Bits erfolgt durch Einlesen des gesamten Registerinhalts und ausblenden der Bits deren Zustand nicht von Interesse ist. Einige Beispiele zum Prüfen ob Bits gesetzt oder gelöscht sind:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#define MEINBIT0 0 &lt;br /&gt;
#define MEINBIT2 2&lt;br /&gt;
&lt;br /&gt;
uint8_t i;&lt;br /&gt;
&lt;br /&gt;
extern test1();&lt;br /&gt;
&lt;br /&gt;
// Funkion test1 aufrufen, wenn Bit 0 in Register PINA gesetzt (1) ist&lt;br /&gt;
i = PINA;         // Inhalt in Arbeitsvariable&lt;br /&gt;
i = i &amp;amp; 0x01;     // alle Bits bis auf Bit 0 ausblenden (logisches und)&lt;br /&gt;
                  // falls das Bit gesetzt war, hat i den Inhalt 1&lt;br /&gt;
if ( i != 0 ) {   // Ergebnis ungleich 0 (wahr)? &lt;br /&gt;
  test1();         // dann muss Bit 0 in i gesetzt sein -&amp;gt; Funktion aufrufen&lt;br /&gt;
}&lt;br /&gt;
// verkürzt:&lt;br /&gt;
if ( ( PINA &amp;amp; 0x01 ) != 0 ) {&lt;br /&gt;
  test1();&lt;br /&gt;
}&lt;br /&gt;
// nochmals verkürzt:&lt;br /&gt;
if ( PINA &amp;amp; 0x01 ) {&lt;br /&gt;
  test1();&lt;br /&gt;
}&lt;br /&gt;
// mit definierter Bitnummer:&lt;br /&gt;
if ( PINA &amp;amp; ( 1 &amp;lt;&amp;lt; MEINBIT0 ) ) {&lt;br /&gt;
  test1();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Funktion aufrufen, wenn Bit 0 und/oder Bit 2 gesetzt ist. (Bit 0 und 2 also Wert 5) &lt;br /&gt;
// (Bedenke: Bit 0 hat Wert 1, Bit 1 hat Wert 2 und Bit 2 hat Wert 4)&lt;br /&gt;
if ( PINA &amp;amp; 0x05 ) {&lt;br /&gt;
  test1();  // Vergleich &amp;lt;&amp;gt; 0 (wahr), also mindestens eines der Bits gesetzt&lt;br /&gt;
}&lt;br /&gt;
// mit definierten Bitnummern:&lt;br /&gt;
if ( PINA &amp;amp; ( ( 1 &amp;lt;&amp;lt; MEINBIT0 ) | ( 1 &amp;lt;&amp;lt; MEINBIT2 ) ) ) {&lt;br /&gt;
  test1();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Funktion aufrufen, wenn Bit 0 und Bit 2 gesetzt sind&lt;br /&gt;
if ( ( PINA &amp;amp; 0x05 ) == 0x05 ) {  // nur wahr, wenn beide Bits gesetzt&lt;br /&gt;
  test1();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Funktion test2() aufrufen, wenn Bit 0 gelöscht (0) ist&lt;br /&gt;
i = PINA;        // einlesen in temporäre Variable&lt;br /&gt;
i = i &amp;amp; 0x01;    // maskieren von Bit 0&lt;br /&gt;
if ( i == 0 ) {  // Vergleich ist wahr, wenn Bit 0 nicht gesetzt ist&lt;br /&gt;
  test2();&lt;br /&gt;
}&lt;br /&gt;
// analog mit not-Operator&lt;br /&gt;
if ( !i ) {&lt;br /&gt;
  test2();&lt;br /&gt;
}&lt;br /&gt;
// nochmals verkürzt:&lt;br /&gt;
if ( !( PINA &amp;amp; 0x01 ) ) {&lt;br /&gt;
  test2();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Warten auf einen bestimmten Zustand ==&lt;br /&gt;
&lt;br /&gt;
Es gibt in der Bibliothek avr-libc Funktionen, die warten, bis ein bestimmter Zustand eines Bits erreicht ist. Es ist allerdings normalerweise eine eher unschöne Programmiertechnik, da in diesen Funktionen &amp;quot;blockierend&amp;quot; gewartet wird. Der Programmablauf bleibt also an dieser Stelle stehen, bis das maskierte Ereignis erfolgt ist. Setzt man den [[Watchdog]] ein, muss man darauf achten, dass dieser auch noch getriggert wird (Zurücksetzen des Watchdogtimers). &lt;br /&gt;
&lt;br /&gt;
Die Funktion &#039;&#039;&#039;loop_until_bit_is_set&#039;&#039;&#039; wartet in einer Schleife, bis das definierte Bit gesetzt ist. Wenn das Bit beim Aufruf der Funktion bereits gesetzt ist, wird die Funktion sofort wieder verlassen. Das niederwertigste Bit hat die Bitnummer 0. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
/* Warten bis Bit Nr. 2 (das dritte Bit) in Register PINA gesetzt (1) ist */&lt;br /&gt;
&lt;br /&gt;
#define WARTEPIN PINA&lt;br /&gt;
#define WARTEBIT PA2&lt;br /&gt;
&lt;br /&gt;
// mit der avr-libc Funktion:&lt;br /&gt;
loop_until_bit_is_set(WARTEPIN, WARTEBIT);&lt;br /&gt;
&lt;br /&gt;
// dito in &amp;quot;C-Standard&amp;quot;:&lt;br /&gt;
// Durchlaufe die (leere) Schleife solange das WARTEBIT in Register WARTEPIN&lt;br /&gt;
// _nicht_ ungleich 0 (also 0) ist.&lt;br /&gt;
while ( !(WARTEPIN &amp;amp; (1 &amp;lt;&amp;lt; WARTEBIT)) ) {}&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Die Funktion &#039;&#039;&#039;loop_until_bit_is_clear&#039;&#039;&#039; wartet in einer Schleife, bis das definierte Bit gelöscht ist. Wenn das Bit beim Aufruf der Funktion bereits gelöscht ist, wird die Funktion sofort wieder verlassen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
/* Warten bis Bit Nr. 4 (das fuenfte Bit) in Register PINB geloescht (0) ist */&lt;br /&gt;
#define WARTEPIN PINB&lt;br /&gt;
#define WARTEBIT PB4&lt;br /&gt;
&lt;br /&gt;
// avr-libc-Funktion:&lt;br /&gt;
loop_until_bit_is_clear(WARTEPIN, WARTEBIT);&lt;br /&gt;
&lt;br /&gt;
// dito in &amp;quot;C-Standard&amp;quot;:&lt;br /&gt;
// Durchlaufe die (leere) Schleife solange das WARTEBIT in Register WARTEPIN&lt;br /&gt;
// gesetzt (1) ist &lt;br /&gt;
while ( WARTEPIN &amp;amp; (1&amp;lt;&amp;lt;WARTEBIT) ) {}&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Universeller und auch auf andere Plattformen besser übertragbar ist die Verwendung von C-Standardoperationen.&lt;br /&gt;
&lt;br /&gt;
Siehe auch: &lt;br /&gt;
* [http://www.nongnu.org/avr-libc/user-manual/index.html Dokumentation der avr-libc] Abschnitt Modules/Special Function Registers&lt;br /&gt;
* [[Bitmanipulation]]&lt;br /&gt;
&lt;br /&gt;
== 16-Bit Register (ADC, ICR1, OCR1x, TCNT1, UBRR) ==&lt;br /&gt;
&lt;br /&gt;
Einige der Portregister in den AVR-Controllern sind 16 Bit breit. Im Datenblatt sind diese Register üblicherweise mit dem Suffix &amp;quot;L&amp;quot; (Low-Byte) und &amp;quot;H&amp;quot; (High-Byte) versehen. Die avr-libc definiert zusätzlich die meisten dieser Variablen die Bezeichnung ohne &amp;quot;L&amp;quot; oder &amp;quot;H&amp;quot;. Auf diese Register kann dann direkt zugegriffen werden. Die ist zum Beispiel der Fall für Register wie ADC oder TCNT1.&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
    uint16_t foo;&lt;br /&gt;
&lt;br /&gt;
    /* setzt die Wort-Variable foo auf den Wert der letzten AD-Wandlung */&lt;br /&gt;
    foo = ADC; &lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei anderen Registern, wie zum Beispiel Baudraten-Register, liegen High- und Low-Teil nicht direkt nebeneinander im SFR-Bereich, so dass ein 16-Bit Zugriff nicht möglich ist und der Zugriff zusammengebastelt werden muss:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#ifndef F_CPU&lt;br /&gt;
#define F_CPU 3686400&lt;br /&gt;
#endif&lt;br /&gt;
#define UART_BAUD_RATE 9600&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
   uint16_t baud = F_CPU / (UART_BAUD_RATE * 16L) -1;&lt;br /&gt;
&lt;br /&gt;
   UBRRH = (uint8_t) (baud &amp;gt;&amp;gt; 8);&lt;br /&gt;
   UBRRL = (uint8_t) baud;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei einigen AVR-Typen wie ATmega8 oder ATmega16 teilen sich UBRRH und UCSRC die gleiche Speicher-Adresse. Damit der AVR trotzdem zwischen den beiden Registern unterscheiden kann, bestimmt das Bit7 (URSEL), welches Register tatsächlich beschrieben werden soll. &#039;&#039;1000 0011&#039;&#039; (0x83) adressiert demnach UCSRC und übergibt den Wert &#039;&#039;3&#039;&#039; und &#039;&#039;0000 0011&#039;&#039; (0x3) adressiert UBRRH und übergibt ebenfalls den Wert &#039;&#039;3&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
Speziell bei den 16-Bit-Timern und auch beim ADC ist es bei allen Zugriffen auf Datenregister erforderlich, dass diese Daten synchronisiert sind. Wenn z.&amp;amp;nbsp;B. bei einem 16-Bit-Timer das High-Byte des Zählregisters gelesen wurde und vor dem Lesezugriff auf das Low-Byte ein Überlauf des Low-Bytes stattfindet, erhält man einen völlig unsinnigen Wert. Auch die Compare-Register müssen synchron geschrieben werden, da es ansonsten zu unerwünschten Compare-Ereignissen kommen kann. &lt;br /&gt;
&lt;br /&gt;
Beim ADC besteht das Problem darin, dass zwischen den Zugriffen auf die beiden Teilregister eine Wandlung beendet werden kann und der ADC ein neues Ergebnis in ADCL und ADCH schreiben will, wodurch High- und Low-Byte nicht zusammenpassen.&lt;br /&gt;
&lt;br /&gt;
Um diese Datenmüllproduktion zu verhindern, gibt es in beiden Fällen eine Synchronisation, die jeweils durch den Zugriff auf das Low-Byte ausgelöst wird:&lt;br /&gt;
* Bei den Timer-Registern (das gilt für alle TCNT-, OCR- und ICR-Register bei den 16-Bit-Timern) wird bei einem &#039;&#039;Lesezugriff&#039;&#039; auf das Low-Byte automatisch das High-Byte in ein temporäres Register, das ansonsten nach außen nicht sichtbar ist, geschoben. Greift man nun &#039;&#039;anschließend&#039;&#039; auf das High-Byte zu, dann wird eben dieses temporäre Register gelesen.&lt;br /&gt;
* Bei einem &#039;&#039;Schreibzugriff&#039;&#039; auf eines der genannten Register wird das High-Byte in besagtem temporären Register zwischengespeichert und erst beim Schreiben des Low-Bytes werden &#039;&#039;beide&#039;&#039; gleichzeitig in das eigentliche Register übernommen.&lt;br /&gt;
&lt;br /&gt;
Das bedeutet für die Reihenfolge:&lt;br /&gt;
* Lesezugriff: Erst Low-Byte, dann High-Byte&lt;br /&gt;
* Schreibzugriff: Erst High-Byte, dann Low-Byte&lt;br /&gt;
&lt;br /&gt;
Des weiteren ist zu beachten, dass es für all diese 16-Bit-Register nur ein einziges temporäres Register gibt, so dass das Auftreten eines Interrupts, in dessen Handler ein solches Register manipuliert wird, bei einem durch ihn unterbrochenen Zugriff i.d.R. zu Datenmüll führt. 16-Bit-Zugriffe sind generell nicht atomar! Wenn mit Interrupts gearbeitet wird, kann es erforderlich sein, vor einem solchen Zugriff auf ein 16-Bit-Register die Interrupt-Bearbeitung zu deaktivieren.&lt;br /&gt;
&lt;br /&gt;
Beim ADC-Datenregister ADCH/ADCL ist die Synchronisierung anders gelöst. Hier wird beim Lesezugriff (ADCH/ADCL sind logischerweise read-only) auf das Low-Byte ADCL beide Teilregister für Zugriffe seitens des ADC so lange gesperrt, bis das High-Byte ADCH ausgelesen wurde. Dadurch kann der ADC nach einem Zugriff auf ADCL keinen neuen Wert in ADCH/ADCL ablegen, bis ADCH gelesen wurde. Ergebnisse von Wandlungen, die zwischen einem Zugriff auf ADCL und ADCH beendet werden, gehen verloren!&lt;br /&gt;
&lt;br /&gt;
Nach einem Zugriff auf ADCL muss grundsätzlich ADCH gelesen werden!&lt;br /&gt;
&lt;br /&gt;
In beiden Fällen – also sowohl bei den Timern als auch beim ADC – werden vom C-Compiler 16-Bit Pseudo-Register zur Verfügung gestellt (z.&amp;amp;nbsp;B. TCNT1H/TCNT1L → TCNT1, ADCH/ADCL → ADC bzw. ADCW), bei deren Verwendung der Compiler automatisch die richtige Zugriffsreihenfolge regelt. In C-Programmen sollten grundsätzlich diese 16-Bit-Register verwendet werden! Sollte trotzdem ein Zugriff auf ein Teilregister erforderlich sein, sind obige Angaben zu berücksichtigen.&lt;br /&gt;
&lt;br /&gt;
Es ist darauf zu achten, dass auch ein Zugriff auf die 16-Bit-Register vom Compiler in zwei 8-Bit-Zugriffe aufgeteilt wird und dementsprechend genauso nicht-atomar ist wie die Einzelzugriffe. Auch hier gilt, dass u.U. die Interrupt-Bearbeitung gesperrt werden muss, um Datenmüll zu vermeiden.&lt;br /&gt;
&lt;br /&gt;
Beim ADC gibt es für den Fall, dass eine Auflösung von 8 Bit ausreicht, die Möglichkeit, das Ergebnis &amp;quot;linksbündig&amp;quot; in ADCH/ADCL auszurichten, so dass die relevanten 8 MSB in ADCH stehen. In diesem Fall muss bzw. sollte nur ADCH ausgelesen werden.&lt;br /&gt;
&lt;br /&gt;
ADC und ADCW sind unterschiedliche Bezeichner für das selbe Registerpaar. Üblicherweise kann man in C-Programmen ADC verwenden, was analog zu den anderen 16-Bit-Registern benannt ist. ADCW (ADC Word) existiert nur deshalb, weil die Headerdateien auch für Assembler vorgesehen sind und es bereits einen Assembler-Befehl namens &#039;&#039;adc&#039;&#039; gibt. &lt;br /&gt;
&lt;br /&gt;
Im Umgang mit 16-Bit Registern siehe auch:&lt;br /&gt;
* [http://www.nongnu.org/avr-libc/user-manual/index.html Dokumentation der avr-libc] Abschnitt Related Pages/Frequently Asked Questions/Nr. 8&lt;br /&gt;
* Datenblatt Abschnitt &#039;&#039;Accessing 16-bit Registers&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== IO-Register als Parameter und Variablen ==&lt;br /&gt;
&lt;br /&gt;
Um Register als Parameter für eigene Funktionen übergeben zu können, muss man sie als einen volatile uint8_t Pointer übergeben. Zum Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;util/delay.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
uint8_t key_pressed (volatile uint8_t *inputreg, uint8_t inputbit)&lt;br /&gt;
{&lt;br /&gt;
  static uint8_t last_state = 0;&lt;br /&gt;
 &lt;br /&gt;
  if (last_state == (*inputreg &amp;amp; (1&amp;lt;&amp;lt;inputbit)))&lt;br /&gt;
     return 0; /* keine Änderung */&lt;br /&gt;
 &lt;br /&gt;
  /* Wenn doch, warten bis etwaiges Prellen vorbei ist: */&lt;br /&gt;
  _delay_ms(20);&lt;br /&gt;
&lt;br /&gt;
  /* Zustand für nächsten Aufruf merken: */&lt;br /&gt;
  last_state = *inputreg &amp;amp; (1&amp;lt;&amp;lt;inputbit);&lt;br /&gt;
 &lt;br /&gt;
  /* und den entprellten Tastendruck zurückgeben: */&lt;br /&gt;
  return *inputreg &amp;amp; (1&amp;lt;&amp;lt;inputbit);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Beispiel für einen Funktionsaufruf: */&lt;br /&gt;
&lt;br /&gt;
void foo (void)&lt;br /&gt;
{&lt;br /&gt;
   uint8_t i = key_pressed (&amp;amp;PINB, PB1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein Aufruf der Funktion mit call by value würde Folgendes bewirken: Beim Funktionseintritt wird nur eine Kopie des momentanen Portzustandes angefertigt, die sich unabhängig vom tatsächlichen Zustand das Ports nicht mehr ändert, womit die Funktion wirkungslos wäre. Die Übergabe eines Zeigers wäre die Lösung, wenn der Compiler nicht optimieren würde. Denn dadurch wird im Programm nicht von der Hardware gelesen, sondern wieder nur von einem Abbild im Speicher. Das Ergebnis wäre das gleiche wie oben. Mit dem Schlüsselwort volatile sagt man nun dem Compiler, dass die entsprechende Variable entweder durch andere Softwareroutinen (Interrupts) oder durch die Hardware verändert werden kann.&lt;br /&gt;
&lt;br /&gt;
= Zugriff auf IO-Ports =&lt;br /&gt;
&lt;br /&gt;
Jeder AVR implementiert eine unterschiedliche Menge an GPIO-Registern&lt;br /&gt;
(GPIO - General Purpose Input/Output). Diese Register dienen dazu:&lt;br /&gt;
* einzustellen welche der Anschlüsse (&amp;quot;Beinchen&amp;quot;) des Controllers als Ein- oder Ausgänge dienen&lt;br /&gt;
* bei Ausgängen deren Zustand festzulegen&lt;br /&gt;
* bei Eingängen deren Zustand zu erfassen&lt;br /&gt;
&lt;br /&gt;
Mittels GPIO werden digitale Zustände gesetzt und erfasst, d.h. die Spannung an einem Ausgang wird ein- oder ausgeschaltet und an einem Eingang wird erfasst, ob die anliegende Spannung über oder unter einem bestimmten Schwellwert liegt. Im Datenblatt Abschnitt Electrical Characteristics/DC Characteristics finden sich die Spannungswerte (V_OL, V_OH für Ausgänge, V_IL, V_IH für Eingänge).&lt;br /&gt;
&lt;br /&gt;
Die Verarbeitung von analogen Eingangswerten und die Ausgabe von Analogwerten wird in Kapitel [[AVR-GCC-Tutorial#Analoge_Ein-_und_Ausgabe|Analoge Ein- und Ausgabe]] behandelt.&lt;br /&gt;
&lt;br /&gt;
Alle Ports der AVR-Controller werden über Register gesteuert. Dazu sind jedem Port 3 Register zugeordnet:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! DDRx&lt;br /&gt;
| Datenrichtungsregister für Port&#039;&#039;&#039;x&#039;&#039;&#039;. &lt;br /&gt;
&#039;&#039;&#039;x&#039;&#039;&#039; entspricht &#039;&#039;&#039;A&#039;&#039;&#039;, &#039;&#039;&#039;B&#039;&#039;&#039;, &#039;&#039;&#039; C&#039;&#039;&#039;, &#039;&#039;&#039;D&#039;&#039;&#039; usw. (abhängig von der Anzahl der Ports des verwendeten AVR). Bit im Register gesetzt (1) für Ausgang, Bit gelöscht (0) für Eingang.&lt;br /&gt;
|- &lt;br /&gt;
! PINx&lt;br /&gt;
| Eingangsadresse für Port&#039;&#039;&#039;x&#039;&#039;&#039;. &lt;br /&gt;
Zustand des Ports. Die Bits in PINx entsprechen dem Zustand der als Eingang definierten Portpins. Bit 1 wenn Pin &amp;quot;high&amp;quot;, Bit 0 wenn Portpin low.&lt;br /&gt;
|-&lt;br /&gt;
! PORTx&lt;br /&gt;
| Datenregister für Port&#039;&#039;&#039;x&#039;&#039;&#039;. &lt;br /&gt;
Dieses Register wird verwendet, um die Ausgänge eines Ports anzusteuern. Bei Pins, die mittels DDRx auf Eingang geschaltet wurden, können über PORTx&lt;br /&gt;
die internen Pull-Up Widerstände aktiviert oder deaktiviert werden (1 = aktiv).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Beispiele gehen von einem AVR aus, der sowohl Port A als auch Port B besitzt. Sie müssen für andere AVRs (zum Beispiel ATmega8/48/88/168) entsprechend angepasst werden.&lt;br /&gt;
&lt;br /&gt;
== Datenrichtung bestimmen ==&lt;br /&gt;
&lt;br /&gt;
Zuerst muss die Datenrichtung der verwendeten Pins bestimmt werden. Um dies zu erreichen, wird das Datenrichtungsregister des entsprechenden Ports beschrieben.&lt;br /&gt;
&lt;br /&gt;
Für jeden Pin, der als Ausgang verwendet werden soll, muss dabei das&lt;br /&gt;
entsprechende Bit auf dem Port gesetzt werden. Soll der Pin als Eingang&lt;br /&gt;
verwendet werden, muss das entsprechende Bit gelöscht sein.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
Angenommen am Port B sollen die Pins 0 bis 4 als Ausgänge definiert werden, die noch verbleibenden Pins 5 bis 7 sollen als Eingänge fungieren. Dazu ist es daher notwendig, im für das Port B zuständigen Datenrichtungsregister DDRB folgende Bitkonfiguration einzutragen&lt;br /&gt;
&lt;br /&gt;
   +---+---+---+---+---+---+---+---+&lt;br /&gt;
   | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 |&lt;br /&gt;
   +---+---+---+---+---+---+---+---+&lt;br /&gt;
     7   6   5   4   3   2   1   0&lt;br /&gt;
&lt;br /&gt;
In C liest sich das dann so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
// in io.h wird u.a. DDRB definiert:&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  // Setzen der Bits 0,1,2,3 und 4&lt;br /&gt;
  // Binär 00011111 = Hexadezimal 1F&lt;br /&gt;
  // direkte Zuweisung - standardkonform */&lt;br /&gt;
  DDRB = 0x1F;    /* &lt;br /&gt;
&lt;br /&gt;
  // übersichtliche Alternative - Binärschreibweise, aber kein ISO-C&lt;br /&gt;
  DDRB = 0b00011111;&lt;br /&gt;
&lt;br /&gt;
  // Ausführliche Schreibweise: identische Funktionalität, mehr Tipparbeit&lt;br /&gt;
  // aber übersichtlicher und selbsterklärend:&lt;br /&gt;
  DDRB = (1 &amp;lt;&amp;lt; DDB0) | (1 &amp;lt;&amp;lt; DDB1) | (1 &amp;lt;&amp;lt; DDB2) | (1 &amp;lt;&amp;lt; DDB3) | (1 &amp;lt;&amp;lt; DDB4); &lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Pins 5 bis 7 werden (da 0) als Eingänge geschaltet. Weitere Beispiele:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
  // Alle Pins des Ports B als Ausgang definieren:&lt;br /&gt;
  DDRB = 0xff; &lt;br /&gt;
  // Pin0 wieder auf Eingang und andere im ursprünglichen Zustand belassen:&lt;br /&gt;
  DDRB &amp;amp;= ~(1 &amp;lt;&amp;lt; DDB0);&lt;br /&gt;
  // Pin 3 und 4 auf Eingang und andere im ursprünglichen Zustand belassen:&lt;br /&gt;
  DDRB &amp;amp;= ~((1 &amp;lt;&amp;lt; DDB3) | (1 &amp;lt;&amp;lt; DDB4));&lt;br /&gt;
  // Pin 0 und 3 wieder auf Ausgang und andere im ursprünglichen Zustand belassen:&lt;br /&gt;
  DDRB |= (1 &amp;lt;&amp;lt; DDB0) | (1 &amp;lt;&amp;lt; DDB3);&lt;br /&gt;
  // Alle Pins auf Eingang:&lt;br /&gt;
  DDRB = 0x00;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Vordefinierte Bitnummern für I/O-Register ==&lt;br /&gt;
&lt;br /&gt;
Die Bitnummern (z.&amp;amp;nbsp;B. PCx, PINCx und DDCx für den Port C) sind in den io*.h-Dateien der avr-libc definiert und dienen lediglich der besseren Lesbarkeit. Man muss diese Definitionen nicht verwenden oder kann auch einfach &amp;quot;immer&amp;quot; PAx, PBx, PCx usw. nutzen, auch wenn der Zugriff auf Bits in DDRx- oder PINx-Registern erfolgt. Für den Compiler sind die Ausdrücke (1&amp;lt;&amp;lt;PC7), (1&amp;lt;&amp;lt;DDC7) und (1&amp;lt;&amp;lt;PINC7) identisch zu (1&amp;lt;&amp;lt;7) (genauer: der Präprozessor ersetzt die Ausdrücke (1&amp;lt;&amp;lt;PC7),... zu (1&amp;lt;&amp;lt;7)). Ein Ausschnitt der Definitionen für Port C eines ATmega32 aus der iom32.h-Datei zur Verdeutlichung (analog für die weiteren Ports):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
/* PORTC */&lt;br /&gt;
#define PC7     7&lt;br /&gt;
#define PC6     6&lt;br /&gt;
#define PC5     5&lt;br /&gt;
#define PC4     4&lt;br /&gt;
#define PC3     3&lt;br /&gt;
#define PC2     2&lt;br /&gt;
#define PC1     1&lt;br /&gt;
#define PC0     0&lt;br /&gt;
&lt;br /&gt;
/* DDRC */&lt;br /&gt;
#define DDC7    7&lt;br /&gt;
#define DDC6    6&lt;br /&gt;
#define DDC5    5&lt;br /&gt;
#define DDC4    4&lt;br /&gt;
#define DDC3    3&lt;br /&gt;
#define DDC2    2&lt;br /&gt;
#define DDC1    1&lt;br /&gt;
#define DDC0    0&lt;br /&gt;
&lt;br /&gt;
/* PINC */&lt;br /&gt;
#define PINC7   7&lt;br /&gt;
#define PINC6   6&lt;br /&gt;
#define PINC5   5&lt;br /&gt;
#define PINC4   4&lt;br /&gt;
#define PINC3   3&lt;br /&gt;
#define PINC2   2&lt;br /&gt;
#define PINC1   1&lt;br /&gt;
#define PINC0   0&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Digitale Signale ==&lt;br /&gt;
&lt;br /&gt;
Am einfachsten ist es, digitale Signale mit dem Mikrocontroller zu erfassen bzw. auszugeben.&lt;br /&gt;
&lt;br /&gt;
== Ausgänge ==&lt;br /&gt;
Will man als Ausgang definierte Pins (entsprechende DDRx-Bits = 1) auf Logisch 1 setzen, setzt man die  entsprechenden Bits im Portregister.&lt;br /&gt;
&lt;br /&gt;
Mit dem Befehl&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
    PORTB = 0x04; /* besser PORTB=(1&amp;lt;&amp;lt;PB2) */&lt;br /&gt;
&lt;br /&gt;
    // übersichtliche Alternative - Binärschreibweise&lt;br /&gt;
    PORTB = 0b00000100;    /* direkte Zuweisung - übersichtlich */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
wird also der Ausgang an Pin PB2 gesetzt (Beachte, dass die Bits immer &#039;&#039;von 0 an&#039;&#039; gezählt werden, das niederwertigste Bit ist also Bitnummer 0 und nicht etwa Bitnummer 1).&lt;br /&gt;
&lt;br /&gt;
Man beachte, dass bei der Zuweisung mittels &#039;&#039;&#039;=&#039;&#039;&#039; immer alle Pins gleichzeitig angegeben werden. Man sollte also, wenn nur bestimmte Ausgänge geschaltet werden sollen, zuerst den aktuellen Wert des Ports einlesen und das Bit des gewünschten Ports in diesen Wert einfließen lassen. Will man also nur den dritten Pin (Bit Nr. 2) an Port B auf &amp;quot;high&amp;quot; setzen und den Status der anderen Ausgänge unverändert lassen, nutze man diese Form:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
    PORTB = PORTB | 0x04; /* besser: PORTB = PORTB | ( 1&amp;lt;&amp;lt;PB2 ) */&lt;br /&gt;
    /* vereinfacht durch Nutzung des |= Operators : */&lt;br /&gt;
    PORTB |= (1&amp;lt;&amp;lt;PB2);&lt;br /&gt;
&lt;br /&gt;
    /* auch mehrere &amp;quot;gleichzeitig&amp;quot;: */&lt;br /&gt;
    PORTB |= (1&amp;lt;&amp;lt;PB4) | (1&amp;lt;&amp;lt;PB5); /* Pins PB4 und PB5 &amp;quot;high&amp;quot; */&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Ausschalten&amp;quot;, also  Ausgänge auf &amp;quot;low&amp;quot; setzen, erfolgt analog:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
    PORTB &amp;amp;= ~(1&amp;lt;&amp;lt;PB2); /* löscht Bit 2 in PORTB und setzt damit Pin PB2 auf low */ &lt;br /&gt;
    PORTB &amp;amp;= ~( (1&amp;lt;&amp;lt;PB4) | (1&amp;lt;&amp;lt;PB5) ); /* Pin PB4 und Pin PB5 &amp;quot;low&amp;quot; */&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
Siehe auch [[Bitmanipulation]]&lt;br /&gt;
&lt;br /&gt;
In Quellcodes, die für ältere Version den des avr-gcc/der avr-libc entwickelt wurden, werden einzelne Bits mittels der Funktionen sbi und cbi gesetzt bzw. gelöscht. Beide Funktionen sind in aktuellen Versionen der avr-libc nicht mehr enthalten und auch nicht mehr erforderlich.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Falls der Anfangszustand von Ausgängen kritisch ist, muss die Reihenfolge beachtet werden, mit der die Datenrichtung (DDRx) eingestellt und der Ausgabewert (PORTx) gesetzt wird:&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Für Ausgangspins, die mit Anfangswert &amp;quot;high&amp;quot; initialisiert werden sollen:&lt;br /&gt;
* zuerst die Bits im PORTx-Register setzen&lt;br /&gt;
* anschließend die Datenrichtung auf Ausgang stellen&lt;br /&gt;
&lt;br /&gt;
Daraus ergibt sich die Abfolge für einen Pin, der bisher als Eingang mit abgeschaltetem Pull-Up konfiguriert war:&lt;br /&gt;
* setze PORTx: interner Pull-Up aktiv&lt;br /&gt;
* setze DDRx: Ausgang (&amp;quot;high&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Bei der Reihenfolge erst DDRx und dann PORTx kann es zu einem kurzen &amp;quot;low-Puls&amp;quot; kommen, der auch externe Pull-Up-Widerstände &amp;quot;überstimmt&amp;quot;. Die (ungünstige) Abfolge: Eingang -&amp;gt; setze DDRx: Ausgang (auf &amp;quot;low&amp;quot;, da PORTx nach Reset 0) -&amp;gt; setze PORTx: Ausgang auf high. Vergleiche dazu auch das Datenblatt Abschnitt &#039;&#039;Configuring the Pin&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Eingänge (Wie kommen Signale in den &amp;amp;micro;C) ==&lt;br /&gt;
&lt;br /&gt;
Die digitalen Eingangssignale können auf verschiedene Arten zu unserer Logik gelangen.&lt;br /&gt;
&lt;br /&gt;
=== Signalkopplung ===&lt;br /&gt;
&lt;br /&gt;
Am einfachsten ist es, wenn die Signale direkt aus einer anderen digitalen Schaltung übernommen werden können. Hat der Ausgang der entsprechenden Schaltung TTL-Pegel dann können wir sogar direkt den Ausgang der Schaltung mit einem Eingangspin von unserem Controller verbinden.&lt;br /&gt;
&lt;br /&gt;
Hat der Ausgang der anderen Schaltung keinen TTL-Pegel so müssen wir den Pegel über entsprechende Hardware (z.&amp;amp;nbsp;B. Optokoppler, [[Widerstand#Spannungsteiler|Spannungsteiler]], &amp;quot;Levelshifter&amp;quot; aka [[Pegelwandler]]) anpassen.&lt;br /&gt;
&lt;br /&gt;
Die Masse der beiden Schaltungen muss selbstverständlich miteinander verbunden werden. Der Software selber ist es natürlich letztendlich egal, wie das Signal eingespeist wird. Wir können ja ohnehin lediglich prüfen, ob an einem Pin unseres Controllers eine logische 1 (Spannung größer ca. 0,7*Vcc) oder eine logische 0 (Spannung kleiner ca. 0,2*Vcc) anliegt. Detaillierte Informationen darüber, ab welcher Spannung ein Eingang als 0 (&amp;quot;low&amp;quot;) bzw. 1 (&amp;quot;high&amp;quot;) erkannt wird, liefert die Tabelle DC Characteristics im Datenblatt des genutzten Controllers.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Spannungstabelle&#039;&#039;&#039; &amp;lt;br /&amp;gt; &amp;lt;small&amp;gt;(ca. Grenzwerte)&amp;lt;/small&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
! Low || High&lt;br /&gt;
|-&lt;br /&gt;
! bei 5 V&lt;br /&gt;
| 1 V || 3,5 V&lt;br /&gt;
|-&lt;br /&gt;
! bei 3,3 V&lt;br /&gt;
| 0,66 V || 2,31 V&lt;br /&gt;
|-&lt;br /&gt;
! bei 1,8 V&lt;br /&gt;
| 0,36 V || 1,26 V&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Die Abfrage der Zustände der Portpins erfolgt direkt über den Registernamen.&lt;br /&gt;
&lt;br /&gt;
{{Warnung|Dabei ist wichtig, zur Abfrage der Eingänge &#039;&#039;nicht&#039;&#039; etwa Portregister &#039;&#039;&#039;PORTx&#039;&#039;&#039; zu verwenden, sondern Eingangsregister &#039;&#039;&#039;PINx&#039;&#039;&#039;. Ansonsten liest man nicht den Zustand der Eingänge, sondern den Status der internen Pull-Up-Widerstände. Die Abfrage der Pinzustände über PORTx statt PINx ist ein häufiger Fehler beim AVR-&amp;quot;Erstkontakt&amp;quot;.}}&lt;br /&gt;
&lt;br /&gt;
Will man also die aktuellen Signalzustände von Port D abfragen und in eine Variable namens bPortD abspeichern, schreibt man folgende Befehlszeilen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
uint8_t bPortD;&lt;br /&gt;
...&lt;br /&gt;
bPortD = PIND;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit den C-Bitoperationen kann man den Status der Bits abfragen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
/* Fuehre Aktion aus, wenn Bit Nr. 1 (das &amp;quot;zweite&amp;quot; Bit) in PINC gesetzt (1) ist */&lt;br /&gt;
if ( PINC &amp;amp; (1&amp;lt;&amp;lt;PINC1) ) {&lt;br /&gt;
  /* Aktion */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Fuehre Aktion aus, wenn Bit Nr. 2 (das &amp;quot;dritte&amp;quot; Bit) in PINB geloescht (0) ist */&lt;br /&gt;
if ( !(PINB &amp;amp; (1&amp;lt;&amp;lt;PINB2)) ) {&lt;br /&gt;
  /* Aktion */&lt;br /&gt;
}&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
Siehe auch [[Bitmanipulation#Bits_prüfen]]&lt;br /&gt;
&lt;br /&gt;
=== Interne Pull-Up Widerstände ===&lt;br /&gt;
&lt;br /&gt;
Portpins für Ein- und Ausgänge (GPIO) eines AVR verfügen über zuschaltbare interne Pull-Up Widerstände (nominal mehrere 10kOhm, z.&amp;amp;nbsp;B. ATmega16 20-50kOhm). Diese können in vielen Fällen statt externer Widerstände genutzt werden.&lt;br /&gt;
&lt;br /&gt;
Die internen Pull-Up Widerstände von Vcc zu den einzelnen Portpins werden über das Register &#039;&#039;&#039; PORTx&#039;&#039;&#039; aktiviert bzw. deaktiviert, wenn ein Pin als &#039;&#039;&#039; Eingang&#039;&#039;&#039; geschaltet ist.&lt;br /&gt;
&lt;br /&gt;
Wird der Wert des entsprechenden Portpins auf 1 gesetzt, so ist der Pull-Up Widerstand aktiviert. Bei einem Wert von 0 ist der Pull-Up Widerstand nicht aktiv. Man sollte jeweils entweder den internen oder einen externen Pull-Up Widerstand verwenden, aber nicht beide zusammen.&lt;br /&gt;
&lt;br /&gt;
Im Beispiel werden alle Pins des Ports D als Eingänge geschaltet und alle Pull-Up Widerstände aktiviert. Weiterhin wird Pin PC7 als Eingang geschaltet und dessen interner Pull-Up Widerstand aktiviert, ohne die Einstellungen für die anderen Portpins (PC0-PC6) zu verändern.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
DDRD  = 0x00; /* alle Pins von Port D als Eingang */&lt;br /&gt;
PORTD = 0xff; /* interne Pull-Ups an allen Port-Pins aktivieren */&lt;br /&gt;
...&lt;br /&gt;
DDRC  &amp;amp;= ~(1&amp;lt;&amp;lt;PC7);  /* Pin PC7 als Eingang */&lt;br /&gt;
PORTC |= (1&amp;lt;&amp;lt;PC7);    /* internen Pull-Up an PC7 aktivieren */&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tasten und Schalter ===&lt;br /&gt;
&lt;br /&gt;
Der Anschluss mechanischer Kontakte an den Mikrocontroller, ist zwischen zwei unterschiedliche Methoden zu unterscheiden: &#039;&#039;Active Low&#039;&#039; und &#039;&#039;Active High&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery widths=&amp;quot;300&amp;quot; heights=&amp;quot;300&amp;quot; caption=&amp;quot;Anschluss mechanischer Kontakte an einen µC&amp;quot;&amp;gt;&lt;br /&gt;
Image:Active Low.gif|&#039;&#039;&#039;Active Low:&#039;&#039;&#039; Bei dieser Methode wird der Kontakt zwischen den Eingangspin des Controllers und Masse geschaltet. Damit bei offenem Schalter der Controller kein undefiniertes Signal bekommt, wird zwischen die Versorgungsspannung und den Eingangspin ein sogenannter &#039;&#039;&#039;Pull-Up&#039;&#039;&#039; Widerstand geschaltet. Dieser dient dazu, den Pegel bei geöffnetem Schalter auf logisch 1 zu ziehen.&lt;br /&gt;
Image:Active High.gif|&#039;&#039;&#039;Active High:&#039;&#039;&#039; Hier wird der Kontakt zwischen die Versorgungsspannung und den Eingangspin geschaltet. Damit bei offener Schalterstellung kein undefiniertes Signal am Controller ansteht, wird zwischen den Eingangspin und die Masse ein &#039;&#039;&#039;Pull-Down&#039;&#039;&#039; Widerstand geschaltet. Dieser dient dazu, den Pegel bei geöffneter Schalterstellung auf logisch 0 zu halten. &lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Widerstandswert von Pull-Up- und Pull-Down-Widerständen ist an sich nicht kritisch. Wird er allerdings zu hoch gewählt, ist die Wirkung eventuell nicht gegeben. Als üblicher Wert haben sich 10 kOhm eingebürgert. Die AVRs verfügen an den meisten Pins über zuschaltbare interne Pull-Up Widerstände (vgl. Abschnitt [[AVR-GCC-Tutorial#Interne Pull-Up Widerstände|Interne Pull-Up Widerstände]]), welche insbesondere wie hier bei Tastern und ähnlichen Bauteilen (z.&amp;amp;nbsp;B. Drehgebern) statt externer Bauteile verwendet werden können. Interne Pull-Down-Widerstand sind nicht verfügbar und müssen daher in Form zusätzlicher Bauteile in die Schaltung eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
==== (Tasten-)Entprellung ====&lt;br /&gt;
&lt;br /&gt;
Siehe: &#039;&#039;[[Entprellung#Warteschleifen-Verfahren|Entprellung: Warteschleifen-Verfahren]]&lt;br /&gt;
&lt;br /&gt;
= Analoge Ein- und Ausgabe =&lt;br /&gt;
&lt;br /&gt;
Analoge Eingangswerte werden in der Regel über den AVR Analog-Digital-Converter (AD-Wandler, ADC) eingelesen, der in vielen Typen verfügbar ist (typisch 10bit Auflösung). Durch diesen werden analoge Signale (Spannungen) in digitale Zahlenwerte gewandelt. Bei AVRs, die über keinen internen AD-Wandler verfügen (z.&amp;amp;nbsp;B. ATmega162), kann durch externe Beschaltung (R/C-Netzwerk und &amp;quot;Zeitmessung&amp;quot;) die Funktion des AD-Wandlers &amp;quot;emuliert&amp;quot; werden.&lt;br /&gt;
&lt;br /&gt;
Es gibt innerhalb der ATMega- und ATTiny-AVR Reihe keine Typen mit eingebautem Digital-Analog-Konverter (DAC) - diese Funktion ist erst ab der XMEGA-Reihe der AVR-Familie verfügbar, die aber wegen ihrer vielen Unterschiede im Umfang dieses Tutorials nicht behandelt wird.&lt;br /&gt;
Die Umsetzung zu einer analogen Spannung muss daher durch externe Komponenten vorgenommen werden. Das kann z.&amp;amp;nbsp;B. durch PWM und deren Filterung zu (fast) DC, oder einem sogenannten R2R-Netzwerk erfolgen.&lt;br /&gt;
&lt;br /&gt;
Unabhängig davon besteht natürlich immer die Möglichkeit, spezielle Bausteine zur Analog-Digital- bzw. Digital-Analog-Wandlung zu nutzen und diese über eine digitale Schnittstelle (z.b. SPI oder I2C) mit einem AVR anzusteuern.&lt;br /&gt;
&lt;br /&gt;
== AC (Analog Comparator) ==&lt;br /&gt;
&lt;br /&gt;
Der Comparator vergleicht 2 Spannungen an den Pins AIN0 und AIN1 und gibt einen Status aus welche der beiden Spannungen größer ist. AIN0 Dient dabei als Referenzspannung (Sollwert) und AIN1 als Vergleichsspannung (Istwert). Als Referenzspannung kann auch alternativ eine interne Referenzspannung ausgewählt werden.&lt;br /&gt;
&lt;br /&gt;
Liegt die Vergleichsspannung (IST) unter der der Referenzspannung (SOLL) gibt der Comparator eine logische 1 aus. Ist die Vergleichsspannung hingegen größer als die Referenzspannung wird eine logische 0 ausgegeben.&lt;br /&gt;
&lt;br /&gt;
Der Comparator arbeitet völlig autark bzw. parallel zum Prozessor. Für mobile Anwendungen empfiehlt es sich ihn abzuschalten sofern er nicht benötigt wird, da er ansonsten Strom benötigt. Der Comparator kann interruptgesteuert abgefragt werden oder im Pollingbetrieb.&lt;br /&gt;
&lt;br /&gt;
Das Steuer- bzw. Statusregister ist wie folgt aufgebaut:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;ACSR - Analog Comparator Status Register&#039;&#039;&#039;&lt;br /&gt;
|- &lt;br /&gt;
! Bit&lt;br /&gt;
| 7|| 6|| 5|| 4|| 3|| 2|| 1|| 0&lt;br /&gt;
|- &lt;br /&gt;
! Name&lt;br /&gt;
| &#039;&#039;&#039;ACD&#039;&#039;&#039;|| &#039;&#039;&#039;ACBG&#039;&#039;&#039;|| &#039;&#039;&#039;ACO&#039;&#039;&#039;|| &#039;&#039;&#039;ACI&#039;&#039;&#039;|| &#039;&#039;&#039;ACIE&#039;&#039;&#039;|| &#039;&#039;&#039;ACIC&#039;&#039;&#039;|| &#039;&#039;&#039;ACIS1&#039;&#039;&#039;|| &#039;&#039;&#039;ACIS0&#039;&#039;&#039;&lt;br /&gt;
|- &lt;br /&gt;
! R/W&lt;br /&gt;
| R/W|| R/W|| R|| R/W|| R/W|| R/W|| R/W|| R/W&lt;br /&gt;
|- &lt;br /&gt;
! Initialwert&lt;br /&gt;
| 0|| 0|| n/a|| 0|| 0|| 0|| 0|| 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
;Bit 7 ACD: Analog Comparator Disable: 0 = Comparator ein, 1 = Comparator aus. Wird dieses Bit geändert kann ein Interrupt ausgelöst werden. Soll dies vermieden werden muss das Bit 3 ACIE ggf. abgeschaltet werden.&lt;br /&gt;
&lt;br /&gt;
;Bit 6 ACBG: Analog Comparator Bandgap Select: Ermöglicht das umschalten zwischen interner und externer Referenzspannung. 1 = interne (~1,3 Volt), 0 = externe Referenzspannung (an Pin AIN0)&lt;br /&gt;
&lt;br /&gt;
;Bit 5 ACO: Analog Comparator Output: Hier wird das Ergebnis des Vergleichs angezeigt. Es liegt typischerweise nach 1-2 Taktzyklen vor.&lt;br /&gt;
:: IST &amp;lt; SOLL &amp;amp;rarr; 1&lt;br /&gt;
:: IST &amp;gt; SOLL &amp;amp;rarr; 0&lt;br /&gt;
&lt;br /&gt;
;Bit 4 ACI: Analog Comparator Interrupt Flag: Dieses Bit wird von der Hardware gesetzt, wenn ein Interruptereignis, das in Bit 0 und 1 definiert ist, eintritt. Dieses Bit löst noch keinen Interrupt aus! Die Interruptroutine wird nur dann ausgeführt, wenn das Bit 3 ACIE gesetzt ist und global Interrupts erlaubt sind (I-Bit in SREG gesetzt). Das Bit 4 ACI wird wieder gelöscht, wenn die Interruptroutine ausgeführt wurde oder wenn es manuell auf 1! gesetzt wird. Das Bit kann für Abfragen genutzt werden, steuert oder konfiguriert aber nicht den Comparator.&lt;br /&gt;
&lt;br /&gt;
;Bit 3 ACIE: Analog Comparator Interrupt Enable: Ist das Bit auf 1 gesetzt, wird immer ein Interrupt ausgelöst, wenn das Ereignis das in Bit 1 und 0 definiert ist, eintritt.&lt;br /&gt;
&lt;br /&gt;
;Bit 2 ACIC: Analog Comparator Input Capture Enable: Wird das Bit gesetzt, wird der Comparatorausgang intern mit dem Counter 1 verbunden. Es könnten damit z.b. die Anzahl der Vergleiche im Counter1 gezählt werden. Um den Comparator an den Timer1 Input Capture Interrupt zu verbinden, muss im Timerregister das TICIE1 Bit auf 1 gesetzt werden. Der Trigger wird immer dann ausgelöst, wenn das in Bit 1 und 0 definierte Ereignis eintritt.&lt;br /&gt;
&lt;br /&gt;
;Bit 1,0 ACIS1,ACIS0: Analog Comparator Interrupt select: Hier wird definiert, welche Ereignisse einen Interrupt auslösen sollen:&lt;br /&gt;
:* 00 = Interrupt auslösen bei jedem Flankenwechsel&lt;br /&gt;
:* 10 = Interrupt auslösen bei fallender Flanke&lt;br /&gt;
:* 11 = Interrupt auslösen bei steigender Flanke&lt;br /&gt;
&lt;br /&gt;
Werden diese Bit geändert, kann ein Interrupt ausgelöst werden. Soll dies vermieden werden, muss das Bit 3 gelöscht werden.&lt;br /&gt;
&lt;br /&gt;
== ADC (Analog Digital Converter) ==&lt;br /&gt;
&lt;br /&gt;
Der Analog-Digital-Konverter (ADC) wandelt analoge Signale in digitale Werte um, welche vom Controller interpretiert werden können. Einige AVR-Typen haben bereits einen mehrkanaligen Analog-Digital-Konverter eingebaut. Die Feinheit, mit welcher ein analoges Signal aufgelöst werden kann, wird durch die Auflösung des ADC, d.h. durch die Anzahl der verwendeten Bits angegeben. So sind derzeit bspw. 8-Bit- oder 10-Bit-ADC im Einsatz. ADCs, die in AVRs enthalten sind, haben zur Zeit eine maximale Auflösung von 10-Bit.&lt;br /&gt;
&lt;br /&gt;
Ein ADC mit 8 Bit Auflösung kann somit das analoge Signal in Abstufungen von 1/256 des Maximalwertes digitalisieren. Wenn wir nun mal annehmen, wir hätten eine Eingangspannung zwischen 0 und 5 Volt, eine Referenzspannung von 5&amp;amp;nbsp;V und eine Auflösung von 3 Bit, dann könnten&lt;br /&gt;
Intervalle mit den Grenzen 0&amp;amp;nbsp;V, 0.625&amp;amp;nbsp;V, 1.25&amp;amp;nbsp;V, 1.875&amp;amp;nbsp;V, 2.5&amp;amp;nbsp;V, 3.125&amp;amp;nbsp;V, 3.75&amp;amp;nbsp;V, 4.375&amp;amp;nbsp;V, 5&amp;amp;nbsp;V entsprechend folgender Tabelle unterschieden werden:&lt;br /&gt;
&lt;br /&gt;
::{|  class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
! Eingangsspannung am ADC / V || Entsprechender Messwert&lt;br /&gt;
|-&lt;br /&gt;
| 0 – 0.625    || 0&lt;br /&gt;
|-&lt;br /&gt;
| 0.625 – 1.25 || 1&lt;br /&gt;
|-&lt;br /&gt;
| 1.25 – 1.875 || 2&lt;br /&gt;
|-&lt;br /&gt;
| 1.875 – 2.5  || 3&lt;br /&gt;
|-&lt;br /&gt;
| 2.5 – 3.125  || 4&lt;br /&gt;
|-&lt;br /&gt;
| 3.125 – 3.75 || 5&lt;br /&gt;
|-&lt;br /&gt;
| 3.75 – 4.375 || 6&lt;br /&gt;
|-&lt;br /&gt;
| 4.375 – 5    || 7&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Die Angaben sind natürlich nur ungefähr. Je höher nun die Auflösung des Analog-Digital-Konverters ist, also, je mehr Bits er hat, desto genauer kann der jeweilige Wert erfasst werden.&lt;br /&gt;
&lt;br /&gt;
=== Der interne ADC im AVR ===&lt;br /&gt;
&lt;br /&gt;
Oft sind auch mehrere Kanäle verfügbar. Kanäle heißt in diesem Zusammenhang, dass zwar bis zu zehn analoge Eingänge am AVR vorhanden sind, aber nur ein &amp;quot;echter&amp;quot; Analog-Digital-Wandler zur Verfügung steht. Vor der eigentlichen Messung ist also festzulegen, welcher Kanal (&amp;quot;Pin&amp;quot;) mit dem Wandler verbunden und gemessen wird.&lt;br /&gt;
&lt;br /&gt;
Die Umwandlung innerhalb des AVR basiert auf der schrittweisen Näherung. Beim AVR müssen die Pins &#039;&#039;&#039;AGND&#039;&#039;&#039; und &#039;&#039;&#039;AVCC&#039;&#039;&#039; beschaltet werden. Für genaue Messungen sollte AVCC über ein L-C Netzwerk mit VCC verbunden werden, um Spannungsspitzen und -einbrüche vom Analog-Digital-Wandler fernzuhalten. Im Datenblatt findet sich dazu eine Schaltung, die 10uH und 100nF vorsieht.&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis der Analog-Digital-Wandlung wird auf eine Referenzspannung bezogen. Aktuelle AVRs bieten drei Möglichkeiten zur Wahl dieser Spannung:&lt;br /&gt;
&lt;br /&gt;
* Eine externe Referenzspannung von maximal &#039;&#039;&#039;Vcc&#039;&#039;&#039; am Anschlusspin &#039;&#039;&#039;AREF&#039;&#039;&#039;. Die minimale (externe) Referenzspannung darf jedoch nicht beliebig niedrig sein, vgl. dazu das (aktuellste) Datenblatt des verwendeten Controllers. &lt;br /&gt;
&lt;br /&gt;
* Verfügt der AVR über eine interne Referenzspannung, kann diese genutzt werden. Alle aktuellen AVRs mit internem AD-Wandler sollten damit ausgestattet sein (vgl. Datenblatt: 2,56V oder 1,1V je nach Typ). Das Datenblatt gibt auch über die Genauigkeit dieser Spannung Auskunft.&lt;br /&gt;
&lt;br /&gt;
* Es kann die Spannung AVcc als Referenzspannung herangezogen werden&lt;br /&gt;
&lt;br /&gt;
Bei Nutzung von AVcc oder der internen Referenz wird empfohlen, einen Kondensator zwischen dem AREF-Pin und GND anzuordnen. Die Festlegung, welche Spannungsreferenz genutzt wird, erfolgt z.&amp;amp;nbsp;B. beim ATmega16 mit den Bits REFS1/REFS0 im ADMUX-Register. Die zu messende Spannung muss im Bereich zwischen &#039;&#039;&#039;AGND&#039;&#039;&#039; und &#039;&#039;&#039;AREF&#039;&#039;&#039; (egal ob intern oder extern) liegen. &lt;br /&gt;
&lt;br /&gt;
Der &#039;&#039;&#039;ADC&#039;&#039;&#039; kann in zwei verschiedenen Betriebsarten verwendet werden:&lt;br /&gt;
&lt;br /&gt;
; Einfache Wandlung (Single Conversion) : In dieser Betriebsart wird der Wandler bei Bedarf vom Programm angestoßen für jeweils eine Messung.&lt;br /&gt;
&lt;br /&gt;
; Frei laufend (Free Running) : In dieser Betriebsart erfasst der Wandler permanent die anliegende Spannung und schreibt diese in das &#039;&#039;&#039;ADC Data Register&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==== Die Register des ADC ====&lt;br /&gt;
&lt;br /&gt;
Der &#039;&#039;&#039;ADC&#039;&#039;&#039; verfügt über eigene Register. Im Folgenden die Registerbeschreibung eines  ATMega16, welcher über 8 ADC-Kanäle verfügt. Die Register unterscheiden sich jedoch nicht erheblich von denen anderer AVRs (vgl. Datenblatt).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
| &#039;&#039;&#039;ADCSRA&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&#039;&#039;&#039;&lt;br /&gt;
| &#039;&#039;&#039;ADC&#039;&#039;&#039; &#039;&#039;&#039;C&#039;&#039;&#039;ontrol and &#039;&#039;&#039;S&#039;&#039;&#039;tatus &#039;&#039;&#039;R&#039;&#039;&#039;egister A.&amp;lt;br /&amp;gt;&lt;br /&gt;
In diesem Register stellen wir ein, wie wir den &#039;&#039;&#039;ADC&#039;&#039;&#039; verwenden möchten.&amp;lt;br /&amp;gt;&lt;br /&gt;
Das Register ist wie folgt aufgebaut:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! Bit&lt;br /&gt;
| 7|| 6|| 5|| 4|| 3|| 2|| 1|| 0&lt;br /&gt;
|- &lt;br /&gt;
! Name&lt;br /&gt;
| &#039;&#039;&#039;ADEN&#039;&#039;&#039;|| &#039;&#039;&#039;ADSC&#039;&#039;&#039;|| &#039;&#039;&#039;ADFR&#039;&#039;&#039;|| &#039;&#039;&#039;ADIF&#039;&#039;&#039;|| &#039;&#039;&#039;ADIE&#039;&#039;&#039;|| &#039;&#039;&#039;ADPS2&#039;&#039;&#039;|| &#039;&#039;&#039;ADPS1&#039;&#039;&#039;|| &#039;&#039;&#039;ADPS0&#039;&#039;&#039;&lt;br /&gt;
|- &lt;br /&gt;
! R/W&lt;br /&gt;
| R/W|| R/W|| R/W|| R/W|| R/W|| R/W|| R/W|| R/W&lt;br /&gt;
|- &lt;br /&gt;
! Initialwert&lt;br /&gt;
| 0|| 0|| 0|| 0|| 0|| 0|| 0|| 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ADEN&#039;&#039;&#039; (&#039;&#039;&#039;AD&#039;&#039;&#039;C &#039;&#039;&#039;En&#039;&#039;&#039;able)&lt;br /&gt;
:Dieses Bit muss gesetzt werden, um den &#039;&#039;&#039; ADC&#039;&#039;&#039; überhaupt zu aktivieren. Wenn das Bit nicht gesetzt ist, können die Pins wie normale I/O-Pins verwendet werden.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ADSC&#039;&#039;&#039; (&#039;&#039;&#039;AD&#039;&#039;&#039;C &#039;&#039;&#039;S&#039;&#039;&#039;tart &#039;&#039;&#039;C&#039;&#039;&#039;onversion)&lt;br /&gt;
:Mit diesem Bit wird ein Messvorgang gestartet. In der frei laufenden Betriebsart muss das Bit gesetzt werden, um die kontinuierliche Messung zu aktivieren.&lt;br /&gt;
:Wenn das Bit nach dem Setzen des &#039;&#039;&#039;ADEN&#039;&#039;&#039;-Bits zum ersten Mal gesetzt wird, führt der Controller zuerst eine zusätzliche Wandlung und erst dann die eigentliche Wandlung aus. Diese zusätzliche Wandlung wird zu Initialisierungszwecken durchgeführt.&lt;br /&gt;
:Das Bit bleibt nun so lange auf 1, bis die Umwandlung abgeschlossen ist, im Initialisierungsfall entsprechend bis die zweite Umwandlung erfolgt ist und geht danach auf 0.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ADFR&#039;&#039;&#039; (&#039;&#039;&#039;AD&#039;&#039;&#039;C &#039;&#039;&#039;F&#039;&#039;&#039;ree &#039;&#039;&#039;R&#039;&#039;&#039;un select)&lt;br /&gt;
:Mit diesem Bit wird die Betriebsart eingestellt.&lt;br /&gt;
:Ist das Bit auf 1 gesetzt arbeitet der ADC im &amp;quot;Free Running&amp;quot;-Modus. Dabei wird das Datenregister permanent aktualisiert. Ist das Bit hingegen auf 0 gesetzt, macht der ADC nur eine &amp;quot;Single Conversion&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ADIF&#039;&#039;&#039; (&#039;&#039;&#039;AD&#039;&#039;&#039;C &#039;&#039;&#039;I&#039;&#039;&#039;nterrupt &#039;&#039;&#039;F&#039;&#039;&#039;lag)&lt;br /&gt;
:Dieses Bit wird vom &#039;&#039;&#039; ADC&#039;&#039;&#039; gesetzt, sobald eine Umwandlung erfolgt ist und das &#039;&#039;&#039;ADC Data Register&#039;&#039;&#039; aktualisiert wurde. Das Bit wird bei lesendem Zugriff auf &#039;&#039;&#039;ADC(L,H)&#039;&#039;&#039; automatisch (d.h. durch die Hardware) gelöscht.&lt;br /&gt;
:Wenn das &#039;&#039;&#039;ADIE&#039;&#039;&#039; Bit sowie das &#039;&#039;&#039;I-Bit&#039;&#039;&#039; im AVR &#039;&#039;&#039;Statusregister&#039;&#039;&#039; gesetzt ist, wird der &#039;&#039;&#039;ADC Interrupt&#039;&#039;&#039; ausgelöst und die Interrupt-Behandlungsroutine aufgerufen.&lt;br /&gt;
:Das Bit wird automatisch gelöscht, wenn die Interrupt-Behandlungsroutine aufgerufen wird. Es kann jedoch auch gelöscht werden, indem eine logische &#039;&#039;&#039;1&#039;&#039;&#039;! in das Register geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ADIE&#039;&#039;&#039; (&#039;&#039;&#039;AD&#039;&#039;&#039;C &#039;&#039;&#039;I&#039;&#039;&#039;nterrupt &#039;&#039;&#039;E&#039;&#039;&#039;nable)&lt;br /&gt;
:Wenn dieses Bit gesetzt ist und ebenso das &#039;&#039;&#039; I-Bit&#039;&#039;&#039; im Statusregister &#039;&#039;&#039;SREG&#039;&#039;&#039;, dann wird der &#039;&#039;&#039; ADC-Interrupt&#039;&#039;&#039; aktiviert.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ADPS2...ADPS0&#039;&#039;&#039; (&#039;&#039;&#039;AD&#039;&#039;&#039;C &#039;&#039;&#039;P&#039;&#039;&#039;rescaler &#039;&#039;&#039;S&#039;&#039;&#039;elect Bits)&lt;br /&gt;
:Diese Bits bestimmen den Teilungsfaktor zwischen der Taktfrequenz und dem Eingangstakt des &#039;&#039;&#039;ADC&#039;&#039;&#039;.&lt;br /&gt;
:Der &#039;&#039;&#039;ADC&#039;&#039;&#039; benötigt einen eigenen Takt, welchen er sich selber aus der CPU-Taktfreqenz erzeugt. Der &#039;&#039;&#039;ADC&#039;&#039;&#039;-Takt sollte zwischen 50 und 200kHz liegen.&lt;br /&gt;
:Der Vorteiler muss also so eingestellt werden, dass CPU-Taktfrequenz dividiert durch den Teilungsfaktor einen Wert im Bereich &#039;&#039;&#039;(50-200)kHz&#039;&#039;&#039; ergibt.&lt;br /&gt;
:Bei einer CPU-Taktfrequenz von 4MHz beispielsweise rechnen wir&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
TF_{min}=\frac{CLK}{200\,\mathrm{kHz}}=\frac{4000000}{200000}=\mathbf{20}&lt;br /&gt;
\\&lt;br /&gt;
\\&lt;br /&gt;
TF_{max}=\frac{CLK}{50\,\mathrm{kHz}}=\frac{4000000}{50000}=\mathbf{80}&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:Somit kann hier der Teilungsfaktor 32 oder 64 verwendet werden. Im Interesse der schnelleren Wandlungszeit werden wir hier den Faktor 32 einstellen.&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! &#039;&#039;&#039;ADPS2&#039;&#039;&#039;|| &#039;&#039;&#039;ADPS1&#039;&#039;&#039;|| &#039;&#039;&#039;ADPS0&#039;&#039;&#039;|| &#039;&#039;&#039;Teilungsfaktor&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| 0|| 0|| 0|| 2&lt;br /&gt;
|-&lt;br /&gt;
| 0|| 0|| 1|| 2&lt;br /&gt;
|-&lt;br /&gt;
| 0|| 1|| 0|| 4&lt;br /&gt;
|-&lt;br /&gt;
| 0|| 1|| 1|| 8&lt;br /&gt;
|-&lt;br /&gt;
| 1|| 0|| 0|| 16&lt;br /&gt;
|-&lt;br /&gt;
| 1|| 0|| 1|| 32&lt;br /&gt;
|-&lt;br /&gt;
| 1|| 1|| 0|| 64&lt;br /&gt;
|-&lt;br /&gt;
| 1|| 1|| 1|| 128&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
|- &lt;br /&gt;
| &#039;&#039;&#039;ADCL&#039;&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;ADCH&#039;&#039;&#039;&lt;br /&gt;
| &#039;&#039;&#039;ADC &#039;&#039;&#039; Data Register&amp;lt;br /&amp;gt;&lt;br /&gt;
Wenn eine Umwandlung abgeschlossen ist, befindet sich der gemessene Wert in&lt;br /&gt;
diesen beiden Registern. Von &#039;&#039;&#039;ADCH&#039;&#039;&#039; werden nur die beiden niederwertigsten Bits verwendet. Es müssen immer beide Register ausgelesen werden, und zwar immer &#039;&#039;&#039;in der Reihenfolge: ADCL, ADCH&#039;&#039;&#039;. &lt;br /&gt;
Der effektive Messwert ergibt sich dann zu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
x = ADCL;       // mit uint16_t x&lt;br /&gt;
x += (ADCH&amp;lt;&amp;lt;8); // in zwei Zeilen (LSB/MSB-Reihenfolge und&lt;br /&gt;
                // C-Operatorpriorität sichergestellt)&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
oder &lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
x = ADCW; // je nach AVR auch x = ADC (siehe avr/ioxxx.h)&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|- &lt;br /&gt;
| &#039;&#039;&#039;ADMUX&amp;amp;nbsp;&amp;amp;nbsp;&#039;&#039;&#039;&lt;br /&gt;
| &#039;&#039;&#039;AD&#039;&#039;&#039;C &#039;&#039;&#039;Mu&#039;&#039;&#039;ltiple&#039;&#039;&#039;x&#039;&#039;&#039;er Select Register&amp;lt;br /&amp;gt;&lt;br /&gt;
Mit diesem Register wird der zu messende Kanal ausgewählt. Beim 90S8535&lt;br /&gt;
kann jeder Pin von Port A als &#039;&#039;&#039;ADC&#039;&#039;&#039;-Eingang verwendet werden (=8 Kanäle).&amp;lt;br /&amp;gt;&lt;br /&gt;
Das Register ist wie folgt aufgebaut:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! Bit&lt;br /&gt;
| 7|| 6|| 5|| 4|| 3|| 2|| 1|| 0&lt;br /&gt;
|- &lt;br /&gt;
! Name&lt;br /&gt;
| &#039;&#039;&#039;REFS1&#039;&#039;&#039;|| &#039;&#039;&#039;REFS0&#039;&#039;&#039;|| &#039;&#039;&#039;ADLAR&#039;&#039;&#039;|| &#039;&#039;&#039;MUX4&#039;&#039;&#039;|| &#039;&#039;&#039;MUX3&#039;&#039;&#039;|| &#039;&#039;&#039;MUX2&#039;&#039;&#039;|| &#039;&#039;&#039;MUX1&#039;&#039;&#039;|| &#039;&#039;&#039;MUX0&#039;&#039;&#039;&lt;br /&gt;
|- &lt;br /&gt;
! &#039;&#039;&#039;R/W&#039;&#039;&#039;&lt;br /&gt;
| R/W|| R/W|| R/W|| R/W|| R/W|| R/W|| R/W|| R/W&lt;br /&gt;
|- &lt;br /&gt;
! Initialwert&lt;br /&gt;
| 0|| 0|| 0|| 0|| 0|| 0|| 0|| 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;REFS1...REFS0&#039;&#039;&#039; (&#039;&#039;&#039;Ref&#039;&#039;&#039;erence&#039;&#039;&#039;S&#039;&#039;&#039;election Bits)&lt;br /&gt;
:Mit diesen Bits kann die Referenzspannung eingestellt werden. Bei der Umstellung sind Wartezeiten zu beachten, bis die ADC-Hardware einsatzfähig ist (Datenblatt und  [http://www.mikrocontroller.net/topic/165513]):&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! &#039;&#039;&#039;REFS1&#039;&#039;&#039;|| &#039;&#039;&#039;REFS0&#039;&#039;&#039;|| &#039;&#039;&#039;Referenzspanung&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| 0|| 0|| Externes AREF&lt;br /&gt;
|-&lt;br /&gt;
| 0|| 1|| AVCC als Referenz&lt;br /&gt;
|-&lt;br /&gt;
| 1|| 0|| Reserviert&lt;br /&gt;
|-&lt;br /&gt;
| 1|| 1|| Interne 2,56 Volt&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ADLAR&#039;&#039;&#039; (&#039;&#039;&#039;ADC &#039;&#039;&#039; &#039;&#039;&#039;L&#039;&#039;&#039;eft &#039;&#039;&#039;A&#039;&#039;&#039;djust &#039;&#039;&#039;R&#039;&#039;&#039;esult)&lt;br /&gt;
:Das ADLAR Bit verändert das Aussehen des Ergebnisses der AD-Wandlung. Bei einer logischen 1 wird das Ergebnis linksbündig ausgegeben, bei einer 0 rechtsbündig. Eine Änderung in diesem Bit beeinflusst das Ergebnis sofort, ganz egal ob bereits eine Wandlung läuft.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MUX4...MUX0&#039;&#039;&#039;&lt;br /&gt;
:Mit diesen 5 Bits wird der zu messende Kanal bestimmt. Wenn man einen einfachen 1-kanaligen ADC verwendet wird einfach die entsprechende Pinnummer des Ports in die Bits 0...4 eingeschrieben (je nach Anzahl der Wandler des AVR, bei 8 AD-Kanälen halt nur 0...2).&lt;br /&gt;
:Wenn das Register beschrieben wird, während eine Umwandlung läuft, so wird zuerst die aktuelle Umwandlung auf dem bisherigen Kanal beendet. Dies ist vor allem beim frei laufenden Betrieb zu berücksichtigen.&lt;br /&gt;
&lt;br /&gt;
:Eine Empfehlung ist deswegen diese, dass der frei laufende Betrieb nur bei einem einzelnen zu verwendenden Analogeingang verwendet werden sollte, wenn man sich Probleme bei der Umschalterei ersparen will.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Nutzung des ADC ====&lt;br /&gt;
&lt;br /&gt;
Um den &#039;&#039;&#039; ADC&#039;&#039;&#039; zu aktivieren, müssen wir das &#039;&#039;&#039;ADEN&#039;&#039;&#039;-Bit im &#039;&#039;&#039;ADCSR&#039;&#039;&#039;-Register setzen. Im gleichen Schritt legen wir auch die Betriebsart fest. &lt;br /&gt;
&lt;br /&gt;
Ein kleines Beispiel für den &amp;quot;single conversion&amp;quot;-Mode bei einem ATmega169 und Nutzung der internen Referenzspannung (beim &#039;169 1,1V bei anderen AVRs auch 2,56V). D.h. das Eingangssignal darf diese Spannung nicht überschreiten, gegebenenfalls muss es mit einem [[Spannungsteiler]] verringert werden. Das Ergebnis der Routine ist der ADC-Wert, also 0 für 0-Volt und 1023 für V_ref-Volt.&lt;br /&gt;
&lt;br /&gt;
In der praktischen Anwendung wird man zum Programmstart den ADC erst einmal grundlegend konfigurieren und dann auf verschiedenen Kanälen messen. Diese beiden Dinge sollte man meist trennen, denn das Einschalten des ADC und vor allem der Referenzspannung dauert ein paar Dutzend Mikrosekunden. Außerdem ist das erste Ergebnis nach dem Einschalten ungültig und muss verworfen werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* ADC initialisieren */&lt;br /&gt;
void ADC_Init(void) {&lt;br /&gt;
&lt;br /&gt;
  uint16_t result;&lt;br /&gt;
&lt;br /&gt;
//  ADMUX = (0&amp;lt;&amp;lt;REFS1) | (1&amp;lt;&amp;lt;REFS0);      // AVcc als Referenz benutzen&lt;br /&gt;
  ADMUX = (1&amp;lt;&amp;lt;REFS1) | (1&amp;lt;&amp;lt;REFS0);      // interne Referenzspannung nutzen&lt;br /&gt;
  // Bit ADFR (&amp;quot;free running&amp;quot;) in ADCSRA steht beim Einschalten&lt;br /&gt;
  // schon auf 0, also single conversion&lt;br /&gt;
  ADCSRA = (1&amp;lt;&amp;lt;ADPS1) | (1&amp;lt;&amp;lt;ADPS0);     // Frequenzvorteiler&lt;br /&gt;
  ADCSRA |= (1&amp;lt;&amp;lt;ADEN);                  // ADC aktivieren&lt;br /&gt;
&lt;br /&gt;
  /* nach Aktivieren des ADC wird ein &amp;quot;Dummy-Readout&amp;quot; empfohlen, man liest&lt;br /&gt;
     also einen Wert und verwirft diesen, um den ADC &amp;quot;warmlaufen zu lassen&amp;quot; */&lt;br /&gt;
&lt;br /&gt;
  ADCSRA |= (1&amp;lt;&amp;lt;ADSC);                  // eine ADC-Wandlung &lt;br /&gt;
  while (ADCSRA &amp;amp; (1&amp;lt;&amp;lt;ADSC) ) {}        // auf Abschluss der Konvertierung warten&lt;br /&gt;
  /* ADCW muss einmal gelesen werden, sonst wird Ergebnis der nächsten&lt;br /&gt;
     Wandlung nicht übernommen. */&lt;br /&gt;
  result = ADCW;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ADC Einzelmessung */&lt;br /&gt;
uint16_t ADC_Read( uint8_t channel )&lt;br /&gt;
{&lt;br /&gt;
  // Kanal waehlen, ohne andere Bits zu beeinflußen&lt;br /&gt;
  ADMUX = (ADMUX &amp;amp; ~(0x1F)) | (channel &amp;amp; 0x1F);&lt;br /&gt;
  ADCSRA |= (1&amp;lt;&amp;lt;ADSC);            // eine Wandlung &amp;quot;single conversion&amp;quot;&lt;br /&gt;
  while (ADCSRA &amp;amp; (1&amp;lt;&amp;lt;ADSC) ) {}  // auf Abschluss der Konvertierung warten&lt;br /&gt;
  return ADCW;                    // ADC auslesen und zurückgeben&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ADC Mehrfachmessung mit Mittelwertbbildung */&lt;br /&gt;
uint16_t ADC_Read_Avg( uint8_t channel, uint8_t average )&lt;br /&gt;
{&lt;br /&gt;
  uint32_t result = 0;&lt;br /&gt;
&lt;br /&gt;
  for (uint8_t i = 0; i &amp;lt; average; ++i )&lt;br /&gt;
    result += ADC_Read( channel );&lt;br /&gt;
&lt;br /&gt;
  return (uint16_t)( result / average );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
/* Beispielaufrufe: */&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  uint16_t adcval;&lt;br /&gt;
  ADC_Init();&lt;br /&gt;
&lt;br /&gt;
  while( 1 ) {&lt;br /&gt;
    adcval = ADC_Read(0);  // Kanal 0&lt;br /&gt;
    // mach was mit adcval&lt;br /&gt;
&lt;br /&gt;
    adcval = ADC_Read_Avg(2, 4);  // Kanal 2, Mittelwert aus 4 Messungen&lt;br /&gt;
    // mach was mit adcval&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Beispiel läuft der ADC ständig. Für den Fall, dass man Strom sparen will, z.B. mittels Verwendung des [[Sleep Mode]]s, muss man den ADC nach jeder Messung abschalten und vor der nächsten Messung wieder einschalten, wobei auch dann wieder eine kleine Pause und Anfangswandlung nötig sind.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
Das Löschen des ADIF-Flags sollte, &#039;&#039;&#039;entgegen&#039;&#039;&#039; der [http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_intbits FAQ], mit&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
  ADCSRA |= (1&amp;lt;&amp;lt;ADIF);&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
erfolgen. Die Methode in der FAQ eignet sich nur für Register, in denen &#039;&#039;&#039;nur&#039;&#039;&#039; Interrupt-Flags stehen.&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog-Digital-Wandlung ohne internen ADC ===&lt;br /&gt;
&lt;br /&gt;
==== Messen eines Widerstandes ====&lt;br /&gt;
&lt;br /&gt;
[[Image:Poti.gif|framed|right]]&lt;br /&gt;
Analoge Werte lassen sich ohne Analog-Digital-Wandler auch indirekt ermitteln. Im Folgenden wird die Messung des an einem Potentiometer eingestellten Widerstands anhand der Ladekurve eines Kondensators erläutert. Bei dieser Methode wird nur ein Portpin benötigt, ein Analog-Digital-Wandler oder Analog-Comparator ist nicht erforderlich. Es wird dazu ein Kondensator und der Widerstand (das Potentiometer) in Reihe zwischen Vorsorgungsspannung und Masse/GND geschaltet (sogen. RC-Netzwerk). Zusätzlich wird eine Verbindung der Leitung zwischen Kondensator und Potentiometer zu einem Portpin des Controllers hergestellt. Die folgende Abbildung verdeutlicht die erforderliche Schaltung. &lt;br /&gt;
&lt;br /&gt;
Wird der Portpin des Controllers auf Ausgang konfiguriert (im Beispiel &#039;&#039;DDRD&amp;amp;nbsp;|=&amp;amp;nbsp;(1&amp;lt;&amp;lt;PD2)&#039;&#039;) und dieser Ausgang auf Logisch 1 (&amp;quot;High&amp;quot;, &#039;&#039;PORTD&amp;amp;nbsp;|=&amp;amp;nbsp;(1&amp;lt;&amp;lt;PD2)&#039;&#039;) geschaltet, liegt an beiden &amp;quot;Platten&amp;quot; des Kondensators das gleiche Potential &#039;&#039;&#039;VCC&#039;&#039;&#039; an und der Kondensator somit entladen. (Klingt komisch, mit &#039;&#039;&#039; Vcc&#039;&#039;&#039; entladen, ist aber so, da an beiden Seiten des Kondensators das gleiche Potential anliegt und somit eine Potentialdifferenz von 0V besteht =&amp;gt; Kondensator ist entladen).&lt;br /&gt;
&lt;br /&gt;
Nach einer gewissen Zeit ist der Kondensator entladen und der Portpin wird als Eingang konfiguriert (&#039;&#039;DDRD&amp;amp;nbsp;&amp;amp;=&amp;amp;nbsp;~(1&amp;lt;&amp;lt;PD2); PORTD&amp;amp;nbsp;&amp;amp;=&amp;amp;nbsp;~(1&amp;lt;&amp;lt;PD2)&#039;&#039;), wodurch dieser hochohmig wird. Der Status des Eingangspin (in PIND) ist Logisch 1 (High). Der Kondensator lädt sich jetzt über das Poti auf, dabei steigt der Spannungsabfall über dem Kondensator und derjenige über dem Poti sinkt. Fällt nun der Spannungsabfall über dem Poti unter die Threshold-Spannung des Eingangspins (2/5 Vcc, also ca. 2V), wird das Eingangssignal als LOW erkannt (Bit in PIND wird 0). Die Zeitspanne zwischen der Umschaltung von Entladung auf Aufladung und dem Wechsel des Eingangssignals von High auf Low ist ein Maß für den am Potentiometer eingestellten Widerstand. Zur Zeitmessung kann einer der im Controller vorhandenen Timer genutzt werden. Der 220 Ohm Widerstand dient dem Schutz des Controllers. Es würde sonst bei Maximaleinstellung des Potentionmeters (hier 0 Ohm) ein zu hoher Strom fließen, der die Ausgangsstufe des Controllers zerstört. &lt;br /&gt;
&lt;br /&gt;
Mit einem weiteren Eingangspin und ein wenig Software können wir auch eine Kalibrierung realisieren, um den Messwert in einen vernünftigen Bereich (z.B: 0...100 % oder so) umzurechnen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Link 404 =&amp;gt; auskommentiert, mthomas 9.2.2008 &lt;br /&gt;
Ein Beispielprogramm findet sich auf [http://www.mypage.bluewin.ch/ch_schifferle/ Christian Schifferles Web-Seite] im Archiv &#039;&#039;ATMEL.ZIP&#039;&#039;, welches unter den Titel &#039;&#039;Tutorial &amp;quot;Programmieren mit C für Atmel Mikrocontroller&#039;&#039; heruntergeladen werden kann. --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== ADC über Komparator ====&lt;br /&gt;
&lt;br /&gt;
[[Image:ADC ueber Komparator.gif|framed|right]]&lt;br /&gt;
Es gibt einen weiteren Weg, eine analoge Spannung mit Hilfe des&lt;br /&gt;
Komparators, welcher in fast jedem AVR integriert ist, zu messen. Siehe dazu&lt;br /&gt;
auch die Application Note AVR400 von Atmel.&lt;br /&gt;
&lt;br /&gt;
Dabei wird das zu messende Signal auf den invertierenden Eingang&lt;br /&gt;
des Komparators geführt. Zusätzlich wird ein Referenzsignal an den nicht&lt;br /&gt;
invertierenden Eingang des Komparators angeschlossen. Das Referenzsignal wird&lt;br /&gt;
hier auch wieder über ein RC-Glied erzeugt, allerdings mit festen Werten für R&lt;br /&gt;
und C.&lt;br /&gt;
&lt;br /&gt;
Das Prinzip der Messung ist nun dem vorhergehenden recht&lt;br /&gt;
ähnlich. Durch Anlegen eines LOW-Pegels an Pin 2 wird der Kondensator zuerst&lt;br /&gt;
einmal entladen. Auch hier muss darauf geachtet werden, dass der Entladevorgang&lt;br /&gt;
genügend lang dauert.&lt;br /&gt;
Nun wird Pin 2 auf HIGH gelegt. Der Kondensator wird geladen. Wenn die Spannung&lt;br /&gt;
über dem Kondensator die am Eingangspin anliegende Spannung erreicht hat,&lt;br /&gt;
schaltet der Komparator durch. Die Zeit, welche benötigt wird, um den&lt;br /&gt;
Kondensator zu laden, kann nun auch wieder als Maß für die Spannung an Pin 1&lt;br /&gt;
herangezogen werden.&lt;br /&gt;
&lt;br /&gt;
Ich habe es mir gespart, diese Schaltung auch aufzubauen, und zwar aus mehreren Gründen:&lt;br /&gt;
&lt;br /&gt;
# 3 Pins notwendig.&lt;br /&gt;
# Genauigkeit vergleichbar mit einfacherer Lösung.&lt;br /&gt;
# War einfach zu faul.&lt;br /&gt;
&lt;br /&gt;
Der Vorteil dieser Schaltung liegt allerdings darin, dass damit direkt Spannungen gemessen werden können.&lt;br /&gt;
&lt;br /&gt;
== DAC (Digital Analog Converter) ==&lt;br /&gt;
&lt;br /&gt;
Mit Hilfe eines Digital-Analog-Konverters (&#039;&#039;&#039;DAC&#039;&#039;&#039;) können wir nun auch Analogsignale ausgeben. Es gibt hier mehrere Verfahren. &amp;lt;!-- Wenn wir beim ADC die Möglichkeit haben, mit externen Komponenten zu operieren, müssen wir bei der DAC-Wandlung mit dem auskommen, was der Controller selber zu bieten hat. --mt: hmm, richtig? verstaendlich? redundant? --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== DAC über mehrere digitale Ausgänge ===&lt;br /&gt;
&lt;br /&gt;
Wenn wir an den Ausgängen des Controllers ein entsprechendes&lt;br /&gt;
Widerstandsnetzwerk aufbauen haben wir die Möglichkeit, durch die Ansteuerung&lt;br /&gt;
der Ausgänge über den Widerständen einen Addierer aufzubauen, mit dessen&lt;br /&gt;
Hilfe wir eine dem Zahlenwert proportionale Spannung erzeugen können. Das&lt;br /&gt;
Schaltbild dazu kann etwa so aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Image:DAC R2R.gif]]&lt;br /&gt;
&lt;br /&gt;
Es sollten selbstverständlich möglichst genaue Widerstände verwendet&lt;br /&gt;
werden, also nicht unbedingt solche mit einer Toleranz von 10% oder mehr.&lt;br /&gt;
Weiterhin empfiehlt es sich, je nach Anwendung den Ausgangsstrom über einen&lt;br /&gt;
Operationsverstärker zu verstärken.&lt;br /&gt;
&lt;br /&gt;
=== PWM (Pulsweitenmodulation) ===&lt;br /&gt;
&lt;br /&gt;
Wir kommen nun zu einem Thema, welches in aller Munde ist, aber viele&lt;br /&gt;
Anwender verstehen nicht ganz, wie [[PWM]] eigentlich funktioniert.&lt;br /&gt;
&lt;br /&gt;
Wie wir alle wissen, ist ein Mikrocontroller ein rein digitales Bauteil.&lt;br /&gt;
Definieren wir einen Pin als Ausgang, dann können wir diesen Ausgang entweder&lt;br /&gt;
auf HIGH setzen, worauf am Ausgang die Versorgungsspannung &#039;&#039;&#039; Vcc&#039;&#039;&#039; anliegt, oder aber wir setzen den Ausgang auf LOW, wonach dann &#039;&#039;&#039; 0V&#039;&#039;&#039; am Ausgang liegt. Was passiert aber nun, wenn wir periodisch mit einer festen Frequenz zwischen HIGH und LOW umschalten? - Richtig, wir erhalten eine Rechteckspannung, wie die folgende Abbildung zeigt:&lt;br /&gt;
&lt;br /&gt;
[[Image:PWM Theorie 1.gif]]&lt;br /&gt;
&lt;br /&gt;
Diese Rechteckspannung hat nun einen arithmetischen Mittelwert, &lt;br /&gt;
der je nach Pulsbreite kleiner oder größer ist.&lt;br /&gt;
&lt;br /&gt;
[[Image:PWM Theorie 2.gif]]&lt;br /&gt;
&lt;br /&gt;
Wenn wir nun diese pulsierende Ausgangsspannung noch über ein RC-Glied filtern/&amp;quot;glätten&amp;quot;, dann haben wir schon eine entsprechende Gleichspannung erzeugt.&lt;br /&gt;
&lt;br /&gt;
Mit den AVRs können wir direkt PWM-Signale erzeugen. &lt;br /&gt;
Dazu dient der 16-Bit Zähler, welcher im sogenannten PWM-Modus betrieben werden kann.&lt;br /&gt;
&lt;br /&gt;
;Hinweis: In den folgenden Überlegungen wird als Controller der 90S2313 vorausgesetzt. Die Theorie ist bei anderen AVR-Controllern vergleichbar, die Pinbelegung allerdings nicht unbedingt, weshalb ein Blick ins entsprechende Datenblatt dringend angeraten wird.&lt;br /&gt;
&lt;br /&gt;
Um den PWM-Modus zu aktivieren, müssen im Timer/Counter1 Control&lt;br /&gt;
Register A TCCR1A die Pulsweiten-Modulatorbits PWM10 bzw. PWM11 entsprechend nachfolgender Tabelle gesetzt werden:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! PWM11 || PWM10 || Bedeutung&lt;br /&gt;
|- &lt;br /&gt;
| 0 || 0 || PWM-Modus des Timers ist nicht aktiv&lt;br /&gt;
|- &lt;br /&gt;
| 0 || 1 || 8-Bit PWM&lt;br /&gt;
|- &lt;br /&gt;
| 1 || 0 || 9-Bit PWM&lt;br /&gt;
|- &lt;br /&gt;
| 1 || 1 || 10-Bit PWM&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Der Timer/Counter zählt nun permanent von 0 bis zur Obergrenze&lt;br /&gt;
und wieder zurück, er wird also als sogenannter Auf-/Ab Zähler betrieben. &lt;br /&gt;
Die Obergrenze hängt davon ab, ob wir mit 8, 9 oder 10-Bit PWM arbeiten wollen:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! Auflösung || Obergrenze || Frequenz&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 8&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 255&lt;br /&gt;
| f&amp;lt;sub&amp;gt;TC1&amp;lt;/sub&amp;gt; / 510&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 9&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 511&lt;br /&gt;
| f&amp;lt;sub&amp;gt;TC1&amp;lt;/sub&amp;gt; / 1022&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 10&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1023&lt;br /&gt;
| f&amp;lt;sub&amp;gt;TC1&amp;lt;/sub&amp;gt; / 2046&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Zusätzlich muss mit den Bits &#039;&#039;&#039;COM1A1&#039;&#039;&#039; und &#039;&#039;&#039;COM1A0&#039;&#039;&#039; desselben&lt;br /&gt;
Registers die gewünschte Ausgabeart des Signals definiert werden:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! COM1A1 || COM1A0 || Bedeutung&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| Keine Wirkung, Pin wird nicht geschaltet.&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| Keine Wirkung, Pin wird nicht geschaltet.&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| Nicht invertierende PWM.&amp;lt;br /&amp;gt;&lt;br /&gt;
Der Ausgangspin wird gelöscht beim Hochzählen und gesetzt beim&lt;br /&gt;
Herunterzählen.&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| Invertierende PWM.&amp;lt;br /&amp;gt;&lt;br /&gt;
Der Ausgangspin wird gelöscht beim Herunterzählen und gesetzt beim&lt;br /&gt;
Hochzählen.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Der entsprechende Befehl, um beispielsweise den Timer/Counter als&lt;br /&gt;
nicht invertierenden 10-Bit PWM zu verwenden, heißt dann:&lt;br /&gt;
&lt;br /&gt;
alte Schreibweise (PWMxx wird nicht mehr akzeptiert)&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
TCCR1A = (1&amp;lt;&amp;lt;PWM11)|(1&amp;lt;&amp;lt;PWM10)|(1&amp;lt;&amp;lt;COM1A1);&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
neue Schreibweise&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
TCCR1A = (1&amp;lt;&amp;lt;WGM11)|(1&amp;lt;&amp;lt;WGM10)|(1&amp;lt;&amp;lt;COM1A1);&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit der Timer/Counter überhaupt läuft, müssen wir im Control&lt;br /&gt;
Register B &#039;&#039;&#039;TCCR1B&#039;&#039;&#039; noch den gewünschten Takt (Vorteiler) einstellen und&lt;br /&gt;
somit auch die Frequenz des &#039;&#039;&#039;PWM&#039;&#039;&#039;-Signals bestimmen.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! CS12 || CS11 || CS10 || Bedeutung&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| Stop. Der Timer/Counter wird gestoppt.&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| CK&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| CK / 8&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| CK / 64&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| CK / 256&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| CK / 1024&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| Externer Pin 1, negative Flanke&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| Externer Pin 1, positive Flanke&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Also um einen Takt von CK / 1024 zu generieren, verwenden wir&lt;br /&gt;
folgenden Befehl:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
TCCR1B = (1&amp;lt;&amp;lt;CS12) | (1&amp;lt;&amp;lt;CS10);&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jetzt muss nur noch der Vergleichswert festgelegt werden. Diesen&lt;br /&gt;
schreiben wir in das 16-Bit Timer/Counter Output Compare Register &#039;&#039;&#039;OCR1A&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
OCR1A = xxx;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die folgende Grafik soll den Zusammenhang zwischen dem Vergleichswert und dem generierten &#039;&#039;&#039;PWM&#039;&#039;&#039;-Signal aufzeigen.&lt;br /&gt;
&lt;br /&gt;
[[Image:PWM Theorie 3.gif]]&lt;br /&gt;
&lt;br /&gt;
[[Image:PWM Theorie 4.gif]]&lt;br /&gt;
&lt;br /&gt;
Ach ja, fast hätte ich&#039;s vergessen. Das generierte &#039;&#039;&#039;PWM&#039;&#039;&#039;-Signal&lt;br /&gt;
wird am Output Compare Pin &#039;&#039;&#039;OC1&#039;&#039;&#039; des Timers ausgegeben und leider können wir&lt;br /&gt;
deshalb auch beim AT90S2313 nur ein einzelnes &#039;&#039;&#039;PWM&#039;&#039;&#039;-Signal mit dieser Methode generieren. Andere AVR-Typen verfügen über bis zu vier PWM-Ausgänge. Zu beachten ist außerdem, das wenn der OC Pin aktiviert ist, er nichtmehr wie üblich funktioniert und z.&amp;amp;nbsp;B. nicht einfach über PINx ausgelesen werden kann.&lt;br /&gt;
&lt;br /&gt;
Ein Programm, welches an einem ATmega8 den Fast-PWM Modus verwendet, den Modus 14, könnte so aussehen&lt;br /&gt;
&amp;lt;C&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  // OC1A auf Ausgang&lt;br /&gt;
  DDRB = (1 &amp;lt;&amp;lt; PB1 );  //ATMega8&lt;br /&gt;
  // DDRD = (1 &amp;lt;&amp;lt; PD5 ); //ATMega16&lt;br /&gt;
  //&lt;br /&gt;
  // Timer 1 einstellen&lt;br /&gt;
  //  &lt;br /&gt;
  // Modus 14:&lt;br /&gt;
  //    Fast PWM, Top von ICR1&lt;br /&gt;
  //&lt;br /&gt;
  //    WGM13    WGM12   WGM11    WGM10&lt;br /&gt;
  //      1        1       1        0&lt;br /&gt;
  //&lt;br /&gt;
  //    Timer Vorteiler: 1&lt;br /&gt;
  //     CS12     CS11    CS10&lt;br /&gt;
  //       0        0       1&lt;br /&gt;
  //&lt;br /&gt;
  //  Steuerung des Ausgangsport: Set at BOTTOM, Clear at match&lt;br /&gt;
  //     COM1A1   COM1A0&lt;br /&gt;
  //       1        0&lt;br /&gt;
 &lt;br /&gt;
  TCCR1A = (1&amp;lt;&amp;lt;COM1A1) | (1&amp;lt;&amp;lt;WGM11);&lt;br /&gt;
  TCCR1B = (1&amp;lt;&amp;lt;WGM13) | (1&amp;lt;&amp;lt;WGM12) | (1&amp;lt;&amp;lt;CS10);&lt;br /&gt;
 &lt;br /&gt;
  //  den Endwert (TOP) für den Zähler setzen&lt;br /&gt;
  //  der Zähler zählt bis zu diesem Wert&lt;br /&gt;
&lt;br /&gt;
  ICR1 = 0x6FFF;&lt;br /&gt;
 &lt;br /&gt;
  // der Compare Wert&lt;br /&gt;
  // Wenn der Zähler diesen Wert erreicht, wird mit&lt;br /&gt;
  // obiger Konfiguration der OC1A Ausgang abgeschaltet&lt;br /&gt;
  // Sobald der Zähler wieder bei 0 startet, wird der&lt;br /&gt;
  // Ausgang wieder auf 1 gesetzt&lt;br /&gt;
  //&lt;br /&gt;
  // Durch Verändern dieses Wertes, werden die unterschiedlichen&lt;br /&gt;
  // PWM Werte eingestellt.&lt;br /&gt;
&lt;br /&gt;
  OCR1A = 0x3FFF;&lt;br /&gt;
&lt;br /&gt;
  while (1) {}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/C&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;PWM-Mode Tabelle aus dem Datenblatt des ATmega8515&#039;&#039;&#039;&lt;br /&gt;
|- &lt;br /&gt;
!Mode || WGM13 || WGM12 || WGM11 || WGM10 || Timer/Counter Mode of Operation&lt;br /&gt;
! TOP|| Update of OCR1x at || TOV1 Flag set on&lt;br /&gt;
|- &lt;br /&gt;
! 0&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| Normal&lt;br /&gt;
| 0xFFFF&lt;br /&gt;
| Immediate&lt;br /&gt;
| MAX&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| PWM, Phase Correct, 8-Bit&lt;br /&gt;
| 0x00FF&lt;br /&gt;
| TOP&lt;br /&gt;
| BOTTOM&lt;br /&gt;
|- &lt;br /&gt;
! 2&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
| PWM, Phase Correct, 9-Bit&lt;br /&gt;
| 0x01FF&lt;br /&gt;
| TOP&lt;br /&gt;
| BOTTOM&lt;br /&gt;
|-&lt;br /&gt;
! 3&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
| PWM, Phase Correct, 10-Bit&lt;br /&gt;
| 0x03FF&lt;br /&gt;
| TOP&lt;br /&gt;
| BOTTOM&lt;br /&gt;
|-&lt;br /&gt;
! 4&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| CTC&lt;br /&gt;
| OCR1A&lt;br /&gt;
| Immediate&lt;br /&gt;
| MAX&lt;br /&gt;
|-&lt;br /&gt;
! 5&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| Fast PWM, 8-Bit&lt;br /&gt;
| 0x00FF&lt;br /&gt;
| BOTTOM&lt;br /&gt;
| TOP&lt;br /&gt;
|-&lt;br /&gt;
! 6&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
| Fast PWM, 9-Bit&lt;br /&gt;
| 0x01FF&lt;br /&gt;
| BOTTOM&lt;br /&gt;
| TOP&lt;br /&gt;
|-&lt;br /&gt;
! 7&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
| Fast PWM, 10-Bit&lt;br /&gt;
| 0x03FF&lt;br /&gt;
| BOTTOM&lt;br /&gt;
| TOP&lt;br /&gt;
|-&lt;br /&gt;
! 8&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| PWM, Phase an Frequency Correct&lt;br /&gt;
| ICR1&lt;br /&gt;
| BOTTOM&lt;br /&gt;
| BOTTOM&lt;br /&gt;
|-    &lt;br /&gt;
! 9&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| PWM, Phase an Frequency Correct&lt;br /&gt;
| OCR1A&lt;br /&gt;
| BOTTOM&lt;br /&gt;
| BOTTOM&lt;br /&gt;
|-&lt;br /&gt;
! 10&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
| PWM, Phase Correct&lt;br /&gt;
| ICR1&lt;br /&gt;
| TOP&lt;br /&gt;
| BOTTOM&lt;br /&gt;
|-&lt;br /&gt;
! 11&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
| PWM, Phase an Frequency Correct&lt;br /&gt;
| OCR1A&lt;br /&gt;
| TOP&lt;br /&gt;
| BOTTOM&lt;br /&gt;
|-&lt;br /&gt;
! 12&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| CTC&lt;br /&gt;
| ICR1&lt;br /&gt;
| Immediate&lt;br /&gt;
| MAX&lt;br /&gt;
|-&lt;br /&gt;
! 13&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| Reserved&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
! 14&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
| Fast PWM&lt;br /&gt;
| ICR1&lt;br /&gt;
| BOTTOM&lt;br /&gt;
| TOP&lt;br /&gt;
|-&lt;br /&gt;
! 15&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
| Fast PWM&lt;br /&gt;
| OCR1A&lt;br /&gt;
| BOTTOM&lt;br /&gt;
| TOP&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Für Details der PWM-Möglichkeiten muss immer das jeweilige Datenblatt des Prozessors konsultiert werden, da sich die unterschiedlichen Prozessoren in ihren Möglichkeiten doch stark unterscheiden. Auch muss man aufpassen, welches zu setzende Bit in welchem Register ist. Auch hier kann es sein, dass gleichnamige Konfigurationsbits in unterschiedlichen Konfigurationsregistern (je nach konkretem Prozessortyp) sitzen.&lt;br /&gt;
&lt;br /&gt;
= Warteschleifen (delay.h) =&lt;br /&gt;
&lt;br /&gt;
Der Programmablauf kann verschiedene Arten von Wartefunktionen erfordern:&lt;br /&gt;
&lt;br /&gt;
* Warten im Sinn von Zeitvertrödeln&lt;br /&gt;
* Warten auf einen bestimmten Zustand an den I/O-Pins&lt;br /&gt;
* Warten auf einen bestimmten Zeitpunkt (siehe Timer)&lt;br /&gt;
* Warten auf einen bestimmten Zählerstand (siehe Counter)&lt;br /&gt;
&lt;br /&gt;
Der einfachste Fall, das Zeitvertrödeln, kann in vielen Fällen und mit großer Genauigkeit anhand der avr-libc Bibliotheksfunktionen _delay_ms() und _delay_us() erledigt werden. Die Bibliotheksfunktionen sind einfachen Zählschleifen (Warteschleifen) vorzuziehen, da leere Zählschleifen ohne besondere Vorkehrungen sonst bei eingeschalteter Optimierung vom avr-gcc-Compiler wegoptimiert werden. Weiterhin sind die Bibliotheksfunktionen bereits darauf vorbereitet, die in F_CPU definierte Taktfrequenz zu verwenden. Außerdem sind die Funktionen der Bibliothek wirklich getestet.&lt;br /&gt;
&lt;br /&gt;
Einfach!? Schon, aber während gewartet wird, macht der µC nichts anderes mehr. Die Wartefunktion blockiert den Programmablauf. Möchte man einerseits warten, um z.&amp;amp;nbsp;B. eine LED blinken zu lassen und gleichzeitig andere Aktionen ausführen z.&amp;amp;nbsp;B. weitere LED bedienen, sollten die Timer/Counter des AVR verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Die Bibliotheksfunktionen funktionieren allerdings nur dann korrekt, wenn sie mit zur Übersetzungszeit (beim Compilieren) bekannten konstanten Werten aufgerufen werden. Der Quellcode muss mit eingeschalteter Optimierung übersetzt werden, sonst wird sehr viel Maschinencode erzeugt, und die Wartezeiten stimmen nicht mehr mit dem Parameter überein.&lt;br /&gt;
&lt;br /&gt;
Abhängig von der Version der Bibliothek verhalten sich die Bibliotheksfunktionen etwas unterschiedlich.&lt;br /&gt;
&lt;br /&gt;
== avr-libc Versionen kleiner 1.6 ==&lt;br /&gt;
&lt;br /&gt;
Die Wartezeit der Funktion _delay_ms() ist auf 262,14ms/F_CPU (in MHz) begrenzt, d.h. bei 20 MHz kann man nur max. 13,1ms warten. Die Wartezeit der Funktion _delay_us() ist auf 768us/F_CPU (in MHz) begrenzt, d.h. bei 20 MHz kann man nur max. 38,4us warten. Längere Wartezeiten müssen dann über einen mehrfachen Aufruf in einer Schleife gelöst werden.&lt;br /&gt;
&lt;br /&gt;
Beispiel: Blinken einer LED an PORTB Pin PB0 im ca. 1s Rhythmus&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#ifndef F_CPU&lt;br /&gt;
/* Definiere F_CPU, wenn F_CPU nicht bereits vorher definiert &lt;br /&gt;
   (z.&amp;amp;nbsp;B. durch Übergabe als Parameter zum Compiler innerhalb &lt;br /&gt;
   des Makefiles). Zusätzlich Ausgabe einer Warnung, die auf die&lt;br /&gt;
   &amp;quot;nachträgliche&amp;quot; Definition hinweist */&lt;br /&gt;
#warning &amp;quot;F_CPU war noch nicht definiert, wird nun mit 3686400 definiert&amp;quot;&lt;br /&gt;
#define F_CPU 3686400UL     /* Quarz mit 3.6864 Mhz */&lt;br /&gt;
#endif&lt;br /&gt;
#include &amp;lt;util/delay.h&amp;gt;     /* in älteren avr-libc Versionen &amp;lt;avr/delay.h&amp;gt; */ &lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 lange, variable Verzögerungszeit, Einheit in Millisekunden&lt;br /&gt;
&lt;br /&gt;
Die maximale Zeit pro Funktionsaufruf ist begrenzt auf &lt;br /&gt;
262.14 ms / F_CPU in MHz (im Beispiel: &lt;br /&gt;
262.1 / 3.6864 = max. 71 ms) &lt;br /&gt;
&lt;br /&gt;
Daher wird die kleine Warteschleife mehrfach aufgerufen,&lt;br /&gt;
um auf eine längere Wartezeit zu kommen. Die zusätzliche &lt;br /&gt;
Prüfung der Schleifenbedingung lässt die Wartezeit geringfügig&lt;br /&gt;
ungenau werden (macht hier vielleicht 2-3ms aus).&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
void long_delay(uint16_t ms)&lt;br /&gt;
{&lt;br /&gt;
    for(; ms&amp;gt;0; ms--) _delay_ms(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main( void )&lt;br /&gt;
{&lt;br /&gt;
    DDRB = ( 1 &amp;lt;&amp;lt; PB0 );        // PB0 an PORTB als Ausgang setzen&lt;br /&gt;
&lt;br /&gt;
    while( 1 )                  // Endlosschleife&lt;br /&gt;
    {                &lt;br /&gt;
        PORTB ^= ( 1 &amp;lt;&amp;lt; PB0 );  // Toggle PB0 z.&amp;amp;nbsp;B. angeschlossene LED&lt;br /&gt;
        long_delay(1000);       // Eine Sekunde warten...&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== avr-libc Versionen ab 1.6 ==&lt;br /&gt;
&lt;br /&gt;
_delay_ms() kann mit einem Argument bis 6553,5 ms (= 6,5535 Sekunden) benutzt werden. Wird die früher gültige Grenze von 262,14 ms/F_CPU (in MHz) überschritten, so arbeitet _delay_ms() einfach etwas ungenauer und zählt nur noch mit einer Auflösung von 1/10 ms. Eine Verzögerung von 1000,10 ms ließe sich nicht mehr von einer von 1000,19 ms unterscheiden. Ein Verlust, der sich im Allgemeinen verschmerzen lässt. Dem Programmierer wird keine Rückmeldung gegeben, dass die Funktion ggf. gröber arbeitet, d.h. wenn es darauf ankommt, bitte den Parameter wie bisher geschickt wählen.&lt;br /&gt;
&lt;br /&gt;
Die Funktion _delay_us() wurde ebenfalls erweitert. Wenn deren maximal als genau behandelbares Argument überschritten wird, benutzt diese intern _delay_ms(). Damit gelten in diesem Fall die _delay_ms() Einschränkungen.&lt;br /&gt;
&lt;br /&gt;
Beispiel: Blinken einer LED an PORTB Pin PB0 im ca. 1s Rhythmus, avr-libc ab Version 1.6&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#ifndef F_CPU&lt;br /&gt;
/* Definiere F_CPU, wenn F_CPU nicht bereits vorher definiert &lt;br /&gt;
   (z.&amp;amp;nbsp;B. durch Übergabe als Parameter zum Compiler innerhalb &lt;br /&gt;
   des Makefiles). Zusätzlich Ausgabe einer Warnung, die auf die&lt;br /&gt;
   &amp;quot;nachträgliche&amp;quot; Definition hinweist */&lt;br /&gt;
#warning &amp;quot;F_CPU war noch nicht definiert, wird nun mit 3686400 definiert&amp;quot;&lt;br /&gt;
#define F_CPU 3686400UL     /* Quarz mit 3.6864 Mhz */&lt;br /&gt;
#endif&lt;br /&gt;
#include &amp;lt;util/delay.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main( void )&lt;br /&gt;
{&lt;br /&gt;
    DDRB = ( 1 &amp;lt;&amp;lt; PB0 );        // PB0 an PORTB als Ausgang setzen&lt;br /&gt;
&lt;br /&gt;
    while( 1 ) {                // Endlosschleife&lt;br /&gt;
        PORTB ^= ( 1 &amp;lt;&amp;lt; PB0 );  // Toggle PB0 z.&amp;amp;nbsp;B. angeschlossene LED&lt;br /&gt;
        _delay_ms(1000);        // Eine Sekunde +/-1/10000 Sekunde warten...&lt;br /&gt;
                                // funktioniert nicht mit Bibliotheken vor 1.6&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die _delay_ms() und die _delay_us aus &#039;&#039;&#039;avr-libc 1.7.0&#039;&#039;&#039; sind fehlerhaft. _delay_ms () läuft 4x schneller als erwartet. Abhilfe ist eine korrigierte Includedatei: [http://www.mikrocontroller.net/topic/196738#1943039]&lt;br /&gt;
&lt;br /&gt;
= Programmieren mit Interrupts =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;float:right; margin:2em;&amp;quot;&amp;gt;&lt;br /&gt;
[[Image:Interrupt Programme.gif]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
Nachdem wir nun alles Wissenswerte für die serielle Programmerstellung&lt;br /&gt;
gelernt haben nehmen wir jetzt ein völlig anderes Thema in Angriff, nämlich&lt;br /&gt;
die Programmierung unter Zuhilfenahme der Interrupts des AVR.&lt;br /&gt;
&lt;br /&gt;
Als erstes wollen wir uns noch einmal den allgemeinen Programmablauf bei der&lt;br /&gt;
Interrupt-Programmierung zu Gemüte führen.&lt;br /&gt;
&lt;br /&gt;
Man sieht, dass die Interruptroutine quasi parallel zum Hauptprogramm&lt;br /&gt;
abläuft. Da wir nur eine CPU haben ist es natürlich keine echte Parallelität,&lt;br /&gt;
sondern das Hauptprogramm wird beim Eintreffen eines Interrupts unterbrochen,&lt;br /&gt;
die Interruptroutine wird ausgeführt und danach erst wieder zum Hauptprogramm&lt;br /&gt;
zurückgekehrt.&lt;br /&gt;
&lt;br /&gt;
Siehe auch&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/forum/read-1-235092.html#new Ausführlicher Thread im Forum]&lt;br /&gt;
* Artikel [[Interrupt]]&lt;br /&gt;
* Artikel [[Multitasking]]&lt;br /&gt;
{{Clear}}&lt;br /&gt;
&lt;br /&gt;
== Anforderungen an Interrupt-Routinen ==&lt;br /&gt;
&lt;br /&gt;
Um unliebsamen Überraschungen vorzubeugen, sollten einige Grundregeln bei der Implementierung der Interruptroutinen beachtet werden. Interruptroutinen sollten möglichst kurz und schnell abarbeitbar sein, daraus folgt:&lt;br /&gt;
&lt;br /&gt;
* Keine umfangreichen Berechnungen innerhalb der Interruptroutine. (*)&lt;br /&gt;
* Keine langen Programmschleifen.&lt;br /&gt;
* Obwohl es möglich ist, während der Abarbeitung einer Interruptroutine andere oder sogar den gleichen Interrupt wieder zuzulassen, wird davon ohne genaue Kenntnis der internen Abläufe dringend abgeraten.&lt;br /&gt;
&lt;br /&gt;
Interruptroutinen (ISRs) sollten also möglichst kurz sein und keine Schleifen mit vielen Durchläufen enthalten. Längere Operationen können meist in einen &amp;quot;Interrupt-Teil&amp;quot; in einer ISR und einen &amp;quot;Arbeitsteil&amp;quot; im Hauptprogramm aufgetrennt werden. Z.B. Speichern des Zustands aller Eingänge im EEPROM in bestimmten Zeitabständen: ISR-Teil: Zeitvergleich (Timer,RTC) mit Logzeit/-intervall. Bei Übereinstimmung ein globales Flag setzen (volatile bei Flag-Deklaration nicht vergessen, s.u.). Dann im Hauptprogramm prüfen, ob das Flag gesetzt ist. Wenn ja: die Daten im EEPROM ablegen und Flag löschen.&lt;br /&gt;
&lt;br /&gt;
(*)&lt;br /&gt;
Hinweis: &lt;br /&gt;
Es gibt allerdings die seltene Situation, dass man gerade eingelesene&lt;br /&gt;
ADC-Werte sofort verarbeiten muss. Besonders dann, wenn man mehrere Werte sehr&lt;br /&gt;
schnell hintereinander bekommt. Dann bleibt einem nichts anderes übrig, als die&lt;br /&gt;
Werte noch in der ISR zu verarbeiten. Kommt aber sehr selten vor und sollte&lt;br /&gt;
durch geeignete Wahl des Systemtaktes bzw. Auswahl des Controllers vermieden werden!&lt;br /&gt;
&lt;br /&gt;
== Interrupt-Quellen ==&lt;br /&gt;
&lt;br /&gt;
Die folgenden Ereignisse können einen Interrupt auf einem AVR AT90S2313 auslösen, wobei die Reihenfolge der Auflistung auch die Priorität der Interrupts aufzeigt.&lt;br /&gt;
&lt;br /&gt;
* Reset&lt;br /&gt;
* Externer Interrupt 0&lt;br /&gt;
* Externer Interrupt 1&lt;br /&gt;
* Timer/Counter 1 Capture Ereignis&lt;br /&gt;
* Timer/Counter 1 Compare Match&lt;br /&gt;
* Timer/Counter 1 Überlauf&lt;br /&gt;
* Timer/Counter 0 Überlauf&lt;br /&gt;
* UART Zeichen empfangen&lt;br /&gt;
* UART Datenregister leer&lt;br /&gt;
* UART Zeichen gesendet&lt;br /&gt;
* Analoger Komparator&lt;br /&gt;
&lt;br /&gt;
Die Anzahl der möglichen Interruptquellen variiert zwischen den verschiedenen Microcontroller-Typen. Im Zweifel hilft ein Blick ins Datenblatt (&amp;quot;Interrupt Vectors&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
== Register ==&lt;br /&gt;
&lt;br /&gt;
Der AT90S2313 verfügt über 2 Register die mit den&lt;br /&gt;
Interrupts zusammen hängen.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
| &#039;&#039;&#039;GIMSK&#039;&#039;&#039;&lt;br /&gt;
| &#039;&#039;&#039;G&#039;&#039;&#039;eneral &#039;&#039;&#039;I&#039;&#039;&#039;nterrupt &#039;&#039;&#039;M&#039;&#039;&#039;ask &#039;&#039;&#039;R&#039;&#039;&#039;egister.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! Bit &lt;br /&gt;
| 7 || 6|| 5 || 4 || 3 || 2 || 1 || 0&lt;br /&gt;
|- &lt;br /&gt;
! Name&lt;br /&gt;
| &#039;&#039;&#039;INT1&#039;&#039;&#039; || &#039;&#039;&#039;INT0&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039;&lt;br /&gt;
|- &lt;br /&gt;
! R/W&lt;br /&gt;
| R/W || R/W || R || R || R || R || R || R&lt;br /&gt;
|- &lt;br /&gt;
! Initialwert&lt;br /&gt;
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;INT1&#039;&#039;&#039; (External &#039;&#039;&#039;Int&#039;&#039;&#039;errupt Request &#039;&#039;&#039;1&#039;&#039;&#039; Enable)&lt;br /&gt;
:Wenn dieses Bit gesetzt ist, wird ein Interrupt ausgelöst, wenn am &#039;&#039;&#039;INT1&#039;&#039;&#039;-Pin eine steigende oder fallende (je nach Konfiguration im &#039;&#039;&#039;MCUCR&#039;&#039;&#039;) Flanke erkannt wird.&lt;br /&gt;
:Das Global Enable Interrupt Flag muss selbstverständlich auch gesetzt sein.&lt;br /&gt;
:Der Interrupt wird auch ausgelöst, wenn der Pin als Ausgang geschaltet ist. Auf diese Weise bietet sich die Möglichkeit, Software-Interrupts zu realisieren.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;INT0&#039;&#039;&#039; (External &#039;&#039;&#039;Int&#039;&#039;&#039;errupt Request &#039;&#039;&#039;0&#039;&#039;&#039; Enable)&lt;br /&gt;
:Wenn dieses Bit gesetzt ist, wird ein Interrupt ausgelöst, wenn am &#039;&#039;&#039;INT0&#039;&#039;&#039;-Pin eine steigende oder fallende (je nach Konfiguration im &#039;&#039;&#039;MCUCR&#039;&#039;&#039;) Flanke erkannt wird.&lt;br /&gt;
:Das Global Enable Interrupt Flag muss selbstverständlich auch gesetzt sein.&lt;br /&gt;
:Der Interrupt wird auch ausgelöst, wenn der Pin als Ausgang geschaltet ist. Auf diese Weise bietet sich die Möglichkeit, Software-Interrupts zu realisieren.&lt;br /&gt;
&lt;br /&gt;
|- &lt;br /&gt;
| &#039;&#039;&#039;GIFR&#039;&#039;&#039;&lt;br /&gt;
| &#039;&#039;&#039;G&#039;&#039;&#039;eneral &#039;&#039;&#039;I&#039;&#039;&#039;nterrupt &#039;&#039;&#039;F&#039;&#039;&#039;lag &#039;&#039;&#039;R&#039;&#039;&#039;egister.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! Bit&lt;br /&gt;
| 7 || 6 || 5 || 4 || 3 || 2 || 1 || 0&lt;br /&gt;
|- &lt;br /&gt;
! Name&lt;br /&gt;
| &#039;&#039;&#039;INTF1&#039;&#039;&#039; || &#039;&#039;&#039;INTF0&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039;&lt;br /&gt;
|- &lt;br /&gt;
! R/W&lt;br /&gt;
| R/W || R/W || R || R || R || R || R || R&lt;br /&gt;
|- &lt;br /&gt;
! Initialwert&lt;br /&gt;
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;INTF1&#039;&#039;&#039; (External &#039;&#039;&#039;Int&#039;&#039;&#039;errupt Flag &#039;&#039;&#039;1&#039;&#039;&#039;)&lt;br /&gt;
:Dieses Bit wird gesetzt, wenn am &#039;&#039;&#039;INT1&#039;&#039;&#039;-Pin eine Interrupt-Kondition, entsprechend der Konfiguration, erkannt wird. Wenn das Global Enable Interrupt Flag gesetzt ist, wird die Interruptroutine angesprungen.&lt;br /&gt;
:Das Flag wird automatisch gelöscht, wenn die Interruptroutine beendet ist. Alternativ kann das Flag gelöscht werden, indem der Wert &#039;&#039;&#039;1(!)&#039;&#039;&#039; eingeschrieben wird.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;INTF0&#039;&#039;&#039; (External &#039;&#039;&#039;Int&#039;&#039;&#039;errupt Flag &#039;&#039;&#039;0&#039;&#039;&#039;)&lt;br /&gt;
:Dieses Bit wird gesetzt, wenn am &#039;&#039;&#039;INT0&#039;&#039;&#039;-Pin eine Interrupt-Kondition, entsprechend der Konfiguration, erkannt wird. Wenn das Global Enable Interrupt Flag gesetzt ist, wird die Interruptroutine angesprungen.&lt;br /&gt;
:Das Flag wird automatisch gelöscht, wenn die Interruptroutine beendet ist. Alternativ kann das Flag gelöscht werden, indem der Wert &#039;&#039;&#039;1(!)&#039;&#039;&#039; eingeschrieben wird.&lt;br /&gt;
|- &lt;br /&gt;
| &#039;&#039;&#039;MCUCR&#039;&#039;&#039;&lt;br /&gt;
| &#039;&#039;&#039;MCU&#039;&#039;&#039; &#039;&#039;&#039;C&#039;&#039;&#039;ontrol &#039;&#039;&#039;R&#039;&#039;&#039;egister.&lt;br /&gt;
&lt;br /&gt;
Das MCU Control Register enthält Kontrollbits für allgemeine&lt;br /&gt;
MCU-Funktionen.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! Bit&lt;br /&gt;
| 7 || 6 || 5 || 4 || 3 || 2 || 1 || 0&lt;br /&gt;
|- &lt;br /&gt;
! Name&lt;br /&gt;
| &#039;&#039;&#039;-&#039;&#039;&#039;|| &#039;&#039;&#039;-&#039;&#039;&#039;|| &#039;&#039;&#039;SE&#039;&#039;&#039;|| &#039;&#039;&#039;SM&#039;&#039;&#039;|| &#039;&#039;&#039;ISC11&#039;&#039;&#039;|| &#039;&#039;&#039;ISC10&#039;&#039;&#039;|| &#039;&#039;&#039;ISC01&#039;&#039;&#039;|| &#039;&#039;&#039;ISC00&#039;&#039;&#039;&lt;br /&gt;
|- &lt;br /&gt;
! R/W&lt;br /&gt;
| R || R || R/W || R/W || R/W || R/W || R/W || R/W&lt;br /&gt;
|- &lt;br /&gt;
! Initialwert&lt;br /&gt;
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;SE&#039;&#039;&#039; (&#039;&#039;&#039;S&#039;&#039;&#039;leep &#039;&#039;&#039;E&#039;&#039;&#039;nable)&lt;br /&gt;
:Dieses Bit muss gesetzt sein, um den Controller mit dem &#039;&#039;&#039;SLEEP&#039;&#039;&#039;-Befehl in den Schlafzustand versetzen zu können.&lt;br /&gt;
:Um den Schlafmodus nicht irrtümlich einzuschalten, wird empfohlen, das Bit erst unmittelbar vor Ausführung des &#039;&#039;&#039;SLEEP&#039;&#039;&#039;-Befehls zu setzen.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;SM&#039;&#039;&#039; (&#039;&#039;&#039;S&#039;&#039;&#039;leep &#039;&#039;&#039;M&#039;&#039;&#039;ode)&lt;br /&gt;
:Dieses Bit bestimmt der Schlafmodus.&lt;br /&gt;
:Ist das Bit gelöscht, so wird der &#039;&#039;&#039;Idle&#039;&#039;&#039;-Modus ausgeführt. Ist das Bit gesetzt, so wird der &#039;&#039;&#039;Power-Down&#039;&#039;&#039;-Modus ausgeführt. (für andere AVR Controller siehe Abschnitt &amp;quot;Sleep-Mode&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ISC11&#039;&#039;&#039;, &#039;&#039;&#039;ISC10&#039;&#039;&#039; (&#039;&#039;&#039;I&#039;&#039;&#039;nterrupt &#039;&#039;&#039;S&#039;&#039;&#039;ense &#039;&#039;&#039;C&#039;&#039;&#039;ontrol &#039;&#039;&#039;1&#039;&#039;&#039; Bits)&lt;br /&gt;
:Diese beiden Bits bestimmen, ob die steigende oder die fallende Flanke für die Interrupterkennung am &#039;&#039;&#039;INT1&#039;&#039;&#039;-Pin ausgewertet wird.&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! ISC11 || ISC10 || Bedeutung&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| Low Level an &#039;&#039;&#039;INT1&#039;&#039;&#039; erzeugt einen Interrupt.&lt;br /&gt;
&lt;br /&gt;
Der Interrupt wird getriggert, solange der Pin auf 0 bleibt.&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| Reserviert&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| Die fallende Flanke an &#039;&#039;&#039;INT1&#039;&#039;&#039; erzeugt einen Interrupt.&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| Die steigende Flanke an &#039;&#039;&#039;INT1&#039;&#039;&#039; erzeugt einen Interrupt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ISC01&#039;&#039;&#039;, &#039;&#039;&#039;ISC00&#039;&#039;&#039; (&#039;&#039;&#039;I&#039;&#039;&#039;nterrupt &#039;&#039;&#039;S&#039;&#039;&#039;ense &#039;&#039;&#039;C&#039;&#039;&#039;ontrol &#039;&#039;&#039;0&#039;&#039;&#039; Bits)&lt;br /&gt;
:Diese beiden Bits bestimmen, ob die steigende oder die fallende Flanke für die Interrupterkennung am &#039;&#039;&#039;INT0&#039;&#039;&#039;-Pin ausgewertet wird.&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! ISC01 || ISC00 || Bedeutung&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| Low Level an &#039;&#039;&#039;INT0&#039;&#039;&#039; erzeugt einen Interrupt.&lt;br /&gt;
&lt;br /&gt;
Der Interrupt wird getriggert, solange der Pin auf 0 bleibt.&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| Reserviert&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| Die fallende Flanke an &#039;&#039;&#039;INT0&#039;&#039;&#039; erzeugt einen Interrupt.&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| Die steigende Flanke an &#039;&#039;&#039;INT0&#039;&#039;&#039; erzeugt einen Interrupt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Allgemeines über die Interrupt-Abarbeitung ==&lt;br /&gt;
&lt;br /&gt;
Wenn ein Interrupt eintrifft, wird automatisch das &#039;&#039;&#039;Global Interrupt Enable&#039;&#039;&#039; Bit im Status Register &#039;&#039;&#039;SREG&#039;&#039;&#039; gelöscht und alle weiteren Interrupts unterbunden. Obwohl es möglich ist, zu diesem Zeitpunkt bereits wieder das GIE-bit zu setzen, wird dringend davon abgeraten. Dieses wird nämlich automatisch gesetzt, wenn die Interruptroutine beendet wird. Wenn in der Zwischenzeit weitere Interrupts eintreffen, werden die zugehörigen Interrupt-Bits gesetzt und die Interrupts bei Beendigung der laufenden Interrupt-Routine in der Reihenfolge ihrer Priorität ausgeführt. Dies kann&lt;br /&gt;
eigentlich nur dann zu Problemen führen, wenn ein hoch priorisierter Interrupt ständig und in kurzer Folge auftritt. Dieser sperrt dann möglicherweise alle anderen Interrupts mit niedrigerer Priorität. Dies ist einer der Gründe, weshalb die Interrupt-Routinen sehr kurz gehalten werden sollen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- === Das Status-Register ===&lt;br /&gt;
&lt;br /&gt;
Es gilt auch zu beachten, dass das Status-Register während der Abarbeitung einer Interruptroutine nicht automatisch gesichert wird. Falls notwendig, muss dies vom Programmierer selber vorgesehen werden. --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Interrupts mit dem AVR GCC Compiler (WinAVR) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Selbstverständlich können alle interruptspezifischen Registerzugriffe wie gewohnt über I/O-Adressierung vorgenommen werden. Etwas einfacher geht es jedoch, wenn wir die vom Compiler zur Verfügung gestellten Mittel einsetzen.--&amp;gt;&lt;br /&gt;
Funktionen zur Interrupt-Verarbeitung werden in den Includedateien &#039;&#039;interrupt.h&#039;&#039;  der avr-libc zur Verfügung gestellt (bei älterem Quellcode zusätzlich &#039;&#039;signal.h&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
// fuer sei(), cli() und ISR():&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Makro &#039;&#039;&#039;sei()&#039;&#039;&#039; schaltet die Interrupts ein. Eigentlich wird nichts anderes gemacht, als das &#039;&#039;&#039;Global Interrupt Enable&#039;&#039;&#039; Bit im Status Register gesetzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
    sei();&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Makro &#039;&#039;&#039;cli()&#039;&#039;&#039; schaltet die Interrupts aus, oder anders gesagt, das &#039;&#039;&#039;Global Interrupt Enable&#039;&#039;&#039; Bit im Status Register wird gelöscht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
    cli();&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Oft steht man vor der Aufgabe, dass eine Codesequenz nicht unterbrochen werden darf. Es liegt dann nahe, zu Beginn dieser Sequenz ein cli() und am Ende ein sei() einzufügen. Dies ist jedoch ungünstig, wenn die Interrupts vor Aufruf der Sequenz deaktiviert waren und danach auch weiterhin deaktiviert bleiben sollen. Ein sei() würde ungeachtet des vorherigen  Zustands die Interrupts aktivieren, was zu unerwünschten Seiteneffekten führen kann. Die aus dem folgenden Beispiel ersichtliche Vorgehensweise ist in solchen Fällen vorzuziehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
#include &amp;lt;inttypes.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
//...&lt;br /&gt;
&lt;br /&gt;
void NichtUnterbrechenBitte(void)&lt;br /&gt;
{&lt;br /&gt;
   uint8_t tmp_sreg;  // temporaerer Speicher fuer das Statusregister&lt;br /&gt;
&lt;br /&gt;
   tmp_sreg = SREG;   // Statusregister (also auch das I-Flag darin) sichern&lt;br /&gt;
   cli();             // Interrupts global deaktivieren&lt;br /&gt;
&lt;br /&gt;
   /* hier &amp;quot;unterbrechnungsfreier&amp;quot; Code */&lt;br /&gt;
&lt;br /&gt;
   /* Beispiel Anfang&lt;br /&gt;
     JTAG-Interface eines ATmega16 per Software deaktivieren &lt;br /&gt;
     und damit die JTAG-Pins an PORTC für &amp;quot;general I/O&amp;quot; nutzbar machen&lt;br /&gt;
     ohne die JTAG-Fuse-Bit zu aendern. Dazu ist eine &amp;quot;timed sequence&amp;quot;&lt;br /&gt;
     einzuhalten (vgl Datenblatt ATmega16, Stand 10/04, S. 229): &lt;br /&gt;
     Das JTD-Bit muss zweimal innerhalb von 4 Taktzyklen geschrieben &lt;br /&gt;
     werden. Ein Interrupt zwischen den beiden Schreibzugriffen wuerde &lt;br /&gt;
     die erforderliche Sequenz &amp;quot;brechen&amp;quot;, das JTAG-Interface bliebe&lt;br /&gt;
     weiterhin aktiv und die IO-Pins weiterhin für JTAG reserviert. */&lt;br /&gt;
&lt;br /&gt;
   MCUCSR |= (1&amp;lt;&amp;lt;JTD);&lt;br /&gt;
   MCUCSR |= (1&amp;lt;&amp;lt;JTD); // 2 mal in Folge ,vgl. Datenblatt fuer mehr Information&lt;br /&gt;
&lt;br /&gt;
   /* Beispiel Ende */&lt;br /&gt;
  &lt;br /&gt;
   SREG = tmp_sreg;     // Status-Register wieder herstellen &lt;br /&gt;
                      // somit auch das I-Flag auf gesicherten Zustand setzen&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void NichtSoGut(void)&lt;br /&gt;
{&lt;br /&gt;
   cli();&lt;br /&gt;
   &lt;br /&gt;
   /* hier &amp;quot;unterbrechnungsfreier&amp;quot; Code */&lt;br /&gt;
   &lt;br /&gt;
   sei();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
   //...&lt;br /&gt;
&lt;br /&gt;
   cli();  &lt;br /&gt;
   // Interrupts global deaktiviert &lt;br /&gt;
&lt;br /&gt;
   NichtUnterbrechenBitte();&lt;br /&gt;
   // auch nach Aufruf der Funktion deaktiviert&lt;br /&gt;
&lt;br /&gt;
   sei();&lt;br /&gt;
   // Interrupts global aktiviert &lt;br /&gt;
&lt;br /&gt;
   NichtUnterbrechenBitte();&lt;br /&gt;
   // weiterhin aktiviert&lt;br /&gt;
   //...&lt;br /&gt;
&lt;br /&gt;
   /* Verdeutlichung der unguenstigen Vorgehensweise mit cli/sei: */&lt;br /&gt;
   cli();  &lt;br /&gt;
   // Interrupts jetzt global deaktiviert &lt;br /&gt;
&lt;br /&gt;
   NichtSoGut();&lt;br /&gt;
   // nach Aufruf der Funktion sind Interrupts global aktiviert &lt;br /&gt;
   // dies ist mglw. ungewollt!&lt;br /&gt;
   //...&lt;br /&gt;
   &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- mt: besser so nicht(?), lieber &amp;quot;datenblattkonform&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;font face=&amp;quot;Courier New&amp;quot;&amp;gt;&#039;&#039;&#039;timer_enable_int (unsigned char ints);&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;/font&amp;gt;Schaltet Timerbezogene Interrupts ein bzw. aus.&amp;lt;br /&amp;gt;&lt;br /&gt;
Wenn als Argument &#039;&#039;&#039;ints&#039;&#039;&#039; der Wert 0 übergeben wird so werden alle&lt;br /&gt;
Timerinterrupts ausgeschaltet, ansonsten muss in &#039;&#039;&#039;ints&#039;&#039;&#039; angegeben werden,&lt;br /&gt;
welche Interrupts zu aktivieren sind. Dabei müssen einfach die entsprechend zu&lt;br /&gt;
setzenden Bits definiert werden.&amp;lt;br /&amp;gt;&lt;br /&gt;
Beispiel: &#039;&#039;&#039;&amp;lt;font face=&amp;quot;Courier New&amp;quot;&amp;gt;timer_enable_int (1 &amp;lt;&amp;lt; TOIE1));&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;/font&amp;gt;&#039;&#039;&#039;Achtung: Wenn ein Timerinterrupt eingeschaltet wird während ein&lt;br /&gt;
anderer Timerinterrupt bereits läuft, dann müssen beide Bits angegeben werden&lt;br /&gt;
sonst wird der andere Timerinterrupt versehentlich ausgeschaltet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;font face=&amp;quot;Courier New&amp;quot;&amp;gt;&#039;&#039;&#039;enable_external_int (unsigned char ints);&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;/font&amp;gt;Schaltet die externen Interrupts ein bzw. aus.&amp;lt;br /&amp;gt;&lt;br /&gt;
Wenn als Argument &#039;&#039;&#039;ints&#039;&#039;&#039; der Wert 0 übergeben wird so werden alle externen&lt;br /&gt;
Interrrups ausgeschaltet, ansonsten muss in &#039;&#039;&#039;ints&#039;&#039;&#039; angegeben werden, welche&lt;br /&gt;
Interrupts zu aktivieren sind. Dabei müssen einfach die entsprechend zu&lt;br /&gt;
setzenden Bits definiert werden.&amp;lt;br /&amp;gt;&lt;br /&gt;
Beispiel: &#039;&#039;&#039;&amp;lt;font face=&amp;quot;Courier New&amp;quot;&amp;gt;enable_external_int ((1&amp;lt;&lt;br /&gt;
&amp;lt;/font&amp;gt;&#039;&#039;&#039;Schaltet die externen Interrupts 0 und 1 ein.&lt;br /&gt;
&lt;br /&gt;
Nachdem nun die Interrupts aktiviert sind, braucht es selbstverständlich noch den auszuführenden Code, der ablaufen soll, wenn ein Interrupt eintrifft.&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
Zu den aktivierten Interrupts ist eine Funktion zu programmieren, deren Code aufgerufen wird, wenn der betreffende Interrupt auftritt (Interrupt-Handler, Interrupt-Service-Routine). Dazu existiert die Definition (ein Makro) &#039;&#039;&#039;ISR&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== ISR ===&lt;br /&gt;
&lt;br /&gt;
(&#039;&#039;ISR()&#039;&#039; ersetzt bei neueren Versionen der avr-libc &#039;&#039;SIGNAL()&#039;&#039;. SIGNAL sollte nicht mehr genutzt werden, zur Portierung von SIGNAL nach ISR siehe den [[AVR-GCC-Tutorial#Anhang|Anhang]].)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
//...&lt;br /&gt;
ISR(Vectorname) /* vormals: SIGNAL(siglabel) dabei Vectorname != siglabel ! */&lt;br /&gt;
{&lt;br /&gt;
    /* Interrupt Code */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;ISR&#039;&#039; wird eine Funktion für die Bearbeitung eines Interrupts eingeleitet. Als Argument muss dabei die Benennung des entsprechenden Interruptvektors angegeben werden. Diese sind in den jeweiligen Includedateien IOxxxx.h zu finden. Die Bezeichnung entspricht dem Namen aus dem Datenblatt, bei dem die Leerzeichen durch Unterstriche ersetzt sind und ein &#039;&#039;_vect&#039;&#039; angehängt ist.&lt;br /&gt;
&lt;br /&gt;
Als Beispiel ein Ausschnitt aus der Datei für den ATmega8 (bei WinAVR Standardinstallation in C:\WinAVR\avr\include\avr\iom8.h) in der neben den aktuellen Namen für &#039;&#039;ISR&#039;&#039; (*_vect) noch die Bezeichnungen für das inzwischen nicht mehr aktuelle &#039;&#039;SIGNAL&#039;&#039; (SIG_*) enthalten sind.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
//...&lt;br /&gt;
/* $Id: iom8.h,v 1.13 2005/10/30 22:11:23 joerg_wunsch Exp $ */&lt;br /&gt;
&lt;br /&gt;
/* avr/iom8.h - definitions for ATmega8 */&lt;br /&gt;
//...&lt;br /&gt;
&lt;br /&gt;
/* Interrupt vectors */&lt;br /&gt;
&lt;br /&gt;
/* External Interrupt Request 0 */&lt;br /&gt;
#define INT0_vect                       _VECTOR(1)&lt;br /&gt;
#define SIG_INTERRUPT0                  _VECTOR(1)&lt;br /&gt;
&lt;br /&gt;
/* External Interrupt Request 1 */&lt;br /&gt;
#define INT1_vect                       _VECTOR(2)&lt;br /&gt;
#define SIG_INTERRUPT1                  _VECTOR(2)&lt;br /&gt;
&lt;br /&gt;
/* Timer/Counter2 Compare Match */&lt;br /&gt;
#define TIMER2_COMP_vect                _VECTOR(3)&lt;br /&gt;
#define SIG_OUTPUT_COMPARE2             _VECTOR(3)&lt;br /&gt;
&lt;br /&gt;
/* Timer/Counter2 Overflow */&lt;br /&gt;
#define TIMER2_OVF_vect                 _VECTOR(4)&lt;br /&gt;
#define SIG_OVERFLOW2                   _VECTOR(4)&lt;br /&gt;
&lt;br /&gt;
/* Timer/Counter1 Capture Event */&lt;br /&gt;
#define TIMER1_CAPT_vect                _VECTOR(5)&lt;br /&gt;
#define SIG_INPUT_CAPTURE1              _VECTOR(5)&lt;br /&gt;
&lt;br /&gt;
/* Timer/Counter1 Compare Match A */&lt;br /&gt;
#define TIMER1_COMPA_vect               _VECTOR(6)&lt;br /&gt;
#define SIG_OUTPUT_COMPARE1A            _VECTOR(6)&lt;br /&gt;
&lt;br /&gt;
/* Timer/Counter1 Compare Match B */&lt;br /&gt;
#define TIMER1_COMPB_vect               _VECTOR(7)&lt;br /&gt;
#define SIG_OUTPUT_COMPARE1B            _VECTOR(7)&lt;br /&gt;
&lt;br /&gt;
//...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--Vor Nutzung von SIGNAL muss ebenfalls die Header-Datei signal.h eingebunden werden.--&amp;gt; &lt;br /&gt;
Mögliche Funktionsrümpfe für Interruptfunktionen sind zum Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
/* veraltet: #include &amp;lt;avr/signal.h&amp;gt; */&lt;br /&gt;
&lt;br /&gt;
ISR(INT0_vect)       /* veraltet: SIGNAL(SIG_INTERRUPT0) */&lt;br /&gt;
{&lt;br /&gt;
    /* Interrupt Code */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER0_OVF_vect) /* veraltet: SIGNAL(SIG_OVERFLOW0) */&lt;br /&gt;
{&lt;br /&gt;
    /* Interrupt Code */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
ISR(USART_RXC_vect) /* veraltet: SIGNAL(SIG_UART_RECV) */&lt;br /&gt;
{&lt;br /&gt;
    /* Interrupt Code */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// und so weiter und so fort...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auf die korrekte Schreibweise der Vektorbezeichnung ist zu achten. Der gcc-Compiler prüft erst ab Version 4.x, ob ein Signal/Interrupt der angegebenen Bezeichnung tatsächlich in der Includedatei definiert ist und gibt andernfalls eine Warnung aus. Bei WinAVR (ab 2/2005) wurde die Überprüfung auch in den mitgelieferten Compiler der Version 3.x integriert. Aus dem gcc-Quellcode Version 3.x selbst erstellte Compiler enthalten die Prüfung nicht (vgl. [[AVR-GCC]]). &lt;br /&gt;
&lt;br /&gt;
Während der Ausführung der Funktion sind alle weiteren Interrupts automatisch gesperrt. Beim Verlassen der Funktion werden die Interrupts wieder zugelassen.&lt;br /&gt;
&lt;br /&gt;
Sollte während der Abarbeitung der Interruptroutine ein weiterer Interrupt (gleiche oder andere Interruptquelle) auftreten, so wird das entsprechende Bit im zugeordneten Interrupt Flag Register gesetzt und die entsprechende Interruptroutine automatisch nach dem Beenden der aktuellen Funktion aufgerufen.&lt;br /&gt;
&lt;br /&gt;
Ein Problem ergibt sich eigentlich nur dann, wenn während der Abarbeitung der aktuellen Interruptroutine mehrere gleichartige Interrupts auftreten. Die entsprechende Interruptroutine wird im Nachhinein zwar aufgerufen jedoch wissen wir nicht, ob nun der entsprechende Interrupt einmal, zweimal oder gar noch öfter aufgetreten ist. Deshalb soll hier noch einmal betont werden, dass Interruptroutinen so schnell wie nur irgend möglich wieder verlassen werden sollten.&lt;br /&gt;
&lt;br /&gt;
=== Unterbrechbare Interruptroutinen ===&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Faustregel&amp;quot;: im Zweifel &#039;&#039;&#039;ISR&#039;&#039;&#039;. Die nachfolgend beschriebene Methode nur dann verwenden, wenn man sich über die unterschiedliche Funktionsweise im Klaren ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ISR(XXX,ISR_NOBLOCK) /* veraltet: INTERRUPT(SIG_OVERFLOW0) */&lt;br /&gt;
{&lt;br /&gt;
    /* Interrupt-Code */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hierbei steht XXX für den oben beschriebenen Namen des Vektors (also z.&amp;amp;nbsp;B. &#039;&#039;TIMER0_OVF_vect&#039;&#039;). Der Unterschied im Vergleich zu einer herkömmlichen ISR ist, dass hier beim Aufrufen der Funktion das &#039;&#039;&#039;Global Enable Interrupt&#039;&#039;&#039; Bit durch Einfügen einer SEI-Anweisung direkt wieder gesetzt und somit alle Interrupts zugelassen werden &amp;amp;ndash; auch XXX-Interrupts. &lt;br /&gt;
&lt;br /&gt;
Bei unsachgemässer Handhabung kann dies zu erheblichen Problemen wie einem Stack-Overflow oder anderen unerwarteten Effekten führen und sollte wirklich nur dann eingesetzt werden, wenn man sich sicher ist, das Ganze auch im Griff zu haben.&lt;br /&gt;
&lt;br /&gt;
Insbesondere sollte möglichst am ISR-Anfang die auslösende IRQ-Quelle deaktiviert und erst am Ende der ISR wieder aktiviert werden. Robuster als die Verwendung einer NOBLOCK-ISR ist daher folgender ISR-Aufbau:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ISR (XXX) &lt;br /&gt;
{&lt;br /&gt;
    // Implementiere die ISR ohne zunaechst weitere IRQs zuzulassen&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;&amp;lt;Dektiviere die XXX-IRQ&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    // Erlaube alle Interrupts (ausser XXX)&lt;br /&gt;
    sei();&lt;br /&gt;
&lt;br /&gt;
    //... Code ...&lt;br /&gt;
&lt;br /&gt;
    // IRQs global deaktivieren um die XXX-IRQ wieder gefahrlos &lt;br /&gt;
    // aktivieren zu koennen&lt;br /&gt;
    cli();&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;&amp;lt;Aktiviere die XXX-IRQ&amp;gt;&amp;gt;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
Auf diese Weise kann sich die XXX-IRQ nicht selbst unterbrechen, was zu einer Art Endlosschleife führen würde.&lt;br /&gt;
&lt;br /&gt;
Siehe auch: Hinweise in [[AVR-GCC]]&lt;br /&gt;
&lt;br /&gt;
siehe dazu: http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html&lt;br /&gt;
&lt;br /&gt;
== Datenaustausch mit Interrupt-Routinen ==&lt;br /&gt;
&lt;br /&gt;
Variablen, die sowohl in Interrupt-Routinen (ISR = Interrupt Service Routine(s)) als auch vom übrigen Programmcode geschrieben oder gelesen werden, müssen mit einem &#039;&#039;&#039;volatile&#039;&#039;&#039; deklariert werden. Damit wird dem Compiler mitgeteilt, dass der Inhalt der Variablen vor jedem Lesezugriff aus dem Speicher gelesen und nach jedem Schreibzugriff in den Speicher geschrieben wird. Ansonsten könnte der Compiler den Code so optimieren, dass der Wert der Variablen nur in Prozessorregistern zwischengespeichert wird, die nichts von der Änderung woanders mitbekommen.&lt;br /&gt;
&lt;br /&gt;
Zur Veranschaulichung ein Codefragment für eine Tastenentprellung mit Erkennung einer &amp;quot;lange gedrückten&amp;quot; Taste.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
//...&lt;br /&gt;
&lt;br /&gt;
// Schwellwerte&lt;br /&gt;
// Entprellung: &lt;br /&gt;
#define CNTDEBOUNCE 10&lt;br /&gt;
// &amp;quot;lange gedrueckt:&amp;quot;&lt;br /&gt;
#define CNTREPEAT 200&lt;br /&gt;
&lt;br /&gt;
// hier z.&amp;amp;nbsp;B. Taste an Pin2 PortA &amp;quot;active low&amp;quot; = 0 wenn gedrueckt&lt;br /&gt;
#define KEY_PIN  PINA&lt;br /&gt;
#define KEY_PINNO PA2&lt;br /&gt;
&lt;br /&gt;
// beachte: volatile! &lt;br /&gt;
volatile uint8_t gKeyCounter;&lt;br /&gt;
&lt;br /&gt;
// Timer-Compare Interrupt ISR, wird z.B. alle 10ms ausgefuehrt&lt;br /&gt;
ISR(TIMER1_COMPA_vect)&lt;br /&gt;
{&lt;br /&gt;
   // hier wird gKeyCounter veraendert. Die übrigen&lt;br /&gt;
   // Programmteile müssen diese Aenderung &amp;quot;sehen&amp;quot;:&lt;br /&gt;
   // volatile -&amp;gt; aktuellen Wert immer in den Speicher schreiben&lt;br /&gt;
   if ( !(KEY_PIN &amp;amp; (1&amp;lt;&amp;lt;KEY_PINNO)) ) {&lt;br /&gt;
      if (gKeyCounter &amp;lt; CNTREPEAT) gKeyCounter++;&lt;br /&gt;
   }&lt;br /&gt;
   else {&lt;br /&gt;
      gKeyCounter = 0;&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//...&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
//...&lt;br /&gt;
    /* hier: Initialisierung der Ports und des Timer-Interrupts */&lt;br /&gt;
//... &lt;br /&gt;
   // hier wird auf gKeyCounter zugegriffen. Dazu muss der in der&lt;br /&gt;
   // ISR geschriebene Wert bekannt sein:&lt;br /&gt;
   // volatile -&amp;gt; aktuellen Wert immer aus dem Speicher lesen&lt;br /&gt;
   if ( gKeyCounter &amp;gt; CNTDEBOUNCE ) { // Taste mind. 10*10 ms &amp;quot;prellfrei&amp;quot;&lt;br /&gt;
       if (gKeyCounter == CNTREPEAT) {&lt;br /&gt;
          /* hier: Code fuer &amp;quot;Taste lange gedrueckt&amp;quot; */&lt;br /&gt;
       }&lt;br /&gt;
       else {&lt;br /&gt;
          /* hier: Code fuer &amp;quot;Taste kurz gedrueckt&amp;quot; */&lt;br /&gt;
       }&lt;br /&gt;
   }&lt;br /&gt;
//...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wird innerhalb einer ISR mehrfach auf eine mit volatile deklarierte Variable zugegriffen, wirkt sich dies ungünstig auf die Verarbeitungsgeschwindigkeit aus, da bei jedem Zugriff mit dem Speicherinhalt abgeglichen wird. Da bei AVR-Controllern &#039;&#039;innerhalb&#039;&#039; einer ISR keine Unterbrechungen zu erwarten sind, bietet es sich an, einen Zwischenspeicher in Form einer lokalen Variable zu verwenden, deren Inhalt zu Beginn und am Ende mit dem der volatile Variable synchronisiert wird. Lokale Variable werden bei eingeschalteter Optimierung mit hoher Wahrscheinlichkeit in Prozessorregistern verwaltet und der Zugriff darauf ist daher nur mit wenigen internen Operationen verbunden. Die ISR aus dem vorherigen Beispiel lässt sich so optimieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
//...&lt;br /&gt;
ISR(TIMER1_COMPA_vect)&lt;br /&gt;
{&lt;br /&gt;
   uint8_t tmp_kc;&lt;br /&gt;
&lt;br /&gt;
   tmp_kc = gKeyCounter; // Uebernahme in lokale Arbeitsvariable&lt;br /&gt;
&lt;br /&gt;
   if ( !(KEY_PIN &amp;amp; (1&amp;lt;&amp;lt;KEY_PINNO)) ) {&lt;br /&gt;
      if (tmp_kc &amp;lt; CNTREPEAT) {&lt;br /&gt;
         tmp_kc++;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
   else {&lt;br /&gt;
      tmp_kc = 0;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   gKeyCounter = tmp_kc; // Zurueckschreiben&lt;br /&gt;
}&lt;br /&gt;
//...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zum Vergleich die Disassemblies (Ausschnitte der &amp;quot;lss-Dateien&amp;quot;, compiliert für ATmega162) im Anschluss. Man erkennt den viermaligen Zugriff auf die Speicheraddresse von &#039;&#039;gKeyCounter&#039;&#039; (hier 0x032A) in der ISR ohne &amp;quot;Cache&amp;quot;-Variable und den zweimaligen Zugriff in der Variante mit Zwischenspeicher. Im Beispiel ist der Vorteil gering, bei komplexeren Routinen kann die Zwischenspeicherung in lokalen Variablen jedoch zu deutlicheren Verbesserungen führen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ISR(TIMER1_COMPA_vect)&lt;br /&gt;
{&lt;br /&gt;
     86a:	1f 92       	push	r1&lt;br /&gt;
     86c:	0f 92       	push	r0&lt;br /&gt;
     86e:	0f b6       	in	r0, 0x3f	; 63&lt;br /&gt;
     870:	0f 92       	push	r0&lt;br /&gt;
     872:	11 24       	eor	r1, r1&lt;br /&gt;
     874:	8f 93       	push	r24&lt;br /&gt;
    if ( !(KEY_PIN &amp;amp; (1&amp;lt;&amp;lt;KEY_PINNO)) ) {&lt;br /&gt;
     876:	ca 99       	sbic	0x19, 2	; 25&lt;br /&gt;
     878:	0a c0       	rjmp	.+20     	; 0x88e &amp;lt;__vector_13+0x24&amp;gt;&lt;br /&gt;
      if (gKeyCounter &amp;lt; CNTREPEAT) gKeyCounter++;&lt;br /&gt;
     87a:	80 91 2a 03 	lds	r24, 0x032A&lt;br /&gt;
     87e:	88 3c       	cpi	r24, 0xC8	; 200 &lt;br /&gt;
     880:	40 f4       	brcc	.+16     	; 0x892 &amp;lt;__vector_13+0x28&amp;gt;&lt;br /&gt;
     882:	80 91 2a 03 	lds	r24, 0x032A&lt;br /&gt;
     886:	8f 5f       	subi	r24, 0xFF	; 255&lt;br /&gt;
     888:	80 93 2a 03 	sts	0x032A, r24&lt;br /&gt;
     88c:	02 c0       	rjmp	.+4      	; 0x892 &amp;lt;__vector_13+0x28&amp;gt;&lt;br /&gt;
   }&lt;br /&gt;
   else {&lt;br /&gt;
      gKeyCounter = 0;&lt;br /&gt;
     88e:	10 92 2a 03 	sts	0x032A, r1&lt;br /&gt;
     892:	8f 91       	pop	r24&lt;br /&gt;
     894:	0f 90       	pop	r0&lt;br /&gt;
     896:	0f be       	out	0x3f, r0	; 63&lt;br /&gt;
     898:	0f 90       	pop	r0&lt;br /&gt;
     89a:	1f 90       	pop	r1&lt;br /&gt;
     89c:	18 95       	reti&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ISR(TIMER1_COMPA_vect)&lt;br /&gt;
{&lt;br /&gt;
     86a:	1f 92       	push	r1&lt;br /&gt;
     86c:	0f 92       	push	r0&lt;br /&gt;
     86e:	0f b6       	in	r0, 0x3f	; 63&lt;br /&gt;
     870:	0f 92       	push	r0&lt;br /&gt;
     872:	11 24       	eor	r1, r1&lt;br /&gt;
     874:	8f 93       	push	r24&lt;br /&gt;
   uint8_t tmp_kc;&lt;br /&gt;
 &lt;br /&gt;
   tmp_kc = gKeyCounter;&lt;br /&gt;
     876:	80 91 2a 03 	lds	r24, 0x032A&lt;br /&gt;
 &lt;br /&gt;
   if ( !(KEY_PIN &amp;amp; (1&amp;lt;&amp;lt;KEY_PINNO)) ) {&lt;br /&gt;
     87a:	ca 9b       	sbis	0x19, 2	; 25&lt;br /&gt;
     87c:	02 c0       	rjmp	.+4      	; 0x882 &amp;lt;__vector_13+0x18&amp;gt;&lt;br /&gt;
     87e:	80 e0       	ldi	r24, 0x00	; 0&lt;br /&gt;
     880:	03 c0       	rjmp	.+6      	; 0x888 &amp;lt;__vector_13+0x1e&amp;gt;&lt;br /&gt;
      if (tmp_kc &amp;lt; CNTREPEAT) {&lt;br /&gt;
     882:	88 3c       	cpi	r24, 0xC8	; 200&lt;br /&gt;
     884:	08 f4       	brcc	.+2      	; 0x888 &amp;lt;__vector_13+0x1e&amp;gt;&lt;br /&gt;
         tmp_kc++;&lt;br /&gt;
     886:	8f 5f       	subi	r24, 0xFF	; 255&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
   else {&lt;br /&gt;
      tmp_kc = 0;&lt;br /&gt;
   }&lt;br /&gt;
 &lt;br /&gt;
   gKeyCounter = tmp_kc;&lt;br /&gt;
     888:	80 93 2a 03 	sts	0x032A, r24&lt;br /&gt;
     88c:	8f 91       	pop	r24&lt;br /&gt;
     88e:	0f 90       	pop	r0&lt;br /&gt;
     890:	0f be       	out	0x3f, r0	; 63&lt;br /&gt;
     892:	0f 90       	pop	r0&lt;br /&gt;
     894:	1f 90       	pop	r1&lt;br /&gt;
     896:	18 95       	reti&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== volatile und Pointer ===&lt;br /&gt;
&lt;br /&gt;
Bei &#039;&#039;&#039;volatile&#039;&#039;&#039; in Verbindung mit Pointern ist zu beachten, ob der Pointer selbst oder die Variable, auf die der Pointer zeigt, &#039;&#039;&#039;volatile&#039;&#039;&#039; ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
volatile uint8_t *a;   // das Ziel von a ist volatile&lt;br /&gt;
&lt;br /&gt;
uint8_t *volatile a;   // a selbst ist volatile&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Falls der Pointer volatile ist (zweiter Fall im Beispiel), ist zu beachten, dass der Wert des Pointers, also eine Speicheradresse, intern in mehr als einem Byte verwaltet wird. Lese- und Schreibzugriffe im Hauptprogramm (außerhalb von Interrupt-Routinen) sind daher so zu implementieren, dass alle Teilbytes der Adresse konsistent bleiben, vgl. dazu den folgenden Abschnitt.&lt;br /&gt;
&lt;br /&gt;
=== Variablen größer 1 Byte ===&lt;br /&gt;
&lt;br /&gt;
Bei Variablen größer ein Byte, auf die in Interrupt-Routinen und im Hauptprogramm zugegriffen wird, muss darauf geachtet werden, dass die Zugriffe auf die einzelnen Bytes außerhalb der ISR nicht durch einen Interrupt unterbrochen werden. (Allgemeinplatz: AVRs sind 8-bit Controller). Zur Veranschaulichung ein Codefragment:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
//...&lt;br /&gt;
volatile uint16_t gMyCounter16bit;&lt;br /&gt;
//...&lt;br /&gt;
ISR(...)&lt;br /&gt;
{&lt;br /&gt;
//...&lt;br /&gt;
   gMyCounter16Bit++;&lt;br /&gt;
//...&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
   uint16_t tmpCnt;&lt;br /&gt;
//...&lt;br /&gt;
   // nicht gut: Mglw. hier ein Fehler, wenn ein Byte von MyCounter &lt;br /&gt;
   // schon in tmpCnt kopiert ist aber vor dem Kopieren des zweiten Bytes &lt;br /&gt;
   // ein Interrupt auftritt, der den Inhalt von MyCounter verändert.&lt;br /&gt;
   tmpCnt = gMyCounter16bit; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   // besser: Änderungen &amp;quot;außerhalb&amp;quot; verhindern -&amp;gt; alle &amp;quot;Teilbytes&amp;quot;&lt;br /&gt;
   // bleiben konsistent&lt;br /&gt;
   cli();  // Interrupts deaktivieren&lt;br /&gt;
   tmpCnt = gMyCounter16Bit;&lt;br /&gt;
   sei();  // wieder aktivieren&lt;br /&gt;
&lt;br /&gt;
   // oder: vorheriger Status des globalen Interrupt-Flags bleibt erhalten&lt;br /&gt;
   uint8_t sreg_tmp;&lt;br /&gt;
   sreg_tmp = SREG;    /* Sichern */&lt;br /&gt;
   cli()&lt;br /&gt;
   tmpCnt = gMyCounter16Bit;&lt;br /&gt;
   SREG = sreg_tmp;    /* Wiederherstellen */&lt;br /&gt;
&lt;br /&gt;
   // oder: mehrfach lesen, bis man konsistente Daten hat&lt;br /&gt;
   uint16_t count1 = gMyCounter16Bit;&lt;br /&gt;
   uint16_t count2 = gMyCounter16Bit;&lt;br /&gt;
   while (count1 != count2) {&lt;br /&gt;
       count1 = count2;&lt;br /&gt;
       count2 = gMyCounter16Bit;&lt;br /&gt;
   }&lt;br /&gt;
   tmpCnt = count1;&lt;br /&gt;
//...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die avr-libc bietet ab Version 1.6.0(?) einige Hilfsfunktionen/Makros, mit der im Beispiel oben gezeigten Funktionalität, die zusätzlich auch sogenannte [http://en.wikipedia.org/wiki/Memory_barrier memory barriers] beinhalten. Diese stehen nach #include &amp;lt;util/atomic.h&amp;gt; zur Verfügung.&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
//...&lt;br /&gt;
#include &amp;lt;util/atomic.h&amp;gt;&lt;br /&gt;
//...&lt;br /&gt;
&lt;br /&gt;
    // analog zu cli, Zugriff, sei:&lt;br /&gt;
    ATOMIC_BLOCK(ATOMIC_FORCEON) {&lt;br /&gt;
        tmpCnt = gMyCounter16Bit;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
// oder:&lt;br /&gt;
&lt;br /&gt;
    // analog zu Sicherung des SREG, cli, Zugriff und Zurückschreiben des SREG:&lt;br /&gt;
    ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {&lt;br /&gt;
        tmpCnt = gMyCounter16Bit;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
//...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* siehe auch [http://www.nongnu.org/avr-libc/user-manual/group__util__atomic.html Dokumentation der avr-libc zu atomic.h]&lt;br /&gt;
&lt;br /&gt;
== Interrupt-Routinen und Registerzugriffe ==&lt;br /&gt;
&lt;br /&gt;
Falls Register sowohl im Hauptprogramm als auch in Interrupt-Routinen verändert werden, ist darauf zu achten, dass diese Zugriffe sich nicht überlappen. Nur wenige Anweisungen lassen sich in sogenannte &amp;quot;atomare&amp;quot; Zugriffe übersetzen, die nicht von Interrupt-Routinen unterbrochen werden können. &lt;br /&gt;
&lt;br /&gt;
Zur Veranschaulichung eine Anweisung, bei der ein Bit und im Anschluss drei Bits in einem Register gesetzt werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
//...&lt;br /&gt;
	PORTA |= (1&amp;lt;&amp;lt;PA0);&lt;br /&gt;
	&lt;br /&gt;
	PORTA |= (1&amp;lt;&amp;lt;PA2)|(1&amp;lt;&amp;lt;PA3)|(1&amp;lt;&amp;lt;PA4);&lt;br /&gt;
//...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Compiler übersetzt diese Anweisungen für einen ATmega128 bei Optimierungsstufe &amp;quot;S&amp;quot; nach:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;code&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
        PORTA |= (1&amp;lt;&amp;lt;PA0);&lt;br /&gt;
  d2:	d8 9a       	sbi	0x1b, 0	; 27 (a)&lt;br /&gt;
	&lt;br /&gt;
        PORTA |= (1&amp;lt;&amp;lt;PA2)|(1&amp;lt;&amp;lt;PA3)|(1&amp;lt;&amp;lt;PA4);&lt;br /&gt;
  d4:	8b b3       	in	r24, 0x1b	; 27 (b)&lt;br /&gt;
  d6:	8c 61       	ori	r24, 0x1C	; 28 (c)&lt;br /&gt;
  d8:	8b bb       	out	0x1b, r24	; 27 (d)&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Setzen des einzelnen Bits wird bei eingeschalteter Optimierung für Register im unteren Speicherbereich in eine einzige Assembler-Anweisung (sbi) übersetzt und ist nicht anfällig für Unterbrechungen durch Interrupts. Die Anweisung zum Setzen von drei Bits wird jedoch in drei abhängige Assembler-Anweisungen übersetzt und bietet damit zwei &amp;quot;Angriffspunkte&amp;quot; für Unterbrechungen. Eine Interrupt-Routine könnte nach dem Laden des Ausgangszustands in den Zwischenspeicher (hier Register 24) den Wert des Registers ändern, z.&amp;amp;nbsp;B. ein Bit löschen. Damit würde der Zwischenspeicher nicht mehr mit dem tatsächlichen Zustand übereinstimmen aber dennoch nach der Bitoperation (hier ori) in das Register zurückgeschrieben. &lt;br /&gt;
&lt;br /&gt;
Beispiel: PORTA sei anfangs 0b00000000. Die erste Anweisung (a) setzt Bit 0, PORTA ist danach 0b00000001. Nun wird im ersten Teil der zweiten Anweisung der Portzustand in ein Register eingelesen (b). Unmittelbar darauf (vor (c)) &amp;quot;feuert&amp;quot; ein Interrupt, in dessen Interrupt-Routine Bit 0 von PORTA gelöscht wird. Nach Verlassen der Interrupt-Routine hat PORTA den Wert 0b00000000. In den beiden noch folgenden Anweisungen des Hauptprogramms wird nun der zwischengespeicherte &amp;quot;alte&amp;quot; Zustand 0b00000001 mit 0b00011100 logisch-oder-verknüft (c) und das Ergebnis 0b00011101 in PortA geschrieben (d). Obwohl zwischenzeitlich Bit 0 gelöscht wurde, ist es nach (d) wieder gesetzt. &lt;br /&gt;
&lt;br /&gt;
Lösungsmöglichkeiten:&lt;br /&gt;
* Register ohne besondere Vorkehrungen nicht in Interruptroutinen &#039;&#039;und&#039;&#039; im Hauptprogramm verändern.&lt;br /&gt;
* Interrupts vor Veränderungen in Registern, die auch in ISRs verändert werden, deaktivieren (&amp;quot;cli&amp;quot;).&lt;br /&gt;
* Bits einzeln löschen oder setzen. sbi und cbi können nicht unterbrochen werden. Vorsicht: nur Register im unteren Speicherbereich sind mittels sbi/cbi ansprechbar. Der Compiler kann nur für diese sbi/cbi-Anweisungen generieren. Für Register außerhalb dieses Adressbereichs (&amp;quot;Memory-Mapped&amp;quot;-Register) werden auch zur Manipulation einzelner Bits abhängige Anweisungen erzeugt (lds,...,sts).&lt;br /&gt;
&lt;br /&gt;
* siehe auch: [http://www.nongnu.org/avr-libc/user-manual/index.html Dokumentation der avr-libc] Frequently asked Questions/Fragen Nr. 1 und 8. (Stand: avr-libc Vers. 1.0.4)&lt;br /&gt;
&lt;br /&gt;
== Interruptflags löschen ==&lt;br /&gt;
&lt;br /&gt;
Beim Löschen von Interruptflags haben AVRs eine Besonderheit, die auch im Datenblatt beschrieben ist: Es wird zum Löschen eine 1 in das betreffende Bit geschrieben. &lt;br /&gt;
&lt;br /&gt;
Hinweis: Dazu &#039;&#039;&#039;nicht&#039;&#039;&#039; übliche bitweise VerODERung nehmen, sondern eine direkte Zuweisung machen ([http://www.mikrocontroller.net/topic/171148#1640133 Erklärung]).&lt;br /&gt;
&lt;br /&gt;
== Was macht das Hauptprogramm? ==&lt;br /&gt;
&lt;br /&gt;
Im einfachsten (Ausnahme-)Fall gar nichts mehr. Es ist also durchaus denkbar, ein Programm zu schreiben, welches in der main-Funktion lediglich noch die Interrupts aktiviert und dann in einer Endlosschleife verharrt. Sämtliche Funktionen werden dann in den ISRs abgearbeitet. Diese Vorgehensweise ist jedoch bei den meisten Anwendungen schlecht: man verschenkt eine Verarbeitungsebene und hat außerdem möglicherweise Probleme durch Interruptroutinen, die zu viel Verarbeitungszeit benötigen.&lt;br /&gt;
&lt;br /&gt;
Normalerweise wird man in den Interruptroutinen nur die bei Auftreten des jeweiligen Interruptereignisses unbedingt notwendigen Operationen ausführen lassen. Alle weniger kritischen Aufgaben werden dann im Hauptprogramm abgearbeitet.&lt;br /&gt;
&lt;br /&gt;
* siehe auch: [http://www.nongnu.org/avr-libc/user-manual/index.html Dokumentation der avr-libc] Abschnitt Modules/Interrupts and Signals&lt;br /&gt;
&lt;br /&gt;
= Sleep-Modes =&lt;br /&gt;
&lt;br /&gt;
AVR Controller verfügen über eine Reihe von sogenannten [[Sleep Mode |&#039;&#039;Sleep-Modes&#039;&#039;]] (&amp;quot;Schlaf-Modi&amp;quot;). Diese ermöglichen es, Teile des Controllers abzuschalten. Zum Einen kann damit besonders bei Batteriebetrieb Strom gespart werden, zum Anderen können Komponenten des Controllers deaktiviert werden, die die Genauigkeit des Analog-Digital-Wandlers bzw. des Analog-Comparators negativ beeinflussen. Der Controller wird durch Interrupts aus dem Schlaf geweckt. Welche Interrupts den jeweiligen Schlafmodus beenden, ist einer Tabelle im Datenblatt des jeweiligen Controllers zu entnehmen.&lt;br /&gt;
Die Funktionen (eigentlich Makros) der avr-libc stehen nach Einbinden der header-Datei &#039;&#039;sleep.h&#039;&#039; zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
;set_sleep_mode (uint8_t mode): Setzt den Schlafmodus, der bei Aufruf von sleep() aktiviert wird. In sleep.h sind einige Konstanten definiert (z.&amp;amp;nbsp;B. SLEEP_MODE_PWR_DOWN). Die definierten Modi werden jedoch nicht alle von sämtlichten AVR-Controllern unterstützt.&lt;br /&gt;
;sleep_enable(): Aktiviert den gesetzten Schlafmodus, versetzt den Controller aber noch nicht in den Schlafmodus&lt;br /&gt;
;sleep_cpu(): Versetzt den Controller in den Schlafmodus .sleep_cpu wird im Prinzip durch die Assembler-Anweisung &#039;&#039;sleep&#039;&#039; ersetzt.&lt;br /&gt;
;sleep_disable(): Deaktiviert den gesetzten Schlafmodus&lt;br /&gt;
;sleep_mode(): Versetzt den Controller in den mit set_sleep_mode gewählten Schlafmodus. Das Makro entspricht sleep_enable()+sleep_cpu()+sleep_disable(), beinhaltet also nicht die Aktivierung von Interrupts (besser nicht benutzen).&lt;br /&gt;
&lt;br /&gt;
Bei Anwendung von sleep_cpu() müssen Interrupts also bereits freigeben sein (sei()), da der Controller sonst nicht mehr &amp;quot;aufwachen&amp;quot; kann. sleep_mode() ist nicht geeignet für die Verwendung in ISR Interrupt-Service-Routinen, da bei deren Abarbeitung Interrupts global deaktiviert sind und somit auch die möglichen &amp;quot;Aufwachinterrupts&amp;quot;. Abhilfe: stattdessen sleep_enable(), sei(), sleep_cpu(), sleep_disable() und evtl. cli() verwenden (vgl. Dokumentation der avr-libc).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/sleep.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
   while (1) {&lt;br /&gt;
...&lt;br /&gt;
      set_sleep_mode(SLEEP_MODE_PWR_DOWN);&lt;br /&gt;
      sleep_mode();&lt;br /&gt;
   &lt;br /&gt;
      // Code hier wird erst nach Auftreten eines entsprechenden&lt;br /&gt;
      // &amp;quot;Aufwach-Interrupts&amp;quot; verarbeitet&lt;br /&gt;
...&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In älteren Versionenen der avr-libc wurden nicht alle AVR-Controller durch die sleep-Funktionen richtig angesteuert. Mit avr-libc 1.2.0 wurde die Anzahl der unterstützten Typen jedoch deutlich erweitert. Bei nicht-unterstützten Typen erreicht man die gewünschte Funktionalität durch direkte &amp;quot;[[Bitmanipulation]]&amp;quot; der entsprechenden Register (vgl. Datenblatt) und Aufruf des Sleep-Befehls via Inline-Assembler oder sleep_cpu():&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
   // Sleep-Mode &amp;quot;Power-Save&amp;quot; beim ATmega169 &amp;quot;manuell&amp;quot; aktivieren&lt;br /&gt;
   SMCR = (3&amp;lt;&amp;lt;SM0) | (1&amp;lt;&amp;lt;SE);&lt;br /&gt;
   asm volatile (&amp;quot;sleep&amp;quot;::); // alternativ sleep_cpu() aus sleep.h&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sleep Modi ==&lt;br /&gt;
Zu beachten ist, dass unterschiedliche Prozessoren aus der AVR Familie unterschiedliche Sleep-Modi unterstützen oder nicht unterstützen. Auskunft über die tatsächlichen Gegebenheiten gibt, wie immer, das zum Prozessor gehörende Datenblatt. Die unterschiedlichen Modi unterscheiden sich dadurch, welche Bereiche des Prozessors abgeschaltet werden. Damit korrespondiert unmittelbar welche Möglichkeiten es gibt, den Prozessor aus den jeweiligen Sleep Modus wieder aufzuwecken.&lt;br /&gt;
&lt;br /&gt;
;Idle Mode (SLEEP_MODE_IDLE): Die CPU kann durch SPI, USART, Analog Comperator, ADC, TWI, Timer, Watchdog und irgendeinen anderen Interrupt wieder aufgeweckt werden.&lt;br /&gt;
&lt;br /&gt;
;ADC Noise Reduction Mode (SLEEP_MODE_ADC): In diesem Modus liegt das Hauptaugenmerk darauf, die CPU soweit stillzulegen, dass der ADC möglichst keine Störungen aus dem inneren der CPU auffangen kann. Aufwachen aus diesem Modus kann ausgelöst werden durch den ADC, externe Interrupts, TWI, Timer und Watchdog.&lt;br /&gt;
&lt;br /&gt;
;Power-Down Mode (SLEEP_MODE_PWR_DOWN): In diesem Modus wird ein externer Oszillator (Quarz, Quarzoszillator) gestoppt. Geweckt werden kann die CPU durch einen externen Level Interrupt, TWI, Watchdog, Brown-Out-Reset&lt;br /&gt;
&lt;br /&gt;
;Power-Save-Mode (SLEEP_MODE_PWR_SAVE): Power-Save ist identisch zu Power-Down mit einer Ausnahme: Ist der Timer 2 auf die Verwendung eines externen Taktes konfiguriert, so läuft dieser Timer auch im Power-Save weiter und kann die CPU mit einem Interrupt aufwecken.&lt;br /&gt;
&lt;br /&gt;
;Standby-Mode (SLEEP_MODE_STANDBY, SLEEP_MODE_EXT_STANDBY): Voraussetzung für den Standby-Modus ist die Verwendung eines Quarzes oder eines Quarzoszillators (also einer externen Taktquelle). Ansonsten ist dieser Modus identisch zum Power-Down Modus. Vorteil dieses Modus ist eine kürzere Aufwachzeit.&lt;br /&gt;
&lt;br /&gt;
Siehe auch:&lt;br /&gt;
* [http://www.nongnu.org/avr-libc/user-manual/index.html Dokumentation der avr-libc] Abschnitt Modules/Power Management and Sleep-Modes&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/96369#832712 Forenbeitrag] zur &amp;quot;Nichtverwendung&amp;quot; von sleep_mode in ISRs.&lt;br /&gt;
&lt;br /&gt;
= Zeiger =&lt;br /&gt;
Zeiger (engl. /pointer/), d.h. Variablen, die die Adresse von Daten oder Funktionen enthalten, belegen 16 bits. Das hängt mit dem addressierbaren Speicherbereich zusammen, und gcc reserviert dann den entsprechenden Platz.&lt;br /&gt;
Ggf. ist es also günstiger, Indizes auf Arrays (Listen) zu verwenden, so dass der GCC für die Zeigerarithmetik den erforderlichen RAM nur temporär benötigt.&lt;br /&gt;
&lt;br /&gt;
Siehe auch: [[Zeiger]]&lt;br /&gt;
&lt;br /&gt;
= Speicherzugriffe =&lt;br /&gt;
&lt;br /&gt;
Atmel AVR-Controller verfügen typisch über drei Speicher:&lt;br /&gt;
&lt;br /&gt;
* [[RAM]]: Im RAM (genauer statisches RAM/SRAM) wird vom gcc-Compiler Platz für Variablen reserviert. Auch der Stack befindet sich im RAM. Dieser Speicher ist &amp;quot;flüchtig&amp;quot;, d.h. der Inhalt der Variablen geht beim Ausschalten oder einem Zusammenbruch der Spannungsversorgung verloren.&lt;br /&gt;
&lt;br /&gt;
* Programmspeicher: Ausgeführt als FLASH-Speicher, seitenweise wiederbeschreibbar. Darin ist das Anwendungsprogramm abgelegt.&lt;br /&gt;
&lt;br /&gt;
* [[EEPROM]]: Nichtflüchtiger Speicher, d.h. der einmal geschriebene Inhalt bleibt auch ohne Stromversorgung erhalten. Byte-weise schreib/lesbar. Im EEPROM werden typischerweise gerätespezifische Werte wie z.&amp;amp;nbsp;B. Kalibrierungswerte von Sensoren abgelegt.&lt;br /&gt;
&lt;br /&gt;
Einige AVRs besitzen keinen RAM-Speicher, lediglich die Register können als &amp;quot;Arbeitsvariablen&amp;quot;&lt;br /&gt;
genutzt werden. Da die Anwendung des avr-gcc auf solch &amp;quot;kleinen&amp;quot; Controllern ohnehin selten sinnvoll ist und auch nur bei einigen RAM-losen Typen nach [http://lightner.net/avr/ATtinyAvrGcc.html &amp;quot;Bastelarbeiten&amp;quot;] möglich ist, werden diese Controller hier nicht weiter berücksichtigt. Auch EEPROM-Speicher ist nicht auf allen Typen verfügbar. Generell sollten die nachfolgenden Erläuterungen auf alle ATmega-Controller und die größeren AT90-Typen übertragbar sein. Für die Typen ATtiny2313, ATtiny26 und viele weitere der &amp;quot;ATtiny-Reihe&amp;quot; gelten die Ausführungen ebenfalls.&lt;br /&gt;
&lt;br /&gt;
Siehe auch:&lt;br /&gt;
* [[Binäre Daten zum Programm hinzufügen]]&lt;br /&gt;
== RAM ==&lt;br /&gt;
&lt;br /&gt;
Die Verwaltung des RAM-Speichers erfolgt durch den Compiler, im Regelfall ist beim Zugriff auf Variablen im RAM nichts Besonderes zu beachten. Die Erläuterungen in jedem brauchbaren C-Buch gelten auch für den vom avr-gcc-Compiler erzeugten Code.&lt;br /&gt;
&lt;br /&gt;
Um Speicher dynamisch (während der Laufzeit) zu reservieren, kann &#039;&#039;&#039;malloc()&#039;&#039;&#039; verwendet werden. malloc(size) &amp;quot;alloziert&amp;quot; (~reserviert) einen gewissen Speicherblock mit &#039;&#039;&#039;size&#039;&#039;&#039; Bytes. Ist kein Platz für den neuen Block, wird NULL (0) zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Wird der angelegte Block zu klein (groß), kann die Größe mit realloc() verändert werden. Den allozierten Speicherbereich kann man mit free() wieder freigeben. Wenn das Freigeben eines Blocks vergessen wird spricht man von einem &amp;quot;Speicherleck&amp;quot; (memory leak).&lt;br /&gt;
&lt;br /&gt;
malloc() legt Speicherblöcke im &#039;&#039;&#039;Heap&#039;&#039;&#039; an, belegt man zuviel Platz, dann wächst der Heap zu weit nach oben und überschreibt den Stack, und der Controller kommt in Teufels Küche. Das kann leider nicht nur passieren wenn man insgesamt zu viel Speicher anfordert, sondern auch wenn man Blöcke unterschiedlicher Größe in ungünstiger Reihenfolge alloziert/freigibt (siehe Artikel [[Heap-Fragmentierung]]). Aus diesem Grund sollte man malloc() auf Mikrocontrollern sehr sparsam (am besten gar nicht) verwenden.&lt;br /&gt;
&lt;br /&gt;
Beispiel zur Verwendung von malloc():&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void foo(void) {&lt;br /&gt;
  // neuen speicherbereich anlegen,&lt;br /&gt;
  // platz für 10 uint16&lt;br /&gt;
  uint16_t* pBuffer = malloc(10 * sizeof(uint16_t));&lt;br /&gt;
&lt;br /&gt;
  // darauf zugreifen, als wärs ein gewohnter Buffer&lt;br /&gt;
  pBuffer[2] = 5;&lt;br /&gt;
&lt;br /&gt;
  // Speicher (unbedingt!) wieder freigeben&lt;br /&gt;
  free(pBuffer);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn (wie in obigem Beispiel) dynamischer Speicher nur für die Dauer einer Funktion benötigt und am Ende wieder freigegeben wird, bietet es sich an, statt malloc() &#039;&#039;&#039;alloca()&#039;&#039;&#039; zu verwenden. Der Unterschied zu malloc() ist, dass der Speicher auf dem Stack reserviert wird, und beim Verlassen der Funktion automatisch wieder freigegeben wird. Es kann somit kein Speicherleck und keine Fragmentierung entstehen.&lt;br /&gt;
&lt;br /&gt;
siehe auch:&lt;br /&gt;
* http://www.nongnu.org/avr-libc/user-manual/malloc.html&lt;br /&gt;
&lt;br /&gt;
== Programmspeicher (Flash) ==&lt;br /&gt;
&lt;br /&gt;
Ein Zugriff auf Konstanten im Programmspeicher ist mittels avr-gcc nicht &amp;quot;transparent&amp;quot; möglich. D.h. es sind besondere Zugriffsfunktionen erforderlich, um Daten aus diesem Speicher zu lesen. Grundsätzlich basieren alle Zugriffsfunktionen auf der Assembler-Anweisung lpm (load program memory, bei AVR Controllern mit mehr als 64kB Flash auch elpm). Die Standard-Laufzeitbibliothek des avr-gcc (die avr-libc) stellt diese Funktionen nach Einbinden der Header-Datei pgmspace.h zur Verfügung. Mit diesen Funktionen können einzelne Bytes, Datenworte (16bit) und Datenblöcke gelesen werden. &lt;br /&gt;
&lt;br /&gt;
Deklarationen von Variablen im Flash-Speicher werden durch das &amp;quot;Attribut&amp;quot; PROGMEM ergänzt. Lokale Variablen (eigentlich Konstanten) innerhalb von Funktionen können ebenfalls im Programmspeicher abgelegt werden. Dazu ist bei der Definition jedoch ein &#039;&#039;static&#039;&#039; voranzustellen, da solche &amp;quot;Variablen&amp;quot; nicht auf dem Stack bzw. (bei Optimierung) in Registern verwaltet werden können. Der Compiler &amp;quot;wirft&amp;quot; eine Warnung falls static fehlt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* Byte */&lt;br /&gt;
const uint8_t pgmFooByte PROGMEM = 123;&lt;br /&gt;
&lt;br /&gt;
/* Wort */&lt;br /&gt;
const uint16_t pgmFooWort PROGMEM = 12345;&lt;br /&gt;
&lt;br /&gt;
/* Byte-Array */&lt;br /&gt;
const uint8_t pgmFooByteArray1[] PROGMEM = { 18, 3 ,70 };&lt;br /&gt;
const uint8_t pgmFooByteArray2[] PROGMEM = { 30, 7 ,79 };&lt;br /&gt;
&lt;br /&gt;
/* Zeiger */&lt;br /&gt;
const uint8_t * const pgmPointerToArray1 PROGMEM = pgmFooByteArray1;&lt;br /&gt;
const uint8_t * const pgmPointerArray[] PROGMEM = { pgmFooByteArray1, pgmFooByteArray2 };&lt;br /&gt;
&lt;br /&gt;
void foo(void)&lt;br /&gt;
{&lt;br /&gt;
  static const uint8_t pgmTestByteLocal PROGMEM = 0x55;&lt;br /&gt;
  static const char pgmTestStringLocal[] PROGMEM = &amp;quot;im Flash&amp;quot;;&lt;br /&gt;
  // so nicht (static fehlt) &lt;br /&gt;
  // char pgmTestStringLocalFalsch [] PROGMEM = &amp;quot;so nicht&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Byte lesen ===&lt;br /&gt;
&lt;br /&gt;
Mit der Funktion pgm_read_byte aus pgmspace.h erfolgt der Zugriff auf die Daten. Parameter der Funktion ist die Adresse des Bytes im Flash-Speicher.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
const uint8_t pgmFooByte PROGMEM = 123;&lt;br /&gt;
const uint8_t pgmFooByteArray1[] PROGMEM = { 18, 3, 70 };&lt;br /&gt;
&lt;br /&gt;
void foo (void)&lt;br /&gt;
    // Wert der Ram-Variablen myByte auf den Wert von pgmFooByte setzen:&lt;br /&gt;
    uint8_t myByte;&lt;br /&gt;
&lt;br /&gt;
    myByte = pgm_read_byte (&amp;amp;pgmFooByte);&lt;br /&gt;
    // myByte hat nun den Wert 123&lt;br /&gt;
&lt;br /&gt;
    // Schleife ueber ein Array aus Byte-Werten im Flash&lt;br /&gt;
    uint8_t i;&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; 3; i++)&lt;br /&gt;
    {&lt;br /&gt;
        myByte = pgm_read_byte (&amp;amp;pgmFooByteArray1[i]);&lt;br /&gt;
        // mach was mit myByte&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Wort lesen ===&lt;br /&gt;
&lt;br /&gt;
Für &amp;quot;einfache&amp;quot; 16-Bit breite Variablen erfolgt der Zugriff analog zum Byte-Beispiel, jedoch mit der Funktion &amp;lt;code&amp;gt;pgm_read_word&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
const uint16_t pgmFooWort PROGMEM = 12345;&lt;br /&gt;
&lt;br /&gt;
    uint16_t myWord = pgm_read_word (&amp;amp;pgmFooWort);&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zeiger auf Werte im Flash sind ebenfalls 16 Bits &amp;quot;groß&amp;quot;.&lt;br /&gt;
Damit ist der mögliche Speicherbereich für &amp;quot;Flash-Konstanten&amp;quot; auf 64kB begrenzt.&amp;lt;ref&amp;gt;Einige avr-libc/pgmspace-Funktionen ermöglichen den Lesezugriff auf den gesamten Flash-Speicher, intern via Assembler Anweisung ELPM. Die Initialisierungswerte des Speicherinhalts jenseits der 64kB-Marke müssen dann jedoch auf anderem Weg angelegt werden, d.h. nicht per PROGMEM; evtl. eigene Section und Linker-Optionen. Alt und nicht ganz korrekt: Die avr-libc pgmspace-Funktionen unterstützen nur die unteren 64kB Flash bei Controllern mit mehr als 64kB.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
    const uint8_t *ptrToArray;&lt;br /&gt;
&lt;br /&gt;
    ptrToArray = (const uint8_t*) pgm_read_word (&amp;amp;pgmPointerToArray1);&lt;br /&gt;
    // ptrToArray enthält nun die Startadresse des Byte-Arrays pgmFooByteArray1&lt;br /&gt;
    // Allerdings würde ein direkter Zugriff mit diesem Pointer (z.&amp;amp;nbsp;B. temp=*ptrToArray)&lt;br /&gt;
    // nicht den Inhalt von pgmFooByteArray1[0] liefern, sondern von einer Speicherstelle&lt;br /&gt;
    // im RAM, die die gleiche Adresse hat wie pgmFooByteArray1[0]&lt;br /&gt;
    // Daher muss nun die Funktion pgm_read_byte() benutzt werden, die die in ptrToArray&lt;br /&gt;
    // enthaltene Adresse benutzt und auf das Flash zugreift.&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; 3; i++)&lt;br /&gt;
    {&lt;br /&gt;
        myByte = pgm_read_byte (ptrToArray+i);&lt;br /&gt;
        // mach was mit myByte... (18, 3, 70)&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    ptrToArray = (const uint8_t*) pgm_read_word (&amp;amp;pgmPointerArray[1]);&lt;br /&gt;
    &lt;br /&gt;
    // ptrToArray enthält nun die Adresse des ersten Elements des Byte-Arrays pgmFooByteArray2&lt;br /&gt;
    // da im zweiten Element des Pointer-Arrays pgmPointerArray die Adresse&lt;br /&gt;
    // von pgmFooByteArray2 abgelegt ist&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; 3; i++)&lt;br /&gt;
    {&lt;br /&gt;
        myByte = pgm_read_byte (ptrToArray+i);&lt;br /&gt;
        // mach was mit myByte... (30, 7, 79)&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Block lesen ===&lt;br /&gt;
In den Standard-Flash Funktionen ist keine der pgm_read_xxxx Nomenklatur folgenden Funktion enthalten, die einen kompletten Block ausliest. Die enstprechende Funktion ist eine Variante von memcpy und heißt memcpy_P().&lt;br /&gt;
&lt;br /&gt;
Was diese Funktion im Prinzip macht, ist einfach in einer Schleife pgm_read_byte zu benutzen, um einen Speicherblock von der Quelladresse im Flash an eine Zieladresse im SRAM zu kopieren.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
void pgm_read_block( uint8_t* pTarget, const uint8_t* pSource, size_t len )&lt;br /&gt;
{&lt;br /&gt;
  size_t i;&lt;br /&gt;
&lt;br /&gt;
  for( i = 0; i &amp;lt; len; ++i )&lt;br /&gt;
    *pTarget++ = pgm_read_byte( pSource++ );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit ist es dann natürlich kein Problem mehr ganze Arrays oder Strukturen aus dem Flash in das SRAM zu übertragen.&lt;br /&gt;
&lt;br /&gt;
=== Strings lesen ===&lt;br /&gt;
Strings sind in C nichts anderes als eine Abfolge von Zeichen. Der prinzipielle Weg ist daher identisch zu &amp;quot;Bytes lesen&amp;quot;, wobei allerdings auf die [http://www.mikrocontroller.net/articles/FAQ#Wie_funktioniert_String-Verarbeitung_in_C.3F Besonderheiten von Strings] wie 0-Terminierung geachtet werden muss, bzw. diese zur Steuerung einer Schleife über die Zeichen im String ausgenutzt werden kann&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
const char pgmString[] PROGMEM = &amp;quot;Hello world&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  char c;&lt;br /&gt;
  const char* addr;&lt;br /&gt;
&lt;br /&gt;
  addr = pgmString;&lt;br /&gt;
  while (c = pgm_read_byte (addr++), c != &#039;\0&#039;)&lt;br /&gt;
  {&lt;br /&gt;
    // mach was mit c&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zur Unterstützung des Programmierers steht das Repertoir der str-Funktionen auch in jeweils eine Variante zur Verfügung, die mit dem Flash-Speicher arbeiten kann. Die Funktionsnamen tragen den Suffix &amp;lt;tt&amp;gt;_P&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
const char pgmString[] PROGMEM = &amp;quot;Hallo world&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
void foo (void)&lt;br /&gt;
{&lt;br /&gt;
  char string[40];&lt;br /&gt;
&lt;br /&gt;
  strcpy_P (string, pgmString);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Float lesen ===&lt;br /&gt;
&lt;br /&gt;
Auch um floats zu lesen gibt es ein Makro:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
float pgmFloatArray[3] PROGMEM = {1.1, 2.2, 3.3};&lt;br /&gt;
&lt;br /&gt;
void read_float (void)&lt;br /&gt;
{&lt;br /&gt;
   int i;&lt;br /&gt;
   float f;&lt;br /&gt;
&lt;br /&gt;
   for (i=0; i&amp;lt;3; i++) &lt;br /&gt;
   {&lt;br /&gt;
      // entspricht  f = pgmFloatArray[i];&lt;br /&gt;
      f = pgm_read_float (&amp;amp;pgmFloatArray[i]);&lt;br /&gt;
      // mach was mit f &lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TODO: Beispiele für structs und pointer aus Flash auf struct im Flash (menues, state-machines etc.). Eine kleine Einleitung insbesondere auch in Bezug auf die auftretenden Schwierigkeiten liefert [http://www.mail-archive.com/avr-gcc-list@nongnu.org/msg05652.html].&lt;br /&gt;
&lt;br /&gt;
=== Array aus Strings im Flash-Speicher ===&lt;br /&gt;
&lt;br /&gt;
Arrays aus Strings im Flash-Speicher werden in zwei Schritten angelegt: Zuerst die einzelnen Elemente des Arrays und im Anschluss ein Array, in dem die Startaddressen der Strings abgelegt werden. Zum Auslesen wird zuerst die Adresse des i-ten Elements aus dem Array im Flash-Speicher gelesen, die im Anschluss dazu genutzt wird, auf das Element (den String) selbst zuzugreifen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
const char str1[] PROGMEM = &amp;quot;first_A&amp;quot;;&lt;br /&gt;
const char str2[] PROGMEM = &amp;quot;second_A&amp;quot;;&lt;br /&gt;
const char str3[] PROGMEM = &amp;quot;third_A&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
const char * const strarray1[] PROGMEM = &lt;br /&gt;
{&lt;br /&gt;
   str1,&lt;br /&gt;
   str2,&lt;br /&gt;
   str3&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
static char work[20];&lt;br /&gt;
&lt;br /&gt;
void read_strings (void)&lt;br /&gt;
{&lt;br /&gt;
    size_t i;&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; sizeof (strarray1) / sizeof (strarray1[0]); i++)&lt;br /&gt;
    {&lt;br /&gt;
        size_t j, len;&lt;br /&gt;
&lt;br /&gt;
        // setze Pointer auf die Addresse des i-ten Elements des&lt;br /&gt;
        // Flash-Arrays (str1, str2, ...)&lt;br /&gt;
        const char *pstrflash = (const char*) pgm_read_word (&amp;amp;strarray1[i]);&lt;br /&gt;
&lt;br /&gt;
        // kopiere den Inhalt der Zeichenkette von der&lt;br /&gt;
        // in pstrflash abgelegten Adresse in das work-Array&lt;br /&gt;
        // analog zu strcpy( work, strarray1[i]) wenn alles im RAM&lt;br /&gt;
        strcpy_P (work, pstrflash);&lt;br /&gt;
&lt;br /&gt;
        // Gleichbedeutend damit:&lt;br /&gt;
        strcpy_P (work, (const char*) pgm_read_word (&amp;amp;strarray1[i]));&lt;br /&gt;
    &lt;br /&gt;
        // Zeichen-fuer-Zeichen&lt;br /&gt;
        len = strlen_P (&amp;amp;strarray1[i]);&lt;br /&gt;
&lt;br /&gt;
        // &amp;lt;= da auch das Stringende-Zeichen kopiert werden soll&lt;br /&gt;
        for (j = 0; j &amp;lt;= len; j++)&lt;br /&gt;
        {&lt;br /&gt;
            // analog zu work[j] = strarray[i][j] wenn alles im RAM&lt;br /&gt;
            work[i] = (char) pgm_read_byte (pstrflash++);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Siehe dazu auch die avr-libc FAQ: [http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_rom_array How do I put an array of strings completely in ROM?]&lt;br /&gt;
&lt;br /&gt;
=== Vereinfachung für Zeichenketten (Strings) im Flash ===&lt;br /&gt;
&lt;br /&gt;
Zeichenketten können innerhalb des Quellcodes als &amp;quot;Flash-Konstanten&amp;quot; ausgewiesen werden. Dazu dient das Makro PSTR aus pgmspace.h. Dies erspart die getrennte Deklaration mit PROGMEM-Attribut.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define MAXLEN 30&lt;br /&gt;
&lt;br /&gt;
char StringImFlash[] PROGMEM = &amp;quot;Erwin Lindemann&amp;quot;;&lt;br /&gt;
char StringImRam[MAXLEN];&lt;br /&gt;
&lt;br /&gt;
void read_string (void)&lt;br /&gt;
{&lt;br /&gt;
    strcpy (StringImRam, &amp;quot;Mueller-Luedenscheidt&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    if (!strncmp_P (StringImRam, StringImFlash, 5))&lt;br /&gt;
    {&lt;br /&gt;
        // mach was, wenn die ersten 5 Zeichen identisch - hier nicht&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        // der Code hier wuerde ausgefuehrt &lt;br /&gt;
    } &lt;br /&gt;
&lt;br /&gt;
    if (!strncmp_P (StringImRam, PSTR(&amp;quot;Mueller-Schmitt&amp;quot;), 5))&lt;br /&gt;
    {&lt;br /&gt;
        // der Code hier wird ausgefuehrt, wenn die ersten &lt;br /&gt;
        // 5 Zeichen uebereinstimmen&lt;br /&gt;
    }&lt;br /&gt;
    else &lt;br /&gt;
    {&lt;br /&gt;
        // wird bei Nicht-Uebereinstimmung ausgefuehrt&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Aber Vorsicht: Ersetzt man zum Beispiel&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
// Daten im &amp;quot;Flash&amp;quot;&lt;br /&gt;
const char flashText[] PROGMEM = &amp;quot;mit[]&amp;quot;; &lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
durch&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
// Hier wird &amp;quot;mit*&amp;quot; im RAM angelegt und flashPointer&lt;br /&gt;
// enthaelt die Adresse&lt;br /&gt;
const char* const flashPointer PROGMEM = &amp;quot;mit*&amp;quot;;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
dann kann es zu Problemen kommen.&lt;br /&gt;
&lt;br /&gt;
Übergibt man Zeichenketten, die im Flash abglegt sind an eine Funktion – also die Adresse des ersten Zeichens – so muss die Funktion entsprechend programmiert sein. Die Funktion selbst hat keine Möglichkeit zu unterscheiden, ob es sich um eine Flash-Adresse oder ein RAM-Adresse handelt. Die avr-libc und viele andere avr-gcc-Bibliotheken halten sich an die Konvention, dass Namen von Funktionen, die Flash-Adressen erwarten, mit dem Suffix &amp;lt;code&amp;gt;_P&amp;lt;/code&amp;gt; versehen sind.&lt;br /&gt;
&lt;br /&gt;
Eine Funktion, die einen im Flash abgelegten String z.&amp;amp;nbsp;B. an eine UART ausgibt, würde dann so aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
void uart_puts_p (const char *text)&lt;br /&gt;
{&lt;br /&gt;
    char zeichen;&lt;br /&gt;
&lt;br /&gt;
    while ((zeichen = pgm_read_byte (text)))&lt;br /&gt;
    {&lt;br /&gt;
        // so lange, wie mittels pgm_read_byte nicht das Stringende&lt;br /&gt;
        // gelesen wurde: gib dieses Zeichen aus&lt;br /&gt;
&lt;br /&gt;
        uart_putc (Zeichen);&lt;br /&gt;
        text++;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Von einigen Bibliotheken werden Makros definiert, die &amp;quot;automatisch&amp;quot; ein PSTR bei Verwendung einer Funktion einfügen. Ein Blick in den Header-File der Bibliothek zeigt, ob dies der Fall ist. Ein Beispiel aus P. Fleurys lcd-Library:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
// Ausschnitt aus dem Header-File lcd.h der &amp;quot;Fleury-LCD-Lib.&amp;quot;&lt;br /&gt;
extern void lcd_puts_p (const char *progmem_s);&lt;br /&gt;
#define lcd_puts_P(__s) lcd_puts_p(PSTR(__s))&lt;br /&gt;
&lt;br /&gt;
// in einer Anwendung&lt;br /&gt;
#include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;quot;lcd.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
const char StringImFlash[] PROGMEM = &amp;quot;Erwin Lindemann&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
void my_write (coid)&lt;br /&gt;
{&lt;br /&gt;
    lcd_puts_p (StringImFlash); &lt;br /&gt;
    lcd_puts_P (&amp;quot;Dr. Kloebner&amp;quot;); &lt;br /&gt;
}&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Flash in der Anwendung schreiben ===&lt;br /&gt;
&lt;br /&gt;
Bei AVRs mit &amp;quot;self-programming&amp;quot;-Option – auch bekannt als [[Bootloader]]-Support – können Teile des Flash-Speichers vom Anwendungsprogramm beschrieben werden. Dies ist nur möglich, wenn die Schreibfunktion in einem besonderen Speicherbereich, der boot-section des Programmspeichers/Flash, abgelegt ist.&lt;br /&gt;
&lt;br /&gt;
Bei einigen kleinen AVRs gibt es keine gesonderte Boot-Section, bei diesen kann der Flashspeicher von jeder Stelle des Programms geschrieben werden. Für Details sei hier auf das jeweilige Controller-Datenblatt und die Erläuterungen zum Modul boot.h der avr-libc verwiesen. Es existieren auch Application-Notes dazu bei atmel.com, die auf avr-gcc-Code übertragbar sind.&lt;br /&gt;
&lt;br /&gt;
Siehe auch: &lt;br /&gt;
* Forumsbeitrag [http://www.mikrocontroller.net/topic/163632#1561622 Daten in Programmspeicher speichern]&lt;br /&gt;
&lt;br /&gt;
=== Warum so kompliziert? ===&lt;br /&gt;
&lt;br /&gt;
Zu dem Thema, warum die Verabeitung von Werten aus dem Flash-Speicher so kompliziert ist, sei hier nur kurz erläutert: Die Harvard-Architektur des AVR weist getrennte Adressräume für Programm(Flash)- und Datenspeicher(RAM) auf. Der C-Standard und der gcc-Compiler sehen keine unterschiedlichen Adressräume vor.&lt;br /&gt;
&lt;br /&gt;
Hat man zum Beispiel eine Funktion string_an_uart(const char* s) und übergibt an diese Funktion die Adresse einer Zeichenkette, z.&amp;amp;nbsp;B. 0x01fe, weiß die Funktion nicht, ob die Adresse auf den Flash-Speicher oder den/das RAM zeigt. Allein aus dem Pointer-Wert, also dem Zahlenwert, kann nicht auf den Ort der Ablage geschlossen werden.&lt;br /&gt;
&lt;br /&gt;
Einige AVR-Compiler bilden die Harvard-Architektur ab, indem sie in einen Pointer nicht nur die Adresse speichern, sondern auch den Ablageort wie &#039;&#039;Flash&#039;&#039; oder &#039;&#039;RAM&#039;&#039;. In einem Aufruf einer Funktion wird dann bei Pointer-Parametern neben der Adresse auch der Speicherbereich, auf den der Pointer zeigt, übergeben. Dies hat jedoch auch Nachteile, denn bei jeden Zugriff über einen Zeiger muss zur &#039;&#039;Laufzeit&#039;&#039; entschieden werden, wie der Zugriff auszuführen ist und entsprechend länglicher und langsamer kann Code ausgeführt werden.&lt;br /&gt;
&lt;br /&gt;
* siehe auch: [http://www.nongnu.org/avr-libc/user-manual/index.html Dokumentation der avr-libc] Abschnitte Modules/Program Space String Utilities und Abschnitt Modules/Bootloader Support Utilities&lt;br /&gt;
&lt;br /&gt;
== EEPROM ==&lt;br /&gt;
&lt;br /&gt;
Man beachte, dass der EEPROM-Speicher nur eine begrenzte Anzahl von Schreibzugriffen zulässt. Beschreibt man eine EEPROM-Zelle öfter als die im Datenblatt zugesicherte Anzahl (typisch 100.000), wird die Funktion der Zelle nicht mehr garantiert. &lt;br /&gt;
Dies gilt für jede einzelne Zelle. Bei geschickter Programmierung (z.&amp;amp;nbsp;B. Ring-Puffer), bei der die zu beschreibenden Zellen regelmäßig gewechselt werden, kann man eine deutlich höhere Anzahl an Schreibzugriffen, bezogen auf den Gesamtspeicher, erreichen.&lt;br /&gt;
&lt;br /&gt;
Schreib- und Lesezugriffe auf den EEPROM-Speicher erfolgen über die im Modul eeprom.h definierten Funktionen. Mit diesen Funktionen können einzelne Bytes, Datenworte (16bit) und Datenblöcke geschrieben und gelesen werden. &lt;br /&gt;
&lt;br /&gt;
Bei Nutzung des EEPROMs ist zu beachten, dass vor dem Zugriff auf diesen Speicher abgefragt wird, ob der Controller die vorherige EEPROM-Operation abgeschlossen hat. Die avr-libc-Funktionen beinhalten diese Prüfung, man muss sie nicht selbst implementieren. Man sollte auch verhindern, dass der Zugriff durch die Abarbeitung einer Interrupt-Routine unterbrochen wird, da bestimme Befehlsabfolgen vorgegeben sind, die innerhalb weniger Taktzyklen aufeinanderfolgen müssen (&amp;quot;timed sequence&amp;quot;). Auch dies muss bei Nutzung der Funktionen aus der avr-libc/eeprom.h-Datei nicht selbst implementiert werden. Innerhalb der Funktionen werden Interrupts vor der &amp;quot;EEPROM-Sequenz&amp;quot; global deaktiviert und im Anschluss, falls vorher auch schon eingeschaltet, wieder aktiviert.&lt;br /&gt;
&lt;br /&gt;
Um eine Variable im EEPROM anzulegen, stellt die avr-libc das Makro EEMEM zur Verfügung&amp;lt;ref&amp;gt;In älteren Versionen der avr-libc ist EEMEM noch nicht vorhanden, und man kann sich folgendermassen behelfen:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/eeprom.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#ifndef EEMEM&lt;br /&gt;
#define EEMEM __attribute__((section (&amp;quot;.eeprom&amp;quot;)))&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/c&amp;gt;&amp;lt;/ref&amp;gt;, das analog zu PROGMEM verwendet wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/eeprom.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* Byte */&lt;br /&gt;
uint8_t eeFooByte EEMEM = 123;&lt;br /&gt;
&lt;br /&gt;
/* Wort */&lt;br /&gt;
uint16_t eeFooWord EEMEM = 12345;&lt;br /&gt;
&lt;br /&gt;
/* float */&lt;br /&gt;
float eeFooFloat EEMEM;&lt;br /&gt;
&lt;br /&gt;
/* Byte-Array */&lt;br /&gt;
uint8_t eeFooByteArray1[] EEMEM = { 18, 3, 70 };&lt;br /&gt;
uint8_t eeFooByteArray2[] EEMEM = { 30, 7, 79 };&lt;br /&gt;
&lt;br /&gt;
/* 16-bit unsigned short feld */&lt;br /&gt;
uint16_t eeFooWordArray1[4] EEMEM;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Bytes lesen/schreiben ===&lt;br /&gt;
&lt;br /&gt;
Die avr-libc Funktion zum Lesen eines Bytes heißt eeprom_read_byte. Parameter ist die Adresse des Bytes im EEPROM. Geschrieben wird über die Funktion eeprom_write_byte mit den Parametern Adresse und Inhalt. Anwendungsbeispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#define EEPROM_DEF 0xFF&lt;br /&gt;
&lt;br /&gt;
void eeprom_example (void)&lt;br /&gt;
{&lt;br /&gt;
    uint8_t myByte;&lt;br /&gt;
&lt;br /&gt;
    // myByte lesen (Wert = 123)&lt;br /&gt;
    myByte = eeprom_read_byte (&amp;amp;eeFooByte);&lt;br /&gt;
&lt;br /&gt;
    // der Wert 99 wird im EEPROM an die Adresse der&lt;br /&gt;
    // Variablen eeFooByte geschrieben&lt;br /&gt;
    myByte = 99;&lt;br /&gt;
    eeprom_write_byte(&amp;amp;eeFooByte, myByte); // schreiben&lt;br /&gt;
&lt;br /&gt;
    myByte = eeprom_read_byte (&amp;amp;eeFooByteArray1[1]); &lt;br /&gt;
    // myByte hat nun den Wert 3&lt;br /&gt;
&lt;br /&gt;
    // Beispiel zur &amp;quot;Sicherung&amp;quot; gegen leeres EEPROM nach &amp;quot;Chip Erase&amp;quot;&lt;br /&gt;
    // (z.&amp;amp;nbsp;B. wenn die .eep-Datei nach Programmierung einer neuen Version&lt;br /&gt;
    // des Programms nicht in den EEPROM uebertragen wurde und EESAVE&lt;br /&gt;
    // deaktiviert ist (unprogrammed/1)&lt;br /&gt;
    // &lt;br /&gt;
    // Vorsicht: wenn EESAVE &amp;quot;programmed&amp;quot; ist, hilft diese Sicherung nicht&lt;br /&gt;
    // weiter, da die Speicheraddressen in einem neuen/erweiterten Programm&lt;br /&gt;
    // moeglicherweise verschoben wurden. An der Stelle &amp;amp;eeFooByte steht&lt;br /&gt;
    // dann u.U. der Wert einer anderen Variable aus einer &amp;quot;alten&amp;quot; Version.&lt;br /&gt;
&lt;br /&gt;
    uint8_t fooByteDefault = 222;&lt;br /&gt;
    if ((myByte = eeprom_read_byte (&amp;amp;eeFooByte)) == EEPROM_DEF)&lt;br /&gt;
    {&lt;br /&gt;
        myByte = fooByteDefault;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Wort lesen/schreiben ===&lt;br /&gt;
&lt;br /&gt;
Schreiben und Lesen von Datenworten erfolgt analog zur Vorgehensweise bei Bytes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
    // lesen&lt;br /&gt;
    uint16_t myWord = eeprom_read_word (&amp;amp;eeFooWord);&lt;br /&gt;
&lt;br /&gt;
    // schreiben&lt;br /&gt;
    eeprom_write_word (&amp;amp;eeFooWord, 2222);&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Block lesen/schreiben ===&lt;br /&gt;
&lt;br /&gt;
Lesen und Schreiben von Datenblöcken erfolgt über die Funktionen &amp;lt;code&amp;gt;eeprom_read_block()&amp;lt;/code&amp;gt; bzw. &amp;lt;code&amp;gt;eeprom_write_block()&amp;lt;/code&amp;gt;. Die Funktionen erwarten drei Parameter: die Adresse der Quell- bzw. Zieldaten im RAM, die EEPROM-Addresse und die Länge des Datenblocks in Bytes als &amp;lt;code&amp;gt;size_t&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
uint8_t  myByteBuffer[3];&lt;br /&gt;
uint16_t myWordBuffer[4];&lt;br /&gt;
&lt;br /&gt;
void eeprom_block_example (void)&lt;br /&gt;
{&lt;br /&gt;
    /* Datenblock aus EEPROM lesen  */&lt;br /&gt;
&lt;br /&gt;
    /* liest 3 Bytes ab der von eeFooByteArray1 definierten EEPROM-Adresse&lt;br /&gt;
       in das RAM-Array myByteBuffer */&lt;br /&gt;
    eeprom_read_block (myByteBuffer, eeFooByteArray1, 3);&lt;br /&gt;
&lt;br /&gt;
    /* dito mit etwas Absicherung betr. der Länge */&lt;br /&gt;
    eeprom_read_block (myByteBuffer, eeFooByteArray1, sizeof(myByteBuffer));&lt;br /&gt;
&lt;br /&gt;
    /* und nun mit 16-Bit Array */&lt;br /&gt;
    eeprom_read_block (myWordBuffer, eeFooWordArray1, sizeof(myWordBuffer));&lt;br /&gt;
&lt;br /&gt;
    /* Datenblock in EEPROM schreiben */&lt;br /&gt;
    eeprom_write_block (myByteBuffer, eeFooByteArray1, sizeof(myByteBuffer));&lt;br /&gt;
    eeprom_write_block (myWordBuffer, eeFooWordArray1, sizeof(myWordBuffer));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ebenso lassen sich float-Variablen lesen und schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/eeprom.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
float eeFloat EEMEM = 12.34f;&lt;br /&gt;
&lt;br /&gt;
float void eeprom_float_example (float value)&lt;br /&gt;
{&lt;br /&gt;
   /* float in EEPROM schreiben */&lt;br /&gt;
   eeprom_write_float (&amp;amp;eeFloat, value);&lt;br /&gt;
&lt;br /&gt;
   /* float aus EEPROM lesen */&lt;br /&gt;
   return  eeprom_read_float (&amp;amp;eeFloat);&lt;br /&gt;
}&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== EEPROM-Speicherabbild in .eep-Datei ===&lt;br /&gt;
&lt;br /&gt;
Mit den zum Compiler gehörenden Werkzeugen kann der aus den Variablendeklarationen abgeleitete EEPROM-Inhalt in eine Datei geschrieben werden. Die übliche Dateiendung ist .eep, Daten im Intel Hex-Format. Damit können Standardwerte für den EEPROM-Inhalt im Quellcode definiert werden. &lt;br /&gt;
&lt;br /&gt;
Makefiles nach WinAVR/MFile-Vorlage enthalten bereits die notwendigen Einstellungen, siehe dazu die Erläuterungen im [[AVR-GCC-Tutorial/Exkurs Makefiles|Exkurs Makefiles]].&lt;br /&gt;
&lt;br /&gt;
Der Inhalt der eep-Datei muss ebenfalls zum Mikrocontroller übertragen werden, wenn die Initialisierungswerte aus der Deklaration vom Programm erwartet werden. Ansonsten enthält der EEPROM-Speicher nach der Übertragung des Programmers mittels ISP abhängig von der Einstellung der EESAVE-Fuse&amp;lt;ref&amp;gt;vgl. Datenblatt Abschnitt Fuse Bits&amp;lt;/ref&amp;gt; nicht die korrekten Werte:&lt;br /&gt;
; EESAVE = 0 (programmed): Die Daten im EEPROM bleiben erhalten. Werden sie nicht neu geschrieben, so enthält das EEPROM evtl. Daten, die nicht mehr zum Programm passen.&lt;br /&gt;
; EESAVE = 1 (unprogrammed): Beim Programmieren werden die Daten im EEPROM gelöscht, also auf 0xff gesetzt.&lt;br /&gt;
&lt;br /&gt;
Als Sicherung kann man im Programm nochmals die Standardwerte vorhalten, beim Lesen auf 0xFF prüfen und gegebenenfalls einen Standardwert nutzen.&lt;br /&gt;
&lt;br /&gt;
=== Direkter Zugriff auf EEPROM-Adressen ===&lt;br /&gt;
&lt;br /&gt;
Will man direkt auf bestimmte EEPROM Adressen zugreifen, dann sind folgende Funktionen hilfreich, um sich die Typecasts zu ersparen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/eeprom.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Byte aus dem EEPROM lesen&lt;br /&gt;
uint8_t EEPReadByte(uint16_t addr)&lt;br /&gt;
{&lt;br /&gt;
  return eeprom_read_byte((uint8_t *)addr);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Byte in das EEPROM schreiben&lt;br /&gt;
void EEPWriteByte(uint16_t addr, uint8_t val)&lt;br /&gt;
{&lt;br /&gt;
  eeprom_write_byte((uint8_t *)addr, val);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
oder als Makro:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#define   EEPReadByte(addr)         eeprom_read_byte((uint8_t *)addr)     &lt;br /&gt;
#define   EEPWriteByte(addr, val)   eeprom_write_byte((uint8_t *)addr, val)&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verwendung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
EEPWriteByte(0x20, 128);   // Byte an die Adresse 0x20 schreiben&lt;br /&gt;
...&lt;br /&gt;
Val=EEPReadByte(0x20);     // EEPROM-Wert von Adresse 0x20 lesen&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Bekannte Probleme bei den EEPROM-Funktionen ===&lt;br /&gt;
&lt;br /&gt;
Vorsicht: Bei alten Versionen der avr-libc wurden nicht alle AVR Controller  unterstützt. Z.B. bei der avr-libc Version 1.2.3 insbesondere bei AVRs &amp;quot;der neuen Generation&amp;quot; (ATmega48/88/168/169) funktionieren die Funktionen nicht korrekt (Ursache: unterschiedliche Speicheradressen der EEPROM-Register). In neueren Versionen (z.&amp;amp;nbsp;B. avr-libc 1.4.3 aus WinAVR 20050125) wurde die Zahl der unterstüzten Controller deutlich erweitert und eine Methode zur leichten Anpassung an zukünftige Controller eingeführt.&lt;br /&gt;
&lt;br /&gt;
In jedem Datenblatt zu AVR-Controllern mit EEPROM sind kurze Beispielecodes für den Schreib- und Lesezugriff enthalten. Will oder kann man nicht auf die neue Version aktualisieren, kann der dort gezeigte Code auch mit dem avr-gcc (ohne avr-libc/eeprom.h) genutzt werden (&amp;quot;copy/paste&amp;quot;, gegebenfalls Schutz vor Unterbrechnung/Interrupt ergänzen &#039;&#039;uint8_t sreg; sreg=SREG; cli(); [EEPROM-Code] ; SREG=sreg; return;&#039;&#039;, siehe Abschnitt Interrupts). Im Zweifel hilft ein Blick in den vom Compiler erzeugten Assembler-Code (lst/lss-Dateien).&lt;br /&gt;
&lt;br /&gt;
* siehe auch: [http://www.nongnu.org/avr-libc/user-manual/index.html Dokumentation der avr-libc] Abschnitt Modules/EEPROM handling&lt;br /&gt;
&lt;br /&gt;
=== EEPROM Register ===&lt;br /&gt;
Um das EEPROM anzusteuern, sind drei Register von Bedeutung:&lt;br /&gt;
;EEAR: Hier werden die Adressen eingetragen zum Schreiben oder Lesen. Dieses Register unterteilt sich nochmal in EEARH und EEARL, da in einem 8-Bit-Register keine 512 Adressen adressiert werden können.&lt;br /&gt;
;EEDR: Hier werden die Daten eingetragen, die geschrieben werden sollen, bzw. es enthält die gelesenen Daten.&lt;br /&gt;
;EECR: Ist das Kontrollregister für das EEPROM&lt;br /&gt;
&lt;br /&gt;
Das EECR steuert den Zugriff auf das EEPROM und ist wie folgt aufgebaut:&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Aufbau des EECR-Registers&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
!Bit&lt;br /&gt;
| 7 || 6 || 5 || 4 || 3 || 2 || 1 || 0&lt;br /&gt;
|-&lt;br /&gt;
! Name&lt;br /&gt;
| - || - || - ||- || EERIE || EEMWE || EEWE || EERE&lt;br /&gt;
|-&lt;br /&gt;
! Read/Write&lt;br /&gt;
| R || R || R || R || R/W || R/W || R/W || R/W&lt;br /&gt;
|-&lt;br /&gt;
!Init Value&lt;br /&gt;
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Bedeutung der Bits&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
;Bit 4-7: nicht belegt&lt;br /&gt;
&lt;br /&gt;
;Bit 3 (EERIE): &#039;&#039;EEPROM Ready Interrupt Enable&#039;&#039;: Wenn das Bit gesetzt ist und globale Interrupts erlaubt sind in Register SREG (Bit 7), wird ein Interrupt ausgelöst nach Beendigung des Schreibzyklus (EEPROM Ready Interrupt). Ist einer der beiden Bits 0, wird kein Interrupt ausgelöst.&lt;br /&gt;
&lt;br /&gt;
;Bit 2 EEMWE): &#039;&#039;EEPROM Master Write Enable&#039;&#039;: Dieses Bit bestimmt, dass, wenn EEWE = 1 gesetzt wird (innerhalb von 4 Taktzyklen), das EEPROM beschrieben wird mit den Daten in EEDR bei Adresse EEAR. Wenn EEMWE = 0 ist und EEWE = 1 gesetzt wird, hat das keine Auswirkungen. Der Schreibvorgang wird dann nicht ausgelöst. Nach 4 Taktzyklen wird das Bit EEMWE automatisch wieder auf 0 gesetzt. Dieses Bit löst den Schreibvorgang nicht aus, es dient sozusagen als Sicherungsbit für EEWE.&lt;br /&gt;
&lt;br /&gt;
;Bit 1 (EEWE): &#039;&#039;EEPROM Write Enable&#039;&#039;: Dieses Bit löst den Schreibvorgang aus, wenn es auf 1 gesetzt wird, sofern vorher EEMWE gesetzt wurde und seitdem nicht mehr als 4 Taktzyklen vergangen sind. Wenn der Schreibvorgang abgeschlossen ist, wird dieses Bit automatisch wieder auf 0 gesetzt und, sofern EERIE gesetzt ist, ein Interrupt ausgelöst. Ein Schreibvorgang sieht typischerweise wie folgt aus:&lt;br /&gt;
:# EEPROM-Bereitschaft abwarten (EEWE=0) &lt;br /&gt;
:# Adresse übergeben an EEAR&lt;br /&gt;
:# Daten übergeben an EEDR&lt;br /&gt;
:# Schreibvorgang auslösen in EECR mit Bit EEMWE=1 und EEWE=1&lt;br /&gt;
:# (Optional) Warten, bis Schreibvorgang abgeschlossen ist&lt;br /&gt;
&lt;br /&gt;
;Bit 0 EERE: &#039;&#039;EEPROM Read Enable&#039;&#039;: Wird dieses Bit auf 1 gesetzt wird das EEPROM an der Adresse in EEAR ausgelesen und die Daten in EEDR gespeichert. Das EEPROM kann nicht ausgelesen werden, wenn bereits eine Schreiboperation gestartet wurde. Es ist daher zu empfehlen, die Bereitschaft vorher zu prüfen. Das EEPROM ist lesebereit, wenn das Bit EEWE=0 ist. Ist der Lesevorgang abgeschlossen, wird das Bit wieder auf 0 gesetzt, und das EEPROM ist für neue Lese- und Schreibbefehle wieder bereit. Ein typischer Lesevorgang kann wie folgt aufgebaut sein:&lt;br /&gt;
:# Bereitschaft zum Lesen prüfen (EEWE=0)&lt;br /&gt;
:# Adresse übergeben an EEAR&lt;br /&gt;
:# Lesezyklus auslösen mit EERE = 1&lt;br /&gt;
:# Warten, bis Lesevorgang abgeschlossen EERE = 0&lt;br /&gt;
:# Daten abholen aus EEDR&lt;br /&gt;
&lt;br /&gt;
= Die Nutzung von sprintf und printf =&lt;br /&gt;
&lt;br /&gt;
Um komfortabel, d.h. formatiert, Ausgaben auf ein Display oder die serielle Schnittstelle zu tätigen, bieten sich &#039;&#039;&#039;sprintf&#039;&#039;&#039; oder &#039;&#039;&#039;printf&#039;&#039;&#039; an. Alle *printf-Varianten sind jedoch ziemlich speicherintensiv und der Einsatz in einem Mikrocontroller mit knappem Speicher muss sorgsam abgewogen werden.&lt;br /&gt;
&lt;br /&gt;
Bei &#039;&#039;&#039;sprintf&#039;&#039;&#039; wird die Ausgabe zunächst in einem Puffer vorbereitet und anschließend mit einfachen Funktionen zeichenweise ausgegeben. Es liegt in der Verantwortung des Programmierers, genügend Platz im Puffer für die erwarteten Zeichen bereitzuhalten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ...&lt;br /&gt;
// nicht dargestellt: Implementierung von uart_puts (vgl. Abschnitt UART)&lt;br /&gt;
// ...&lt;br /&gt;
&lt;br /&gt;
uint16_t counter;&lt;br /&gt;
&lt;br /&gt;
// Ausgabe eines unsigned Integerwertes&lt;br /&gt;
void uart_puti( uint16_t value )&lt;br /&gt;
{&lt;br /&gt;
    uint8_t puffer[20];&lt;br /&gt;
&lt;br /&gt;
    sprintf( puffer, &amp;quot;Zählerstand: %u&amp;quot;, value );&lt;br /&gt;
    uart_puts( puffer );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  counter = 5;&lt;br /&gt;
&lt;br /&gt;
  uart_puti( counter );&lt;br /&gt;
  uart_puti( 42 );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine weitere elegante Möglichkeit besteht darin, den STREAM stdout (Standardausgabe) auf eine eigene Ausgabefunktion umzuleiten. Dazu wird dem Ausgabemechanismus der C-Bibliothek eine neue Ausgabefunktion bekannt gemacht, deren Aufgabe es ist, ein einzelnes Zeichen auszugeben. Wohin die Ausgabe dann tatsächlich stattfindet, ist Sache der Ausgabefunktion. Im Beispiel unten wird auf UART ausgegeben. Alle anderen, höheren Funktionen wie z.&amp;amp;nbsp;B. &#039;&#039;&#039;printf&#039;&#039;&#039;, greifen letztendlich auf diese primitive Ausgabefunktion zurück. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void uart_init(void);&lt;br /&gt;
&lt;br /&gt;
// a. Deklaration der primitiven Ausgabefunktion&lt;br /&gt;
int uart_putchar(char c, FILE *stream);&lt;br /&gt;
&lt;br /&gt;
// b. Umleiten der Standardausgabe stdout (Teil 1)&lt;br /&gt;
static FILE mystdout = FDEV_SETUP_STREAM( uart_putchar, NULL, _FDEV_SETUP_WRITE );&lt;br /&gt;
&lt;br /&gt;
// c. Definition der Ausgabefunktion&lt;br /&gt;
int uart_putchar( char c, FILE *stream )&lt;br /&gt;
{&lt;br /&gt;
    if( c == &#039;\n&#039; )&lt;br /&gt;
        uart_putchar( &#039;\r&#039;, stream );&lt;br /&gt;
&lt;br /&gt;
    loop_until_bit_is_set( UCSRA, UDRE );&lt;br /&gt;
    UDR = c;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void uart_init(void)&lt;br /&gt;
{&lt;br /&gt;
    /* hier µC spezifischen Code zur Initialisierung */&lt;br /&gt;
    /* des UART einfügen... s.o. im AVR-GCC-Tutorial */&lt;br /&gt;
&lt;br /&gt;
    // Beispiel: &lt;br /&gt;
    //&lt;br /&gt;
    // myAVR Board 1.5 mit externem Quarz Q1 3,6864 MHz&lt;br /&gt;
    // 9600 Baud 8N1&lt;br /&gt;
&lt;br /&gt;
#ifndef F_CPU&lt;br /&gt;
#define F_CPU 3686400&lt;br /&gt;
#endif&lt;br /&gt;
#define UART_BAUD_RATE 9600&lt;br /&gt;
&lt;br /&gt;
// Hilfsmakro zur UBRR-Berechnung (&amp;quot;Formel&amp;quot; laut Datenblatt)&lt;br /&gt;
#define UART_UBRR_CALC(BAUD_,FREQ_) ((FREQ_)/((BAUD_)*16L)-1)&lt;br /&gt;
&lt;br /&gt;
    UCSRB |= (1&amp;lt;&amp;lt;TXEN) | (1&amp;lt;&amp;lt;RXEN);    // UART TX und RX einschalten&lt;br /&gt;
    UCSRC |= (1&amp;lt;&amp;lt;URSEL)|(3&amp;lt;&amp;lt;UCSZ0);    // Asynchron 8N1 &lt;br /&gt;
 &lt;br /&gt;
    UBRRH = (uint8_t)( UART_UBRR_CALC( UART_BAUD_RATE, F_CPU ) &amp;gt;&amp;gt; 8 );&lt;br /&gt;
    UBRRL = (uint8_t)UART_UBRR_CALC( UART_BAUD_RATE, F_CPU );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    int16_t antwort = 42;&lt;br /&gt;
    uart_init();&lt;br /&gt;
&lt;br /&gt;
    // b. Umleiten der Standardausgabe stdout (Teil 2)&lt;br /&gt;
    stdout = &amp;amp;mystdout;&lt;br /&gt;
&lt;br /&gt;
    // Anwendung&lt;br /&gt;
    printf( &amp;quot;Die Antwort ist %d.\n&amp;quot;, antwort );&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Quelle: avr-libc-user-manual-1.4.3.pdf, S.74&lt;br /&gt;
//         + Ergänzungen&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Sollen Fließkommazahlen ausgegeben werden, muss im Makefile eine andere (größere) Version der [[FAQ#Aktivieren_der_Floating_Point_Version_von_sprintf_beim_WinAVR_mit_AVR-Studio|printflib]] eingebunden werden.&lt;br /&gt;
&lt;br /&gt;
= Anhang =&lt;br /&gt;
&lt;br /&gt;
== Externe Referenzspannung des internen Analog-Digital-Wandlers ==&lt;br /&gt;
&lt;br /&gt;
Die minimale (externe) Referenzspannung des ADC darf nicht beliebig niedrig sein, vgl. dazu das (aktuellste) Datenblatt des verwendeten Controllers. z.&amp;amp;nbsp;B. beim ATMEGA8 darf sie laut Datenblatt (S.245, Tabelle 103, Zeile &amp;quot;VREF&amp;quot;) 2,0V nicht unterschreiten. HINWEIS: diese Information findet sich erst in der letzten Revision (Rev. 2486O-10/04) des Datenblatts.&lt;br /&gt;
&lt;br /&gt;
Meiner &amp;lt;!-- Wer? - es gibt inzwischen x Leute die mehr oder weniger viel in diesem Artikel geschrieben haben --&amp;gt; eigenen Erfahrung nach kann man aber (auf eigene Gefahr und natürlich nicht für Seriengeräte) durchaus noch ein klein wenig weiter heruntergehen, bei dem von mir unter die Lupe genommenen ATMEGA8L (also die Low-Voltage-Variante) funktioniert der ADC bei 5V Betriebsspannung mit bis zu VREF=1,15V hinunter korrekt, ab 1,1V und darunter digitalisiert er jedoch nur noch Blödsinn). Ich würde sicherheitshalber nicht unter 1,5V gehen und bei niedrigeren Betriebsspannungen mag sich die Untergrenze für VREF am Pin AREF ggf. nach oben&#039;&#039;&#039;(!)&#039;&#039;&#039; verschieben.&lt;br /&gt;
&lt;br /&gt;
In der letzten Revision des Datenblatts ist außerdem korrigiert, dass ADC4 und ADC5 sehr wohl 10 Bit Genauigkeit bieten (und nicht bloß 8 Bit, wie in älteren Revisionen irrtümlich angegeben.)&lt;br /&gt;
&lt;br /&gt;
= Anmerkungen =&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= TODO =&lt;br /&gt;
* Aktualisierung Register- und Bitbeschreibungen an aktuelle AVR&lt;br /&gt;
* stdio.h, malloc() &lt;br /&gt;
* &amp;quot;naked&amp;quot;-Funktionen&lt;br /&gt;
* Übersicht zu den C bzw. GCC-predefined Makros (__DATE__, __TIME__,...)&lt;br /&gt;
* Bootloader =&amp;gt; erl. [[AVR Bootloader in C - eine einfache Anleitung]]&lt;br /&gt;
* [http://myweb.msoe.edu/~barnicks/courses/CE-2800/documents/Mixing%20C%20and%20assembly%20language%20programs.pdf Mixing C and assembly language programs] Copyright © 2007 William Barnekow (PDF).&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:avr-gcc Tutorial| ]]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=AVR_Bootloader_in_C_-_eine_einfache_Anleitung&amp;diff=61252</id>
		<title>AVR Bootloader in C - eine einfache Anleitung</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=AVR_Bootloader_in_C_-_eine_einfache_Anleitung&amp;diff=61252"/>
		<updated>2011-10-22T08:15:12Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: /* Schritt 3 - Programmieren des Bootloaders */ Schreibfehler korrigiert&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Dieser Artikel soll dazu dienen, das Thema [[Bootloader]] im AVR etwas zu demystifizieren.&lt;br /&gt;
&lt;br /&gt;
Es gibt schon einige Artikel und Codebeispiele für verschiedene Bootloader in Assembler oder C (bzw. gemischt), aber kein Artikel beleuchtet das Thema von einer einfachen Seite aus Anwendungssicht. In diese Lücke zielt dieses Tutorial.&lt;br /&gt;
Es soll anhand von Beispielen einen möglichst einfachen, verständlichen und nachvollziehbaren Weg zeigen, sich mit Hilfe der Hochsprache C in das Thema einzuarbeiten (dabei soll weder Assembler noch Inline-Assembler verwendet werden). &lt;br /&gt;
&lt;br /&gt;
Vielleicht werden einige meinen dass es nicht möglich ist das Thema ohne tieferen Einblick in die Hardware und die AVR-Register zu beleuchten, ich möchte es aber trotzdem versuchen.&lt;br /&gt;
&lt;br /&gt;
Der Artikel wird sich auf das notwendige Wissen beschränken, um mit Booloadern arbeiten zu können. Es wird ein genereller Weg gezeigt, der sich leicht auf andere AVR-Devices (mit Bootloader Sektion) übertragen lässt.&lt;br /&gt;
Die Codebeispiele wurden für den ATmega88 kompiliert und getestet.&lt;br /&gt;
&lt;br /&gt;
== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
Zu Beginn soll das notwendige Wissen über die Bootloaderunterstützung im AVR vermittelt werden, um eine Arbeitsgrundlage zu schaffen.&lt;br /&gt;
&lt;br /&gt;
Im weiteren Verlauf des Artikels werden insgesamt drei Anwendungen programmiert: Zuerst ein einfacher Bootloader, welcher in der Bootloadersektion des Flashs ausgeführt wird, aber noch keine eigentliche Bootloader-Funktion hat, sozusagen ein &amp;quot;Hallo Welt&amp;quot;-Bootloader. Danach soll eine kleine Applikation programmiert werden, welche der spätere &#039;&#039;echte&#039;&#039; Bootloader ins Flash programmieren soll. Als großes Finale soll dann ein Bootloader entstehen, welcher in der Lage ist, Intel-HEX-Dateien über die serielle Schnittstelle zu laden, ins Flash zu programmieren und zu starten.&lt;br /&gt;
&lt;br /&gt;
Der Leser sollte bereits Erfahrungen im Umgang mit dem AVR Studio und der Programmiersprache C gemacht haben und schon Anwendungen geschrieben haben. Für absolute Einsteiger ist der Artikel ungeeignet.&lt;br /&gt;
&lt;br /&gt;
Den Thread zum Artikel gibt es hier: http://www.mikrocontroller.net/topic/195102&lt;br /&gt;
&lt;br /&gt;
== Software ==&lt;br /&gt;
&lt;br /&gt;
Für den Artikel werden folgende Software-Pakete benötigt:&lt;br /&gt;
&lt;br /&gt;
* aktuelles [http://http://www.atmel.com/dyn/products/tools_card.asp?tool_id=2725 AVR Studio] (hier verwendet: AVR Studio v4.18) &lt;br /&gt;
* aktuelles [http://sourceforge.net/projects/winavr/files/ WinAVR] (hier verwendet: WinAVR20100110)&lt;br /&gt;
* [http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html PuTTY] als serielle Konsole (Version v0.6)&lt;br /&gt;
&lt;br /&gt;
Des weiteren wurde auf der AVR-Seite für die serielle Kommunikation mit dem PC auf die beliebte UART-Library von [http://www.jump.to/fleury Peter Fleury] zurückgegriffen, damit wir uns nicht um die gepufferte UART-Kommunikation kümmern müssen.&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
&lt;br /&gt;
Für den Artikel wurde eine kleine Hardware bestehend aus einem [http://www.atmel.com/dyn/products/product_card.asp?part_id=3302 Atmega88] und einem [http://www.ftdichip.com/Products/ICs/FT232R.htm FT232] als USB-Seriell-Wandler erstellt. Dies soll als Basis für die Experimente dienen. Der USB-Seriell-Wandler ist nicht zwingend notwendig und kann auch durch den üblichen Pegelwandler vom Typ [http://www.maxim-ic.com/datasheet/index.mvp/id/1798/ln/en MAX232] ersetzt werden, wenn der PC noch eine serielle Schnittstelle besitzt. Entscheidend ist nur die Möglichkeit der seriellen Kommunikation mit dem Rechner.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Schaltplan-ATmega88-USB.png|800px|Schaltplan]]&lt;br /&gt;
&lt;br /&gt;
Für die ISP-Programmierung wurde der [http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3808 AVRISPmkII-In-System-Programmer] von Atmel verwendet. Es kann natürlich auch ein anderer Programmer (z.B. [http://www.atmel.com/dyn/products/tools_card.asp?tool_id=2735 STK500]) verwendet werden, welcher mit dem AVR Studio zusammenarbeitet. Prinzipiell kann natürlich auch ein selbstgebastelter Parallel-Programmer verwendet werden, dann kann aber nicht via AVR Studio programmiert werden, sondern mit [http://www.nongnu.org/avrdude/ AVRDude] oder [http://www.lancos.com/prog.html PonyProg] o.ä. Der Artikel beschränkt sich auf die Verwendung vom AVR Studio.&lt;br /&gt;
&lt;br /&gt;
Für das Verständis der Hardware und der seriellen Kommunikation sind folgende Artikel empfehlenswert:&lt;br /&gt;
&lt;br /&gt;
* [[AVR-Tutorial: UART]]&lt;br /&gt;
* [[RS-232]]&lt;br /&gt;
&lt;br /&gt;
= Grundlagen =&lt;br /&gt;
&lt;br /&gt;
[[Bild:AVR-Memory.png|400px|thumb|Flash Speicher Aufteilung]]&lt;br /&gt;
&lt;br /&gt;
Was ist eigentlich ein Bootloader und was macht er? Wofür sollte ich so etwas brauchen? Ist das nicht viel zu kompliziert? Ich bin eingefleischter AVR Studio-Benutzer, muss ich mich jetzt mit makefiles beschäftigen? Kann man im AVR Studio mit C überhaupt einen Bootloader schreiben? Vielleicht hat sich der eine oder andere schon einmal diese oder ähnliche Fragen gestellt. &lt;br /&gt;
&lt;br /&gt;
Der Programmcode des AVR steht in seinem Flashspeicher und wird von dort ausgeführt. Normalerweise kann während der Ausführung des Programms nicht auf den Flashspeicher geschrieben werden. Dies ist auch einleuchtend da sich das Programm ja sonst selbst überschreiben oder löschen könnte. Das Beschreiben des Flashs erfolgt beim AVR üblicherweise über die ISP-Schnittstelle, dabei befindet sich der Controller im Reset und es wird kein Programm ausgeführt. Dies ist für Prototyping und kleine Anwendungen hinnehmbar. Ist der Controller allerdings in einem größeren System oder in größerer räumlicher Entfernung verbaut und die ISP-Schnittstelle nicht mehr zugänglich, ist ein Update der Firmware nicht mehr ohne Weiteres möglich oder sehr teuer und aufwendig. Hier kann ein Bootloader Abhilfe schaffen, in dem er das Anwendungsprogramm auf einer definierten Schnittstelle entgegennimmt (UART, I2C, Wireless) und ins Flash transferiert. Ein Bootloader ist also in erster Linie ein kleines Programm, welches in einem besonderem Teil des Flash steht - der &#039;&#039;&#039;Boot Loader Section&#039;&#039;&#039;.  Durch die Lokalisierung des Bootloader-Programms in dieser besonderen Sektion des AVR ist es dem Programm möglich, auf Teile des Flashs - der sogenannten &#039;&#039;&#039;Application Flash Section&#039;&#039;&#039; - zu schreiben. Die eigentliche Anwendung wird ausschließlich in der &#039;&#039;&#039;Application Flash Section&#039;&#039;&#039; ausgeführt. Wenn man so will, können im Flash des AVR also zwei unabhängige Programme stehen. Der Flash ist in zwei Bereiche mit unterschiedlichen Merkmalen aufgeteilt (siehe Bild). Auf die RWW bzw. NRWW-Sektion möchte ich an dieser Stelle (noch) nicht eingehen.&lt;br /&gt;
&lt;br /&gt;
Wie man unschwer erkennen kann, liegt der Bootloader-Bereich am Ende des Flash-Speichers. Normalerweise startet der Controller die Abarbeitung seiner Programmierung an der Stelle 0x0000. Ein Bootloader soll ja aber &#039;&#039;&#039;vor&#039;&#039;&#039; der Abarbeitung der eigentlichen Applikation ausgeführt werden. Woher weiß also der AVR-Controller nach dem Reset, dass er nicht von Adresse 0x0000 sondern einer anderen Adresse starten soll? Diese Konfiguration ist wie alle wichtigen und grundlegenden Konfigurationen über die Fuses des AVRs geregelt. Wir beginnen mit der folgende Tabelle, welche die Speicheraufteilung des Programmspeichers veranschaulicht.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Boot Size Konfiguration, Tabelle 26-6 im Atmega88-Datenblatt S.280&lt;br /&gt;
|- &lt;br /&gt;
! BOOTSZ1 || BOOTSZ0 || Boot&amp;lt;br&amp;gt;Size || Pages || Application&amp;lt;br&amp;gt;Flash Section || Boot Loader&amp;lt;br&amp;gt;Flash Section || End&amp;lt;br&amp;gt;Application&amp;lt;br&amp;gt;Section || Boot Reset&amp;lt;br&amp;gt;(Start Boot&amp;lt;br&amp;gt;Loader Section)&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1 || 128 words || 4 || 0x000 - 0xF7F || 0xF80 - 0xFFF || 0xF7F || 0xF80&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 0 || 256 words || 8 || 0x000 - 0xEFF || 0xF00 - 0xFFF || 0xEFF || 0xF00&lt;br /&gt;
|-&lt;br /&gt;
| 0 || 1 || 512 words || 16 || 0x000 - 0xDFF || 0xE00 - 0xFFF || 0xDFF || 0xE00&lt;br /&gt;
|-&lt;br /&gt;
| 0 || 0 || 1024 words || 32 || 0x000 - 0xBFF || 0xC00 - 0xFFF || 0xBFF || 0xC00&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Um die Tabelle zu verstehen muss man wissen, dass der Flash-Speicher intern in sogenannten &#039;&#039;Pages&#039;&#039; (Seiten) organisiert ist. Die Multiplikation der &#039;&#039;Page&#039;&#039;-Größe mit der Anzahl der &#039;&#039;Pages&#039;&#039; ergibt die Speichergröße. Die Größe einer &#039;&#039;Page&#039;&#039; steht im Datenblatt und ist in &#039;&#039;Words&#039;&#039; - also Datenworte - angegeben. Ein Datenwort entspricht zwei Bytes. &#039;&#039;&#039;&#039;&#039;Hier offenbart sich eine Tücke des Datenblatts: Alle Speicherbezüge und Adressen sind in Datenworten  (also immer 2 Bytes) angegeben!&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
Aus der Tabelle erfahren wir auch, dass man mit den beiden Fuses &#039;&#039;&#039;BOOTSZ0&#039;&#039;&#039; und &#039;&#039;&#039;BOOTSZ1&#039;&#039;&#039; die Größe des Bootloaderbereichs einstellen kann. Eine weitere Tabelle aus dem Atmega88-Datenblatt gibt Auskunft über die Aufteilung der Pages und die Anzahl der Datenworte einer Page.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ No.of Words in a Page and No.of Pages in Flash, Tabelle 27-9 im Atmega88-Datenblatt S.288&lt;br /&gt;
|- &lt;br /&gt;
!  Device || Flash Size || Page Size || PCWORD || No. of Pages || PCPAGE || PCMSB&lt;br /&gt;
|-&lt;br /&gt;
| Atmega88 || 4K words (8 Kbytes) || 32 words || PC[4:0] || 128 || PC[11:5] || 11&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Aus der Tabelle ergibt sich, dass die Größe einer &#039;&#039;Page&#039;&#039; des verwendeten Atmega88 32 &#039;&#039;Words&#039;&#039; - also 64 Byte sind. Insgesamt gibt es 128 &#039;&#039;Pages&#039;&#039;, damit ergibt sich nach Adam Riese 128 * 64 = 8192 Byte, also 8 Kbytes. In unserem späteren Codebeispiel soll die Größe des Bootloaderbereichs auf 1024 &#039;&#039;words&#039;&#039; - also 2048 Bytes gestellt werden (&#039;&#039;&#039;BOOTSZ0=0&#039;&#039;&#039; und &#039;&#039;&#039;BOOTSZ1=0&#039;&#039;&#039;). Nun können wir ausrechnen, in welcher Flash-&#039;&#039;Page&#039;&#039; bzw. an welcher Flash-Adresse der Bootloaderbereich beginnt: Er beginnt in der 96 &#039;&#039;Page&#039;&#039; (128 - 32) an &#039;&#039;Word&#039;&#039;-Adresse 0xC00, also Byteadresse 0xC00 * 2 = 0x1800. Dies ist die exakte Startadresse unseres Bootloaderbereiches.&lt;br /&gt;
&lt;br /&gt;
Weiter oben wurde die Frage gestellt, woher der AVR weiß, an welcher Stelle (entweder 0x0000 oder in unserem Fall 0x1800) er nach dem Reset starten soll. Um dem AVR dies mitzuteilen, ist eine weitere Fuse nötig - die &#039;&#039;&#039;BOOTRST&#039;&#039;&#039;-Fuse. Eine weitere Tabelle aus dem Atmega88-Datenblatt gibt Auskunft über diese Fuse.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Reset and Interrupt Vectors Placement in Atmega88, Tabelle 11-3 im Atmega88-Datenblatt S.58&lt;br /&gt;
|- &lt;br /&gt;
!  BOOTRST|| IVSEL || Reset Adress || Interrupt Vectors Start Adress&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 0 || 0x000 || 0x001 &lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1 || 0x000 || Boot Reset Address + 0x001 &lt;br /&gt;
|-&lt;br /&gt;
| 0 || 0 || Boot Reset Address || 0x001 &lt;br /&gt;
|-&lt;br /&gt;
| 0 || 1 || Boot Reset Address || Boot Reset Address + 0x001 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Mit der &#039;&#039;&#039;BOOTRST&#039;&#039;&#039;-Fuse wird festgelegt, dass der AVR nach dem Reset an die Startadresse der Bootloader Sektion im Flash springt. Auf das &#039;&#039;&#039;IVSEL&#039;&#039;&#039;-Bit (keine Fuse) möchte ich erst an späterer Stelle - wenn es um Interrupts geht - zurückkommen.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Noch ein wichtiger Hinweis für die Werte der Fuses im Datenblatt:&#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;Der Wert &amp;quot;0&amp;quot; bedeutet, dass die Fuse programmiert ist, es entspicht dem Häkchen im AVR Studio!&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
= Der &amp;quot;Hallo Welt&amp;quot; - Bootloader =&lt;br /&gt;
&lt;br /&gt;
Wie oben erwähnt, wird für die Erstellung des Codes die kostenlose IDE von Atmel - das AVRStudio - benutzt. Ergänzt wird es durch C-Compiler und Tools des WinAVR Projektes. Des weiteren wird zur seriellen Kommunikation das Terminalprogramm benötigt. Im Tutorial wird PuTTY verwendet und sollte installiert sein. Die Hardware ist aufgebaut und via AVRISPmkII-Programmer an den PC angeschlossen - nun kann es losgehen!&lt;br /&gt;
&lt;br /&gt;
Zu Beginn wird ein neues AVRStudio-Projekt erstellt. Danach werden folgende Schritte abgearbeitet:&lt;br /&gt;
&lt;br /&gt;
== Schritt 1 - Konfiguration der Projekteinstellungen ==&lt;br /&gt;
[[Bild:Bootloader-Projekt.png|200px|thumb|Erstellen des Projekts]]&lt;br /&gt;
[[Bild:Bootloader-Config-General.PNG|200px|thumb|Generelle Optionen - setzten der Taktfrequenz]]&lt;br /&gt;
[[Bild:Bootloader-Config-Linker.png|200px|thumb|Linker Option eingeben]]&lt;br /&gt;
&lt;br /&gt;
Als erstes öffnen wir die Projekteinstellungen (Menü &#039;&#039;Project/Configuration Options&#039;&#039;) und tragen die richtige Taktfrequenz ein (Im Beispiel nutzen wir den internen Oszillator mit 8 Mhz). Danach gehen wir zum Reiter &#039;&#039;&#039;Custom Options&#039;&#039;&#039;. Dort klicken wir auf &#039;&#039;&#039;Linker Options&#039;&#039;&#039; und geben dann im Textfeld daneben &#039;&#039;&#039;-Ttext=0x1800&#039;&#039;&#039; ein. Danach drücken wir auf &#039;&#039;&#039;Add&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
Was bewirkt dieser Linker-Parameter? Dafür muß wieder etwas weiter ausgeholt werden. Nach dem Kompilieren der Programmquellen &#039;&#039;linkt&#039;&#039; der Linker den Programmcode an bestimmte Stellen in den drei verschiedenen Speichern Flash, EEPROM und SRAM des AVR. In der vom Compiler verwendeten [http://www.nongnu.org/avr-libc/user-manual/mem_sections.html AVR Libc] ist der Speicher in verschiedene Sektionen aufgeteilt. Dem Linker muss mitgeteilt werden, in welche Speicher er den Programmcode linken soll. Die Lokalisierung des Speichers sind die Sektionen. Die Sektion &#039;&#039;.text&#039;&#039; ist dem ausführbaren Programmcode - also den Befehlen - vorbehalten und liegt im Flash des AVR, des weiteren gibt es auch noch die Sektionen &#039;&#039;.data&#039;&#039; und &#039;&#039;.bss&#039;&#039; für die statischen und dynamischen Variablen im SRAM und eine Sektion &#039;&#039;.eeprom&#039;&#039; für den EEPROM und noch ein paar spezielle (Flash-)Sektionen.&lt;br /&gt;
&lt;br /&gt;
Nun gibt es verschiedene Methoden, dem Linker mitzuteilen, dass man den Programmcode an die Stelle des Bootloaderbereichs haben möchte. Eine sehr einfache Methode ist &#039;&#039;&#039;die Verschiebung der Sektion &#039;&#039;&#039; &#039;&#039;&#039;&#039;&#039;.text&#039;&#039;&#039;&#039;&#039;, welche normalerweise ab Adresse 0x0000 beginnt. Eben dies geschieht mit dem Linker Parameter &#039;&#039;&#039;-Ttext=0x1800&#039;&#039;&#039;. Die Adresse des Beginns der &#039;&#039;.text&#039;&#039; Sektion wird auf die (Byte-)Adresse 0x1800 gesetzt.&lt;br /&gt;
&lt;br /&gt;
== Schritt 2 - Einbinden der UART Library von Peter Fleury ==&lt;br /&gt;
&lt;br /&gt;
Wie bereits erwähnt, wird für die serielle Kommunikation auf der AVR-Seite die UART-Library von [http://www.jump.to/fleury Peter Fleury] verwendet. Nach dem Download werden die uart.c und uart.h in das Projekt eingebunden (für die uart.c im AVR Studio rechte Maustaste auf &#039;&#039;Source Files&#039;&#039; und dann &#039;&#039;Add Existing Source File(s)...&#039;&#039; und für die uart.h die rechte Maustaste auf &#039;&#039;Header Files&#039;&#039; und dann &#039;&#039;Add Existing Header File(s)...&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
== Schritt 3 - Programmieren des Bootloaders ==&lt;br /&gt;
&lt;br /&gt;
[[Bild:Bootloader-Config-Linker-ok.PNG|200px|thumb|Linker Option nach Add]]&lt;br /&gt;
[[Bild:Bootloader-AVRStudio.PNG|200px|thumb|Kompilieren des Bootloaders]]&lt;br /&gt;
&lt;br /&gt;
Nun soll eine kleine Applikation geschrieben werden. Keine Angst, unser erstes Ziel ist es, eine kleine Anwendung in dem Bootloaderbereich zu positionieren, welche serielle Ein-und Ausgaben behandelt. Die eigentliche Bootloaderfunktionalität kommt später dazu. Also schreiben wir die Datei &#039;&#039;main.c&#039;&#039; wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/boot.h&amp;gt;&lt;br /&gt;
#include &amp;lt;util/delay.h&amp;gt;&lt;br /&gt;
#include &amp;quot;uart.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
#define BOOT_UART_BAUD_RATE     9600     /* Baudrate */&lt;br /&gt;
#define XON                     17       /* XON Zeichen */&lt;br /&gt;
#define XOFF                    19       /* XOFF Zeichen */&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
    unsigned int 	c=0;               /* Empfangenes Zeichen + Statuscode */&lt;br /&gt;
    unsigned char	temp,              /* Variable */&lt;br /&gt;
                        flag=1,            /* Flag zum steuern der Endlosschleife */&lt;br /&gt;
			p_mode=0;	   /* Flag zum steuern des Programmiermodus */&lt;br /&gt;
    void (*start)( void ) = 0x0000;        /* Funktionspointer auf 0x0000 */&lt;br /&gt;
 &lt;br /&gt;
    /* Interrupt Vektoren verbiegen */&lt;br /&gt;
&lt;br /&gt;
    char sregtemp = SREG;&lt;br /&gt;
    cli();&lt;br /&gt;
    temp = MCUCR;&lt;br /&gt;
    MCUCR = temp | (1&amp;lt;&amp;lt;IVCE);&lt;br /&gt;
    MCUCR = temp | (1&amp;lt;&amp;lt;IVSEL);&lt;br /&gt;
    SREG = sregtemp;&lt;br /&gt;
 &lt;br /&gt;
    /* Einstellen der Baudrate und aktivieren der Interrupts */&lt;br /&gt;
    uart_init( UART_BAUD_SELECT(BOOT_UART_BAUD_RATE,F_CPU) ); &lt;br /&gt;
    sei();&lt;br /&gt;
 &lt;br /&gt;
    uart_puts(&amp;quot;Hallo hier ist der Bootloader\n\r&amp;quot;);&lt;br /&gt;
    _delay_ms(1000);&lt;br /&gt;
 &lt;br /&gt;
    do&lt;br /&gt;
    {&lt;br /&gt;
        c = uart_getc();&lt;br /&gt;
        if( !(c &amp;amp; UART_NO_DATA) )&lt;br /&gt;
        {&lt;br /&gt;
            switch((unsigned char)c)&lt;br /&gt;
            {&lt;br /&gt;
                 case &#039;q&#039;: &lt;br /&gt;
		     flag=0;&lt;br /&gt;
                     uart_puts(&amp;quot;Verlasse den Bootloader!\n\r&amp;quot;);&lt;br /&gt;
                     break;&lt;br /&gt;
                  default:&lt;br /&gt;
                     uart_puts(&amp;quot;Du hast folgendes Zeichen gesendet: &amp;quot;);&lt;br /&gt;
                     uart_putc((unsigned char)c);&lt;br /&gt;
                     uart_puts(&amp;quot;\n\r&amp;quot;);&lt;br /&gt;
                     break;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    while(flag);&lt;br /&gt;
 &lt;br /&gt;
    uart_puts(&amp;quot;Springe zur Adresse 0x0000!\n\r&amp;quot;);&lt;br /&gt;
    _delay_ms(1000);&lt;br /&gt;
&lt;br /&gt;
    /* vor Rücksprung eventuell benutzte Hardware deaktivieren&lt;br /&gt;
       und Interrupts global deaktivieren, da kein &amp;quot;echter&amp;quot; Reset erfolgt */&lt;br /&gt;
&lt;br /&gt;
    /* Interrupt Vektoren wieder gerade biegen */&lt;br /&gt;
    cli();&lt;br /&gt;
    temp = MCUCR;&lt;br /&gt;
    MCUCR = temp | (1&amp;lt;&amp;lt;IVCE);&lt;br /&gt;
    MCUCR = temp &amp;amp; ~(1&amp;lt;&amp;lt;IVSEL);&lt;br /&gt;
&lt;br /&gt;
    /* Rücksprung zur Adresse 0x0000 */&lt;br /&gt;
    start(); &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Erklärung des Codes&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Beginnen wir mit den Defines: Die Baudrate erklärt sich von selbst. Die Defines XON und XOFF werden später, wenn die Bootloader-Funktionalität dazukommt, zur Flusssteuerung gebraucht. Wir werden also die XON/XOFF-Flussteuerung nutzen (merken für die Einstellung von PuTTY). &lt;br /&gt;
&lt;br /&gt;
Bei den Variablen ist nur eine interessant: Der Funktionspointer &amp;lt;pre&amp;gt;void (*start)( void ) = 0x0000;&amp;lt;/pre&amp;gt; ist ein einfacher Trick, um mit dem Programmcounter (PC) zur Adresse 0x0000 zu springen. Wir definieren einfach eine (fiktive) Funktion an der Stelle 0x0000. Beim Aufruf der Funktion mit &amp;lt;pre&amp;gt;start();&amp;lt;/pre&amp;gt; springt der Programmcounter und damit das Programm an Adresse 0x0000 und das Anwendungsprogramm - wenn es eins gibt - kann starten. &lt;br /&gt;
&lt;br /&gt;
Nun folgt ein sehr wichtiger Teil, auf den ich noch eingehen muss - die Interrupt-Vektoren. Interrupt-Vektoren sind Einsprungpunkte der Interrupts, welche normalerweise fest ab Adresse 0x0001 im Flash liegen. Wird ein Interrupt ausgelöst, springt der AVR automatisch zu der festen Flash-Adresse. Von dort aus - wenn eine ISR programmiert ist - springt der Controller zur ISR (&#039;&#039;&#039;I&#039;&#039;&#039;nterrupt &#039;&#039;&#039;S&#039;&#039;&#039;ervice &#039;&#039;&#039;R&#039;&#039;&#039;outine). Nun haben wir folgendes Problem: Wenn wir den Bootloadercode ab der Adresse 0x1800 ausführen, nützt es uns gar nichts, wenn der AVR nach Auslösen eines Interrupts an die Stelle 0x0001 + X springt, da dieser Speicherbereich ja im Zweifelsfalle sogar von uns überschrieben wird. Unser Code soll nur ab Adresse 0x1800 stehen! Wir müssen also die Sprungtabelle &amp;quot;verbiegen&amp;quot;, d.h. den AVR veranlassen, bei Auslösung eines Interrupts an Adresse 0x1801 + X zu springen und dann zur ISR. Das Verbiegen der Sprungtabelle passiert mit dem Setzen des &#039;&#039;&#039;IVSEL&#039;&#039;&#039;-Bits im &#039;&#039;&#039;MCUCR&#039;&#039;&#039; (ACHTUNG: beim Atmega8 &#039;&#039;&#039;GICR&#039;&#039;&#039;), also&lt;br /&gt;
&lt;br /&gt;
beim Atmega88:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
temp = MCUCR;&lt;br /&gt;
MCUCR = temp | (1&amp;lt;&amp;lt;IVCE);&lt;br /&gt;
MCUCR = temp | (1&amp;lt;&amp;lt;IVSEL);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
bzw. beim Atmega8:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
temp = GICR;&lt;br /&gt;
GICR = temp | (1&amp;lt;&amp;lt;IVCE);&lt;br /&gt;
GICR = temp | (1&amp;lt;&amp;lt;IVSEL);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Das &#039;&#039;&#039;IVCE&#039;&#039;&#039;-Bit wird nur benötigt, um dem Mikrocontroller zu sagen, dass wir als nächstes den Parameter &#039;&#039;&#039;IVSEL&#039;&#039;&#039; setzen wollen, das Bit wird nachher vom Controller wieder gelöscht. Um versehentliches verstellen der Interrupttabelle zu vermeiden muss das setzen von &#039;&#039;&#039;IVCE&#039;&#039;&#039; und &#039;&#039;&#039;IVSEL&#039;&#039;&#039; innerhalb von 4 Taktzyklen erfolgen. Um dies zu gewährleisten müssen alle interrupts während des Setzens deaktiviert sein. ACHTUNG Stolperfalle: Die Variable temp wird benötigt, da beim Setzen von &#039;&#039;&#039;IVSEL&#039;&#039;&#039; gleichzeitig &#039;&#039;&#039;IVCE&#039;&#039;&#039; gelöscht werden muss:&lt;br /&gt;
&lt;br /&gt;
bei Atmega8/16:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
GICR |= (1&amp;lt;&amp;lt;IVCE);   // noch richtig. IVCE wird gesetzt&lt;br /&gt;
GICR |= (1&amp;lt;&amp;lt;IVSEL);  // falsch! IVSEL wird zwar gesetzt, &lt;br /&gt;
                        IVCE bleibt jedoch in diesem Prozessortakt gesetzt.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In der Hauptschleife wird lediglich gepollt, ob ein neues Zeichen von der Konsole kommt. Nach dem Empfang eines Zeichens wird es ausgewertet (switch). Nach dem Drücken von &#039;&#039;&amp;quot;q&amp;quot;&#039;&#039; verlässt der Bootloader die Hauptschleife, setzt die Interrupt-Vektoren wieder zurück und startet die Hauptanwendung - wenn eine da ist.&lt;br /&gt;
&lt;br /&gt;
Nach dem Kompilieren sagt uns der Linker, dass 754 Byte Programmspeicher und 265 Byte Datenspeicher verbraucht wurde. 754 Byte ist weit unter den 2048 Byte, welche uns ab der Adresse 0x1800 zur Verfügung stehen, wir haben also alles richtig gemacht.&lt;br /&gt;
&lt;br /&gt;
Nun kontrollieren wir noch schnell, ob das Programm an der richtigen Stelle im Flash steht. Mit dem Hex-File (Bootloader.hex) wird auch ein List-File (Bootloader.lss) erzeugt. Im List-File findet sich das disassemblierte Programm und die Speicherzuordnungen. Hier ein Auszug der Datei:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Bootloader.elf:     file format elf32-avr&lt;br /&gt;
&lt;br /&gt;
Sections:&lt;br /&gt;
Idx Name          Size      VMA       LMA       File off  Algn&lt;br /&gt;
  0 .data         00000080  00800100  00001a68  000002fc  2**0&lt;br /&gt;
                  CONTENTS, ALLOC, LOAD, DATA&lt;br /&gt;
  1 .text         00000268  00001800  00001800  00000094  2**1&lt;br /&gt;
                  CONTENTS, ALLOC, LOAD, READONLY, CODE&lt;br /&gt;
  2 .bss          00000085  00800180  00800180  0000037c  2**0&lt;br /&gt;
                  ALLOC&lt;br /&gt;
  3 .debug_aranges 00000040  00000000  00000000  0000037c  2**0&lt;br /&gt;
                  CONTENTS, READONLY, DEBUGGING&lt;br /&gt;
  4 .debug_pubnames 00000095  00000000  00000000  000003bc  2**0&lt;br /&gt;
                  CONTENTS, READONLY, DEBUGGING&lt;br /&gt;
  5 .debug_info   00000459  00000000  00000000  00000451  2**0&lt;br /&gt;
                  CONTENTS, READONLY, DEBUGGING&lt;br /&gt;
  6 .debug_abbrev 00000238  00000000  00000000  000008aa  2**0&lt;br /&gt;
                  CONTENTS, READONLY, DEBUGGING&lt;br /&gt;
  7 .debug_line   000003eb  00000000  00000000  00000ae2  2**0&lt;br /&gt;
                  CONTENTS, READONLY, DEBUGGING&lt;br /&gt;
  8 .debug_frame  000000a0  00000000  00000000  00000ed0  2**2&lt;br /&gt;
                  CONTENTS, READONLY, DEBUGGING&lt;br /&gt;
  9 .debug_str    000001cf  00000000  00000000  00000f70  2**0&lt;br /&gt;
                  CONTENTS, READONLY, DEBUGGING&lt;br /&gt;
 10 .debug_loc    0000024a  00000000  00000000  0000113f  2**0&lt;br /&gt;
                  CONTENTS, READONLY, DEBUGGING&lt;br /&gt;
 11 .debug_ranges 00000048  00000000  00000000  00001389  2**0&lt;br /&gt;
                  CONTENTS, READONLY, DEBUGGING&lt;br /&gt;
&lt;br /&gt;
Disassembly of section .text:&lt;br /&gt;
&lt;br /&gt;
00001800 &amp;lt;__vectors&amp;gt;:&lt;br /&gt;
    1800:	19 c0       	rjmp	.+50     	; 0x1834 &amp;lt;__ctors_end&amp;gt;&lt;br /&gt;
    1802:	33 c0       	rjmp	.+102    	; 0x186a &amp;lt;__bad_interrupt&amp;gt;&lt;br /&gt;
    1804:	32 c0       	rjmp	.+100    	; 0x186a &amp;lt;__bad_interrupt&amp;gt;&lt;br /&gt;
    1806:	31 c0       	rjmp	.+98     	; 0x186a &amp;lt;__bad_interrupt&amp;gt;&lt;br /&gt;
    1808:	30 c0       	rjmp	.+96     	; 0x186a &amp;lt;__bad_interrupt&amp;gt;&lt;br /&gt;
    180a:	2f c0       	rjmp	.+94     	; 0x186a &amp;lt;__bad_interrupt&amp;gt;&lt;br /&gt;
    180c:	2e c0       	rjmp	.+92     	; 0x186a &lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
(viele Zeilen)&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
0000186c &amp;lt;main&amp;gt;:&lt;br /&gt;
#define BOOT_UART_BAUD_RATE     9600     /* Baudrate */&lt;br /&gt;
#define XON                     17       /* XON Zeichen */&lt;br /&gt;
#define XOFF                    19       /* XOFF Zeichen */&lt;br /&gt;
 &lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
    186c:	cf 93       	push	r28&lt;br /&gt;
    186e:	df 93       	push	r29&lt;br /&gt;
    unsigned char	temp,            /* Variable */&lt;br /&gt;
                        flag=1;          /* Flag zum steuern der Endlosschleife */&lt;br /&gt;
    void (*start)( void ) = 0x0000;    /* Funktionspointer auf 0x0000 */&lt;br /&gt;
 &lt;br /&gt;
    /* Interrupt Vektoren verbiegen */&lt;br /&gt;
    temp = MCUCR;&lt;br /&gt;
    1870:	85 b7       	in	r24, 0x35	; 53&lt;br /&gt;
    MCUCR = temp | (1&amp;lt;&amp;lt;IVCE);&lt;br /&gt;
    1872:	98 2f       	mov	r25, r24&lt;br /&gt;
    1874:	91 60       	ori	r25, 0x01	; 1&lt;br /&gt;
    1876:	95 bf       	out	0x35, r25	; 53&lt;br /&gt;
    MCUCR = temp | (1&amp;lt;&amp;lt;IVSEL);&lt;br /&gt;
    1878:	82 60       	ori	r24, 0x02	; 2&lt;br /&gt;
    187a:	85 bf       	out	0x35, r24	; 53&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
(noch mehr Zeilen)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir erkennen, dass die Sektion &#039;&#039;.text&#039;&#039; ab der Adresse (VMA) 0x1800 beginnt. Weiter sehen wir im Disassembly der Sektion &#039;&#039;.text&#039;&#039;, dass unser Programm mit der Interrupt-Einsprungstabelle ab Adresse 0x1800 beginnt. Unsere &#039;&#039;main()&#039;&#039; beginnt ab Adresse 0x186C. Super. Das hat geklappt. Aber nun schnell zu Schritt 4 - dem Flashen und Ausprobieren des Programms...&lt;br /&gt;
&lt;br /&gt;
== Schritt 4 - Flashen und Ausprobieren des Bootloaders ==&lt;br /&gt;
&lt;br /&gt;
[[Bild:Bootloader-AVRStudio-Fuses.png|200px|thumb|Setzen der Fuses]]&lt;br /&gt;
[[Bild:PuTTY-Serconfig.png|200px|thumb|Serielle Konfiguration von PuTTY]]&lt;br /&gt;
[[Bild:PuTTY-Serconfig-xon.png|200px|thumb|Serielle Konfiguration von PuTTY]]&lt;br /&gt;
&lt;br /&gt;
Nach dem Start des AVRISPmkII-In-System-Programmers aus dem AVRStudio werden zunächst die Einstellungen geprüft. Die Signatur des AVRs muss stimmen und die ISP-Frequenz. Im Reiter Program muss unter &#039;&#039;Flash&#039;&#039; die richtige Datei angegeben sein (&#039;&#039;Bootloader.hex&#039;&#039;). Danach können wir uns an das setzen der Fuses machen. &#039;&#039;&#039;CKDIV8&#039;&#039;&#039; sollte ausgeschalten werden, der interne Takt von 8 Mhz sollte genutzt werden (&#039;&#039;&#039;SUT_CKSEL&#039;&#039;&#039;) und &#039;&#039;BOOTSZ&#039;&#039; auf 1024 words gestellt werden. Zusätzlich muß die &#039;&#039;&#039;BOOTRST&#039;&#039;&#039;-Fuse gesetzt werden, damit der Bootloader an der richtigen Adresse anfängt. Für alle, die einen anderen Programmer benutzen (z.B. avrdude), hier die exakten Werte der Fuses:&lt;br /&gt;
* Low Fuse: &#039;&#039;&#039;0xE2&#039;&#039;&#039;&lt;br /&gt;
* High Fuse: &#039;&#039;&#039;0xD2&#039;&#039;&#039;&lt;br /&gt;
* Extended Fuse: &#039;&#039;&#039;0xF8&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Jetzt kann PuTTY gestartet und konfiguriert werden. Der &#039;&#039;Connection type&#039;&#039; muss auf &#039;&#039;&#039;Serial&#039;&#039;&#039; gestellt werden. Die Baudrate beträgt 9600 Baud. Unter &#039;&#039;Connection/Serial&#039;&#039; muss der &#039;&#039;Flow control&#039;&#039; auf &#039;&#039;&#039;XON/XOFF&#039;&#039;&#039; gestellt werden. Nach dem Konfigurieren kann die Konsole mit &#039;&#039;Open&#039;&#039; geöffnet werden.&lt;br /&gt;
&lt;br /&gt;
Jetzt kann wieder in das AVR Studio gewechselt werden. Mit einem beherztem Druck auf &#039;&#039;Program&#039;&#039; wird das Flash im ATmega88 programmiert. Nach dem Wechsel auf die Konsole erscheint folgendes Bild:&lt;br /&gt;
&lt;br /&gt;
[[Bild:PuTTY-Bootloader-start.png|600px|Bootloader in PuTTY]]&lt;br /&gt;
&lt;br /&gt;
Nach dem Drücken von ein paar Tasten erscheint folgendes:&lt;br /&gt;
&lt;br /&gt;
[[Bild:PuTTY-Bootloader-taste.png|600px|Bootloader nach Tastendruck in PuTTY]]&lt;br /&gt;
&lt;br /&gt;
Nach dem Drücken von &#039;&#039;&#039;q&#039;&#039;&#039; erscheint folgendes Bild:&lt;br /&gt;
&lt;br /&gt;
[[Bild:PuTTY-Bootloader-restart.png|600px|Bootloader nach Tastendruck in PuTTY]]&lt;br /&gt;
&lt;br /&gt;
Der Bootloader versucht, zur Adresse 0x0000 zu springen, wo er allerdings keinen Programmcode findet. Wie auch? Wir haben ja den ganzen Flash des AVR gerade gelöscht und mit dem Bootloader gefüllt. Nun muss man wissen, dass in einem gelöschten Flash &#039;&#039;0xFF&#039;&#039; in jeder Speicherzelle steht. &#039;&#039;0xFF&#039;&#039; ist für den AVR kein gültiger Opcode. Der Programmzähler zählt nur um eins nach oben. Damit hopst er sozusagen durch den gesamten Flash bis er wieder beim Bootloader landet.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;[http://de.wikipedia.org/wiki/Heureka Heureka]&#039;&#039;&#039;&#039;&#039; wir haben es geschafft! Ein Programm wird im Bootloaderbereich des Flashs ausgeführt! Es &#039;&#039;bootet&#039;&#039; zwar schon schön, aber es &#039;&#039;loadet&#039;&#039; noch nichts in den Flash. Aber die halbe Miete haben wir damit schon. Nun schreiben wir erst einmal eine kleine Anwendung, welche wir nach der Erweiterung unseres Bootloaders in den Flash-Speicher laden.&lt;br /&gt;
&lt;br /&gt;
= Die Test-Anwendung =&lt;br /&gt;
&lt;br /&gt;
[[Bild:Anwendung-AVRStudio.png|200px|thumb|Erstellen des Projektes]]&lt;br /&gt;
[[Bild:Anwendung-AVRStudio-Code.png|200px|thumb|Sourcecode im AVRStudio]]&lt;br /&gt;
&lt;br /&gt;
Die Kategorie Anwendung möchte ich möglichst kurz halten. Ziel ist es, eine kleine Anwendung zu schreiben, welche dann mit dem (echten) Bootloader ins Flash gespeichert wird. &lt;br /&gt;
&lt;br /&gt;
== Schritt 1 - Erstellen des Projektes ==&lt;br /&gt;
&lt;br /&gt;
Nach dem Erstellen eines neuen Projektes muss in den Projekt-Einstellungen des AVR Studios nur die Taktfrequenz eingetragen werden. Die Linker-Optionen werden nicht verändert, also bleibt wie es ist.&lt;br /&gt;
&lt;br /&gt;
== Schritt 2 - Einbinden der UART Library ==&lt;br /&gt;
&lt;br /&gt;
Dieser Schritt kann vom Bootloader übernommen werden. Es wird wieder die UART-Bibliothek von Peter Fleury verwendet.&lt;br /&gt;
&lt;br /&gt;
== Schritt 3 - Programmieren der Anwendung ==&lt;br /&gt;
&lt;br /&gt;
Wir starten also ein neues AVR Studio und legen ein neues Projekt an, konfigurieren die Taktfrequenz (8 MHz) und laden die &#039;&#039;uart.c&#039;&#039; und &#039;&#039;uart.h&#039;&#039; dazu. Nun schreiben wir in die &#039;&#039;main.c&#039;&#039; folgende Zeilen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
#include &amp;lt;util/delay.h&amp;gt;&lt;br /&gt;
#include &amp;quot;uart.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define UART_BAUD_RATE	9600&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
   unsigned int 	c;&lt;br /&gt;
   void (*bootloader)( void ) = 0x1800;&lt;br /&gt;
&lt;br /&gt;
   uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) ); &lt;br /&gt;
   sei();&lt;br /&gt;
    &lt;br /&gt;
   uart_puts_P(&amp;quot;\n\rHier ist das Anwendungsprogramm...&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
   for(;;)&lt;br /&gt;
   {&lt;br /&gt;
       c = uart_getc();&lt;br /&gt;
       if(!(c &amp;amp; UART_NO_DATA))&lt;br /&gt;
       {&lt;br /&gt;
	   switch( (unsigned char)c)&lt;br /&gt;
	   {&lt;br /&gt;
	       case &#039;b&#039;:&lt;br /&gt;
		   uart_puts(&amp;quot;\n\rSpringe zum Bootloader...&amp;quot;);&lt;br /&gt;
		   _delay_ms(1000);&lt;br /&gt;
		    bootloader();&lt;br /&gt;
		    break;&lt;br /&gt;
		default:&lt;br /&gt;
                    uart_puts(&amp;quot;\n\rDu hast folgendes Zeichen gesendet: &amp;quot;);&lt;br /&gt;
		    uart_putc((unsigned char)c);&lt;br /&gt;
		    break;&lt;br /&gt;
	    }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Erklärung des Codes&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Viel interessantes ist nicht an diesem Code. Es gibt wie immer die berühmte Endlosschleife. Wir definieren wieder einen fiktiven Funktionspointer&amp;lt;pre&amp;gt;void (*bootloader)( void ) = 0x1800;&amp;lt;/pre&amp;gt; Nach drücken der Taste &#039;&#039;&#039;b&#039;&#039;&#039; soll das Programm wieder zum Bootloader springen.&lt;br /&gt;
&lt;br /&gt;
Nach dem Kompilieren des Programms sehen wir, dass der Programmspeicher mit 686 Byte belegt ist, der Datenspeicher mit 201 Bytes.&lt;br /&gt;
&lt;br /&gt;
== Schritt 4 - Ausprobieren der Anwendung ==&lt;br /&gt;
&lt;br /&gt;
Wer möchte kann die Anwendung auf den AVR flashen und ausprobieren. Die Funktion sollte sich von selbst erschließen.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Achtung:&#039;&#039;&#039; Es muss darauf geachtet werden, dass beim flashen der Anwendung nicht der Bootloader überschrieben wird.&amp;lt;br&amp;gt;Bei Verwendung von avrdude muss dazu die Option &amp;quot;-D&amp;quot; angegeben werden.&lt;br /&gt;
&lt;br /&gt;
Nun wollen wir uns der Erweiterung des Bootloaders widmen.&lt;br /&gt;
&lt;br /&gt;
= Der &amp;quot;echte&amp;quot; Bootloader =&lt;br /&gt;
[[Bild:Real-Bootloader-AVRStudio.png|200px|thumb|Programmieren des Bootloaders]]&lt;br /&gt;
&lt;br /&gt;
Zum Erstellen des Bootloaders wird wieder Schrittweise vorgegangen. Folgende Schritte sind zu befolgen:&lt;br /&gt;
&lt;br /&gt;
== Schritt 1 und 2 - siehe &amp;quot;Hallo Welt&amp;quot; Bootloader ==&lt;br /&gt;
Schritt 1 und 2 können vom &amp;quot;Hallo Welt&amp;quot; Bootloader übernommen werden. Es sind wieder die korrekte Taktfrequenz und die Verschiebung der Sektion &#039;&#039;&#039;.text&#039;&#039;&#039; auf die Bootresetadresse einzustellen.&lt;br /&gt;
&lt;br /&gt;
== Schritt 3 - Programmieren des Bootloaders ==&lt;br /&gt;
&lt;br /&gt;
Nun soll der Bootloader erweitert werden. Nach dem Kompilieren des Anwendungsprogramms erhalten wir eine Datei &#039;&#039;Anwendung.hex&#039;&#039; im [http://de.wikipedia.org/wiki/Intel_HEX Intel-HEX-Format]. Da wir im Bootloader diese Daten auswerten müssen, wollen wir uns kurz mit dem Format beschäftigen. Das Intel-HEX-Format ist geschaffen worden, um Binärdaten als ASCII-Daten zu übertragen. Jedes Byte ist in Form von zwei ASCII-Zeichen gespeichert, d.h. aus der Zahl &#039;&#039;0x4A&#039;&#039; wird die ASCII-Zeichenfolge &#039;&#039;&amp;quot;4A&amp;quot;&#039;&#039;. Das bedeutet aber auch, dass aus den Binärdaten die doppelte Anzahl von Zeichen wird, welche übertragen werden müssen, hinzu kommen noch Steuerzeichen und Zusatzinformationen. Jede Zeile in der Intel-HEX-Datei folgt einem bestimmten Schema, in dem u.a. die Anzahl der Bytes, die Zieladresse und Checksumme stehen.&lt;br /&gt;
&lt;br /&gt;
Für weiterführende Erklärungen zum Thema HEX-Datei-Format empfehle ich folgende Lektüre:&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Intel_HEX Wikipedia Artikel über HEX-Files]&lt;br /&gt;
* [http://www.rn-wissen.de/index.php/HEX-Datei RN-Wissen-Artikel über HEX-Files]&lt;br /&gt;
* [http://www.schulz-koengen.de/biblio/intelhex.htm Artikel von Wolfgang R.Schulz]&lt;br /&gt;
&lt;br /&gt;
Unser Bootloader muss in der Lage sein, dieses Format zu interpretieren. Wir müssen also einen Parser schreiben. &#039;&#039;Oje&#039;&#039; werden manche denken, das ist ja wieder ein Thema für sich. Das stimmt prinzipiell auch. Allerdings kommt uns hier das einfache Format der Intel-Hex-Datei zugute, welches den Aufwand in Grenzen hält.&lt;br /&gt;
&lt;br /&gt;
Also erstes brauchen wir also Funktionen, um die ASCII-Zeichenfolgen wieder in Binärdaten umzuwandeln. Normalerweise könnte man dafür die C-Funktion [http://www.nongnu.org/avr-libc/user-manual/group__avr__stdlib.html#gaf8ce3b8dae3d45c34c3b172de503f7b3 strtol] aus der stdlib.h nehmen. Allerdings würde das Benutzen dieses Befehls das Linken der Standardbibliothek nach sich ziehen und damit den Code unnötig aufblähen. Daher werden wir uns eine einfache eigene Funktion schreiben, um die Zeichenfolgen umzuwandeln. In der HEX-Datei kommen 2 Byte und 4 Byte Hex-Zahlen im ASCII-Format vor. Wir brauchen also eine Funktion, welche die ASCII-Zeichenfolgen in Zahlen umwandelt, hier ist sie:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
static uint16_t hex2num(const uint8_t * ascii, uint8_t num)&lt;br /&gt;
{&lt;br /&gt;
    uint8_t  i;&lt;br /&gt;
    uint16_t val = 0;&lt;br /&gt;
 &lt;br /&gt;
    for (i=0; i&amp;lt;num; i++)&lt;br /&gt;
    {&lt;br /&gt;
        uint8_t c = ascii[i];&lt;br /&gt;
        &lt;br /&gt;
        /* Hex-Ziffer auf ihren Wert abbilden */&lt;br /&gt;
        if (c &amp;gt;= &#039;0&#039; &amp;amp;&amp;amp; c &amp;lt;= &#039;9&#039;)            c -= &#039;0&#039;;  &lt;br /&gt;
        else if (c &amp;gt;= &#039;A&#039; &amp;amp;&amp;amp; c &amp;lt;= &#039;F&#039;)       c -= &#039;A&#039; - 10;&lt;br /&gt;
        else if (c &amp;gt;= &#039;a&#039; &amp;amp;&amp;amp; c &amp;lt;= &#039;f&#039;)       c -= &#039;a&#039; - 10;&lt;br /&gt;
            &lt;br /&gt;
        val = 16 * val + c;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return val;  &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
Wir benutzen hier einen sehr einfachen Ansatz, um die Zahlen zu generieren. Die Funktionen wandeln die ASCII-Zeichen entsprechend ihrer Wertigkeit in Zahlen um. Soll z.B. das ASCII-Zeichen &#039;1&#039; umgewandelt werden, wird vom ASCII-Code &#039;1&#039;, also dezimal 49, 48=&#039;0&#039; abgezogen: 49 - 48 = 1, somit haben wir ein ASCII-Zeichen in eine Zahl umgewandelt. Wenn das ASCII-Zeichen &#039;C&#039; ist (Dezimal: 67), werden &#039;A&#039; - 10 = 65 -10 = 55 abgezogen, um 12 zu erhalten, den Wert der hex-Ziffer C. Näher möchte an dieser Stelle nicht darauf eingehen, wir wollen schnell weiter zum Beschreiben des Flashs kommen.&lt;br /&gt;
&lt;br /&gt;
Um in den Flash zu schreiben, werden wir Makros aus der &#039;&#039;[http://www.nongnu.org/avr-libc/user-manual/group__avr__boot.html boot.h]&#039;&#039; der avr-libc verwenden. Hier findet man alle Werkzeuge, die wir brauchen. Dabei sollte vor allen das &#039;&#039;API Usage Example&#039;&#039; in der [http://www.nongnu.org/avr-libc/user-manual/group__avr__boot.html Online Doku] näher betrachtet werden. Dieses Beispiel soll weitestgehend übernommen werden, da es die nötige Funktionalität beinhaltet. Hier ist die Funktion:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
void boot_program_page (uint32_t page, uint8_t *buf)&lt;br /&gt;
{&lt;br /&gt;
    uint16_t i;&lt;br /&gt;
    uint8_t sreg;&lt;br /&gt;
&lt;br /&gt;
    /* Disable interrupts.*/&lt;br /&gt;
    sreg = SREG;&lt;br /&gt;
    cli();&lt;br /&gt;
&lt;br /&gt;
    eeprom_busy_wait ();&lt;br /&gt;
&lt;br /&gt;
    boot_page_erase (page);&lt;br /&gt;
    boot_spm_busy_wait ();      /* Wait until the memory is erased. */&lt;br /&gt;
&lt;br /&gt;
    for (i=0; i&amp;lt;SPM_PAGESIZE; i+=2)&lt;br /&gt;
    {&lt;br /&gt;
        /* Set up little-endian word. */&lt;br /&gt;
        uint16_t w = *buf++;&lt;br /&gt;
        w += (*buf++) &amp;lt;&amp;lt; 8;&lt;br /&gt;
    &lt;br /&gt;
        boot_page_fill (page + i, w);&lt;br /&gt;
    }&lt;br /&gt;
    boot_page_write (page);     /* Store buffer in flash page.		*/&lt;br /&gt;
    boot_spm_busy_wait();       /* Wait until the memory is written.*/&lt;br /&gt;
&lt;br /&gt;
    /* Reenable RWW-section again. We need this if we want to jump back */&lt;br /&gt;
    /* to the application after bootloading. */&lt;br /&gt;
    boot_rww_enable ();&lt;br /&gt;
&lt;br /&gt;
    /* Re-enable interrupts (if they were ever enabled). */&lt;br /&gt;
    SREG = sreg;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
Als erstes fällt auf, dass man der Funktion die &#039;&#039;Page&#039;&#039;-Adresse übergibt. Es wird also immer seitenweise geschrieben. Dies ist eine Spezialität des Flash-Speichers. Es &#039;&#039;&#039;muss&#039;&#039;&#039; immer die gesamte Seite geschrieben werden, dafür gibt es einen &#039;&#039;Page&#039;&#039;-Puffer, welcher die Daten enthält, welche mit der nächsten Schreiboperation in die entsprechende Page geschrieben werden. Dabei werden die Daten Wortweise in den &#039;&#039;Page&#039;&#039;-Puffer geschrieben. Die wesentlichen Funktionen der Routine sind &#039;&#039;boot_page_erase(page)&#039;&#039;, &#039;&#039;boot_page_fill(page + i, w)&#039;&#039; und &#039;&#039;boot_page_write(page)&#039;&#039;. Nicht zu vergessen auch &#039;&#039;boot_spm_busy_wait()&#039;&#039;. Die Bedeutung der Funktionen (naja es sind eher Makros) findet man in der Dokumentation der AVR Libc. Im wesentlichen läuft das Schreiben einer &#039;&#039;Page&#039;&#039; so ab:&lt;br /&gt;
* &#039;&#039;Page&#039;&#039; löschen&lt;br /&gt;
* &#039;&#039;Page&#039;&#039;-Puffer befüllen (aus der Variable &#039;&#039;buf&#039;&#039;)&lt;br /&gt;
* &#039;&#039;Page&#039;&#039; schreiben&lt;br /&gt;
So einfach, so gut. Für den Bootloader bedeutet das, dass er die Daten sammeln muß, bis er genügend Daten für eine &#039;&#039;Page&#039;&#039; hat. Dann wird eine &#039;&#039;Page&#039;&#039; geschrieben und der Spaß fängt von vorn an.&lt;br /&gt;
&lt;br /&gt;
Mit diesen beiden Funktionen sind wir nun in der Lage, den Parser zu schreiben. Die &#039;&#039;main.c&#039;&#039; sieht folgt aus:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/boot.h&amp;gt;&lt;br /&gt;
#include &amp;lt;util/delay.h&amp;gt;&lt;br /&gt;
#include &amp;quot;uart.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define BOOT_UART_BAUD_RATE     9600     /* Baudrate */&lt;br /&gt;
#define XON                     17       /* XON Zeichen */&lt;br /&gt;
#define XOFF                    19       /* XOFF Zeichen */&lt;br /&gt;
#define START_SIGN              &#039;:&#039;      /* Hex-Datei Zeilenstartzeichen */&lt;br /&gt;
&lt;br /&gt;
/* Zustände des Bootloader-Programms */&lt;br /&gt;
#define BOOT_STATE_EXIT	        0        &lt;br /&gt;
#define BOOT_STATE_PARSER       1&lt;br /&gt;
&lt;br /&gt;
/* Zustände des Hex-File-Parsers */&lt;br /&gt;
#define PARSER_STATE_START      0&lt;br /&gt;
#define PARSER_STATE_SIZE       1&lt;br /&gt;
#define PARSER_STATE_ADDRESS    2&lt;br /&gt;
#define PARSER_STATE_TYPE       3&lt;br /&gt;
#define PARSER_STATE_DATA       4&lt;br /&gt;
#define PARSER_STATE_CHECKSUM   5&lt;br /&gt;
#define PARSER_STATE_ERROR      6&lt;br /&gt;
&lt;br /&gt;
void program_page (uint32_t page, uint8_t *buf)&lt;br /&gt;
{&lt;br /&gt;
    uint16_t i;&lt;br /&gt;
    uint8_t sreg;&lt;br /&gt;
&lt;br /&gt;
    /* Disable interrupts */&lt;br /&gt;
    sreg = SREG;&lt;br /&gt;
    cli();&lt;br /&gt;
&lt;br /&gt;
    eeprom_busy_wait ();&lt;br /&gt;
&lt;br /&gt;
    boot_page_erase (page);&lt;br /&gt;
    boot_spm_busy_wait ();      /* Wait until the memory is erased. */&lt;br /&gt;
&lt;br /&gt;
    for (i=0; i&amp;lt;SPM_PAGESIZE; i+=2)&lt;br /&gt;
    {&lt;br /&gt;
        /* Set up little-endian word. */&lt;br /&gt;
        uint16_t w = *buf++;&lt;br /&gt;
        w += (*buf++) &amp;lt;&amp;lt; 8;&lt;br /&gt;
    &lt;br /&gt;
        boot_page_fill (page + i, w);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    boot_page_write (page);     /* Store buffer in flash page.		*/&lt;br /&gt;
    boot_spm_busy_wait();       /* Wait until the memory is written.*/&lt;br /&gt;
&lt;br /&gt;
    /* Reenable RWW-section again. We need this if we want to jump back */&lt;br /&gt;
    /* to the application after bootloading. */&lt;br /&gt;
    boot_rww_enable ();&lt;br /&gt;
&lt;br /&gt;
    /* Re-enable interrupts (if they were ever enabled). */&lt;br /&gt;
    SREG = sreg;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
static uint16_t hex2num (const uint8_t * ascii, uint8_t num)&lt;br /&gt;
{&lt;br /&gt;
    uint8_t  i;&lt;br /&gt;
    uint16_t val = 0;&lt;br /&gt;
&lt;br /&gt;
    for (i=0; i&amp;lt;num; i++)&lt;br /&gt;
    {&lt;br /&gt;
        uint8_t c = ascii[i];&lt;br /&gt;
        &lt;br /&gt;
        /* Hex-Ziffer auf ihren Wert abbilden */&lt;br /&gt;
        if (c &amp;gt;= &#039;0&#039; &amp;amp;&amp;amp; c &amp;lt;= &#039;9&#039;)            c -= &#039;0&#039;;  &lt;br /&gt;
        else if (c &amp;gt;= &#039;A&#039; &amp;amp;&amp;amp; c &amp;lt;= &#039;F&#039;)       c -= &#039;A&#039; - 10;&lt;br /&gt;
        else if (c &amp;gt;= &#039;a&#039; &amp;amp;&amp;amp; c &amp;lt;= &#039;f&#039;)       c -= &#039;a&#039; - 10;&lt;br /&gt;
            &lt;br /&gt;
        val = 16 * val + c;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return val;  &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
                    /* Empfangenes Zeichen + Statuscode */&lt;br /&gt;
    uint16_t        c = 0, &lt;br /&gt;
                    /* Intel-HEX Zieladresse */&lt;br /&gt;
           	    hex_addr = 0,&lt;br /&gt;
                    /* Zu schreibende Flash-Page */&lt;br /&gt;
                    flash_page = 0,                    &lt;br /&gt;
                    /* Intel-HEX Checksumme zum Überprüfen des Daten */&lt;br /&gt;
                    hex_check = 0,&lt;br /&gt;
                    /* Positions zum Schreiben in der Datenpuffer */&lt;br /&gt;
                    flash_cnt = 0;&lt;br /&gt;
                    /* temporäre Variable */&lt;br /&gt;
    uint8_t         temp,&lt;br /&gt;
                    /* Flag zum steuern des Programmiermodus */&lt;br /&gt;
                    boot_state = BOOT_STATE_EXIT,&lt;br /&gt;
                    /* Empfangszustandssteuerung */&lt;br /&gt;
                    parser_state = PARSER_STATE_START,&lt;br /&gt;
                    /* Flag zum ermitteln einer neuen Flash-Page */&lt;br /&gt;
                    flash_page_flag = 1,&lt;br /&gt;
                    /* Datenpuffer für die Hexdaten*/&lt;br /&gt;
                    flash_data[SPM_PAGESIZE], &lt;br /&gt;
                    /* Position zum Schreiben in den HEX-Puffer */&lt;br /&gt;
                    hex_cnt = 0, &lt;br /&gt;
                    /* Puffer für die Umwandlung der ASCII in Binärdaten */&lt;br /&gt;
                    hex_buffer[5], &lt;br /&gt;
                    /* Intel-HEX Datenlänge */&lt;br /&gt;
                    hex_size = 0,&lt;br /&gt;
                    /* Zähler für die empfangenen HEX-Daten einer Zeile */&lt;br /&gt;
                    hex_data_cnt = 0, &lt;br /&gt;
                    /* Intel-HEX Recordtype */&lt;br /&gt;
                    hex_type = 0, &lt;br /&gt;
                    /* empfangene HEX-Checksumme */&lt;br /&gt;
                    hex_checksum=0;&lt;br /&gt;
                    /* Funktionspointer auf 0x0000 */&lt;br /&gt;
    void            (*start)( void ) = 0x0000; &lt;br /&gt;
 &lt;br /&gt;
    /* Füllen der Puffer mit definierten Werten */&lt;br /&gt;
    memset(hex_buffer, 0x00, sizeof(hex_buffer));&lt;br /&gt;
    memset(flash_data, 0xFF, sizeof(flash_data));&lt;br /&gt;
 &lt;br /&gt;
    /* Interrupt Vektoren verbiegen */&lt;br /&gt;
    temp = MCUCR;&lt;br /&gt;
    MCUCR = temp | (1&amp;lt;&amp;lt;IVCE);&lt;br /&gt;
    MCUCR = temp | (1&amp;lt;&amp;lt;IVSEL);&lt;br /&gt;
 &lt;br /&gt;
    /* Einstellen der Baudrate und aktivieren der Interrupts */&lt;br /&gt;
    uart_init( UART_BAUD_SELECT(BOOT_UART_BAUD_RATE,F_CPU) ); &lt;br /&gt;
    sei();&lt;br /&gt;
 &lt;br /&gt;
    uart_puts(&amp;quot;Hallo hier ist der echte Bootloader\n\r&amp;quot;);&lt;br /&gt;
    _delay_ms(2000);&lt;br /&gt;
 &lt;br /&gt;
    do&lt;br /&gt;
    {&lt;br /&gt;
        c = uart_getc();&lt;br /&gt;
        if( !(c &amp;amp; UART_NO_DATA) )&lt;br /&gt;
        {&lt;br /&gt;
             /* Programmzustand: Parser */&lt;br /&gt;
             if(boot_state == BOOT_STATE_PARSER)&lt;br /&gt;
             {&lt;br /&gt;
                  switch(parser_state)&lt;br /&gt;
                  {&lt;br /&gt;
                      /* Warte auf Zeilen-Startzeichen */&lt;br /&gt;
                      case PARSER_STATE_START:			&lt;br /&gt;
                          if((uint8_t)c == START_SIGN) &lt;br /&gt;
                          {&lt;br /&gt;
                              uart_putc(XOFF);&lt;br /&gt;
                              parser_state = PARSER_STATE_SIZE;&lt;br /&gt;
                              hex_cnt = 0;&lt;br /&gt;
                              hex_check = 0;&lt;br /&gt;
                              uart_putc(XON);&lt;br /&gt;
                          }&lt;br /&gt;
                          break;&lt;br /&gt;
                      /* Parse Datengröße */&lt;br /&gt;
                      case PARSER_STATE_SIZE:	&lt;br /&gt;
                          hex_buffer[hex_cnt++] = (uint8_t)c;&lt;br /&gt;
                          if(hex_cnt == 2)&lt;br /&gt;
                          {&lt;br /&gt;
                              uart_putc(XOFF);&lt;br /&gt;
                              parser_state = PARSER_STATE_ADDRESS;&lt;br /&gt;
                              hex_cnt = 0;&lt;br /&gt;
                              hex_size = (uint8_t)hex2num(hex_buffer, 2);&lt;br /&gt;
                              hex_check += hex_size;&lt;br /&gt;
                              uart_putc(XON);&lt;br /&gt;
                           }&lt;br /&gt;
                           break;&lt;br /&gt;
                      /* Parse Zieladresse */&lt;br /&gt;
                      case PARSER_STATE_ADDRESS:&lt;br /&gt;
                          hex_buffer[hex_cnt++] = (uint8_t)c;&lt;br /&gt;
                          if(hex_cnt == 4)&lt;br /&gt;
                          {&lt;br /&gt;
                              uart_putc(XOFF);&lt;br /&gt;
                              parser_state = PARSER_STATE_TYPE;&lt;br /&gt;
                              hex_cnt = 0;&lt;br /&gt;
                              hex_addr = hex2num(hex_buffer, 4);&lt;br /&gt;
                              hex_check += (uint8_t) hex_addr;&lt;br /&gt;
                              hex_check += (uint8_t) (hex_addr &amp;gt;&amp;gt; 8);&lt;br /&gt;
                              if(flash_page_flag) &lt;br /&gt;
                              {&lt;br /&gt;
                                  flash_page = hex_addr - hex_addr % SPM_PAGESIZE;&lt;br /&gt;
                                  flash_page_flag = 0;&lt;br /&gt;
                              }&lt;br /&gt;
                              uart_putc(XON);&lt;br /&gt;
                           }&lt;br /&gt;
                           break;&lt;br /&gt;
                      /* Parse Zeilentyp */&lt;br /&gt;
                      case PARSER_STATE_TYPE:	&lt;br /&gt;
                           hex_buffer[hex_cnt++] = (uint8_t)c;&lt;br /&gt;
                           if(hex_cnt == 2)&lt;br /&gt;
                           {&lt;br /&gt;
                               uart_putc(XOFF);&lt;br /&gt;
                               hex_cnt = 0;&lt;br /&gt;
                               hex_data_cnt = 0;&lt;br /&gt;
                               hex_type = (uint8_t)hex2num(hex_buffer, 2);&lt;br /&gt;
                               hex_check += hex_type;&lt;br /&gt;
                               switch(hex_type)&lt;br /&gt;
                               {&lt;br /&gt;
                                   case 0: parser_state = PARSER_STATE_DATA; break;&lt;br /&gt;
                                   case 1: parser_state = PARSER_STATE_CHECKSUM; break;&lt;br /&gt;
                                   default: parser_state = PARSER_STATE_DATA; break;&lt;br /&gt;
                               }&lt;br /&gt;
                               uart_putc(XON);&lt;br /&gt;
                           }&lt;br /&gt;
                           break;&lt;br /&gt;
                      /* Parse Flash-Daten */&lt;br /&gt;
                      case PARSER_STATE_DATA:&lt;br /&gt;
                          hex_buffer[hex_cnt++] = (uint8_t)c;&lt;br /&gt;
                          if(hex_cnt == 2)&lt;br /&gt;
                          {&lt;br /&gt;
                              uart_putc(XOFF);&lt;br /&gt;
                              uart_putc(&#039;.&#039;);&lt;br /&gt;
                              hex_cnt = 0;&lt;br /&gt;
                              flash_data[flash_cnt] = (uint8_t)hex2num(hex_buffer, 2);&lt;br /&gt;
                              hex_check += flash_data[flash_cnt];&lt;br /&gt;
                              flash_cnt++;&lt;br /&gt;
                              hex_data_cnt++;&lt;br /&gt;
                              if(hex_data_cnt == hex_size)&lt;br /&gt;
                              {&lt;br /&gt;
                                  parser_state = PARSER_STATE_CHECKSUM;&lt;br /&gt;
                                  hex_data_cnt=0;&lt;br /&gt;
                                  hex_cnt = 0;&lt;br /&gt;
                              }&lt;br /&gt;
                              /* Puffer voll -&amp;gt; schreibe Page */&lt;br /&gt;
                              if(flash_cnt == SPM_PAGESIZE)&lt;br /&gt;
                              {&lt;br /&gt;
                                  uart_puts(&amp;quot;P\n\r&amp;quot;);&lt;br /&gt;
                                  _delay_ms(100);&lt;br /&gt;
                                  program_page((uint16_t)flash_page, flash_data);&lt;br /&gt;
                                  memset(flash_data, 0xFF, sizeof(flash_data));&lt;br /&gt;
                                  flash_cnt = 0;&lt;br /&gt;
                                  flash_page_flag = 1;&lt;br /&gt;
                              }&lt;br /&gt;
                              uart_putc(XON);&lt;br /&gt;
                          }&lt;br /&gt;
                          break;&lt;br /&gt;
                      /* Parse Checksumme */                             &lt;br /&gt;
                      case PARSER_STATE_CHECKSUM:&lt;br /&gt;
                          hex_buffer[hex_cnt++] = (uint8_t)c;&lt;br /&gt;
                          if(hex_cnt == 2)&lt;br /&gt;
                          {&lt;br /&gt;
                              uart_putc(XOFF);&lt;br /&gt;
                              hex_checksum = (uint8_t)hex2num(hex_buffer, 2);&lt;br /&gt;
                              hex_check += hex_checksum;&lt;br /&gt;
                              hex_check &amp;amp;= 0x00FF;&lt;br /&gt;
                              /* Dateiende -&amp;gt; schreibe Restdaten */ &lt;br /&gt;
                              if(hex_type == 1)&lt;br /&gt;
                              {&lt;br /&gt;
                                  uart_puts(&amp;quot;P\n\r&amp;quot;);&lt;br /&gt;
                                  _delay_ms(100);&lt;br /&gt;
                                  program_page((uint16_t)flash_page, flash_data);&lt;br /&gt;
                                  boot_state = BOOT_STATE_EXIT;&lt;br /&gt;
                              }&lt;br /&gt;
                              /* Überprüfe Checksumme -&amp;gt; muss &#039;0&#039; sein */&lt;br /&gt;
                              if(hex_check == 0) parser_state = PARSER_STATE_START;&lt;br /&gt;
                              else parser_state = PARSER_STATE_ERROR;&lt;br /&gt;
                              uart_putc(XON);&lt;br /&gt;
                          }&lt;br /&gt;
                          break;			&lt;br /&gt;
                      /* Parserfehler (falsche Checksumme) */&lt;br /&gt;
                      case PARSER_STATE_ERROR:&lt;br /&gt;
                          uart_putc(&#039;#&#039;);&lt;br /&gt;
                          break;			&lt;br /&gt;
                      default:&lt;br /&gt;
                          break;&lt;br /&gt;
                  }&lt;br /&gt;
             }&lt;br /&gt;
             /* Programmzustand: UART Kommunikation */               &lt;br /&gt;
             else if(boot_state != BOOT_STATE_PARSER)&lt;br /&gt;
             {&lt;br /&gt;
                 switch((uint8_t)c)&lt;br /&gt;
                 {&lt;br /&gt;
                     case &#039;p&#039;: &lt;br /&gt;
                         boot_state = BOOT_STATE_PARSER;&lt;br /&gt;
                         uart_puts(&amp;quot;Programmiere den Flash!\n\r&amp;quot;);&lt;br /&gt;
                         uart_puts(&amp;quot;Kopiere die Hex-Datei und füge sie&amp;quot;&lt;br /&gt;
                                   &amp;quot; hier ein (rechte Maustaste)\n\r&amp;quot;);&lt;br /&gt;
                         break;&lt;br /&gt;
                     case &#039;q&#039;: &lt;br /&gt;
                         boot_state = BOOT_STATE_EXIT;&lt;br /&gt;
                         uart_puts(&amp;quot;Verlasse den Bootloader!\n\r&amp;quot;);&lt;br /&gt;
                         break;&lt;br /&gt;
                     default:&lt;br /&gt;
                         uart_puts(&amp;quot;Du hast folgendes Zeichen gesendet: &amp;quot;);&lt;br /&gt;
                         uart_putc((unsigned char)c);&lt;br /&gt;
                         uart_puts(&amp;quot;\n\r&amp;quot;);&lt;br /&gt;
                         break;&lt;br /&gt;
                 }&lt;br /&gt;
             }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    while(boot_state!=BOOT_STATE_EXIT);&lt;br /&gt;
 &lt;br /&gt;
    uart_puts(&amp;quot;Reset AVR!\n\r&amp;quot;);&lt;br /&gt;
    _delay_ms(1000);&lt;br /&gt;
 &lt;br /&gt;
    /* Interrupt Vektoren wieder gerade biegen */&lt;br /&gt;
    temp = MCUCR;&lt;br /&gt;
    MCUCR = temp | (1&amp;lt;&amp;lt;IVCE);&lt;br /&gt;
    MCUCR = temp &amp;amp; ~(1&amp;lt;&amp;lt;IVSEL);&lt;br /&gt;
 &lt;br /&gt;
    /* Reset */&lt;br /&gt;
    start();&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Erklärung des Codes&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Der Bootloader wird als &#039;&#039;Zustandsmaschine&#039;&#039; programmiert. Die Variable &#039;&#039;boot_state&#039;&#039; beinhaltet den aktuelle Programmzustand. Für den Parser gibt es eine eigene Zustandsvariable &#039;&#039;parser_state&#039;&#039;, welche die einzelne Zustände des Parsers hält. Mit jeder HEX-Datei-Zeile läuft der Parser einmal durch alle Zustände. Nach Abarbeiten des aktuellen Zustands und Auswertung der empfangenen Daten wird der nächste Zustand aktiviert usw. Für das Verarbeiten der Datei wird jedes Mal die Kommunikation angehalten und ein &#039;&#039;XOFF&#039;&#039; gesendet. Nach Abarbeitung der Daten gibt der Parser den seriellen Empfang wieder frei (&#039;&#039;XON&#039;&#039;). &#039;&#039;&#039;&#039;&#039;Es ist also wichtig, dass in PuTTY die XON/XOFF-Flußkontrolle aktiviert wird!&#039;&#039;&#039;&#039;&#039; Durch den interruptgesteuerten Empfang mit einem 32 Byte tiefen Empfangspuffer geht kein Byte verloren. Am Ende einer HEX-Datei-Zeile wird die Checksumme ausgewertet. Bei falscher Checksumme springt der Parser in den &#039;&#039;PARSER_STATE_ERROR&#039;&#039;, aus dem er nicht mehr rauskommt. Somit wird kein weiteres Byte in den Flash geschrieben. Zusätzlich könnte man noch implementieren, dass der Flash wieder gelöscht wird, wenn falsche Daten empfangen wurden, damit kein unvollständiges Programm im Flash steht.&lt;br /&gt;
Einschränkend muss noch festgehalten werden, das der Bootloader in dieser Fassung einen Adressraum bis 64K unterstützt (HEX-Zeilentyp 1). Die erweiterten Adressräume (HEX-Zeilentyp 2 bis 5) werden noch nicht unterstützt. Für ATmega-Devices mit &amp;gt; 64K Flash muss der Bootloader noch erweitert werden.&lt;br /&gt;
&lt;br /&gt;
Nach dem Kompilieren beträgt die Größe des Bootloaders 1796 Byte, wir sind also unterhalb der 2048 Byte die wir &amp;quot;verbraten&amp;quot; können. Der Datenspeicher wird mit 283 Byte belastet.&lt;br /&gt;
&lt;br /&gt;
Die Funktion des Bootloaders sieht wie folgt aus: Nach dem Reset wartet der Bootloader 2 Sekunden auf Eingaben (&#039;&#039;_delay_ms(2000);&#039;&#039;). Falls keine Eingaben von der Konsole kommen, springt der Bootloader zur Anwendung. Damit ist gewährleiset, dass die Anwendung später automatisch startet, auch wenn wir keine Taste drücken. Wird ein &#039;&#039;p&#039;&#039; gedrückt, springt der Bootloader in den &#039;&#039;BOOT_STATE_PARSER&#039;&#039; und erwartet eine HEX-Datei auf der Konsole. Dies ist der Zeitpunkt, die HEX-Datei der Anwendung mit Copy &amp;amp; Paste in die Konsole zu schreiben. Zum Einfügen von Daten aus dem Zwischenspeicher in die Konsole wird bei PuTTY die rechte Maustaste verwendet.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;WICHTIGER HINWEIS: &#039;&#039;&#039;&#039;&#039; Es hat sich gezeigt, das die Flußkontrolle durch XON/XOFF nicht immer funktioniert, da es eine Software-Flußsteuerung ist und u.U. der (UART-Sende-)Interrupt zu spät (oder gar nicht) ausgeführt wird. Bei Problemen beim Übertragen des HEX-Files sollte man als erstes versuchen die Baudrate zu senken (oder die Taktrate des Controllers erhöhen) um dem Controller mehr Zeit zum Verarbeiten und schnellerem Reagieren auf Interrupts zu geben.&lt;br /&gt;
&lt;br /&gt;
== Schritt 4 - Flashen und Ausprobieren des Bootloaders ==&lt;br /&gt;
Nach dem Flashen via AVRISPmkII startet der Bootloader in der Konsole. Da noch kein Anwendungsprogramm im Flash liegt, startet der Bootloader nach 2 Sekunden immer wieder neu. Nach Drücken der Taste &#039;&#039;p&#039;&#039; erwartet der Bootlader die HEX-Datei der Anwendung. Nach dem Einfügen der Datei in Konsole erscheint für jedes empfangene Byte ein Punkt (&amp;quot;.&amp;quot;). Das Beschreiben einer Flash-&#039;&#039;Page&#039;&#039; kenzeichnet ein &#039;&#039;P&#039;&#039;. Nach dem erfolgreichen Flashen startet die Anwendung automatisch.&lt;br /&gt;
&lt;br /&gt;
Nach erfolgreichem Flashen des Bootloaders via AVRISPmkII erscheint nach dem Reset folgendes Bild:&lt;br /&gt;
&lt;br /&gt;
[[Bild:PuTTY-Real-Bootloader-start.png|PuTTY: Bootloader nach dem Reset]]&lt;br /&gt;
&lt;br /&gt;
Drückt man die Taste &#039;&#039;&#039;p&#039;&#039;&#039;, springt ist der Bootloader bereit zum Empfang der HEX-Datei:&lt;br /&gt;
&lt;br /&gt;
[[Bild:PuTTY-Real-Bootloader-wait.png|PuTTY: Warten auf die HEX-Datei &amp;quot;Anwendung.hex&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
Nach Kopieren &amp;amp; Einfügen der HEX-Datei der vorher kompilierten Anwendung, hier die Intel-HEX-Datei &amp;quot;Anwendung.hex&amp;quot;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
:100000002CC046C045C044C043C042C041C040C0EF&lt;br /&gt;
:100010003FC03EC03DC03CC03BC03AC039C038C004&lt;br /&gt;
:1000200037C036C064C08FC033C032C031C030C0AA&lt;br /&gt;
:100030002FC02EC048696572206973742064617393&lt;br /&gt;
:1000400020416E77656E64756E677370726F67724C&lt;br /&gt;
:10005000616D6D2E2E2E0D0A000011241FBECFEFF4&lt;br /&gt;
:10006000D4E0DEBFCDBF11E0A0E0B1E0EAE6F2E00F&lt;br /&gt;
:1000700002C005900D92A434B107D9F711E0A4E4B1&lt;br /&gt;
:10008000B1E001C01D92A938B107E1F702D0EBC081&lt;br /&gt;
:10009000B7CFEF92FF920F931F93CF93DF9383E33A&lt;br /&gt;
:1000A00090E07BD0789484E390E0D0D088ECE82E88&lt;br /&gt;
:1000B000F12C00E018E18BD0EC0190FDFCCF8236F2&lt;br /&gt;
:1000C00069F480E091E0B6D080E197E2F7013197E2&lt;br /&gt;
:1000D000F1F70197D9F7F8010995EDCF8CE191E09F&lt;br /&gt;
:1000E000A9D08C2F91D081E491E0A4D0E4CF1F92CD&lt;br /&gt;
:1000F0000F920FB60F9211242F938F939F93EF932C&lt;br /&gt;
:10010000FF939091C0002091C600E0918601EF5FBF&lt;br /&gt;
:10011000EF7180918701E81711F482E008C0892F00&lt;br /&gt;
:100120008871E0938601F0E0EC59FE4F20838093C4&lt;br /&gt;
:100130008801FF91EF919F918F912F910F900FBEAA&lt;br /&gt;
:100140000F901F9018951F920F920FB60F921124C7&lt;br /&gt;
:100150008F939F93EF93FF939091840180918501FA&lt;br /&gt;
:10016000981769F0E0918501EF5FEF71E0938501E9&lt;br /&gt;
:10017000F0E0EC5BFE4F80818093C60005C080916B&lt;br /&gt;
:10018000C1008F7D8093C100FF91EF919F918F916E&lt;br /&gt;
:100190000F900FBE0F901F9018959C011092840134&lt;br /&gt;
:1001A00010928501109286011092870197FF04C07A&lt;br /&gt;
:1001B00082E08093C0003F773093C5002093C40055&lt;br /&gt;
:1001C00088E98093C10086E08093C20008959091F1&lt;br /&gt;
:1001D000860180918701981719F420E031E012C060&lt;br /&gt;
:1001E000E0918701EF5FEF71E0938701F0E0EC5958&lt;br /&gt;
:1001F000FE4F308120918801922F80E0AC01430FA7&lt;br /&gt;
:10020000511D9A01C9010895282F909184019F5F83&lt;br /&gt;
:100210009F71809185019817E1F3E92FF0E0EC5B85&lt;br /&gt;
:10022000FE4F2083909384018091C100806280936F&lt;br /&gt;
:10023000C1000895CF93DF93EC0102C02196E4DF63&lt;br /&gt;
:1002400088818823D9F7DF91CF910895CF93DF93E9&lt;br /&gt;
:10025000EC0101C0D9DFFE01219684918823D1F7FA&lt;br /&gt;
:0A026000DF91CF910895F894FFCFCD&lt;br /&gt;
:10026A00537072696E6765207A756D20426F6F747C&lt;br /&gt;
:10027A006C6F616465722E2E2E0D0A00447520681B&lt;br /&gt;
:10028A0061737420666F6C67656E646573205A6566&lt;br /&gt;
:10029A00696368656E20676573656E6465743A2084&lt;br /&gt;
:0402AA00000A0D0039&lt;br /&gt;
:00000001FF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
erscheinen folgende Ausgaben in PuTTY:&lt;br /&gt;
&lt;br /&gt;
[[Bild:PuTTY-Real-Bootloader-prog.png|PuTTY: Flashen der HEX-Datei &amp;quot;Anwendung.hex&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
Nach erfolgreichem Flashen startet die Anwendung und meldet sich mit der Zeile&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hier ist das Anwendungsprogramm...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Jetzt können nach belieben Tasten gedrückt werden, was die Anwendung jedesmal quittiert:&lt;br /&gt;
&lt;br /&gt;
[[Bild:PuTTY-Real-Bootloader-anwend.png|PuTTY: Ausprobieren der Anwendung]]&lt;br /&gt;
&lt;br /&gt;
Nach Drücken der Taste &#039;&#039;&#039;b&#039;&#039;&#039; springt die Anwendung wieder zur Startadresse des Bootloaders, also zur Adresse &#039;&#039;0x1800&#039;&#039; im Flash-Speicher. Nun hat man wieder 2 Sekunden Zeit, um die Taste &#039;&#039;&#039;p&#039;&#039;&#039; zu drücken, sonst startet die Anwendung wieder:&lt;br /&gt;
&lt;br /&gt;
[[Bild:PuTTY-Real-Bootloader-reset.png|PuTTY: Rücksprung zum Bootloader auf Adresse 0x1800]]&lt;br /&gt;
&lt;br /&gt;
Damit ist das Tutorial abgeschlossen.&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Viel Spass beim Ausprobieren und Weiterentwickeln!&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
= Zusammenfassung =&lt;br /&gt;
&lt;br /&gt;
Wer den Artikel bis hier hin nachvollzogen hat, ist jetzt in der Lage einen Bootloader selbst zu schreiben. Dabei kann der Bootloader an jede in Frage kommenden ATmega-Plattform angepaßt werden. Dazu muss&lt;br /&gt;
* die Linkereinstellung für das Verschieben der Sektion &#039;&#039;.text&#039;&#039; angepasst werden und (&#039;&#039;&#039;-Ttext = 0xXXXX&#039;&#039;&#039;)&lt;br /&gt;
* evtl. der virtuelle Funktionspointer in der Anwendung geändert werden (falls ein Rücksprung zum Bootloader gewünscht ist &#039;&#039;&#039;void (*bootloader)(void) = 0xXXXX&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Um dies zu erleichtern, habe ich hier die Sprungadressen für ausgewählte AVRs tabellarisch zusammengetragen. Dabei wurde immer die maximale Größe des Bootloader betrachtet, also &#039;&#039;&#039;BOOTSZ0=0&#039;&#039;&#039; und &#039;&#039;&#039;BOOTSZ1=0&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Größe und Startadresse der Bootloader Sektion für ausgewählte AVR-Devices&lt;br /&gt;
|- &lt;br /&gt;
! Device || Flash-Größe&amp;lt;br&amp;gt;für Applikation || Flash-Größe&amp;lt;br&amp;gt;des Bootloaders || Startadresse des Bootloaders&amp;lt;br&amp;gt;(Byteadresse)&lt;br /&gt;
|-&lt;br /&gt;
| ATmega8/88 || 6144 Byte || 2048 Byte || 0x1800&lt;br /&gt;
|-&lt;br /&gt;
| ATmega16/164/168 || 14336 Byte || 2048 Byte || 0x3800&lt;br /&gt;
|-&lt;br /&gt;
| ATmega32/324/328 || 28672 Byte || 4096 Byte || 0x7000&lt;br /&gt;
|-&lt;br /&gt;
| ATmega64/644/640 || 57344 Byte || 8192 Byte || 0xE000&lt;br /&gt;
|-&lt;br /&gt;
| ATmega128/1284/1280/1281 || 122880 Byte || 8192 Byte || 0x1E000&lt;br /&gt;
|-&lt;br /&gt;
| ATmega2560/2561 ||  253952 Byte || 8192 Byte || 0x3E000&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Damit kann jeder den Bootloader nach seinen Wünschen anpassen. Eine gängige Praxis ist auch, ein kleines PC-Programm zu schreiben, welches dem Bootloader die Flash-Daten gleich Binär übergibt. Das geht schneller und spart das aufwendige Parsen. Eine weitere Idee ist es, den Bootloader so anzupassen, das er sich wie ein STK500 an der seriellen Schnittstelle verhält. Dazu muss man die [http://www.atmel.com/dyn/products/tools_card.asp?tool_id=2735 AP068] von Atmel umsetzen. Auch dies sollte nach dem Studium des Tutorial kein Problem mehr sein :)&lt;br /&gt;
&lt;br /&gt;
[http://www.mikrocontroller.net/user/show/mario Nachricht an den Autor]&lt;br /&gt;
&lt;br /&gt;
= FAQ =&lt;br /&gt;
&lt;br /&gt;
== Wie kann man Bootloader und Anwendungsprogramm gemeinsam flashen? ==&lt;br /&gt;
&lt;br /&gt;
Es ist in C ohne weiteres nicht möglich ein gemeinsames Hexfile aus Bootloader und Anwendungsprogramm zu kompilieren. Aber man kann das getrennt erstellte Hexfile des Bootloaders und das getrennt erstellte Hexfile des Anwendungsprogramms zusammenfügen und so gemeinsam mit ISP flashen. Dazu die letzte Zeile des 1. Hexfiles entfernen und dahinter das 2. Hexfile anfügen [http://www.mikrocontroller.net/topic/199241#1955092], [http://www.mikrocontroller.net/topic/198428#1949164]. &lt;br /&gt;
&lt;br /&gt;
[[Kategorie:AVR-Programmer und -Bootloader|B]]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Akku_Tester&amp;diff=60361</id>
		<title>Akku Tester</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Akku_Tester&amp;diff=60361"/>
		<updated>2011-09-11T13:53:12Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: /* Downloads */ Schreibfehler korrigiert&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;von Philipp Kälin [[Benutzer:philippk]]&lt;br /&gt;
&lt;br /&gt;
== Einleitung ==&lt;br /&gt;
[[Bild:AkkuTesterFoto.png|center]]&lt;br /&gt;
&lt;br /&gt;
Mit diesem Artikel will ich ein Projekt vorstellen, mit dem man (wie es der Name schon verrät) Akkus Testen kann. Die Idee ist, dass man einen Akku den man testen möchte zuerst mit einem Ladegerät voll lädt. Der Akku Tester entlädt dann den Akku und misst die Kapazität [mAh] die entnommen wurde, und die Energie [mWh]. Diese Werte kann man dann mit den Herstellerangaben vom Akku vergleichen und so sehen, wie fit der Akku noch ist.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Features&#039;&#039;&#039;&lt;br /&gt;
* Bedienung mit nur einem Drehknopf und einem Taster&lt;br /&gt;
* Vordefinierte Akkutypen&lt;br /&gt;
* Vordefinierte Ladeschlussspannungen&lt;br /&gt;
* Mehrsprachige grafische Menüführung (Deutsch / Englisch) kann noch erweitert werden&lt;br /&gt;
* Abspeichern der Einstellungen ins interne EEPROM&lt;br /&gt;
* Loggen der Daten auf eine SD-Speicherkarte mit FAT12 / FAT16 / FAT32&lt;br /&gt;
* Spannungen bis 40V&lt;br /&gt;
* Strom bis 5A&lt;br /&gt;
* Drehzahlregelung eines Lüfters zur Kühlung&lt;br /&gt;
* Mehrere Logdateien können auf einer SD-Karte abgespeichert werden da der Dateiname einstellbar ist&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Elektrische Daten&#039;&#039;&#039;&lt;br /&gt;
* Betriebsspannung: 12 - 15V DC&lt;br /&gt;
* Betriebsstrom: 150 mA (mit Lüfter)&lt;br /&gt;
* Min. Entladestrom: 10mA&lt;br /&gt;
* Max. Entladestrom: 5000 mA&lt;br /&gt;
* Schrittbreite Entladestrom: 10 mA&lt;br /&gt;
* Max. Akkuspannung: 40 V&lt;br /&gt;
* Min. Spannung Standardschaltung: ~3V (erst ab 9V max. Entladestrom)&lt;br /&gt;
* Min. Spannung Schaltung für kleine Spannungen: ~0.5 bis 1V&lt;br /&gt;
* Max. Entladeleistung: 100W&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Einstellparameter im Menü&#039;&#039;&#039;&lt;br /&gt;
* Akkutyp (Pb, NiCd, HiMH)&lt;br /&gt;
* Zellenzahl (je nach Akkutyp)&lt;br /&gt;
* Entladestrom (10 mA bis 5000mA)&lt;br /&gt;
* Schlussspannung (50 mV bis 30000 mV &lt;br /&gt;
* Speicherintervall (10 s bis 900 s oder aus)&lt;br /&gt;
* Sprache (Deutsch, Englisch)&lt;br /&gt;
* Dateiname der Logdatei&lt;br /&gt;
* Auf Werkseinstellungen zurücksetzen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[http://web205.server-drome.net/AkkuTester/Bilder/Thumbnails.html Bilder von meinem Aufbau]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[http://www.mikrocontroller.net/topic/108663#960254 Diskussionsforum]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[http://web205.server-drome.net/AkkuTester/Doxygen/index.html DoxygenDokumentation]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Fragen und Antworten ==&lt;br /&gt;
=== Hardware ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Welche Speicherkarten kann man verwenden?&#039;&#039;&#039; &amp;lt;br&amp;gt;&lt;br /&gt;
Grundsätzlich kann man alle SD und MMC Speicherkarten verwenden. In den Beschreibungen wird nur von SD-Karten geschreiben, da diese viel verbreiteter sind. Die SD-Karte ist jedoch abwärt kompatibel zur MMC und wird auch wie eine Solche angesprochen. Die Speicherkarten sollten mit FAT12, FAT16 oder FAT32 formatiert sein. Gestestet habe ich nur mit einer 128MB Kingston und einer 1GB Swissbit und allen FAT Dateisystemen.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Warum braucht es eine 3.3V Speisung?&#039;&#039;&#039; &amp;lt;br&amp;gt;&lt;br /&gt;
Die Speicherkarten brauchen 3.3V. Man könnte die Spannung auch einfach mit 2 Dioden aus den 5V erzeigen, davon ist aber abzuraten, da die Spannung dann schwankt weil eine schnelle SD-Karte beim schreiben auch mal 100mA ziehen kann.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Kann man auch andere OPs verwenden?&#039;&#039;&#039; &amp;lt;br&amp;gt;&lt;br /&gt;
Grundsätzlich gibt es viele OPs die man verwenden kann. Man sollte jedoch darauf achten dass der OP RailToRail Ein- und Ausgänge hat.&lt;br /&gt;
&lt;br /&gt;
=== Software ===&lt;br /&gt;
&#039;&#039;&#039;Kann man auch einen anderen Controller als den ATmega32 verwenden?&#039;&#039;&#039; &amp;lt;br&amp;gt;&lt;br /&gt;
Ja, aber auf keinen Fall einen Mit AT90Sxxxx oder ATMega8515 da bei denen die SD-Routinen nicht mehr funktionieren. Auch muss man darauf achten, dass der Controller mehr als 1 kB RAM hat, da die SD-Routinen alleine schon 1,2kB RAM brauchen.&lt;br /&gt;
&lt;br /&gt;
== Worauf sollte man achten ==&lt;br /&gt;
* Die Signale zur SD-Karte sind sehr schnell, bei Leitungslängen von mehr als 10cm ist da nichts mehr zu machen.&lt;br /&gt;
&lt;br /&gt;
* Die Leitungen in denen viel Strom fliesst so kurz wie möglich halten.&lt;br /&gt;
&lt;br /&gt;
* Die Verbindungen zwischen Controller und Powerteil direkt am Akku aschliessen, da durch den Widerstand der Leitungen sonst ein Spannungsabfall entsteht.&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Beschreibung ===&lt;br /&gt;
&#039;&#039;&#039;Achtung!!!&#039;&#039;&#039; Es sollte immer darauf geachtet werden die neueste Version aus dem SVN zu verwenden. Die Schemaabbildungen hier sollten nur zur Erklärung sein und sind nicht immer aktuell.&lt;br /&gt;
&lt;br /&gt;
==== Versorgung ====&lt;br /&gt;
[[Bild:Versorgung.png|thumb|center|500px|Spannungsversorgung]]&lt;br /&gt;
&lt;br /&gt;
* Die Schaltung wird über ein externes Steckernetzteil gespeist. Bei dem Netzteil muss darauf geachtet werden, dass es eine Spannung von etwa 12V hat um den Maximalstrom zu erreichen (Transistor als Spannungfolger) aber die Spannung nicht grösser als 16V ist, da das die maximale Betriebsspannung des OPs ist.&lt;br /&gt;
* Für die 5V Versorgung wird ein 7805 Festspannungsregler verwendet; die Kondensatoren müssen nicht genau dieselben sein, da sie nur zur Stabilisierung dienen.&lt;br /&gt;
* Für die 3,3V Versorgung wird ein LM317 verwendet. Ich habe ein Poti verwendet, da man mit E12 Widerständen keinen guten Spannungsteiler hinbekommt. Bei der Spannung sollte darauf geachtet werden, dass sie nich allzuviel über 3,3V liegt, da die Speicherkarten empfindlich auf Überspannung reagieren. Wichtig ist die LED! Der LM317 braucht einen Minimalstrom von etwa 10mA, damit er richtig funktioniert. Auch hier können die Kondensatoren angepasst werden.&lt;br /&gt;
&lt;br /&gt;
==== Prozessor ====&lt;br /&gt;
Es gibt unstimmigkeiten, ob man am DO Pin der SD-Karte einen PullUp zuschalten sollte oder nicht. Ich habe einen 10k hingemacht. Mehr dazu:&lt;br /&gt;
[http://www.mikrocontroller.net/topic/119520#new MMC-Karte funktioniert nicht]&lt;br /&gt;
[[Bild:CPU.png|thumb|center|500px|CPU]]&lt;br /&gt;
&lt;br /&gt;
* Als Prozessor wird ein ATmega32 verwendet, da die FAT-Library für die SD-Karte mindestens 1,2kB RAM benötigt.&lt;br /&gt;
* SW1 ist ein Inkrementaldrehgeber mit eingebautem Taster, der zur Bedienung dient.&lt;br /&gt;
* Zur Programmierung und zum Debuggen wird eine JTAG Schnittstelle auf eine 10pol Pfostenleiste mit Standardbelegung hinausgeführt.&lt;br /&gt;
* Da die SD-Karte ein 3,3V Interface hat, braucht es eine Pegelanpassung mit R4-R9 auf den Datenleitungen vom Prozessor zur SD-Karte. In die Gegenrichtung braucht es keine Pegelanpassung, da der Prozessor 3,3V als ein High erkennt. Die SD-Karte wird uber den SPI-Bus angesteuert.&lt;br /&gt;
* Beim LCD handelt es sich um ein Standard 128x64 Pixel mit KS0108 Treibern. R16 wird zur Strombegrenzung der LED-Hintergrundbeleuchtung verwendet. R15 ist ein Poti zur Kontrasteinstellung.&lt;br /&gt;
&lt;br /&gt;
==== Leistungsteil ====&lt;br /&gt;
Beim Leistungsteil gibt es zwei verschiedene Varianten, wobei bei der Variante für kleine Spannungen ein paar besondere Sachen beachtet werden müssen &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Standard Schaltung für grosse Ströme&#039;&#039;&#039;&lt;br /&gt;
[[Bild:Power V1.1.png|thumb|center|500px|Power]]&lt;br /&gt;
&#039;&#039;&#039;Für kleine Spannungen&#039;&#039;&#039; Achtung es sind spezielle Massnahmen zu beachten&lt;br /&gt;
[[Bild:Power LV.png|thumb|center|500px|Power LV]]&lt;br /&gt;
* Bei dieser Schaltung wird die Leistung nicht mehr über einem Transistor und einem Leistungswiderstand verheitzt, sondern nur noch auf dem Transistor. Daher ist diese Schaltung nur für kleine Leistungen geeignet.&lt;br /&gt;
* Es ist empfehlenswert den Transistor direkt auf das Kühlblech zu montieren, da eine Isolierfolie in den meisten Fällen schon einen zu grossen Wärmewiderstand hat und der Transistor sich dann in Rauch auflöst. Dabei ist zu beachten, dass die Kühlfahne mit dem Kollektor verbunden ist, oder anders gesagt mit dem +Pol des Akkus. !!! Erhöhte Kurzschlussgefahr !!!&lt;br /&gt;
* Damit man die gleiche Software verwenden kann kommt der OP IC4B zum einsatz. Er sorgt dafür, dass bei gleichem Strom die gleiche Spannung am &amp;quot;Messwiderstand&amp;quot; anliegt wie bei der Standardschaltung&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Um den Strom zu regeln gibt der Prozessor ein PWM Signal auf den Tiefpass mit C1 und R11 der dann eine Analogspannung generiert. Diese Analogspannung ist der Sollwert für den Strom. Der OP IC5A vergleicht die Sollspannung mit der, die über den Spannungsteiler R10 und R21 zurückkommt. Über diesen Spannungsteiler kann der Prozessor gleichzeitig den Strom (Spannung) messen. Da der OP IC5A keine Rückkopplung hat (und somit eine riesige Verstärkung hat) wird sein Ausgang immer an einem der beiden Anschläge sein. Dieses Signal wird mit einem weiteren Tiefpass aus R22 und C16 zu einer Analogspannung geglättet. IC4A dient als Impedanzwandler um den Tiefpass nicht zu belasten und den Transistor, der als Emitterfolger arbeitet, anzusteuern. Der Spannungsteiler R13 und R12 dient dazu, die Spannung am Akku zu messen.&lt;br /&gt;
* R20 und C11 bilden einen Tiefpass, der das PWM Signal vom Prozessor in eine Analogspannung umwandelt. Die Spannung wird mit dem OP IC5B um den Faktor 2.5 Verstärkt. Der Transistor T1 bildet einen Emitterfolger, der dann den Lüfter steuert. Die Diode D2 dient als Schutz, da der Lüfter induktiv ist und somit Spannunsspitzen verursachen kann. Der Kondensator dient der Pufferung und Entlastung des Transistors.&lt;br /&gt;
* Mit IC6 und R14 wird die Temperatur gemessen. IC6 ist sozusagen eine Temperaturabhängige Z-Diode mit 10mV pro Kelvin. Somit wird die Temperaturmessung einfach, da der Temperatursensor eine lineare Spannung liefert.&lt;br /&gt;
* Um die Spannung und den Strom genauer messen zu können werden zwei Referenzspannungen verwendet. Die interne 2,56V und AVCC(5V). Da bezweckt, dass man hohe Spannungen messen kann und doch bei kleinen Spannungen eine hohe Auflösung hat. Der Prozentuale Fehler über den ganzen Spannungsbereich bleibt immer etwa gleich.&lt;br /&gt;
* Die Schottkydiode D3 schütz den Transistor vor verpoltem Akku. Der Prozessor schützt sich selber, da er am Eingeng zwei Dioden hat, die die Spannung begrenzen. Durch den Hochohmigen Spannungsteiler R12 und R13 wird der Strom durch die Dioden so klein gehalten, dass diese keinen Schaden nehmen.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Eingansschaltung eines IO-Pins&#039;&#039;&#039; &amp;lt;br&amp;gt;&lt;br /&gt;
Das Bild ist aus dem Datenblatt von Atmel kopiert.&lt;br /&gt;
[[Bild:Eingangsschaltung_m32.png|thumb|center|500px|Power]]&lt;br /&gt;
&lt;br /&gt;
=== Worterläuterungen ===&lt;br /&gt;
* Emitterfolger: An die Basis wird eine Spannung angelegt (ohne Vorwiderstand). Da ein Transistor ein Ube von 0,7V hat wird am Emitter eine Spannung anliegen, die um 0,7V kleiner ist als die an der Basis. Wird nun an den Emitter ein Widerstand zu GND angelegt so hat man einen konstanten Widerstsnd und eine konstante Spannung. --&amp;gt; I = U/R Und man hat eine Stromquelle.&lt;br /&gt;
* Rückkopplung: Ein OP will nichts anderes als dass zwischen dem invertierenden (-) und dem nicht invertierenden (+) Eingang kein Spannungsunterschied herrscht. Mit einer Rückkopplung wird der Ausgang über ein Bauteil (Widerstand, Kondensator, Diode usw.) mit dem invertierenden Eingang verbunden. Daher &amp;quot;weiß&amp;quot; der OP, was er am Ausgang macht und kann vernünftig regeln. Weiß er das nicht, wird der Ausgang immer an einem der beiden Speisungen anschlagen.&lt;br /&gt;
* Impedanzwandler: Der Ausgang wird mit dem invertierenden Eingang des OPs verbunden. Somit &amp;quot;macht&amp;quot; er am Ausgang immer die gleiche Spannung wie am nicht invertierenden Eingang. Der Sinn dieser Schaltung ist, dass der Eingang das was davor ist nicht belastet und der Ausgang belastet werden kann, ohne dass sich die Spannung verändert.&lt;br /&gt;
&lt;br /&gt;
== Software ==&lt;br /&gt;
Danke an:&lt;br /&gt;
* Fabian Maximilian Thiele für die GLCD Library http://www.mikrocontroller.net/topic/12202#new&lt;br /&gt;
* Holger Klabunde für die SD und FAT Library http://www.holger-klabunde.de/index.html&lt;br /&gt;
&lt;br /&gt;
=== Speicherung der Daten ===&lt;br /&gt;
Die Daten werden in einer Textdatei abgespeichert, die einfach in ein Tabellenkalkulationsprogramm importiert werden kann (z.B Microsoft Office Excel, OpenOffice Calc).&lt;br /&gt;
&lt;br /&gt;
Die Daten werden wie folgt abgespeichert:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
Akkutyp Pb&lt;br /&gt;
Zellenzahl 5&lt;br /&gt;
Schlussspannung 8750&lt;br /&gt;
Entladestrom 200&lt;br /&gt;
Speicherintervall 20&lt;br /&gt;
&lt;br /&gt;
Entladezeit[s] Spannung[mV] Strom[mA] Kapazität[mAs] Energie[mWs]&lt;br /&gt;
11     660     22      73      46&lt;br /&gt;
31     660     33      358     226&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tipps zum Aufbau ==&lt;br /&gt;
Eine günstige Variante ist es einen Prozessorkühler von einem PC zu nehmen und den Transistor und den Leistungswiderstand dort draufzubauen. Wichtig ist es, alle Leitungen, in denen viel Strom fließt, so kurz wie möglich zu halten.&lt;br /&gt;
&lt;br /&gt;
== Downloads ==&lt;br /&gt;
Alle Downloads sind im SVN gespeichert: [http://www.mikrocontroller.net/svnbrowser/akkutester/ http://www.mikrocontroller.net/svnbrowser/akkutester/] oder via [svn://mikrocontroller.net/akkutester svn://mikrocontroller.net/akkutester]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Ordnerstruktur und Beschreibung der wichtigsten &#039;&#039;Dateien&#039;&#039; im SVN&#039;&#039;&#039;&lt;br /&gt;
|- style=&amp;quot;background-color:#B3B7FF&amp;quot;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; colspan=&amp;quot;2&amp;quot; | &#039;&#039;&#039;Ordner&#039;&#039;&#039; || &#039;&#039;&#039;Dateien&#039;&#039;&#039; || &#039;&#039;&#039;Beschreibung&#039;&#039;&#039;&lt;br /&gt;
|-   style=&amp;quot;background-color:#B9FFC5&amp;quot;&lt;br /&gt;
| &#039;&#039;&#039;hardware&#039;&#039;&#039; || || || Enthält das Eagle (5.x) Schema und ein PDF davon&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk&#039;&#039;&#039; || || Aktueller Hardware-Entwicklungszweig&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;tags&#039;&#039;&#039; || || Fertige Versionen der Hardware als ZIP gepackt&lt;br /&gt;
|-&lt;br /&gt;
| || || &#039;&#039;changelog.txt&#039;&#039; || &#039;&#039;Hier sollte jede Änderung inkl. Datum und Versionsnummer eingetragen werden&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
|- style=&amp;quot;background-color:#B9FFC5&amp;quot;&lt;br /&gt;
| &#039;&#039;&#039;software&#039;&#039;&#039; || || || Software für AVR-GCC 4.3&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk&#039;&#039;&#039; || || Aktueller Software-Entwicklungszweig&lt;br /&gt;
|-&lt;br /&gt;
| || || &#039;&#039;changelog.txt&#039;&#039; || &#039;&#039;Hier sollte jede Änderung inkl. Datum und Versionsnummer eingetragen werden&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;tags&#039;&#039;&#039; || || Fertige Software als ZIP gepackt&lt;br /&gt;
|-&lt;br /&gt;
| || || &#039;&#039;Fusebits.pdf&#039;&#039; || &#039;&#039;Einstellungen zu den Fusebits&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:1. Wettbewerb]]&lt;br /&gt;
[[Kategorie:Spannungsversorgung und Energiequellen]]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Lichtsensor_/_Helligkeitssensor&amp;diff=59926</id>
		<title>Lichtsensor / Helligkeitssensor</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Lichtsensor_/_Helligkeitssensor&amp;diff=59926"/>
		<updated>2011-08-26T23:26:16Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: /* LED */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Lichtsensoren wandeln Licht in eine Spannung, Strom oder Frequenz, welche dann weiterverarbeitet werden kann.&lt;br /&gt;
&lt;br /&gt;
== Photowiderstand == &lt;br /&gt;
&lt;br /&gt;
Im Englischen &#039;&#039;&#039;L&#039;&#039;&#039;ight &#039;&#039;&#039;D&#039;&#039;&#039;ependent &#039;&#039;&#039;R&#039;&#039;&#039;esistor genannt (LDR, lichtabhängiger Widerstand). Diese gibt es in verschiedensten Bauformen und  Materialien. Einige bekannte und beliebte Typen basieren auf Cadmium, einem giftigen Schwermetall, welches nach den neusten Elektronikrichtlinien (RoHS) verboten ist.&lt;br /&gt;
Vorteile der LDRs sind ihre Einfachheit, Robustheit und der recht große Dynamikbereich (k&amp;amp;Omega; bis M&amp;amp;Omega;). Wesentlicher Nachteil ist die sehr geringe Reaktionsgeschwindigkeit (einige Millisekunden bis Minuten). Die Auswertung erfolgt über einen einfachen [[Spannungsteiler]].&lt;br /&gt;
&lt;br /&gt;
[[bild:photo_ldr.png]]&lt;br /&gt;
&lt;br /&gt;
== Photohalbleiter == &lt;br /&gt;
&lt;br /&gt;
Photohalbleiter sind Bauelemente, bei denen in einer PN-Sperrschicht durch Lichteinfall freie Ladungsträger erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
=== Photodiode ===&lt;br /&gt;
&lt;br /&gt;
Photodioden sind sehr schnell (Schaltzeiten im Nanosekundenbereich), liefern aber nur sehr kleine Photoströme (nA..µA). Es gibt zur Nutzung für Photodioden drei prinzipielle Schaltungen:&lt;br /&gt;
&lt;br /&gt;
==== Photospannungsbetrieb ====&lt;br /&gt;
&lt;br /&gt;
[[bild:photo_diode_blank.png]]&lt;br /&gt;
&lt;br /&gt;
Hier arbeitet die Photodiode als Solarzelle, was sie ja im Prinzip ist. Allerdings bringt sie aufgrund der kleinen Fläche (meist weniger als 1mm^2) keine nennenswerte Leistung. Die Ausgangsspannung ist logarithmisch von der einfallenden Lichtleistung abhängig und entspricht der umgedrehten Diodenkennlinie (~0,7V). Allerdings ist diese Kennlinie auch sehr temperaturabhängig. Diese Schaltung wird nur selten angewendet.&lt;br /&gt;
&lt;br /&gt;
==== Konstantstromquelle mit Arbeitswiderstand ====&lt;br /&gt;
&lt;br /&gt;
Das ist die einfachste Schaltung zur Auswertung einer Photodiode. Über einen [[Spannungsteiler]] mit einem relativ hochohmigen Widerstand kann eine lichtabhängige Spannung über dem Arbeitswiderstand abgegriffen werden. Die Ausgangsspannung ist linear proportional zur Lichtleistung.&lt;br /&gt;
&lt;br /&gt;
[[bild:photo_diode.png]]&lt;br /&gt;
&lt;br /&gt;
Diese Schaltung ist jedoch ziemlich langsam. Als Näherung gilt&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;f_{3dB}=\frac{1}{2 \pi R1 C_D}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;math&amp;gt;C_D&amp;lt;/math&amp;gt; : Sperrschichtkapazität der Diode&lt;br /&gt;
&lt;br /&gt;
Bei angenommenen 20pF ergibt sie hier eine Grenzfrequenz von ca. 8kHz.&lt;br /&gt;
&lt;br /&gt;
==== Konstantstromquelle mit Transimpedanzverstärker ====&lt;br /&gt;
&lt;br /&gt;
Hier wird die Photodiode nahezu im Kurzschluss als lichtabhängige Stromquelle betrieben. Der Kurzschluss sorgt dafür, dass die Sperrschichtkapazität nicht umgeladen werden muss, das macht die Schaltung sehr schnell. Der Aufbau wird Transimpedanzverstärker genannt (engl. &#039;&#039;&#039;T&#039;&#039;&#039;rans&#039;&#039;&#039;I&#039;&#039;&#039;mpedance &#039;&#039;&#039;A&#039;&#039;&#039;mplifier, TIA). Einen guten [http://electronicdesign.com/Articles/Index.cfm?AD=1&amp;amp;AD=1&amp;amp;ArticleID=4346 Grundlagenartikel] zum TIA gibt es beim Analog-Guru Bob Pease bei [http://www.national.com National Semiconductor].&lt;br /&gt;
&lt;br /&gt;
[[bild:photo_diode_tia.png]]&lt;br /&gt;
&lt;br /&gt;
Vorteil dieser Schaltung ist die hohe Grenzfrequenz. Sie berechnet sich durch&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;f_{3dB}=\sqrt{\frac{GBP}{2 \pi R1 C_I}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*GBP : Verstärkungs-Bandbreite-Produkt des Operationsverstärkers (engl. &#039;&#039;&#039;G&#039;&#039;&#039;ain &#039;&#039;&#039;B&#039;&#039;&#039;andwidth &#039;&#039;&#039;P&#039;&#039;&#039;roduct), hier 1 MHz für den LM358&lt;br /&gt;
*&amp;lt;math&amp;gt;C_I&amp;lt;/math&amp;gt; : Summe aus Sperrschichtkapazität der Photodiode + Eingangskapazität des OPVs, hier mit 30pF angenommen.&lt;br /&gt;
&lt;br /&gt;
Selbst mit diesem eher langsamen OPV und schon sehr großen Rückkopplungswiderstand von 1M&amp;amp;Omega; erreichen wir schon eine Bandbreite von sagenhaften 72kHz! Wichtig ist hier C1, die Kompensationskapazität. Ist sie zu klein oder fehlt sie gar, schwingt der TIA. Die Berechnung von C1 erfolgt klassisch gemäß&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;C1=\frac{R_D}{R1} \cdot C_I&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;math&amp;gt;R_D&amp;lt;/math&amp;gt; : Sperrschichtwiderstand der Photodiode. Dieser ist selten in den Datenblättern angegeben, liegt aber meist im Bereich 1..100M&amp;amp;Omega;.&lt;br /&gt;
&lt;br /&gt;
Hier muss man mit C1 experimentieren, vor allem weil er meist sehr klein ist (einstelliger Picofaradbereich) und hier das Layout eine wesentlichen Rolle spielt. Eine verbessere Formel für C1 ergibt kleinere Werte, wobei allerdings ein geringfügiges Überschwingen des Verstärkers in Kauf genommen wird. Der Vorteil ist die bis zu zehnfach(!) höhere Bandbreite.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;C1=\sqrt{\frac{C_I}{R1 \cdot GBP}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Sperrschichtkapazität &amp;lt;math&amp;gt;C_D&amp;lt;/math&amp;gt; der Diode kann man verkleinern, indem man die Anode nicht auf GND, sondern eine negative Spannung legt, je nach Typ zwischen -5..-100V. Dadurch kann man &amp;lt;math&amp;gt;C_D&amp;lt;/math&amp;gt; um den Faktor 2..10 verkleinern und somit die Schaltung schneller machen.&lt;br /&gt;
&lt;br /&gt;
=== Phototransistor ===&lt;br /&gt;
&lt;br /&gt;
[[bild:photo_transistor.png|thumb|right|300px|NPN Fototransistor in &#039;&#039;Common-Collector Amplifier&#039;&#039; Schaltung]]&lt;br /&gt;
&lt;br /&gt;
Phototransistoren sind mit Schaltzeiten im Mikrosekundenbereich wesentlich langsamer als Photodioden, erlauben dafür aber die Steuerung bzw. das Schalten relativ großer Ströme (&amp;amp;mu;A..mA) durch Licht. Je nach Schaltung erreicht man Grenzfrequenzen von einigen Dutzend Kilohertz. Benutzt werden sie wie Photodioden mit Arbeitswiderstand. Eine Verschaltung mit TIA ist nur mit negativer Vorspannung möglich, da Phototransistoren aktiv keinen Strom liefern.&lt;br /&gt;
&lt;br /&gt;
Auf Grund des relativ großen Photostroms kann man hier mit relativ kleinen Widerständen arbeiten und erhält eine hohe Bandbreite. Diese wird aber nach oben vor allem durch die Millerkapazität des Phototransistors sowie dessen Sättigungsverhalten der Basis-Emitter-Strecke begrenzt. Die Basis von Phototransistoren ist meist nicht zugänglich und bleibt offen. Bei einigen Typen ist sie als Pin am Bauteil herausgeführt. Mit einem hochohmigen Widerstand im Bereich 100k&amp;amp;Omega; bis 10M&amp;amp;Omega; von der Basis zum Emitter kann man die Schaltgeschwindigkeit des Phototransistors erhöhen, allerdings auf Kosten der Empfindlichkeit.&lt;br /&gt;
&lt;br /&gt;
Siehe auch:&lt;br /&gt;
* [http://www.fairchildsemi.com/an/AN/AN-3005.pdf Application Note AN-3005: Design Fundamentals for Phototransistor Circuits], 2002 Fairchild Semiconductor Corporation (PDF)&lt;br /&gt;
* [http://www.evilmadscientist.com/article.php/nightlight A Simple and Cheap Dark-Detecting LED Circuit] - Nachtaktives LED-Throwie, aber hoher Knopfzellen-Ruhestrom 3mA !&lt;br /&gt;
* [http://www.datasheetcatalog.org/cgi-bin/helo.pl?field=Nume&amp;amp;type=C&amp;amp;text=sfh300&amp;amp;producedby=&amp;amp;action=Search SFH 300 FA-3/4 mit integriertem Infrarotfilter]&lt;br /&gt;
&lt;br /&gt;
=== LED ===&lt;br /&gt;
&lt;br /&gt;
[[LED]]s kann man auch als Photodiode betreiben, wenngleich der Wirkungsgrad bescheiden ist.&lt;br /&gt;
&lt;br /&gt;
Günstiger für Helligkeitsmessungen ist jedoch, die LED in Sperrrichtung zu betreiben. Hier verhält sie sich wie einen Kondensator mit einer parallelen lichtabhängigen Stromquelle (Siehe erstes Paper). Die Anode wird gegen Ground geschaltet und die Kathode kommt an einen IO-Port-Pin eines µC.&lt;br /&gt;
&lt;br /&gt;
[[bild:led_brightnessensor.svg]]&lt;br /&gt;
&lt;br /&gt;
Die Messung erfolgt in 3 Schritten:&lt;br /&gt;
# LED aufladen durch Schalten des Pins auf High und kurz warten.&lt;br /&gt;
# Umstellen des Pins auf High-Impedanz Eingang (kein Pull-Up!). Der Strom fließt nun recht langsam aus dem Kondensator über die Stromquelle nach GND ab. Daher sinkt die Spannung stetig und fällt soweit ab, dass der µC ihn als Low erkennt.&lt;br /&gt;
# Zeit messen, bis Eingang auf LOW fällt.&lt;br /&gt;
&lt;br /&gt;
Hier eine beispielhafte C-Routine für [[AVR]]:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
static uint8_t SensorLEDGetValue()  &lt;br /&gt;
{&lt;br /&gt;
 uint8_t entladezeit = 0;&lt;br /&gt;
&lt;br /&gt;
 // Portpin PB3 auf Ausgang stellen und LED aufladen&lt;br /&gt;
 DDRB  |= (1&amp;lt;&amp;lt;PIN3);  &lt;br /&gt;
 PORTB |= (1&amp;lt;&amp;lt;PIN3);  &lt;br /&gt;
 _delay_us(10);&lt;br /&gt;
&lt;br /&gt;
 // Portpin PB3 auf Eingang stellen&lt;br /&gt;
 DDRB  &amp;amp;= ~(1&amp;lt;&amp;lt;PIN3);&lt;br /&gt;
 PORTB &amp;amp;= ~(1&amp;lt;&amp;lt;PIN3);&lt;br /&gt;
  &lt;br /&gt;
 // Zeit (in 5ms Schritten) messen bis &lt;br /&gt;
 // Signalpegel am Portpin auf LOW fällt&lt;br /&gt;
 while(PINB &amp;amp; (1&amp;lt;&amp;lt;PIN3) &amp;amp;&amp;amp; (entladezeit != 0xff)){&lt;br /&gt;
   ++entladezeit;&lt;br /&gt;
   _delay_ms(5);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 return entladezeit;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Ganze lässt sich natürlich noch clever in Timer-ISRs packen, damit das Programm zwischendurch weiterlaufen kann. Hängt man das andere Ende anstatt an Ground ebenfalls an einen µC-PIN so kann man die LED zusätzlich auch noch ganz normal benutzen.&lt;br /&gt;
&lt;br /&gt;
* [http://www.merl.com/reports/docs/TR2003-35.pdf] Paper (die Theorie und Möglichkeiten)&lt;br /&gt;
* [http://www.geoclub.de/ftopic5753.html Reaktives Licht fürs Geocaching] - Doppelnutzung einer LED als Lichtsensor und als Lichtquelle von Sir Vivor. ([[AVR]])&lt;br /&gt;
* [http://www.ti.com/litv/zip/slac136c] - MSP430 Demo Code&lt;br /&gt;
* [http://mrl.nyu.edu/~jhan/ledtouch/index.html] - LED Matrix als Touch-Sensor&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/73776] - LED Matrix als Touch-Sensor&lt;br /&gt;
&lt;br /&gt;
== Integrierte Photosensoren ==&lt;br /&gt;
&lt;br /&gt;
*[http://www.taosinc.com Texas Advanced Optoelectronic Solutions]&lt;br /&gt;
*[http://www.micromaus.de Micromaus: Sensoren, AVRs, PICs und mehr]&lt;br /&gt;
*Light-to-Voltage Converters&lt;br /&gt;
*Light-to-Frequency Converters (z.&amp;amp;nbsp;B. TSL230R, tageslichttauglich)&lt;br /&gt;
*Linear Sensor Arrays&lt;br /&gt;
*Light-to-Digital Converters&lt;br /&gt;
*Color Sensors&lt;br /&gt;
&lt;br /&gt;
Texas Instruments&lt;br /&gt;
* [http://focus.ti.com/lit/ds/symlink/opt101.pdf OPT101, Photodiode mit integriertem TIA]&lt;br /&gt;
* [http://www.ti.com/lit/gpn/opt301 OPT301, Photodiode mit integriertem TIA]&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/163163#new Thread im Forum, Gleichanteil bei Photodioden aktiv kompensieren]&lt;br /&gt;
* [http://www.lichtsprechen.de/ Webseite zu Amateurfunk mit Lichtwellen, Tips zur Schaltungstechnik und Optik]&lt;br /&gt;
* [http://de.wikipedia.org/wiki/Photowiderstand Wikipedia:Photowiderstand]&lt;br /&gt;
* [http://de.wikipedia.org/wiki/Photohalbleiter Wikipedia:Photohalbleiter]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Sensorik]]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=RFM12&amp;diff=59764</id>
		<title>RFM12</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=RFM12&amp;diff=59764"/>
		<updated>2011-08-23T19:31:14Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: /* Links */ Link geändert von Code auf Wiki&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Beschreibung der Funkmodule RFM01, RFM02 und RFM12.&lt;br /&gt;
&lt;br /&gt;
Benötigt werden in der Minimal-Version im FIFO-Modus nur die Anschlüsse nSEL, SDO, SDI und SCK, eben das komplette SPI-Interface. Der Zugriff auf das Sende- und Empfangs-FIFO ist per Software möglich, ebenso die Abfrage der Statusbits. Deshalb werden z.&amp;amp;nbsp;B. nIRQ und nFFS nicht unbedingt benötigt. nIRQ signalisiert unter anderem, dass das Modul bereit ist Daten zu empfangen. Wenn Daten empfangen wurden, kann dies über den FFIT-Pin abgefragt werden (falls die Füllschwelle eingestellt wurde). nFFS dient dazu das FIFO direkt anzusprechen (es ist quasi der Chipselect für das FIFO), davon wird in der Minimalversion aber kein Gebrauch gemacht. Der Pin muss daher auf high-Pegel gelegt werden!&lt;br /&gt;
An CLK kann eine Frequenz von 1MHz bis 10MHz eingestellt werden. Hiermit kann dann z.&amp;amp;nbsp;B. der Mikrocontroller versorgt werden.&lt;br /&gt;
Reset ist ein Open-Collector-Ausgang und gleichzeitig der Reset-Eingang. Er sollte daher entweder gar nicht, oder aber hochohmig angeschlossen werden.&lt;br /&gt;
&lt;br /&gt;
Im FIFO-Mode kann das Modul konfiguriert werden mit dem Empfang zu warten, bis die Daten 0x2DD4 empfangen wurden. Sobald dieses Bitmuster empfangen wurde, werden Daten in das FIFO geschrieben, bis man das FIFO abschaltet und die Mustererkennung neu startet.&lt;br /&gt;
&lt;br /&gt;
Als weitere Modi stehen unter anderem ein synchroner Modus zur Verfügung (no FIFO mode), in dem der Sender/Empfänger den Bittakt ausgibt, und synchron dazu die zu sendenden Daten einliest bzw. die empfangenen Daten ausgibt. Der SPI Bus ist trotzdem zur Initialisierung des Moduls notwendig.&lt;br /&gt;
&lt;br /&gt;
== FAQ ==&lt;br /&gt;
&lt;br /&gt;
=== Soll ich 433 oder 868 MHz nehmen? ===&lt;br /&gt;
&lt;br /&gt;
Wähle das für deine Anwendung kleinere der beiden Übel: Bei 433 MHz sind i.d.R. mehr Störer unterwegs und bei 868 MHz sind die maximale Belegungsdauer bzw. das listen-before-talk (LBT) Verfahren gemäß [[Allgemeinzuteilung]] zu beachten. Siehe auch im Forum [http://www.mikrocontroller.net/topic/198559] und [http://www.mikrocontroller.net/topic/196693].&lt;br /&gt;
&lt;br /&gt;
=== SPI Interface ===&lt;br /&gt;
&lt;br /&gt;
* Maximale SPI Frequenz: 2,5MHz (10MHz Quarz / 4)&lt;br /&gt;
&lt;br /&gt;
=== CLK-Ausgang bleibt bei 1 MHz ===&lt;br /&gt;
&lt;br /&gt;
* Vor dem Umschalten (mit 0xC0E0) länger warten.&lt;br /&gt;
&lt;br /&gt;
=== RFM12 empfängt ein paar Bytes, dann nur Müll ===&lt;br /&gt;
&lt;br /&gt;
* Es wird zu langsam gesendet (TX FIFO underrun)&lt;br /&gt;
* Es wird zu langsam empfangen (RX FIFO overrun)&lt;br /&gt;
&lt;br /&gt;
Die Status-Bits helfen hier beim Debuggen. SPI sollte auf maximaler Transferrate stehen.&lt;br /&gt;
&lt;br /&gt;
=== RFM empfängt nur Müll ===&lt;br /&gt;
&lt;br /&gt;
http://www.mikrocontroller.net/topic/73560#605528&lt;br /&gt;
&lt;br /&gt;
Deine Module verhalten sich normal. Man muß mit den Gain- und AFC-Bits&lt;br /&gt;
eine ganze Weile spielen, bis die Module korrekt laufen (kommt auf die&lt;br /&gt;
Anwendung an). Fakt ist: der Empfänger empfängt ständig Datenmüll als&lt;br /&gt;
Rauschen. Wenn der FIFO durch die Präambel getriggert wird, sind die&lt;br /&gt;
Daten im FIFO ziemlich korrekt, wenn alles &amp;quot;gut&amp;quot; eingestellt ist. Der&lt;br /&gt;
FIFO sollte per Interrupt dann auch sofort abgeholt werden, da sonst das&lt;br /&gt;
nächste Byte das alte direkt überschreibt. Jeder zusammenhängende&lt;br /&gt;
Datensatz (mehrere Bytes an einem Stück) muß von einer Präambel&lt;br /&gt;
eingeleitet werden. Nach dem kompletten Einlesen eines Datensatzes muß&lt;br /&gt;
der FIFO abgeschaltet, wieder eingeschaltet und für den Empfang der&lt;br /&gt;
nächsten Präambel neu scharf gemacht werden.&lt;br /&gt;
&lt;br /&gt;
=== RFM hängt sich auf ===&lt;br /&gt;
&lt;br /&gt;
Wenn man die AFC nicht begrenzt, also keinen Wertebereich vorgibt, die eine maximale Abweichung korrigiert wird passiert es nach einer Weile, dass sich der Empfänger aufhängt, die Offsetbits im Status werden maximal und dann geht gar nichts mehr, er hängt fest.&lt;br /&gt;
&lt;br /&gt;
edit: Leider bringt die Beschränkung der AFC auf Minimum bei mir keine Verbesserung. Zumindest ist obige Aussage nicht allgemein gültig.&lt;br /&gt;
&lt;br /&gt;
Siehe auch &lt;br /&gt;
* Forenbeitrag [http://www.mikrocontroller.net/topic/82456#689660 RFM12: Erfahrungen ]&lt;br /&gt;
&lt;br /&gt;
=== Kommunikation mit RFM funktioniert nur sporadisch ===&lt;br /&gt;
&lt;br /&gt;
* Ist die Versorgungsspannung stabil? (evtl. Kondensator einbauen)&lt;br /&gt;
&lt;br /&gt;
=== Interrupt nIRQ klappt nicht bei 868MHz ===&lt;br /&gt;
&lt;br /&gt;
Wenn bei der Verwendung der 868er Module die üblichen Sourcen (dasLabor, etc) verwendet werden, müssen einige Änderungen gemacht werden, die sich leicht finden lassen. Ohne weiteres funktionierte der blockierende Empfang, der Interruptbetriebene (nIRQ) machte in mindestens einem Fall Probleme. Hier half die Anpassung des FIFO IT Level . In vorhandenen Sourcen ist 0xCA83 zu finden, eine Änderung auf 0xCAF3 hilft dabei.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Register ==&lt;br /&gt;
&lt;br /&gt;
Von https://www.mikrocontroller.net/attachment/24947/RFM12.txt&lt;br /&gt;
&lt;br /&gt;
Dieses Dokument beschreibt die Nutzung des RFM12 TRX Moduls!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039; WICHTIG &#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Dieses Dokument wurde aus mehreren Quellen zusammengestellt, und kann Fehler enthalten!&lt;br /&gt;
Es können Abweichungen in Bezug auf RF01 / RF02 / RF12 / RFM01 / RFM02 und andere Module auftreten!&lt;br /&gt;
Es wurde das Datenblatt vom RFM12B und RF12 von www.hoperf.com als Basis genuzt. Zusätzlich wurden diese Informationen mit Hilfe von Forums-Nutzern (https://www.mikrocontroller.net/topic/71682) weiter vervollständigt!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039; WICHTIG &#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Hinweis:&#039;&#039;&#039; Die LNA-Eingangsimpedanz beträgt 250 Ohm, und muss beim Anschluss einer 50-Ohm-Antenne entsprechend angepasst werden, um das Rauschen zu minimieren! &#039;&#039; -- (Auf den Pollin-Modulen bereits vorhanden)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Configuration Setting ===&lt;br /&gt;
 Hex = 80 &amp;amp; xx&lt;br /&gt;
 Bit-Syntax: &lt;br /&gt;
{| cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
!width=&amp;quot;20%&amp;quot;| Byte ||width=&amp;quot;40%&amp;quot;| 1 || 2&lt;br /&gt;
|-&lt;br /&gt;
!Bits&lt;br /&gt;
|{{8Bit|width=100%| 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 }}||{{8Bit|width=100%| el | ef | b1 | b0 | x3 | x2 | x1 | x0}}|}&lt;br /&gt;
 el (TX FIFO) = Sendepuffer für Datentransfer nutzen (1 = An / 0 = Aus)&lt;br /&gt;
 ef (RX FIFO) = Empfangspuffer für Datenspeicherung nutzen (1 = An / 0 = Aus)&lt;br /&gt;
 b... = Zu nutzende Basisfrequenz (00=315MHz / 01=433MHz / 10=868MHz / 11=915MHz)&lt;br /&gt;
 x... = Interner Clock des Chips kann durch verschieben einer Kondensator-Anpass-Stufe bestimmt werden.&lt;br /&gt;
        0,5pF pro Schritt. Basis ist 8,5pF -&amp;gt; (0000=8,5 / 0001=9,0 / 0010=9,5 / ...)&lt;br /&gt;
&lt;br /&gt;
=== Power-Management ===&lt;br /&gt;
 Hex = 82 &amp;amp; xx&lt;br /&gt;
 Bit-Syntax: 10000010 | er | ebb | et | es | ex | eb | ew | dc&lt;br /&gt;
 er = Empfänger einschalten (1 = an / 0 = Aus)&lt;br /&gt;
 ebb = ... (Synthesizer muss aktiv sein!) (1 = an / 0 = aus)&lt;br /&gt;
 et = Sender einschalten (1 = an / 0 = Aus) (Wenn das TX-Register aktiv und mit Daten gefüllt ist/wurde,&lt;br /&gt;
      werden diese Daten sofort gesendet) (1 = an / 0 = aus)&lt;br /&gt;
 es = Schaltet den Synthesizer ein. (1 = an / 0 = aus)&lt;br /&gt;
 ex = Schaltet den Quarz-Oszilator ein. (1 = an / 0 = aus)&lt;br /&gt;
 eb = Vergleichbar mit BrownOutDetection -&amp;gt; Erkennt eine zu geringe Betriebsspannung und erzeugt einen Interrupt,&lt;br /&gt;
      um einen drohenden Spannungsaufall anzukündigen (1 = An / 0 = Aus)&lt;br /&gt;
 ew = Aktiviert den WakeUpTimer des Prozessors. (1 = an / 0 = aus)&lt;br /&gt;
 dc = Deaktiviert die Ausgabe des SystemClocks auf dem CLK Pin am Chip (1 = Keine ClockAusgabe / 0 = Clock ausgeben)&lt;br /&gt;
&lt;br /&gt;
=== PLL Setting ===&lt;br /&gt;
 Hex = 198 + y&lt;br /&gt;
 Bit-Syntax: 110011000 | ob1 | ob0 | lpx | ddy | ddit | bw1 | bw0&lt;br /&gt;
 ob... = ... (00= 5 oder 10MHz [standard] / 01=3.3MHz / 1x=2.5MHz oder weniger)&lt;br /&gt;
 lpx = Wählt den Low-Power-Mode für den Quarz-Oszilator aus. (0=1ms [620µA] / 1=2ms [460µA])&lt;br /&gt;
 ddy = ...&lt;br /&gt;
 ddi = Schaltet das Dithering in PLL-Schleife ab. (1=abgeschaltet / 0=eingeschaltet)&lt;br /&gt;
 bw... = Wählt die Bandbreite des PLL-Signals aus. (00=86.2kbps [-107dBc/Hz] / 01=256kbps [-102dBc/Hz]) Bei 1MHz Offset Phasenrauschen.&lt;br /&gt;
&lt;br /&gt;
=== LowBatt / µC Clock Control ===&lt;br /&gt;
 Hex = c0 &amp;amp; xx&lt;br /&gt;
 Bit-Syntax: 11000000 | d2 | d1 | d0 | v4 | v3 | v2 | v1 | v0&lt;br /&gt;
 d... = Bestimmt den Teilungsfaktor für die Clockausgabe am CLK-Pin in Abhängigkeit des Internen SystemTakts.&lt;br /&gt;
        (000=1 / 001=1.25 / 010=1.66 / 011=2 / 100=2.5 / 101=3.33 / 110=5 / 111=10)&lt;br /&gt;
 v... = Bestimmt die Minimalspannung, ab der ein Interrupt durchgeführt werden&lt;br /&gt;
 muss. (Ähnlich einer BrownOutDetection). Im Power-Managment muss das eb-Bit&lt;br /&gt;
 aktiv sein, damit dies funktioniert.&lt;br /&gt;
&lt;br /&gt;
=== Frequency-setting ===&lt;br /&gt;
Bestimmt den Offset der Sende- und Empfangsfrequenz. Dieser Offset wird auf das Basisband im Configuration Setting hinzu gerechnet.&lt;br /&gt;
 Hex = a &amp;amp; xxx&lt;br /&gt;
 Bit-Syntax:&lt;br /&gt;
{| cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
!width=&amp;quot;20%&amp;quot;| Byte ||width=&amp;quot;40%&amp;quot;| 1 || 2&lt;br /&gt;
|-&lt;br /&gt;
!Bits&lt;br /&gt;
|{{8Bit|width=100%| 1 | 0 | 1 | 0 | f11 | f10 | f9 | f8 }}||{{8Bit|width=100%| f7 | f6 | f5 | f4 | f3 | f2 | f1 | f0}}|}&lt;br /&gt;
&lt;br /&gt;
 f... = Bestimmt den Offsetwert der Frequenz.&lt;br /&gt;
        Als Basis gilt das eingestellte Band im Configuration-Settings-Kommando&lt;br /&gt;
&lt;br /&gt;
freq = 10 * C1 * (C2 + f/4000) [MHz]&lt;br /&gt;
&lt;br /&gt;
{| cellspacing=&amp;quot;0&amp;quot; border=&amp;quot;1&amp;quot; style=&amp;quot;text-align:center;&amp;quot;&lt;br /&gt;
! Band || C1 || C2&lt;br /&gt;
|-&lt;br /&gt;
| 315 || 1 || 31&lt;br /&gt;
|-&lt;br /&gt;
| 433 || 1 || 43&lt;br /&gt;
|-&lt;br /&gt;
| 868 || 2 || 43&lt;br /&gt;
|-&lt;br /&gt;
| 915 || 3 || 30&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Data-Rate ===&lt;br /&gt;
 Hex = c6 &amp;amp; xx&lt;br /&gt;
 Bit-Syntax: 11000110 | cs | r6 | r5 | r4 | r3 | r2 | r1 | r0&lt;br /&gt;
 cs =  Vorteiler, Faktor 8. Hiermit kann ein Vorteiler aktiviert werden,&lt;br /&gt;
       der die errechnete Baudrate (r...) durch 8 teilt.&lt;br /&gt;
 r... = Baudratenteilerfaktor&lt;br /&gt;
&lt;br /&gt;
=== RX Control ===&lt;br /&gt;
 Hex = 94 &amp;amp; xx&lt;br /&gt;
 Bit-Syntax: 10010 | p20 | d1 | d2 | i2 | i1 | i0 | g1 | g0 | r2 | r1 | r0&lt;br /&gt;
 p20 = Bestimmt die Funktion des Pin20 (nINT / VDI) am RFM12 Chip (1 = VDI-Ausgang / 0 = Interrupt-Eingang)&lt;br /&gt;
 d... = (Valid Data Indicator). Definiert die Geschwindigkeit, mit der bestimmt wird, ob ein Signal korrekt ist, oder nicht.&lt;br /&gt;
        (00=schnell / 01=mittel / 10=langsam / 11=immer an). Je nach eingestellter Variante werden&lt;br /&gt;
        unterschiedliche Hardware- und Software-Kombinationen genuzt.&lt;br /&gt;
        Fast:  CR_Lock  OR  DQD  ... Medium:  CR_Lock  AND ( DRSSI  OR  DQD ) ... &lt;br /&gt;
        SLOW: R/S FlipFlop aus (SET)  DRSSI  OR  DQD  OR  CR_Lock  und (CLR)  DRSSI  AND  DQD  AND  CR_Lock .&lt;br /&gt;
 i... = Bestimmt die Bandbreite des Empfängers in KHz (KiloHertz).&lt;br /&gt;
        (000=Reserviert / 001=400 / 010=340 / 011=270 / 100=200 / 101=134 / 110=67 / 111=Reserviert)&lt;br /&gt;
 g... = (LNA-Gain) Verstärkungsfaktor des Rauscharmen-Eingangs-Signal-Verstärkers (LNA Low Noise Amplifier).&lt;br /&gt;
        Werte in dBm (Dezibel [Grösse: Milliwatt]) Mögliche Werte sind: 0 / -6 / -14 / -20&lt;br /&gt;
 r... = (DRSSI = Digital Received Signal Strength Indication) Minimale Empfangssignalfeldstärke.&lt;br /&gt;
        6 dBm pro Schritt: (000=-103 / 001=-97 / 010=-91 / ...)&lt;br /&gt;
&lt;br /&gt;
=== Synchron Pattern ===&lt;br /&gt;
 Hex = ce &amp;amp; xx&lt;br /&gt;
 Bit-Syntax: 11001110 | b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0&lt;br /&gt;
 b... = Legt den Wert fest, der als Synchronisations-Byte für die Datenfilterung verwendet werden soll.&lt;br /&gt;
&lt;br /&gt;
=== Data Filter ===&lt;br /&gt;
 Hex = c2 &amp;amp; xx&lt;br /&gt;
 Bit-Syntax: 11000010 | al | ml | -unknow- (1) | s | -unknow- (1) | f2 | f1 | f0&lt;br /&gt;
 al = Baudratenregenerator schaltet automatisch in den langsamen Modus, &lt;br /&gt;
      sobald er einen Takt erkannt hat.&lt;br /&gt;
 ml = schneller/langsamer Modus&lt;br /&gt;
 -unknown- (1) = ??? (Standard = 1) (Auch im Datenblatt von IA4420 so beschrieben)&lt;br /&gt;
 s = (DataFilter) Typ des Datenfilters (0=DigitalFilter / 1=AnalogFilter).&lt;br /&gt;
     Bei Nutzung des Analog-Filters kann kein FIFO sowie kein ClockRecovery genuzt werden.&lt;br /&gt;
 -unknown- (1) = ??? (Standard = 1) (Auch im Datenblatt von IA4420 so beschrieben)&lt;br /&gt;
 f... = (DQD Threshold) Bestimmt den Schwellwert, ab dem ein Signal als gut empfunden wird,&lt;br /&gt;
         und der Empfänger dieses weiterverarbeiten soll.&lt;br /&gt;
         DQD (data quality detection) zählt die &amp;quot;Spikes&amp;quot; des ungefilterten Signals, und bestimmt darüber die Qualität der Daten.&lt;br /&gt;
&lt;br /&gt;
=== FIFO und RESET-Mode ===&lt;br /&gt;
 Hex = ca &amp;amp; xx&lt;br /&gt;
 Bit-Syntax: 11001010 | f3 | f2 | f1 | f0 | sp | al | ff | dr&lt;br /&gt;
 f... = (FIFO interrupt Level)&lt;br /&gt;
 sp = (Sync-Pattern length) Legt die Länge des Synchron-Patterns fest&lt;br /&gt;
      (0 = 2Byte / 1 = 1Byte)&lt;br /&gt;
 al = (FIFO Fill Condition) Legt den Wert fest, ab dem das Füllen des FIFOs beginnt.&lt;br /&gt;
      (0=Synchron / 1=Ständig). Bei Nutzung des Synchron-Modus, werden erst dann Daten in den FIFO geschrieben,&lt;br /&gt;
      wenn eine definierte 8-Bit od. 16-Bit lange Datenfolge empfangen wurde (Standard ist Hex: 2dd4,&lt;br /&gt;
      das LSB kann geändert werden und stellt das 8-Bit Synchron-Pattern dar).&lt;br /&gt;
 ff = (FIFO Fill) Startet das Einlesen der empfangenen Daten in den FIFO-Puffer.&lt;br /&gt;
      Wenn al (FIFO Fill Condition) auf synchron steht, dann startet das Setzen dieses Bits die Synchronisation-Bit-Erkennung.&lt;br /&gt;
 dr = (Sens Reset Mode) Wenn dieses Bit auf 0 steht, wird bei einer Schwankung von 200mV auf&lt;br /&gt;
      der VCC-Leitung (Spannungsversorgung des Chips), ein System-Reset ausgelöst.&lt;br /&gt;
&lt;br /&gt;
=== Automatic Frequency Control ===&lt;br /&gt;
 Hex = c4 &amp;amp; xx&lt;br /&gt;
 Bit-Syntax: 11000100 | a1 | a0 | rl1 | rl0 | st | fi | oe | en&lt;br /&gt;
 a... = Modus der AFC-Schaltung, 0=Auto off, 1=einmalig nach Einschalten, 2=Solange VDI low ist, 3=unabhängig von VDI&lt;br /&gt;
 r... = (Range Limit) Frequenzraster (00=KeineBegrenzung / 01=+15 &amp;gt; -16 / 10=+7 &amp;gt; -8 / 11=+3 &amp;gt; -4)&lt;br /&gt;
 st = Berechneten Offset-Wert übernehmen&lt;br /&gt;
 fi = Genauer Berechnungsmodus (besser aber lansgamer)&lt;br /&gt;
 oe = AFC-Offset freischalten&lt;br /&gt;
 en = AFC-Berechnung aktivieren&lt;br /&gt;
&lt;br /&gt;
=== TX Configuration Control ===&lt;br /&gt;
 Hex = 98 &amp;amp; xx&lt;br /&gt;
 Bit-Syntax: 1001100 | mp | m3 | m2 | m1 | m0 | -unknow- (0) | p2 | p1 | p0&lt;br /&gt;
 mp = (Modulation Polarity) Bestimmt die Richtung der FSK-Erzeugung (invertiert das Spektrum).&lt;br /&gt;
 m... = (fDeviation) Bestimmt den Frequenzabstand des High- und Low-Wertes bei der Ubertragung im FSK-Betrieb. Basis ist der mp-Wert.&lt;br /&gt;
 -unknown- (0) = ??? (Standard = 0) (Auch im Datenblatt von IA4420 so beschrieben)&lt;br /&gt;
 p... = Bestimmt die relative Ausgangsleistung des Senders anhand des dBm-Wertes (Dezibel [Grösse: Milliwat]) 3-dBm-Schritte.&lt;br /&gt;
        (000=0 / 001=-3 / 010=-6 / ...). Der Wert steht im Zusammenhang mit der angeschlossenen Antennen-Impedanz.&lt;br /&gt;
&lt;br /&gt;
=== Wake-Up Timer ===&lt;br /&gt;
 Bestimmt die Zeitperiode der zyklischen Einschaltung des WakeUp-Timers&lt;br /&gt;
 Hex = e &amp;amp; xxx&lt;br /&gt;
 Bit-Syntax: 111 | R4 | R3 | R2 | R1 | R0 | M7 | M6 | M5 | M4 | M3 | M2 | M1 | M0&lt;br /&gt;
 R = Exponent der Zeit&lt;br /&gt;
 M = Zeit&lt;br /&gt;
&lt;br /&gt;
=== Low Duty-Cycle ===&lt;br /&gt;
&lt;br /&gt;
Bestimmt die maximale Sendezeit pro Stunde. Dies ist wichtig, um sich an gesetzliche Frequenzzuteilungsrichtlinien zu halten, die bestimmen, wie lang jemand mit einer definierten Sendeleistung auf einer bestimmten Frequenz (mit eventuell definierter Betriebsart [Modulationstyp]) senden darf.)&lt;br /&gt;
&lt;br /&gt;
 hex = 6400 + Bits&lt;br /&gt;
 Bit-Syntax: 11001000 | d6 | d5 | d4 | d3 | d2 | d1 | d0 | en&lt;br /&gt;
 d... = Einschaltdauer während der zyklischen Einschaltung&lt;br /&gt;
 en = zyklische Einschaltung aktivieren&lt;br /&gt;
&lt;br /&gt;
=== RX FIFO Read ===&lt;br /&gt;
 Hex = b000&lt;br /&gt;
 Bit-Syntax: 1011000000000000&lt;br /&gt;
&lt;br /&gt;
Dieses Kommando löst die Rückgabe eines Datenbytes (synchron mit dem 8. Bit) aus. Es ist nötig, dass das ef-Bit (RX-FIFO) im Configuration Setting gesetzt wurde, um diese Funktion nutzen zu können!&lt;br /&gt;
&lt;br /&gt;
=== TX Register Write ===&lt;br /&gt;
Dieses Kommando schreibt Daten in den TX-Puffer. Wenn der Sender aktiv ist, wird dieses sofort gesendet. el (TX-Register) muss im Configuration-Setting-Kommando aktiv sein.&lt;br /&gt;
 Hex = b8 &amp;amp; xx&lt;br /&gt;
 Bit-Syntax: 10111000 | DataByteToSend&lt;br /&gt;
 DataByteToSend = Das Datenbyte, welches gesendet werden soll.&lt;br /&gt;
&lt;br /&gt;
(Senden Funktioniert nur wenn zuvor der Status abgefragt wurde)&lt;br /&gt;
&lt;br /&gt;
=== Status Read ===&lt;br /&gt;
Dieses Kommando löst die Rückgabe des Statusregisters aus, welches nach der ersten 0 im ersten Bit synchron übertragen wird.&lt;br /&gt;
 Hex = 0000&lt;br /&gt;
 Bit-Syntax: 0000000000000000&amp;lt;000&amp;gt;&lt;br /&gt;
 Rückgabe-Syntax: x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | x10 | x11 | x12 | x13 | x14 | x15 | x16 | x17 | x18&lt;br /&gt;
 x0 -&amp;gt; x5 = Interrupt bits&lt;br /&gt;
 x6 -&amp;gt; x15 = Status Bits&lt;br /&gt;
 x16 -&amp;gt; x18 = FIFO&lt;br /&gt;
 x0 = FFIT / RGIT (RGIT = TX-Register ist bereit neue Daten zu senden ... kann mit dem TX-Register gelöscht werden)&lt;br /&gt;
     (FFIT = Die Anzahl der Datenbits im FIFO-Puffer hat das eingestellte Limit erreicht.&lt;br /&gt;
      Kann mit einer der FIFO-Lesemethoden gelöscht werden)&lt;br /&gt;
 x1 = POR (PowerOnReset)&lt;br /&gt;
 x2 = FFOV / RGUR (RGUR = Der Datenstrom beim Senden ist abgerissen, da nicht schnell genug Daten nachgeladen wurden)&lt;br /&gt;
      (FFOV = Der RX-FIFO ist übergelaufen)&lt;br /&gt;
 x3 = WKUP&lt;br /&gt;
 x4 = EXT (Externer IRq vom nINT-Pin)&lt;br /&gt;
 x5 = LBD (Low Battery Detected)&lt;br /&gt;
 x6 = FFEM (Der FIFO-Puffer ist leer/EMpty)&lt;br /&gt;
 x7 = RSSI/ATS (ATS = )(RSSI = Die Signalstärke ist über dem eingestelltem Limit)&lt;br /&gt;
 x8 = DQD&lt;br /&gt;
 x9 = CRL&lt;br /&gt;
 x10 = ATGL&lt;br /&gt;
 x11 = OFFS_6 (sign of offset)&lt;br /&gt;
 x12 = OFFS_3&lt;br /&gt;
 x13 = OFFS_2&lt;br /&gt;
 x14 = OFFS_1&lt;br /&gt;
 x15 = OFFS_0&lt;br /&gt;
 x16 = FO&lt;br /&gt;
 x17 = FO+1&lt;br /&gt;
 x18 = FO+2&lt;br /&gt;
&lt;br /&gt;
== Einstellungen für maximale Reichweite ==&lt;br /&gt;
&lt;br /&gt;
Für eine maximale Reichweite eignen sich folgende Einstellungen:&lt;br /&gt;
* Bitrate: 2k - 10kbit/s.&lt;br /&gt;
* Receiver Baseband Bandwidth: 134kHz&lt;br /&gt;
* RSSI Threshold: -97dBm&lt;br /&gt;
* LNA gain: 0dB. Falls in der Gegend Störer im gleichen Frequenzbereich sind, dann -6dB, ansonsten kann die Eingangsstufe übersteuern.&lt;br /&gt;
* FSK frequency deviation: +/-90kHz&lt;br /&gt;
* Output Power: 0dB&lt;br /&gt;
&lt;br /&gt;
Und vor allem: Eine gute (Richt-) Antenne.&lt;br /&gt;
&lt;br /&gt;
== Quarzfrequenz ändern==&lt;br /&gt;
Im Datenblatt wird die Verwendung eines 10 MHz-Quarzes empfohlen. Man darf die Frequenz aber nach oben und unten variieren, wie Messungen mit einem DDS-Generators anstelle des Quarzes zeigen: [[Media:PLL-Rastbereich_log.pdf|PLL-Einrast-Tabelle]]. Eine [[Media:RFM12Quarz.pdf|Tabelle: Quarzfrequenzen von 8,5-11 MHz]] zeigt die damit erreichbaren Frequenzen. Quarze für 3. oder auch 5.Oberton sollten auch auf ihrer Grundfrequenz verwendbar sein, dafür bieten sich u.a. CB-Funk- und 10m-Amateurbandquarze an. &lt;br /&gt;
&lt;br /&gt;
Den Einfluß der vier unteren Bits im Configuration Setting Register und des mp-Bits (Modulations-Polarität?) auf die PLL-Frequenz zeigt diese [[Media:Varicap_RFM12.pdf|Kapazitäts-Tabelle]]. Pro Stufe sind es hier etwa 4 kHz, das kann je nach Quarz schwanken. Möglicherweise ist so auch Schmalband-FSK möglich, ohne Änderung des PLL-Teilers.&lt;br /&gt;
&lt;br /&gt;
Was können wir damit anfangen? Neben dem regulären Einsatz auf den beiden zugelassenen Bändern 433 und 868 MHz sind das unter anderem (bitte weitere Ideen einfügen):&lt;br /&gt;
&lt;br /&gt;
* Packet-Radio mit 9600 Baud im 70cm-Amateurband 430-440 MHz. Die einfachste Möglichkeit ist das Programm [http://www.baycom.org/~tom/ham/soundmodem/ Soundmodem], das für Windows und Linux existiert. Wer es komfortabler haben will findet [http://www.dj4uf.de/funktechnik/soundmodem/soundmodem.htm hier] eine Beschreibung wie Soundmodem mit den Programmen [http://www.flexnet.info/ Flexnet] und [http://www.paxon.de Paxon] zusammenarbeitet. Eine Karte der Packet-Radio-Digipeater im 70cm-Band kann man mittels [http://www.hammap.de Hammap] erstellen. Leider werden die Daten in den letzten Jahren nicht mehr sehr gepflegt, es dürften einige Karteileichen enthalten sein.&lt;br /&gt;
&lt;br /&gt;
* Empfang der [http://www.adacom.org/projekte/funkruf/ POCSAG-Funkrufsender] am oberen Ende des Amateurbandes auf  439,9875 MHz 2-FSK mit 4kHz Hub und 1200 bit/s im POCSAG Radio Paging Code 1 [http://home.arcor.de/norbert_n/samsfaq/sams.txt (Liste der Sender, Stand 18.09.07)]. Zur Decodierung existieren mehrere Programme, aufbauend auf [http://www.baycom.org/~tom/ham/linux/multimon.html Multimon] die Weiterentwicklungen [http://www.monitor.mgrohmann.de/ Monitor] und [http://monitord.de/ MonitorD]. Im Prinzip könnte man damit auch die verschlüsselten Wettermeldungen auf 466,23 MHz mitschreiben, aber nicht decodieren.&lt;br /&gt;
&lt;br /&gt;
* Empfang der [http://www.darc.de/vus/digital.html D-Star-Relais]. Das ist eine patentierte digitale Sprach- und Datenübertragung, deren Eigentümer dafür sorgt, dass kein käufliches oder Selbstbaufunkgerät ohne den &amp;quot;AMBE&amp;quot;-Modemchip D-Star senden und empfangen darf. Es gibt eine kleine Ausnahme, das [http://www.darc.de/vus/down/dstar_decode_v02a.zip Programm r00t&#039;s D-Star Decoder V0.2a] für die Soundkarte, das nur Rufzeichen und Datentelegramme der beteiligten Funkamateure darstellt.&lt;br /&gt;
&lt;br /&gt;
* Panoramaempfänger (die Bezeichnung Spektrumanalysator wäre etwas übertrieben) unter Verwendung des analogen RSSI Ausgangs (Anschluß am Kondensator in der Ecke). Damit ließe sich z.&amp;amp;nbsp;B. auch die Bandbelegung im PMR-Bereich 446,0-446,2 MHz oder im Mobilfunkband um 900 MHz anzeigen.&lt;br /&gt;
&lt;br /&gt;
* Pegelanzeige für Mobilfunksender. Im 900 MHz Mobilfunkbereich könnte man mit dem RSSI-Ausgang die umliegenden Funkmasten anpeilen und ihre Pegel anzeigen. Laut Datenblatt nur ein Anzeigeumfang von 35 dB, aber mit umschaltbarem Grundpegel.&lt;br /&gt;
&lt;br /&gt;
* In Verbindung mit einem Frequenzumsetzer lassen sich weitere Frequenzbereiche erschließen, z.&amp;amp;nbsp;B. Packet-Radio im 23cm- (1240-1200 MHz)  und 13cm- (2320-2450 MHz) Amateurband. Leider liegt die Zwischenfrequenz der Satellitentuner (479,5 MHz) schon am oberen Ende des PLL-VCO-Einrastbereiches. Damit wäre ein preiswerter Konverter für 23cm möglich, meistens schon mit I2C-Bus PLL.&lt;br /&gt;
&lt;br /&gt;
* Local Oscillator für einen Empfänger. Mir den ca. 5 Milliwatt des RFM12 läßt sich ein [http://www.mini-circuits.com/products/fm_sm_main.html passiver Diodenringmischer] ansteuern. Damit kann man einen Überlagerungsempfänger oder -sender mit hoher erster Zwischenfrequenz bauen.&lt;br /&gt;
&lt;br /&gt;
== Antennen-Anpaßnetzwerk==&lt;br /&gt;
[[Image:Antennenanpassung.png|thumb|right|400px|Antennen-Anpassnetzwerk im Datenblatt]]&lt;br /&gt;
Soll das RFM12 auf anderen Frequenzen betrieben werden, ist nur eine Änderung des Antennennetzwerks nötig. Das Datenblatt bietet knappe aber ausreichende Informationen.  &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zwischen Pin 12 und 13 liegt eine Spannungsquelle, die ihre maximale Sendeleistung in eine komplexe Last nach der Tabelle &amp;quot;Note4&amp;quot; abgibt. Das bedeutet, ihr Innenwiderstand ist konjugiert-komplex zu dieser Last, also dieselben Zahlenwerte, nur mit Minuszeichen vor dem &amp;quot;j&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Anpassnetzwerk läßt sich auf zwei Bauteile reduzieren: von der Antenne ausgehend, die als reeller 50 Ohm- Widerstand angenommen wird, ist ein Kondensator in Reihe geschaltet. C8 und C9 (in der Tabelle C9 und C10 bezeichnet) liegen in Reihe und sind gleich groß, dürfen also in einem Kondensator mit der halben Kapazität zusammengefasst werden. Dann liegt noch L1 parallel zur Quelle, L3 hat mehr als den 20-fachen Wert und kann vernachlässigt werden.&lt;br /&gt;
Das ganze läßt sich im Smith-Diagramm gut darstellen.&lt;br /&gt;
&lt;br /&gt;
[[Image:SmithDiagramm.png|thumb|right|400px|Anpassnetzwerk im Smith-Diagramm]]&lt;br /&gt;
&lt;br /&gt;
Von der Antenne im Mittelpunkt ausgehend bewegen wir uns mit dem Serien-C Cs auf einem Kreisbogen nach unten (kapazitive Halbebene) auf den Punkt &amp;quot;Unendlich&amp;quot; rechts außen zu. Ungefähr senkrecht unter dem Zielpunkt, hier für 433 MHz gezeichnet, biegen wir ab auf eine Kreisbahn für die Parallelinduktivität Lp. Sie führt in die obere (induktive) Halbebene auf den Nullpunkt links zu. Der genaue Schnittpunkt beider Kreise kann &amp;quot;mit Zirkel und Lineal&amp;quot; oder einem der [http://www.mikrocontroller.net/articles/Schaltungssimulation#Hochfrequenztechnik Hochfrequenz-Berechnungsprogramme] ermittelt werden.&lt;br /&gt;
&lt;br /&gt;
Die Kreise für Lp oder Cp sind im Smith-Diagramm nicht eingezeichnet , um die Übersicht zu wahren. Man könnte ein gespiegeltes Diagramm darüberlegen, aber stattdessen spiegelt man die Kurve am Diagramm-Mittelpunkt (dünne blaue Kurven). Am Rand kann man jetzt die auf 50 Ohm (bzw. 1/50Ohm für die gespiegelte Kurve) normierten Blindwiderstände ablesen. Für Cs lesen wir eine Differenz zwischen Start und Zielpunkt von etwa Xc=(3,2-0) * 50 Ohm ab, für Lp sind es (0,25 +0,32) = 0,57*(1/50 Ohm). Damit erhalten wir Cs=1/(2*Pi*f*Xc)=2,3 pF das war wie gesagt die halbe Kapazität der beiden hintereinandergeschalteten Kondensatoren, Tabellenwert ist 4,7pF und Lp=1/(2*Pi*f*0,57*(1/50))= 32,2 nH, der Tabellenwert ist 27nH.&lt;br /&gt;
&lt;br /&gt;
[[Image:Antennenanpassung_RF12.png|thumb|right|400px|Anpassnetzwerk im Datenblatt zu RF12]]&lt;br /&gt;
[[Image:Smith-Diagramm-RF12.png|thumb|right|400px|Smith-Diagramm zum RF12]]&lt;br /&gt;
Im RF12 wird ein um zwei Bauteile (im Bild C2 und L1 genannt) erweitertes Netzwerk empfohlen, das macht man um eine breitbandigere Anpassung zu erreichen.&lt;br /&gt;
&lt;br /&gt;
== Betriebsspannung==&lt;br /&gt;
Achtung nicht alle Module sind für 5V geeignet, alle Typen mit &amp;quot;B&amp;quot; am Ende sind nur für 3,3V. Man muß dann entweder den Mikrocontroller ebenfalls mit 3,3V betreiben, oder [http://www.mikrocontroller.net/articles/Pegelwandler Pegelwandler] verwenden.&lt;br /&gt;
&lt;br /&gt;
== Messungen ==&lt;br /&gt;
Drei Messungen am RFM12 zeigen den Einfluß von Eingangpegel, Frequenzhub und Mittenfrequenz auf das Ausgangssignal, gemessen am Filterkondensator CFIL. Zwei weitere Kurven zeigen die ARSSI-Spannung (Anschluß am Kondensator in der Ecke) und die damit gemessene Filterkurve.&lt;br /&gt;
[[Image:RFM12_Eingangspegel.png|thumb|right|800px|Messungen am RFM12 Änderung des Eingangspegels]]&lt;br /&gt;
[[Image:RFM12_Frequenzhub.png|thumb|right|800px|Messungen am RFM12 Änderung des Frequenzhubs]]&lt;br /&gt;
[[Image:RFM12_Mittenfrequenz.png|thumb|right|800px|Messungen am RFM12 Änderung der Mittenfrequenz]]&lt;br /&gt;
[[Image:RFM12_ARSSI_und_Filterkurve.png|thumb|right|200px|Messungen am RFM12 ARSSI_und_Filterkurve]]&lt;br /&gt;
&lt;br /&gt;
Was folgt aus diesen Messungen?&lt;br /&gt;
* Der ARRSI-Anschluß zeigt uns über mehr als 100 kHz ein Sendesignal an. Decodierbar ist es aber nur im Abstand von weniger als 5 kHz von der Mittenfrequenz. Ohne Abgleich von Sender und Empfänger ist also die AFC unverzichtbar.&lt;br /&gt;
* Das &amp;quot;Loch&amp;quot; in der Mitte der Durchlaßkurve stammt von dem im Datenblatt gezeigten Hochpass &amp;quot;&amp;gt; 7 kHz&amp;quot;. Für ein unmoduliertes Sendesignal geht die ARSSI-Spannung fast auf den Rauschpegel herunter, hier wurde mit +/-15kHz moduliert. &lt;br /&gt;
* Damit läßt sich der Empfänger abgleichen. Man braucht dazu nur ein unmoduliertes Sendesignal auf der Sollfrequenz. Das kann ein mittels Frequenzzähler abgeglichenes zweites RFM12 sein. Der Empfängerquarz wird mit den 4 Bit für die Oszillatorkapazität genau auf dieses &amp;quot;Loch&amp;quot; der ARRSI-Spannung eingestellt.&lt;br /&gt;
&lt;br /&gt;
Die AFC-Messdauer ist im Datenblatt nicht genannt, eine schnelle Abfrage des ATGL-Bit im Statusregister im &amp;quot;Auto-AFC&amp;quot; - Modus liefert minimale Pulsbreiten von ca. 250..270 µsec, entsprechend einer Messfolgefrequenz von 4 kHz - leider nicht ausreichend um 9600 Baud Schmalband-FM zu demodulieren. Im Auto-Modus werden zwei Messungen zusammengefasst, damit beträgt die Updaterate sogar nur 2 kHz. Weitere Messung : ab etwa +/-10 kHz Hub synchronisiert sich das ATGL-Bit auf der Mittenfrequenz mit einem bis zu 1,8...2 kHz FM-modulierten Signal.&lt;br /&gt;
&lt;br /&gt;
Neue Idee: &amp;quot;Dithering und FM-Flankendemodulator&amp;quot;: &amp;lt;br&amp;gt; &lt;br /&gt;
Wenn das Empfangssignal nicht weit genug FM-moduliert ist, müssen wir eben den Empfänger modulieren. Im Timer-Interrupt wird die Quarzkapazität oder die PLL z.&amp;amp;nbsp;B. mit 38,4 oder 76,8 kHz und mindestens +/-15kHz Hub umgeschaltet, sodaß bei Empfang eines unmodulierten Signals am CFIL-Ausgang ein symmetrisches Rechteck dieser Frequenz erscheint. Ist das Empfangssignal schmalbandig FM-moduliert, und man stimmt den Empfänger leicht daneben ab, so sollte das CFIL-Signal mit dieser Modulation PWM-moduliert sein. Ein Tiefpass filtert die Dithering-Frequenz weg und übrig bleibt (wenns funktioniert) die Modulation, vielleicht sogar analoger Sprechfunk...&lt;br /&gt;
Motto &amp;quot;Engineering is the art of making what you want from things you can get.&amp;quot; (von http://www.dsprelated.com)&lt;br /&gt;
&lt;br /&gt;
== Bezugsquellen ==&lt;br /&gt;
* [[Elektronikversender#csd-electronics|csd-electronics]]&lt;br /&gt;
* [[Elektronikversender#IT-WNS|IT-WNS]]&lt;br /&gt;
* [[Elektronikversender#Pollin_Electronic|Pollin Electronic]]&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
* [[AVR RFM12]]&lt;br /&gt;
* [[RFM12 Protokoll Stack]]&lt;br /&gt;
* [[RF_SOAP]]&lt;br /&gt;
* [[ Pollin_Funk-AVR-Evaluationsboard]]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/93801 Bezugsquellen]&lt;br /&gt;
* [http://www.das-labor.org/wiki/RFM12_library Library zur Ansteuerung des RFM12]&lt;br /&gt;
* [http://www.compotron.com/daten/any/IA4420.pdf Datenblatt des Chipherstellers Integration IA4420.pdf]&lt;br /&gt;
* [https://www.silabs.com/Support%20Documents/TechnicalDocs/Si4420.pdf Silabs hat Integration im Juni 2008 gekauft, Chipbezeichnung jetzt Si4420]&lt;br /&gt;
Folgende Links sind mit Vorsicht zu genießen, da die Datenblätter teilweise  fehlerbehaftet sind. Es empfiehlt sich, direkt mit dem Datenblatt des RF12 (das ist das IC auf dem Modul) zu arbeiten. Dieses ist so gut wie fehlerfrei.&lt;br /&gt;
&lt;br /&gt;
* [http://www.hoperf.com/upload/rf/RF12.pdf Datenblatt des ICs RF12] (PDF)&lt;br /&gt;
* [http://www.hoperf.com/upload/rf/RFM12.pdf Datenblatt des Moduls RFM12] (PDF)&lt;br /&gt;
* [http://www.hoperf.com/upload/rf/RF12_code.pdf Programming Guide] (PDF)&lt;br /&gt;
* [http://www.hoperf.com/upload/rf/RF12TOOLS.pdf Demo Kit User Manual] (PDF)&lt;br /&gt;
* [http://www.pollin.de/shop/downloads/D810047S.ZIP Beispielprogramm von Pollin] (ZIP)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Bauteile]]&lt;br /&gt;
[[Kategorie:Funk]]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=RFM12&amp;diff=59762</id>
		<title>RFM12</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=RFM12&amp;diff=59762"/>
		<updated>2011-08-23T19:28:09Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: /* Links */ Links aktualisiert.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Beschreibung der Funkmodule RFM01, RFM02 und RFM12.&lt;br /&gt;
&lt;br /&gt;
Benötigt werden in der Minimal-Version im FIFO-Modus nur die Anschlüsse nSEL, SDO, SDI und SCK, eben das komplette SPI-Interface. Der Zugriff auf das Sende- und Empfangs-FIFO ist per Software möglich, ebenso die Abfrage der Statusbits. Deshalb werden z.&amp;amp;nbsp;B. nIRQ und nFFS nicht unbedingt benötigt. nIRQ signalisiert unter anderem, dass das Modul bereit ist Daten zu empfangen. Wenn Daten empfangen wurden, kann dies über den FFIT-Pin abgefragt werden (falls die Füllschwelle eingestellt wurde). nFFS dient dazu das FIFO direkt anzusprechen (es ist quasi der Chipselect für das FIFO), davon wird in der Minimalversion aber kein Gebrauch gemacht. Der Pin muss daher auf high-Pegel gelegt werden!&lt;br /&gt;
An CLK kann eine Frequenz von 1MHz bis 10MHz eingestellt werden. Hiermit kann dann z.&amp;amp;nbsp;B. der Mikrocontroller versorgt werden.&lt;br /&gt;
Reset ist ein Open-Collector-Ausgang und gleichzeitig der Reset-Eingang. Er sollte daher entweder gar nicht, oder aber hochohmig angeschlossen werden.&lt;br /&gt;
&lt;br /&gt;
Im FIFO-Mode kann das Modul konfiguriert werden mit dem Empfang zu warten, bis die Daten 0x2DD4 empfangen wurden. Sobald dieses Bitmuster empfangen wurde, werden Daten in das FIFO geschrieben, bis man das FIFO abschaltet und die Mustererkennung neu startet.&lt;br /&gt;
&lt;br /&gt;
Als weitere Modi stehen unter anderem ein synchroner Modus zur Verfügung (no FIFO mode), in dem der Sender/Empfänger den Bittakt ausgibt, und synchron dazu die zu sendenden Daten einliest bzw. die empfangenen Daten ausgibt. Der SPI Bus ist trotzdem zur Initialisierung des Moduls notwendig.&lt;br /&gt;
&lt;br /&gt;
== FAQ ==&lt;br /&gt;
&lt;br /&gt;
=== Soll ich 433 oder 868 MHz nehmen? ===&lt;br /&gt;
&lt;br /&gt;
Wähle das für deine Anwendung kleinere der beiden Übel: Bei 433 MHz sind i.d.R. mehr Störer unterwegs und bei 868 MHz sind die maximale Belegungsdauer bzw. das listen-before-talk (LBT) Verfahren gemäß [[Allgemeinzuteilung]] zu beachten. Siehe auch im Forum [http://www.mikrocontroller.net/topic/198559] und [http://www.mikrocontroller.net/topic/196693].&lt;br /&gt;
&lt;br /&gt;
=== SPI Interface ===&lt;br /&gt;
&lt;br /&gt;
* Maximale SPI Frequenz: 2,5MHz (10MHz Quarz / 4)&lt;br /&gt;
&lt;br /&gt;
=== CLK-Ausgang bleibt bei 1 MHz ===&lt;br /&gt;
&lt;br /&gt;
* Vor dem Umschalten (mit 0xC0E0) länger warten.&lt;br /&gt;
&lt;br /&gt;
=== RFM12 empfängt ein paar Bytes, dann nur Müll ===&lt;br /&gt;
&lt;br /&gt;
* Es wird zu langsam gesendet (TX FIFO underrun)&lt;br /&gt;
* Es wird zu langsam empfangen (RX FIFO overrun)&lt;br /&gt;
&lt;br /&gt;
Die Status-Bits helfen hier beim Debuggen. SPI sollte auf maximaler Transferrate stehen.&lt;br /&gt;
&lt;br /&gt;
=== RFM empfängt nur Müll ===&lt;br /&gt;
&lt;br /&gt;
http://www.mikrocontroller.net/topic/73560#605528&lt;br /&gt;
&lt;br /&gt;
Deine Module verhalten sich normal. Man muß mit den Gain- und AFC-Bits&lt;br /&gt;
eine ganze Weile spielen, bis die Module korrekt laufen (kommt auf die&lt;br /&gt;
Anwendung an). Fakt ist: der Empfänger empfängt ständig Datenmüll als&lt;br /&gt;
Rauschen. Wenn der FIFO durch die Präambel getriggert wird, sind die&lt;br /&gt;
Daten im FIFO ziemlich korrekt, wenn alles &amp;quot;gut&amp;quot; eingestellt ist. Der&lt;br /&gt;
FIFO sollte per Interrupt dann auch sofort abgeholt werden, da sonst das&lt;br /&gt;
nächste Byte das alte direkt überschreibt. Jeder zusammenhängende&lt;br /&gt;
Datensatz (mehrere Bytes an einem Stück) muß von einer Präambel&lt;br /&gt;
eingeleitet werden. Nach dem kompletten Einlesen eines Datensatzes muß&lt;br /&gt;
der FIFO abgeschaltet, wieder eingeschaltet und für den Empfang der&lt;br /&gt;
nächsten Präambel neu scharf gemacht werden.&lt;br /&gt;
&lt;br /&gt;
=== RFM hängt sich auf ===&lt;br /&gt;
&lt;br /&gt;
Wenn man die AFC nicht begrenzt, also keinen Wertebereich vorgibt, die eine maximale Abweichung korrigiert wird passiert es nach einer Weile, dass sich der Empfänger aufhängt, die Offsetbits im Status werden maximal und dann geht gar nichts mehr, er hängt fest.&lt;br /&gt;
&lt;br /&gt;
edit: Leider bringt die Beschränkung der AFC auf Minimum bei mir keine Verbesserung. Zumindest ist obige Aussage nicht allgemein gültig.&lt;br /&gt;
&lt;br /&gt;
Siehe auch &lt;br /&gt;
* Forenbeitrag [http://www.mikrocontroller.net/topic/82456#689660 RFM12: Erfahrungen ]&lt;br /&gt;
&lt;br /&gt;
=== Kommunikation mit RFM funktioniert nur sporadisch ===&lt;br /&gt;
&lt;br /&gt;
* Ist die Versorgungsspannung stabil? (evtl. Kondensator einbauen)&lt;br /&gt;
&lt;br /&gt;
=== Interrupt nIRQ klappt nicht bei 868MHz ===&lt;br /&gt;
&lt;br /&gt;
Wenn bei der Verwendung der 868er Module die üblichen Sourcen (dasLabor, etc) verwendet werden, müssen einige Änderungen gemacht werden, die sich leicht finden lassen. Ohne weiteres funktionierte der blockierende Empfang, der Interruptbetriebene (nIRQ) machte in mindestens einem Fall Probleme. Hier half die Anpassung des FIFO IT Level . In vorhandenen Sourcen ist 0xCA83 zu finden, eine Änderung auf 0xCAF3 hilft dabei.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Register ==&lt;br /&gt;
&lt;br /&gt;
Von https://www.mikrocontroller.net/attachment/24947/RFM12.txt&lt;br /&gt;
&lt;br /&gt;
Dieses Dokument beschreibt die Nutzung des RFM12 TRX Moduls!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039; WICHTIG &#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Dieses Dokument wurde aus mehreren Quellen zusammengestellt, und kann Fehler enthalten!&lt;br /&gt;
Es können Abweichungen in Bezug auf RF01 / RF02 / RF12 / RFM01 / RFM02 und andere Module auftreten!&lt;br /&gt;
Es wurde das Datenblatt vom RFM12B und RF12 von www.hoperf.com als Basis genuzt. Zusätzlich wurden diese Informationen mit Hilfe von Forums-Nutzern (https://www.mikrocontroller.net/topic/71682) weiter vervollständigt!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039; WICHTIG &#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Hinweis:&#039;&#039;&#039; Die LNA-Eingangsimpedanz beträgt 250 Ohm, und muss beim Anschluss einer 50-Ohm-Antenne entsprechend angepasst werden, um das Rauschen zu minimieren! &#039;&#039; -- (Auf den Pollin-Modulen bereits vorhanden)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Configuration Setting ===&lt;br /&gt;
 Hex = 80 &amp;amp; xx&lt;br /&gt;
 Bit-Syntax: &lt;br /&gt;
{| cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
!width=&amp;quot;20%&amp;quot;| Byte ||width=&amp;quot;40%&amp;quot;| 1 || 2&lt;br /&gt;
|-&lt;br /&gt;
!Bits&lt;br /&gt;
|{{8Bit|width=100%| 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 }}||{{8Bit|width=100%| el | ef | b1 | b0 | x3 | x2 | x1 | x0}}|}&lt;br /&gt;
 el (TX FIFO) = Sendepuffer für Datentransfer nutzen (1 = An / 0 = Aus)&lt;br /&gt;
 ef (RX FIFO) = Empfangspuffer für Datenspeicherung nutzen (1 = An / 0 = Aus)&lt;br /&gt;
 b... = Zu nutzende Basisfrequenz (00=315MHz / 01=433MHz / 10=868MHz / 11=915MHz)&lt;br /&gt;
 x... = Interner Clock des Chips kann durch verschieben einer Kondensator-Anpass-Stufe bestimmt werden.&lt;br /&gt;
        0,5pF pro Schritt. Basis ist 8,5pF -&amp;gt; (0000=8,5 / 0001=9,0 / 0010=9,5 / ...)&lt;br /&gt;
&lt;br /&gt;
=== Power-Management ===&lt;br /&gt;
 Hex = 82 &amp;amp; xx&lt;br /&gt;
 Bit-Syntax: 10000010 | er | ebb | et | es | ex | eb | ew | dc&lt;br /&gt;
 er = Empfänger einschalten (1 = an / 0 = Aus)&lt;br /&gt;
 ebb = ... (Synthesizer muss aktiv sein!) (1 = an / 0 = aus)&lt;br /&gt;
 et = Sender einschalten (1 = an / 0 = Aus) (Wenn das TX-Register aktiv und mit Daten gefüllt ist/wurde,&lt;br /&gt;
      werden diese Daten sofort gesendet) (1 = an / 0 = aus)&lt;br /&gt;
 es = Schaltet den Synthesizer ein. (1 = an / 0 = aus)&lt;br /&gt;
 ex = Schaltet den Quarz-Oszilator ein. (1 = an / 0 = aus)&lt;br /&gt;
 eb = Vergleichbar mit BrownOutDetection -&amp;gt; Erkennt eine zu geringe Betriebsspannung und erzeugt einen Interrupt,&lt;br /&gt;
      um einen drohenden Spannungsaufall anzukündigen (1 = An / 0 = Aus)&lt;br /&gt;
 ew = Aktiviert den WakeUpTimer des Prozessors. (1 = an / 0 = aus)&lt;br /&gt;
 dc = Deaktiviert die Ausgabe des SystemClocks auf dem CLK Pin am Chip (1 = Keine ClockAusgabe / 0 = Clock ausgeben)&lt;br /&gt;
&lt;br /&gt;
=== PLL Setting ===&lt;br /&gt;
 Hex = 198 + y&lt;br /&gt;
 Bit-Syntax: 110011000 | ob1 | ob0 | lpx | ddy | ddit | bw1 | bw0&lt;br /&gt;
 ob... = ... (00= 5 oder 10MHz [standard] / 01=3.3MHz / 1x=2.5MHz oder weniger)&lt;br /&gt;
 lpx = Wählt den Low-Power-Mode für den Quarz-Oszilator aus. (0=1ms [620µA] / 1=2ms [460µA])&lt;br /&gt;
 ddy = ...&lt;br /&gt;
 ddi = Schaltet das Dithering in PLL-Schleife ab. (1=abgeschaltet / 0=eingeschaltet)&lt;br /&gt;
 bw... = Wählt die Bandbreite des PLL-Signals aus. (00=86.2kbps [-107dBc/Hz] / 01=256kbps [-102dBc/Hz]) Bei 1MHz Offset Phasenrauschen.&lt;br /&gt;
&lt;br /&gt;
=== LowBatt / µC Clock Control ===&lt;br /&gt;
 Hex = c0 &amp;amp; xx&lt;br /&gt;
 Bit-Syntax: 11000000 | d2 | d1 | d0 | v4 | v3 | v2 | v1 | v0&lt;br /&gt;
 d... = Bestimmt den Teilungsfaktor für die Clockausgabe am CLK-Pin in Abhängigkeit des Internen SystemTakts.&lt;br /&gt;
        (000=1 / 001=1.25 / 010=1.66 / 011=2 / 100=2.5 / 101=3.33 / 110=5 / 111=10)&lt;br /&gt;
 v... = Bestimmt die Minimalspannung, ab der ein Interrupt durchgeführt werden&lt;br /&gt;
 muss. (Ähnlich einer BrownOutDetection). Im Power-Managment muss das eb-Bit&lt;br /&gt;
 aktiv sein, damit dies funktioniert.&lt;br /&gt;
&lt;br /&gt;
=== Frequency-setting ===&lt;br /&gt;
Bestimmt den Offset der Sende- und Empfangsfrequenz. Dieser Offset wird auf das Basisband im Configuration Setting hinzu gerechnet.&lt;br /&gt;
 Hex = a &amp;amp; xxx&lt;br /&gt;
 Bit-Syntax:&lt;br /&gt;
{| cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
!width=&amp;quot;20%&amp;quot;| Byte ||width=&amp;quot;40%&amp;quot;| 1 || 2&lt;br /&gt;
|-&lt;br /&gt;
!Bits&lt;br /&gt;
|{{8Bit|width=100%| 1 | 0 | 1 | 0 | f11 | f10 | f9 | f8 }}||{{8Bit|width=100%| f7 | f6 | f5 | f4 | f3 | f2 | f1 | f0}}|}&lt;br /&gt;
&lt;br /&gt;
 f... = Bestimmt den Offsetwert der Frequenz.&lt;br /&gt;
        Als Basis gilt das eingestellte Band im Configuration-Settings-Kommando&lt;br /&gt;
&lt;br /&gt;
freq = 10 * C1 * (C2 + f/4000) [MHz]&lt;br /&gt;
&lt;br /&gt;
{| cellspacing=&amp;quot;0&amp;quot; border=&amp;quot;1&amp;quot; style=&amp;quot;text-align:center;&amp;quot;&lt;br /&gt;
! Band || C1 || C2&lt;br /&gt;
|-&lt;br /&gt;
| 315 || 1 || 31&lt;br /&gt;
|-&lt;br /&gt;
| 433 || 1 || 43&lt;br /&gt;
|-&lt;br /&gt;
| 868 || 2 || 43&lt;br /&gt;
|-&lt;br /&gt;
| 915 || 3 || 30&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Data-Rate ===&lt;br /&gt;
 Hex = c6 &amp;amp; xx&lt;br /&gt;
 Bit-Syntax: 11000110 | cs | r6 | r5 | r4 | r3 | r2 | r1 | r0&lt;br /&gt;
 cs =  Vorteiler, Faktor 8. Hiermit kann ein Vorteiler aktiviert werden,&lt;br /&gt;
       der die errechnete Baudrate (r...) durch 8 teilt.&lt;br /&gt;
 r... = Baudratenteilerfaktor&lt;br /&gt;
&lt;br /&gt;
=== RX Control ===&lt;br /&gt;
 Hex = 94 &amp;amp; xx&lt;br /&gt;
 Bit-Syntax: 10010 | p20 | d1 | d2 | i2 | i1 | i0 | g1 | g0 | r2 | r1 | r0&lt;br /&gt;
 p20 = Bestimmt die Funktion des Pin20 (nINT / VDI) am RFM12 Chip (1 = VDI-Ausgang / 0 = Interrupt-Eingang)&lt;br /&gt;
 d... = (Valid Data Indicator). Definiert die Geschwindigkeit, mit der bestimmt wird, ob ein Signal korrekt ist, oder nicht.&lt;br /&gt;
        (00=schnell / 01=mittel / 10=langsam / 11=immer an). Je nach eingestellter Variante werden&lt;br /&gt;
        unterschiedliche Hardware- und Software-Kombinationen genuzt.&lt;br /&gt;
        Fast:  CR_Lock  OR  DQD  ... Medium:  CR_Lock  AND ( DRSSI  OR  DQD ) ... &lt;br /&gt;
        SLOW: R/S FlipFlop aus (SET)  DRSSI  OR  DQD  OR  CR_Lock  und (CLR)  DRSSI  AND  DQD  AND  CR_Lock .&lt;br /&gt;
 i... = Bestimmt die Bandbreite des Empfängers in KHz (KiloHertz).&lt;br /&gt;
        (000=Reserviert / 001=400 / 010=340 / 011=270 / 100=200 / 101=134 / 110=67 / 111=Reserviert)&lt;br /&gt;
 g... = (LNA-Gain) Verstärkungsfaktor des Rauscharmen-Eingangs-Signal-Verstärkers (LNA Low Noise Amplifier).&lt;br /&gt;
        Werte in dBm (Dezibel [Grösse: Milliwatt]) Mögliche Werte sind: 0 / -6 / -14 / -20&lt;br /&gt;
 r... = (DRSSI = Digital Received Signal Strength Indication) Minimale Empfangssignalfeldstärke.&lt;br /&gt;
        6 dBm pro Schritt: (000=-103 / 001=-97 / 010=-91 / ...)&lt;br /&gt;
&lt;br /&gt;
=== Synchron Pattern ===&lt;br /&gt;
 Hex = ce &amp;amp; xx&lt;br /&gt;
 Bit-Syntax: 11001110 | b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0&lt;br /&gt;
 b... = Legt den Wert fest, der als Synchronisations-Byte für die Datenfilterung verwendet werden soll.&lt;br /&gt;
&lt;br /&gt;
=== Data Filter ===&lt;br /&gt;
 Hex = c2 &amp;amp; xx&lt;br /&gt;
 Bit-Syntax: 11000010 | al | ml | -unknow- (1) | s | -unknow- (1) | f2 | f1 | f0&lt;br /&gt;
 al = Baudratenregenerator schaltet automatisch in den langsamen Modus, &lt;br /&gt;
      sobald er einen Takt erkannt hat.&lt;br /&gt;
 ml = schneller/langsamer Modus&lt;br /&gt;
 -unknown- (1) = ??? (Standard = 1) (Auch im Datenblatt von IA4420 so beschrieben)&lt;br /&gt;
 s = (DataFilter) Typ des Datenfilters (0=DigitalFilter / 1=AnalogFilter).&lt;br /&gt;
     Bei Nutzung des Analog-Filters kann kein FIFO sowie kein ClockRecovery genuzt werden.&lt;br /&gt;
 -unknown- (1) = ??? (Standard = 1) (Auch im Datenblatt von IA4420 so beschrieben)&lt;br /&gt;
 f... = (DQD Threshold) Bestimmt den Schwellwert, ab dem ein Signal als gut empfunden wird,&lt;br /&gt;
         und der Empfänger dieses weiterverarbeiten soll.&lt;br /&gt;
         DQD (data quality detection) zählt die &amp;quot;Spikes&amp;quot; des ungefilterten Signals, und bestimmt darüber die Qualität der Daten.&lt;br /&gt;
&lt;br /&gt;
=== FIFO und RESET-Mode ===&lt;br /&gt;
 Hex = ca &amp;amp; xx&lt;br /&gt;
 Bit-Syntax: 11001010 | f3 | f2 | f1 | f0 | sp | al | ff | dr&lt;br /&gt;
 f... = (FIFO interrupt Level)&lt;br /&gt;
 sp = (Sync-Pattern length) Legt die Länge des Synchron-Patterns fest&lt;br /&gt;
      (0 = 2Byte / 1 = 1Byte)&lt;br /&gt;
 al = (FIFO Fill Condition) Legt den Wert fest, ab dem das Füllen des FIFOs beginnt.&lt;br /&gt;
      (0=Synchron / 1=Ständig). Bei Nutzung des Synchron-Modus, werden erst dann Daten in den FIFO geschrieben,&lt;br /&gt;
      wenn eine definierte 8-Bit od. 16-Bit lange Datenfolge empfangen wurde (Standard ist Hex: 2dd4,&lt;br /&gt;
      das LSB kann geändert werden und stellt das 8-Bit Synchron-Pattern dar).&lt;br /&gt;
 ff = (FIFO Fill) Startet das Einlesen der empfangenen Daten in den FIFO-Puffer.&lt;br /&gt;
      Wenn al (FIFO Fill Condition) auf synchron steht, dann startet das Setzen dieses Bits die Synchronisation-Bit-Erkennung.&lt;br /&gt;
 dr = (Sens Reset Mode) Wenn dieses Bit auf 0 steht, wird bei einer Schwankung von 200mV auf&lt;br /&gt;
      der VCC-Leitung (Spannungsversorgung des Chips), ein System-Reset ausgelöst.&lt;br /&gt;
&lt;br /&gt;
=== Automatic Frequency Control ===&lt;br /&gt;
 Hex = c4 &amp;amp; xx&lt;br /&gt;
 Bit-Syntax: 11000100 | a1 | a0 | rl1 | rl0 | st | fi | oe | en&lt;br /&gt;
 a... = Modus der AFC-Schaltung, 0=Auto off, 1=einmalig nach Einschalten, 2=Solange VDI low ist, 3=unabhängig von VDI&lt;br /&gt;
 r... = (Range Limit) Frequenzraster (00=KeineBegrenzung / 01=+15 &amp;gt; -16 / 10=+7 &amp;gt; -8 / 11=+3 &amp;gt; -4)&lt;br /&gt;
 st = Berechneten Offset-Wert übernehmen&lt;br /&gt;
 fi = Genauer Berechnungsmodus (besser aber lansgamer)&lt;br /&gt;
 oe = AFC-Offset freischalten&lt;br /&gt;
 en = AFC-Berechnung aktivieren&lt;br /&gt;
&lt;br /&gt;
=== TX Configuration Control ===&lt;br /&gt;
 Hex = 98 &amp;amp; xx&lt;br /&gt;
 Bit-Syntax: 1001100 | mp | m3 | m2 | m1 | m0 | -unknow- (0) | p2 | p1 | p0&lt;br /&gt;
 mp = (Modulation Polarity) Bestimmt die Richtung der FSK-Erzeugung (invertiert das Spektrum).&lt;br /&gt;
 m... = (fDeviation) Bestimmt den Frequenzabstand des High- und Low-Wertes bei der Ubertragung im FSK-Betrieb. Basis ist der mp-Wert.&lt;br /&gt;
 -unknown- (0) = ??? (Standard = 0) (Auch im Datenblatt von IA4420 so beschrieben)&lt;br /&gt;
 p... = Bestimmt die relative Ausgangsleistung des Senders anhand des dBm-Wertes (Dezibel [Grösse: Milliwat]) 3-dBm-Schritte.&lt;br /&gt;
        (000=0 / 001=-3 / 010=-6 / ...). Der Wert steht im Zusammenhang mit der angeschlossenen Antennen-Impedanz.&lt;br /&gt;
&lt;br /&gt;
=== Wake-Up Timer ===&lt;br /&gt;
 Bestimmt die Zeitperiode der zyklischen Einschaltung des WakeUp-Timers&lt;br /&gt;
 Hex = e &amp;amp; xxx&lt;br /&gt;
 Bit-Syntax: 111 | R4 | R3 | R2 | R1 | R0 | M7 | M6 | M5 | M4 | M3 | M2 | M1 | M0&lt;br /&gt;
 R = Exponent der Zeit&lt;br /&gt;
 M = Zeit&lt;br /&gt;
&lt;br /&gt;
=== Low Duty-Cycle ===&lt;br /&gt;
&lt;br /&gt;
Bestimmt die maximale Sendezeit pro Stunde. Dies ist wichtig, um sich an gesetzliche Frequenzzuteilungsrichtlinien zu halten, die bestimmen, wie lang jemand mit einer definierten Sendeleistung auf einer bestimmten Frequenz (mit eventuell definierter Betriebsart [Modulationstyp]) senden darf.)&lt;br /&gt;
&lt;br /&gt;
 hex = 6400 + Bits&lt;br /&gt;
 Bit-Syntax: 11001000 | d6 | d5 | d4 | d3 | d2 | d1 | d0 | en&lt;br /&gt;
 d... = Einschaltdauer während der zyklischen Einschaltung&lt;br /&gt;
 en = zyklische Einschaltung aktivieren&lt;br /&gt;
&lt;br /&gt;
=== RX FIFO Read ===&lt;br /&gt;
 Hex = b000&lt;br /&gt;
 Bit-Syntax: 1011000000000000&lt;br /&gt;
&lt;br /&gt;
Dieses Kommando löst die Rückgabe eines Datenbytes (synchron mit dem 8. Bit) aus. Es ist nötig, dass das ef-Bit (RX-FIFO) im Configuration Setting gesetzt wurde, um diese Funktion nutzen zu können!&lt;br /&gt;
&lt;br /&gt;
=== TX Register Write ===&lt;br /&gt;
Dieses Kommando schreibt Daten in den TX-Puffer. Wenn der Sender aktiv ist, wird dieses sofort gesendet. el (TX-Register) muss im Configuration-Setting-Kommando aktiv sein.&lt;br /&gt;
 Hex = b8 &amp;amp; xx&lt;br /&gt;
 Bit-Syntax: 10111000 | DataByteToSend&lt;br /&gt;
 DataByteToSend = Das Datenbyte, welches gesendet werden soll.&lt;br /&gt;
&lt;br /&gt;
(Senden Funktioniert nur wenn zuvor der Status abgefragt wurde)&lt;br /&gt;
&lt;br /&gt;
=== Status Read ===&lt;br /&gt;
Dieses Kommando löst die Rückgabe des Statusregisters aus, welches nach der ersten 0 im ersten Bit synchron übertragen wird.&lt;br /&gt;
 Hex = 0000&lt;br /&gt;
 Bit-Syntax: 0000000000000000&amp;lt;000&amp;gt;&lt;br /&gt;
 Rückgabe-Syntax: x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | x10 | x11 | x12 | x13 | x14 | x15 | x16 | x17 | x18&lt;br /&gt;
 x0 -&amp;gt; x5 = Interrupt bits&lt;br /&gt;
 x6 -&amp;gt; x15 = Status Bits&lt;br /&gt;
 x16 -&amp;gt; x18 = FIFO&lt;br /&gt;
 x0 = FFIT / RGIT (RGIT = TX-Register ist bereit neue Daten zu senden ... kann mit dem TX-Register gelöscht werden)&lt;br /&gt;
     (FFIT = Die Anzahl der Datenbits im FIFO-Puffer hat das eingestellte Limit erreicht.&lt;br /&gt;
      Kann mit einer der FIFO-Lesemethoden gelöscht werden)&lt;br /&gt;
 x1 = POR (PowerOnReset)&lt;br /&gt;
 x2 = FFOV / RGUR (RGUR = Der Datenstrom beim Senden ist abgerissen, da nicht schnell genug Daten nachgeladen wurden)&lt;br /&gt;
      (FFOV = Der RX-FIFO ist übergelaufen)&lt;br /&gt;
 x3 = WKUP&lt;br /&gt;
 x4 = EXT (Externer IRq vom nINT-Pin)&lt;br /&gt;
 x5 = LBD (Low Battery Detected)&lt;br /&gt;
 x6 = FFEM (Der FIFO-Puffer ist leer/EMpty)&lt;br /&gt;
 x7 = RSSI/ATS (ATS = )(RSSI = Die Signalstärke ist über dem eingestelltem Limit)&lt;br /&gt;
 x8 = DQD&lt;br /&gt;
 x9 = CRL&lt;br /&gt;
 x10 = ATGL&lt;br /&gt;
 x11 = OFFS_6 (sign of offset)&lt;br /&gt;
 x12 = OFFS_3&lt;br /&gt;
 x13 = OFFS_2&lt;br /&gt;
 x14 = OFFS_1&lt;br /&gt;
 x15 = OFFS_0&lt;br /&gt;
 x16 = FO&lt;br /&gt;
 x17 = FO+1&lt;br /&gt;
 x18 = FO+2&lt;br /&gt;
&lt;br /&gt;
== Einstellungen für maximale Reichweite ==&lt;br /&gt;
&lt;br /&gt;
Für eine maximale Reichweite eignen sich folgende Einstellungen:&lt;br /&gt;
* Bitrate: 2k - 10kbit/s.&lt;br /&gt;
* Receiver Baseband Bandwidth: 134kHz&lt;br /&gt;
* RSSI Threshold: -97dBm&lt;br /&gt;
* LNA gain: 0dB. Falls in der Gegend Störer im gleichen Frequenzbereich sind, dann -6dB, ansonsten kann die Eingangsstufe übersteuern.&lt;br /&gt;
* FSK frequency deviation: +/-90kHz&lt;br /&gt;
* Output Power: 0dB&lt;br /&gt;
&lt;br /&gt;
Und vor allem: Eine gute (Richt-) Antenne.&lt;br /&gt;
&lt;br /&gt;
== Quarzfrequenz ändern==&lt;br /&gt;
Im Datenblatt wird die Verwendung eines 10 MHz-Quarzes empfohlen. Man darf die Frequenz aber nach oben und unten variieren, wie Messungen mit einem DDS-Generators anstelle des Quarzes zeigen: [[Media:PLL-Rastbereich_log.pdf|PLL-Einrast-Tabelle]]. Eine [[Media:RFM12Quarz.pdf|Tabelle: Quarzfrequenzen von 8,5-11 MHz]] zeigt die damit erreichbaren Frequenzen. Quarze für 3. oder auch 5.Oberton sollten auch auf ihrer Grundfrequenz verwendbar sein, dafür bieten sich u.a. CB-Funk- und 10m-Amateurbandquarze an. &lt;br /&gt;
&lt;br /&gt;
Den Einfluß der vier unteren Bits im Configuration Setting Register und des mp-Bits (Modulations-Polarität?) auf die PLL-Frequenz zeigt diese [[Media:Varicap_RFM12.pdf|Kapazitäts-Tabelle]]. Pro Stufe sind es hier etwa 4 kHz, das kann je nach Quarz schwanken. Möglicherweise ist so auch Schmalband-FSK möglich, ohne Änderung des PLL-Teilers.&lt;br /&gt;
&lt;br /&gt;
Was können wir damit anfangen? Neben dem regulären Einsatz auf den beiden zugelassenen Bändern 433 und 868 MHz sind das unter anderem (bitte weitere Ideen einfügen):&lt;br /&gt;
&lt;br /&gt;
* Packet-Radio mit 9600 Baud im 70cm-Amateurband 430-440 MHz. Die einfachste Möglichkeit ist das Programm [http://www.baycom.org/~tom/ham/soundmodem/ Soundmodem], das für Windows und Linux existiert. Wer es komfortabler haben will findet [http://www.dj4uf.de/funktechnik/soundmodem/soundmodem.htm hier] eine Beschreibung wie Soundmodem mit den Programmen [http://www.flexnet.info/ Flexnet] und [http://www.paxon.de Paxon] zusammenarbeitet. Eine Karte der Packet-Radio-Digipeater im 70cm-Band kann man mittels [http://www.hammap.de Hammap] erstellen. Leider werden die Daten in den letzten Jahren nicht mehr sehr gepflegt, es dürften einige Karteileichen enthalten sein.&lt;br /&gt;
&lt;br /&gt;
* Empfang der [http://www.adacom.org/projekte/funkruf/ POCSAG-Funkrufsender] am oberen Ende des Amateurbandes auf  439,9875 MHz 2-FSK mit 4kHz Hub und 1200 bit/s im POCSAG Radio Paging Code 1 [http://home.arcor.de/norbert_n/samsfaq/sams.txt (Liste der Sender, Stand 18.09.07)]. Zur Decodierung existieren mehrere Programme, aufbauend auf [http://www.baycom.org/~tom/ham/linux/multimon.html Multimon] die Weiterentwicklungen [http://www.monitor.mgrohmann.de/ Monitor] und [http://monitord.de/ MonitorD]. Im Prinzip könnte man damit auch die verschlüsselten Wettermeldungen auf 466,23 MHz mitschreiben, aber nicht decodieren.&lt;br /&gt;
&lt;br /&gt;
* Empfang der [http://www.darc.de/vus/digital.html D-Star-Relais]. Das ist eine patentierte digitale Sprach- und Datenübertragung, deren Eigentümer dafür sorgt, dass kein käufliches oder Selbstbaufunkgerät ohne den &amp;quot;AMBE&amp;quot;-Modemchip D-Star senden und empfangen darf. Es gibt eine kleine Ausnahme, das [http://www.darc.de/vus/down/dstar_decode_v02a.zip Programm r00t&#039;s D-Star Decoder V0.2a] für die Soundkarte, das nur Rufzeichen und Datentelegramme der beteiligten Funkamateure darstellt.&lt;br /&gt;
&lt;br /&gt;
* Panoramaempfänger (die Bezeichnung Spektrumanalysator wäre etwas übertrieben) unter Verwendung des analogen RSSI Ausgangs (Anschluß am Kondensator in der Ecke). Damit ließe sich z.&amp;amp;nbsp;B. auch die Bandbelegung im PMR-Bereich 446,0-446,2 MHz oder im Mobilfunkband um 900 MHz anzeigen.&lt;br /&gt;
&lt;br /&gt;
* Pegelanzeige für Mobilfunksender. Im 900 MHz Mobilfunkbereich könnte man mit dem RSSI-Ausgang die umliegenden Funkmasten anpeilen und ihre Pegel anzeigen. Laut Datenblatt nur ein Anzeigeumfang von 35 dB, aber mit umschaltbarem Grundpegel.&lt;br /&gt;
&lt;br /&gt;
* In Verbindung mit einem Frequenzumsetzer lassen sich weitere Frequenzbereiche erschließen, z.&amp;amp;nbsp;B. Packet-Radio im 23cm- (1240-1200 MHz)  und 13cm- (2320-2450 MHz) Amateurband. Leider liegt die Zwischenfrequenz der Satellitentuner (479,5 MHz) schon am oberen Ende des PLL-VCO-Einrastbereiches. Damit wäre ein preiswerter Konverter für 23cm möglich, meistens schon mit I2C-Bus PLL.&lt;br /&gt;
&lt;br /&gt;
* Local Oscillator für einen Empfänger. Mir den ca. 5 Milliwatt des RFM12 läßt sich ein [http://www.mini-circuits.com/products/fm_sm_main.html passiver Diodenringmischer] ansteuern. Damit kann man einen Überlagerungsempfänger oder -sender mit hoher erster Zwischenfrequenz bauen.&lt;br /&gt;
&lt;br /&gt;
== Antennen-Anpaßnetzwerk==&lt;br /&gt;
[[Image:Antennenanpassung.png|thumb|right|400px|Antennen-Anpassnetzwerk im Datenblatt]]&lt;br /&gt;
Soll das RFM12 auf anderen Frequenzen betrieben werden, ist nur eine Änderung des Antennennetzwerks nötig. Das Datenblatt bietet knappe aber ausreichende Informationen.  &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zwischen Pin 12 und 13 liegt eine Spannungsquelle, die ihre maximale Sendeleistung in eine komplexe Last nach der Tabelle &amp;quot;Note4&amp;quot; abgibt. Das bedeutet, ihr Innenwiderstand ist konjugiert-komplex zu dieser Last, also dieselben Zahlenwerte, nur mit Minuszeichen vor dem &amp;quot;j&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Anpassnetzwerk läßt sich auf zwei Bauteile reduzieren: von der Antenne ausgehend, die als reeller 50 Ohm- Widerstand angenommen wird, ist ein Kondensator in Reihe geschaltet. C8 und C9 (in der Tabelle C9 und C10 bezeichnet) liegen in Reihe und sind gleich groß, dürfen also in einem Kondensator mit der halben Kapazität zusammengefasst werden. Dann liegt noch L1 parallel zur Quelle, L3 hat mehr als den 20-fachen Wert und kann vernachlässigt werden.&lt;br /&gt;
Das ganze läßt sich im Smith-Diagramm gut darstellen.&lt;br /&gt;
&lt;br /&gt;
[[Image:SmithDiagramm.png|thumb|right|400px|Anpassnetzwerk im Smith-Diagramm]]&lt;br /&gt;
&lt;br /&gt;
Von der Antenne im Mittelpunkt ausgehend bewegen wir uns mit dem Serien-C Cs auf einem Kreisbogen nach unten (kapazitive Halbebene) auf den Punkt &amp;quot;Unendlich&amp;quot; rechts außen zu. Ungefähr senkrecht unter dem Zielpunkt, hier für 433 MHz gezeichnet, biegen wir ab auf eine Kreisbahn für die Parallelinduktivität Lp. Sie führt in die obere (induktive) Halbebene auf den Nullpunkt links zu. Der genaue Schnittpunkt beider Kreise kann &amp;quot;mit Zirkel und Lineal&amp;quot; oder einem der [http://www.mikrocontroller.net/articles/Schaltungssimulation#Hochfrequenztechnik Hochfrequenz-Berechnungsprogramme] ermittelt werden.&lt;br /&gt;
&lt;br /&gt;
Die Kreise für Lp oder Cp sind im Smith-Diagramm nicht eingezeichnet , um die Übersicht zu wahren. Man könnte ein gespiegeltes Diagramm darüberlegen, aber stattdessen spiegelt man die Kurve am Diagramm-Mittelpunkt (dünne blaue Kurven). Am Rand kann man jetzt die auf 50 Ohm (bzw. 1/50Ohm für die gespiegelte Kurve) normierten Blindwiderstände ablesen. Für Cs lesen wir eine Differenz zwischen Start und Zielpunkt von etwa Xc=(3,2-0) * 50 Ohm ab, für Lp sind es (0,25 +0,32) = 0,57*(1/50 Ohm). Damit erhalten wir Cs=1/(2*Pi*f*Xc)=2,3 pF das war wie gesagt die halbe Kapazität der beiden hintereinandergeschalteten Kondensatoren, Tabellenwert ist 4,7pF und Lp=1/(2*Pi*f*0,57*(1/50))= 32,2 nH, der Tabellenwert ist 27nH.&lt;br /&gt;
&lt;br /&gt;
[[Image:Antennenanpassung_RF12.png|thumb|right|400px|Anpassnetzwerk im Datenblatt zu RF12]]&lt;br /&gt;
[[Image:Smith-Diagramm-RF12.png|thumb|right|400px|Smith-Diagramm zum RF12]]&lt;br /&gt;
Im RF12 wird ein um zwei Bauteile (im Bild C2 und L1 genannt) erweitertes Netzwerk empfohlen, das macht man um eine breitbandigere Anpassung zu erreichen.&lt;br /&gt;
&lt;br /&gt;
== Betriebsspannung==&lt;br /&gt;
Achtung nicht alle Module sind für 5V geeignet, alle Typen mit &amp;quot;B&amp;quot; am Ende sind nur für 3,3V. Man muß dann entweder den Mikrocontroller ebenfalls mit 3,3V betreiben, oder [http://www.mikrocontroller.net/articles/Pegelwandler Pegelwandler] verwenden.&lt;br /&gt;
&lt;br /&gt;
== Messungen ==&lt;br /&gt;
Drei Messungen am RFM12 zeigen den Einfluß von Eingangpegel, Frequenzhub und Mittenfrequenz auf das Ausgangssignal, gemessen am Filterkondensator CFIL. Zwei weitere Kurven zeigen die ARSSI-Spannung (Anschluß am Kondensator in der Ecke) und die damit gemessene Filterkurve.&lt;br /&gt;
[[Image:RFM12_Eingangspegel.png|thumb|right|800px|Messungen am RFM12 Änderung des Eingangspegels]]&lt;br /&gt;
[[Image:RFM12_Frequenzhub.png|thumb|right|800px|Messungen am RFM12 Änderung des Frequenzhubs]]&lt;br /&gt;
[[Image:RFM12_Mittenfrequenz.png|thumb|right|800px|Messungen am RFM12 Änderung der Mittenfrequenz]]&lt;br /&gt;
[[Image:RFM12_ARSSI_und_Filterkurve.png|thumb|right|200px|Messungen am RFM12 ARSSI_und_Filterkurve]]&lt;br /&gt;
&lt;br /&gt;
Was folgt aus diesen Messungen?&lt;br /&gt;
* Der ARRSI-Anschluß zeigt uns über mehr als 100 kHz ein Sendesignal an. Decodierbar ist es aber nur im Abstand von weniger als 5 kHz von der Mittenfrequenz. Ohne Abgleich von Sender und Empfänger ist also die AFC unverzichtbar.&lt;br /&gt;
* Das &amp;quot;Loch&amp;quot; in der Mitte der Durchlaßkurve stammt von dem im Datenblatt gezeigten Hochpass &amp;quot;&amp;gt; 7 kHz&amp;quot;. Für ein unmoduliertes Sendesignal geht die ARSSI-Spannung fast auf den Rauschpegel herunter, hier wurde mit +/-15kHz moduliert. &lt;br /&gt;
* Damit läßt sich der Empfänger abgleichen. Man braucht dazu nur ein unmoduliertes Sendesignal auf der Sollfrequenz. Das kann ein mittels Frequenzzähler abgeglichenes zweites RFM12 sein. Der Empfängerquarz wird mit den 4 Bit für die Oszillatorkapazität genau auf dieses &amp;quot;Loch&amp;quot; der ARRSI-Spannung eingestellt.&lt;br /&gt;
&lt;br /&gt;
Die AFC-Messdauer ist im Datenblatt nicht genannt, eine schnelle Abfrage des ATGL-Bit im Statusregister im &amp;quot;Auto-AFC&amp;quot; - Modus liefert minimale Pulsbreiten von ca. 250..270 µsec, entsprechend einer Messfolgefrequenz von 4 kHz - leider nicht ausreichend um 9600 Baud Schmalband-FM zu demodulieren. Im Auto-Modus werden zwei Messungen zusammengefasst, damit beträgt die Updaterate sogar nur 2 kHz. Weitere Messung : ab etwa +/-10 kHz Hub synchronisiert sich das ATGL-Bit auf der Mittenfrequenz mit einem bis zu 1,8...2 kHz FM-modulierten Signal.&lt;br /&gt;
&lt;br /&gt;
Neue Idee: &amp;quot;Dithering und FM-Flankendemodulator&amp;quot;: &amp;lt;br&amp;gt; &lt;br /&gt;
Wenn das Empfangssignal nicht weit genug FM-moduliert ist, müssen wir eben den Empfänger modulieren. Im Timer-Interrupt wird die Quarzkapazität oder die PLL z.&amp;amp;nbsp;B. mit 38,4 oder 76,8 kHz und mindestens +/-15kHz Hub umgeschaltet, sodaß bei Empfang eines unmodulierten Signals am CFIL-Ausgang ein symmetrisches Rechteck dieser Frequenz erscheint. Ist das Empfangssignal schmalbandig FM-moduliert, und man stimmt den Empfänger leicht daneben ab, so sollte das CFIL-Signal mit dieser Modulation PWM-moduliert sein. Ein Tiefpass filtert die Dithering-Frequenz weg und übrig bleibt (wenns funktioniert) die Modulation, vielleicht sogar analoger Sprechfunk...&lt;br /&gt;
Motto &amp;quot;Engineering is the art of making what you want from things you can get.&amp;quot; (von http://www.dsprelated.com)&lt;br /&gt;
&lt;br /&gt;
== Bezugsquellen ==&lt;br /&gt;
* [[Elektronikversender#csd-electronics|csd-electronics]]&lt;br /&gt;
* [[Elektronikversender#IT-WNS|IT-WNS]]&lt;br /&gt;
* [[Elektronikversender#Pollin_Electronic|Pollin Electronic]]&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
* [[AVR RFM12]]&lt;br /&gt;
* [[RFM12 Protokoll Stack]]&lt;br /&gt;
* [[RF_SOAP]]&lt;br /&gt;
* [[ Pollin_Funk-AVR-Evaluationsboard]]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/93801 Bezugsquellen]&lt;br /&gt;
* [http://www.das-labor.org/storage/LaborLib/rfm12/ Library zur Ansteuerung des RFM12]&lt;br /&gt;
* [http://www.compotron.com/daten/any/IA4420.pdf Datenblatt des Chipherstellers Integration IA4420.pdf]&lt;br /&gt;
* [https://www.silabs.com/Support%20Documents/TechnicalDocs/Si4420.pdf Silabs hat Integration im Juni 2008 gekauft, Chipbezeichnung jetzt Si4420]&lt;br /&gt;
Folgende Links sind mit Vorsicht zu genießen, da die Datenblätter teilweise  fehlerbehaftet sind. Es empfiehlt sich, direkt mit dem Datenblatt des RF12 (das ist das IC auf dem Modul) zu arbeiten. Dieses ist so gut wie fehlerfrei.&lt;br /&gt;
&lt;br /&gt;
* [http://www.hoperf.com/upload/rf/RF12.pdf Datenblatt des ICs RF12] (PDF)&lt;br /&gt;
* [http://www.hoperf.com/upload/rf/RFM12.pdf Datenblatt des Moduls RFM12] (PDF)&lt;br /&gt;
* [http://www.hoperf.com/upload/rf/RF12_code.pdf Programming Guide] (PDF)&lt;br /&gt;
* [http://www.hoperf.com/upload/rf/RF12TOOLS.pdf Demo Kit User Manual] (PDF)&lt;br /&gt;
* [http://www.pollin.de/shop/downloads/D810047S.ZIP Beispielprogramm von Pollin] (ZIP)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Bauteile]]&lt;br /&gt;
[[Kategorie:Funk]]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=AVR_RFM12&amp;diff=59068</id>
		<title>AVR RFM12</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=AVR_RFM12&amp;diff=59068"/>
		<updated>2011-07-30T10:54:23Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: Aktuelle Version von Jeenode&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Schaltungen und Software für AVR und das Funkmodul [[RFM12]].&lt;br /&gt;
&lt;br /&gt;
== SVN ==&lt;br /&gt;
&lt;br /&gt;
svn://mikrocontroller.net/rfm12 (siehe auch: http://www.mikrocontroller.net/svn/list)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Software ==&lt;br /&gt;
&lt;br /&gt;
=== Treiber ===&lt;br /&gt;
&lt;br /&gt;
[http://www.mikrocontroller.net/attachment/22473/rfm12_pc.zip Firmware v1.0.0] von Benedikt K.&lt;br /&gt;
&lt;br /&gt;
[http://www.mikrocontroller.net/attachment/23542/RMxx_Driver.tar.bz2 Firmware v2.0.1] von Jürgen Eckert&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot;&lt;br /&gt;
|+ Funktionalität&lt;br /&gt;
|-&lt;br /&gt;
!  || Beschreibung || Software&lt;br /&gt;
|-&lt;br /&gt;
!1. Stufe:&lt;br /&gt;
| Die Daten von der seriellen Schnittstelle werden über die Funkstrecke auf die serielle Schnittstelle der anderen Seite übertragen. (Wir freuen uns über jedes Byte das ankommt)&lt;br /&gt;
| [http://www.mikrocontroller.net/topic/67273#564945 Claude Schwarz], [http://www.mikrocontroller.net/topic/71682#584915 Benedikt K.] oder [http://www.mikrocontroller.net/attachment/36742/RFM12_V3.zip Manuel Stahl]&lt;br /&gt;
|-&lt;br /&gt;
! 2. Stufe:&lt;br /&gt;
| Es findet eine Fehlererkennung (z.&amp;amp;nbsp;B. mit CRC-Summen) statt. Fehlerhafte Daten werden erneut angefordert. Dadurch gehen auf der Funkstrecke keine Daten verloren und es werden keine Daten verfälscht.&lt;br /&gt;
| [http://www.mikrocontroller.net/topic/71682#585851 Benedikt K.]&lt;br /&gt;
|-&lt;br /&gt;
! 3. Stufe:&lt;br /&gt;
| Die Datenübertragung wird individualisiert. Dadurch können zwei Funkstrecken, die im gleichen Empfangsbereich liegen nebeneinander arbeiten, ohne sich zu beeinträchtigen.&lt;br /&gt;
| [[RFM12_Protokoll_Stack]]&lt;br /&gt;
|-&lt;br /&gt;
! 4. Stufe: &lt;br /&gt;
| Die Datenübertragung wird verschlüsselt und damit abhörsicher.&lt;br /&gt;
| [http://ethersex.de/index.php/OpenVPN ethersex OpenVPN]&lt;br /&gt;
|-&lt;br /&gt;
!5. Stufe:&lt;br /&gt;
| Neben den Daten der seriellen Schnittstelle werden auch Änderungen der Statusleitungen übertragen. Damit erhält man eine &amp;quot;RS232-Verlängerung&amp;quot; über eine Funkstrecke, die fehlerfrei arbeitet und zu einer Drahtverbindung weitestgehend kompatibel ist.&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== RS232 &amp;lt;-&amp;gt; RFM12 ===&lt;br /&gt;
&lt;br /&gt;
TODO&lt;br /&gt;
&lt;br /&gt;
=== USB &amp;lt;-&amp;gt; RFM12 ===&lt;br /&gt;
&lt;br /&gt;
Mit [http://www.obdev.at/vusb/ V-USB] lässt sich ein USB-Slave in Software emulieren.&lt;br /&gt;
&lt;br /&gt;
* [http://www.recursion.jp/avrcdc/ AVR-CDC] läuft mit Anpassung der USB-Pins. &#039;&#039;(Zumindest unter Windows an einem USB2.0-Port)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Adapter für [http://www.embedded-projects.net/?page_id=135 USBprog]:&lt;br /&gt;
&lt;br /&gt;
* Funktionierender Code liegt im oben genannten SVN&lt;br /&gt;
* Implementiert die USB-CDC-Klasse (kein Treiber nötig)&lt;br /&gt;
* Sicherung der Übertragung durch Hamming-Code&lt;br /&gt;
* Work in progress... (Manuel Stahl)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Alternative rfm12lib ===&lt;br /&gt;
rfm12lib von das-labor.org&lt;br /&gt;
&lt;br /&gt;
==== Features ====&lt;br /&gt;
* Ein einfaches Paketformat, bestehend aus:&lt;br /&gt;
** Einem 8-bit (0..255) Pakettyp- oder Adress-feld&lt;br /&gt;
** Paketlänge bis zu 255 Bytes&lt;br /&gt;
** Eine simple Header Checksumme&lt;br /&gt;
* Interrupt oder Polling basierte Datenübertragung&lt;br /&gt;
* Verschiedene Frequenzbänder, abhängig von dem verwendeten Modul (433, 868 und 915 MHz)&lt;br /&gt;
* Collision avoidance (carrier sense)&lt;br /&gt;
* Synchronisierungsfunktion beim Datenempfang&lt;br /&gt;
* Hardware oder software SPI&lt;br /&gt;
* Nur-Sende-Modus, zum verkleinern der binaries&lt;br /&gt;
* Grundlegende ASK (amplitude shift keying) empfangs und sende Funktionalität (Für Funksteckdosen aus dem Baumarkt und ähnlichem)&lt;br /&gt;
* Low-battery detector (funktion des RFM12)&lt;br /&gt;
* Low-power Wakeup timer (funktion des RFM12)&lt;br /&gt;
&lt;br /&gt;
==== Download ====&lt;br /&gt;
* [http://www.das-labor.org/wiki/RFM12_library Projektseite]&lt;br /&gt;
* [http://www.das-labor.org/LaborLibTrac/browser/rfm12 Code im SVN]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
=== Alternative myrfm12 ===&lt;br /&gt;
&lt;br /&gt;
ACHTUNG: Links führen auf Phishing Seite!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
myrfm12 von mydani&lt;br /&gt;
&lt;br /&gt;
Download:&lt;br /&gt;
http://www. mydani. com/dl/myrfm12/&lt;br /&gt;
&lt;br /&gt;
Dokumentation:&lt;br /&gt;
http://www. mydani. com/dl/myrfm12/help&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
&lt;br /&gt;
=== Basismodul V1.0 ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Prozessor&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
ATmega8 TQFP32 (kompatibel ATmega48, ATmega88, ATmega168)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Schnittstellen&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* RS232&lt;br /&gt;
* I²C:&lt;br /&gt;
* USB&lt;br /&gt;
* GPIO&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Platine&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Bild:AVR RFM12 Schematic.png|200px|ATmega48 + USB]]&lt;br /&gt;
[[Bild:AVR RFM12 Board TOP.png|220px|2-lagig top]]&lt;br /&gt;
[[Bild:AVR RFM12 Board BOTTOM.png|240px|2-lagig bottom]]&lt;br /&gt;
[[Bild:AVR_RFM12_Photo.jpg|240px|Photo]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;float:left; border-right:1px solid gray; padding-right:10px;&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Bauteile:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Größe: SMD 0603&lt;br /&gt;
&lt;br /&gt;
* R1, R2: 68R (nur USB)&lt;br /&gt;
* R3, R4: 10k&lt;br /&gt;
* R5: 1k5 (nur USB)&lt;br /&gt;
* C1, C2: 22pF&lt;br /&gt;
* C3 - C9: 100nF&lt;br /&gt;
* Q1: 12Mhz (nur USB)&lt;br /&gt;
* D1, D2: beliebig, Minimelf&lt;br /&gt;
* IC3: MAX3221CUE&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;float:left; border-right:1px solid gray; padding: 0px 0px 10px 10px; width:33%&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Kosten:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* MiniUSB SMD: &#039;&#039;&#039;1,25€&#039;&#039;&#039;&lt;br /&gt;
* HF-Buchse MMCX: &#039;&#039;&#039;4,25€&#039;&#039;&#039;&lt;br /&gt;
* ATmega48: &#039;&#039;&#039;2,85€&#039;&#039;&#039;&lt;br /&gt;
* MAX3221CUE: &#039;&#039;&#039;1,10€&#039;&#039;&#039;&lt;br /&gt;
* Quarz 12Mhz 30ppm: &#039;&#039;&#039;1,19€&#039;&#039;&#039;&lt;br /&gt;
* Kleinkram: &#039;&#039;&#039;&amp;lt; 1,10€&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* habe ein verbindliches Angebot für 24 Stück von http://mme-pcb.de/: &#039;&#039;&#039;4,00€ pro Platine&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;float:left; padding: 0px 0px 10px 10px; width:33%&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039; Bugs / Erweiterungen:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Der 1,5k Widerstand muss direkt an den VCC-Pin angelötet werden (Pad ist nicht verbunden)&lt;br /&gt;
* Beim Fertigen wurde das Polygon, welches das VCC-Signal durch die eine Ecke des ATmega48 leitet, unterbrochen. Hier hilft nur eine Drahtbrücke.&lt;br /&gt;
* Unter den RFM12 und unter den Quarz am Besten Isolierband kleben!&lt;br /&gt;
* Beim Programmieren sollte der SEL des RFM12 (J1 der zweite Pin vom RS232 aus) auf VCC gelegt werden&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[http://www.mikrocontroller.net/attachment/24012/RFM12.brd Board (Eagle)]:&lt;br /&gt;
&lt;br /&gt;
[[Bild:AVR RFM12 Board top bestuecken.png|200px|top]]&lt;br /&gt;
[[Bild:Board bottom bestuecken.png|200px|bottom]]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Flashcraft Funkboard ===&lt;br /&gt;
&lt;br /&gt;
[http://flashcraft.de/index.php/funkboard-uebersicht Homepage des Projekts]&lt;br /&gt;
&lt;br /&gt;
Eine andere Funklösung mit dem RFM12 bietet das &#039;&#039;&#039;Open Source&#039;&#039;&#039; Flashcraft Funkboard von Florian Scherb.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Flashcraft_funkboard_pic.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Das Projekt enthält&#039;&#039;&#039;&lt;br /&gt;
* Funkboard Platine&lt;br /&gt;
* Code für AVR&lt;br /&gt;
* PC Terminalprogramm&lt;br /&gt;
* Dokumentation&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Überblick:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
# Über 60 Seiten starke Dokumentation&lt;br /&gt;
# PC Terminalprogramm zum Testen und Konfigurieren&lt;br /&gt;
# Abmessungen: 32x34mm, Montage durch 2 Stiftleisten im 2,54mm Raster&lt;br /&gt;
# ATmega32 übernimmt komplette Ansteuerung&lt;br /&gt;
# 3 Schnittstellen sind vorgesehen: I2C, SPI, UART (derzeit nur UART)&lt;br /&gt;
# SMA-Antennenanschluss&lt;br /&gt;
# Stromaufnahme: 40mA im normalen Betrieb, 2 Schlafmodi mit Stromverbrauch bis min. 25µA!&lt;br /&gt;
# Betriebsspannungsbereich von 3,2 - 5,4V (mit ATmega32L)&lt;br /&gt;
# 5V oder 3V Spannungsregler onBoard! Direkter Batteriebetrieb möglich; Kann externe Schaltung versorgen! &lt;br /&gt;
# uvm.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Außerdem:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
# Unterstützt Funknetzwerk mit bis zu 125 Modulen!&lt;br /&gt;
# Kontrolle über fast alle Konfigurationen, direkt im Betrieb änderbar, kein Umprogrammieren notwendig!&lt;br /&gt;
# Zahlreiche Sicherheitsfeatures wie Acknowledge, CRCs,...&lt;br /&gt;
# RS232-Treiberbaustein MAX3221 onBoard. Damit TTL- und RS232-UART möglich&lt;br /&gt;
# Clock Takt am Funkboard abgreifbar, z.&amp;amp;nbsp;B. für externen Mikrocontroller&lt;br /&gt;
# Totzeiten ca. 1,5 Millisekunden beim Wechsel zwischen Sende- und Empfangsbetrieb&lt;br /&gt;
# uvm. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Schaltpläne, Board-Layout, Sourcecodes und andere Files sind auf der [http://flashcraft.de/index.php/funkboard-uebersicht Homepage] des Funkboard-Projekts verfügbar. Diskussionen zum Projekt gibt es im [http://www.mikrocontroller.net/topic/115542 Forums-Thread]&#039;&#039;&#039;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== USBprogRFM12 ===&lt;br /&gt;
&lt;br /&gt;
Da der USBprog genau das SPI-Interface des ATmega32 zur Verfügung stellt, eignet er sich perfekt als USB-RFM12-Adapter.&lt;br /&gt;
&lt;br /&gt;
[[Bild:USBprogRFM12_schematic.png|200px|USBprogRFM12]] [[Bild:USBprogRFM12_board.png|200px|USBprogRFM12]]&lt;br /&gt;
&lt;br /&gt;
[[Bild:USBprogRFM12.jpg|400px|USBprogRFM12]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
=== RF SOAP ===&lt;br /&gt;
&lt;br /&gt;
→ &#039;&#039;Hauptartikel: [[RF SOAP]]&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Kompakte Leiterplatte mit RFM12, ATmega88, FT232 für USB und LiPo Akku&lt;br /&gt;
&lt;br /&gt;
[[Bild:RealSoap.jpg|200px]]&lt;br /&gt;
[[Bild:PovTop.jpg|200px]]&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/65984 Allgemeine Diskussion]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/71682  bidirektionale RS232 Funkbrücke mit RFM12]&lt;br /&gt;
* [http://www.das-labor.org/wiki/Datenfunk_mit_dem_AVR Datenfunk mit dem AVR] bei das-labor.org&lt;br /&gt;
* [http://jeelabs.net/projects/hardware/wiki/JeeNode JeeNode]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:AVR-Projekte]]&lt;br /&gt;
[[Kategorie:Funk]]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=AVR-GCC-Codeoptimierung&amp;diff=58845</id>
		<title>AVR-GCC-Codeoptimierung</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=AVR-GCC-Codeoptimierung&amp;diff=58845"/>
		<updated>2011-07-23T18:48:13Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: kleinere Schreibfehler korrigiert&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Entstanden aus diesem [http://www.mikrocontroller.net/topic/66690 Thread] sollen hier ein paar Hinweise/Erfahrungen gegeben werden, um den Quellcode in Punkto Größe und Geschwindigkeit zu optimieren. &#039;&#039;En detail&#039;&#039; ist das Thema komplex, da es stark von der Codeoptimierung des Compilers abhängt. Es ist im Einzelfall ratsam zu prüfen, ob die eigenen Maßnahmen auch erfolgreich waren. Die Diskussionen [http://www.mikrocontroller.net/topic/132624] bzw. [http://www.mikrocontroller.net/topic/180800#new] können als Anhaltspunkte dienen, wie eine solche Prüfung ablaufen kann.&lt;br /&gt;
&lt;br /&gt;
== Prinzipien der Optimierung ==&lt;br /&gt;
&lt;br /&gt;
Wie so oft sollte man nicht einfach wild drauf los optimieren und sich zunächst ein paar Dinge klar machen.&lt;br /&gt;
&lt;br /&gt;
* Warum will ich optimieren?&lt;br /&gt;
* Was kann man sinnvoll optimieren?&lt;br /&gt;
* Wieviel Rechenzeit oder Speicher soll dabei gespart werden?&lt;br /&gt;
* Wie kann optimiert werden?&lt;br /&gt;
* &amp;quot;Verfrühte Optimierung ist die Wurzel allen Übels&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Viele Optimierungen sind &amp;quot;Angst-Optimierungen&amp;quot;, die nicht wirklich nötig sind. Die Gefahr mit Optimierungen ist, den Code tot zu optimieren, sprich Lesbarkeit, Portierbarkeit und ggf. Fehlerfreiheit sinken massgeblich. Kurz und knapp in diesem [http://blogs.msdn.com/b/audiofool/archive/2007/06/14/the-rules-of-code-optimization.aspx BLOG] formuliert.&lt;br /&gt;
&lt;br /&gt;
=== Warum ===&lt;br /&gt;
&lt;br /&gt;
Optimieren sollte man nur, wenn&lt;br /&gt;
* der Speicher nicht mehr ausreicht (RAM, Flash)&lt;br /&gt;
* Die Laufzeit für bestimmte Programmteile zu groß wird und somit bestimmte (Echtzeit-)Ausgaben nicht im erforderlichen Zeitrahmen erledigt werden&lt;br /&gt;
&lt;br /&gt;
Weiter sollte man folgende Punkte gegeneinander abwägen:&lt;br /&gt;
&lt;br /&gt;
* Codeverbrauch&lt;br /&gt;
* Datenverbrauch. Statisch/Stack/Heap&lt;br /&gt;
* Mittlere Laufzeit/maximale Laufzeit&lt;br /&gt;
* Entwicklungszeit&lt;br /&gt;
* Portabilität (Compiler, Hardware, ...)&lt;br /&gt;
* Verständlichkeit der Quelle, siehe [[Strukturierte Programmierung auf Mikrocontrollern]] &lt;br /&gt;
* ABI-Konformität&lt;br /&gt;
&lt;br /&gt;
=== Was ===&lt;br /&gt;
&lt;br /&gt;
Die goldene Regle lautet: 90% der Rechenleistung werden in 10% des Codes verbraucht. Diese 10% muss man finden und zum richtigen Zeitpunkt optimieren. Der Rest muss nur sauber und lesbar geschrieben sein. Was jedoch nichts bringt, ist eine Funktion, die von 1 Minute Programmlaufzeit lediglich 1 Sekunde verbraucht, um den Faktor 10 schneller zu machen. Die Programmlaufzeit sinkt dann von 60 Sekunden auf 59.1 Sekunden. Der Aufwand, die Funktion um einen Faktor 10 schneller zu machen ist aber meistens beträchtlich!  Kann ich aber den Code, der für die 59 Sekunden verantwortlich ist um einen Faktor 10 schneller machen, dann sinkt die Gesamtlaufzeit von 60 Sekunden auf 6.9 Sekunden. Dort bringt Optimieren augenscheinlich viel mehr!&lt;br /&gt;
&lt;br /&gt;
Um die optimierungswürdigen Stellen zu finden, muss man sein Programm analysieren. Dazu gibt es verschiedene Möglichkeiten.&lt;br /&gt;
&lt;br /&gt;
====Speicherverbrauch nach Funktionen aufschlüsseln====&lt;br /&gt;
&lt;br /&gt;
;map-File:&lt;br /&gt;
:dort sind alle globalen und statischen Variablen enthalten. Eine Map-Datei kann mit den GNU-Tools während des Linkens angelegt werden:&lt;br /&gt;
::&amp;lt;pre&amp;gt;&amp;amp;gt; avr-gcc ... -Wl,-Map,foo.map&amp;lt;/pre&amp;gt;&lt;br /&gt;
: Die Option -Wl bewirkt, daß avr-gcc die angehängen Optionen unverändert an den Linker weiterreicht. Dieser erzeugt dann das Mapfile &amp;quot;foo.map&amp;quot;, eine Textdatei.&lt;br /&gt;
;avr-size: Mit Tools wie avr-size kann die Platzbelegung einzelner Module ermittelt werden:&lt;br /&gt;
::&amp;lt;pre&amp;gt;&amp;amp;gt; avr-size -x foo1.o foo2.o ...&amp;lt;/pre&amp;gt;&lt;br /&gt;
:bzw. die Platzbelegung der elf-Datei:&lt;br /&gt;
::&amp;lt;pre&amp;gt;&amp;amp;gt; avr-size -C --mcu=atmega8 foo.elf&amp;lt;/pre&amp;gt;&lt;br /&gt;
;avr-nm:&lt;br /&gt;
::&amp;lt;pre&amp;gt;&amp;amp;gt; avr-nm --size-sort -S foo.elf&amp;lt;/pre&amp;gt;&lt;br /&gt;
:ergibt eine Liste mit der Größe aller Objekte: der erste Spalte enthälte die Adresse, die zweite Spalte die Größe, die dritte den Typ und die vierte Spalte den zugehörigen Symbolnamen. Der Typ ergibt sich aus der folgenden Zuordnung, wobei Großbuchstaben globale Symbole kennzeichnen und Kleinbuchstaben Symbole, die Modul-lokal sind:&lt;br /&gt;
:;T/t: Objekte in der text-Section: Funktionen, Daten im Flash&lt;br /&gt;
:;D/d: Objekte im data-Segment (initialisierte Daten)&lt;br /&gt;
:;B/b: Objekte im bss-Segment (Null-initialisierte Daten)&lt;br /&gt;
&lt;br /&gt;
;avr-gcc: Der Compiler hat bereits Informationen über die übersetzten Funktionen, die man direkt zur Analyse verwenden kann. Dazu lässt man avr-gcc die Assembler-Ausgabe, die ohne weiteres Zutun nur als temporäre Datei angelegt wird, abspeichern. Etwa für die Quelldatei foo.c:&lt;br /&gt;
::&amp;lt;pre&amp;gt;&amp;amp;gt; avr-gcc -save-temps foo.c -c ...&amp;lt;/pre&amp;gt;&lt;br /&gt;
:Die Assembler-Datei wird damit als foo.s angelegt und nicht gelöscht. (Das ebenfalls angelegte Präcompilat foo.i wird nicht benötigt). Für jede Funktion gibt avr-gcc 3.4.x im Prolog einen Kommentar der Form&amp;lt;ref&amp;gt;Für avr-gcc 4.x sehen die Kommentare anders aus oder fehlen je nach Compilerversion ganz&amp;lt;/ref&amp;gt;&lt;br /&gt;
::&amp;lt;pre&amp;gt;/* prologue: frame size=0 */&amp;lt;/pre&amp;gt;&lt;br /&gt;
:aus, was die Größe des aktuellen Frames angibt. Dies ist der Platz auf dem Stack, der für lokale Variablen benötigt wird. Am besten ist es, wenn die Frame-Size wie im Beispiel gleich 0 ist. Ansonsten sollte man versuchen, diese Größe auf Null zu bringen. Für Variablen, die nicht in Registern gehalten werden können, müssen Speicherzugriffe in den Stack erzeugt werden. Diese machen das Programm sowohl größer aus auch langsamer. Zudem reserviert avr-gcc bei solche Funktionen das Y-Register als Frame-Pointer; das Y-Register steht damit nicht mehr für lokale Variablen zur Verfügung was sich ebenfalls ungünstig auf die Codegüte auswirkt. Ein Grund für das Anlegen eines Frames können zu viele lokale Variablen sein (zB lokale Puffer/Arrays) oder lokale Variablen/Strukturen/Parameter mit ungünstigen Größen, etwa eine 3-Byte große Struktur. &lt;br /&gt;
&lt;br /&gt;
: Neben dieser Information gibt avr-gcc Kommentare der Gestalt&lt;br /&gt;
::&amp;lt;pre&amp;gt;/* prologue end (size=2) */&amp;lt;/pre&amp;gt;&lt;br /&gt;
:aus die darüber informieren, wie viele Register auf dem Stack gesichert wurden.&lt;br /&gt;
&lt;br /&gt;
: Zusammen mit Werkzeugen wie grep, die in jedem Linux und jeder WinAVR-Distribution enthalten sind, findet man schnell Übeltäter wie Funktionen mit Frame.&lt;br /&gt;
&lt;br /&gt;
;Assembler-Code sichten: Ein kurzer Blick auf den erzeugten Assembler-Code zeigt oft, wie gut der Compiler den Code umgesetzt hat. Den erzeugten Assembler-Code zu überfliegen ist wesentlich zeitsparender als selbst in Assembler zu programmieren. Je nach Gusto verwendet man zur Einsicht den Assembler-Code, den avr-gcc ausgibt (s.o.), Assembler-Dumps des Assemblers, List-Files oder HEX-Dumps. Siehe auch&amp;lt;ref&amp;gt;[http://rn-wissen.de/index.php/Assembler-Dump_erstellen_mit_avr-gcc roboternetz.de: Assembler-Dump erstellen mit avr-gcc]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Hilfsmittel: einkaufen oder selber bauen. Es gilt herauszufinden, welche Funktion massig Stack durch lokale Variablen verbraucht. Stacktracer können das. Wenn man keinen hat, dann muss man sich eben selber einen bauen, indem man den Stackpointer mitloggt. Zur Not einen Code-Review machen: Alle Funktionen optisch durchgehen und die identifizieren, die viele Variablen anlegen. Dann die Aufrufhierarchie der Funktion feststellen: Wirken sich die vielen Variablen überhaupt aus oder entsteht mein Problem durch eine tiefe Funktionsaufrufhierarchie, bei der zwar wenige Variablen pro Funktion im Spiel sind, aber die Menge der ineinandergeschachtelten Aufrufe &#039;das Kraut fett macht&#039;&lt;br /&gt;
;Profitools: können das alles fast auf Knopfdruck, kosten aber viel Geld&lt;br /&gt;
&lt;br /&gt;
====Laufzeit messen====&lt;br /&gt;
&lt;br /&gt;
*Simulator&lt;br /&gt;
*In Echtzeit mittels Testpin, welche an Anfang einer Funktion/Blocks gesetzt wird und am Ende wieder gelöscht wird. Mit einem [[Oszilloskop]] kann man so sehr einfach die Laufzeit messen.&lt;br /&gt;
&lt;br /&gt;
; Anmerkung: Solche Messverfahren liefern immer nur eine &#039;&#039;untere&#039;&#039; Schranke für die Laufzeit, niemals eine obere Schranke. Eine obere Schranke, wie man sie etwa in sicherheitsktitischen Systemen benötigt, liefert eine statische Codeanalyse.&lt;br /&gt;
&lt;br /&gt;
=== Wieviel ===&lt;br /&gt;
&lt;br /&gt;
Der Aufwand von Optimierungen wächst exponentiell. Die letzten paar Prozent brauchen überproportional viel Aufwand.&lt;br /&gt;
&lt;br /&gt;
=== Wie ===&lt;br /&gt;
&lt;br /&gt;
Meist muss man die Wahl treffen ob man Speicher oder Rechenzeit sparen will, beides gleichzeitg geht meist nicht. Das Konzept heißt &#039;Space for Time&#039; und kann in beide Richtungen verwendet werden. Als Beispiel soll eine komplizierte Berechnung dienen. Diese kann man relativ kompakt in eine Funktion packen, welche dann aber eher langsam ist. Oder man benutzt eine sehr große Tabelle, in welcher die Ergebnisse schon für jeden Eingangswert vorausberechnet wurden. Diese Lösung ist sehr schnell, verbraucht aber sehr viel Speicher.&lt;br /&gt;
&lt;br /&gt;
* Inlining von Funktionen erhöht den Speicherverbrauch, senkt aber die Laufzeit. Beispiel: Funktion A ist 50 Byte groß und wird 10 mal im Programm aufgerufen. Ein Aufruf kostet 10 Byte:&lt;br /&gt;
** Ohne Inline: 10 * 10Byte + 50 Byte = 150 Byte Platzverbrauch&lt;br /&gt;
** Mit Inline: 10 * 50 Byte = 500 Byte&lt;br /&gt;
* Optimierer einschalten&lt;br /&gt;
* möglichst keine Floating Point Operationen, besser ist meist [[Festkommaarithmetik]]&lt;br /&gt;
* Formeln umstellen und zusammenfassen&lt;br /&gt;
* Variablen so klein wie möglich, uint8_t wo&#039;s nur geht.&lt;br /&gt;
* Wirklich zeitkritische Funktionen und Interrupts als Assemblercode in separater Datei&lt;br /&gt;
&lt;br /&gt;
==Optimierung der Größe==&lt;br /&gt;
&lt;br /&gt;
===GCC-interne Optimierung===&lt;br /&gt;
&lt;br /&gt;
avr-gcc kennt mehrere Optimierungsstufen:&lt;br /&gt;
;&amp;lt;tt&amp;gt;-O0&amp;lt;/tt&amp;gt;: Keine Optimierung. Alle lokalen Variablen werden auf dem Stack angelegt und nicht in Registern gehalten. Es werden keine komplexen Optimierungsalgorithmen angewandt; lediglich Konstanten wie 1+2 werden zu 3 gefaltet. Diese Optimierungsstufe erzeugt zusammen mit Debug-Information Code, der sehr gut in einem Debugger nachvollzogen werden kann.&lt;br /&gt;
;&amp;lt;tt&amp;gt;-O1&amp;lt;/tt&amp;gt;: Je höher die Optimierungsstufe, desto schwieriger ist der erzeugte Code nachvollziehbar &amp;amp;mdash; auch mit Debugger. Diese O-Stufe ist ein Kompromiss zwischen agressiver Optimierung und Nachvollziehbarkeit des erzeugten Codes. Ein ehernes Gesetz in GCC ist, dass er den gleichen Code erzeugen muss unabhängig davon, ob Debug-Information erzeugt wird oder nicht. Im Umkehrschluss erlaubt volle Debug-Unterstützung nicht alle Optimierungen, wozu diese Optimierungsstufe dient.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-O2&amp;lt;/tt&amp;gt;: Optimierung auf Geschwindigkeit. Für AVR nur mässig sinnvoll, da sich der Codezuwachs nicht in einem entsprechenden Geschwindigkeitszuwachs transformiert. Dies liegt vor allem daran, daß Sprünge und Funktionsaufrufe auf AVR im Vergleich zu anderen Architekturen sehr billig sind. Es bringt also kaum einen Geschwindigkeitszuwachs, einen Block zu kopieren um einen Sprung zu sparen. Hingegen vergrößert dies den Code deutlich.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-O3&amp;lt;/tt&amp;gt;: Ditto. Auf Teufel-komm-raus Funktionen zu inlinen, Schleifen aufzurollen oder gar Funktionen mehrfach für unterschiedliche Aufruf-Szenarien zu implementieren, ist auf einem kleinen µC wie AVR der Overkill.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-Os&amp;lt;/tt&amp;gt;: Optimierung auf Codegröße. Die bevorzugte Optimierungsstufe für AVR und viele andere µC.&lt;br /&gt;
&lt;br /&gt;
Jede O-Option ist ein Sammlung von verschiedenen Schaltern, welche bestimmte Optimierungsstrategien aktivieren. Um zu sehen, welche Schalter dies genau sind, erzeugt man wie oben beschrieben mit den Schalten&lt;br /&gt;
   -fsave-temps -fverbose-asm&lt;br /&gt;
die Assembler-Ausgabe von gcc und schaut die Optionen im s-File nach. Einzelne Optionen lassen sich gezielt aktivieren bzw. deaktivieren und damit zum Beispiel zum &amp;lt;tt&amp;gt;-Os&amp;lt;/tt&amp;gt;-Paket hinzufügen. &lt;br /&gt;
&lt;br /&gt;
Eine Ausnahme bildet &amp;lt;tt&amp;gt;-O0&amp;lt;/tt&amp;gt;: Hier ist Code-Optimierung generell deaktiviert, und Optimierungsschalter bleiben ohne Wirkung. &amp;lt;tt&amp;gt;-O0&amp;lt;/tt&amp;gt; optimiert auf Resourcenverbrauch des &#039;&#039;Compilers&#039;&#039; und auf Nachvollziehbarkeit per Debug-Info (so diese erzeugt wird).&lt;br /&gt;
&lt;br /&gt;
Kandidaten dafür für Optimierungsoptionen sind folgende Schalter. &amp;lt;tt&amp;gt;-m&amp;lt;/tt&amp;gt; kennzeichnet maschinenspezifische Schalter, die nur für AVR gültig sind. &amp;lt;tt&amp;gt;-f&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;-fno-&amp;lt;/tt&amp;gt; sind maschinenunabhängige Schalter, die auch für andere Architekturen verfügbar sind.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-fno-split-wide-types&amp;lt;/tt&amp;gt;: Je nach Quelle kann die Deaktivierung von -fsplit-wide-types besseren Code ergeben.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-fno-inline-small-functions&amp;lt;/tt&amp;gt;: Relativ kleine Funktionen /immer/ zu inlinen kann den Code unnötig vergrößern, dieser Schalter unterbindet das automatische Inlinen kleiner Funktionen.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-finline-limit=&amp;lt;n&amp;gt;&amp;lt;/tt&amp;gt;: Maximale Wert für automatisch geinlinte Funktionen. In einschlägigen Foren werden kleine Werte für den Parameter vorgeschlagem, z.B. 1...3&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-mcall-prologues&amp;lt;/tt&amp;gt;: Die für aufwändige Funktionen mitunter recht langen push/pop-Sequenzen werden durch Hilfsfunktionen ersetzt. Das kann vor allem bei grossen Programmen Platz sparen. Die Ausführungszeit steigt an.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-fno-jump-tables&amp;lt;/tt&amp;gt;: Switch-Statements werden hierdurch mitunter deutlich kürzer.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-fno-move-loop-invariants&amp;lt;br/&amp;gt;-fno-tree-loop-optimize&amp;lt;/tt&amp;gt;: einige Schleifenoptimierungen, welche die Registerlast erhöhen und für AVR kaum zu einem Geschwindigkeitszuwachs führen, unterbleiben&lt;br /&gt;
&lt;br /&gt;
Generall gilt für all diese Optionen, daß sie abhängig vom Projekt zu einer Codeverbesserung oder -verschlechterung führen können — dies ist i.d.R. vom Projektcode abhängig.&lt;br /&gt;
&lt;br /&gt;
=== Attribute noreturn, OS_main und OS_task ===&lt;br /&gt;
Mikrocontroller-Programme laufen normalerweise in einer Endlosschleife, so dass die main-Routine nie verlassen wird.&lt;br /&gt;
Teilt man dies dem Compiler mit, kann er bestimmte Optimierungen durchführen.&lt;br /&gt;
So ist es zum Beispiel unnötig, Code zum Sichern und Zurücklesen von Registern zu erzeugen.&lt;br /&gt;
&lt;br /&gt;
Das Mitteilen funktioniert beim gcc über attribute, die man der Deklaration oder bei der Implementierung einer Funktion anhängt:&lt;br /&gt;
&amp;lt;c&amp;gt;static void main_loop (void) __attribute__((noreturn));&lt;br /&gt;
void main_loop (void)&lt;br /&gt;
{&lt;br /&gt;
  for(;;)&lt;br /&gt;
  {&lt;br /&gt;
     // Hauptschleife&lt;br /&gt;
  }&lt;br /&gt;
}&amp;lt;/c&amp;gt;&lt;br /&gt;
oder&lt;br /&gt;
&amp;lt;c&amp;gt;static void __attribute__((noreturn))&lt;br /&gt;
main_loop (void)&lt;br /&gt;
{&lt;br /&gt;
  for(;;)&lt;br /&gt;
  {&lt;br /&gt;
     // Hauptschleife&lt;br /&gt;
  }&lt;br /&gt;
}&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion &amp;lt;tt&amp;gt;main_loop&amp;lt;/tt&amp;gt; kann dann in &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; aufgerufen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;int main()&lt;br /&gt;
{&lt;br /&gt;
  main_loop();&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&amp;lt;/c&amp;gt;&lt;br /&gt;
Das abschließende &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; wird vom Compiler wegoptimiert und belegt keinen Speicher.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;avr-gcc&amp;lt;/tt&amp;gt; kennt weiterhin die Attribute &amp;lt;tt&amp;gt;OS_main&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;OS_task&amp;lt;/tt&amp;gt;, die leider nicht dokumentiert sind (Stand 07/2011).&lt;br /&gt;
Die Verwendung von &amp;lt;tt&amp;gt;OS_main&amp;lt;/tt&amp;gt; kann etwa aussehen wie folgt. Natürlich kann auch wie oben die Hauptschleife in einer eigenen Funktion implementiert werden, und das &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; verursacht keinen zusätzlichen Code:&lt;br /&gt;
&amp;lt;c&amp;gt;int __attribute__((OS_main))&lt;br /&gt;
main(void)&lt;br /&gt;
{&lt;br /&gt;
  for(;;)&lt;br /&gt;
  {&lt;br /&gt;
     // Hauptschleife&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Statische (globale) Variablen in einer Struktur sammeln===&lt;br /&gt;
&lt;br /&gt;
Das erleichtert dem Compiler die Adressierung, da er den Basiszeiger wiederverwenden kann. Die Codegröße kann dann noch von der Reihenfolge der struct-Member abhängen. Die häufigst benutzte Variable sollte am Anfang stehen, dann kann sie ohne Offset direkt mit dem Basiszeiger adressiert werden. Ansonsten in Gruppen, wie die Variablen auch gebraucht werden. Hier kann man viel rumprobieren.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
typedef struct &lt;br /&gt;
{&lt;br /&gt;
    uint16_t sec;            // Meistbenutze Variable an den Anfang&lt;br /&gt;
    uint16_t minute;&lt;br /&gt;
    uint16_t hour;&lt;br /&gt;
} time_t;&lt;br /&gt;
&lt;br /&gt;
time_t global;                    // Globale Struktur definieren&lt;br /&gt;
uint8_t min;                 // Als Vergleich: einzelne globale Variable&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    time_t *time = &amp;amp;global;       // Zeiger auf die globale Struktur&lt;br /&gt;
    // LDI R30,LOW(global)   ; Init Z pointer&lt;br /&gt;
    // LDI R31,(global &amp;gt;&amp;gt; 8) ; Init Z high byte&lt;br /&gt;
    if (++time-&amp;gt;sec == 60)&lt;br /&gt;
    {&lt;br /&gt;
    // LDD R16,Z+2           ; Load with displacement&lt;br /&gt;
    // INC R16               ; Increment&lt;br /&gt;
    // STD Z+2,R16           ; Store with displacement&lt;br /&gt;
    // CPI R16,LOW(60)       ; Compare&lt;br /&gt;
    // BRNE ?0005            ; Branch if not equal&lt;br /&gt;
    }&lt;br /&gt;
    if ( ++min == 60)&lt;br /&gt;
    {&lt;br /&gt;
    // LDS R16,LWRD(min)     ; Load direct from SRAM&lt;br /&gt;
    // INC R16               ; Increment&lt;br /&gt;
    // STS LWRD(min),R16     ; Store direct to SRAM&lt;br /&gt;
    // CPI R16,LOW(60)       ; Compare&lt;br /&gt;
    // BRNE ?0005            ; Branch if not equal&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch, dass die Strukturvariable über LDD/STD (LDD/STD 2 Bytes; LDS/STS 4 Bytes) angesprochen werden kann, werden an dieser Stelle 4 Bytes eingespart.&lt;br /&gt;
Hinzu kommen jedoch noch einmal die 4 Bytes für die Initialisierung des Z-pointers, sodass die Einsparung erst bei mehreren Globalvariablen zum Tragen kommt.&lt;br /&gt;
&lt;br /&gt;
; Anmerkung: Dieses Beispiel zeigt sehr schön, daß solcherlei &amp;quot;Optimierung&amp;quot; ohne Wissen um die Arbeitsweise des eingesetzten Compilers nach hinten losgehen können oder ins Leere laufen. Der erzeugte Code (avr-gcc 4.3.3 -Os) ist:&lt;br /&gt;
::{|&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
main:&lt;br /&gt;
/* prologue: function */&lt;br /&gt;
    lds r24,global&lt;br /&gt;
    lds r25,(global)+1&lt;br /&gt;
    adiw r24,1&lt;br /&gt;
    sts (global)+1,r25&lt;br /&gt;
    sts global,r24&lt;br /&gt;
    lds r24,min&lt;br /&gt;
    subi r24,lo8(-(1))&lt;br /&gt;
    sts min,r24&lt;br /&gt;
    ldi r24,lo8(0)&lt;br /&gt;
    ldi r25,hi8(0)&lt;br /&gt;
/* epilogue start */&lt;br /&gt;
    ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
: D.h. es wird &#039;&#039;nicht&#039;&#039; indirekt auf die Daten zugegriffen. Grund ist, daß gcc die Adresse zur Compilzeit ermitteln kann und dieses Wissen ausnutzt. Angemerkt sei noch, daß der Code im Beispiel von oben entweder gefaket ist und nicht von einem Compiler stammt (die wahrscheinlichere Variante), oder der Compiler inkorrekten Code erzeugte: Das INC erhöht nur die unteren 8 Bit der Komponenten, welche jedoch 16-Bit Werte sind.&lt;br /&gt;
&lt;br /&gt;
: Dennoch ist die angedeutete Zusammenfassung von &#039;&#039;inhaltlich zusammengehörenden&#039;&#039; Variablen sinnvoll und besser als ein Schwarm frei-flottierender int-Variablen.&lt;br /&gt;
&lt;br /&gt;
===Multiplikationen mit Konstanten===&lt;br /&gt;
&lt;br /&gt;
Der Compiler instanziiert sofort eine teure allgemeine Bibliotheksfunktion, auch wenn es anders ginge. Ich hatte eine einzige 32-bit Multiplikation mit 10 drin, die mir ein mulsi3 beschert hat. Mit a = (b&amp;lt;&amp;lt;3) + (b&amp;lt;&amp;lt;1) geht es in dem Fall kürzer. Wie gesagt, map-File beobachten. &lt;br /&gt;
Anmerkung: Variablen als unsigned definieren, dann sollte der Compiler das selbst machen.&lt;br /&gt;
&lt;br /&gt;
;Anmerkung: Auch Schieben ist teuer auf AVR. Schauen wir uns also mal an, was aus folgendem Code wird:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
uint32_t foo (uint32_t i)&lt;br /&gt;
{&lt;br /&gt;
    return i*10;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
uint32_t bar (uint32_t i)&lt;br /&gt;
{&lt;br /&gt;
    return (i &amp;lt;&amp;lt; 1) + (i &amp;lt;&amp;lt; 3);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Scrollbox|18ex;|&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
00000032 &amp;lt;foo&amp;gt;:&lt;br /&gt;
  32:	2a e0       	ldi	r18, 0x0A	; 10&lt;br /&gt;
  34:	30 e0       	ldi	r19, 0x00	; 0&lt;br /&gt;
  36:	40 e0       	ldi	r20, 0x00	; 0&lt;br /&gt;
  38:	50 e0       	ldi	r21, 0x00	; 0&lt;br /&gt;
  3a:	19 d0       	rcall	.+50     	; 0x6e &amp;lt;__mulsi3&amp;gt;&lt;br /&gt;
  3c:	08 95       	ret&lt;br /&gt;
&lt;br /&gt;
0000003e &amp;lt;bar&amp;gt;:&lt;br /&gt;
  3e:	26 2f       	mov	r18, r22&lt;br /&gt;
  40:	37 2f       	mov	r19, r23&lt;br /&gt;
  42:	48 2f       	mov	r20, r24&lt;br /&gt;
  44:	59 2f       	mov	r21, r25&lt;br /&gt;
  46:	22 0f       	add	r18, r18&lt;br /&gt;
  48:	33 1f       	adc	r19, r19&lt;br /&gt;
  4a:	44 1f       	adc	r20, r20&lt;br /&gt;
  4c:	55 1f       	adc	r21, r21&lt;br /&gt;
  4e:	e3 e0       	ldi	r30, 0x03	; 3&lt;br /&gt;
  50:	66 0f       	add	r22, r22&lt;br /&gt;
  52:	77 1f       	adc	r23, r23&lt;br /&gt;
  54:	88 1f       	adc	r24, r24&lt;br /&gt;
  56:	99 1f       	adc	r25, r25&lt;br /&gt;
  58:	ea 95       	dec	r30&lt;br /&gt;
  5a:	d1 f7       	brne	.-12     	; 0x50 &amp;lt;__SREG__+0x11&amp;gt;&lt;br /&gt;
  5c:	26 0f       	add	r18, r22&lt;br /&gt;
  5e:	37 1f       	adc	r19, r23&lt;br /&gt;
  60:	48 1f       	adc	r20, r24&lt;br /&gt;
  62:	59 1f       	adc	r21, r25&lt;br /&gt;
  64:	95 2f       	mov	r25, r21&lt;br /&gt;
  66:	84 2f       	mov	r24, r20&lt;br /&gt;
  68:	73 2f       	mov	r23, r19&lt;br /&gt;
  6a:	62 2f       	mov	r22, r18&lt;br /&gt;
  6c:	08 95       	ret&lt;br /&gt;
&lt;br /&gt;
0000006e &amp;lt;__mulsi3&amp;gt;:&lt;br /&gt;
  6e:	ff 27       	eor	r31, r31&lt;br /&gt;
  70:	ee 27       	eor	r30, r30&lt;br /&gt;
  72:	bb 27       	eor	r27, r27&lt;br /&gt;
  74:	aa 27       	eor	r26, r26&lt;br /&gt;
&lt;br /&gt;
00000076 &amp;lt;__mulsi3_loop&amp;gt;:&lt;br /&gt;
  76:	60 ff       	sbrs	r22, 0&lt;br /&gt;
  78:	04 c0       	rjmp	.+8      	; 0x82 &amp;lt;__mulsi3_skip1&amp;gt;&lt;br /&gt;
  7a:	a2 0f       	add	r26, r18&lt;br /&gt;
  7c:	b3 1f       	adc	r27, r19&lt;br /&gt;
  7e:	e4 1f       	adc	r30, r20&lt;br /&gt;
  80:	f5 1f       	adc	r31, r21&lt;br /&gt;
&lt;br /&gt;
00000082 &amp;lt;__mulsi3_skip1&amp;gt;:&lt;br /&gt;
  82:	22 0f       	add	r18, r18&lt;br /&gt;
  84:	33 1f       	adc	r19, r19&lt;br /&gt;
  86:	44 1f       	adc	r20, r20&lt;br /&gt;
  88:	55 1f       	adc	r21, r21&lt;br /&gt;
  8a:	96 95       	lsr	r25&lt;br /&gt;
  8c:	87 95       	ror	r24&lt;br /&gt;
  8e:	77 95       	ror	r23&lt;br /&gt;
  90:	67 95       	ror	r22&lt;br /&gt;
  92:	89 f7       	brne	.-30     	; 0x76 &amp;lt;__mulsi3_loop&amp;gt;&lt;br /&gt;
  94:	00 97       	sbiw	r24, 0x00	; 0&lt;br /&gt;
  96:	76 07       	cpc	r23, r22&lt;br /&gt;
  98:	71 f7       	brne	.-36     	; 0x76 &amp;lt;__mulsi3_loop&amp;gt;&lt;br /&gt;
&lt;br /&gt;
0000009a &amp;lt;__mulsi3_exit&amp;gt;:&lt;br /&gt;
  9a:	9f 2f       	mov	r25, r31&lt;br /&gt;
  9c:	8e 2f       	mov	r24, r30&lt;br /&gt;
  9e:	7b 2f       	mov	r23, r27&lt;br /&gt;
  a0:	6a 2f       	mov	r22, r26&lt;br /&gt;
  a2:	08 95       	ret&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
: Der Funktionsaufruf samt Lib-Funktion ist garnicht sooo teuer. Bereits mit zwei Multiplikationen im Programm &amp;amp;mdash; auch einer Multiplikation mit einer anderen Konstanten oder einer Variablen &amp;amp;mdash; gewinnt die lib-Version, da der Code wiederverwendet wird. Übrigens sind diese Multiplikationsroutinen und auch die in die libgcc enthaltenen Divisionen keine &amp;quot;normalen&amp;quot; Funktionen wie sie von C erzeugt werden. avr-gcc weiß genau, welche Register diese Routinen belegen und welche nicht. Damit ist der Aufruf einer solchen Funktion billiger als ein herkömmlicher Funktionsaufruf, bei dem die Funktion als Blackbox behandelt werden muss, die alle call-clobbered Register zerstört.&lt;br /&gt;
&lt;br /&gt;
===Alle Variablen nur so breit wie nötig===&lt;br /&gt;
&lt;br /&gt;
Hatte ich eigentlich schon, nur an einigen wenigen Stellen war ich da etwas nachlässig. Mitunter reicht ein kleinerer Typ doch, wenn man z.&amp;amp;nbsp;B. vorher geeignet skaliert. Am besten nur die skalaren Typen aus &amp;lt;stdint.h&amp;gt; verwenden, das erleichtert auch das Folgende. Bei RAM Knappheit: kann ich Strings sinnvollerweise aus dem RAM ins Flash verbannen? Kann ich es mir leisten mehrere Flag-Variablen in ein Byte zusammenzufassen, auch wenn dann die Zugriffe möglicherweise etwas langsamer werden.&lt;br /&gt;
&lt;br /&gt;
===Logische Operatoren werden auf int-Größe erweitert===&lt;br /&gt;
&lt;br /&gt;
Obwohl der AVR ein 8-Bit Controller ist, weitet der AVR-GCC an manchen Stellen  Vergleiche von zwei 8-Bit Variablen auf 16-Bit auf.&lt;br /&gt;
Als Beispiel sei dabei folgendes gezeigt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
void foo (uint8_t a, uint8_t b)&lt;br /&gt;
{&lt;br /&gt;
    if (a == ~b)&lt;br /&gt;
    {&lt;br /&gt;
    // clr r19           ; clear register&lt;br /&gt;
    // mov r24,r22       ; copy register&lt;br /&gt;
    // clr r25           ; clear register&lt;br /&gt;
    // com r24           ; one&#039;s complement&lt;br /&gt;
    // com r25           ; one&#039;s complement&lt;br /&gt;
    // cp r18,r24        ; compare registers&lt;br /&gt;
    // cpc r19,r25       ; compare registers with carry&lt;br /&gt;
    // brne .L1          ; branch if not equal&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
Den zweiten Vergleich mit der Negation weitet der Compiler auf 16 Bit auf.&lt;br /&gt;
Ein Cast verhindert dieses:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
void foo(uint8_t a, uint8_t b)&lt;br /&gt;
{&lt;br /&gt;
    if (a == (uint8_t) ~b)&lt;br /&gt;
    {&lt;br /&gt;
    // com r22           ; one&#039;s complement&lt;br /&gt;
    // cp r25,r22        ; compare registers&lt;br /&gt;
    // brne .L1          ; branch if not equal&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
Die Einsparung an Speicher zwischen den beiden Versionen beträgt 12 Bytes. Außerdem ist die zweite Version um 6 Takte schneller.&lt;br /&gt;
&lt;br /&gt;
;Achtung: Tatsächlich handelt es sich dabei nicht um ein Optimierungsproblem, sondern einen typischen Programmierfehler. Die beiden Varianten sind keineswegs identisch. Bei Variablen vom Typ uint8_t wird der Ausdruck (a == ~b) immer falsch sein: a=0x0000...0x00ff, ~b=0xff00...0xffff.&lt;br /&gt;
&lt;br /&gt;
===Compileroption -mint8 für 8-Bit Arithmetik als Default===&lt;br /&gt;
&lt;br /&gt;
Mit obigen casts überall sähe der Code ziemlich schlimm aus. Blöd auch, wenn man mal einen Type ändert, dann muß man sorgsam nach den zugehörigen casts&lt;br /&gt;
suchen. Mit dem Compilerschalter -mint8 wird das zum Standard. Bei mir&lt;br /&gt;
hat das etwa 200 Byte gespart! Man sollte dafür aber keine ints mehr im&lt;br /&gt;
Code haben, nur noch Typen definierter Größe aus &amp;lt;stdint.h&amp;gt;.&lt;br /&gt;
Literal-Werte muß man ggf. anpassen (z.&amp;amp;nbsp;B. mit postfix L long machen)&lt;br /&gt;
damit sie nicht überlaufen, Compiler-Warnings beachten.  Ist anscheinend&lt;br /&gt;
noch etwas experimentell(?), mit dem aktuellen gcc 4.1.1 gibt es eine&lt;br /&gt;
Unverträglichkeit in &amp;lt;stdint.h&amp;gt;, der kriegt ein Problem mit den 64-bit Typen. Ist aber wohl in Arbeit, ich habe einen Patch gesehen.&lt;br /&gt;
&lt;br /&gt;
{{Warnung|&lt;br /&gt;
;Warnung:Diese Option verändert das Binärinterface! Funktionen, die nicht mit dieser Option übersetzt wurden, sind nicht unbedingt kompatiablen mit solchen, die mit dem Schalter erzeugt wurden. Da die Bibliotheken &amp;amp;mdash; auch die Compiler-interne libgcc &amp;amp;mdash; ohne diesen Schalter generiert werden, ist mit Problemen zu rechnen. Weiterhin sind bestimmte Typen nicht mehr verfügbar bzw. werden mit anderer Semantik belegt, etwa int und long. Für die Option gibt es in avr-gcc 4.x kein Support mehr.}}&lt;br /&gt;
&lt;br /&gt;
===Stack auf 256 Bytes begrenzen===&lt;br /&gt;
&lt;br /&gt;
Mit dem Compileflag -mtiny-stack wird für den Stack eine einfachere Adressierung möglich, die aber &amp;quot;nur&amp;quot; 256 Byte Stacktiefe erlaubt. Wenn man nicht exzessiv automatische Variablen benutzt (Arrays!) oder eine hohe&lt;br /&gt;
Verschachtelungstiefe hat, sollte das ausreichen. Hat mir nochmal knapp 100 Byte (!) kleineren Code erzeugt.&lt;br /&gt;
&lt;br /&gt;
===Speichern von globalen Flags===&lt;br /&gt;
&lt;br /&gt;
Oft werden in den Programmen Flags verwendet um beispielsweise eingetroffene Interrupts in der main-Routine auszuwerten. Hierzu wird üblicherweise eine globale Variable verwendet.&lt;br /&gt;
&lt;br /&gt;
Um den Wert dieser Variable abzufragen, muss sie jedoch erst aus dem SRAM in ein Register geladen werden, und kann dann erst auf ihren Status hin überprüft werden. Eine Möglichkeit ist, der globalen Variablen ein einziges Register fest zuzuordnen:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
register uint8_t counter8_1 asm(&amp;quot;r2&amp;quot;);&lt;br /&gt;
register uint8_t counter8_2 asm(&amp;quot;r3&amp;quot;);&lt;br /&gt;
register uint16_t counter16_1 asm(&amp;quot;r4&amp;quot;); // r4:r5&lt;br /&gt;
register uint16_t counter16_2 asm(&amp;quot;r6&amp;quot;); // r6:r7&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
siehe auch: http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_regbind&lt;br /&gt;
&lt;br /&gt;
Als Alternative kann man ein nicht verwendetes Register des I/O-Bereichs verwenden. Dabei würde sich z.&amp;amp;nbsp;B. das Register eines zweiten UARTs, oder das  EEPROM-Register anbieten, falls diese nicht benötigt werden.&lt;br /&gt;
&lt;br /&gt;
Neuere AVR-Modelle besitzen für diesen Zweck 3 frei verwendbare Bytes im bitadressierbaren I/O-Bereich: GPIOR0-2.&lt;br /&gt;
&lt;br /&gt;
{{Warnung|&lt;br /&gt;
;Warnung: Dieses Vorgehen verändert das ABI! Um dieses Feature fehlerfrei anzuwenden, ist einiges an Wissen über die Interna von GCC notwendig. Auch ein korrekt funktionierendes Programm ist keine Garantie dafür, daß die globalen Register fehlerfrei implementiert wurden. Unter Umständen bringen erst spätere Codeänderungen/-erweiterung den Fehler zum Vorschein, und weil der Fehler vorher nicht akut war, sucht man sich den Wolf an der falschen Stelle im Code anstatt bei der globalen Registern. Siehe auch [[Globale Register]].}}&lt;br /&gt;
&lt;br /&gt;
===Puffern von volatile-Variablen===&lt;br /&gt;
&lt;br /&gt;
Der Compiler behandelt volatile-Variablen bei mehreren Manipulationen wie heiße Kartoffeln. Für jeden einzelnen Vorgang wiederholt sich das Spiel:&lt;br /&gt;
&lt;br /&gt;
* aus dem Speicher holen&lt;br /&gt;
* bearbeiten&lt;br /&gt;
* zurückspeichern&lt;br /&gt;
&lt;br /&gt;
Unter Umständen ist dieses Verhalten unsinnig. Ein Minimalbeispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
volatile char var;&lt;br /&gt;
&lt;br /&gt;
ISR()&lt;br /&gt;
{&lt;br /&gt;
    var++;&lt;br /&gt;
&lt;br /&gt;
    if (var &amp;gt; 100)&lt;br /&gt;
        var = 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void main (void)&lt;br /&gt;
{&lt;br /&gt;
    while (1)&lt;br /&gt;
        printf (var);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Hier wird &#039;&#039;&#039;var&#039;&#039;&#039; pro [[ISR]]-Ausführung zwei mal aus dem RAM geholt und zurückgeschrieben. Das ist überflüssig, weil die Interruptrountine nicht unterbrochen werden kann. Aus Sicht der ISR bräuchte man eigentlich kein volatile, kann es aber wegen dem Zugriff von main heraus nicht weglassen. Eine Lösung findet sich im folgenden Schnipsel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
volatile char var;&lt;br /&gt;
&lt;br /&gt;
ISR()&lt;br /&gt;
{&lt;br /&gt;
    char temp = var;&lt;br /&gt;
&lt;br /&gt;
    if (++temp &amp;gt; 100)&lt;br /&gt;
        temp=0;&lt;br /&gt;
&lt;br /&gt;
    var = temp;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void main (void)&lt;br /&gt;
{&lt;br /&gt;
    while (1)&lt;br /&gt;
        printf (var);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Hier wird die globale Variable &#039;&#039;&#039;var&#039;&#039;&#039; in der lokalen Variable &#039;&#039;&#039;temp&#039;&#039;&#039; gepuffert. Ein Nachteil durch das Anlegen von &#039;&#039;&#039;temp&#039;&#039;&#039; ergibt sich nicht, da das dafür verwendete Register für die Manipulation sowieso benötigt wird. &lt;br /&gt;
&lt;br /&gt;
Wie alle Optimierungen kann dieses Vorgehen auch nach hinten losgehen: Wenn Laden und Zurückspeichern von &#039;&#039;&#039;var&#039;&#039;&#039; weit auseinanderliegen (extrem lange ISR), müllt man sich die Register zu. Im schlimmsten Fall wird &#039;&#039;&#039;temp&#039;&#039;&#039; sogar zwischenzeitlich auf dem Stack ausgelagert.&lt;br /&gt;
&lt;br /&gt;
===Schleifen===&lt;br /&gt;
&lt;br /&gt;
Bei Schleifen, die eine bestimmte Anzahl an Durchläufen ausgeführt werden sollen, ist es besser den Schleifenzähler vorher auf einen Wert zu setzen, und am Ende einer Do-While Schleife diesen zu dekrementieren.&lt;br /&gt;
So beschränkt sich die Sprungbedingung auf ein brne (branch if not equal).&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
uint8_t counter;	&lt;br /&gt;
counter = 100;&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
    // mach irgendetwas&lt;br /&gt;
} while (--counter);&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Unbenutzte Funktionen und/oder Variablen entfernen===&lt;br /&gt;
&lt;br /&gt;
F: Mir ist aufgefallen, dass der Linker nicht benutzte Funktionen trotzdem mit linkt und Speicherplatz belegt. Gibt es eine Möglichkeit diese Funktionen automatisch weg zu lassen?&lt;br /&gt;
&lt;br /&gt;
A: Dem GNU Linker sagt man mit &#039;&#039;--gc-sections&#039;&#039;, dass er unbenutzte Sektionen rauswirft. Mit &#039;&#039;--print-gc-sections&#039;&#039; listet er die rausgeworfenen auch auf. Dem GCC kann man mit &#039;&#039;-ffunction-sections&#039;&#039; sagen, dass er jede Funktion in eine eigene Sektion legt, damit funktioniert das auch unterhalb der Ebene einer Quellcodedatei (also eine Funktion rausschmeissen obwohl fünf andere in derselben Datei gebraucht werden). Mit der Option &#039;&#039;-fdata-sections&#039;&#039; geht das auch für statische Variablen ([http://www.mikrocontroller.net/topic/210453#2084822 Forumsbeitrag von Andreas B.]).&lt;br /&gt;
&lt;br /&gt;
Vorsicht: Je nach Implementierung der Interruptsprung- bzw. Vektorleiste kann es dazu führen, dass alle eigenen Interrupt-Handler ebenfalls wegoptimiert werden. Dies passiert dann, wenn es im Code keinen Verweis (typisch: Ermittlung der Adresse zum Eintrag in eine Interrupt-Vektortabelle oder in Hardwareregister eines Interrupt-Controllers) auf die Handler-Funktion gibt oder die Funktion, in der der Verweis auf eine ISR enthalten ist, nie aufgerufen wird. In solchen Fällen kann es notwendig sein, die Handler mit __attribute__((used)) zu versehen. Bei Verwendung der Makros aus der avr-libc (in WinAVR enthalten, z.B. ISR()) ist dies nicht erforderlich, da das Attribut bereits in den Makro-Definitionen enthalten ist (avr-libc/interrupt.h/ __INTR_ATTRS). In manch anderer Umgebung, wie bei einigen Quellcodes für ARM-basierte Controller, ist das Attribut jedoch zu ergänzen.&lt;br /&gt;
&lt;br /&gt;
==Optimierung der Ausführungsgeschwindigkeit==&lt;br /&gt;
&lt;br /&gt;
Hierzu gibt es schon eine Application-Note von Atmel. Diese AppNote bezieht sich auf den IAR-Compiler. Die darin genannten &amp;quot;Optimierungen&amp;quot; sind für avr-gcc größtenteils obsolet oder bleiben bestenfalls ohne Effekt.&lt;br /&gt;
&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/doc1497.pdf AVR035]: Efficient C Coding for AVR&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Program_optimization Program optimization] auf Wikipedia, engl.&lt;br /&gt;
&lt;br /&gt;
== Fußnoten ==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:avr-gcc]]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=MSP430_Codebeispiele&amp;diff=58109</id>
		<title>MSP430 Codebeispiele</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=MSP430_Codebeispiele&amp;diff=58109"/>
		<updated>2011-06-23T13:21:32Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: /* I2C/TWI in Software */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;MSP430 &amp;amp;#8211; Codebeispiele&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Einleitung:&#039;&#039;&#039;&lt;br /&gt;
Da der MSP430 eine sehr schöner Mikrocontroller für energiesparende Anwendungen ist, jedoch bei weitem nicht so verbreitet wie z.&amp;amp;nbsp;B. diverse 8051er, AVRs, PICs usw. ist, gibt es auch nicht all zu viele Codebeispiele aus Projekten für den/die Hobbybastler(in).&lt;br /&gt;
Aus diesem Grund werden hier Grundlagen der Initialisierung diverser Hardwarefeatures sowie grundlegende Softwareroutinen und dergleichen beschrieben, so dass für Anfänger auch ein einfaches Copy&amp;amp;Paste möglich ist.&lt;br /&gt;
Hierbei kommt der MSPGCC zum Einsatz, da eine professionelle unlimitierte Ausgabe des z.&amp;amp;nbsp;B. IAR für Bastler nahezu unbezahlbar ist.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Hardware =&lt;br /&gt;
&lt;br /&gt;
== Initializing/ Configuring UARTs ==&lt;br /&gt;
Von www.mathar.com stammt diese Routine zur initialisierung eines beliebigen UARTS. Zusätzlich müssen jedoch die Pins noch definiert werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
void InitUSART(char USART0, char USART1, unsigned int baudrate1, unsigned int baudrate2, char IR0, char IR1)&lt;br /&gt;
{&lt;br /&gt;
  if (USART0) ME1 |= UTXE0 + URXE0;    // falls gesetzt, USART0 einschalten (TX- und RX-teil)&lt;br /&gt;
  if (USART1) ME2 |= UTXE1 + URXE1;    // falls gesetzt, USART1 einschalten (TX- und RX-teil)&lt;br /&gt;
  UCTL0 |= CHAR;                       // 8 data bits, 1 stop bit, no parity (8N1)&lt;br /&gt;
  UCTL1 |= CHAR;&lt;br /&gt;
  UTCTL0 |= SSEL1;                     // SMCLK als UCLK festlegen&lt;br /&gt;
  UTCTL1 |= SSEL1;&lt;br /&gt;
  if (baudrate1==19200)&lt;br /&gt;
  {&lt;br /&gt;
    UBR00 = 0xA0;                      // 19200 baud aus 8 MHz erzeugen&lt;br /&gt;
    UBR10 = 0x01;                      // siehe application note tabelle 1, seite 9&lt;br /&gt;
    UMCTL0 = 0x00;                     // keine korrektur der division noetig&lt;br /&gt;
  }&lt;br /&gt;
  if (baudrate2==19200)&lt;br /&gt;
  {&lt;br /&gt;
    UBR01 = 0xA0;                      // 19200 baud aus 8 MHz erzeugen&lt;br /&gt;
    UBR11 = 0x01;                      // siehe application note tabelle 1, seite 9&lt;br /&gt;
    UMCTL1 = 0x00;                     // keine korrektur der division noetig&lt;br /&gt;
  }&lt;br /&gt;
  if (USART0) UCTL0 &amp;amp;= ~SWRST;         // USART freigeben&lt;br /&gt;
  if (USART1) UCTL1 &amp;amp;= ~SWRST;&lt;br /&gt;
  if (IR0==0) IE1 |= URXIE0;           // IR0: 0 -&amp;gt; nur RX-interrupt anschalten&lt;br /&gt;
  if (IR0==1) IE1 |= UTXIE0;           //      1 -&amp;gt; nur TX-interrupt anschalten&lt;br /&gt;
  if (IR0==2) IE1 |= URXIE0 + UTXIE0;  //      2 -&amp;gt; TX- und RX-interrupt anschalten&lt;br /&gt;
  if (IR1==1||IR1==2) IFG1 &amp;amp;= ~UTXIFG0;  // initales interrupt-flag loeschen&lt;br /&gt;
  if (IR1==0) IE2 |= URXIE1;           // IR1: 0 -&amp;gt; nur RX-interrupt anschalten&lt;br /&gt;
  if (IR1==1) IE2 |= UTXIE1;           //      1 -&amp;gt; nur TX-interrupt anschalten&lt;br /&gt;
  if (IR1==2) IE2 |= URXIE1 + UTXIE1;  //      2 -&amp;gt; TX- und RX-interrupt anschalten&lt;br /&gt;
  if (IR1==1||IR1==2) IFG1 &amp;amp;= ~UTXIFG1;  // initales interrupt-flag loeschen&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Initialization/configuration of USART (SPI and I2C/TWI) ==&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
void init_spi(void)&lt;br /&gt;
{&lt;br /&gt;
  ME1 |= USPIE0;                        // Enable USART0 SPI mode&lt;br /&gt;
  UTCTL0 = CKPH+SSEL1+SSEL0+STC;        // SMCLK, 3-pin mode&lt;br /&gt;
  UCTL0 = CHAR+SYNC+MM;                 // 8-bit SPI Master **SWRST**&lt;br /&gt;
  UBR00 = 0x02;                         // UCLK/2 &lt;br /&gt;
  UBR10 = 0x00;                         // 0&lt;br /&gt;
  UMCTL0 = 0x00;                        // no modulation&lt;br /&gt;
  P3SEL |= 0x0E;                        // P3.1-3 SPI option select&lt;br /&gt;
  P3DIR |= 0x01;                        // P3.0 output direction&lt;br /&gt;
  _EINT();                              // Enable interrupts&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void init_i2c(unsigned char slave)&lt;br /&gt;
{&lt;br /&gt;
  P3SEL |= 0x0a;                            // Assign I2C pins to module&lt;br /&gt;
  U0CTL |= I2C + SYNC;                      // Switch USART0 to I2C mode&lt;br /&gt;
  U0CTL &amp;amp;= ~I2CEN;                          // Recommended I2C init procedure&lt;br /&gt;
  I2CTCTL = I2CSSEL_2;                      // SMCLK&lt;br /&gt;
  I2CSCLH = 0x03;                           // High period of SCL&lt;br /&gt;
  I2CSCLL = 0x03;                           // Low period of SCL&lt;br /&gt;
  I2CNDAT = 0x01;                           // Transmit one byte&lt;br /&gt;
  I2CSA = slave;                             // Slave address&lt;br /&gt;
  U0CTL |= I2CEN;                           // Enable I2C, 7 bit addr,&lt;br /&gt;
  I2CIE = RXRDYIE;                          // I2C receive ready interrupt enable&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Initialisierung der Quarze ==&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
void init_XT2(void)&lt;br /&gt;
{&lt;br /&gt;
  unsigned int i;&lt;br /&gt;
  WDTCTL = WDTPW + WDTHOLD;             // Stop WDT&lt;br /&gt;
  BCSCTL1 &amp;amp;= ~XT2OFF;                   // XT2 = HF XTAL&lt;br /&gt;
  do &lt;br /&gt;
  {&lt;br /&gt;
    IFG1 &amp;amp;= ~OFIFG;                       // Clear OSCFault flag&lt;br /&gt;
    for (i = 0xFF; i &amp;gt; 0; i--);           // Time for flag to set&lt;br /&gt;
  }&lt;br /&gt;
  while ((IFG1 &amp;amp; OFIFG) != 0);          // OSCFault flag still set?                &lt;br /&gt;
  BCSCTL2 |= SELM1;                     // MCLK = XT2 (safe)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
void init_XT(void) // high frequenz resonators ( 455 kHz - 8MhZ )&lt;br /&gt;
{&lt;br /&gt;
  unsigned int i;&lt;br /&gt;
  WDTCTL = WDTPW + WDTHOLD;             // Stop WDT&lt;br /&gt;
  BCSCTL1 |= XTS;                       // ACLK = LFXT1 = HF XTAL&lt;br /&gt;
  do &lt;br /&gt;
  {&lt;br /&gt;
    IFG1 &amp;amp;= ~OFIFG;                       // Clear OSCFault flag&lt;br /&gt;
    for (i = 0xFF; i &amp;gt; 0; i--);           // Time for flag to set&lt;br /&gt;
  }&lt;br /&gt;
  while ((IFG1 &amp;amp; OFIFG) == OFIFG);      // OSCFault flag still set?                &lt;br /&gt;
  BCSCTL2 |= SELM1+SELM0;               // MCLK = LFXT1 (safe)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
Bei den neueren MSP430F55xx nicht vergessen, dass bei CPU-Taktfrequenzen über 8 MHz vorher die Kernspannung erhöht werden muss, sonst drohen Abstürze oder „rätselhaftes“ Verhalten. Eins der TI-Beispiele (12 MHz) „vergisst“ das sogar.&lt;br /&gt;
&lt;br /&gt;
== Initialisierung des ADCs ==&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
void init_ADC(void)&lt;br /&gt;
{&lt;br /&gt;
  ADC12CTL0 = ADC12ON;	// ADC12ON / reference on Avcc&lt;br /&gt;
  P6SEL |= 0x01;        // P6.0 ADC option select &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
unsigned int sampling_ADC(void)&lt;br /&gt;
{&lt;br /&gt;
  ADC12CTL0 |= ADC12SC + ENC;   // Sampling open&lt;br /&gt;
  ADC12CTL0 &amp;amp;= ~ADC12SC;        // Sampling closed, start conversion&lt;br /&gt;
  while ((ADC12CTL1 &amp;amp; ADC12BUSY) == 1);   // ADC12BUSY?&lt;br /&gt;
  return(ADC12MEM0);	// return the value read from ADC P6.0&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Initialisierung des DACs ==&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void init_DAC(void)&lt;br /&gt;
{&lt;br /&gt;
  ADC12CTL0 = REF2_5V + REFON;              // Internal 2.5V ref on&lt;br /&gt;
  DAC12_0CTL = DAC12IR + DAC12AMP_5 + DAC12ENC;   // Internal ref gain &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void write_DAC(unsigned int val)&lt;br /&gt;
{&lt;br /&gt;
  DAC12_0DAT = val;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Initialisierung des Timers A ==&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
void init_TimerA(unsigned int cycles )&lt;br /&gt;
{&lt;br /&gt;
  TACTL = TASSEL1 + TACLR;              // SMCLK, clear TAR&lt;br /&gt;
  CCTL0 = CCIE;                         // CCR0 interrupt enabled&lt;br /&gt;
  CCR0 = cycles;&lt;br /&gt;
  TACTL |= MC_2;                         // Start Timer_A in continuous mode&lt;br /&gt;
  _EINT();                              // interrupt enable&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Timer A0 interrupt service routine&lt;br /&gt;
interrupt (TIMERA0_VECTOR) Timer_A(void)&lt;br /&gt;
{&lt;br /&gt;
  P1OUT ^= 0x01;                        // Toggle P1.0&lt;br /&gt;
  CCR0 += 50000;                        // Add Offset to CCR0&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Initialisierung des Timers B ==&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
void init_TimerB(unsigned int cycles)&lt;br /&gt;
{&lt;br /&gt;
  TBCTL = TBSSEL1 + TBCLR;              // SMCLK, clear TAR&lt;br /&gt;
  TBCCTL0 = CCIE;                       // CCR0 interrupt enabled&lt;br /&gt;
  TBCCR0 = cycles;&lt;br /&gt;
  TBCTL |= MC_2;                         // Start Timer_B in continuous mode&lt;br /&gt;
  _EINT();                              // interrupt enable&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Timer B0 interrupt service routine&lt;br /&gt;
interrupt (TIMERB0_VECTOR) Timer_B(void)&lt;br /&gt;
{&lt;br /&gt;
  P1OUT ^= 0x01;                        // Toggle P1.0&lt;br /&gt;
  TBCCR0 += 50000;                      // Add Offset to CCR0&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Initialisierung des Watchdogs ==&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
void init_wdt(void)&lt;br /&gt;
{&lt;br /&gt;
  WDTCTL = WDT_MDLY_32;                 // Set Watchdog Timer interval to ~30ms&lt;br /&gt;
  IE1 |= WDTIE;                         // Enable WDT interrupt&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Watchdog Timer interrupt service routine&lt;br /&gt;
interrupt (WDT_VECTOR) watchdog_timer(void)&lt;br /&gt;
{&lt;br /&gt;
  // do this, in an case of an interrupt&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
  WDTCTL = WDTPW + WDTHOLD;	// Watchdog anhalten&lt;br /&gt;
  P1DIR |= 0x01;		// P1.0 als Ausgang&lt;br /&gt;
&lt;br /&gt;
  for (;;)&lt;br /&gt;
  {&lt;br /&gt;
    volatile unsigned i;	// volatile, sonst wird die Warteschleife „wegoptimiert“&lt;br /&gt;
    P1OUT ^= 0x01;		// P1.0 umschalten mit Exklusiv-ODER&lt;br /&gt;
&lt;br /&gt;
    i = 10000;			// Warteschleife in Software&lt;br /&gt;
    do; while (--i);		// (CPU-Leistung „verheizen“)&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Initialisierung der GPIO ==&lt;br /&gt;
Die Ein/Ausgabeleitungen haben beim MSP430, je nach Ausbaustufe, folgende Fähigkeiten:&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Einzeln (bitweise) programmierbare Ein/Ausgabe (&amp;lt;b&amp;gt;PxDIR&amp;lt;/b&amp;gt;, &amp;lt;b&amp;gt;PxOUT&amp;lt;/b&amp;gt;)&lt;br /&gt;
&amp;lt;li&amp;gt;Unabhängige Lese-Adresse (&amp;lt;b&amp;gt;PxIN&amp;lt;/b&amp;gt;)&lt;br /&gt;
&amp;lt;li&amp;gt;Ansprechbar als 8-Bit-Ports oder je paarweise als 16-bit-Port, bspw. P1 + P2 = PA usw.&lt;br /&gt;
&amp;lt;li&amp;gt;Interrupt auf Pegelwechsel einzelner Portpins (nur P1 und P2) (&amp;lt;b&amp;gt;PxIES&amp;lt;/b&amp;gt;)&lt;br /&gt;
&amp;lt;li&amp;gt;Pull-Up, Pull-Down oder kein Widerstand auswählbar (&amp;lt;b&amp;gt;PxREN&amp;lt;/b&amp;gt;, PxOUT)&lt;br /&gt;
&amp;lt;li&amp;gt;Einstellbare Treiberstärke (reduziert und voll) (&amp;lt;b&amp;gt;PxDS&amp;lt;/b&amp;gt;)&lt;br /&gt;
&amp;lt;li&amp;gt;Ein bis zwei Peripheriefunktionen pro Pin (&amp;lt;b&amp;gt;PxSEL&amp;lt;/b&amp;gt;), auswählbar mittels PxDIR (d.h. bei zwei Peripheriefunktionen ist eine Ausgang und die andere Eingang)&lt;br /&gt;
&amp;lt;li&amp;gt;Das JTAG-Port (4 Pins) und das USB-Port (2 Pins) ist standardmäßig ein E/A-Port (MSP430F55xx)&lt;br /&gt;
&amp;lt;li&amp;gt;Erweiterte Peripheriezuordnung bei P4 (MSP430F55xx) mittels Port Mapping Controller&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Nicht 5-V-verträglich!!&amp;lt;/b&amp;gt; Keinem Portpin darf ohne genügend großen Vorwiderstand 5 V angeboten werden. Ableitströme dürfen nicht zum Ansteigen der Speisespannung führen!&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Manche Portpins haben ein gemeinsames PxSEL, etwa:&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;das JTAG-Port (entweder alle 4 oder kein Pin zugeordnet)&lt;br /&gt;
&amp;lt;li&amp;gt;das USB-Port (entweder Portpin oder USB D+ und D–)&lt;br /&gt;
&amp;lt;li&amp;gt;die Quarz-Anschlüsse (das niederwertige PxSEL schaltet beide Portpins)&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle Portpins sind beim Einschalten (PUC) wie folgt initialisiert:&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Eingang ohne Pull-Up oder Pull-Down&lt;br /&gt;
&amp;lt;li&amp;gt;Reduzierte Treiberstärke&lt;br /&gt;
&amp;lt;li&amp;gt;Kein Pegelwechsel-Interrupt&lt;br /&gt;
&amp;lt;li&amp;gt;Keine Peripherie-Zuordnung&lt;br /&gt;
&amp;lt;li&amp;gt;Der Inhalt des Ausgaberegisters &amp;lt;b&amp;gt;PxOUT&amp;lt;/b&amp;gt; ist undefiniert!&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Alle ungenutzten Anschlüsse sollten per PullDown (&amp;lt;b&amp;gt;PxREN&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;PxOUT&amp;lt;/b&amp;gt;) festgelegt werden.&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Kein MSP430 hat einen herausgeführten Busanschluss.&lt;br /&gt;
&lt;br /&gt;
== Initialisierung von PWM ==&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
void init_PWM_TimerA(void)&lt;br /&gt;
{&lt;br /&gt;
  TACTL = TASSEL1 + TACLR;              // SMCLK, Clear Tar&lt;br /&gt;
  CCR0 = 512-1;                         // PWM Period&lt;br /&gt;
  CCTL1 = OUTMOD_7;                     // CCR1 reset/set&lt;br /&gt;
  P1DIR |= 0x04;                        // P1.2 PWM output&lt;br /&gt;
  P1SEL |= 0x04;                        // P1.2 and TA1/2 otions&lt;br /&gt;
  TACTL |= MC0;                         // Start Timer_A in up mode&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void set_PWM_duty_cycle(unsigned char duty)&lt;br /&gt;
{&lt;br /&gt;
  CCR1 = duty;                           // CCR1 PWM duty cycle &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Interrupts: =&lt;br /&gt;
&lt;br /&gt;
== UARTs ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
// z.&amp;amp;nbsp;B. ein Echo mit dem MSPGCC-Compiler:&lt;br /&gt;
interrupt (UART0RX_VECTOR) usart0_rx(void)&lt;br /&gt;
{&lt;br /&gt;
   TXBUF0=RXBUF0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// z.&amp;amp;nbsp;B. ein Echo mit dem ImageCraft ICC430-Compiler:&lt;br /&gt;
#pragma interrupt_handler usart0_rx:UART0RX_VECTOR&lt;br /&gt;
void usart0_rx(void)&lt;br /&gt;
{&lt;br /&gt;
   TXBUF0=RXBUF0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
Die Funktionen selbst können natürlich auch anders genannt werden.&lt;br /&gt;
&lt;br /&gt;
== Timer ==&lt;br /&gt;
&lt;br /&gt;
== IOs ==&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Softwareroutinen: =&lt;br /&gt;
&lt;br /&gt;
== I2C/TWI in Software ==&lt;br /&gt;
Diese Routinen wurden ursprünglich für einen MSP430F149 geschrieben. Es werden ausschließlich IOs benutzt. Da Code in C geschrieben wurde sollte er sich einfach auf alle MSP430s ohne (aber auch mit I²C) portieren lassen. Der ist zwar nicht ganz schön, aber er funktioniert soweit ganz gut. Auch ein Beispiel ist dabei.&lt;br /&gt;
&lt;br /&gt;
http://www.mikrocontroller.net/attachment.php/324877/soft-i2c.zip&lt;br /&gt;
&lt;br /&gt;
== PWM ==&lt;br /&gt;
&lt;br /&gt;
Untenstehender Code ist nur mit msp320-gcc getestet.&lt;br /&gt;
&lt;br /&gt;
Folgende Routine initialisiert den Timer als Up-Counter mit der Clock-Quelle SMCLK und einem Teiler von 8. Zudem wird der Interrupt aktiviert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
void timerA_init(void)&lt;br /&gt;
{&lt;br /&gt;
	TACTL =  TASSEL_SMCLK | TACLR | ID_DIV8 | TAIE;&lt;br /&gt;
	TACTL |= MC_UPTO_CCR0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Um den Timer zu starten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
void timerA_start(int timing[2], int mode)&lt;br /&gt;
{&lt;br /&gt;
	TACCTL0 = mode;&lt;br /&gt;
	TACCTL0 |= CCIE ;                // enable interrupt&lt;br /&gt;
	TACCTL1 = mode;&lt;br /&gt;
	TACCR0 = timing[0];&lt;br /&gt;
	TACCR1 = timing[1];&lt;br /&gt;
	TAR = 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Die Funktion wird normalerweise mit &#039;mode&#039; 3 aufgerufen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
timerA_start(timing, OUTMOD_SET_RESET);&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
timing[0] enthaelt die komplette Zyklendauer einer PWM-Phase (H und L)&lt;br /&gt;
Beispiel: Um eine Pulsfrequenz von 125 Hz bei einem SMCLK von 1.0 MHz zu erhalten, gilt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;timing_0 = 1.0e6 / 8 / 125 = 1000&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
timing[1] schliesslich enthält die Zyklendauer des H-Pulses und ist immer kleiner als timing[0]. Bei einem &#039;duty cycle&#039; (Tastverhältnis) 50% gilt also&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;timing_1 = 500&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zu beachten ist, dass der Timerkanal 0 bei manchen Modi (wie dem obenstehenden) für die PWM nicht genutzt wird, &amp;quot;TACCTL0 = mode&amp;quot; keinen speziellen Effekt zeigt (siehe auch Manual).&lt;br /&gt;
&lt;br /&gt;
Deswegen wird das PWM-Signal auch an TA1 abgegriffen, nicht an TA0.&lt;br /&gt;
&lt;br /&gt;
Schlussendlich muss der entsprechende Ausgangspin für TA1 konfiguriert werden. Beim F2013 z.&amp;amp;nbsp;B. geschieht dies für P1.2 per&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
	P1SEL |= 0x04;  // Enable primary peripheral&lt;br /&gt;
	P1DIR |= 0x04;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Was war nun mit dem Interrupt? Falls wir z.&amp;amp;nbsp;B. die Zyklen zählen wollen, definieren wir einen Interrupt-Handler:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;signal.h&amp;gt; // &#039;interrupt&#039; makro&lt;br /&gt;
interrupt (TIMERA0_VECTOR) timera0_isr(void)&lt;br /&gt;
{&lt;br /&gt;
	g_count++;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Schlussendlich müssen wir noch die Interrupts im Initialisierungscode aktivieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
_EINT();&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Senden eines Bytes ==&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
void SendUSART0c(char c)             // ein einzelnes zeichen über die serielle schnittstelle (USART0) senden&lt;br /&gt;
                                     // FJG: Obacht: x12xx : IFG1 =&amp;gt; IFG2 !&lt;br /&gt;
{&lt;br /&gt;
  while (!(IFG1 &amp;amp; UTXIFG0));           // warten, bis USART0 TX-buffer sendebereit&lt;br /&gt;
  TXBUF0 = c;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void SendUSART1c(char c)             // ein einzelnes zeichen über die serielle schnittstelle (USART1) senden&lt;br /&gt;
{&lt;br /&gt;
  while (!(IFG2 &amp;amp; UTXIFG1));           // warten, bis USART1 TX-buffer sendebereit&lt;br /&gt;
  TXBUF1 = c;&lt;br /&gt;
}     &lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Senden eines Strings ==&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
void SendUSART0(char* str)             // einen string über die serielle schnittstelle (USART0) senden&lt;br /&gt;
{&lt;br /&gt;
  while (*str != 0)&lt;br /&gt;
  {&lt;br /&gt;
    while (!(IFG1 &amp;amp; UTXIFG0));         // warten, bis USART0 TX-buffer sendebereit&lt;br /&gt;
    TXBUF0 = *str++;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void SendUSART1(char* str)             // einen string über die serielle schnittstelle (USART1) senden&lt;br /&gt;
{&lt;br /&gt;
  while (*str != 0)&lt;br /&gt;
  {&lt;br /&gt;
    while (!(IFG2 &amp;amp; UTXIFG1));         // warten, bis USART1 TX-buffer sendebereit&lt;br /&gt;
    TXBUF1 = *str++;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Empfangen eines Bytes (interruptgesteuert)  // Receiving a byte-&amp;gt; Interrupt controlled ==&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
/*Hab diese Interrupt Funktion für meine I²C Kommunikation verwendet&lt;br /&gt;
Startcondition wird erkannt, aber nicht Stop, da man die Flanken(die den&lt;br /&gt;
interrupt auslösen) umkehren müsste, aber dann keine Startkondition erkannt werden kann.&lt;br /&gt;
&lt;br /&gt;
Hab mir jetzt nicht die mühe gemacht alles rauszupicken was ihr nicht braucht.&lt;br /&gt;
Wer sich auskennt, kann das auch selber machen.&lt;br /&gt;
&lt;br /&gt;
Das Busy wird fürs stretching verwendet(CLK wird auf low gezogen)&lt;br /&gt;
*/  &lt;br /&gt;
&lt;br /&gt;
#pragma vector = PORT1_VECTOR           // Port 1 - Interrupt-Funktions-&amp;quot;Alias&amp;quot;&lt;br /&gt;
__interrupt void Interrupt_Port1()&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
//  I2CTransfer = 0;&lt;br /&gt;
&lt;br /&gt;
    TACTL |= TACLR;&lt;br /&gt;
    TACTL |= TAIE;&lt;br /&gt;
#ifdef WD&lt;br /&gt;
    WDTCTL = WDTPW + WDTCNTCL;&lt;br /&gt;
#endif&lt;br /&gt;
    &lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
  if ((P1IFG &amp;amp; 0x04) &amp;amp;&amp;amp; !(I2CCLK)) { //if startdataimpuls but clk low is detected --return--&lt;br /&gt;
    P1IFG &amp;amp;= ~0x0C;&lt;br /&gt;
    return;}&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
//    P1IE &amp;amp;= ~0x0C;&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
  if ((P1IFG &amp;amp; 0x04) &amp;amp;&amp;amp; I2CCLK)   //Start Condition       (I2CStart)&lt;br /&gt;
    {&lt;br /&gt;
      P1IFG &amp;amp;= ~0x0C;&lt;br /&gt;
      &lt;br /&gt;
//    I2CTransfer = 1;&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
        P1IE &amp;amp;= ~0x0C;&lt;br /&gt;
//        TACTL |= TACLR;&lt;br /&gt;
//        TACTL |= TAIE;&lt;br /&gt;
//        _EINT();&lt;br /&gt;
&lt;br /&gt;
      &lt;br /&gt;
/*#ifdef Debug&lt;br /&gt;
      P2OUT |= 0x04;&lt;br /&gt;
      P2DIR |= 0x04; &lt;br /&gt;
#endif*/&lt;br /&gt;
      &lt;br /&gt;
//      Wait(10);&lt;br /&gt;
//      while(I2CCLK)  {CheckTimer;}&lt;br /&gt;
&lt;br /&gt;
//      set_Busy;&lt;br /&gt;
  &lt;br /&gt;
      BitCnt = 0x01;&lt;br /&gt;
      ByteCnt = 0;&lt;br /&gt;
//      I2CByte = 0;&lt;br /&gt;
      StartCondition = 1;&lt;br /&gt;
//      CRCByte = 0x00;&lt;br /&gt;
      GetData = 0;&lt;br /&gt;
      I2CTransfer = 0;&lt;br /&gt;
    &lt;br /&gt;
//    clr_Busy;&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
        _DINT();&lt;br /&gt;
        P1IE |= 0x0C;&lt;br /&gt;
&lt;br /&gt;
      return;&lt;br /&gt;
    }&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
  P1IFG &amp;amp;= ~0x0C;&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
    TACTL |= TACLR;&lt;br /&gt;
    _EINT();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
  if (I2CCLK)&lt;br /&gt;
  {&lt;br /&gt;
  &lt;br /&gt;
 &lt;br /&gt;
      TACTL |= TAIE;&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    I2CByte &amp;lt;&amp;lt;= 1; &lt;br /&gt;
    if (I2CDAT){&lt;br /&gt;
      I2CByte += 0x01;&lt;br /&gt;
     }&lt;br /&gt;
    I2CTransfer = 1;&lt;br /&gt;
    while(I2CCLK) {CheckTimer;}&lt;br /&gt;
    set_Busy;&lt;br /&gt;
    BitCnt &amp;lt;&amp;lt;= 1;&lt;br /&gt;
  &lt;br /&gt;
    if(!(BitCnt == 0x00))&lt;br /&gt;
    {&lt;br /&gt;
      clr_Busy;  &lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
      _NOP();&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
  }&lt;br /&gt;
//----------------------------------------------------------------------------  &lt;br /&gt;
&lt;br /&gt;
P1DIR &amp;amp;= ~0x0C;&lt;br /&gt;
P1IFG = 0x00;&lt;br /&gt;
P1IE |= 0x0C;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Ermitteln der Temperatur ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
// von FJG info@aqua-sun.net :&lt;br /&gt;
// ---------------   Temperatur des Chips   ---------------------&lt;br /&gt;
&lt;br /&gt;
#define T_Faktor_a1000       ((long)103)     // REF 1,5V&lt;br /&gt;
#define T_Faktor_b1000       ((long)172)     // REF 2,5V&lt;br /&gt;
#define T_Faktor_c1000       ((long)278000)&lt;br /&gt;
&lt;br /&gt;
int Hole_Temp(void)       // Temperatur ch 10&lt;br /&gt;
{                         // Temp = N* 0,17193 -278  1000Temp = N*172 -278000 bei 2,5V&lt;br /&gt;
  long Temp_L;&lt;br /&gt;
  int  Temp , Delta ;&lt;br /&gt;
&lt;br /&gt;
  Start_AD();&lt;br /&gt;
&lt;br /&gt;
  Temp_L = ((long)ADC12MEM10 * T_Faktor_a1000) - T_Faktor_c1000 ;&lt;br /&gt;
  Temp   = (int)( Temp_L / 1000);&lt;br /&gt;
&lt;br /&gt;
  Delta = Read_EEPROM( EPROM_INTERN_BL1_R_ADR,DELTA_TEMP_ADR );    // falls Temp&lt;br /&gt;
                                                                   // Messung&lt;br /&gt;
  if( Delta &amp;lt;= 120 &amp;amp;&amp;amp; Delta &amp;gt;= 80 ) Delta -= 100 ; else Delta = 0; // ungenau war&lt;br /&gt;
                                                                   // siehe dazu TI&lt;br /&gt;
  return (Temp + Delta);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// INIT AD&lt;br /&gt;
// AD muss angesto�?en werden mit :   Start_AD()&lt;br /&gt;
&lt;br /&gt;
// #define ADC12TL0WERT15           (SHT1_8 + SHT0_3 + MSC + REFON + ADC12ON)&lt;br /&gt;
#define ADC12TL0WERT15           (SHT1_3 + SHT0_3 + MSC + REFON + ADC12ON)&lt;br /&gt;
#define ADC12TL0WERT25           (SHT1_3 + SHT0_3 + MSC + +REF2_5V + REFON + ADC12ON)&lt;br /&gt;
&lt;br /&gt;
//                        Start CH0 , ADC12SCBIT , SampleT , F/2 , MCLK , Sequenze of CH&lt;br /&gt;
#define ADC12CTL1WERT   ( CSTARTADD_0 + SHS_0 + SHP + ADC12DIV_1 + ADC12SSEL_2 + CONSEQ_1 )&lt;br /&gt;
&lt;br /&gt;
void adc12_init()           // ADC12CTL0 modifizieren nur mit ENC = 0&lt;br /&gt;
{&lt;br /&gt;
  ADC12CTL0   = 0x00;&lt;br /&gt;
  ADC12CTL1   = ADC12CTL1WERT ;&lt;br /&gt;
&lt;br /&gt;
  ADC12MCTL0  = INCH_0;                  &lt;br /&gt;
  ADC12MCTL1  = INCH_1;                  &lt;br /&gt;
  ADC12MCTL2  = INCH_2;&lt;br /&gt;
  ADC12MCTL3  = INCH_3;&lt;br /&gt;
  ADC12MCTL4  = INCH_4;&lt;br /&gt;
  ADC12MCTL5  = INCH_5;&lt;br /&gt;
  ADC12MCTL6  = INCH_6;&lt;br /&gt;
  ADC12MCTL7  = INCH_7;                  &lt;br /&gt;
  ADC12MCTL8  = INCH_8;                  // VeREF+&lt;br /&gt;
  ADC12MCTL9  = INCH_9;                  // VeREF-&lt;br /&gt;
&lt;br /&gt;
  ADC12MCTL10 = INCH_10 + SREF_1 ;&lt;br /&gt;
  ADC12MCTL11 = INCH_11 + SREF_1 +EOS;&lt;br /&gt;
&lt;br /&gt;
  ADC12IE     = 0x00;&lt;br /&gt;
  ADC12CTL0   = ADC12TL0WERT15 ;&lt;br /&gt;
  ADC12CTL0  |= 0x0003;      // ENC + ADC12SC = Enable Conversation + StartConversation&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// --------------------   Diverses AD_Wandler   --------------------&lt;br /&gt;
&lt;br /&gt;
void Start_AD(void)&lt;br /&gt;
{&lt;br /&gt;
  ADC12CTL0 &amp;amp;= ~ENC;&lt;br /&gt;
  ADC12CTL0 |= (ADC12SC+ENC);&lt;br /&gt;
  NOP();&lt;br /&gt;
  NOP();&lt;br /&gt;
  ADC12CTL0 &amp;amp;=~ADC12SC;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#ifndef TEST_AD&lt;br /&gt;
#define Ist_AD_Busy()        ( ADC12CTL1 &amp;amp; ADC12BUSY )&lt;br /&gt;
#else&lt;br /&gt;
int Ist_AD_Busy()&lt;br /&gt;
{&lt;br /&gt;
  if (ADC12CTL1 &amp;amp; ADC12BUSY)&lt;br /&gt;
  {&lt;br /&gt;
     printf(&amp;quot;\n\r... BUSY ...&amp;quot;); &lt;br /&gt;
     delay_ms(500);&lt;br /&gt;
     return(1);&lt;br /&gt;
  }&lt;br /&gt;
  return(0);&lt;br /&gt;
}&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Ansteuerung eines LCD &amp;amp;#8211; Zeichendisplays // Controlling the LCD character==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
  // hier nun der vollständige Code 14 Jan 08&lt;br /&gt;
  // von mir seinerseits entwickelt, ich hoffe, er ist eine Hilfe&lt;br /&gt;
 &lt;br /&gt;
  // Aquasun Germany  Remscheid  Franz-Josef Günther&lt;br /&gt;
  // Development info@aqua-sun.net&lt;br /&gt;
&lt;br /&gt;
  // LCD.h Header für Allgemeines zum LCD ab 02.12.04 Aquasun GUE&lt;br /&gt;
  // C-Compiler ICC&lt;br /&gt;
&lt;br /&gt;
  // -------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
  // Beispiel :&lt;br /&gt;
&lt;br /&gt;
int Aepfel = 8;&lt;br /&gt;
&lt;br /&gt;
print_LCD(&amp;quot;\nRotkaepchen hat %d Aepfel im Korb&amp;quot;,Aepfel);&lt;br /&gt;
&lt;br /&gt;
  // -------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;_const.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdarg.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt; STRING.H&amp;gt;&lt;br /&gt;
#include &amp;lt; stdio.h &amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define LCD_MAX          8&lt;br /&gt;
#define Mem_LCD         16&lt;br /&gt;
&lt;br /&gt;
#ifndef Mem_LCD&lt;br /&gt;
#define Mem_LCD 20&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
    Header für 8 x 7 Segmentanzeigen 2 MUX MSP430 x4xx&lt;br /&gt;
&lt;br /&gt;
    V3 = V1 (VDD) , V5 = 0 ,&lt;br /&gt;
&lt;br /&gt;
    für : LCD siehe TI Info dazu,&lt;br /&gt;
    für : LED&#039;s :&lt;br /&gt;
&lt;br /&gt;
    LED mit gemeinsamer Kathode, SP über Buffer 74HC245 (8x) o.ä.&lt;br /&gt;
    /G=L , DIR=H A ==&amp;gt; B an 5V , COM mit Emitterfolger PNP ViL=0,8V ViH=2V&lt;br /&gt;
&lt;br /&gt;
    LED mit gemeinsamer Anode, COM über PNP Transistor invertiert&lt;br /&gt;
    und SP über ULN2804(8x) getrieben&lt;br /&gt;
            _   ___   ___   ___&lt;br /&gt;
    COM0 :   |_|   |_|   |_|&lt;br /&gt;
            ____   ___   ___&lt;br /&gt;
    COM1 :      |_|   |_|   |_|&lt;br /&gt;
             __    __    __&lt;br /&gt;
    SPon :  |  |__|  |__|  |__| mit COM0&lt;br /&gt;
&lt;br /&gt;
    SPin :   0  1  2  3  4  5  6  7    8  9 10 11 12 13 14 15&lt;br /&gt;
    COM0 :  1a 1b 1c 1d 1e 1f 1g 1h   2a 2b 2c 2d 2e 2f 2g 2h&lt;br /&gt;
    COM1 :  5a 5b 5c 5d 5e 5f 5g 5h   6a 6b 6c 6d 6e 6f 6g 6h&lt;br /&gt;
&lt;br /&gt;
    SPin :  16 17 18 19 20 21 22 23   24 25 26 27 28 29 30 31&lt;br /&gt;
    COM0 :  3a 3b 3c 3d 3e 3f 3g 3h   4a 4b 4c 4d 4e 4f 4g 4h&lt;br /&gt;
    COM1 :  7a 7b 7c 7d 7e 7f 7g 7h   8a 8b 8c 8d 8e 8f 8g 8h&lt;br /&gt;
&lt;br /&gt;
    COM        3 2   1  0   3 2   1  0&lt;br /&gt;
    MAP 0A0    - -   8h 4h  - -   8g 4g&lt;br /&gt;
        09F    - -   8f 4f  - -   8e 4e&lt;br /&gt;
        09E    - -   8d 4d  - -   8c 4c&lt;br /&gt;
        09D    - -   8b 4b  - -   8a 4a&lt;br /&gt;
&lt;br /&gt;
        09C    - -   7h 3h  - -   7g 3g&lt;br /&gt;
        09B    - -   7f 3f  - -   7e 3e&lt;br /&gt;
        09A    - -   7d 3d  - -   7c 3c&lt;br /&gt;
        099    - -   7b 3b  - -   7a 3a&lt;br /&gt;
&lt;br /&gt;
        098    - -   6h 2h  - -   6g 2g&lt;br /&gt;
        097    - -   6f 2f  - -   6e 2e&lt;br /&gt;
        096    - -   6d 2d  - -   6c 2c&lt;br /&gt;
        095    - -   6b 2b  - -   6a 2a&lt;br /&gt;
&lt;br /&gt;
        094    - -   5h 1h  - -   5g 1g&lt;br /&gt;
        093    - -   5f 1f  - -   5e 1e&lt;br /&gt;
        092    - -   5d 1d  - -   5c 1c&lt;br /&gt;
        091    - -   5b 1b  - -   5a 1a&lt;br /&gt;
&lt;br /&gt;
             ---a----&lt;br /&gt;
            |        |&lt;br /&gt;
          f |        | b&lt;br /&gt;
            |        |&lt;br /&gt;
             ---g----&lt;br /&gt;
            |        |&lt;br /&gt;
          e |        | c&lt;br /&gt;
            |        |    _&lt;br /&gt;
              ---d---    | | h&lt;br /&gt;
                          -&lt;br /&gt;
&lt;br /&gt;
*/&lt;br /&gt;
#define a0      0x01  // Char durch rechtsschiften &amp;amp; 0x..&lt;br /&gt;
#define b0      0x10&lt;br /&gt;
#define c0      0x02&lt;br /&gt;
#define d0      0x20&lt;br /&gt;
#define e0      0x04&lt;br /&gt;
#define f0      0x40&lt;br /&gt;
#define g0      0x08&lt;br /&gt;
#define h0      0x80&lt;br /&gt;
&lt;br /&gt;
#define ch_0    ( e0+f0+a0+b0+c0+d0 )&lt;br /&gt;
#define ch_1    ( b0+c0 )&lt;br /&gt;
#define ch_2    ( a0+b0+g0+e0+d0 )&lt;br /&gt;
#define ch_3    ( a0+b0+g0+c0+d0 )&lt;br /&gt;
#define ch_4    ( f0+g0+b0+c0 )&lt;br /&gt;
#define ch_5    ( a0+f0+g0+c0+d0 )&lt;br /&gt;
#define ch_6    ( a0+f0+c0+d0+e0+g0 )&lt;br /&gt;
#define ch_7    ( a0+b0+c0 )&lt;br /&gt;
#define ch_8    ( a0+b0+c0+d0+e0+f0+g0 )&lt;br /&gt;
#define ch_9    ( a0+b0+c0+f0+g0 )&lt;br /&gt;
&lt;br /&gt;
#define ch_a    ( a0+b0+c0+d0+e0+g0 )&lt;br /&gt;
#define ch_A    ( e0+f0+a0+b0+c0+g0 )&lt;br /&gt;
#define ch_B    ( a0+b0+c0+d0+e0+f0+g0 )&lt;br /&gt;
#define ch_b    ( f0+e0+d0+c0+g0 )&lt;br /&gt;
#define ch_c    ( g0+e0+d0 )&lt;br /&gt;
#define ch_C    ( a0+f0+e0+d0 )&lt;br /&gt;
#define ch_d    ( b0+c0+d0+e0+g0 )&lt;br /&gt;
#define ch_D    ( e0+f0+a0+b0+c0+d0 )&lt;br /&gt;
#define ch_e    ( f0+e0+d0+a0+b0+g0 )&lt;br /&gt;
#define ch_E    ( a0+f0+g0+d0+e0 )&lt;br /&gt;
#define ch_F    ( a0+f0+g0+e0 )&lt;br /&gt;
#define ch_G    ( a0+f0+c0+d0+e0+g0 )&lt;br /&gt;
#define ch_g    ( a0+b0+c0+d0+f0+g0 )&lt;br /&gt;
#define ch_h    ( f0+c0+e0+g0 )&lt;br /&gt;
#define ch_H    ( f0+c0+e0+g0+b0 )&lt;br /&gt;
#define ch_I    ( f0+e0 )&lt;br /&gt;
#define ch_i    ( e0 )&lt;br /&gt;
#define ch_k    ( b0+e0+f0+g0 )&lt;br /&gt;
#define ch_L    ( f0+e0+d0 )&lt;br /&gt;
#define ch_l    ( b0+c0 )&lt;br /&gt;
#define ch_M    ( c0+b0+e0+f0 )&lt;br /&gt;
&lt;br /&gt;
#define ch_n    ( e0+g0+c0 )&lt;br /&gt;
#define ch_N    ( a0+b0+c0+e0+f0 )&lt;br /&gt;
#define ch_o    ( e0+g0+c0+d0 )&lt;br /&gt;
#define ch_O    ( e0+f0+a0+b0+c0+d0 )&lt;br /&gt;
#define ch_P    ( e0+f0+a0+b0+g0 )&lt;br /&gt;
#define ch_r    ( g0+e0 )&lt;br /&gt;
#define ch_S    ( a0+f0+g0+c0+d0 )&lt;br /&gt;
#define ch_T    ( a0+f0+e0 )&lt;br /&gt;
#define ch_U    ( f0+e0+d0+c0+b0 )&lt;br /&gt;
#define ch_u    ( e0+d0+c0 )&lt;br /&gt;
#define ch_X    ( b0+g0+e0 )&lt;br /&gt;
#define ch_Y    ( f0+g0+b0+c0+d0 )&lt;br /&gt;
#define ch_Z    ( a0+b0+g0+e0+d0 )&lt;br /&gt;
#define ch_Blank  0&lt;br /&gt;
#define Unter_  ( d0 )&lt;br /&gt;
#define DP_Pkt  ( h0 )&lt;br /&gt;
#define Minus   ( g0 )&lt;br /&gt;
#define Tilde   ( a0+g0+d0 )&lt;br /&gt;
#define GLEICH  ( g0+d0 )&lt;br /&gt;
#define FRAGE   ( a0+f0+g0+c0+d0+h0 )&lt;br /&gt;
&lt;br /&gt;
// #define Digi_X1ste         LCDM17       // die erste freie LCD_Mem_Stelle 18,19,20&lt;br /&gt;
                                           // in lcd_init() auf 0&lt;br /&gt;
&lt;br /&gt;
// extern unsigned int Digi_X;             // für LCD&lt;br /&gt;
&lt;br /&gt;
const char  letter[] = &amp;quot;0123456789 _.-~?=AaBbCcDdEeFGgHhIiKkLlMmNnOoPRrSsTtUuxXYyZz&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
const int hex_Wert[] = {&lt;br /&gt;
      ch_0,    ch_1, ch_2, ch_3, ch_4, ch_5, ch_6, ch_7, ch_8, ch_9,&lt;br /&gt;
      ch_Blank, Unter_, DP_Pkt, Minus, Tilde, FRAGE , GLEICH ,&lt;br /&gt;
      ch_A, ch_a, ch_B, ch_b, ch_C, ch_c, ch_D, ch_d, ch_E, ch_e, ch_F, ch_G, ch_g,&lt;br /&gt;
      ch_H, ch_h, ch_I, ch_i, ch_k, ch_k, ch_L, ch_l , ch_M, ch_M, ch_N, ch_n, ch_O, ch_o,&lt;br /&gt;
      ch_P, ch_r, ch_r, ch_S, ch_S, ch_T, ch_T, ch_U, ch_u, ch_X, ch_X,&lt;br /&gt;
      ch_Y, ch_Y, ch_Z , ch_Z  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void All_LCD(void);&lt;br /&gt;
void Clear_LCD_M(void);                     // Clears LCD memory&lt;br /&gt;
void Clear_LCD(void);&lt;br /&gt;
void lcd_init(void); in ini&lt;br /&gt;
void Write_LCD_Hex(int Digit_n , int HEX_Zeichen);&lt;br /&gt;
void SetzeDP( int welches_Displ);&lt;br /&gt;
int putchar_LCD(char);&lt;br /&gt;
int print_LCD(CONST char *fmt, ...)  ;      // LCD 1-7 Digit nur realisiert sonst 1...11&lt;br /&gt;
extern int _print(void (*_put)(char), const char *fmt, va_list va);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    // ----------------------------------------&lt;br /&gt;
&lt;br /&gt;
void Clear_LCD_M(void)&lt;br /&gt;
{&lt;br /&gt;
    int i;&lt;br /&gt;
    for (i =0; i&amp;lt;Mem_LCD; i++) LCDMEM[i] = 0;   // Mem_LCD extern , abhängig vom Display&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
    // ----------------------------------------&lt;br /&gt;
&lt;br /&gt;
void Clear_LCD(void)&lt;br /&gt;
{&lt;br /&gt;
      print_LCD(&amp;quot;\n_&amp;quot;);                     // beim Cursor wird DIGIT_X nicht weitergezählt&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
    // ----------------------------------------&lt;br /&gt;
&lt;br /&gt;
void All_LCD(void)                          // alle = 8888..&lt;br /&gt;
{&lt;br /&gt;
    int i;&lt;br /&gt;
    for (i=0; i&amp;lt;Mem_LCD; i++) LCDMEM[i] = 0xFF;   // Mem_LCD extern , abhängig vom Display&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
    // ----------------------------------------&lt;br /&gt;
&lt;br /&gt;
int putchar_LCD(char c_in)&lt;br /&gt;
{&lt;br /&gt;
                                            //  Digi_X  == LCDM17&lt;br /&gt;
    int i, leng;&lt;br /&gt;
    char c = c_in;&lt;br /&gt;
    leng = strlen(letter);                  // Länge ohne /0 , 1..&lt;br /&gt;
&lt;br /&gt;
      if( (c==&#039;\n&#039;) || (c==&#039;\r&#039;))           // nichts gefunden =&amp;gt; CLR_Displ&lt;br /&gt;
        {&lt;br /&gt;
          Digi_X =1;  Clear_LCD_M(); return c;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    for(i=0;i&amp;lt;leng;i++) { if( c == letter[i] ) break; }        // Char gefunden&lt;br /&gt;
&lt;br /&gt;
    if(i == leng)&lt;br /&gt;
      {&lt;br /&gt;
        for(i=0;i&amp;lt;leng;i++) { if( &#039; &#039; == letter[i] ) break; }  // Char &#039; &#039; als Ersatz&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
    if(i&amp;lt;leng)                              // es gibt &#039;.&#039; als Ersatz&lt;br /&gt;
      {&lt;br /&gt;
        Write_LCD_Hex((int)Digi_X , i);     // Digi beschreiben oder löschen&lt;br /&gt;
                                            // if(Digi_X) Write_LCD_Hex(Digi_X , i);&lt;br /&gt;
        if(C != &#039;_&#039;)Digi_X++;&lt;br /&gt;
        if(Digi_X &amp;gt; LCD_MAX) Digi_X =1;     // if(Digi_X &amp;gt;= Mem_LCD) Digi_X =1;&lt;br /&gt;
      }&lt;br /&gt;
    return c;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
    // ----------------------------------------&lt;br /&gt;
&lt;br /&gt;
int print_LCD(CONST char *fmt, ...)&lt;br /&gt;
{&lt;br /&gt;
    va_list va;&lt;br /&gt;
    int val;&lt;br /&gt;
&lt;br /&gt;
    va_start(va, fmt);&lt;br /&gt;
    val = _print((void (*)(char))putchar_LCD, fmt, va);&lt;br /&gt;
    va_end(va);&lt;br /&gt;
&lt;br /&gt;
    return val;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
   // ----------------------------------------&lt;br /&gt;
&lt;br /&gt;
void lcd_init(void)             // LCD init&lt;br /&gt;
{&lt;br /&gt;
 LCDCTL=0xAD;                   // LCDM567.2,LCDM567.0,LCDM234.1,LCDM234.0,LCDM0&lt;br /&gt;
 LCDM1 =0x00;                   // 0xAD = 101 01 101&lt;br /&gt;
 LCDM2 =0x00;                   // 101 = LCDP2 ,0, LCDP0 =&amp;gt; S0..S31&lt;br /&gt;
 LCDM3 =0x00;                   //  01 = LCDMX1,LCDMX0   =&amp;gt; 2-mux&lt;br /&gt;
 LCDM4 =0x00;                   // 101 = LCDSON,x,LCDON Segments ON ,x,LCD ON&lt;br /&gt;
 LCDM5 =0x00;&lt;br /&gt;
 LCDM6 =0x00; LCDM7 =0x00; LCDM8 =0x00; LCDM9 =0x00; LCDM10 =0x00;LCDM11 =0x00;&lt;br /&gt;
 LCDM12=0x00; LCDM13=0x00; LCDM14=0x00; LCDM15=0x00; LCDM16=0x00; LCDM17=0x00;&lt;br /&gt;
 LCDM18=0x00; LCDM19=0x00; LCDM20=0x00;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
   // ----------------------------------------&lt;br /&gt;
&lt;br /&gt;
void Write_LCD_Hex(int Digit_n , int char_Nr)   // Digit1 bis 4 und 5 bis 8&lt;br /&gt;
{&lt;br /&gt;
  int i ,i_End , ch , Maske_loesch , Maske_setz ;&lt;br /&gt;
&lt;br /&gt;
  if((Digit_n == 0 ) || (Digit_n &amp;gt; LCD_MAX))&lt;br /&gt;
    {&lt;br /&gt;
        Clear_LCD_M(); i=0;&lt;br /&gt;
    }&lt;br /&gt;
   else i= (Digit_n - 1);                   // Startadresse = Digit_n x4 siehe unten&lt;br /&gt;
&lt;br /&gt;
  if(Digit_n &amp;lt; (LCD_MAX/2+1))               // Digit 1 ... 4 , i 0...3&lt;br /&gt;
    {&lt;br /&gt;
        Maske_setz   = 0x0011;&lt;br /&gt;
        Maske_loesch = 0x00FF - Maske_setz ;&lt;br /&gt;
        ch           = hex_Wert[char_Nr];&lt;br /&gt;
    } else                                  // Digit 5 ... 8&lt;br /&gt;
    {&lt;br /&gt;
        Maske_setz   = 0x0022;&lt;br /&gt;
        Maske_loesch = 0x00FF - Maske_setz ;&lt;br /&gt;
        ch           = hex_Wert[char_Nr] &amp;lt;&amp;lt; 1;&lt;br /&gt;
        i           -= (LCD_MAX/2) ;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
  i &amp;lt;&amp;lt;= 2; i_End = i +4;                    // Berechnung der Start- und End -adresse&lt;br /&gt;
&lt;br /&gt;
  for(; i &amp;lt; i_End;i++)&lt;br /&gt;
    {&lt;br /&gt;
       LCDMEM[i] &amp;amp;= Maske_loesch;&lt;br /&gt;
       LCDMEM[i] |= ( ch &amp;amp; Maske_setz );&lt;br /&gt;
       ch &amp;gt;&amp;gt;=1;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
  // -----------------------------------------------&lt;br /&gt;
&lt;br /&gt;
void SetzeDP( int welches_Displ)          // Displ 8 , 7 , 6 ...&lt;br /&gt;
{&lt;br /&gt;
  int i , i1;&lt;br /&gt;
    for (i=0,i1=1;i&amp;lt;8;i++,i1 &amp;lt;&amp;lt;=1)&lt;br /&gt;
      {&lt;br /&gt;
        if(welches_Displ &amp;amp; i1)&lt;br /&gt;
        switch(i)&lt;br /&gt;
         {&lt;br /&gt;
           case 0 : LCDM4  |= 0x10; break;&lt;br /&gt;
           case 1 : LCDM8  |= 0x10; break;&lt;br /&gt;
           case 2 : LCDM12 |= 0x10; break;&lt;br /&gt;
           case 3 : LCDM16 |= 0x10; break;&lt;br /&gt;
           case 4 : LCDM4  |= 0x20; break;&lt;br /&gt;
           case 5 : LCDM8  |= 0x20; break;&lt;br /&gt;
           case 6 : LCDM12 |= 0x20; break;&lt;br /&gt;
           case 7 : LCDM16 |= 0x20; break;&lt;br /&gt;
           default: break;&lt;br /&gt;
         }&lt;br /&gt;
      }  // for&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
  // ------------------  ENDE  ----------------------&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
[[Kategorie:MSP430]]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=MSPGCC&amp;diff=58095</id>
		<title>MSPGCC</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=MSPGCC&amp;diff=58095"/>
		<updated>2011-06-21T22:45:17Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: /* Gentoo Ebuilds */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;MSPGCC ist ein kostenloser, unbeschränkter [[C]]-[[Compiler]] für die [[MSP430]]-[[Mikrocontroller]] von [[TI]]. Die Portierung auf MSP430 wurde von Chris Liechti und Dmitry Diky durchgeführt.&lt;br /&gt;
&lt;br /&gt;
== Dokumentation ==&lt;br /&gt;
&lt;br /&gt;
* [http://mspgcc.sourceforge.net/manual/ MSPGCC Manual]&lt;br /&gt;
* [http://mspgcc.sourceforge.net/faq/ FAQ]&lt;br /&gt;
&lt;br /&gt;
== Beispielprogramme ==&lt;br /&gt;
&lt;br /&gt;
Für MSPGCC sind umfangreiche Beispielprogramme ([[LCD]]-Ansteuerung, TCP/IP, ...) verfügbar, außerdem wurden alle TI-Appnotes (C und Assembler) von Steve Underwood für MSPGCC angepasst.&lt;br /&gt;
&lt;br /&gt;
* [http://mspgcc.cvs.sourceforge.net/mspgcc/examples/ MSPGCC Beispiele &amp;amp; Appnotes]&lt;br /&gt;
&lt;br /&gt;
== Windows-Version ==&lt;br /&gt;
&lt;br /&gt;
* [http://sourceforge.net/project/showfiles.php?group_id=42303&amp;amp;package_id=68584 MSPGCC Komplettpaket]&lt;br /&gt;
* [[MSP430_eclipse_helios_mspgcc4_gdb-proxy|Anleitung mit Eclipse 3.6 Helios via mspgcc4 compilieren und debuggen]] (06/2010)&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/Eclipse_und_MSPGCC_unter_Windows Eclipse und MSPGCC unter Windows] (03/2009)&lt;br /&gt;
&amp;lt;!-- * [http://matthias-hartmann.blogspot.com/ Use Eclipse and mspgcc - the easy way] (Windows 02/2009). (offline) --&amp;gt;&lt;br /&gt;
* [http://www.mikrocontroller.net/Eclipse%20und%20MSPGCC/ ausführliche Anleitung zur Verwendung von Eclipse mit MSPGCC unter Windows] (03/2006)&lt;br /&gt;
&lt;br /&gt;
== Installationsanleitung für Unix/Linux/Cygwin ==&lt;br /&gt;
man kann nach wie vor Schritt für Schritt über die Kommandozeile gehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  $ su&lt;br /&gt;
 &lt;br /&gt;
  $ mkdir /tmp/mspgcc&lt;br /&gt;
  $ cd /tmp/mspgcc&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Oder die Installationsanleitung im MSPGCC-Wiki nutzen:&lt;br /&gt;
[http://sourceforge.net/apps/mediawiki/mspgcc/index.php?title=Linux_installation#Get_the_Sources_and_build_the_Package]&lt;br /&gt;
&lt;br /&gt;
Dabei gibt es zwei Fallstricke:&lt;br /&gt;
&lt;br /&gt;
1.: Das Beispiel geht davon aus, dass GCC 3.4 installiert ist. Diese Version ist relativ alt und behandelt Compilerwarnungen etwas nachsichtiger. Wer eine neuere oder andere Version von GCC installiert hat, muss das im Make-Aufruf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 cvs -d:pserver:anonymous@mspgcc.cvs.sourceforge.net:/cvsroot/mspgcc login&lt;br /&gt;
 cvs -z3 -d:pserver:anonymous@mspgcc.cvs.sourceforge.net:/cvsroot/mspgcc co -P .&lt;br /&gt;
 cd packaging&lt;br /&gt;
 make folders&lt;br /&gt;
 CC=gcc-3.4 make build&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
vorangestellte &amp;quot;CC=gcc-3.4&amp;quot; auf die installierte GCC-Version abändern, z.&amp;amp;nbsp;B. &amp;quot;CC=gcc-4.4&amp;quot;. Tut man das nicht, wird der vorhandene GCC-Compiler nicht gefunden und make liefert Fehler 77 zurück (Compiler kann keine ausführbare Dateien erstellen).&lt;br /&gt;
&lt;br /&gt;
2.: Das verlinkte Package lädt sich (eventuell nur im Moment, 7.2.2010) die binutils-2.18 per Ftp herunter. Einige der Quelldateien produzieren bei GCC Versionen ab 4.X Warnungen, die durch den Compilerschalter -Werror als Fehler behandelt und zum Abbruch des Compiliervorgangs führen.&lt;br /&gt;
Workaround: in der Datei /packaging/build/binutils-2.18/binutils/Makefile die Zeile&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CFLAGS = -g -O2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
auf &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CFLAGS = -g -O2 -Wno-error&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
erweitern.&lt;br /&gt;
&lt;br /&gt;
Oder binutils-2.19 von Hand kompilieren und installieren, auch hier auf passende Angabe der GCC-Version achten.&lt;br /&gt;
[http://sourceforge.net/apps/mediawiki/mspgcc/index.php?title=Building_MSPGCC_from_Source_Code]&lt;br /&gt;
Achtung: in der aktuellen Version heißt die benötigte Datei /package/patches/binutils-2.19.patch irrtümlicherweise binutils-2.19&#039;&#039;&#039;-&#039;&#039;&#039;patch (mit bindestrich statt Punkt).&lt;br /&gt;
&lt;br /&gt;
=== binutils ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  $ wget ftp://sources.redhat.com/pub/binutils/releases/binutils-2.17.tar.bz2&lt;br /&gt;
  $ tar xjvf binutils-2.17.tar.bz2&lt;br /&gt;
 &lt;br /&gt;
  $ cd binutils-2.17&lt;br /&gt;
  $ ./configure --prefix=/usr/local/msp430 --target=msp430&lt;br /&gt;
  $ make&lt;br /&gt;
  $ make install&lt;br /&gt;
  $ cd ..&lt;br /&gt;
 &lt;br /&gt;
  $ export PATH=/usr/local/msp430/bin:$PATH&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hinweis: Das Kommando wget setzt einen Internetzugang voraus.&lt;br /&gt;
&lt;br /&gt;
Hinweis2:&amp;lt;br&amp;gt; Die Version 2.14 enthält nicht alle Controllertypen. So fehlen zum Beispiel die Typen MSP430F1611 und MSP430F1612.&amp;lt;br&amp;gt;&lt;br /&gt;
Bei Version 2.17 kann es zu fehlerhaften binarys kommen (Fehler: test.elf has no bss section)&amp;lt;br&amp;gt;&lt;br /&gt;
Mit der Version 2.16.1 sollte alles funktionieren.&lt;br /&gt;
&lt;br /&gt;
Hinweis3:&amp;lt;br&amp;gt;Ich versuche es mit 2.19.1, wenn ich auf Fehler stosse, dann berichte ich davon..&lt;br /&gt;
&lt;br /&gt;
=== gcc ===&lt;br /&gt;
&#039;&#039;&#039;Achtung:&#039;&#039;&#039; MSPGCC kompiliert nicht gcc-4.1. Abhilfe schafft es zu Beginn (oder vor configure) den Befehl &amp;quot;export CC=gcc-3.3&amp;quot; bzw. &amp;quot;export CC=gcc-3.4&amp;quot; aufzurufen. Auch ist darauf zu achten die Dateien gcc-core-3.2.3 und gcc-g++.tar.bz2 und nicht etwa gcc-3.2.3 runterzuladen. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  $ wget ftp://gcc.gnu.org/pub/gcc/releases/gcc-3.2.3/gcc-core-3.2.3.tar.bz2&lt;br /&gt;
  $ wget ftp://gcc.gnu.org/pub/gcc/releases/gcc-3.2.3/gcc-g++-3.2.3.tar.bz2&lt;br /&gt;
  $ tar xjvf gcc-core-3.2.3.tar.bz2&lt;br /&gt;
  $ tar xjvf gcc-g++-3.2.3.tar.bz2&lt;br /&gt;
&lt;br /&gt;
  $ cvs -d:pserver:anonymous@mspgcc.cvs.sourceforge.net:/cvsroot/mspgcc login&lt;br /&gt;
  $ cvs -z3 -d:pserver:anonymous@mspgcc.cvs.sourceforge.net:/cvsroot/mspgcc co gcc/gcc-3.3&lt;br /&gt;
  $ cp -r gcc/gcc-3.3/* gcc-3.2.3/&lt;br /&gt;
 &lt;br /&gt;
  $ cd gcc-3.2.3&lt;br /&gt;
  $ ./configure --prefix=/usr/local/msp430 --target=msp430 --enable-languages=c,c++&lt;br /&gt;
  $ make&lt;br /&gt;
  $ make install&lt;br /&gt;
  $ cd ..&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== msp430-libc ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  $ cvs -d:pserver:anonymous@mspgcc.cvs.sourceforge.net:/cvsroot/mspgcc login&lt;br /&gt;
  $ cvs -z3 -d:pserver:anonymous@mspgcc.cvs.sourceforge.net:/cvsroot/mspgcc co msp430-libc&lt;br /&gt;
 &lt;br /&gt;
  $ cd msp430-libc/src&lt;br /&gt;
  $ make&lt;br /&gt;
  $ make install&lt;br /&gt;
  $ cd ../..&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== gdb ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  $ wget http://mirrors.redwire.net/pub/sources.redhat.com/gdb/old-releases/gdb-6.0.tar.bz2&lt;br /&gt;
  $ tar xjvf gdb-6.0.tar.bz2&lt;br /&gt;
 &lt;br /&gt;
  $ cvs -d:pserver:anonymous@mspgcc.cvs.sourceforge.net:/cvsroot/mspgcc login&lt;br /&gt;
  $ cvs -z3 -d:pserver:anonymous@mspgcc.cvs.sourceforge.net:/cvsroot/mspgcc co gdb/gdb-current&lt;br /&gt;
  $ cp -r gdb/gdb-current/* gdb-6.0/&lt;br /&gt;
 &lt;br /&gt;
  $ cd gdb-6.0&lt;br /&gt;
  $ ./configure --prefix=/usr/local/msp430 --target=msp430&lt;br /&gt;
  $ make&lt;br /&gt;
  $ make install&lt;br /&gt;
  $ cd ..&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Achtung: Der GDB kann nicht mit GCC 4.x übersetzt werden. Wenn dieser auf dem System standardmäßig installiert ist, kann man z.&amp;amp;nbsp;B. den GCC 3.4 zusätzlich installieren und dann vor der ./configure- Zeile&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  $ export CC=gcc-3.4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
einfügen.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Bei Ubuntu (evtl auch bei anderen Distributionen) sind die Entwicklerdateien für die Library libtermcap im Paket libncurses5-dev&lt;br /&gt;
&lt;br /&gt;
=== JTAG ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  $ cvs -d:pserver:anonymous@mspgcc.cvs.sourceforge.net:/cvsroot/mspgcc login&lt;br /&gt;
  $ cvs -z3 -d:pserver:anonymous@mspgcc.cvs.sourceforge.net:/cvsroot/mspgcc co jtag&lt;br /&gt;
 &lt;br /&gt;
  $ cd jtag/hardware_access&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wer ein 64-Bit-Linux verwendet, muss im makefile die CFLAGS und die LNOPTS um ein -m32 ergänzen. Das sollte dann so aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    CFLAGS  += -fPIC -m32&lt;br /&gt;
    LNOPTS   = -fPIC -shared -m32&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Weiter geht&#039;s:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  $ make&lt;br /&gt;
  $ mv libHIL.so /usr/local/lib&lt;br /&gt;
  $ ldconfig&lt;br /&gt;
  $ cd ../..&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== gdbproxy ===&lt;br /&gt;
&lt;br /&gt;
Den msp430-gdbproxy und libMSP430.so von http://www.soft-switch.org/downloads/mspgcc herunterladen. Danach&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  $ chmod +x msp430-gdbproxy&lt;br /&gt;
  $ mv msp430-gdbproxy /usr/local/msp430/bin/&lt;br /&gt;
  $ mv libMSP430.so /usr/local/lib/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ausführen.&lt;br /&gt;
&lt;br /&gt;
=== Installations-Skript ===&lt;br /&gt;
&lt;br /&gt;
Für Installation/Update gibt es hier ein bash-Skript, das nach dem Starten (und einmal Return zum Downloaden der Sourcen aus dem CVS) das Installieren automatisch erledigt.&lt;br /&gt;
&lt;br /&gt;
Eingebaut sind auch die Anpassungen von ~/.profile und ~/.gdbinit, so dass man sofort loslegen und auch debuggen kann.&lt;br /&gt;
&lt;br /&gt;
* [http://www.true-random.com/files/mspgcc/build_mspgcc.sh Installations-Skript]&lt;br /&gt;
&lt;br /&gt;
Dieses Script ist jedoch relativ veraltet. Daher ist es schneller obige Anleitung per Copy&#039;n&#039;Paste in eine Shell zu übernehmen, als das Script zu verwenden. &lt;br /&gt;
&lt;br /&gt;
=== Gentoo Ebuilds ===&lt;br /&gt;
&lt;br /&gt;
Für Gentoo-Benutzer gibt es an der [http://pi4.informatik.uni-mannheim.de/pi4.data/content/projects/msp430/ Uni Mannheim] Ebuilds zum Download.&lt;br /&gt;
&lt;br /&gt;
Diese Ebuilds haben bei mir aufgrund von Datei Kollisionen nicht funktioniert.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 * Detected file collision(s):&lt;br /&gt;
 * &lt;br /&gt;
 *      /usr/share/info/standards.info.bz2&lt;br /&gt;
 *      /usr/share/locale/de/LC_MESSAGES/opcodes.mo&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Anleitung von diesem [https://github.com/radhermit/msp430-overlay Overlay] hat es dann funktioniert.&lt;br /&gt;
&lt;br /&gt;
=== .gdbinit ===&lt;br /&gt;
&lt;br /&gt;
Um das JTAG-Interface schneller zu machen kann man in ~/.gdbinit diese Werte eintragen:&lt;br /&gt;
&lt;br /&gt;
 set remoteaddresssize 16&lt;br /&gt;
 set remotetimeout 999999&lt;br /&gt;
 set download-write-size 512&lt;br /&gt;
 target remote localhost:2000&lt;br /&gt;
 set remote memory-write-packet-size 512&lt;br /&gt;
 set remote memory-write-packet-size fixed&lt;br /&gt;
 set remote memory-read-packet-size 512&lt;br /&gt;
 set remote memory-read-packet-size fixed&lt;br /&gt;
&lt;br /&gt;
Und vor dem Debuggen von Programmen auf dem Rechner (nicht MSP430) sollte man ~/.gdbinit umbenennen, beispielsweise in ~/.gdbinit_msp430.&lt;br /&gt;
&lt;br /&gt;
== Mac OS X ==&lt;br /&gt;
&lt;br /&gt;
Um msp430-gcc unter Mac OS X (Intel) kompilieren zu können, &lt;br /&gt;
gcc-3.2.3/gcc/config.gcc wie folgt aendern:&lt;br /&gt;
&lt;br /&gt;
Von&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 i[34567]86-*-freebsd[12] | i[34567]86-*-freebsd[12].* | i[34567]86-*-freebsd*aout* )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
auf:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 i[34567]86-*-freebsd[12] | i[34567]86-*-freebsd[12].* | i[34567]86-*-freebsd*aout* | i[34567]86-apple-darwin8* )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ansonsten die Anleitung für Linux befolgen.&lt;br /&gt;
&lt;br /&gt;
== Einfaches Beispielprogramm ==&lt;br /&gt;
&lt;br /&gt;
=== Sourcecode ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
 #include &amp;lt;io.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 void wait(void);         /* prototype for wait()      */&lt;br /&gt;
&lt;br /&gt;
 int&lt;br /&gt;
 main(void)&lt;br /&gt;
 { /* main function, called by startup-code */&lt;br /&gt;
   P1DIR = 0xFF;          /* port 1 = output           */&lt;br /&gt;
   P1OUT = 0x01;          /* set bit 0 in port 1       */&lt;br /&gt;
&lt;br /&gt;
   for(;;)&lt;br /&gt;
   { /* infinite loop */&lt;br /&gt;
     P1OUT = ~P1OUT;      /* invert port 1             */&lt;br /&gt;
     wait();              /* call delay function       */&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 void&lt;br /&gt;
 wait(void)&lt;br /&gt;
 { /* simple delay function */&lt;br /&gt;
   volatile int i;        /* declare i as volatile int */&lt;br /&gt;
   for(i = 0; i &amp;lt; 32000; i++)&lt;br /&gt;
   ;                      /* repeat 32000 times (nop)  */&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sourcecode für msp430x1121 kompilieren ===&lt;br /&gt;
&lt;br /&gt;
  $ msp430-gcc -Os -mmcu=msp430x1121 -o test.elf test.c&lt;br /&gt;
&lt;br /&gt;
=== Sourcecode für msp430x1121 kompilieren, wenn math.h includiert wird ===&lt;br /&gt;
&lt;br /&gt;
  msp430-gcc -Os -mmcu=msp430x1121 -o test.elf test.c -lm&lt;br /&gt;
&lt;br /&gt;
Wichtig ist hierbei -lm als letzte Option.&lt;br /&gt;
&lt;br /&gt;
=== Assemblerlisting erzeugen (optional) ===&lt;br /&gt;
&lt;br /&gt;
  $ msp430-objdump -DS test.elf &amp;gt; test.lst&lt;br /&gt;
&lt;br /&gt;
=== Hex-Datei erzeugen ===&lt;br /&gt;
&lt;br /&gt;
  $ msp430-objcopy -O ihex test.elf test.hex&lt;br /&gt;
&lt;br /&gt;
Die Hex-Datei kann man mit C-Spy (im Kickstart-Paket enthalten) über das JTAG-Interface in den Controller programmieren. Nach einem Klick auf &amp;quot;Go&amp;quot; läuft das Programm los. Wenn 2 LEDs an P1.0 und P1.1 angeschlossen sind, sollten sie nun blinken.&lt;br /&gt;
&lt;br /&gt;
== In-System-Debugging mit GDB/Insight und dem Flash Emulation Tool (FET) ==&lt;br /&gt;
&lt;br /&gt;
Wie bei anderen MSP430-Compilern ist es möglich mspgcc-Programme direkt in der Schaltung zu debuggen. Alles was man dazu braucht, ist ein JTAG-Adapter, mdp430-gdbproxy, und gdb (im aktuellen Windows-Paket bereits enthalten).&lt;br /&gt;
&lt;br /&gt;
Um ein Programm mit GDB/Insight debuggen zu können, muss man die Option &amp;quot;-g&amp;quot; an den mspgcc-Aufruf anhängen:&lt;br /&gt;
&lt;br /&gt;
  $ msp430-gcc -mmcu=msp430x123 -g -Os -o test.elf test.c&lt;br /&gt;
&lt;br /&gt;
Damit erhält man die Datei &amp;quot;test.elf&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== gdbproxy starten ===&lt;br /&gt;
&lt;br /&gt;
Der nächste Schritt ist das Programm gdbproxy zu starten, das für die Kommunikation zwischen GDB und dem FET zuständig ist:&lt;br /&gt;
&lt;br /&gt;
  $ msp430-gdbproxy --port=2000 msp430&lt;br /&gt;
&lt;br /&gt;
Wenn das FET richtig an den Parallelport angeschlossen ist, sollte ungefähr der folgende Text angezeigt werden:&lt;br /&gt;
&lt;br /&gt;
 info:      msp430: Target device is a &#039;MSP430F12x&#039; (type 11)&lt;br /&gt;
 notice:    msp430-gdbproxy: waiting on TCP port 2000&lt;br /&gt;
&lt;br /&gt;
Hinweis: Falls /dev/parport0 nicht existiert, was sich so äußert:&lt;br /&gt;
 open: No such file or directory&lt;br /&gt;
 error:     msp430: Could not initialize device interface (1)&lt;br /&gt;
...als root ...&lt;br /&gt;
 mknod /dev/parport0 c 99 0 &lt;br /&gt;
...eingeben.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Bei udev im neuen Linuxkernel ab 2.6.x wird das Device /dev/parport0 nicht automatisch angelegt und man muss jedesmal neu den Aufruf mit mknod machen. Abhilfe schafft hier der Eintrag in der /etc/modules:&lt;br /&gt;
ppdev&lt;br /&gt;
&lt;br /&gt;
Beim nächsten Booten dürfte der RAW-Parallelport vorhanden sein.&lt;br /&gt;
&lt;br /&gt;
=== Insight benutzen (Windows) ===&lt;br /&gt;
&lt;br /&gt;
Nachdem Insight gestartet ist (c:\msp430\bin\msp430-gdb.exe), klicke auf &amp;quot;File-&amp;gt;Open&amp;quot; und wähle die elf-Datei (z.&amp;amp;nbsp;B. &amp;quot;test.elf&amp;quot;) aus, die du debuggen möchtest.&lt;br /&gt;
&lt;br /&gt;
Klicke dann auf &amp;quot;Run-&amp;gt;Connect to target&amp;quot; und stelle folgendes ein:&lt;br /&gt;
&lt;br /&gt;
  Target:                    &amp;quot;Remote/TCP&amp;quot;&lt;br /&gt;
  Hostname:                  &amp;quot;localhost&amp;quot;&lt;br /&gt;
  Port:                      &amp;quot;2000&amp;quot;&lt;br /&gt;
  Set breakpoint at &#039;main&#039;:  yes&lt;br /&gt;
  Set breakpoint at &#039;exit&#039;:  yes&lt;br /&gt;
  Attach to target:          yes&lt;br /&gt;
  Download Program:          yes&lt;br /&gt;
  Command  after attaching:  &amp;quot;monitor erase all&amp;quot; (ACHTUNG: Optional, damit wird der gesamte Flash-Inhalt gelöscht!)&lt;br /&gt;
  Run Method:                Continue from last Stop&lt;br /&gt;
&lt;br /&gt;
Wenn man auf &amp;quot;Ok&amp;quot; klickt, sollte Insight berichten, dass die Verbindung erfolgreich aufgenommen wurde, und gdbproxy sollte melden:&lt;br /&gt;
&lt;br /&gt;
  &amp;quot;notice: msp430-gdbproxy: connected&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Um den Debugging-Vorgang zu starten, klicke auf &amp;quot;Run&amp;quot; oder drücke einfach die Taste &amp;quot;r&amp;quot;. Wenn alles geklappt hat, sollte nun der Sourcecode des Programmes angezeigt werden und die erste Zeile von main() grün markiert sein. Der rote Punkt ist der Breakpoint, der von Insight automatisch gesetzt wurde. Um selber Breakpoints zu setzen oder zu löschen, klicke auf den Strich &#039;-&#039; am Anfang der Zeile.&lt;br /&gt;
&lt;br /&gt;
Jetzt kann man mit &#039;c&#039; (continue) das Programm am nächsten Breakpoint fortsetzen, die Zeilen mit &#039;s&#039; (step) der Reihe nach ausführen, oder einzelne Assemblerbefehle ausführen... aber Vorsicht mit &amp;quot;finish&amp;quot;: Anscheinend hängt sich Insight manchmal bei diesem Befehl auf. Wenn man also eine Funktion beenden will, ist es wohl besser, einen Breakpoint auf das Ende der Funktion zu setzen und &amp;quot;continue&amp;quot; zu verwenden.&lt;br /&gt;
&lt;br /&gt;
=== DDD benutzen (Unix/Linux) ===&lt;br /&gt;
&lt;br /&gt;
Leider läuft Insight nicht besonders stabil und ist auch etwas umständlich zu bedienen. Wer Unix bzw. Linux verwendet, der ist deshalb mit DDD (http://www.gnu.org/software/ddd/) besser bedient. Um DDD zu verwenden braucht man msp430-gdbproxy und die Kommandozeilen-Version von GDB (msp430-gdb).&lt;br /&gt;
&lt;br /&gt;
Zuerst stellt man wie unter Windows über gdbproxy eine Verbindung zum JTAG-Adapter her. Wenn das funktioniert hat, kann man DDD starten. Als Parameter wird der zu verwendende Debugger (msp430-gdb) und die zu ladende ELF-Datei (test.elf) übergeben:&lt;br /&gt;
&lt;br /&gt;
  $ ddd --debugger msp430-gdb test.elf&lt;br /&gt;
&lt;br /&gt;
Zunächst sollte man nun unter &amp;quot;Commands / Edit Buttons&amp;quot; ein paar Buttons anlegen, indem man die folgenden Zeilen in das Textfeld bei &amp;quot;Console Buttons&amp;quot; einfügt:&lt;br /&gt;
&lt;br /&gt;
  target remote localhost:2000     // Connect&lt;br /&gt;
  monitor erase all                // Erase&lt;br /&gt;
  load                             // Load&lt;br /&gt;
  monitor reset                    // Reset&lt;br /&gt;
&lt;br /&gt;
Um jetzt die Verbindung zum gdbproxy herzustellen muss man nur auf &amp;quot;Connect&amp;quot; klicken, danach auf &amp;quot;Erase&amp;quot; um den Flash-Speicher des Controllers zu löschen, und schließlich auf &amp;quot;Load&amp;quot;, damit das Programm in den Controller geladen wird. Mit &amp;quot;Reset&amp;quot; kann man einen Reset auslösen (wer hätte das gedacht?).&lt;br /&gt;
&lt;br /&gt;
Wichtig: Nachdem einige breakpoints gesetzt sind, das Programm nicht mit &amp;quot;run&amp;quot; ausführen! Dass &amp;quot;run&amp;quot; Kommando wird benutzt um Programme auf dem lokalen Rechner zu starten. Für eingebettete Systeme ist das korrekte Kommando &amp;quot;continue&amp;quot; (siehe http://mspgcc.sourceforge.net/manual/x1602.html).&lt;br /&gt;
&lt;br /&gt;
=== GDB Scripts ===&lt;br /&gt;
&lt;br /&gt;
Hier eine kleine Ansammlung von Scripts, um download und reset via GDB etwas zu vereinfachen:&lt;br /&gt;
&lt;br /&gt;
[[Media:Gdb_scripts_win.zip]]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:MSP430]]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=MSPGCC&amp;diff=58094</id>
		<title>MSPGCC</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=MSPGCC&amp;diff=58094"/>
		<updated>2011-06-21T22:28:26Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: /* Gentoo Ebuilds */  Ergänzung für Overlay&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;MSPGCC ist ein kostenloser, unbeschränkter [[C]]-[[Compiler]] für die [[MSP430]]-[[Mikrocontroller]] von [[TI]]. Die Portierung auf MSP430 wurde von Chris Liechti und Dmitry Diky durchgeführt.&lt;br /&gt;
&lt;br /&gt;
== Dokumentation ==&lt;br /&gt;
&lt;br /&gt;
* [http://mspgcc.sourceforge.net/manual/ MSPGCC Manual]&lt;br /&gt;
* [http://mspgcc.sourceforge.net/faq/ FAQ]&lt;br /&gt;
&lt;br /&gt;
== Beispielprogramme ==&lt;br /&gt;
&lt;br /&gt;
Für MSPGCC sind umfangreiche Beispielprogramme ([[LCD]]-Ansteuerung, TCP/IP, ...) verfügbar, außerdem wurden alle TI-Appnotes (C und Assembler) von Steve Underwood für MSPGCC angepasst.&lt;br /&gt;
&lt;br /&gt;
* [http://mspgcc.cvs.sourceforge.net/mspgcc/examples/ MSPGCC Beispiele &amp;amp; Appnotes]&lt;br /&gt;
&lt;br /&gt;
== Windows-Version ==&lt;br /&gt;
&lt;br /&gt;
* [http://sourceforge.net/project/showfiles.php?group_id=42303&amp;amp;package_id=68584 MSPGCC Komplettpaket]&lt;br /&gt;
* [[MSP430_eclipse_helios_mspgcc4_gdb-proxy|Anleitung mit Eclipse 3.6 Helios via mspgcc4 compilieren und debuggen]] (06/2010)&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/Eclipse_und_MSPGCC_unter_Windows Eclipse und MSPGCC unter Windows] (03/2009)&lt;br /&gt;
&amp;lt;!-- * [http://matthias-hartmann.blogspot.com/ Use Eclipse and mspgcc - the easy way] (Windows 02/2009). (offline) --&amp;gt;&lt;br /&gt;
* [http://www.mikrocontroller.net/Eclipse%20und%20MSPGCC/ ausführliche Anleitung zur Verwendung von Eclipse mit MSPGCC unter Windows] (03/2006)&lt;br /&gt;
&lt;br /&gt;
== Installationsanleitung für Unix/Linux/Cygwin ==&lt;br /&gt;
man kann nach wie vor Schritt für Schritt über die Kommandozeile gehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  $ su&lt;br /&gt;
 &lt;br /&gt;
  $ mkdir /tmp/mspgcc&lt;br /&gt;
  $ cd /tmp/mspgcc&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Oder die Installationsanleitung im MSPGCC-Wiki nutzen:&lt;br /&gt;
[http://sourceforge.net/apps/mediawiki/mspgcc/index.php?title=Linux_installation#Get_the_Sources_and_build_the_Package]&lt;br /&gt;
&lt;br /&gt;
Dabei gibt es zwei Fallstricke:&lt;br /&gt;
&lt;br /&gt;
1.: Das Beispiel geht davon aus, dass GCC 3.4 installiert ist. Diese Version ist relativ alt und behandelt Compilerwarnungen etwas nachsichtiger. Wer eine neuere oder andere Version von GCC installiert hat, muss das im Make-Aufruf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 cvs -d:pserver:anonymous@mspgcc.cvs.sourceforge.net:/cvsroot/mspgcc login&lt;br /&gt;
 cvs -z3 -d:pserver:anonymous@mspgcc.cvs.sourceforge.net:/cvsroot/mspgcc co -P .&lt;br /&gt;
 cd packaging&lt;br /&gt;
 make folders&lt;br /&gt;
 CC=gcc-3.4 make build&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
vorangestellte &amp;quot;CC=gcc-3.4&amp;quot; auf die installierte GCC-Version abändern, z.&amp;amp;nbsp;B. &amp;quot;CC=gcc-4.4&amp;quot;. Tut man das nicht, wird der vorhandene GCC-Compiler nicht gefunden und make liefert Fehler 77 zurück (Compiler kann keine ausführbare Dateien erstellen).&lt;br /&gt;
&lt;br /&gt;
2.: Das verlinkte Package lädt sich (eventuell nur im Moment, 7.2.2010) die binutils-2.18 per Ftp herunter. Einige der Quelldateien produzieren bei GCC Versionen ab 4.X Warnungen, die durch den Compilerschalter -Werror als Fehler behandelt und zum Abbruch des Compiliervorgangs führen.&lt;br /&gt;
Workaround: in der Datei /packaging/build/binutils-2.18/binutils/Makefile die Zeile&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CFLAGS = -g -O2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
auf &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CFLAGS = -g -O2 -Wno-error&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
erweitern.&lt;br /&gt;
&lt;br /&gt;
Oder binutils-2.19 von Hand kompilieren und installieren, auch hier auf passende Angabe der GCC-Version achten.&lt;br /&gt;
[http://sourceforge.net/apps/mediawiki/mspgcc/index.php?title=Building_MSPGCC_from_Source_Code]&lt;br /&gt;
Achtung: in der aktuellen Version heißt die benötigte Datei /package/patches/binutils-2.19.patch irrtümlicherweise binutils-2.19&#039;&#039;&#039;-&#039;&#039;&#039;patch (mit bindestrich statt Punkt).&lt;br /&gt;
&lt;br /&gt;
=== binutils ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  $ wget ftp://sources.redhat.com/pub/binutils/releases/binutils-2.17.tar.bz2&lt;br /&gt;
  $ tar xjvf binutils-2.17.tar.bz2&lt;br /&gt;
 &lt;br /&gt;
  $ cd binutils-2.17&lt;br /&gt;
  $ ./configure --prefix=/usr/local/msp430 --target=msp430&lt;br /&gt;
  $ make&lt;br /&gt;
  $ make install&lt;br /&gt;
  $ cd ..&lt;br /&gt;
 &lt;br /&gt;
  $ export PATH=/usr/local/msp430/bin:$PATH&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hinweis: Das Kommando wget setzt einen Internetzugang voraus.&lt;br /&gt;
&lt;br /&gt;
Hinweis2:&amp;lt;br&amp;gt; Die Version 2.14 enthält nicht alle Controllertypen. So fehlen zum Beispiel die Typen MSP430F1611 und MSP430F1612.&amp;lt;br&amp;gt;&lt;br /&gt;
Bei Version 2.17 kann es zu fehlerhaften binarys kommen (Fehler: test.elf has no bss section)&amp;lt;br&amp;gt;&lt;br /&gt;
Mit der Version 2.16.1 sollte alles funktionieren.&lt;br /&gt;
&lt;br /&gt;
Hinweis3:&amp;lt;br&amp;gt;Ich versuche es mit 2.19.1, wenn ich auf Fehler stosse, dann berichte ich davon..&lt;br /&gt;
&lt;br /&gt;
=== gcc ===&lt;br /&gt;
&#039;&#039;&#039;Achtung:&#039;&#039;&#039; MSPGCC kompiliert nicht gcc-4.1. Abhilfe schafft es zu Beginn (oder vor configure) den Befehl &amp;quot;export CC=gcc-3.3&amp;quot; bzw. &amp;quot;export CC=gcc-3.4&amp;quot; aufzurufen. Auch ist darauf zu achten die Dateien gcc-core-3.2.3 und gcc-g++.tar.bz2 und nicht etwa gcc-3.2.3 runterzuladen. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  $ wget ftp://gcc.gnu.org/pub/gcc/releases/gcc-3.2.3/gcc-core-3.2.3.tar.bz2&lt;br /&gt;
  $ wget ftp://gcc.gnu.org/pub/gcc/releases/gcc-3.2.3/gcc-g++-3.2.3.tar.bz2&lt;br /&gt;
  $ tar xjvf gcc-core-3.2.3.tar.bz2&lt;br /&gt;
  $ tar xjvf gcc-g++-3.2.3.tar.bz2&lt;br /&gt;
&lt;br /&gt;
  $ cvs -d:pserver:anonymous@mspgcc.cvs.sourceforge.net:/cvsroot/mspgcc login&lt;br /&gt;
  $ cvs -z3 -d:pserver:anonymous@mspgcc.cvs.sourceforge.net:/cvsroot/mspgcc co gcc/gcc-3.3&lt;br /&gt;
  $ cp -r gcc/gcc-3.3/* gcc-3.2.3/&lt;br /&gt;
 &lt;br /&gt;
  $ cd gcc-3.2.3&lt;br /&gt;
  $ ./configure --prefix=/usr/local/msp430 --target=msp430 --enable-languages=c,c++&lt;br /&gt;
  $ make&lt;br /&gt;
  $ make install&lt;br /&gt;
  $ cd ..&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== msp430-libc ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  $ cvs -d:pserver:anonymous@mspgcc.cvs.sourceforge.net:/cvsroot/mspgcc login&lt;br /&gt;
  $ cvs -z3 -d:pserver:anonymous@mspgcc.cvs.sourceforge.net:/cvsroot/mspgcc co msp430-libc&lt;br /&gt;
 &lt;br /&gt;
  $ cd msp430-libc/src&lt;br /&gt;
  $ make&lt;br /&gt;
  $ make install&lt;br /&gt;
  $ cd ../..&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== gdb ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  $ wget http://mirrors.redwire.net/pub/sources.redhat.com/gdb/old-releases/gdb-6.0.tar.bz2&lt;br /&gt;
  $ tar xjvf gdb-6.0.tar.bz2&lt;br /&gt;
 &lt;br /&gt;
  $ cvs -d:pserver:anonymous@mspgcc.cvs.sourceforge.net:/cvsroot/mspgcc login&lt;br /&gt;
  $ cvs -z3 -d:pserver:anonymous@mspgcc.cvs.sourceforge.net:/cvsroot/mspgcc co gdb/gdb-current&lt;br /&gt;
  $ cp -r gdb/gdb-current/* gdb-6.0/&lt;br /&gt;
 &lt;br /&gt;
  $ cd gdb-6.0&lt;br /&gt;
  $ ./configure --prefix=/usr/local/msp430 --target=msp430&lt;br /&gt;
  $ make&lt;br /&gt;
  $ make install&lt;br /&gt;
  $ cd ..&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Achtung: Der GDB kann nicht mit GCC 4.x übersetzt werden. Wenn dieser auf dem System standardmäßig installiert ist, kann man z.&amp;amp;nbsp;B. den GCC 3.4 zusätzlich installieren und dann vor der ./configure- Zeile&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  $ export CC=gcc-3.4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
einfügen.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Bei Ubuntu (evtl auch bei anderen Distributionen) sind die Entwicklerdateien für die Library libtermcap im Paket libncurses5-dev&lt;br /&gt;
&lt;br /&gt;
=== JTAG ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  $ cvs -d:pserver:anonymous@mspgcc.cvs.sourceforge.net:/cvsroot/mspgcc login&lt;br /&gt;
  $ cvs -z3 -d:pserver:anonymous@mspgcc.cvs.sourceforge.net:/cvsroot/mspgcc co jtag&lt;br /&gt;
 &lt;br /&gt;
  $ cd jtag/hardware_access&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wer ein 64-Bit-Linux verwendet, muss im makefile die CFLAGS und die LNOPTS um ein -m32 ergänzen. Das sollte dann so aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    CFLAGS  += -fPIC -m32&lt;br /&gt;
    LNOPTS   = -fPIC -shared -m32&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Weiter geht&#039;s:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  $ make&lt;br /&gt;
  $ mv libHIL.so /usr/local/lib&lt;br /&gt;
  $ ldconfig&lt;br /&gt;
  $ cd ../..&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== gdbproxy ===&lt;br /&gt;
&lt;br /&gt;
Den msp430-gdbproxy und libMSP430.so von http://www.soft-switch.org/downloads/mspgcc herunterladen. Danach&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  $ chmod +x msp430-gdbproxy&lt;br /&gt;
  $ mv msp430-gdbproxy /usr/local/msp430/bin/&lt;br /&gt;
  $ mv libMSP430.so /usr/local/lib/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ausführen.&lt;br /&gt;
&lt;br /&gt;
=== Installations-Skript ===&lt;br /&gt;
&lt;br /&gt;
Für Installation/Update gibt es hier ein bash-Skript, das nach dem Starten (und einmal Return zum Downloaden der Sourcen aus dem CVS) das Installieren automatisch erledigt.&lt;br /&gt;
&lt;br /&gt;
Eingebaut sind auch die Anpassungen von ~/.profile und ~/.gdbinit, so dass man sofort loslegen und auch debuggen kann.&lt;br /&gt;
&lt;br /&gt;
* [http://www.true-random.com/files/mspgcc/build_mspgcc.sh Installations-Skript]&lt;br /&gt;
&lt;br /&gt;
Dieses Script ist jedoch relativ veraltet. Daher ist es schneller obige Anleitung per Copy&#039;n&#039;Paste in eine Shell zu übernehmen, als das Script zu verwenden. &lt;br /&gt;
&lt;br /&gt;
=== Gentoo Ebuilds ===&lt;br /&gt;
&lt;br /&gt;
Für Gentoo-Benutzer gibt es an der [http://pi4.informatik.uni-mannheim.de/pi4.data/content/projects/msp430/ Uni Mannheim] Ebuilds zum Download.&lt;br /&gt;
&lt;br /&gt;
Diese Ebuilds haben bei mir aufgrund von Datei Kollisionen nicht funktioniert.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 * Detected file collision(s):&lt;br /&gt;
 * &lt;br /&gt;
 *      /usr/share/info/standards.info.bz2&lt;br /&gt;
 *      /usr/share/locale/de/LC_MESSAGES/opcodes.mo&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Anleitung von diesem [https://github.com/radhermit/msp430-overlay#readme Overlay] hat es dann funktioniert.&lt;br /&gt;
&lt;br /&gt;
=== .gdbinit ===&lt;br /&gt;
&lt;br /&gt;
Um das JTAG-Interface schneller zu machen kann man in ~/.gdbinit diese Werte eintragen:&lt;br /&gt;
&lt;br /&gt;
 set remoteaddresssize 16&lt;br /&gt;
 set remotetimeout 999999&lt;br /&gt;
 set download-write-size 512&lt;br /&gt;
 target remote localhost:2000&lt;br /&gt;
 set remote memory-write-packet-size 512&lt;br /&gt;
 set remote memory-write-packet-size fixed&lt;br /&gt;
 set remote memory-read-packet-size 512&lt;br /&gt;
 set remote memory-read-packet-size fixed&lt;br /&gt;
&lt;br /&gt;
Und vor dem Debuggen von Programmen auf dem Rechner (nicht MSP430) sollte man ~/.gdbinit umbenennen, beispielsweise in ~/.gdbinit_msp430.&lt;br /&gt;
&lt;br /&gt;
== Mac OS X ==&lt;br /&gt;
&lt;br /&gt;
Um msp430-gcc unter Mac OS X (Intel) kompilieren zu können, &lt;br /&gt;
gcc-3.2.3/gcc/config.gcc wie folgt aendern:&lt;br /&gt;
&lt;br /&gt;
Von&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 i[34567]86-*-freebsd[12] | i[34567]86-*-freebsd[12].* | i[34567]86-*-freebsd*aout* )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
auf:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 i[34567]86-*-freebsd[12] | i[34567]86-*-freebsd[12].* | i[34567]86-*-freebsd*aout* | i[34567]86-apple-darwin8* )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ansonsten die Anleitung für Linux befolgen.&lt;br /&gt;
&lt;br /&gt;
== Einfaches Beispielprogramm ==&lt;br /&gt;
&lt;br /&gt;
=== Sourcecode ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
 #include &amp;lt;io.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 void wait(void);         /* prototype for wait()      */&lt;br /&gt;
&lt;br /&gt;
 int&lt;br /&gt;
 main(void)&lt;br /&gt;
 { /* main function, called by startup-code */&lt;br /&gt;
   P1DIR = 0xFF;          /* port 1 = output           */&lt;br /&gt;
   P1OUT = 0x01;          /* set bit 0 in port 1       */&lt;br /&gt;
&lt;br /&gt;
   for(;;)&lt;br /&gt;
   { /* infinite loop */&lt;br /&gt;
     P1OUT = ~P1OUT;      /* invert port 1             */&lt;br /&gt;
     wait();              /* call delay function       */&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 void&lt;br /&gt;
 wait(void)&lt;br /&gt;
 { /* simple delay function */&lt;br /&gt;
   volatile int i;        /* declare i as volatile int */&lt;br /&gt;
   for(i = 0; i &amp;lt; 32000; i++)&lt;br /&gt;
   ;                      /* repeat 32000 times (nop)  */&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sourcecode für msp430x1121 kompilieren ===&lt;br /&gt;
&lt;br /&gt;
  $ msp430-gcc -Os -mmcu=msp430x1121 -o test.elf test.c&lt;br /&gt;
&lt;br /&gt;
=== Sourcecode für msp430x1121 kompilieren, wenn math.h includiert wird ===&lt;br /&gt;
&lt;br /&gt;
  msp430-gcc -Os -mmcu=msp430x1121 -o test.elf test.c -lm&lt;br /&gt;
&lt;br /&gt;
Wichtig ist hierbei -lm als letzte Option.&lt;br /&gt;
&lt;br /&gt;
=== Assemblerlisting erzeugen (optional) ===&lt;br /&gt;
&lt;br /&gt;
  $ msp430-objdump -DS test.elf &amp;gt; test.lst&lt;br /&gt;
&lt;br /&gt;
=== Hex-Datei erzeugen ===&lt;br /&gt;
&lt;br /&gt;
  $ msp430-objcopy -O ihex test.elf test.hex&lt;br /&gt;
&lt;br /&gt;
Die Hex-Datei kann man mit C-Spy (im Kickstart-Paket enthalten) über das JTAG-Interface in den Controller programmieren. Nach einem Klick auf &amp;quot;Go&amp;quot; läuft das Programm los. Wenn 2 LEDs an P1.0 und P1.1 angeschlossen sind, sollten sie nun blinken.&lt;br /&gt;
&lt;br /&gt;
== In-System-Debugging mit GDB/Insight und dem Flash Emulation Tool (FET) ==&lt;br /&gt;
&lt;br /&gt;
Wie bei anderen MSP430-Compilern ist es möglich mspgcc-Programme direkt in der Schaltung zu debuggen. Alles was man dazu braucht, ist ein JTAG-Adapter, mdp430-gdbproxy, und gdb (im aktuellen Windows-Paket bereits enthalten).&lt;br /&gt;
&lt;br /&gt;
Um ein Programm mit GDB/Insight debuggen zu können, muss man die Option &amp;quot;-g&amp;quot; an den mspgcc-Aufruf anhängen:&lt;br /&gt;
&lt;br /&gt;
  $ msp430-gcc -mmcu=msp430x123 -g -Os -o test.elf test.c&lt;br /&gt;
&lt;br /&gt;
Damit erhält man die Datei &amp;quot;test.elf&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== gdbproxy starten ===&lt;br /&gt;
&lt;br /&gt;
Der nächste Schritt ist das Programm gdbproxy zu starten, das für die Kommunikation zwischen GDB und dem FET zuständig ist:&lt;br /&gt;
&lt;br /&gt;
  $ msp430-gdbproxy --port=2000 msp430&lt;br /&gt;
&lt;br /&gt;
Wenn das FET richtig an den Parallelport angeschlossen ist, sollte ungefähr der folgende Text angezeigt werden:&lt;br /&gt;
&lt;br /&gt;
 info:      msp430: Target device is a &#039;MSP430F12x&#039; (type 11)&lt;br /&gt;
 notice:    msp430-gdbproxy: waiting on TCP port 2000&lt;br /&gt;
&lt;br /&gt;
Hinweis: Falls /dev/parport0 nicht existiert, was sich so äußert:&lt;br /&gt;
 open: No such file or directory&lt;br /&gt;
 error:     msp430: Could not initialize device interface (1)&lt;br /&gt;
...als root ...&lt;br /&gt;
 mknod /dev/parport0 c 99 0 &lt;br /&gt;
...eingeben.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Bei udev im neuen Linuxkernel ab 2.6.x wird das Device /dev/parport0 nicht automatisch angelegt und man muss jedesmal neu den Aufruf mit mknod machen. Abhilfe schafft hier der Eintrag in der /etc/modules:&lt;br /&gt;
ppdev&lt;br /&gt;
&lt;br /&gt;
Beim nächsten Booten dürfte der RAW-Parallelport vorhanden sein.&lt;br /&gt;
&lt;br /&gt;
=== Insight benutzen (Windows) ===&lt;br /&gt;
&lt;br /&gt;
Nachdem Insight gestartet ist (c:\msp430\bin\msp430-gdb.exe), klicke auf &amp;quot;File-&amp;gt;Open&amp;quot; und wähle die elf-Datei (z.&amp;amp;nbsp;B. &amp;quot;test.elf&amp;quot;) aus, die du debuggen möchtest.&lt;br /&gt;
&lt;br /&gt;
Klicke dann auf &amp;quot;Run-&amp;gt;Connect to target&amp;quot; und stelle folgendes ein:&lt;br /&gt;
&lt;br /&gt;
  Target:                    &amp;quot;Remote/TCP&amp;quot;&lt;br /&gt;
  Hostname:                  &amp;quot;localhost&amp;quot;&lt;br /&gt;
  Port:                      &amp;quot;2000&amp;quot;&lt;br /&gt;
  Set breakpoint at &#039;main&#039;:  yes&lt;br /&gt;
  Set breakpoint at &#039;exit&#039;:  yes&lt;br /&gt;
  Attach to target:          yes&lt;br /&gt;
  Download Program:          yes&lt;br /&gt;
  Command  after attaching:  &amp;quot;monitor erase all&amp;quot; (ACHTUNG: Optional, damit wird der gesamte Flash-Inhalt gelöscht!)&lt;br /&gt;
  Run Method:                Continue from last Stop&lt;br /&gt;
&lt;br /&gt;
Wenn man auf &amp;quot;Ok&amp;quot; klickt, sollte Insight berichten, dass die Verbindung erfolgreich aufgenommen wurde, und gdbproxy sollte melden:&lt;br /&gt;
&lt;br /&gt;
  &amp;quot;notice: msp430-gdbproxy: connected&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Um den Debugging-Vorgang zu starten, klicke auf &amp;quot;Run&amp;quot; oder drücke einfach die Taste &amp;quot;r&amp;quot;. Wenn alles geklappt hat, sollte nun der Sourcecode des Programmes angezeigt werden und die erste Zeile von main() grün markiert sein. Der rote Punkt ist der Breakpoint, der von Insight automatisch gesetzt wurde. Um selber Breakpoints zu setzen oder zu löschen, klicke auf den Strich &#039;-&#039; am Anfang der Zeile.&lt;br /&gt;
&lt;br /&gt;
Jetzt kann man mit &#039;c&#039; (continue) das Programm am nächsten Breakpoint fortsetzen, die Zeilen mit &#039;s&#039; (step) der Reihe nach ausführen, oder einzelne Assemblerbefehle ausführen... aber Vorsicht mit &amp;quot;finish&amp;quot;: Anscheinend hängt sich Insight manchmal bei diesem Befehl auf. Wenn man also eine Funktion beenden will, ist es wohl besser, einen Breakpoint auf das Ende der Funktion zu setzen und &amp;quot;continue&amp;quot; zu verwenden.&lt;br /&gt;
&lt;br /&gt;
=== DDD benutzen (Unix/Linux) ===&lt;br /&gt;
&lt;br /&gt;
Leider läuft Insight nicht besonders stabil und ist auch etwas umständlich zu bedienen. Wer Unix bzw. Linux verwendet, der ist deshalb mit DDD (http://www.gnu.org/software/ddd/) besser bedient. Um DDD zu verwenden braucht man msp430-gdbproxy und die Kommandozeilen-Version von GDB (msp430-gdb).&lt;br /&gt;
&lt;br /&gt;
Zuerst stellt man wie unter Windows über gdbproxy eine Verbindung zum JTAG-Adapter her. Wenn das funktioniert hat, kann man DDD starten. Als Parameter wird der zu verwendende Debugger (msp430-gdb) und die zu ladende ELF-Datei (test.elf) übergeben:&lt;br /&gt;
&lt;br /&gt;
  $ ddd --debugger msp430-gdb test.elf&lt;br /&gt;
&lt;br /&gt;
Zunächst sollte man nun unter &amp;quot;Commands / Edit Buttons&amp;quot; ein paar Buttons anlegen, indem man die folgenden Zeilen in das Textfeld bei &amp;quot;Console Buttons&amp;quot; einfügt:&lt;br /&gt;
&lt;br /&gt;
  target remote localhost:2000     // Connect&lt;br /&gt;
  monitor erase all                // Erase&lt;br /&gt;
  load                             // Load&lt;br /&gt;
  monitor reset                    // Reset&lt;br /&gt;
&lt;br /&gt;
Um jetzt die Verbindung zum gdbproxy herzustellen muss man nur auf &amp;quot;Connect&amp;quot; klicken, danach auf &amp;quot;Erase&amp;quot; um den Flash-Speicher des Controllers zu löschen, und schließlich auf &amp;quot;Load&amp;quot;, damit das Programm in den Controller geladen wird. Mit &amp;quot;Reset&amp;quot; kann man einen Reset auslösen (wer hätte das gedacht?).&lt;br /&gt;
&lt;br /&gt;
Wichtig: Nachdem einige breakpoints gesetzt sind, das Programm nicht mit &amp;quot;run&amp;quot; ausführen! Dass &amp;quot;run&amp;quot; Kommando wird benutzt um Programme auf dem lokalen Rechner zu starten. Für eingebettete Systeme ist das korrekte Kommando &amp;quot;continue&amp;quot; (siehe http://mspgcc.sourceforge.net/manual/x1602.html).&lt;br /&gt;
&lt;br /&gt;
=== GDB Scripts ===&lt;br /&gt;
&lt;br /&gt;
Hier eine kleine Ansammlung von Scripts, um download und reset via GDB etwas zu vereinfachen:&lt;br /&gt;
&lt;br /&gt;
[[Media:Gdb_scripts_win.zip]]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:MSP430]]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=MSPGCC&amp;diff=58092</id>
		<title>MSPGCC</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=MSPGCC&amp;diff=58092"/>
		<updated>2011-06-21T19:40:47Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: /* Gentoo Ebuilds */ fixed link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;MSPGCC ist ein kostenloser, unbeschränkter [[C]]-[[Compiler]] für die [[MSP430]]-[[Mikrocontroller]] von [[TI]]. Die Portierung auf MSP430 wurde von Chris Liechti und Dmitry Diky durchgeführt.&lt;br /&gt;
&lt;br /&gt;
== Dokumentation ==&lt;br /&gt;
&lt;br /&gt;
* [http://mspgcc.sourceforge.net/manual/ MSPGCC Manual]&lt;br /&gt;
* [http://mspgcc.sourceforge.net/faq/ FAQ]&lt;br /&gt;
&lt;br /&gt;
== Beispielprogramme ==&lt;br /&gt;
&lt;br /&gt;
Für MSPGCC sind umfangreiche Beispielprogramme ([[LCD]]-Ansteuerung, TCP/IP, ...) verfügbar, außerdem wurden alle TI-Appnotes (C und Assembler) von Steve Underwood für MSPGCC angepasst.&lt;br /&gt;
&lt;br /&gt;
* [http://mspgcc.cvs.sourceforge.net/mspgcc/examples/ MSPGCC Beispiele &amp;amp; Appnotes]&lt;br /&gt;
&lt;br /&gt;
== Windows-Version ==&lt;br /&gt;
&lt;br /&gt;
* [http://sourceforge.net/project/showfiles.php?group_id=42303&amp;amp;package_id=68584 MSPGCC Komplettpaket]&lt;br /&gt;
* [[MSP430_eclipse_helios_mspgcc4_gdb-proxy|Anleitung mit Eclipse 3.6 Helios via mspgcc4 compilieren und debuggen]] (06/2010)&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/Eclipse_und_MSPGCC_unter_Windows Eclipse und MSPGCC unter Windows] (03/2009)&lt;br /&gt;
&amp;lt;!-- * [http://matthias-hartmann.blogspot.com/ Use Eclipse and mspgcc - the easy way] (Windows 02/2009). (offline) --&amp;gt;&lt;br /&gt;
* [http://www.mikrocontroller.net/Eclipse%20und%20MSPGCC/ ausführliche Anleitung zur Verwendung von Eclipse mit MSPGCC unter Windows] (03/2006)&lt;br /&gt;
&lt;br /&gt;
== Installationsanleitung für Unix/Linux/Cygwin ==&lt;br /&gt;
man kann nach wie vor Schritt für Schritt über die Kommandozeile gehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  $ su&lt;br /&gt;
 &lt;br /&gt;
  $ mkdir /tmp/mspgcc&lt;br /&gt;
  $ cd /tmp/mspgcc&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Oder die Installationsanleitung im MSPGCC-Wiki nutzen:&lt;br /&gt;
[http://sourceforge.net/apps/mediawiki/mspgcc/index.php?title=Linux_installation#Get_the_Sources_and_build_the_Package]&lt;br /&gt;
&lt;br /&gt;
Dabei gibt es zwei Fallstricke:&lt;br /&gt;
&lt;br /&gt;
1.: Das Beispiel geht davon aus, dass GCC 3.4 installiert ist. Diese Version ist relativ alt und behandelt Compilerwarnungen etwas nachsichtiger. Wer eine neuere oder andere Version von GCC installiert hat, muss das im Make-Aufruf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 cvs -d:pserver:anonymous@mspgcc.cvs.sourceforge.net:/cvsroot/mspgcc login&lt;br /&gt;
 cvs -z3 -d:pserver:anonymous@mspgcc.cvs.sourceforge.net:/cvsroot/mspgcc co -P .&lt;br /&gt;
 cd packaging&lt;br /&gt;
 make folders&lt;br /&gt;
 CC=gcc-3.4 make build&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
vorangestellte &amp;quot;CC=gcc-3.4&amp;quot; auf die installierte GCC-Version abändern, z.&amp;amp;nbsp;B. &amp;quot;CC=gcc-4.4&amp;quot;. Tut man das nicht, wird der vorhandene GCC-Compiler nicht gefunden und make liefert Fehler 77 zurück (Compiler kann keine ausführbare Dateien erstellen).&lt;br /&gt;
&lt;br /&gt;
2.: Das verlinkte Package lädt sich (eventuell nur im Moment, 7.2.2010) die binutils-2.18 per Ftp herunter. Einige der Quelldateien produzieren bei GCC Versionen ab 4.X Warnungen, die durch den Compilerschalter -Werror als Fehler behandelt und zum Abbruch des Compiliervorgangs führen.&lt;br /&gt;
Workaround: in der Datei /packaging/build/binutils-2.18/binutils/Makefile die Zeile&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CFLAGS = -g -O2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
auf &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CFLAGS = -g -O2 -Wno-error&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
erweitern.&lt;br /&gt;
&lt;br /&gt;
Oder binutils-2.19 von Hand kompilieren und installieren, auch hier auf passende Angabe der GCC-Version achten.&lt;br /&gt;
[http://sourceforge.net/apps/mediawiki/mspgcc/index.php?title=Building_MSPGCC_from_Source_Code]&lt;br /&gt;
Achtung: in der aktuellen Version heißt die benötigte Datei /package/patches/binutils-2.19.patch irrtümlicherweise binutils-2.19&#039;&#039;&#039;-&#039;&#039;&#039;patch (mit bindestrich statt Punkt).&lt;br /&gt;
&lt;br /&gt;
=== binutils ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  $ wget ftp://sources.redhat.com/pub/binutils/releases/binutils-2.17.tar.bz2&lt;br /&gt;
  $ tar xjvf binutils-2.17.tar.bz2&lt;br /&gt;
 &lt;br /&gt;
  $ cd binutils-2.17&lt;br /&gt;
  $ ./configure --prefix=/usr/local/msp430 --target=msp430&lt;br /&gt;
  $ make&lt;br /&gt;
  $ make install&lt;br /&gt;
  $ cd ..&lt;br /&gt;
 &lt;br /&gt;
  $ export PATH=/usr/local/msp430/bin:$PATH&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hinweis: Das Kommando wget setzt einen Internetzugang voraus.&lt;br /&gt;
&lt;br /&gt;
Hinweis2:&amp;lt;br&amp;gt; Die Version 2.14 enthält nicht alle Controllertypen. So fehlen zum Beispiel die Typen MSP430F1611 und MSP430F1612.&amp;lt;br&amp;gt;&lt;br /&gt;
Bei Version 2.17 kann es zu fehlerhaften binarys kommen (Fehler: test.elf has no bss section)&amp;lt;br&amp;gt;&lt;br /&gt;
Mit der Version 2.16.1 sollte alles funktionieren.&lt;br /&gt;
&lt;br /&gt;
Hinweis3:&amp;lt;br&amp;gt;Ich versuche es mit 2.19.1, wenn ich auf Fehler stosse, dann berichte ich davon..&lt;br /&gt;
&lt;br /&gt;
=== gcc ===&lt;br /&gt;
&#039;&#039;&#039;Achtung:&#039;&#039;&#039; MSPGCC kompiliert nicht gcc-4.1. Abhilfe schafft es zu Beginn (oder vor configure) den Befehl &amp;quot;export CC=gcc-3.3&amp;quot; bzw. &amp;quot;export CC=gcc-3.4&amp;quot; aufzurufen. Auch ist darauf zu achten die Dateien gcc-core-3.2.3 und gcc-g++.tar.bz2 und nicht etwa gcc-3.2.3 runterzuladen. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  $ wget ftp://gcc.gnu.org/pub/gcc/releases/gcc-3.2.3/gcc-core-3.2.3.tar.bz2&lt;br /&gt;
  $ wget ftp://gcc.gnu.org/pub/gcc/releases/gcc-3.2.3/gcc-g++-3.2.3.tar.bz2&lt;br /&gt;
  $ tar xjvf gcc-core-3.2.3.tar.bz2&lt;br /&gt;
  $ tar xjvf gcc-g++-3.2.3.tar.bz2&lt;br /&gt;
&lt;br /&gt;
  $ cvs -d:pserver:anonymous@mspgcc.cvs.sourceforge.net:/cvsroot/mspgcc login&lt;br /&gt;
  $ cvs -z3 -d:pserver:anonymous@mspgcc.cvs.sourceforge.net:/cvsroot/mspgcc co gcc/gcc-3.3&lt;br /&gt;
  $ cp -r gcc/gcc-3.3/* gcc-3.2.3/&lt;br /&gt;
 &lt;br /&gt;
  $ cd gcc-3.2.3&lt;br /&gt;
  $ ./configure --prefix=/usr/local/msp430 --target=msp430 --enable-languages=c,c++&lt;br /&gt;
  $ make&lt;br /&gt;
  $ make install&lt;br /&gt;
  $ cd ..&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== msp430-libc ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  $ cvs -d:pserver:anonymous@mspgcc.cvs.sourceforge.net:/cvsroot/mspgcc login&lt;br /&gt;
  $ cvs -z3 -d:pserver:anonymous@mspgcc.cvs.sourceforge.net:/cvsroot/mspgcc co msp430-libc&lt;br /&gt;
 &lt;br /&gt;
  $ cd msp430-libc/src&lt;br /&gt;
  $ make&lt;br /&gt;
  $ make install&lt;br /&gt;
  $ cd ../..&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== gdb ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  $ wget http://mirrors.redwire.net/pub/sources.redhat.com/gdb/old-releases/gdb-6.0.tar.bz2&lt;br /&gt;
  $ tar xjvf gdb-6.0.tar.bz2&lt;br /&gt;
 &lt;br /&gt;
  $ cvs -d:pserver:anonymous@mspgcc.cvs.sourceforge.net:/cvsroot/mspgcc login&lt;br /&gt;
  $ cvs -z3 -d:pserver:anonymous@mspgcc.cvs.sourceforge.net:/cvsroot/mspgcc co gdb/gdb-current&lt;br /&gt;
  $ cp -r gdb/gdb-current/* gdb-6.0/&lt;br /&gt;
 &lt;br /&gt;
  $ cd gdb-6.0&lt;br /&gt;
  $ ./configure --prefix=/usr/local/msp430 --target=msp430&lt;br /&gt;
  $ make&lt;br /&gt;
  $ make install&lt;br /&gt;
  $ cd ..&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Achtung: Der GDB kann nicht mit GCC 4.x übersetzt werden. Wenn dieser auf dem System standardmäßig installiert ist, kann man z.&amp;amp;nbsp;B. den GCC 3.4 zusätzlich installieren und dann vor der ./configure- Zeile&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  $ export CC=gcc-3.4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
einfügen.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Bei Ubuntu (evtl auch bei anderen Distributionen) sind die Entwicklerdateien für die Library libtermcap im Paket libncurses5-dev&lt;br /&gt;
&lt;br /&gt;
=== JTAG ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  $ cvs -d:pserver:anonymous@mspgcc.cvs.sourceforge.net:/cvsroot/mspgcc login&lt;br /&gt;
  $ cvs -z3 -d:pserver:anonymous@mspgcc.cvs.sourceforge.net:/cvsroot/mspgcc co jtag&lt;br /&gt;
 &lt;br /&gt;
  $ cd jtag/hardware_access&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wer ein 64-Bit-Linux verwendet, muss im makefile die CFLAGS und die LNOPTS um ein -m32 ergänzen. Das sollte dann so aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    CFLAGS  += -fPIC -m32&lt;br /&gt;
    LNOPTS   = -fPIC -shared -m32&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Weiter geht&#039;s:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  $ make&lt;br /&gt;
  $ mv libHIL.so /usr/local/lib&lt;br /&gt;
  $ ldconfig&lt;br /&gt;
  $ cd ../..&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== gdbproxy ===&lt;br /&gt;
&lt;br /&gt;
Den msp430-gdbproxy und libMSP430.so von http://www.soft-switch.org/downloads/mspgcc herunterladen. Danach&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  $ chmod +x msp430-gdbproxy&lt;br /&gt;
  $ mv msp430-gdbproxy /usr/local/msp430/bin/&lt;br /&gt;
  $ mv libMSP430.so /usr/local/lib/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ausführen.&lt;br /&gt;
&lt;br /&gt;
=== Installations-Skript ===&lt;br /&gt;
&lt;br /&gt;
Für Installation/Update gibt es hier ein bash-Skript, das nach dem Starten (und einmal Return zum Downloaden der Sourcen aus dem CVS) das Installieren automatisch erledigt.&lt;br /&gt;
&lt;br /&gt;
Eingebaut sind auch die Anpassungen von ~/.profile und ~/.gdbinit, so dass man sofort loslegen und auch debuggen kann.&lt;br /&gt;
&lt;br /&gt;
* [http://www.true-random.com/files/mspgcc/build_mspgcc.sh Installations-Skript]&lt;br /&gt;
&lt;br /&gt;
Dieses Script ist jedoch relativ veraltet. Daher ist es schneller obige Anleitung per Copy&#039;n&#039;Paste in eine Shell zu übernehmen, als das Script zu verwenden. &lt;br /&gt;
&lt;br /&gt;
=== Gentoo Ebuilds ===&lt;br /&gt;
&lt;br /&gt;
Für Gentoo-Benutzer gibt es an der [http://pi4.informatik.uni-mannheim.de/pi4.data/content/projects/msp430/ Uni Mannheim] Ebuilds zum Download.&lt;br /&gt;
&lt;br /&gt;
=== .gdbinit ===&lt;br /&gt;
&lt;br /&gt;
Um das JTAG-Interface schneller zu machen kann man in ~/.gdbinit diese Werte eintragen:&lt;br /&gt;
&lt;br /&gt;
 set remoteaddresssize 16&lt;br /&gt;
 set remotetimeout 999999&lt;br /&gt;
 set download-write-size 512&lt;br /&gt;
 target remote localhost:2000&lt;br /&gt;
 set remote memory-write-packet-size 512&lt;br /&gt;
 set remote memory-write-packet-size fixed&lt;br /&gt;
 set remote memory-read-packet-size 512&lt;br /&gt;
 set remote memory-read-packet-size fixed&lt;br /&gt;
&lt;br /&gt;
Und vor dem Debuggen von Programmen auf dem Rechner (nicht MSP430) sollte man ~/.gdbinit umbenennen, beispielsweise in ~/.gdbinit_msp430.&lt;br /&gt;
&lt;br /&gt;
== Mac OS X ==&lt;br /&gt;
&lt;br /&gt;
Um msp430-gcc unter Mac OS X (Intel) kompilieren zu können, &lt;br /&gt;
gcc-3.2.3/gcc/config.gcc wie folgt aendern:&lt;br /&gt;
&lt;br /&gt;
Von&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 i[34567]86-*-freebsd[12] | i[34567]86-*-freebsd[12].* | i[34567]86-*-freebsd*aout* )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
auf:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 i[34567]86-*-freebsd[12] | i[34567]86-*-freebsd[12].* | i[34567]86-*-freebsd*aout* | i[34567]86-apple-darwin8* )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ansonsten die Anleitung für Linux befolgen.&lt;br /&gt;
&lt;br /&gt;
== Einfaches Beispielprogramm ==&lt;br /&gt;
&lt;br /&gt;
=== Sourcecode ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
 #include &amp;lt;io.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 void wait(void);         /* prototype for wait()      */&lt;br /&gt;
&lt;br /&gt;
 int&lt;br /&gt;
 main(void)&lt;br /&gt;
 { /* main function, called by startup-code */&lt;br /&gt;
   P1DIR = 0xFF;          /* port 1 = output           */&lt;br /&gt;
   P1OUT = 0x01;          /* set bit 0 in port 1       */&lt;br /&gt;
&lt;br /&gt;
   for(;;)&lt;br /&gt;
   { /* infinite loop */&lt;br /&gt;
     P1OUT = ~P1OUT;      /* invert port 1             */&lt;br /&gt;
     wait();              /* call delay function       */&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 void&lt;br /&gt;
 wait(void)&lt;br /&gt;
 { /* simple delay function */&lt;br /&gt;
   volatile int i;        /* declare i as volatile int */&lt;br /&gt;
   for(i = 0; i &amp;lt; 32000; i++)&lt;br /&gt;
   ;                      /* repeat 32000 times (nop)  */&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sourcecode für msp430x1121 kompilieren ===&lt;br /&gt;
&lt;br /&gt;
  $ msp430-gcc -Os -mmcu=msp430x1121 -o test.elf test.c&lt;br /&gt;
&lt;br /&gt;
=== Sourcecode für msp430x1121 kompilieren, wenn math.h includiert wird ===&lt;br /&gt;
&lt;br /&gt;
  msp430-gcc -Os -mmcu=msp430x1121 -o test.elf test.c -lm&lt;br /&gt;
&lt;br /&gt;
Wichtig ist hierbei -lm als letzte Option.&lt;br /&gt;
&lt;br /&gt;
=== Assemblerlisting erzeugen (optional) ===&lt;br /&gt;
&lt;br /&gt;
  $ msp430-objdump -DS test.elf &amp;gt; test.lst&lt;br /&gt;
&lt;br /&gt;
=== Hex-Datei erzeugen ===&lt;br /&gt;
&lt;br /&gt;
  $ msp430-objcopy -O ihex test.elf test.hex&lt;br /&gt;
&lt;br /&gt;
Die Hex-Datei kann man mit C-Spy (im Kickstart-Paket enthalten) über das JTAG-Interface in den Controller programmieren. Nach einem Klick auf &amp;quot;Go&amp;quot; läuft das Programm los. Wenn 2 LEDs an P1.0 und P1.1 angeschlossen sind, sollten sie nun blinken.&lt;br /&gt;
&lt;br /&gt;
== In-System-Debugging mit GDB/Insight und dem Flash Emulation Tool (FET) ==&lt;br /&gt;
&lt;br /&gt;
Wie bei anderen MSP430-Compilern ist es möglich mspgcc-Programme direkt in der Schaltung zu debuggen. Alles was man dazu braucht, ist ein JTAG-Adapter, mdp430-gdbproxy, und gdb (im aktuellen Windows-Paket bereits enthalten).&lt;br /&gt;
&lt;br /&gt;
Um ein Programm mit GDB/Insight debuggen zu können, muss man die Option &amp;quot;-g&amp;quot; an den mspgcc-Aufruf anhängen:&lt;br /&gt;
&lt;br /&gt;
  $ msp430-gcc -mmcu=msp430x123 -g -Os -o test.elf test.c&lt;br /&gt;
&lt;br /&gt;
Damit erhält man die Datei &amp;quot;test.elf&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== gdbproxy starten ===&lt;br /&gt;
&lt;br /&gt;
Der nächste Schritt ist das Programm gdbproxy zu starten, das für die Kommunikation zwischen GDB und dem FET zuständig ist:&lt;br /&gt;
&lt;br /&gt;
  $ msp430-gdbproxy --port=2000 msp430&lt;br /&gt;
&lt;br /&gt;
Wenn das FET richtig an den Parallelport angeschlossen ist, sollte ungefähr der folgende Text angezeigt werden:&lt;br /&gt;
&lt;br /&gt;
 info:      msp430: Target device is a &#039;MSP430F12x&#039; (type 11)&lt;br /&gt;
 notice:    msp430-gdbproxy: waiting on TCP port 2000&lt;br /&gt;
&lt;br /&gt;
Hinweis: Falls /dev/parport0 nicht existiert, was sich so äußert:&lt;br /&gt;
 open: No such file or directory&lt;br /&gt;
 error:     msp430: Could not initialize device interface (1)&lt;br /&gt;
...als root ...&lt;br /&gt;
 mknod /dev/parport0 c 99 0 &lt;br /&gt;
...eingeben.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Bei udev im neuen Linuxkernel ab 2.6.x wird das Device /dev/parport0 nicht automatisch angelegt und man muss jedesmal neu den Aufruf mit mknod machen. Abhilfe schafft hier der Eintrag in der /etc/modules:&lt;br /&gt;
ppdev&lt;br /&gt;
&lt;br /&gt;
Beim nächsten Booten dürfte der RAW-Parallelport vorhanden sein.&lt;br /&gt;
&lt;br /&gt;
=== Insight benutzen (Windows) ===&lt;br /&gt;
&lt;br /&gt;
Nachdem Insight gestartet ist (c:\msp430\bin\msp430-gdb.exe), klicke auf &amp;quot;File-&amp;gt;Open&amp;quot; und wähle die elf-Datei (z.&amp;amp;nbsp;B. &amp;quot;test.elf&amp;quot;) aus, die du debuggen möchtest.&lt;br /&gt;
&lt;br /&gt;
Klicke dann auf &amp;quot;Run-&amp;gt;Connect to target&amp;quot; und stelle folgendes ein:&lt;br /&gt;
&lt;br /&gt;
  Target:                    &amp;quot;Remote/TCP&amp;quot;&lt;br /&gt;
  Hostname:                  &amp;quot;localhost&amp;quot;&lt;br /&gt;
  Port:                      &amp;quot;2000&amp;quot;&lt;br /&gt;
  Set breakpoint at &#039;main&#039;:  yes&lt;br /&gt;
  Set breakpoint at &#039;exit&#039;:  yes&lt;br /&gt;
  Attach to target:          yes&lt;br /&gt;
  Download Program:          yes&lt;br /&gt;
  Command  after attaching:  &amp;quot;monitor erase all&amp;quot; (ACHTUNG: Optional, damit wird der gesamte Flash-Inhalt gelöscht!)&lt;br /&gt;
  Run Method:                Continue from last Stop&lt;br /&gt;
&lt;br /&gt;
Wenn man auf &amp;quot;Ok&amp;quot; klickt, sollte Insight berichten, dass die Verbindung erfolgreich aufgenommen wurde, und gdbproxy sollte melden:&lt;br /&gt;
&lt;br /&gt;
  &amp;quot;notice: msp430-gdbproxy: connected&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Um den Debugging-Vorgang zu starten, klicke auf &amp;quot;Run&amp;quot; oder drücke einfach die Taste &amp;quot;r&amp;quot;. Wenn alles geklappt hat, sollte nun der Sourcecode des Programmes angezeigt werden und die erste Zeile von main() grün markiert sein. Der rote Punkt ist der Breakpoint, der von Insight automatisch gesetzt wurde. Um selber Breakpoints zu setzen oder zu löschen, klicke auf den Strich &#039;-&#039; am Anfang der Zeile.&lt;br /&gt;
&lt;br /&gt;
Jetzt kann man mit &#039;c&#039; (continue) das Programm am nächsten Breakpoint fortsetzen, die Zeilen mit &#039;s&#039; (step) der Reihe nach ausführen, oder einzelne Assemblerbefehle ausführen... aber Vorsicht mit &amp;quot;finish&amp;quot;: Anscheinend hängt sich Insight manchmal bei diesem Befehl auf. Wenn man also eine Funktion beenden will, ist es wohl besser, einen Breakpoint auf das Ende der Funktion zu setzen und &amp;quot;continue&amp;quot; zu verwenden.&lt;br /&gt;
&lt;br /&gt;
=== DDD benutzen (Unix/Linux) ===&lt;br /&gt;
&lt;br /&gt;
Leider läuft Insight nicht besonders stabil und ist auch etwas umständlich zu bedienen. Wer Unix bzw. Linux verwendet, der ist deshalb mit DDD (http://www.gnu.org/software/ddd/) besser bedient. Um DDD zu verwenden braucht man msp430-gdbproxy und die Kommandozeilen-Version von GDB (msp430-gdb).&lt;br /&gt;
&lt;br /&gt;
Zuerst stellt man wie unter Windows über gdbproxy eine Verbindung zum JTAG-Adapter her. Wenn das funktioniert hat, kann man DDD starten. Als Parameter wird der zu verwendende Debugger (msp430-gdb) und die zu ladende ELF-Datei (test.elf) übergeben:&lt;br /&gt;
&lt;br /&gt;
  $ ddd --debugger msp430-gdb test.elf&lt;br /&gt;
&lt;br /&gt;
Zunächst sollte man nun unter &amp;quot;Commands / Edit Buttons&amp;quot; ein paar Buttons anlegen, indem man die folgenden Zeilen in das Textfeld bei &amp;quot;Console Buttons&amp;quot; einfügt:&lt;br /&gt;
&lt;br /&gt;
  target remote localhost:2000     // Connect&lt;br /&gt;
  monitor erase all                // Erase&lt;br /&gt;
  load                             // Load&lt;br /&gt;
  monitor reset                    // Reset&lt;br /&gt;
&lt;br /&gt;
Um jetzt die Verbindung zum gdbproxy herzustellen muss man nur auf &amp;quot;Connect&amp;quot; klicken, danach auf &amp;quot;Erase&amp;quot; um den Flash-Speicher des Controllers zu löschen, und schließlich auf &amp;quot;Load&amp;quot;, damit das Programm in den Controller geladen wird. Mit &amp;quot;Reset&amp;quot; kann man einen Reset auslösen (wer hätte das gedacht?).&lt;br /&gt;
&lt;br /&gt;
Wichtig: Nachdem einige breakpoints gesetzt sind, das Programm nicht mit &amp;quot;run&amp;quot; ausführen! Dass &amp;quot;run&amp;quot; Kommando wird benutzt um Programme auf dem lokalen Rechner zu starten. Für eingebettete Systeme ist das korrekte Kommando &amp;quot;continue&amp;quot; (siehe http://mspgcc.sourceforge.net/manual/x1602.html).&lt;br /&gt;
&lt;br /&gt;
=== GDB Scripts ===&lt;br /&gt;
&lt;br /&gt;
Hier eine kleine Ansammlung von Scripts, um download und reset via GDB etwas zu vereinfachen:&lt;br /&gt;
&lt;br /&gt;
[[Media:Gdb_scripts_win.zip]]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:MSP430]]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=MSP430_Codebeispiele&amp;diff=58070</id>
		<title>MSP430 Codebeispiele</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=MSP430_Codebeispiele&amp;diff=58070"/>
		<updated>2011-06-19T07:48:10Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: /* I2C/TWI in Software */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;MSP430 &amp;amp;#8211; Codebeispiele&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Einleitung:&#039;&#039;&#039;&lt;br /&gt;
Da der MSP430 eine sehr schöner Mikrocontroller für energiesparende Anwendungen ist, jedoch bei weitem nicht so verbreitet wie z.&amp;amp;nbsp;B. diverse 8051er, AVRs, PICs usw. ist, gibt es auch nicht all zu viele Codebeispiele aus Projekten für den/die Hobbybastler(in).&lt;br /&gt;
Aus diesem Grund werden hier Grundlagen der Initialisierung diverser Hardwarefeatures sowie grundlegende Softwareroutinen und dergleichen beschrieben, so dass für Anfänger auch ein einfaches Copy&amp;amp;Paste möglich ist.&lt;br /&gt;
Hierbei kommt der MSPGCC zum Einsatz, da eine professionelle unlimitierte Ausgabe des z.&amp;amp;nbsp;B. IAR für Bastler nahezu unbezahlbar ist.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Hardware =&lt;br /&gt;
&lt;br /&gt;
== Initializing/ Configuring UARTs ==&lt;br /&gt;
Von www.mathar.com stammt diese Routine zur initialisierung eines beliebigen UARTS. Zusätzlich müssen jedoch die Pins noch definiert werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
void InitUSART(char USART0, char USART1, unsigned int baudrate1, unsigned int baudrate2, char IR0, char IR1)&lt;br /&gt;
{&lt;br /&gt;
  if (USART0) ME1 |= UTXE0 + URXE0;    // falls gesetzt, USART0 einschalten (TX- und RX-teil)&lt;br /&gt;
  if (USART1) ME2 |= UTXE1 + URXE1;    // falls gesetzt, USART1 einschalten (TX- und RX-teil)&lt;br /&gt;
  UCTL0 |= CHAR;                       // 8 data bits, 1 stop bit, no parity (8N1)&lt;br /&gt;
  UCTL1 |= CHAR;&lt;br /&gt;
  UTCTL0 |= SSEL1;                     // SMCLK als UCLK festlegen&lt;br /&gt;
  UTCTL1 |= SSEL1;&lt;br /&gt;
  if (baudrate1==19200)&lt;br /&gt;
  {&lt;br /&gt;
    UBR00 = 0xA0;                      // 19200 baud aus 8 MHz erzeugen&lt;br /&gt;
    UBR10 = 0x01;                      // siehe application note tabelle 1, seite 9&lt;br /&gt;
    UMCTL0 = 0x00;                     // keine korrektur der division noetig&lt;br /&gt;
  }&lt;br /&gt;
  if (baudrate2==19200)&lt;br /&gt;
  {&lt;br /&gt;
    UBR01 = 0xA0;                      // 19200 baud aus 8 MHz erzeugen&lt;br /&gt;
    UBR11 = 0x01;                      // siehe application note tabelle 1, seite 9&lt;br /&gt;
    UMCTL1 = 0x00;                     // keine korrektur der division noetig&lt;br /&gt;
  }&lt;br /&gt;
  if (USART0) UCTL0 &amp;amp;= ~SWRST;         // USART freigeben&lt;br /&gt;
  if (USART1) UCTL1 &amp;amp;= ~SWRST;&lt;br /&gt;
  if (IR0==0) IE1 |= URXIE0;           // IR0: 0 -&amp;gt; nur RX-interrupt anschalten&lt;br /&gt;
  if (IR0==1) IE1 |= UTXIE0;           //      1 -&amp;gt; nur TX-interrupt anschalten&lt;br /&gt;
  if (IR0==2) IE1 |= URXIE0 + UTXIE0;  //      2 -&amp;gt; TX- und RX-interrupt anschalten&lt;br /&gt;
  if (IR1==1||IR1==2) IFG1 &amp;amp;= ~UTXIFG0;  // initales interrupt-flag loeschen&lt;br /&gt;
  if (IR1==0) IE2 |= URXIE1;           // IR1: 0 -&amp;gt; nur RX-interrupt anschalten&lt;br /&gt;
  if (IR1==1) IE2 |= UTXIE1;           //      1 -&amp;gt; nur TX-interrupt anschalten&lt;br /&gt;
  if (IR1==2) IE2 |= URXIE1 + UTXIE1;  //      2 -&amp;gt; TX- und RX-interrupt anschalten&lt;br /&gt;
  if (IR1==1||IR1==2) IFG1 &amp;amp;= ~UTXIFG1;  // initales interrupt-flag loeschen&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Initialization/configuration of USART (SPI and I2C/TWI) ==&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
void init_spi(void)&lt;br /&gt;
{&lt;br /&gt;
  ME1 |= USPIE0;                        // Enable USART0 SPI mode&lt;br /&gt;
  UTCTL0 = CKPH+SSEL1+SSEL0+STC;        // SMCLK, 3-pin mode&lt;br /&gt;
  UCTL0 = CHAR+SYNC+MM;                 // 8-bit SPI Master **SWRST**&lt;br /&gt;
  UBR00 = 0x02;                         // UCLK/2 &lt;br /&gt;
  UBR10 = 0x00;                         // 0&lt;br /&gt;
  UMCTL0 = 0x00;                        // no modulation&lt;br /&gt;
  P3SEL |= 0x0E;                        // P3.1-3 SPI option select&lt;br /&gt;
  P3DIR |= 0x01;                        // P3.0 output direction&lt;br /&gt;
  _EINT();                              // Enable interrupts&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void init_i2c(unsigned char slave)&lt;br /&gt;
{&lt;br /&gt;
  P3SEL |= 0x0a;                            // Assign I2C pins to module&lt;br /&gt;
  U0CTL |= I2C + SYNC;                      // Switch USART0 to I2C mode&lt;br /&gt;
  U0CTL &amp;amp;= ~I2CEN;                          // Recommended I2C init procedure&lt;br /&gt;
  I2CTCTL = I2CSSEL_2;                      // SMCLK&lt;br /&gt;
  I2CSCLH = 0x03;                           // High period of SCL&lt;br /&gt;
  I2CSCLL = 0x03;                           // Low period of SCL&lt;br /&gt;
  I2CNDAT = 0x01;                           // Transmit one byte&lt;br /&gt;
  I2CSA = slave;                             // Slave address&lt;br /&gt;
  U0CTL |= I2CEN;                           // Enable I2C, 7 bit addr,&lt;br /&gt;
  I2CIE = RXRDYIE;                          // I2C receive ready interrupt enable&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Initialisierung der Quarze ==&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
void init_XT2(void)&lt;br /&gt;
{&lt;br /&gt;
  unsigned int i;&lt;br /&gt;
  WDTCTL = WDTPW + WDTHOLD;             // Stop WDT&lt;br /&gt;
  BCSCTL1 &amp;amp;= ~XT2OFF;                   // XT2 = HF XTAL&lt;br /&gt;
  do &lt;br /&gt;
  {&lt;br /&gt;
    IFG1 &amp;amp;= ~OFIFG;                       // Clear OSCFault flag&lt;br /&gt;
    for (i = 0xFF; i &amp;gt; 0; i--);           // Time for flag to set&lt;br /&gt;
  }&lt;br /&gt;
  while ((IFG1 &amp;amp; OFIFG) != 0);          // OSCFault flag still set?                &lt;br /&gt;
  BCSCTL2 |= SELM1;                     // MCLK = XT2 (safe)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
void init_XT(void) // high frequenz resonators ( 455 kHz - 8MhZ )&lt;br /&gt;
{&lt;br /&gt;
  unsigned int i;&lt;br /&gt;
  WDTCTL = WDTPW + WDTHOLD;             // Stop WDT&lt;br /&gt;
  BCSCTL1 |= XTS;                       // ACLK = LFXT1 = HF XTAL&lt;br /&gt;
  do &lt;br /&gt;
  {&lt;br /&gt;
    IFG1 &amp;amp;= ~OFIFG;                       // Clear OSCFault flag&lt;br /&gt;
    for (i = 0xFF; i &amp;gt; 0; i--);           // Time for flag to set&lt;br /&gt;
  }&lt;br /&gt;
  while ((IFG1 &amp;amp; OFIFG) == OFIFG);      // OSCFault flag still set?                &lt;br /&gt;
  BCSCTL2 |= SELM1+SELM0;               // MCLK = LFXT1 (safe)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
Bei den neueren MSP430F55xx nicht vergessen, dass bei CPU-Taktfrequenzen über 8 MHz vorher die Kernspannung erhöht werden muss, sonst drohen Abstürze oder „rätselhaftes“ Verhalten. Eins der TI-Beispiele (12 MHz) „vergisst“ das sogar.&lt;br /&gt;
&lt;br /&gt;
== Initialisierung des ADCs ==&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
void init_ADC(void)&lt;br /&gt;
{&lt;br /&gt;
  ADC12CTL0 = ADC12ON;	// ADC12ON / reference on Avcc&lt;br /&gt;
  P6SEL |= 0x01;        // P6.0 ADC option select &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
unsigned int sampling_ADC(void)&lt;br /&gt;
{&lt;br /&gt;
  ADC12CTL0 |= ADC12SC + ENC;   // Sampling open&lt;br /&gt;
  ADC12CTL0 &amp;amp;= ~ADC12SC;        // Sampling closed, start conversion&lt;br /&gt;
  while ((ADC12CTL1 &amp;amp; ADC12BUSY) == 1);   // ADC12BUSY?&lt;br /&gt;
  return(ADC12MEM0);	// return the value read from ADC P6.0&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Initialisierung des DACs ==&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void init_DAC(void)&lt;br /&gt;
{&lt;br /&gt;
  ADC12CTL0 = REF2_5V + REFON;              // Internal 2.5V ref on&lt;br /&gt;
  DAC12_0CTL = DAC12IR + DAC12AMP_5 + DAC12ENC;   // Internal ref gain &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void write_DAC(unsigned int val)&lt;br /&gt;
{&lt;br /&gt;
  DAC12_0DAT = val;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Initialisierung des Timers A ==&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
void init_TimerA(unsigned int cycles )&lt;br /&gt;
{&lt;br /&gt;
  TACTL = TASSEL1 + TACLR;              // SMCLK, clear TAR&lt;br /&gt;
  CCTL0 = CCIE;                         // CCR0 interrupt enabled&lt;br /&gt;
  CCR0 = cycles;&lt;br /&gt;
  TACTL |= MC_2;                         // Start Timer_A in continuous mode&lt;br /&gt;
  _EINT();                              // interrupt enable&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Timer A0 interrupt service routine&lt;br /&gt;
interrupt (TIMERA0_VECTOR) Timer_A(void)&lt;br /&gt;
{&lt;br /&gt;
  P1OUT ^= 0x01;                        // Toggle P1.0&lt;br /&gt;
  CCR0 += 50000;                        // Add Offset to CCR0&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Initialisierung des Timers B ==&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
void init_TimerB(unsigned int cycles)&lt;br /&gt;
{&lt;br /&gt;
  TBCTL = TBSSEL1 + TBCLR;              // SMCLK, clear TAR&lt;br /&gt;
  TBCCTL0 = CCIE;                       // CCR0 interrupt enabled&lt;br /&gt;
  TBCCR0 = cycles;&lt;br /&gt;
  TBCTL |= MC_2;                         // Start Timer_B in continuous mode&lt;br /&gt;
  _EINT();                              // interrupt enable&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Timer B0 interrupt service routine&lt;br /&gt;
interrupt (TIMERB0_VECTOR) Timer_B(void)&lt;br /&gt;
{&lt;br /&gt;
  P1OUT ^= 0x01;                        // Toggle P1.0&lt;br /&gt;
  TBCCR0 += 50000;                      // Add Offset to CCR0&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Initialisierung des Watchdogs ==&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
void init_wdt(void)&lt;br /&gt;
{&lt;br /&gt;
  WDTCTL = WDT_MDLY_32;                 // Set Watchdog Timer interval to ~30ms&lt;br /&gt;
  IE1 |= WDTIE;                         // Enable WDT interrupt&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Watchdog Timer interrupt service routine&lt;br /&gt;
interrupt (WDT_VECTOR) watchdog_timer(void)&lt;br /&gt;
{&lt;br /&gt;
  // do this, in an case of an interrupt&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
  WDTCTL = WDTPW + WDTHOLD;	// Watchdog anhalten&lt;br /&gt;
  P1DIR |= 0x01;		// P1.0 als Ausgang&lt;br /&gt;
&lt;br /&gt;
  for (;;)&lt;br /&gt;
  {&lt;br /&gt;
    volatile unsigned i;	// volatile, sonst wird die Warteschleife „wegoptimiert“&lt;br /&gt;
    P1OUT ^= 0x01;		// P1.0 umschalten mit Exklusiv-ODER&lt;br /&gt;
&lt;br /&gt;
    i = 10000;			// Warteschleife in Software&lt;br /&gt;
    do; while (--i);		// (CPU-Leistung „verheizen“)&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Initialisierung der GPIO ==&lt;br /&gt;
Die Ein/Ausgabeleitungen haben beim MSP430, je nach Ausbaustufe, folgende Fähigkeiten:&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Einzeln (bitweise) programmierbare Ein/Ausgabe (&amp;lt;b&amp;gt;PxDIR&amp;lt;/b&amp;gt;, &amp;lt;b&amp;gt;PxOUT&amp;lt;/b&amp;gt;)&lt;br /&gt;
&amp;lt;li&amp;gt;Unabhängige Lese-Adresse (&amp;lt;b&amp;gt;PxIN&amp;lt;/b&amp;gt;)&lt;br /&gt;
&amp;lt;li&amp;gt;Ansprechbar als 8-Bit-Ports oder je paarweise als 16-bit-Port, bspw. P1 + P2 = PA usw.&lt;br /&gt;
&amp;lt;li&amp;gt;Interrupt auf Pegelwechsel einzelner Portpins (nur P1 und P2) (&amp;lt;b&amp;gt;PxIES&amp;lt;/b&amp;gt;)&lt;br /&gt;
&amp;lt;li&amp;gt;Pull-Up, Pull-Down oder kein Widerstand auswählbar (&amp;lt;b&amp;gt;PxREN&amp;lt;/b&amp;gt;, PxOUT)&lt;br /&gt;
&amp;lt;li&amp;gt;Einstellbare Treiberstärke (reduziert und voll) (&amp;lt;b&amp;gt;PxDS&amp;lt;/b&amp;gt;)&lt;br /&gt;
&amp;lt;li&amp;gt;Ein bis zwei Peripheriefunktionen pro Pin (&amp;lt;b&amp;gt;PxSEL&amp;lt;/b&amp;gt;), auswählbar mittels PxDIR (d.h. bei zwei Peripheriefunktionen ist eine Ausgang und die andere Eingang)&lt;br /&gt;
&amp;lt;li&amp;gt;Das JTAG-Port (4 Pins) und das USB-Port (2 Pins) ist standardmäßig ein E/A-Port (MSP430F55xx)&lt;br /&gt;
&amp;lt;li&amp;gt;Erweiterte Peripheriezuordnung bei P4 (MSP430F55xx) mittels Port Mapping Controller&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Nicht 5-V-verträglich!!&amp;lt;/b&amp;gt; Keinem Portpin darf ohne genügend großen Vorwiderstand 5 V angeboten werden. Ableitströme dürfen nicht zum Ansteigen der Speisespannung führen!&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Manche Portpins haben ein gemeinsames PxSEL, etwa:&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;das JTAG-Port (entweder alle 4 oder kein Pin zugeordnet)&lt;br /&gt;
&amp;lt;li&amp;gt;das USB-Port (entweder Portpin oder USB D+ und D–)&lt;br /&gt;
&amp;lt;li&amp;gt;die Quarz-Anschlüsse (das niederwertige PxSEL schaltet beide Portpins)&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle Portpins sind beim Einschalten (PUC) wie folgt initialisiert:&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Eingang ohne Pull-Up oder Pull-Down&lt;br /&gt;
&amp;lt;li&amp;gt;Reduzierte Treiberstärke&lt;br /&gt;
&amp;lt;li&amp;gt;Kein Pegelwechsel-Interrupt&lt;br /&gt;
&amp;lt;li&amp;gt;Keine Peripherie-Zuordnung&lt;br /&gt;
&amp;lt;li&amp;gt;Der Inhalt des Ausgaberegisters &amp;lt;b&amp;gt;PxOUT&amp;lt;/b&amp;gt; ist undefiniert!&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Alle ungenutzten Anschlüsse sollten per PullDown (&amp;lt;b&amp;gt;PxREN&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;PxOUT&amp;lt;/b&amp;gt;) festgelegt werden.&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Kein MSP430 hat einen herausgeführten Busanschluss.&lt;br /&gt;
&lt;br /&gt;
== Initialisierung von PWM ==&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
void init_PWM_TimerA(void)&lt;br /&gt;
{&lt;br /&gt;
  TACTL = TASSEL1 + TACLR;              // SMCLK, Clear Tar&lt;br /&gt;
  CCR0 = 512-1;                         // PWM Period&lt;br /&gt;
  CCTL1 = OUTMOD_7;                     // CCR1 reset/set&lt;br /&gt;
  P1DIR |= 0x04;                        // P1.2 PWM output&lt;br /&gt;
  P1SEL |= 0x04;                        // P1.2 and TA1/2 otions&lt;br /&gt;
  TACTL |= MC0;                         // Start Timer_A in up mode&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void set_PWM_duty_cycle(unsigned char duty)&lt;br /&gt;
{&lt;br /&gt;
  CCR1 = duty;                           // CCR1 PWM duty cycle &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Interrupts: =&lt;br /&gt;
&lt;br /&gt;
== UARTs ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
// z.&amp;amp;nbsp;B. ein Echo mit dem MSPGCC-Compiler:&lt;br /&gt;
interrupt (UART0RX_VECTOR) usart0_rx(void)&lt;br /&gt;
{&lt;br /&gt;
   TXBUF0=RXBUF0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// z.&amp;amp;nbsp;B. ein Echo mit dem ImageCraft ICC430-Compiler:&lt;br /&gt;
#pragma interrupt_handler usart0_rx:UART0RX_VECTOR&lt;br /&gt;
void usart0_rx(void)&lt;br /&gt;
{&lt;br /&gt;
   TXBUF0=RXBUF0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
Die Funktionen selbst können natürlich auch anders genannt werden.&lt;br /&gt;
&lt;br /&gt;
== Timer ==&lt;br /&gt;
&lt;br /&gt;
== IOs ==&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Softwareroutinen: =&lt;br /&gt;
&lt;br /&gt;
== I2C/TWI in Software ==&lt;br /&gt;
Diese Routinen wurden ursprünglich für einen MSP430F149 geschrieben. Es werden ausschließlich IOs benutzt. Da Code in C geschrieben wurde sollte er sich einfach auf alle MSP430`s ohne (aber auch mit I²C) portieren lassen. Der ist zwar nicht ganz schön, aber er funktioniert soweit ganz gut. Auch ein Beispiel ist dabei.&lt;br /&gt;
&lt;br /&gt;
http://www.mikrocontroller.net/attachment.php/324877/soft-i2c.zip&lt;br /&gt;
&lt;br /&gt;
== PWM ==&lt;br /&gt;
&lt;br /&gt;
Untenstehender Code ist nur mit msp320-gcc getestet.&lt;br /&gt;
&lt;br /&gt;
Folgende Routine initialisiert den Timer als Up-Counter mit der Clock-Quelle SMCLK und einem Teiler von 8. Zudem wird der Interrupt aktiviert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
void timerA_init(void)&lt;br /&gt;
{&lt;br /&gt;
	TACTL =  TASSEL_SMCLK | TACLR | ID_DIV8 | TAIE;&lt;br /&gt;
	TACTL |= MC_UPTO_CCR0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Um den Timer zu starten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
void timerA_start(int timing[2], int mode)&lt;br /&gt;
{&lt;br /&gt;
	TACCTL0 = mode;&lt;br /&gt;
	TACCTL0 |= CCIE ;                // enable interrupt&lt;br /&gt;
	TACCTL1 = mode;&lt;br /&gt;
	TACCR0 = timing[0];&lt;br /&gt;
	TACCR1 = timing[1];&lt;br /&gt;
	TAR = 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Die Funktion wird normalerweise mit &#039;mode&#039; 3 aufgerufen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
timerA_start(timing, OUTMOD_SET_RESET);&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
timing[0] enthaelt die komplette Zyklendauer einer PWM-Phase (H und L)&lt;br /&gt;
Beispiel: Um eine Pulsfrequenz von 125 Hz bei einem SMCLK von 1.0 MHz zu erhalten, gilt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;timing_0 = 1.0e6 / 8 / 125 = 1000&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
timing[1] schliesslich enthält die Zyklendauer des H-Pulses und ist immer kleiner als timing[0]. Bei einem &#039;duty cycle&#039; (Tastverhältnis) 50% gilt also&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;timing_1 = 500&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zu beachten ist, dass der Timerkanal 0 bei manchen Modi (wie dem obenstehenden) für die PWM nicht genutzt wird, &amp;quot;TACCTL0 = mode&amp;quot; keinen speziellen Effekt zeigt (siehe auch Manual).&lt;br /&gt;
&lt;br /&gt;
Deswegen wird das PWM-Signal auch an TA1 abgegriffen, nicht an TA0.&lt;br /&gt;
&lt;br /&gt;
Schlussendlich muss der entsprechende Ausgangspin für TA1 konfiguriert werden. Beim F2013 z.&amp;amp;nbsp;B. geschieht dies für P1.2 per&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
	P1SEL |= 0x04;  // Enable primary peripheral&lt;br /&gt;
	P1DIR |= 0x04;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Was war nun mit dem Interrupt? Falls wir z.&amp;amp;nbsp;B. die Zyklen zählen wollen, definieren wir einen Interrupt-Handler:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;signal.h&amp;gt; // &#039;interrupt&#039; makro&lt;br /&gt;
interrupt (TIMERA0_VECTOR) timera0_isr(void)&lt;br /&gt;
{&lt;br /&gt;
	g_count++;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Schlussendlich müssen wir noch die Interrupts im Initialisierungscode aktivieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
_EINT();&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Senden eines Bytes ==&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
void SendUSART0c(char c)             // ein einzelnes zeichen über die serielle schnittstelle (USART0) senden&lt;br /&gt;
                                     // FJG: Obacht: x12xx : IFG1 =&amp;gt; IFG2 !&lt;br /&gt;
{&lt;br /&gt;
  while (!(IFG1 &amp;amp; UTXIFG0));           // warten, bis USART0 TX-buffer sendebereit&lt;br /&gt;
  TXBUF0 = c;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void SendUSART1c(char c)             // ein einzelnes zeichen über die serielle schnittstelle (USART1) senden&lt;br /&gt;
{&lt;br /&gt;
  while (!(IFG2 &amp;amp; UTXIFG1));           // warten, bis USART1 TX-buffer sendebereit&lt;br /&gt;
  TXBUF1 = c;&lt;br /&gt;
}     &lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Senden eines Strings ==&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
void SendUSART0(char* str)             // einen string über die serielle schnittstelle (USART0) senden&lt;br /&gt;
{&lt;br /&gt;
  while (*str != 0)&lt;br /&gt;
  {&lt;br /&gt;
    while (!(IFG1 &amp;amp; UTXIFG0));         // warten, bis USART0 TX-buffer sendebereit&lt;br /&gt;
    TXBUF0 = *str++;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void SendUSART1(char* str)             // einen string über die serielle schnittstelle (USART1) senden&lt;br /&gt;
{&lt;br /&gt;
  while (*str != 0)&lt;br /&gt;
  {&lt;br /&gt;
    while (!(IFG2 &amp;amp; UTXIFG1));         // warten, bis USART1 TX-buffer sendebereit&lt;br /&gt;
    TXBUF1 = *str++;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Empfangen eines Bytes (interruptgesteuert)  // Receiving a byte-&amp;gt; Interrupt controlled ==&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
/*Hab diese Interrupt Funktion für meine I²C Kommunikation verwendet&lt;br /&gt;
Startcondition wird erkannt, aber nicht Stop, da man die Flanken(die den&lt;br /&gt;
interrupt auslösen) umkehren müsste, aber dann keine Startkondition erkannt werden kann.&lt;br /&gt;
&lt;br /&gt;
Hab mir jetzt nicht die mühe gemacht alles rauszupicken was ihr nicht braucht.&lt;br /&gt;
Wer sich auskennt, kann das auch selber machen.&lt;br /&gt;
&lt;br /&gt;
Das Busy wird fürs stretching verwendet(CLK wird auf low gezogen)&lt;br /&gt;
*/  &lt;br /&gt;
&lt;br /&gt;
#pragma vector = PORT1_VECTOR           // Port 1 - Interrupt-Funktions-&amp;quot;Alias&amp;quot;&lt;br /&gt;
__interrupt void Interrupt_Port1()&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
//  I2CTransfer = 0;&lt;br /&gt;
&lt;br /&gt;
    TACTL |= TACLR;&lt;br /&gt;
    TACTL |= TAIE;&lt;br /&gt;
#ifdef WD&lt;br /&gt;
    WDTCTL = WDTPW + WDTCNTCL;&lt;br /&gt;
#endif&lt;br /&gt;
    &lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
  if ((P1IFG &amp;amp; 0x04) &amp;amp;&amp;amp; !(I2CCLK)) { //if startdataimpuls but clk low is detected --return--&lt;br /&gt;
    P1IFG &amp;amp;= ~0x0C;&lt;br /&gt;
    return;}&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
//    P1IE &amp;amp;= ~0x0C;&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
  if ((P1IFG &amp;amp; 0x04) &amp;amp;&amp;amp; I2CCLK)   //Start Condition       (I2CStart)&lt;br /&gt;
    {&lt;br /&gt;
      P1IFG &amp;amp;= ~0x0C;&lt;br /&gt;
      &lt;br /&gt;
//    I2CTransfer = 1;&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
        P1IE &amp;amp;= ~0x0C;&lt;br /&gt;
//        TACTL |= TACLR;&lt;br /&gt;
//        TACTL |= TAIE;&lt;br /&gt;
//        _EINT();&lt;br /&gt;
&lt;br /&gt;
      &lt;br /&gt;
/*#ifdef Debug&lt;br /&gt;
      P2OUT |= 0x04;&lt;br /&gt;
      P2DIR |= 0x04; &lt;br /&gt;
#endif*/&lt;br /&gt;
      &lt;br /&gt;
//      Wait(10);&lt;br /&gt;
//      while(I2CCLK)  {CheckTimer;}&lt;br /&gt;
&lt;br /&gt;
//      set_Busy;&lt;br /&gt;
  &lt;br /&gt;
      BitCnt = 0x01;&lt;br /&gt;
      ByteCnt = 0;&lt;br /&gt;
//      I2CByte = 0;&lt;br /&gt;
      StartCondition = 1;&lt;br /&gt;
//      CRCByte = 0x00;&lt;br /&gt;
      GetData = 0;&lt;br /&gt;
      I2CTransfer = 0;&lt;br /&gt;
    &lt;br /&gt;
//    clr_Busy;&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
        _DINT();&lt;br /&gt;
        P1IE |= 0x0C;&lt;br /&gt;
&lt;br /&gt;
      return;&lt;br /&gt;
    }&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
  P1IFG &amp;amp;= ~0x0C;&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
    TACTL |= TACLR;&lt;br /&gt;
    _EINT();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
  if (I2CCLK)&lt;br /&gt;
  {&lt;br /&gt;
  &lt;br /&gt;
 &lt;br /&gt;
      TACTL |= TAIE;&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    I2CByte &amp;lt;&amp;lt;= 1; &lt;br /&gt;
    if (I2CDAT){&lt;br /&gt;
      I2CByte += 0x01;&lt;br /&gt;
     }&lt;br /&gt;
    I2CTransfer = 1;&lt;br /&gt;
    while(I2CCLK) {CheckTimer;}&lt;br /&gt;
    set_Busy;&lt;br /&gt;
    BitCnt &amp;lt;&amp;lt;= 1;&lt;br /&gt;
  &lt;br /&gt;
    if(!(BitCnt == 0x00))&lt;br /&gt;
    {&lt;br /&gt;
      clr_Busy;  &lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
      _NOP();&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
  }&lt;br /&gt;
//----------------------------------------------------------------------------  &lt;br /&gt;
&lt;br /&gt;
P1DIR &amp;amp;= ~0x0C;&lt;br /&gt;
P1IFG = 0x00;&lt;br /&gt;
P1IE |= 0x0C;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Ermitteln der Temperatur ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
// von FJG info@aqua-sun.net :&lt;br /&gt;
// ---------------   Temperatur des Chips   ---------------------&lt;br /&gt;
&lt;br /&gt;
#define T_Faktor_a1000       ((long)103)     // REF 1,5V&lt;br /&gt;
#define T_Faktor_b1000       ((long)172)     // REF 2,5V&lt;br /&gt;
#define T_Faktor_c1000       ((long)278000)&lt;br /&gt;
&lt;br /&gt;
int Hole_Temp(void)       // Temperatur ch 10&lt;br /&gt;
{                         // Temp = N* 0,17193 -278  1000Temp = N*172 -278000 bei 2,5V&lt;br /&gt;
  long Temp_L;&lt;br /&gt;
  int  Temp , Delta ;&lt;br /&gt;
&lt;br /&gt;
  Start_AD();&lt;br /&gt;
&lt;br /&gt;
  Temp_L = ((long)ADC12MEM10 * T_Faktor_a1000) - T_Faktor_c1000 ;&lt;br /&gt;
  Temp   = (int)( Temp_L / 1000);&lt;br /&gt;
&lt;br /&gt;
  Delta = Read_EEPROM( EPROM_INTERN_BL1_R_ADR,DELTA_TEMP_ADR );    // falls Temp&lt;br /&gt;
                                                                   // Messung&lt;br /&gt;
  if( Delta &amp;lt;= 120 &amp;amp;&amp;amp; Delta &amp;gt;= 80 ) Delta -= 100 ; else Delta = 0; // ungenau war&lt;br /&gt;
                                                                   // siehe dazu TI&lt;br /&gt;
  return (Temp + Delta);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// INIT AD&lt;br /&gt;
// AD muss angesto�?en werden mit :   Start_AD()&lt;br /&gt;
&lt;br /&gt;
// #define ADC12TL0WERT15           (SHT1_8 + SHT0_3 + MSC + REFON + ADC12ON)&lt;br /&gt;
#define ADC12TL0WERT15           (SHT1_3 + SHT0_3 + MSC + REFON + ADC12ON)&lt;br /&gt;
#define ADC12TL0WERT25           (SHT1_3 + SHT0_3 + MSC + +REF2_5V + REFON + ADC12ON)&lt;br /&gt;
&lt;br /&gt;
//                        Start CH0 , ADC12SCBIT , SampleT , F/2 , MCLK , Sequenze of CH&lt;br /&gt;
#define ADC12CTL1WERT   ( CSTARTADD_0 + SHS_0 + SHP + ADC12DIV_1 + ADC12SSEL_2 + CONSEQ_1 )&lt;br /&gt;
&lt;br /&gt;
void adc12_init()           // ADC12CTL0 modifizieren nur mit ENC = 0&lt;br /&gt;
{&lt;br /&gt;
  ADC12CTL0   = 0x00;&lt;br /&gt;
  ADC12CTL1   = ADC12CTL1WERT ;&lt;br /&gt;
&lt;br /&gt;
  ADC12MCTL0  = INCH_0;                  &lt;br /&gt;
  ADC12MCTL1  = INCH_1;                  &lt;br /&gt;
  ADC12MCTL2  = INCH_2;&lt;br /&gt;
  ADC12MCTL3  = INCH_3;&lt;br /&gt;
  ADC12MCTL4  = INCH_4;&lt;br /&gt;
  ADC12MCTL5  = INCH_5;&lt;br /&gt;
  ADC12MCTL6  = INCH_6;&lt;br /&gt;
  ADC12MCTL7  = INCH_7;                  &lt;br /&gt;
  ADC12MCTL8  = INCH_8;                  // VeREF+&lt;br /&gt;
  ADC12MCTL9  = INCH_9;                  // VeREF-&lt;br /&gt;
&lt;br /&gt;
  ADC12MCTL10 = INCH_10 + SREF_1 ;&lt;br /&gt;
  ADC12MCTL11 = INCH_11 + SREF_1 +EOS;&lt;br /&gt;
&lt;br /&gt;
  ADC12IE     = 0x00;&lt;br /&gt;
  ADC12CTL0   = ADC12TL0WERT15 ;&lt;br /&gt;
  ADC12CTL0  |= 0x0003;      // ENC + ADC12SC = Enable Conversation + StartConversation&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// --------------------   Diverses AD_Wandler   --------------------&lt;br /&gt;
&lt;br /&gt;
void Start_AD(void)&lt;br /&gt;
{&lt;br /&gt;
  ADC12CTL0 &amp;amp;= ~ENC;&lt;br /&gt;
  ADC12CTL0 |= (ADC12SC+ENC);&lt;br /&gt;
  NOP();&lt;br /&gt;
  NOP();&lt;br /&gt;
  ADC12CTL0 &amp;amp;=~ADC12SC;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#ifndef TEST_AD&lt;br /&gt;
#define Ist_AD_Busy()        ( ADC12CTL1 &amp;amp; ADC12BUSY )&lt;br /&gt;
#else&lt;br /&gt;
int Ist_AD_Busy()&lt;br /&gt;
{&lt;br /&gt;
  if (ADC12CTL1 &amp;amp; ADC12BUSY)&lt;br /&gt;
  {&lt;br /&gt;
     printf(&amp;quot;\n\r... BUSY ...&amp;quot;); &lt;br /&gt;
     delay_ms(500);&lt;br /&gt;
     return(1);&lt;br /&gt;
  }&lt;br /&gt;
  return(0);&lt;br /&gt;
}&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Ansteuerung eines LCD &amp;amp;#8211; Zeichendisplays // Controlling the LCD character==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
  // hier nun der vollständige Code 14 Jan 08&lt;br /&gt;
  // von mir seinerseits entwickelt, ich hoffe, er ist eine Hilfe&lt;br /&gt;
 &lt;br /&gt;
  // Aquasun Germany  Remscheid  Franz-Josef Günther&lt;br /&gt;
  // Development info@aqua-sun.net&lt;br /&gt;
&lt;br /&gt;
  // LCD.h Header für Allgemeines zum LCD ab 02.12.04 Aquasun GUE&lt;br /&gt;
  // C-Compiler ICC&lt;br /&gt;
&lt;br /&gt;
  // -------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
  // Beispiel :&lt;br /&gt;
&lt;br /&gt;
int Aepfel = 8;&lt;br /&gt;
&lt;br /&gt;
print_LCD(&amp;quot;\nRotkaepchen hat %d Aepfel im Korb&amp;quot;,Aepfel);&lt;br /&gt;
&lt;br /&gt;
  // -------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;_const.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdarg.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt; STRING.H&amp;gt;&lt;br /&gt;
#include &amp;lt; stdio.h &amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define LCD_MAX          8&lt;br /&gt;
#define Mem_LCD         16&lt;br /&gt;
&lt;br /&gt;
#ifndef Mem_LCD&lt;br /&gt;
#define Mem_LCD 20&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
    Header für 8 x 7 Segmentanzeigen 2 MUX MSP430 x4xx&lt;br /&gt;
&lt;br /&gt;
    V3 = V1 (VDD) , V5 = 0 ,&lt;br /&gt;
&lt;br /&gt;
    für : LCD siehe TI Info dazu,&lt;br /&gt;
    für : LED&#039;s :&lt;br /&gt;
&lt;br /&gt;
    LED mit gemeinsamer Kathode, SP über Buffer 74HC245 (8x) o.ä.&lt;br /&gt;
    /G=L , DIR=H A ==&amp;gt; B an 5V , COM mit Emitterfolger PNP ViL=0,8V ViH=2V&lt;br /&gt;
&lt;br /&gt;
    LED mit gemeinsamer Anode, COM über PNP Transistor invertiert&lt;br /&gt;
    und SP über ULN2804(8x) getrieben&lt;br /&gt;
            _   ___   ___   ___&lt;br /&gt;
    COM0 :   |_|   |_|   |_|&lt;br /&gt;
            ____   ___   ___&lt;br /&gt;
    COM1 :      |_|   |_|   |_|&lt;br /&gt;
             __    __    __&lt;br /&gt;
    SPon :  |  |__|  |__|  |__| mit COM0&lt;br /&gt;
&lt;br /&gt;
    SPin :   0  1  2  3  4  5  6  7    8  9 10 11 12 13 14 15&lt;br /&gt;
    COM0 :  1a 1b 1c 1d 1e 1f 1g 1h   2a 2b 2c 2d 2e 2f 2g 2h&lt;br /&gt;
    COM1 :  5a 5b 5c 5d 5e 5f 5g 5h   6a 6b 6c 6d 6e 6f 6g 6h&lt;br /&gt;
&lt;br /&gt;
    SPin :  16 17 18 19 20 21 22 23   24 25 26 27 28 29 30 31&lt;br /&gt;
    COM0 :  3a 3b 3c 3d 3e 3f 3g 3h   4a 4b 4c 4d 4e 4f 4g 4h&lt;br /&gt;
    COM1 :  7a 7b 7c 7d 7e 7f 7g 7h   8a 8b 8c 8d 8e 8f 8g 8h&lt;br /&gt;
&lt;br /&gt;
    COM        3 2   1  0   3 2   1  0&lt;br /&gt;
    MAP 0A0    - -   8h 4h  - -   8g 4g&lt;br /&gt;
        09F    - -   8f 4f  - -   8e 4e&lt;br /&gt;
        09E    - -   8d 4d  - -   8c 4c&lt;br /&gt;
        09D    - -   8b 4b  - -   8a 4a&lt;br /&gt;
&lt;br /&gt;
        09C    - -   7h 3h  - -   7g 3g&lt;br /&gt;
        09B    - -   7f 3f  - -   7e 3e&lt;br /&gt;
        09A    - -   7d 3d  - -   7c 3c&lt;br /&gt;
        099    - -   7b 3b  - -   7a 3a&lt;br /&gt;
&lt;br /&gt;
        098    - -   6h 2h  - -   6g 2g&lt;br /&gt;
        097    - -   6f 2f  - -   6e 2e&lt;br /&gt;
        096    - -   6d 2d  - -   6c 2c&lt;br /&gt;
        095    - -   6b 2b  - -   6a 2a&lt;br /&gt;
&lt;br /&gt;
        094    - -   5h 1h  - -   5g 1g&lt;br /&gt;
        093    - -   5f 1f  - -   5e 1e&lt;br /&gt;
        092    - -   5d 1d  - -   5c 1c&lt;br /&gt;
        091    - -   5b 1b  - -   5a 1a&lt;br /&gt;
&lt;br /&gt;
             ---a----&lt;br /&gt;
            |        |&lt;br /&gt;
          f |        | b&lt;br /&gt;
            |        |&lt;br /&gt;
             ---g----&lt;br /&gt;
            |        |&lt;br /&gt;
          e |        | c&lt;br /&gt;
            |        |    _&lt;br /&gt;
              ---d---    | | h&lt;br /&gt;
                          -&lt;br /&gt;
&lt;br /&gt;
*/&lt;br /&gt;
#define a0      0x01  // Char durch rechtsschiften &amp;amp; 0x..&lt;br /&gt;
#define b0      0x10&lt;br /&gt;
#define c0      0x02&lt;br /&gt;
#define d0      0x20&lt;br /&gt;
#define e0      0x04&lt;br /&gt;
#define f0      0x40&lt;br /&gt;
#define g0      0x08&lt;br /&gt;
#define h0      0x80&lt;br /&gt;
&lt;br /&gt;
#define ch_0    ( e0+f0+a0+b0+c0+d0 )&lt;br /&gt;
#define ch_1    ( b0+c0 )&lt;br /&gt;
#define ch_2    ( a0+b0+g0+e0+d0 )&lt;br /&gt;
#define ch_3    ( a0+b0+g0+c0+d0 )&lt;br /&gt;
#define ch_4    ( f0+g0+b0+c0 )&lt;br /&gt;
#define ch_5    ( a0+f0+g0+c0+d0 )&lt;br /&gt;
#define ch_6    ( a0+f0+c0+d0+e0+g0 )&lt;br /&gt;
#define ch_7    ( a0+b0+c0 )&lt;br /&gt;
#define ch_8    ( a0+b0+c0+d0+e0+f0+g0 )&lt;br /&gt;
#define ch_9    ( a0+b0+c0+f0+g0 )&lt;br /&gt;
&lt;br /&gt;
#define ch_a    ( a0+b0+c0+d0+e0+g0 )&lt;br /&gt;
#define ch_A    ( e0+f0+a0+b0+c0+g0 )&lt;br /&gt;
#define ch_B    ( a0+b0+c0+d0+e0+f0+g0 )&lt;br /&gt;
#define ch_b    ( f0+e0+d0+c0+g0 )&lt;br /&gt;
#define ch_c    ( g0+e0+d0 )&lt;br /&gt;
#define ch_C    ( a0+f0+e0+d0 )&lt;br /&gt;
#define ch_d    ( b0+c0+d0+e0+g0 )&lt;br /&gt;
#define ch_D    ( e0+f0+a0+b0+c0+d0 )&lt;br /&gt;
#define ch_e    ( f0+e0+d0+a0+b0+g0 )&lt;br /&gt;
#define ch_E    ( a0+f0+g0+d0+e0 )&lt;br /&gt;
#define ch_F    ( a0+f0+g0+e0 )&lt;br /&gt;
#define ch_G    ( a0+f0+c0+d0+e0+g0 )&lt;br /&gt;
#define ch_g    ( a0+b0+c0+d0+f0+g0 )&lt;br /&gt;
#define ch_h    ( f0+c0+e0+g0 )&lt;br /&gt;
#define ch_H    ( f0+c0+e0+g0+b0 )&lt;br /&gt;
#define ch_I    ( f0+e0 )&lt;br /&gt;
#define ch_i    ( e0 )&lt;br /&gt;
#define ch_k    ( b0+e0+f0+g0 )&lt;br /&gt;
#define ch_L    ( f0+e0+d0 )&lt;br /&gt;
#define ch_l    ( b0+c0 )&lt;br /&gt;
#define ch_M    ( c0+b0+e0+f0 )&lt;br /&gt;
&lt;br /&gt;
#define ch_n    ( e0+g0+c0 )&lt;br /&gt;
#define ch_N    ( a0+b0+c0+e0+f0 )&lt;br /&gt;
#define ch_o    ( e0+g0+c0+d0 )&lt;br /&gt;
#define ch_O    ( e0+f0+a0+b0+c0+d0 )&lt;br /&gt;
#define ch_P    ( e0+f0+a0+b0+g0 )&lt;br /&gt;
#define ch_r    ( g0+e0 )&lt;br /&gt;
#define ch_S    ( a0+f0+g0+c0+d0 )&lt;br /&gt;
#define ch_T    ( a0+f0+e0 )&lt;br /&gt;
#define ch_U    ( f0+e0+d0+c0+b0 )&lt;br /&gt;
#define ch_u    ( e0+d0+c0 )&lt;br /&gt;
#define ch_X    ( b0+g0+e0 )&lt;br /&gt;
#define ch_Y    ( f0+g0+b0+c0+d0 )&lt;br /&gt;
#define ch_Z    ( a0+b0+g0+e0+d0 )&lt;br /&gt;
#define ch_Blank  0&lt;br /&gt;
#define Unter_  ( d0 )&lt;br /&gt;
#define DP_Pkt  ( h0 )&lt;br /&gt;
#define Minus   ( g0 )&lt;br /&gt;
#define Tilde   ( a0+g0+d0 )&lt;br /&gt;
#define GLEICH  ( g0+d0 )&lt;br /&gt;
#define FRAGE   ( a0+f0+g0+c0+d0+h0 )&lt;br /&gt;
&lt;br /&gt;
// #define Digi_X1ste         LCDM17       // die erste freie LCD_Mem_Stelle 18,19,20&lt;br /&gt;
                                           // in lcd_init() auf 0&lt;br /&gt;
&lt;br /&gt;
// extern unsigned int Digi_X;             // für LCD&lt;br /&gt;
&lt;br /&gt;
const char  letter[] = &amp;quot;0123456789 _.-~?=AaBbCcDdEeFGgHhIiKkLlMmNnOoPRrSsTtUuxXYyZz&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
const int hex_Wert[] = {&lt;br /&gt;
      ch_0,    ch_1, ch_2, ch_3, ch_4, ch_5, ch_6, ch_7, ch_8, ch_9,&lt;br /&gt;
      ch_Blank, Unter_, DP_Pkt, Minus, Tilde, FRAGE , GLEICH ,&lt;br /&gt;
      ch_A, ch_a, ch_B, ch_b, ch_C, ch_c, ch_D, ch_d, ch_E, ch_e, ch_F, ch_G, ch_g,&lt;br /&gt;
      ch_H, ch_h, ch_I, ch_i, ch_k, ch_k, ch_L, ch_l , ch_M, ch_M, ch_N, ch_n, ch_O, ch_o,&lt;br /&gt;
      ch_P, ch_r, ch_r, ch_S, ch_S, ch_T, ch_T, ch_U, ch_u, ch_X, ch_X,&lt;br /&gt;
      ch_Y, ch_Y, ch_Z , ch_Z  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void All_LCD(void);&lt;br /&gt;
void Clear_LCD_M(void);                     // Clears LCD memory&lt;br /&gt;
void Clear_LCD(void);&lt;br /&gt;
void lcd_init(void); in ini&lt;br /&gt;
void Write_LCD_Hex(int Digit_n , int HEX_Zeichen);&lt;br /&gt;
void SetzeDP( int welches_Displ);&lt;br /&gt;
int putchar_LCD(char);&lt;br /&gt;
int print_LCD(CONST char *fmt, ...)  ;      // LCD 1-7 Digit nur realisiert sonst 1...11&lt;br /&gt;
extern int _print(void (*_put)(char), const char *fmt, va_list va);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    // ----------------------------------------&lt;br /&gt;
&lt;br /&gt;
void Clear_LCD_M(void)&lt;br /&gt;
{&lt;br /&gt;
    int i;&lt;br /&gt;
    for (i =0; i&amp;lt;Mem_LCD; i++) LCDMEM[i] = 0;   // Mem_LCD extern , abhängig vom Display&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
    // ----------------------------------------&lt;br /&gt;
&lt;br /&gt;
void Clear_LCD(void)&lt;br /&gt;
{&lt;br /&gt;
      print_LCD(&amp;quot;\n_&amp;quot;);                     // beim Cursor wird DIGIT_X nicht weitergezählt&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
    // ----------------------------------------&lt;br /&gt;
&lt;br /&gt;
void All_LCD(void)                          // alle = 8888..&lt;br /&gt;
{&lt;br /&gt;
    int i;&lt;br /&gt;
    for (i=0; i&amp;lt;Mem_LCD; i++) LCDMEM[i] = 0xFF;   // Mem_LCD extern , abhängig vom Display&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
    // ----------------------------------------&lt;br /&gt;
&lt;br /&gt;
int putchar_LCD(char c_in)&lt;br /&gt;
{&lt;br /&gt;
                                            //  Digi_X  == LCDM17&lt;br /&gt;
    int i, leng;&lt;br /&gt;
    char c = c_in;&lt;br /&gt;
    leng = strlen(letter);                  // Länge ohne /0 , 1..&lt;br /&gt;
&lt;br /&gt;
      if( (c==&#039;\n&#039;) || (c==&#039;\r&#039;))           // nichts gefunden =&amp;gt; CLR_Displ&lt;br /&gt;
        {&lt;br /&gt;
          Digi_X =1;  Clear_LCD_M(); return c;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    for(i=0;i&amp;lt;leng;i++) { if( c == letter[i] ) break; }        // Char gefunden&lt;br /&gt;
&lt;br /&gt;
    if(i == leng)&lt;br /&gt;
      {&lt;br /&gt;
        for(i=0;i&amp;lt;leng;i++) { if( &#039; &#039; == letter[i] ) break; }  // Char &#039; &#039; als Ersatz&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
    if(i&amp;lt;leng)                              // es gibt &#039;.&#039; als Ersatz&lt;br /&gt;
      {&lt;br /&gt;
        Write_LCD_Hex((int)Digi_X , i);     // Digi beschreiben oder löschen&lt;br /&gt;
                                            // if(Digi_X) Write_LCD_Hex(Digi_X , i);&lt;br /&gt;
        if(C != &#039;_&#039;)Digi_X++;&lt;br /&gt;
        if(Digi_X &amp;gt; LCD_MAX) Digi_X =1;     // if(Digi_X &amp;gt;= Mem_LCD) Digi_X =1;&lt;br /&gt;
      }&lt;br /&gt;
    return c;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
    // ----------------------------------------&lt;br /&gt;
&lt;br /&gt;
int print_LCD(CONST char *fmt, ...)&lt;br /&gt;
{&lt;br /&gt;
    va_list va;&lt;br /&gt;
    int val;&lt;br /&gt;
&lt;br /&gt;
    va_start(va, fmt);&lt;br /&gt;
    val = _print((void (*)(char))putchar_LCD, fmt, va);&lt;br /&gt;
    va_end(va);&lt;br /&gt;
&lt;br /&gt;
    return val;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
   // ----------------------------------------&lt;br /&gt;
&lt;br /&gt;
void lcd_init(void)             // LCD init&lt;br /&gt;
{&lt;br /&gt;
 LCDCTL=0xAD;                   // LCDM567.2,LCDM567.0,LCDM234.1,LCDM234.0,LCDM0&lt;br /&gt;
 LCDM1 =0x00;                   // 0xAD = 101 01 101&lt;br /&gt;
 LCDM2 =0x00;                   // 101 = LCDP2 ,0, LCDP0 =&amp;gt; S0..S31&lt;br /&gt;
 LCDM3 =0x00;                   //  01 = LCDMX1,LCDMX0   =&amp;gt; 2-mux&lt;br /&gt;
 LCDM4 =0x00;                   // 101 = LCDSON,x,LCDON Segments ON ,x,LCD ON&lt;br /&gt;
 LCDM5 =0x00;&lt;br /&gt;
 LCDM6 =0x00; LCDM7 =0x00; LCDM8 =0x00; LCDM9 =0x00; LCDM10 =0x00;LCDM11 =0x00;&lt;br /&gt;
 LCDM12=0x00; LCDM13=0x00; LCDM14=0x00; LCDM15=0x00; LCDM16=0x00; LCDM17=0x00;&lt;br /&gt;
 LCDM18=0x00; LCDM19=0x00; LCDM20=0x00;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
   // ----------------------------------------&lt;br /&gt;
&lt;br /&gt;
void Write_LCD_Hex(int Digit_n , int char_Nr)   // Digit1 bis 4 und 5 bis 8&lt;br /&gt;
{&lt;br /&gt;
  int i ,i_End , ch , Maske_loesch , Maske_setz ;&lt;br /&gt;
&lt;br /&gt;
  if((Digit_n == 0 ) || (Digit_n &amp;gt; LCD_MAX))&lt;br /&gt;
    {&lt;br /&gt;
        Clear_LCD_M(); i=0;&lt;br /&gt;
    }&lt;br /&gt;
   else i= (Digit_n - 1);                   // Startadresse = Digit_n x4 siehe unten&lt;br /&gt;
&lt;br /&gt;
  if(Digit_n &amp;lt; (LCD_MAX/2+1))               // Digit 1 ... 4 , i 0...3&lt;br /&gt;
    {&lt;br /&gt;
        Maske_setz   = 0x0011;&lt;br /&gt;
        Maske_loesch = 0x00FF - Maske_setz ;&lt;br /&gt;
        ch           = hex_Wert[char_Nr];&lt;br /&gt;
    } else                                  // Digit 5 ... 8&lt;br /&gt;
    {&lt;br /&gt;
        Maske_setz   = 0x0022;&lt;br /&gt;
        Maske_loesch = 0x00FF - Maske_setz ;&lt;br /&gt;
        ch           = hex_Wert[char_Nr] &amp;lt;&amp;lt; 1;&lt;br /&gt;
        i           -= (LCD_MAX/2) ;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
  i &amp;lt;&amp;lt;= 2; i_End = i +4;                    // Berechnung der Start- und End -adresse&lt;br /&gt;
&lt;br /&gt;
  for(; i &amp;lt; i_End;i++)&lt;br /&gt;
    {&lt;br /&gt;
       LCDMEM[i] &amp;amp;= Maske_loesch;&lt;br /&gt;
       LCDMEM[i] |= ( ch &amp;amp; Maske_setz );&lt;br /&gt;
       ch &amp;gt;&amp;gt;=1;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
  // -----------------------------------------------&lt;br /&gt;
&lt;br /&gt;
void SetzeDP( int welches_Displ)          // Displ 8 , 7 , 6 ...&lt;br /&gt;
{&lt;br /&gt;
  int i , i1;&lt;br /&gt;
    for (i=0,i1=1;i&amp;lt;8;i++,i1 &amp;lt;&amp;lt;=1)&lt;br /&gt;
      {&lt;br /&gt;
        if(welches_Displ &amp;amp; i1)&lt;br /&gt;
        switch(i)&lt;br /&gt;
         {&lt;br /&gt;
           case 0 : LCDM4  |= 0x10; break;&lt;br /&gt;
           case 1 : LCDM8  |= 0x10; break;&lt;br /&gt;
           case 2 : LCDM12 |= 0x10; break;&lt;br /&gt;
           case 3 : LCDM16 |= 0x10; break;&lt;br /&gt;
           case 4 : LCDM4  |= 0x20; break;&lt;br /&gt;
           case 5 : LCDM8  |= 0x20; break;&lt;br /&gt;
           case 6 : LCDM12 |= 0x20; break;&lt;br /&gt;
           case 7 : LCDM16 |= 0x20; break;&lt;br /&gt;
           default: break;&lt;br /&gt;
         }&lt;br /&gt;
      }  // for&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
  // ------------------  ENDE  ----------------------&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
[[Kategorie:MSP430]]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=AVRDUDE&amp;diff=56975</id>
		<title>AVRDUDE</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=AVRDUDE&amp;diff=56975"/>
		<updated>2011-05-02T19:02:16Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: /* AVRDUDE mit Arduino Bootloader benutzen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Beschreibung ==&lt;br /&gt;
AVRDUDE (http://www.nongnu.org/avrdude/) ist eine Programmiersoftware für Atmel [[AVR]] Controller. &lt;br /&gt;
&lt;br /&gt;
Funktionen unter Anderem: &lt;br /&gt;
&lt;br /&gt;
* Übertragen von Programmcode in den Flash-Speicher&lt;br /&gt;
* Auslesen ungeschützen Codes aus dem Flash&lt;br /&gt;
* Setzen und Lesen von Fuse- und Lockbits (Siehe auch: [[AVR_Fuses#Vergleich_der_Fuses_bei_verschiedenen_Programmen|Vergleich der Fuses bei verschiedenen Programmen]])&lt;br /&gt;
* Schreiben und Lesen des EEPROMs&lt;br /&gt;
&lt;br /&gt;
AVRDUDE kann das [[STK500]] (auch mit Firmware 2.x als stk500v2), das Atmel AVRISP (auch mit Firmware 2.x als avrispv2 o.ä.), das Atmel AVRISP MKII (USB Ansteuerung mittels lib-usb bzw. lib-usb-W32), [[AVR_In_System_Programmer#USB | AVR910-kompatible]] Programmierer, den [[AVR Butterfly]]/AVR109-kompatible Bootloader, [[STK200]]-Programmierdongles und verschiedene andere Parallelport-Adapter sowie &amp;quot;serielle Statusportprogrammierer&amp;quot; (Siprog) ansteuern. Auch das Atmel JTAGICE (oder Nachbauten wie Bootice oder Evertool), Atmel JTAGICE-MKII und der AVR Dragon können als Programmierhardware genutzt werden.&lt;br /&gt;
&lt;br /&gt;
Das Programm ist unter MS-Windows (Cygwin nicht erforderlich), Linux, BSD, Solaris und Mac OS X lauffähig. Die Version für MS-Windows ist im [[WinAVR]]-Paket enthalten. Der Quellcode ist frei verfügbar (Lizenz beachten).&lt;br /&gt;
&lt;br /&gt;
Da alle AVRDUDE-Funktionen über Kommandozeilenparamter gesteuert werden können, eignet es sich gut zur Integration in Makefiles. Beispiele finden sich in der Makefile-Vorlage von [[WinAVR]] und Mfile. &lt;br /&gt;
&lt;br /&gt;
Die gesamte Konfiguration liegt in einer Textdatei (avrdude.conf), so dass sich bei Bedarf ein beliebiger neuer Parallelport-Programmierdongle oder auch ein noch nicht unterstützter AVR-Controller ergänzen lassen. Die Syntax für die Definition eines AVR-Controllers lehnt sich an die Datenblatt-Tabelle für die serielle Programmierung an, so dass man praktisch nur das Datenblatt &amp;quot;intelligent&amp;quot; abtippen muss.&lt;br /&gt;
&lt;br /&gt;
Für die Ansteuerung von Parallelport-Adaptern unter MS-Windows NT/2000/XP wird ein spezieller Porttreiber (giveio) mitgeliefert. Bei der Installation von [[WinAVR]] wird giveio bereits mitinstalliert. &lt;br /&gt;
&lt;br /&gt;
Programmer mit üblicher serieller Schnittstelle (RS232) benötigen keine zusätzliche Software oder Treiber zum Betrieb mit AVRDUDE. &lt;br /&gt;
&lt;br /&gt;
Für Hardware mit USB-Anschluss muss die lib-usb bzw. lib-usb-win32 installiert sein.&lt;br /&gt;
&lt;br /&gt;
===GUIs===&lt;br /&gt;
Bei [[WinAVR]] wird die grafische Oberfläche avrdude-gui.exe mitgeliefert.&lt;br /&gt;
&lt;br /&gt;
Für Windows, Linux und andere Betriebssysteme gibt zwei weitere GUIs: den in Java geschriebene [[Burn-o-mat|AVR Burn-O-Mat]] und den [http://www.soft-land.de/index.php?page=avrburner avrburner].&lt;br /&gt;
&lt;br /&gt;
Für Mac OS X gibt es noch [http://www.vonnieda.org/software/avrfuses AVRFuses.app]. AVRFuses muss beim ersten Starten auf den verwendeten Programmer und den Speicherort von AVRDUDE eingestellt werden.&lt;br /&gt;
&lt;br /&gt;
GUIs vereinfachen vor allem Programmieren der Fuses.&lt;br /&gt;
&lt;br /&gt;
== Kurzanleitung für Linux und STK200 ==&lt;br /&gt;
&lt;br /&gt;
Dazu muss erst ein Hardware-Link auf die Printerport-Treiber eingerichtet werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
su&lt;br /&gt;
mknod /dev/parport0 c 99 0&lt;br /&gt;
chmod a+rw /dev/parport0&lt;br /&gt;
avrdude -p m8535 -c stk200 -e -U qqtraff.hex&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hinweis :&lt;br /&gt;
Bei USB Programmern ist zu beachten, dass diese durch das Betriebssystem auf einen anderen Port gelegt werden können, als im Beispiel angegeben.&lt;br /&gt;
Diesen Port kann man unter Anderem &amp;quot;im Terminal&amp;quot; mit dem Befehl&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
user@server: dmesg&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
ermitteln.&lt;br /&gt;
Alternativ kann man sich eine Auflistung der Ports, im Verzeichnis &amp;quot;/dev&amp;quot; anzeigen lassen:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
user@server: ls /dev/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Sollte man nicht sicher sein, auf welchem Port der Programmer liegt, kann man den Programmer nochmals ausstecken und &amp;quot;ls /dev/&amp;quot; ausführen. Der nun Fehlende Port, ist der Programmerport.&lt;br /&gt;
Diesen Port muss man statt &amp;quot;parport0&amp;quot; in die oben beschriebenen Terminalkommandos einsetzen.&lt;br /&gt;
&lt;br /&gt;
Siehe auch : &lt;br /&gt;
* [http://wiki.ctbot.de/index.php/AVR_ISP_Programmer#BlueMP3_bzw._STK200_kompatible_Flasher weitere Beispiele für avrdude Kommandos (http://wiki.ctbot.de/index.php)]&lt;br /&gt;
* [[AVR_In_System_Programmer#STK200-kompatibel]]&lt;br /&gt;
* http://www.mikrocontroller.net/topic/200390#new&lt;br /&gt;
&lt;br /&gt;
== Tipps + Tricks ==&lt;br /&gt;
&lt;br /&gt;
=== [[AVR_In_System_Programmer#Parallelport|Parallelport-Programmer]] an aktuellen PCs ===&lt;br /&gt;
Aktuelle PCs sind einfach zu schnell mit dem Bitgewackel an der parallelen Schnittstelle, vor allem für AVRs, die noch mit den 1 MHz im Auslieferungszustand laufen (maximal zulässiger ISP-Takt &amp;lt; 250 kHz). Neuere Versionen von avrdude unterstützen zu diesem Zweck eine Option &#039;&#039;&#039;-i &amp;lt;N&amp;gt;&#039;&#039;&#039;, wobei &amp;lt;N&amp;gt; die Anzahl der Mikrosekunden bezeichnet, die beim Bitwackeln zusätzlich zu warten ist. Einfach mal mit -i 10 anfangen und dann entweder die Fuses auf die Ziel-Taktfrequenz umstellen (falls diese wesentlich höher sein wird als die 1 MHz), oder sukkzessive mit kleineren Werten testen ([http://www.mikrocontroller.net/topic/83524#699933 Forenbeitrag von Jörg]).&lt;br /&gt;
&lt;br /&gt;
Die Option -i ist auch nützlich bei AVRs, die für einen langsamen Takt konfiguriert sind. Bei einem ATmega8, der mit einem 32.768 kHz Quarz läuft, kann es z.B. notwendig sein, die Option -i 90 zu verwenden. Den Zahlenwert ggf. ausprobieren.&lt;br /&gt;
&lt;br /&gt;
Manche Programmer werten die Option -i manchmal nicht aus, dann sollte man einen anderen Programmer versuchen.&lt;br /&gt;
&lt;br /&gt;
Beim USBTINY und USBASP kann man die Geschwindigkeit der SPI-Schnittstelle mit dem Parameter -B [Periodendauer in Mikrosekunden] begrenzen. Da beide Geräte durch Interrupts der Software-USB-Schnittstelle stark belastet werden, handelt es sich hier um die Maximalbitrate.&lt;br /&gt;
&lt;br /&gt;
Unter WinXPsp2 auf einem Thinkpad T40 lies sich die &amp;quot;avrdude: AVR device not responding&amp;quot;-Meldung beheben durch Ändern von Gerätemanager--&amp;gt;Ltp1--&amp;gt;Eigenschaften--&amp;gt;Anschlusseinstellungen--&amp;gt;Interrupt-nie-verwenden in &amp;quot;Jeden dem Anschluss zugewiesenem Interrupt verwenden&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===USB Programmer===&lt;br /&gt;
Ein Selbstbau USB-Programmer ist unter&lt;br /&gt;
[http://www.rototron.info/?Page=USBAVR/USBAVR.aspx http://www.rototron.info]&lt;br /&gt;
zu finden. Er läuft auch unter VISTA und benötigt mit der neuesten AVRDUDE Version keinen Treiber, da er im HID-Modus betrieben wird.&lt;br /&gt;
&lt;br /&gt;
==== libusb0.dll wird bei WinAvr 20070525 nicht gefunden====&lt;br /&gt;
[http://www.mikrocontroller.net/topic/83524#701461 Forenbeitrag von Paul]: Habe leider noch etwas zu bemängeln, und zwar meckerte avrdude, dass es die &amp;quot;libusb0.dll&amp;quot; nicht fand. Musste dann erst noch manuell den Pfad c:\winavr\utils\libusb\bin in die autoxecec.bat eintragen. Siehe auch [http://www.avrfreaks.net/index.php?name=PNphpBB2&amp;amp;file=viewtopic&amp;amp;p=373283 Diskussion bei www.avrfreaks.net]&lt;br /&gt;
&lt;br /&gt;
====Aufruf unter Linux als user (non-root)====&lt;br /&gt;
&lt;br /&gt;
Unter Linux kann häufig avrdude nur als user &#039;root&#039; auf den USB-Programmer zugreifen. Als normaler User bekommt man eine Fehlermeldung wie:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#avrdude -c usbtiny -p m8&lt;br /&gt;
 &lt;br /&gt;
avrdude: error: usbtiny_transmit: &lt;br /&gt;
error sending control message: &lt;br /&gt;
Operation not permitted&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dies liegt daran, dass die device-nodes, die beim Einstecken des USB-Programmers von udev angelegt werden, root zugeordnet sind. Man kann dies ändern, indem man udev-Regeln für die verwendeten Programmer anlegt. Unter Debian muß man dazu nur eine neue Datei, z.&amp;amp;nbsp;B. 015_usbprog.rules unter /etc/udev/rules.d anlegen, z.&amp;amp;nbsp;B. mit folgenden Inhalt:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Atmel AVR ISP mkII&lt;br /&gt;
SUBSYSTEM==&amp;quot;usb&amp;quot;, SYSFS{idVendor}==&amp;quot;03eb&amp;quot;, SYSFS{idProduct}==&amp;quot;2104&amp;quot;, GROUP=&amp;quot;users&amp;quot;, MODE=&amp;quot;0660&amp;quot; &lt;br /&gt;
&lt;br /&gt;
# usbprog bootloader&lt;br /&gt;
ATTRS{idVendor}==&amp;quot;1781&amp;quot;, ATTRS{idProduct}==&amp;quot;0c62&amp;quot;, GROUP=&amp;quot;users&amp;quot;, MODE=&amp;quot;0660&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
# USBasp programmer&lt;br /&gt;
ATTRS{idVendor}==&amp;quot;16c0&amp;quot;, ATTRS{idProduct}==&amp;quot;05dc&amp;quot;, GROUP=&amp;quot;users&amp;quot;, MODE=&amp;quot;0660&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
# USBtiny programmer&lt;br /&gt;
ATTRS{idVendor}==&amp;quot;1781&amp;quot;, ATTRS{idProduct}==&amp;quot;0c9f&amp;quot;, GROUP=&amp;quot;users&amp;quot;, MODE=&amp;quot;0660&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
habe den alten Inhalt nur auskommentiert, weil ich das ganze nur mit dem mkII testen konnte. ...Nur falls sich jemand beschweren sollte.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Atmel AVR ISP mkII&lt;br /&gt;
ATTRS{idVendor}==&amp;quot;03eb&amp;quot;, ATTRS{idProduct}==&amp;quot;2104&amp;quot;, GROUP=&amp;quot;users&amp;quot;, MODE=&amp;quot;0660&amp;quot; &lt;br /&gt;
 &lt;br /&gt;
# usbprog bootloader&lt;br /&gt;
ATTRS{idVendor}==&amp;quot;1781&amp;quot;, ATTRS{idProduct}==&amp;quot;0c62&amp;quot;, GROUP=&amp;quot;users&amp;quot;, MODE=&amp;quot;0660&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
# USBasp programmer&lt;br /&gt;
ATTRS{idVendor}==&amp;quot;16c0&amp;quot;, ATTRS{idProduct}==&amp;quot;05dc&amp;quot;, GROUP=&amp;quot;users&amp;quot;, MODE=&amp;quot;0660&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
# USBtiny programmer&lt;br /&gt;
ATTRS{idVendor}==&amp;quot;1781&amp;quot;, ATTRS{idProduct}==&amp;quot;0c9f&amp;quot;, GROUP=&amp;quot;users&amp;quot;, MODE=&amp;quot;0660&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Danach muss in der Regel der udev-Dienst neu gestartet werden, was -- je nach System -- mit einem der beiden folgenden Befehle funktionieren sollte (natürlich nur als root):&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 /etc/init.d/udev restart&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
oder &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 service udev restart&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;sudo /sbin/udevadm control --reload-rules&amp;lt;/pre&amp;gt; bei aktueller udev-version, oder&lt;br /&gt;
&amp;lt;pre&amp;gt;sudo /sbin/udevcontrol --reload-rules&amp;lt;/pre&amp;gt;, bei älteren udev-versionen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danach sollte der USB-Programmer erneut angeschlossen werden. Falls es immer noch nicht funktioniert kann es helfen, als GROUP &amp;quot;plugdev&amp;quot; statt &amp;quot;users&amp;quot; zu verwenden.&lt;br /&gt;
&lt;br /&gt;
Hiermit werden der AVR ISP mkII, der usbprog Bootloader, USBasp und USBtiny bekannt gemacht, so daß alle User in der Gruppe &amp;quot;users&amp;quot; darauf zugreifen können.&lt;br /&gt;
&lt;br /&gt;
Für weitere USB-Programmer muß man die entsprechende Zeile (mit ATTRS...) anlegen und die passenden Vendor und Product IDs eintragen.&lt;br /&gt;
&lt;br /&gt;
Siehe auch:&lt;br /&gt;
* [http://www.reactivated.net/writing_udev_rules.html Writing udev rules]&lt;br /&gt;
&lt;br /&gt;
=== Anzeige unterstützter AVRs ===&lt;br /&gt;
Wie die anderen Atmels bei avrdude heißen zeigt:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
avrdude -?&lt;br /&gt;
avrdude -p ?&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== neuere AVRs hinzufügen ===&lt;br /&gt;
Manch neueres Silizium wird nicht erkannt da sich z.T. die IDs geändert haben. Um diese erfolgreich zu Programmieren empfiehlt sich ein eigenes config-File zu verwenden. Darin werden die &#039;fehlenden&#039; CPUs ergänzt:&lt;br /&gt;
&lt;br /&gt;
z.B. ATmega168P (Programmierung wie ATmega168): einfach den ATmega168 Teil duplizieren und die entsprechenden Änderungen (id, desc, signature) vornehmen&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#------------------------------------------------------------&lt;br /&gt;
# ATmega168P&lt;br /&gt;
#------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
part&lt;br /&gt;
    id              = &amp;quot;m168p&amp;quot;;&lt;br /&gt;
    desc            = &amp;quot;ATMEGA168P&amp;quot;;&lt;br /&gt;
     has_debugwire = yes;&lt;br /&gt;
     flash_instr   = 0xB6, 0x01, 0x11;&lt;br /&gt;
     eeprom_instr  = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00,&lt;br /&gt;
	             0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF,&lt;br /&gt;
	             0x99, 0xF9, 0xBB, 0xAF;&lt;br /&gt;
    stk500_devcode  = 0x86;&lt;br /&gt;
    # avr910_devcode = 0x;&lt;br /&gt;
    signature       = 0x1e 0x94 0x0b;&lt;br /&gt;
&lt;br /&gt;
 ...&lt;br /&gt;
;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
danach kann, unter Angabe des neuen config-Files, auch ein ATmega168P programmiert werden, z.B.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
avrdude -pm168p -C ~/.avrdude.config.neu -cstk500v2 -v  -U flash:w:main.hex&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Anschluss an COM10 und höher (Windows) ===&lt;br /&gt;
&lt;br /&gt;
Wenn AVRDUDE unter Windows an COM10 und höher betrieben werden soll, ist eine andere Schreibweise für die Schnittstelle in der Kommandozeile nötig. Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
avrdude -c stk500v2 -p m16 -P \\.\com13 -uF -vvvv 2&amp;gt; logfile.txt&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird statt der gewohnten Schreibweise &#039;&#039;&#039;com13&#039;&#039;&#039; die spezielle Schreibweise  &#039;&#039;&#039;\\.\com13&#039;&#039;&#039; verwendet und es wird mit &#039;&#039;-vvvv 2&amp;gt; logfile.txt&#039;&#039; eine ausführliche Debugausgabe für Fragen im Forum erzeugt. Näheres hierzu in der  [http://www.mikrocontroller.net/topic/90401 Forumsdiskussion].&lt;br /&gt;
&lt;br /&gt;
=== AVRISPmkII + AVRDUDE + Window Vista (32) ===&lt;br /&gt;
&lt;br /&gt;
http://www.mikrocontroller.net/topic/126594#1157327&lt;br /&gt;
&lt;br /&gt;
=== &amp;quot;avrdude was compiled without usb support&amp;quot; ===&lt;br /&gt;
&lt;br /&gt;
Offenbar enthielt WinAVR-20100110 zunächst fälschlicherweise eine AVRDUDE Version ohne USB Support [http://www.mikrocontroller.net/topic/163022#1554907].&lt;br /&gt;
&lt;br /&gt;
Abhilfe:&lt;br /&gt;
 &lt;br /&gt;
1. WinAVR deinstallieren, gleiches Release (WinAVR-20100110) nocheinmal herunterladen und installieren (mindestens seit Anfang März 2010 enthält dieses Release avrdude in der Version 5.10 und bringt USB-Support mit).&lt;br /&gt;
&lt;br /&gt;
2. AVRDUDE selbst compilieren: http://www.mikrocontroller.net/topic/163675&lt;br /&gt;
&lt;br /&gt;
3. Compilierte Version 5.10 downloaden: http://www.mikrocontroller.net/topic/163675#1594689&lt;br /&gt;
&lt;br /&gt;
=== Textausgabe in Datei umleiten? ===&lt;br /&gt;
&lt;br /&gt;
Die Windows-&amp;quot;Shell&amp;quot; &#039;&#039;cmd&#039;&#039; benutzt für die Ausgabeumleitung die gleiche Syntax wie die Bourne-Shell (und damit auch&lt;br /&gt;
Bash): &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
programm &amp;gt;datei 2&amp;gt;&amp;amp;1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
zur Umleitung von STDOUT und STDERR in die gleiche Datei (Yalu in [http://www.mikrocontroller.net/topic/124509#1135568]).&lt;br /&gt;
&lt;br /&gt;
Beispiel für Windows ([http://www.mikrocontroller.net/topic/124509#1136322], [http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/redirection.mspx?mfr=true M$]):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
avrdude -c avrispmkII -p m8 -P usb:xx -v &amp;gt; &amp;quot;C:\output.txt&amp;quot; 2&amp;gt;&amp;amp;1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
oder nur STDERR in Datei umleiten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
avrdude -c avrispmkII -p m8 -P usb:xx -v 2&amp;gt; &amp;quot;C:\output.txt&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [http://www.franzis.de/elektronik/lernpakete-elektronik/lernpaket-mikrocontroller Franzis] bzw. [http://www.elo-web.de/elo/mikrocontroller-und-programmierung/avr-grundlagen/experimente-mit-dem-attiny13 ELO] Lernpaket Mikrocontroller (Attiny13) ===&lt;br /&gt;
&lt;br /&gt;
Markus hat in [http://www.mikrocontroller.net/topic/169549#1649459] einen Weg beschrieben, wie man den einfachen Programmieradapter des Lernpakets mit AVRDUDE ansteuern kann.&lt;br /&gt;
&lt;br /&gt;
Eine weitere Anleitung [http://www.elektronik-labor.de/AVR/AVRdude.html LP Mikrocontroller und Attiny45 mit Avrdude] gibt es von Ralf Beesner auf der Webseite des Entwicklers Burkhard Kainka. In &#039;&#039;avrdude.conf&#039;&#039; wird dabei ein neuer Programmieradapter namens &#039;&#039;burkhard&#039;&#039; hinzugefügt. Ein zweiter Eintrag &#039;&#039;burkhard2&#039;&#039; in dieser &#039;&#039;&#039;avrdude.conf&#039;&#039;&#039; ist für die Programmierung des Atmega8 auf dem Franzis Retro-Pong Bausatz mit Hilfe des &amp;quot;Mega8-ISP-Programmer&amp;quot; (Layout siehe ELO-Webseite) vorgesehen.&lt;br /&gt;
&lt;br /&gt;
=== AVRDUDE mit Arduino Bootloader benutzen ===&lt;br /&gt;
&lt;br /&gt;
Mit der Option &#039;&#039;-c stk500v1&#039;&#039; kann AVRDUDE den [[Bootloader]] in Arduino Boards ansprechen [http://www.mikrocontroller.net/topic/195963#1919654].&lt;br /&gt;
&lt;br /&gt;
Es existieren auch modifizierte Versionen von AVRDUDE, die einen Programmer namens &#039;&#039;arduino&#039;&#039; kennen (avrdude.conf untersuchen!). Damit lautet die Kommandozeile für ein Arduinoboard mit Atmega168 beispielsweise [http://www.neuraladvance.com/2010/04/08/using-avrdude-with-the-arduino-duemilanove/]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
avrdude -c arduino -p m168 -P usb -U flash:w:&amp;lt;filename&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Bootloader-Hacks von [http://www.ladyada.net/library/arduino/bootloader.html Ladyada] arbeiten nochmal etwas anders.&lt;br /&gt;
&lt;br /&gt;
Gelegentlich gibt es unter Windows Probleme mit der allgemeinen AVRDUDE Version und deren Handling der DTR/RTS Leitung ([[RS232]]). Es kann helfen unmittelbar von dem Absenden der Kommandozeile einen RESET auf dem Arduinoboard durchzuführen.&lt;br /&gt;
Ein kurzes Setzen der DTR Leitung auf HIGH bewirkt ein RESET. So ist es möglich eine .bat Datei zu erstellen mit folgendem Code: (com6 ist ein Virtueller USB Comport) &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mode com6 dtr=on&lt;br /&gt;
avrdude -c arduino -p m168 -P \\.\com6 -U flash:w:&amp;lt;filename&amp;gt;&lt;br /&gt;
if %ERRORLEVEL%==0 goto fertig&lt;br /&gt;
Pause&lt;br /&gt;
:fertig&lt;br /&gt;
exit&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== mysmartUSB V2.11 und ATtiny 13 ===&lt;br /&gt;
&lt;br /&gt;
mysmartUSB V2.11 verlangt -cavr910 als Programmer. Leider ist in avrdude&lt;br /&gt;
5.10 immer noch nich der ATtiny13 damit zu programmieren. Also in die&lt;br /&gt;
avrdude.conf folgendes mit unter ATtiny13 aufnehmen, so kann er dann&lt;br /&gt;
korrekt programmiert werden(inkl. Fuse Bits).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#------------------------------------------------------------&lt;br /&gt;
# ATtiny13&lt;br /&gt;
#------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
part&lt;br /&gt;
    id                  = &amp;quot;t13&amp;quot;;&lt;br /&gt;
    desc                = &amp;quot;ATtiny13&amp;quot;;&lt;br /&gt;
     has_debugwire = yes;&lt;br /&gt;
     flash_instr   = 0xB4, 0x0E, 0x1E;&lt;br /&gt;
     eeprom_instr  = 0xBB, 0xFE, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,&lt;br /&gt;
               0xBC, 0x0E, 0xB4, 0x0E, 0xBA, 0x0D, 0xBB, 0xBC,&lt;br /&gt;
               0x99, 0xE1, 0xBB, 0xAC;&lt;br /&gt;
    stk500_devcode      = 0x14;&lt;br /&gt;
    avr910_devcode      = 0x55;&lt;br /&gt;
......&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Achtung! Programmieren geht auch mit -cavr911. Allerdings geht das Fuse&lt;br /&gt;
setzen nicht und man bekommt eine Fehlermeldung.(Programm läuft aber)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Reading | ################################################## | 100%&lt;br /&gt;
0.12s&lt;br /&gt;
&lt;br /&gt;
avrdude: verifying ...&lt;br /&gt;
avrdude: 226 bytes of flash verified&lt;br /&gt;
avrdude: reading input file &amp;quot;0x7a&amp;quot;&lt;br /&gt;
avrdude: writing lfuse (1 bytes):&lt;br /&gt;
&lt;br /&gt;
Writing |  ***failed;&lt;br /&gt;
################################################## | 100% 0.00s&lt;br /&gt;
&lt;br /&gt;
avrdude: 1 bytes of lfuse written&lt;br /&gt;
avrdude: verifying lfuse memory against 0x7a:&lt;br /&gt;
avrdude: load data lfuse data from input file 0x7a:&lt;br /&gt;
avrdude: input file 0x7a contains 1 bytes&lt;br /&gt;
avrdude: reading on-chip lfuse data:&lt;br /&gt;
&lt;br /&gt;
Reading | ################################################## | 100%&lt;br /&gt;
0.00s&lt;br /&gt;
&lt;br /&gt;
avrdude: verifying ...&lt;br /&gt;
avrdude: 1 bytes of lfuse verified&lt;br /&gt;
avrdude: reading input file &amp;quot;0xff&amp;quot;&lt;br /&gt;
avrdude: writing hfuse (1 bytes):&lt;br /&gt;
&lt;br /&gt;
Writing |  ***failed;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
* Offizielle AVRDUDE Homepage unter http://www.nongnu.org/avrdude/&lt;br /&gt;
* User Manual (engl.) unter http://www.nongnu.org/avrdude/user-manual/avrdude.html#Top&lt;br /&gt;
* Kompilierte Windows Version mit USB Support http://yuki-lab.jp/hw/avrdude-GUI/avrdude-5.5-win32-bin.zip&lt;br /&gt;
* Kompilierte Windows Version avrdude 5.10 mit USB Support http://www.mikrocontroller.net/topic/163675#1594689&lt;br /&gt;
* Wer Interesse an der modifizierten Version von AVRDUDE und des AVR910-Programmer hat, kann sich bei http://www.fischl.de/thomas/elektronik/avr910e/ informieren. Der Programmer bleibt auch mit der Modifikation weiterhin kompatibel zu anderer Programmiersoftware.&lt;br /&gt;
* [[Burn-o-mat|AVR Burn-O-Mat]] GUI (Graphic User Interface) für AVRDUDE http://burn-o-mat.net mit FUSE-Editor (Java, für Windows und Linux)&lt;br /&gt;
* [http://www.soft-land.de/index.php?page=avrburner AVRBurner] Ponyprog ähnliche Oberfläche für AVRDUDE.&lt;br /&gt;
* [http://www.microstar.ir/download/SinaProg.zip SinaProg] SinaProg - avrdude GUI mit AVR Fuse Calculator.&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:AVR-Programmer und -Bootloader]]&lt;br /&gt;
[[Kategorie:Entwicklungstools]]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=AVR-GCC-Codeoptimierung&amp;diff=55956</id>
		<title>AVR-GCC-Codeoptimierung</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=AVR-GCC-Codeoptimierung&amp;diff=55956"/>
		<updated>2011-03-19T14:01:29Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: kleinere Schreibfehler korrigiert&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Entstanden aus diesem [http://www.mikrocontroller.net/topic/66690 Thread] sollen hier ein paar Hinweise/Erfahrungen gegeben werden, um den Quellcode in Punkto Größe und Geschwindigkeit zu optimieren. &#039;&#039;En detail&#039;&#039; ist das Thema komplex, da es stark von der Codeoptimierung des Compilers abhängt. Es ist im Einzelfall ratsam zu prüfen, ob die eigenen Maßnahmen auch erfolgreich waren. Die Diskussionen [http://www.mikrocontroller.net/topic/132624] bzw. [http://www.mikrocontroller.net/topic/180800#new] können als Anhaltspunkte dienen, wie eine solche Prüfung ablaufen kann.&lt;br /&gt;
&lt;br /&gt;
== Prinzipien der Optimierung ==&lt;br /&gt;
&lt;br /&gt;
Wie so oft sollte man nicht einfach wild drauf los optimieren und sich zunächst ein paar Dinge klar machen.&lt;br /&gt;
&lt;br /&gt;
* Warum will ich optimieren?&lt;br /&gt;
* Was kann man sinnvoll optimieren?&lt;br /&gt;
* Wieviel Rechenzeit oder Speicher soll dabei gespart werden?&lt;br /&gt;
* Wie kann optimiert werden?&lt;br /&gt;
* &amp;quot;Verfrühte Optimierung ist die Wurzel allen Übels&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Viele Optimierungen sind &amp;quot;Angst-Optimierungen&amp;quot;, die nicht wirklich nötig sind. Die Gefahr mit Optimierungen ist, den Code tot zu optimieren, sprich Lesbarkeit, Portierbarkeit und ggf. Fehlerfreiheit sinken massgeblich. Kurz und knapp in diesem [http://blogs.msdn.com/b/audiofool/archive/2007/06/14/the-rules-of-code-optimization.aspx BLOG] formuliert.&lt;br /&gt;
&lt;br /&gt;
=== Warum ===&lt;br /&gt;
&lt;br /&gt;
Optimieren sollte man nur, wenn&lt;br /&gt;
* der Speicher nicht mehr ausreicht (RAM, Flash)&lt;br /&gt;
* Die Laufzeit für bestimmte Programmteile zu groß wird und somit bestimmte (Echtzeit-)Ausgaben nicht im erforderlichen Zeitrahmen erledigt werden&lt;br /&gt;
&lt;br /&gt;
Weiter sollte man folgende Punkte gegeneinander abwägen:&lt;br /&gt;
&lt;br /&gt;
* Codeverbrauch&lt;br /&gt;
* Datenverbrauch. Statisch/Stack/Heap&lt;br /&gt;
* Mittlere Laufzeit/maximale Laufzeit&lt;br /&gt;
* Entwicklungszeit&lt;br /&gt;
* Portabilität (Compiler, Hardware, ...)&lt;br /&gt;
* Verständlichkeit der Quelle, siehe [[Strukturierte Programmierung auf Mikrocontrollern]] &lt;br /&gt;
* ABI-Konformität&lt;br /&gt;
&lt;br /&gt;
=== Was ===&lt;br /&gt;
&lt;br /&gt;
Die goldene Regle lautet: 90% der Rechenleistung werden in 10% des Codes verbraucht. Diese 10% muss man finden und zum richtigen Zeitpunkt optimieren. Der Rest muss nur sauber und lesbar geschrieben sein. Was jedoch nichts bringt, ist eine Funktion, die von 1 Minute Programmlaufzeit lediglich 1 Sekunde verbraucht, um den Faktor 10 schneller zu machen. Die Programmlaufzeit sinkt dann von 60 Sekunden auf 59.1 Sekunden. Der Aufwand, die Funktion um einen Faktor 10 schneller zu machen ist aber meistens beträchtlich!  Kann ich aber den Code, der für die 59 Sekunden verantwortlich ist um einen Faktor 10 schneller machen, dann sinkt die Gesamtlaufzeit von 60 Sekunden auf 6.9 Sekunden. Dort bringt Optimieren augenscheinlich viel mehr!&lt;br /&gt;
&lt;br /&gt;
Um die optimierungswürdigen Stellen zu finden, muss man sein Programm analysieren. Dazu gibt es verschiedene Möglichkeiten.&lt;br /&gt;
&lt;br /&gt;
====Speicherverbrauch nach Funktionen aufschlüsseln====&lt;br /&gt;
&lt;br /&gt;
;map-File:&lt;br /&gt;
:dort sind alle globalen und statischen Variablen enthalten. Eine Map-Datei kann mit den GNU-Tools während des Linkens angelegt werden:&lt;br /&gt;
::&amp;lt;pre&amp;gt;&amp;amp;gt; avr-gcc ... -Wl,-Map,foo.map&amp;lt;/pre&amp;gt;&lt;br /&gt;
: Die Option -Wl bewirkt, daß avr-gcc die angehängen Optionen unverändert an den Linker weiterreicht. Dieser erzeugt dann das Mapfile &amp;quot;foo.map&amp;quot;, eine Textdatei.&lt;br /&gt;
;avr-size: Mit Tools wie avr-size kann die Platzbelegung einzelner Module ermittelt werden:&lt;br /&gt;
::&amp;lt;pre&amp;gt;&amp;amp;gt; avr-size -x foo1.o foo2.o ...&amp;lt;/pre&amp;gt;&lt;br /&gt;
:bzw. die Platzbelegung der elf-Datei:&lt;br /&gt;
::&amp;lt;pre&amp;gt;&amp;amp;gt; avr-size -C --mcu=atmega8 foo.elf&amp;lt;/pre&amp;gt;&lt;br /&gt;
;avr-nm:&lt;br /&gt;
::&amp;lt;pre&amp;gt;&amp;amp;gt; avr-nm --size-sort -S foo.elf&amp;lt;/pre&amp;gt;&lt;br /&gt;
:ergibt eine Liste mit der Größe aller Objekte: der erste Spalte enthälte die Adresse, die zweite Spalte die Größe, die dritte den Typ und die vierte Spalte den zugehörigen Symbolnamen. Der Typ ergibt sich aus der folgenden Zuordnung, wobei Großbuchstaben globale Symbole kennzeichnen und Kleinbuchstaben Symbole, die Modul-lokal sind:&lt;br /&gt;
:;T/t: Objekte in der text-Section: Funktionen, Daten im Flash&lt;br /&gt;
:;D/d: Objekte im data-Segment (initialisierte Daten)&lt;br /&gt;
:;B/b: Objekte im bss-Segment (Null-initialisierte Daten)&lt;br /&gt;
&lt;br /&gt;
;avr-gcc: Der Compiler hat bereits Informationen über die übersetzten Funktionen, die man direkt zur Analyse verwenden kann. Dazu lässt man avr-gcc die Assembler-Ausgabe, die ohne weiteres Zutun nur als temporäre Datei angelegt wird, abspeichern. Etwa für die Quelldatei foo.c:&lt;br /&gt;
::&amp;lt;pre&amp;gt;&amp;amp;gt; avr-gcc -save-temps foo.c -c ...&amp;lt;/pre&amp;gt;&lt;br /&gt;
:Die Assembler-Datei wird damit als foo.s angelegt und nicht gelöscht. (Das ebenfalls angelegte Präcompilat foo.i wird nicht benötigt). Für jede Funktion gibt avr-gcc 3.4.x im Prolog einen Kommentar der Form&amp;lt;ref&amp;gt;Für avr-gcc 4.x sehen die Kommentare anders aus oder fehlen je nach Compilerversion ganz&amp;lt;/ref&amp;gt;&lt;br /&gt;
::&amp;lt;pre&amp;gt;/* prologue: frame size=0 */&amp;lt;/pre&amp;gt;&lt;br /&gt;
:aus, was die Größe des aktuellen Frames angibt. Dies ist der Platz auf dem Stack, der für lokale Variablen benötigt wird. Am besten ist es, wenn die Frame-Size wie im Beispiel gleich 0 ist. Ansonsten sollte man versuchen, diese Größe auf Null zu bringen. Für Variablen, die nicht in Registern gehalten werden können, müssen Speicherzugriffe in den Stack erzeugt werden. Diese machen das Programm sowohl größer aus auch langsamer. Zudem reserviert avr-gcc bei solche Funktionen das Y-Register als Frame-Pointer; das Y-Register steht damit nicht mehr für lokale Variablen zur Verfügung was sich ebenfalls ungünstig auf die Codegüte auswirkt. Ein Grund für das Anlegen eines Frames können zu viele lokale Variablen sein (zB lokale Puffer/Arrays) oder lokale Variablen/Strukturen/Parameter mit ungünstigen Größen, etwa eine 3-Byte große Struktur. &lt;br /&gt;
&lt;br /&gt;
: Neben dieser Information gibt avr-gcc Kommentare der Gestalt&lt;br /&gt;
::&amp;lt;pre&amp;gt;/* prologue end (size=2) */&amp;lt;/pre&amp;gt;&lt;br /&gt;
:aus die darüber informieren, wie viele Register auf dem Stack gesichert wurden.&lt;br /&gt;
&lt;br /&gt;
: Zusammen mit Werkzeugen wie grep, die in jedem Linux und jeder WinAVR-Distribution enthalten sind, findet man schnell Übeltäter wie Funktionen mit Frame.&lt;br /&gt;
&lt;br /&gt;
;Assembler-Code sichten: Ein kurzer Blick auf den erzeugten Assembler-Code zeigt oft, wie gut der Compiler den Code umgesetzt hat. Den erzeugten Assembler-Code zu überfliegen ist wesentlich zeitsparender als selbst in Assembler zu programmieren. Je nach Gusto verwendet man zur Einsicht den Assembler-Code, den avr-gcc ausgibt (s.o.), Assembler-Dumps des Assemblers, List-Files oder HEX-Dumps. Siehe auch&amp;lt;ref&amp;gt;[http://rn-wissen.de/index.php/Assembler-Dump_erstellen_mit_avr-gcc roboternetz.de: Assembler-Dump erstellen mit avr-gcc]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Hilfsmittel: einkaufen oder selber bauen. Es gilt herauszufinden, welche Funktion massig Stack durch lokale Variablen verbraucht. Stacktracer können das. Wenn man keinen hat, dann muss man sich eben selber einen bauen, indem man den Stackpointer mitloggt. Zur Not einen Code-Review machen: Alle Funktionen optisch durchgehen und die identifizieren, die viele Variablen anlegen. Dann die Aufrufhierarchie der Funktion feststellen: Wirken sich die vielen Variablen überhaupt aus oder entsteht mein Problem durch eine tiefe Funktionsaufrufhierarchie, bei der zwar wenige Variablen pro Funktion im Spiel sind, aber die Menge der ineinandergeschachtelten Aufrufe &#039;das Kraut fett macht&#039;&lt;br /&gt;
;Profitools: können das alles fast auf Knopfdruck, kosten aber viel Geld&lt;br /&gt;
&lt;br /&gt;
====Laufzeit messen====&lt;br /&gt;
&lt;br /&gt;
*Simulator&lt;br /&gt;
*In Echtzeit mittels Testpin, welche an Anfang einer Funktion/Blocks gesetzt wird und am Ende wieder gelöscht wird. Mit einem [[Oszilloskop]] kann man so sehr einfach die Laufzeit messen.&lt;br /&gt;
&lt;br /&gt;
; Anmerkung: Solche Messverfahren liefern immer nur eine &#039;&#039;untere&#039;&#039; Schranke für die Laufzeit, niemals eine obere Schranke. Eine obere Schranke, wie man sie etwa in sicherheitsktitischen Systemen benötigt, liefert eine statische Codeanalyse.&lt;br /&gt;
&lt;br /&gt;
=== Wieviel ===&lt;br /&gt;
&lt;br /&gt;
Der Aufwand von Optimierungen wächst exponentiell. Die letzten paar Prozent brauchen überproportional viel Aufwand.&lt;br /&gt;
&lt;br /&gt;
=== Wie ===&lt;br /&gt;
&lt;br /&gt;
Meist muss man die Wahl treffen ob man Speicher oder Rechenzeit sparen will, beides gleichzeitg geht meist nicht. Das Konzept heißt &#039;Space for Time&#039; und kann in beide Richtungen verwendet werden. Als Beispiel soll eine komplizierte Berechnung dienen. Diese kann man relativ kompakt in eine Funktion packen, welche dann aber eher langsam ist. Oder man benutzt eine sehr große Tabelle, in welcher die Ergebnisse schon für jeden Eingangswert vorausberechnet wurden. Diese Lösung ist sehr schnell, verbraucht aber sehr viel Speicher.&lt;br /&gt;
&lt;br /&gt;
* Inlining von Funktionen erhöht den Speicherverbrauch, senkt aber die Laufzeit. Beispiel: Funktion A ist 50 Byte groß und wird 10 mal im Programm aufgerufen. Ein Aufruf kostet 10 Byte:&lt;br /&gt;
** Ohne Inline: 10 * 10Byte + 50 Byte = 150 Byte Platzverbrauch&lt;br /&gt;
** Mit Inline: 10 * 50 Byte = 500 Byte&lt;br /&gt;
* Optimierer einschalten&lt;br /&gt;
* möglichst keine Floating Point Operationen, besser ist meist [[Festkommaarithmetik]]&lt;br /&gt;
* Formeln umstellen und zusammenfassen&lt;br /&gt;
* Variablen so klein wie möglich, uint8_t wo&#039;s nur geht.&lt;br /&gt;
* Wirklich zeitkritische Funktionen und Interrupts als Assemblercode in separater Datei&lt;br /&gt;
&lt;br /&gt;
==Optimierung der Größe==&lt;br /&gt;
&lt;br /&gt;
===GCC-interne Optimierung===&lt;br /&gt;
&lt;br /&gt;
avr-gcc kennt mehrere Optimierungsstufen:&lt;br /&gt;
;-O0: Keine Optimierung. Alle lokalen Variablen werden auf dem Stack angelegt und nicht in Registern gehalten. Es werden keine komplexen Optimierungsalgorithmen angewandt; lediglich Konstanten wie 1+2 werden zu 3 gefaltet. Diese Optimierungsstufe erzeugt zusammen mit Debug-Information Code, der sehr gut in einem Debugger nachvollzogen werden kann.&lt;br /&gt;
;-O1: Je höher die Optimierungsstufe, desto schwieriger ist der erzeugte Code nachvollziehbar &amp;amp;mdash; auch mit Debugger. Diese O-Stufe ist ein Kompromiss zwischen agressiver Optimierung und Nachvollziehbarkeit des erzeugten Codes. Ein ehernes Gesetz in GCC ist, dass er den gleichen Code erzeugen muss unabhängig davon, ob Debug-Information erzeugt wird oder nicht. Im Umkehrschluss erlaubt volle Debug-Unterstützung nicht alle Optimierungen, wozu diese Optimierungsstufe dient.&lt;br /&gt;
&lt;br /&gt;
;-O2: Optimierung auf Geschwindigkeit. Für AVR nur mässig sinnvoll, da sich der Codezuwachs nicht in einem entsprechenden Geschwindigkeitszuwachs transformiert. Dies liegt vor allem daran, daß Sprünge und Funktionsaufrufe auf AVR im Vergleich zu anderen Architekturen sehr billig sind. Es bringt also kaum einen Geschwindigkeitszuwachs, einen Block zu kopieren um einen Sprung zu sparen. Hingegen vergrößert dies den Code deutlich.&lt;br /&gt;
&lt;br /&gt;
;-O3: Ditto. Auf Teufel-komm-raus Funktionen zu inlinen, Schleifen aufzurollen oder gar Funktionen mehrfach für unterschiedliche Aufruf-Szenarien zu implementieren, ist auf einem kleinen µC wie AVR der Overkill.&lt;br /&gt;
&lt;br /&gt;
;-Os: Optimierung auf Codegröße. Die bevorzugte Optimierungsstufe für AVR und viele andere µC.&lt;br /&gt;
&lt;br /&gt;
Jede O-Option ist ein Sammlung von verschiedenen Schaltern, welche bestimmte Optimierungsstrategien aktivieren. Um zu sehen, welche Schalter dies genau sind, erzeugt man wie oben beschrieben mit den Schalten&lt;br /&gt;
   -fsave-temps -fverbose-asm&lt;br /&gt;
die Assembler-Ausgabe von gcc und schaut die Optionen im s-File nach. Einzelne Optionen lassen sich gezielt aktivieren bzw. deaktivieren und damit zum Beispiel zum -Os-Paket hinzufügen. &lt;br /&gt;
&lt;br /&gt;
Eine Ausnahme bildet -O0: Hier ist Code-Optimierung generell deaktiviert, und Optimierungsschalter bleiben ohne Wirkung. -O0 optimiert auf Resourcenverbrauch des /Compilers/ und auf Nachvollziehbarkeit per Debug-Info (so diese erzeugt wird).&lt;br /&gt;
&lt;br /&gt;
Kandidaten dafür für Optimierungsoptionen sind folgende Schalter. -m kennzeichnet maschinenspezifische Schalter, die nur für AVR gültig sind. -f bzw. -fno- sind maschinenunabhängige Schalter, die auch für andere Architekturen verfügbar sind.&lt;br /&gt;
&lt;br /&gt;
;-fno-split-wide-types: Je nach Quelle kann die Deaktivierung von -fsplit-wide-types besseren Code ergeben.&lt;br /&gt;
&lt;br /&gt;
;-fno-inline-small-functions: Relativ kleine Funktionen /immer/ zu inlinen kann den Code unnötig vergrößern, dieser Schalter unterbindet das automatische Inlinen kleiner Funktionen.&lt;br /&gt;
&lt;br /&gt;
;-finline-limit=&amp;lt;n&amp;gt;: Maximale Wert für automatisch geinlinte Funktionen. In einschlägigen Foren werden kleine Werte für den Parameter vorgeschlagem, z.B. 1...3&lt;br /&gt;
&lt;br /&gt;
;-mcall-prologues: Die für aufwändige Funktionen mitunter recht langen push/pop-Sequenzen werden durch Hilfsfunktionen ersetzt. Das kann vor allem bei grossen Programmen Platz sparen. Die Ausführungszeit steigt an.&lt;br /&gt;
&lt;br /&gt;
;-fno-jump-tables: Switch-Statements werden hierdurch mitunter deutlich kürzer.&lt;br /&gt;
&lt;br /&gt;
;-fno-move-loop-invariants&amp;lt;br/&amp;gt;-fno-tree-loop-optimize: einige Schleifenoptimierungen, welche die Registerlast erhöhen und für AVR kaum zu einem Geschwindigkeitszuwachs führen, unterbleiben&lt;br /&gt;
&lt;br /&gt;
Generall gilt für all diese Optionen, daß sie abhängig vom Projekt zu einer Codeverbesserung oder -verschlechterung führen können &amp;amp;mdash; dies ist i.d.R. vom Projektcode abhängig.&lt;br /&gt;
&lt;br /&gt;
===Statische (globale) Variablen in einer Struktur sammeln===&lt;br /&gt;
&lt;br /&gt;
Das erleichtert dem Compiler die Adressierung, da er den Basiszeiger wiederverwenden kann. Die Codegröße kann dann noch von der Reihenfolge der struct-Member abhängen. Die häufigst benutzte Variable sollte am Anfang stehen, dann kann sie ohne Offset direkt mit dem Basiszeiger adressiert werden. Ansonsten in Gruppen, wie die Variablen auch gebraucht werden. Hier kann man viel rumprobieren.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
typedef struct &lt;br /&gt;
{&lt;br /&gt;
    uint16_t sec;            // Meistbenutze Variable an den Anfang&lt;br /&gt;
    uint16_t minute;&lt;br /&gt;
    uint16_t hour;&lt;br /&gt;
} time_t;&lt;br /&gt;
&lt;br /&gt;
time_t global;                    // Globale Struktur definieren&lt;br /&gt;
uint8_t min;                 // Als Vergleich: einzelne globale Variable&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    time_t *time = &amp;amp;global;       // Zeiger auf die globale Struktur&lt;br /&gt;
    // LDI R30,LOW(global)   ; Init Z pointer&lt;br /&gt;
    // LDI R31,(global &amp;gt;&amp;gt; 8) ; Init Z high byte&lt;br /&gt;
    if (++time-&amp;gt;sec == 60)&lt;br /&gt;
    {&lt;br /&gt;
    // LDD R16,Z+2           ; Load with displacement&lt;br /&gt;
    // INC R16               ; Increment&lt;br /&gt;
    // STD Z+2,R16           ; Store with displacement&lt;br /&gt;
    // CPI R16,LOW(60)       ; Compare&lt;br /&gt;
    // BRNE ?0005            ; Branch if not equal&lt;br /&gt;
    }&lt;br /&gt;
    if ( ++min == 60)&lt;br /&gt;
    {&lt;br /&gt;
    // LDS R16,LWRD(min)     ; Load direct from SRAM&lt;br /&gt;
    // INC R16               ; Increment&lt;br /&gt;
    // STS LWRD(min),R16     ; Store direct to SRAM&lt;br /&gt;
    // CPI R16,LOW(60)       ; Compare&lt;br /&gt;
    // BRNE ?0005            ; Branch if not equal&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dadurch, dass die Strukturvariable über LDD/STD (LDD/STD 2 Bytes; LDS/STS 4 Bytes) angesprochen werden kann, werden an dieser Stelle 4 Bytes eingespart.&lt;br /&gt;
Hinzu kommen jedoch noch einmal die 4 Bytes für die Initialisierung des Z-pointers, sodass die Einsparung erst bei mehreren Globalvariablen zum Tragen kommt.&lt;br /&gt;
&lt;br /&gt;
; Anmerkung: Dieses Beispiel zeigt sehr schön, daß solcherlei &amp;quot;Optimierung&amp;quot; ohne Wissen um die Arbeitsweise des eingesetzten Compilers nach hinten losgehen können oder ins Leere laufen. Der erzeugte Code (avr-gcc 4.3.3 -Os) ist:&lt;br /&gt;
::{|&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
main:&lt;br /&gt;
/* prologue: function */&lt;br /&gt;
    lds r24,global&lt;br /&gt;
    lds r25,(global)+1&lt;br /&gt;
    adiw r24,1&lt;br /&gt;
    sts (global)+1,r25&lt;br /&gt;
    sts global,r24&lt;br /&gt;
    lds r24,min&lt;br /&gt;
    subi r24,lo8(-(1))&lt;br /&gt;
    sts min,r24&lt;br /&gt;
    ldi r24,lo8(0)&lt;br /&gt;
    ldi r25,hi8(0)&lt;br /&gt;
/* epilogue start */&lt;br /&gt;
    ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
: D.h. es wird &#039;&#039;nicht&#039;&#039; indirekt auf die Daten zugegriffen. Grund ist, daß gcc die Adresse zur Compilzeit ermitteln kann und dieses Wissen ausnutzt. Angemerkt sei noch, daß der Code im Beispiel von oben entweder gefaket ist und nicht von einem Compiler stammt (die wahrscheinlichere Variante), oder der Compiler inkorrekten Code erzeugte: Das INC erhöht nur die unteren 8 Bit der Komponenten, welche jedoch 16-Bit Werte sind.&lt;br /&gt;
&lt;br /&gt;
: Dennoch ist die angedeutete Zusammenfassung von &#039;&#039;inhaltlich zusammengehörenden&#039;&#039; Variablen sinnvoll und besser als ein Schwarm frei-flottierender int-Variablen.&lt;br /&gt;
&lt;br /&gt;
===Multiplikationen mit Konstanten===&lt;br /&gt;
&lt;br /&gt;
Der Compiler instanziiert sofort eine teure allgemeine Bibliotheksfunktion, auch wenn es anders ginge. Ich hatte eine einzige 32-bit Multiplikation mit 10 drin, die mir ein mulsi3 beschert hat. Mit a = (b&amp;lt;&amp;lt;3) + (b&amp;lt;&amp;lt;1) geht es in dem Fall kürzer. Wie gesagt, map-File beobachten. &lt;br /&gt;
Anmerkung: Variablen als unsigned definieren, dann sollte der Compiler das selbst machen.&lt;br /&gt;
&lt;br /&gt;
;Anmerkung: Auch Schieben ist teuer auf AVR. Schauen wir uns also mal an, was aus folgendem Code wird:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
uint32_t foo (uint32_t i)&lt;br /&gt;
{&lt;br /&gt;
    return i*10;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
uint32_t bar (uint32_t i)&lt;br /&gt;
{&lt;br /&gt;
    return (i &amp;lt;&amp;lt; 1) + (i &amp;lt;&amp;lt; 3);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Scrollbox|18ex;|&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
00000032 &amp;lt;foo&amp;gt;:&lt;br /&gt;
  32:	2a e0       	ldi	r18, 0x0A	; 10&lt;br /&gt;
  34:	30 e0       	ldi	r19, 0x00	; 0&lt;br /&gt;
  36:	40 e0       	ldi	r20, 0x00	; 0&lt;br /&gt;
  38:	50 e0       	ldi	r21, 0x00	; 0&lt;br /&gt;
  3a:	19 d0       	rcall	.+50     	; 0x6e &amp;lt;__mulsi3&amp;gt;&lt;br /&gt;
  3c:	08 95       	ret&lt;br /&gt;
&lt;br /&gt;
0000003e &amp;lt;bar&amp;gt;:&lt;br /&gt;
  3e:	26 2f       	mov	r18, r22&lt;br /&gt;
  40:	37 2f       	mov	r19, r23&lt;br /&gt;
  42:	48 2f       	mov	r20, r24&lt;br /&gt;
  44:	59 2f       	mov	r21, r25&lt;br /&gt;
  46:	22 0f       	add	r18, r18&lt;br /&gt;
  48:	33 1f       	adc	r19, r19&lt;br /&gt;
  4a:	44 1f       	adc	r20, r20&lt;br /&gt;
  4c:	55 1f       	adc	r21, r21&lt;br /&gt;
  4e:	e3 e0       	ldi	r30, 0x03	; 3&lt;br /&gt;
  50:	66 0f       	add	r22, r22&lt;br /&gt;
  52:	77 1f       	adc	r23, r23&lt;br /&gt;
  54:	88 1f       	adc	r24, r24&lt;br /&gt;
  56:	99 1f       	adc	r25, r25&lt;br /&gt;
  58:	ea 95       	dec	r30&lt;br /&gt;
  5a:	d1 f7       	brne	.-12     	; 0x50 &amp;lt;__SREG__+0x11&amp;gt;&lt;br /&gt;
  5c:	26 0f       	add	r18, r22&lt;br /&gt;
  5e:	37 1f       	adc	r19, r23&lt;br /&gt;
  60:	48 1f       	adc	r20, r24&lt;br /&gt;
  62:	59 1f       	adc	r21, r25&lt;br /&gt;
  64:	95 2f       	mov	r25, r21&lt;br /&gt;
  66:	84 2f       	mov	r24, r20&lt;br /&gt;
  68:	73 2f       	mov	r23, r19&lt;br /&gt;
  6a:	62 2f       	mov	r22, r18&lt;br /&gt;
  6c:	08 95       	ret&lt;br /&gt;
&lt;br /&gt;
0000006e &amp;lt;__mulsi3&amp;gt;:&lt;br /&gt;
  6e:	ff 27       	eor	r31, r31&lt;br /&gt;
  70:	ee 27       	eor	r30, r30&lt;br /&gt;
  72:	bb 27       	eor	r27, r27&lt;br /&gt;
  74:	aa 27       	eor	r26, r26&lt;br /&gt;
&lt;br /&gt;
00000076 &amp;lt;__mulsi3_loop&amp;gt;:&lt;br /&gt;
  76:	60 ff       	sbrs	r22, 0&lt;br /&gt;
  78:	04 c0       	rjmp	.+8      	; 0x82 &amp;lt;__mulsi3_skip1&amp;gt;&lt;br /&gt;
  7a:	a2 0f       	add	r26, r18&lt;br /&gt;
  7c:	b3 1f       	adc	r27, r19&lt;br /&gt;
  7e:	e4 1f       	adc	r30, r20&lt;br /&gt;
  80:	f5 1f       	adc	r31, r21&lt;br /&gt;
&lt;br /&gt;
00000082 &amp;lt;__mulsi3_skip1&amp;gt;:&lt;br /&gt;
  82:	22 0f       	add	r18, r18&lt;br /&gt;
  84:	33 1f       	adc	r19, r19&lt;br /&gt;
  86:	44 1f       	adc	r20, r20&lt;br /&gt;
  88:	55 1f       	adc	r21, r21&lt;br /&gt;
  8a:	96 95       	lsr	r25&lt;br /&gt;
  8c:	87 95       	ror	r24&lt;br /&gt;
  8e:	77 95       	ror	r23&lt;br /&gt;
  90:	67 95       	ror	r22&lt;br /&gt;
  92:	89 f7       	brne	.-30     	; 0x76 &amp;lt;__mulsi3_loop&amp;gt;&lt;br /&gt;
  94:	00 97       	sbiw	r24, 0x00	; 0&lt;br /&gt;
  96:	76 07       	cpc	r23, r22&lt;br /&gt;
  98:	71 f7       	brne	.-36     	; 0x76 &amp;lt;__mulsi3_loop&amp;gt;&lt;br /&gt;
&lt;br /&gt;
0000009a &amp;lt;__mulsi3_exit&amp;gt;:&lt;br /&gt;
  9a:	9f 2f       	mov	r25, r31&lt;br /&gt;
  9c:	8e 2f       	mov	r24, r30&lt;br /&gt;
  9e:	7b 2f       	mov	r23, r27&lt;br /&gt;
  a0:	6a 2f       	mov	r22, r26&lt;br /&gt;
  a2:	08 95       	ret&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
: Der Funktionsaufruf samt Lib-Funktion ist garnicht sooo teuer. Bereits mit zwei Multiplikationen im Programm &amp;amp;mdash; auch einer Multiplikation mit einer anderen Konstanten oder einer Variablen &amp;amp;mdash; gewinnt die lib-Version, da der Code wiederverwendetr wird. Übrigens sind diese Multiplikationsroutinen und auch die in die libgcc enthaltenen Divisionen keine &amp;quot;normalen&amp;quot; Funktionen wie sie von C erzeugt werden. avr-gcc weiß genau, welche Register diese Routinen belegen und welche nicht. Damit ist der Aufruf einer solchen Funktion billiger als ein herkömmlicher Funktionsaufruf, bei dem die Funktion als Blackbox behandelt werden muss, die alle call-clobbered Register zerstört.&lt;br /&gt;
&lt;br /&gt;
===Alle Variablen nur so breit wie nötig===&lt;br /&gt;
&lt;br /&gt;
Hatte ich eigentlich schon, nur an einigen wenigen Stellen war ich da etwas nachlässig. Mitunter reicht ein kleinerer Typ doch, wenn man z.&amp;amp;nbsp;B. vorher geeignet skaliert. Am besten nur die skalaren Typen aus &amp;lt;stdint.h&amp;gt; verwenden, das erleichtert auch das Folgende. Bei RAM Knappheit: kann ich Strings sinnvollerweise aus dem RAM ins Flash verbannen? Kann ich es mir leisten mehrere Flag-Variablen in ein Byte zusammenzufassen, auch wenn dann die Zugriffe möglicherweise etwas langsamer werden.&lt;br /&gt;
&lt;br /&gt;
===Logische Operatoren werden auf int-Größe erweitert===&lt;br /&gt;
&lt;br /&gt;
Obwohl der AVR ein 8-Bit Controller ist, weitet der AVR-GCC an manchen Stellen  Vergleiche von zwei 8-Bit Variablen auf 16-Bit auf.&lt;br /&gt;
Als Beispiel sei dabei folgendes gezeigt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
void foo(uint8_t a, uint8_t b)&lt;br /&gt;
{&lt;br /&gt;
    if (a == b)&lt;br /&gt;
    {&lt;br /&gt;
        // tue dies&lt;br /&gt;
    }   &lt;br /&gt;
    if (a == ~b)&lt;br /&gt;
    {&lt;br /&gt;
        // tue das&lt;br /&gt;
    // clr r19           ; clear register&lt;br /&gt;
    // mov r24,r22       ; copy register&lt;br /&gt;
    // clr r25           ; clear register&lt;br /&gt;
    // com r24           ; one&#039;s complement&lt;br /&gt;
    // com r25           ; one&#039;s complement&lt;br /&gt;
    // cp r18,r24        ; compare registers&lt;br /&gt;
    // cpc r19,r25       ; compare registers with carry&lt;br /&gt;
    // brne .L1          ; branch if not equal&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
Den zweiten Vergleich mit der Negation weitet der Compiler auf 16 Bit auf.&lt;br /&gt;
Ein Cast verhindert dieses:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
void foo(uint8_t a, uint8_t b)&lt;br /&gt;
{&lt;br /&gt;
    if (a == b)&lt;br /&gt;
    {&lt;br /&gt;
        // tue dies&lt;br /&gt;
    }   &lt;br /&gt;
    if (a == (uint8_t) ~b)&lt;br /&gt;
    {&lt;br /&gt;
        // tue das&lt;br /&gt;
    // com r22           ; one&#039;s complement&lt;br /&gt;
    // cp r25,r22        ; compare registers&lt;br /&gt;
    // brne .L1          ; branch if not equal&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
Die Einsparung an Speicher zwischen den beiden Versionen beträgt 12 Bytes. Außerdem ist die zweite Version um 6 Takte schneller.&lt;br /&gt;
&lt;br /&gt;
;Achtung: Tatsächlich handelt es sich dabei nicht um ein Optimierungsproblem, sondern einen typischen Programmierfehler. Die beiden Varianten sind keineswegs identisch. Bei Variablen vom Typ uint8_t wird der Ausdruck (a == ~b) immer falsch sein (a=0x0000:0x00FF, ~b=0xFF00:0xFFFF).&lt;br /&gt;
&lt;br /&gt;
===Compileroption -mint8 für 8-Bit Arithmetik als Default===&lt;br /&gt;
&lt;br /&gt;
Mit obigen casts überall sähe der Code ziemlich schlimm aus. Blöd auch, wenn man mal einen Type ändert, dann muß man sorgsam nach den zugehörigen casts&lt;br /&gt;
suchen. Mit dem Compilerschalter -mint8 wird das zum Standard. Bei mir&lt;br /&gt;
hat das etwa 200 Byte gespart! Man sollte dafür aber keine ints mehr im&lt;br /&gt;
Code haben, nur noch Typen definierter Größe aus &amp;lt;stdint.h&amp;gt;.&lt;br /&gt;
Literal-Werte muß man ggf. anpassen (z.&amp;amp;nbsp;B. mit postfix L long machen)&lt;br /&gt;
damit sie nicht überlaufen, Compiler-Warnings beachten.  Ist anscheinend&lt;br /&gt;
noch etwas experimentell(?), mit dem aktuellen gcc 4.1.1 gibt es eine&lt;br /&gt;
Unverträglichkeit in &amp;lt;stdint.h&amp;gt;, der kriegt ein Problem mit den 64-bit Typen. Ist aber wohl in Arbeit, ich habe einen Patch gesehen.&lt;br /&gt;
&lt;br /&gt;
{{Warnung|&lt;br /&gt;
;Warnung:Diese Option verändert das Binärinterface! Funktionen, die nicht mit dieser Option übersetzt wurden, sind nicht unbedingt kompatiablen mit solchen, die mit dem Schalter erzeugt wurden. Da die Bibliotheken &amp;amp;mdash; auch die Compiler-interne libgcc &amp;amp;mdash; ohne diesen Schalter generiert werden, ist mit Problemen zu rechnen. Weiterhin sind bestimmte Typen nicht merh verfügbar bzw. werden mit anderer Semantik belegt, etwa int und long. Für die Option gibt es in avr-gcc 4.x kein Support mehr.}}&lt;br /&gt;
&lt;br /&gt;
===Stack auf 256 Bytes begrenzen===&lt;br /&gt;
&lt;br /&gt;
Mit dem Compileflag -mtiny-stack wird für den Stack eine einfachere Adressierung möglich, die aber &amp;quot;nur&amp;quot; 256 Byte Stacktiefe erlaubt. Wenn man nicht exzessiv automatische Variablen benutzt (Arrays!) oder eine hohe&lt;br /&gt;
Verschachtelungstiefe hat, sollte das ausreichen. Hat mir nochmal knapp 100 Byte (!) kleineren Code erzeugt.&lt;br /&gt;
&lt;br /&gt;
===Speichern von globalen Flags===&lt;br /&gt;
&lt;br /&gt;
Oft werden in den Programmen Flags verwendet um beispielsweise eingetroffene Interrupts in der main-Routine auszuwerten. Hierzu wird üblicherweise eine globale Variable verwendet.&lt;br /&gt;
&lt;br /&gt;
Um den Wert dieser Variable abzufragen, muss sie jedoch erst aus dem SRAM in ein Register geladen werden, und kann dann erst auf ihren Status hin überprüft werden. Eine Möglichkeit ist, der globalen Variablen ein einziges Register fest zuzuordnen:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
register uint8_t counter8_1 asm(&amp;quot;r2&amp;quot;);&lt;br /&gt;
register uint8_t counter8_2 asm(&amp;quot;r3&amp;quot;);&lt;br /&gt;
register uint16_t counter16_1 asm(&amp;quot;r4&amp;quot;); // r4:r5&lt;br /&gt;
register uint16_t counter16_2 asm(&amp;quot;r6&amp;quot;); // r6:r7&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
siehe auch: http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_regbind&lt;br /&gt;
&lt;br /&gt;
Als Alternative kann man ein nicht verwendetes Register des I/O-Bereichs verwenden. Dabei würde sich z.&amp;amp;nbsp;B. das Register eines zweiten UARTs, oder das  EEPROM-Register anbieten, falls diese nicht benötigt werden.&lt;br /&gt;
&lt;br /&gt;
Neuere AVR-Modelle besitzen für diesen Zweck 3 frei verwendbare Bytes im bitadressierbaren I/O-Bereich: GPIOR0-2.&lt;br /&gt;
&lt;br /&gt;
{{Warnung|&lt;br /&gt;
;Warnung: Dieses Vorgehen verändert das ABI! Um dieses Feature fehlerfrei anzuwenden, ist einiges an Wissen über die Interna von GCC notwendig. Auch ein korrekt funktionierendes Programm ist keine Garantie dafür, daß die globalen Register fehlerfrei implementiert wurden. Unter Umständen bringen erst spätere Codeänderungen/-erweiterung den Fehler zum Vorschein, und weil der Fehler vorher nicht akut war, sucht man sich den Wolf an der falschen Stelle im Code anstatt bei der globalen Registern. Siehe auch [[Globale Register]].}}&lt;br /&gt;
&lt;br /&gt;
===Puffern von volatile-Variablen===&lt;br /&gt;
&lt;br /&gt;
Der Compiler behandelt volatile-Variablen bei mehreren Manipulationen wie heiße Kartoffeln. Für jeden einzelnen Vorgang wiederholt sich das Spiel:&lt;br /&gt;
&lt;br /&gt;
* aus dem Speicher holen&lt;br /&gt;
* bearbeiten&lt;br /&gt;
* zurückspeichern&lt;br /&gt;
&lt;br /&gt;
Unter Umständen ist dieses Verhalten unsinnig. Ein Minimalbeispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
volatile char var;&lt;br /&gt;
&lt;br /&gt;
ISR()&lt;br /&gt;
{&lt;br /&gt;
    var++;&lt;br /&gt;
&lt;br /&gt;
    if (var &amp;gt; 100)&lt;br /&gt;
        var = 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void main (void)&lt;br /&gt;
{&lt;br /&gt;
    while (1)&lt;br /&gt;
        printf (var);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Hier wird &#039;&#039;&#039;var&#039;&#039;&#039; pro [[ISR]]-Ausführung zwei mal aus dem RAM geholt und zurückgeschrieben. Das ist überflüssig, weil die Interruptrountine nicht unterbrochen werden kann. Aus Sicht der ISR bräuchte man eigentlich kein volatile, kann es aber wegen dem Zugriff von main heraus nicht weglassen. Eine Lösung findet sich im folgenden Schnipsel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
volatile char var;&lt;br /&gt;
&lt;br /&gt;
ISR()&lt;br /&gt;
{&lt;br /&gt;
    char temp = var;&lt;br /&gt;
&lt;br /&gt;
    if (++temp &amp;gt; 100)&lt;br /&gt;
        temp=0;&lt;br /&gt;
&lt;br /&gt;
    var = temp;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void main (void)&lt;br /&gt;
{&lt;br /&gt;
    while (1)&lt;br /&gt;
        printf (var);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Hier wird die globale Variable &#039;&#039;&#039;var&#039;&#039;&#039; in der lokalen Variable &#039;&#039;&#039;temp&#039;&#039;&#039; gepuffert. Ein Nachteil durch das Anlegen von &#039;&#039;&#039;temp&#039;&#039;&#039; ergibt sich nicht, da das dafür verwendete Register für die Manipulation sowieso benötigt wird. &lt;br /&gt;
&lt;br /&gt;
Wie alle Optimierungen kann dieses Vorgehen auch nach hinten losgehen: Wenn Laden und Zurückspeichern von &#039;&#039;&#039;var&#039;&#039;&#039; weit auseinanderliegen (extrem lange ISR), müllt man sich die Register zu. Im schlimmsten Fall wird &#039;&#039;&#039;temp&#039;&#039;&#039; sogar zwischenzeitlich auf dem Stack ausgelagert.&lt;br /&gt;
&lt;br /&gt;
===Schleifen===&lt;br /&gt;
&lt;br /&gt;
Bei Schleifen, die eine bestimmte Anzahl an Durchläufen ausgeführt werden sollen, ist es besser den Schleifenzähler vorher auf einen Wert zu setzen, und am Ende einer Do-While Schleife diesen zu dekrementieren.&lt;br /&gt;
So beschränkt sich die Sprungbedingung auf ein brne (branch if not equal).&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
uint8_t counter;	&lt;br /&gt;
counter = 100;&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
    // mach irgendetwas&lt;br /&gt;
} while (--counter);&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Unbenutzte Funktionen und/oder Variablen entfernen===&lt;br /&gt;
&lt;br /&gt;
F: Mir ist aufgefallen, dass der Linker nicht benutzte Funktionen trotzdem mit linkt und Speicherplatz belegt. Gibt es eine Möglichkeit diese Funktionen automatisch weg zu lassen?&lt;br /&gt;
&lt;br /&gt;
A: Dem GNU Linker sagt man mit &#039;&#039;--gc-sections&#039;&#039;, dass er unbenutzte Sektionen rauswirft. Mit &#039;&#039;--print-gc-sections&#039;&#039; listet er die rausgeworfenen auch auf. Dem GCC kann man mit &#039;&#039;-ffunction-sections&#039;&#039; sagen, dass er jede Funktion in eine eigene Sektion legt, damit funktioniert das auch unterhalb der Ebene einer Quellcodedatei (also eine Funktion rausschmeissen obwohl fünf andere in derselben Datei gebraucht werden). Mit der Option &#039;&#039;-fdata-sections&#039;&#039; geht das auch für statische Variablen ([http://www.mikrocontroller.net/topic/210453#2084822 Forumsbeitrag von Andreas B.]).&lt;br /&gt;
&lt;br /&gt;
Vorsicht: Je nach Implementierung der Interruptsprung- bzw. Vektorleiste kann es dazu führen, dass alle eigenen Interrupt-Handler ebenfalls wegoptimiert werden. Dies passiert dann, wenn es im Code keinen Verweis (typisch: Ermittlung der Adresse zum Eintrag in eine Interrupt-Vektortabelle oder in Hardwareregister eines Interrupt-Controllers) auf die Handler-Funktion gibt oder die Funktion, in der der Verweis auf eine ISR enthalten ist, nie aufgerufen wird. In solchen Fällen kann es notwendig sein, die Handler mit __attribute__((used)) zu versehen. Bei Verwendung der Makros aus der avr-libc (in WinAVR enthalten, z.B. ISR()) ist dies nicht erforderlich, da das Attribut bereits in den Makro-Definitionen enthalten ist (avr-libc/interrupt.h/ __INTR_ATTRS). In manch anderer Umgebung, wie bei einigen Quellcodes für ARM-basierte Controller, ist das Attribut jedoch zu ergänzen.&lt;br /&gt;
&lt;br /&gt;
==Optimierung der Ausführungsgeschwindigkeit==&lt;br /&gt;
&lt;br /&gt;
Hierzu gibt es schon eine Application-Note von Atmel. Diese AppNote bezieht sich auf den IAR-Compiler. Die darin genannten &amp;quot;Optimierungen&amp;quot; sind für avr-gcc größtenteils obsolet oder bleiben bestenfalls ohne Effekt.&lt;br /&gt;
&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/doc1497.pdf AVR035]: Efficient C Coding for AVR&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Program_optimization Program optimization] auf Wikipedia, engl.&lt;br /&gt;
&lt;br /&gt;
== Fußnoten ==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:avr-gcc]]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Relais_mit_Logik_ansteuern&amp;diff=55606</id>
		<title>Relais mit Logik ansteuern</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Relais_mit_Logik_ansteuern&amp;diff=55606"/>
		<updated>2011-03-07T18:20:36Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
Häufig sollen mit µC-Schaltungen &amp;quot;größere Dinge bewegt werden&amp;quot;, das heißt ein höherer Laststrom oder Netzspannung geschaltet werden. Dieser Artikel soll dem Anfänger dabei helfen, beliebte Probleme zu umgehen. Die hier für Relais aufgeführten Maßnahmen sollen natürlich sinngemäß auch bei anderen induktiven Lasten in Betracht gezogen werden.&lt;br /&gt;
&lt;br /&gt;
== Schaltstufen ==&lt;br /&gt;
&lt;br /&gt;
Wenn normale Bauelemente zum Einsatz kommen sollen, endet man erfahrungsgemäß bei Schaltungen, bei denen mit der Logikspannung ein [[Transistor | Bipolartransistor]] oder [[FET | MOSFET]] im Schaltbetrieb angesteuert wird und die in der Regel höhere Betriebsspannung der Relaisspule geschaltet wird.&lt;br /&gt;
&lt;br /&gt;
=== Schaltstufe für kleine Lasten ===&lt;br /&gt;
&lt;br /&gt;
[[bild:relais_npn.png | framed | ohne| Schaltstufe für kleine Lasten mit Bipolartransitor (links) und MOSFET (rechts)]]&lt;br /&gt;
&lt;br /&gt;
Links im Bild ist die Ansteuerung mit einem NPN-Bipolartransistor gezeigt. Hier wird mit einem Steuersignal durch den Vorwiderstand der Steuerstrom erzeugt, der den Transistor Q2 durchschaltet. Die maximal schaltbare Spannung hängt von dem Transistor ab, bei höheren Lastströmen ist darauf zu achten, daß möglicherweise der Steuerstrom nicht mehr hoch genug ist um den Laststrom sicher zu schalten. Deshalb ist die Stromverstärkung des Transistors zu beachten. Voll durchgesteuert oder voll gesperrt sind die Lieblingszustände des Schalttransistors, bei unvollständiger Ansteuerung (Linearbetrieb) fällt am Transistor eine erhöhte Verlustleistung ab.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
! Schaltstrom [mA]&amp;lt;BR&amp;gt;Transistortyp || Steuerspannung [V] || Bauteilwert&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot;| 500&amp;lt;BR&amp;gt;Q2=BC337 &lt;br /&gt;
|align=&amp;quot;center&amp;quot; |   5 || R2=470&amp;amp;Omega;&lt;br /&gt;
|-&lt;br /&gt;
|align=&amp;quot;center&amp;quot; | 3,3 || R2=270&amp;amp;Omega;&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot;| 100&amp;lt;BR&amp;gt;Q2=BC846(SMD)&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|   5 || R2=2,2k&amp;amp;Omega;&lt;br /&gt;
|-&lt;br /&gt;
|align=&amp;quot;center&amp;quot;| 3,3 || R2=1,3k&amp;amp;Omega;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Werden andere Transistoren eingesetzt oder muss für das Relais mehr oder weniger Strom zur Verfügung gestellt werden, dann findet sich hier die Berechnung des [[Basiswiderstand]]s.&lt;br /&gt;
&lt;br /&gt;
Rechts im Bild wird das Relais mit einem MOSFET gesteuert. Der Vorteil ist hier der wesentlich geringere Steuerstrom im statischen HIGH Zustand (praktisch Null). Wichtig ist hier R1. Dieser Pull-Down-Widerstand sorgt dafür, dass der MOSFET sicher sperrt wenn der steuernde [[Mikrocontroller]] sich im Reset befindet oder gerade programmiert wird. Dann sind nämlich die IO-Pins als Eingänge geschaltet und das Gate des MOSFET würde &amp;quot;in der Luft hängen&amp;quot; (engl. float). R1 verhindert das.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
! Schaltstrom [mA]&amp;lt;BR&amp;gt;Transistortyp || Steuerspannung [V]&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 500&amp;lt;BR&amp;gt;Q1=BS170 &lt;br /&gt;
| align=&amp;quot;center&amp;quot; |  5-10 &lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 200&amp;lt;BR&amp;gt;Q1=BSS138(SMD)&lt;br /&gt;
| align=&amp;quot;center&amp;quot; |   3,3-10&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Schaltstufe für große Lasten ===&lt;br /&gt;
&lt;br /&gt;
Bei großen zu schaltenden Leistungen kommt daher oft vor dem Schalttransistor/FET ein Treiber zum Einsatz. Große MOSFETs brauchen meist 10-15V Gatespannung um voll durchzusteuern, dehalb wird ein [[Pegelwandler]] benötigt und wir haben etwas mehrstufiges. Ausnahmen sind sogenannte &#039;&#039;Logic Level MOSFETs&#039;&#039;, welche schon mit 4,5V praktisch voll durchgesteuert sind. Diese können direkt von 5V Logikausgängen betrieben und somit wie im vorherigen Kapitel angeschlossen werden. Entsprechende Typen findet man im Artikel [[MOSFET-Übersicht]].&lt;br /&gt;
&lt;br /&gt;
[[bild:relais_mosfet.png | framed | ohne| Schaltstufe mit MOSFET für große Lasten]]&lt;br /&gt;
&lt;br /&gt;
Zu beachten ist hier, daß durch den Treiber eine Invertierung stattfindet, d.h. ist der Steuereingang HIGH ist der MOSFET gesperrt und die Last wird nicht von Strom durchflossen. R2 ist die [[Basiswiderstand | Basisstrombegrenzung]], er wird so gewählt daß der Transistor gerade so übersteuert wird um sicherzugehen daß er komplett und schnell durchgesteuert wird. R3 begrenzt den Kollektorstrom des Treibertransistors, wenn dieser leitet, das Gate des MOSFET Q2 liegt dann auf 0V. Wenn er nicht leitet wird über R3 das Gate des MOSFET geladen und dieser ist dann leitend ([[Ausgangsstufen_Logik-ICs#Open_Collector | Open Collector]]). Die hier gezeigte Schaltung kann bis zu 30A schalten, allerdings braucht der MOSFET Q2 ab ca. 5A einen [[Kühlkörper]]. Die Versorgungsspannung VCC kann 10V bis 20V betragen.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Achtung!&#039;&#039;&#039; Diese Schaltung ist nur für langsame Ansteuerung mit ein paar Hertz geeignet. [[PWM]] mit Frequenzen von 50 Hz und höher ist damit nicht möglich, da die erste Schaltstufe dafür viel zu langsam ist. Der Leistungstransistor kann nicht schnell ein und aus geschaltet werden, dadurch befindet er sich während der Umschaltung im Linearbetrieb und erzeugt viel Verlustleistung (=Wärme). Für PWM muss ein schneller [[Mosfet-Übersicht#Mosfet-Treiber | MOSFET-Treiber]] eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Gemeinsam ist diesen Schaltungen allerdings, daß sie sich prima für ohmsche Lasten eignen, aber bei induktiven Lasten gerne Probleme bereiten:&lt;br /&gt;
&lt;br /&gt;
* Die Logikschaltung stürzt beim Schalten gelegentlich oder immer ab, insbesondere beim Abschalten&lt;br /&gt;
* Bauteile verabschieden sich beim ersten Schalten oder nach einigen problemlosen Schaltvorgängen&lt;br /&gt;
* sonstiges unreproduzierbares Verhalten.&lt;br /&gt;
&lt;br /&gt;
== Entstörung ==&lt;br /&gt;
&lt;br /&gt;
Das Hauptproblem ist die Gegeninduktionsspannung der Spule, eine Eigenschaft die in Schaltnetzteilen erwünscht sein mag, mit ihren u.U. mehreren hundert Volt im Logiksystem sich aber eher schädlich auswirkt. Beim Abschalten von Induktivitäten bricht deren Magnetfeld zusammen. Die im Magnetfeld gespeicherte Energie kann nicht einfach verschwinden. Damit wird die Induktivität zur Energiequelle, welche sehr hohe Spannungen erzeugen kann (Prinzip der Zündspule).&lt;br /&gt;
&lt;br /&gt;
Diese Störungen können durch Schaltungsergänzungen gemildert oder beseitigt werden.&lt;br /&gt;
&lt;br /&gt;
=== Freilaufdiode ===&lt;br /&gt;
&lt;br /&gt;
In den obigen Bildern ist die Freilaufdiode als D1 und D2 sichtbar. Dieses Bauteil ist ein absolutes &#039;&#039;&#039;Muss&#039;&#039;&#039; bei induktiven Lasten wie Relais, Motoren etc. Teilweise in Relais schon eingebaut, handelt es sich um eine [[Diode]], die für die Betriebsspannung in Sperrrichtung eingebaut ist. Mit ihr wird die Selbstinduktionsspannung der induktiven Last im Abschaltmoment kurzgeschlossen. Sie sollte mindestens die Versorgungsspannung als Sperrspannung verkraften (plus Reserve von 20% und mehr). Der zulässige Durchlasstrom muss nicht so hoch ausfallen, da die meisten Relais nur mit geringen Frequenzen schalten (einige Hertz). Hier reicht es, wenn der zulässige Pulsstrom der Diode dem Nennstrom des Relais entspricht. Eine kleine 1N4148 kann somit bis zu 1A schalten. Wer auf Nummer sicher gehen will, wählt den Nennwert des Diodenstroms gleich dem Relaisstrom. Einfache Gleichrichterdioden wie z.&amp;amp;nbsp;B. 1N400x sind hier entgegen der oft gehörten Meinung ausreichend, es müssen &#039;&#039;&#039;keine&#039;&#039;&#039; schnellen Schaltdioden verwendet werden. Denn entscheidend für die Freilaufdiode ist die Einschaltzeit (forward recovery time), und die ist auch bei einer langsamen Diode sehr kurz (einige Nanosekunden). Eine umfassende Erklärung findet man auf dieser [http://www.cliftonlaboratories.com/diode_turn-on_time.htm Seite]. &#039;&#039;&#039;Achtung!&#039;&#039;&#039; Das gilt nur für Relais, da diese nicht sehr oft schalten (wenige Hz). In einer Anwendung mit [[PWM]] und hohen Frequenzen im kHz-Bereich müssen schnelle Schaltdioden verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Gelegentlich sieht man auch Dioden in Sperrichtung über die Schaltstrecke (Kollektor-Emitter, Source-Drain), die machen sowas ähnliches. Das klappt aber nur bei Halb-und Vollbrücken! Einfache Emitterschaltungen wie sie hier gezeigt sind brauchen eine Diode antiparallel zum Relais!&lt;br /&gt;
&lt;br /&gt;
[[bild:relais_z-diode.png | framed | Freilaufdiode plus Z-Diode für kurze Abschaltzeiten]]&lt;br /&gt;
&lt;br /&gt;
Wenn ein schnelles Abschalten des Relais gewünscht ist, wie zum Beispiel beim Schalten hoher Ströme, sind andere Maßnahmen besser geeignet, um die Selbstinduktionspannung sicher zu begrenzen. Dazu  nutzt man in Reihe zur Freilaufdiode eine [[Diode#Z-Diode | Z-Diode]], deren Z-Spannung möglichst hoch ist. Dadurch klingt der Spulenstrom wesentlich schneller ab, das Relais fällt schneller ab und der Lichtbogen an den Kontakten wird schneller unterbrochen. Die Kontaktlebensdauer steigt signifikant, ebenso werden weniger Störungen erzeugt. Zu beachten ist dabei, dass der Schalttransistor die Summe aus Betriebsspannung und Z-Spannung als max. Sperrspannung UCE bzw. UDS aushalten muss.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\!\ U_{CE, max} \geqq Vcc+U_Z&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Genaueres findet sich im Abschnitt [[#Links | Links]].&lt;br /&gt;
&lt;br /&gt;
{{Clear}}&lt;br /&gt;
&lt;br /&gt;
=== Entkopplung der Versorgungsspannungen ===&lt;br /&gt;
&lt;br /&gt;
Es schadet in der Regel nicht die Spannungsversorgung für die Logikschaltung gut zu stabilisieren und zu filtern. Die Schaltstufe kann oft mit eher &amp;quot;rohen&amp;quot; Spannungen betrieben werden, also direkt vom Glättungskondensator des Gleichrichters. Allerdings kann etwas Filterung da auch nicht schaden, um Störspannungen durch die Schaltstufe nicht ungedämpft weiterzugeben.&lt;br /&gt;
&lt;br /&gt;
=== Spannungsbegrenzung ===&lt;br /&gt;
&lt;br /&gt;
Parallel zur Schaltstrecke und/oder parallel zur Last können anstelle der Diode Varistoren angeschlossen werden, welche die Spannung am Bauteil begrenzen. Dabei muss beachtet werden, dass die maximal zulässige Kollektor- bzw. Drainspannung nicht überschritten wird. Betriebsspannung und Induktionsspannung der Relaisspule liegen in Reihe, sodass gilt&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\!\ U_{CE,max} \geqq VCC + V_{Varistor}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Suppressordioden eignen sich auch, sie schalten etwas schneller, können aber AFAIK nicht soviel Pulsleistung aufnehmen.&lt;br /&gt;
&lt;br /&gt;
=== Löschglieder ===&lt;br /&gt;
&lt;br /&gt;
[[bild:relais_snubber.png| framed | Löschglied zur Störungsverminderung über einem Relaiskontakt]]&lt;br /&gt;
&lt;br /&gt;
Im Englischen [[Snubber]] Network genannt. Durch eine Beschaltung der Schaltkontakte des Relais mit einem RC-Serienglied werden hochfrequente Überschwingeffekte beim Schalten gedämpft. Snubberglieder sind fast immer sinnvoll. Prinzipiell kann man sagen, daß der Widerstand Rs hochfrequente Anteile verbraucht und der Kondensator dafür sorgt, daß dieser Vorgang nur kurz beim Umschalten erfolgt, aber kein kontinuierlicher Stromfluss erfolgt. Wichtig ist dabei, dass der Widerstand ausreichend dimensioniert ist um die auftretende Verlustleistung auszuhalten. Ebenso muss der Kondensator eine ausreichende Spannungsfestigkeit aufweisen, bei Netzspannung sollten es mindestens 400V sein. Außerdem muss man recht große Mindestabstände zwischen den Steuerkontakten und den 230V Schaltkontakten einhalten, wie in den Artikeln [[Leiterbahnabstände]] und [[Leiterbahnbreite]] beschrieben ist.&lt;br /&gt;
{{Clear}}&lt;br /&gt;
&lt;br /&gt;
== Logikschaltungen mit Relais ==&lt;br /&gt;
&lt;br /&gt;
Wenn gleich Relais heute oft per Mikrocontroller und Transistoren angesteuert werden und die Schaltlogik in der Software steckt, so gibt es dennoch immer mal wieder Fälle, in denen man auf reine Relaislogik zurückgreifen möchte. Die Gründe dafür sind z.B. robuster Aufbau, Stromversorgung, Bauteillogistik etc.&lt;br /&gt;
&lt;br /&gt;
=== Umschaltung per Taster ===&lt;br /&gt;
&lt;br /&gt;
Will man mit einem Taster ein Relais mit jedem Tastendruck zwischen Ein und Aus wechseln lassen (engl. to toggle, umschalten), so kann man das mit der nachfolgenden Schaltung tun. Sie benötigt nur zwei Relais mit einem Wechselkontakt sowie einen Taster mit Wechselkontakt. Hat man den nicht, kann man ihn durch einen einfachen Taster ersetzen, der dann ein drittes Relais mit Wechselkontakt schaltet. Als dritte Möglichkeit kann ein Taster mit getrenntem Öffner und Schließer verwendet werden. Wesentliche Eigenschaft der Schaltung ist, dass bei Ausfall der Stromversorgung immer wieder der Ausgangszustand eingenommen wird.&lt;br /&gt;
&lt;br /&gt;
[[bild:relais_toggle.png| framed | Umschaltung per Tastendruck]]&lt;br /&gt;
&lt;br /&gt;
Und so funktioniert das Ganze&lt;br /&gt;
* Ausgangszustand: K1 und K2 sind ohne Strom, die Kontakte liegen wie im Schaltplan, da kein Strom über K1 oder S1 zu den Relais fließen kann&lt;br /&gt;
* Taster S1 wird gedrückt: Über S1 und K2 wird Spannung an die Spule von K1 gelegt, der Kontakt von K1 schließt&lt;br /&gt;
* Taster S1 wird losgelassen, d.h. ein paar Millisekunden hängt der Schaltkontakt in der Luft, der Strom fließt über K1 und K2 weiter and K1 (Selbsthaltung)&lt;br /&gt;
* Taster S1 erreicht Ruheposition, jetzt fließt Strom über die Kontakte K1, S1 und D1 und D2 an die Spulen von K1 und K2, wodurch der Kontakt K2 öffnet. K1 bekommt nun nur noch über K1, S1 und D1 Strom.&lt;br /&gt;
* S1 wird zum 2. Mal gedrückt und hängt sehr kurz in der Luft. Die Selbsthaltung über K1, S1 und D1 wird unterbrochen, K1 fällt ab, dadurch öffnet K1. K2 würde nun auch abfallen. Tut es aber nicht, da die Umschaltung sehr schnell geht. Und hier liegt der &amp;quot;Trick&amp;quot; der Schaltung. &#039;&#039;&#039;Die Umschaltung von S1 muss schneller sein als die Abfallzeit des Relais K2!&#039;&#039;&#039;&lt;br /&gt;
* S1 schaltet komplett um, die Selbsthaltung für K2 läuft über S1, K2&lt;br /&gt;
* S1 wird wieder losgelassen und hängt kurz in der Luft, die Selbsthaltung für K2 wird unterbrochen und K2 fällt ab. &lt;br /&gt;
&lt;br /&gt;
Wie man sieht schaltet K1 immer dann, wenn die Taste gedrückt wird und K2 immer dann, wenn die Taste losgelassen wird. Je nach gewünschter Funktion kann man das Signal für weitere Schaltfunktionen an der Spule für K1 oder K2 abgreifen. &lt;br /&gt;
&lt;br /&gt;
In der Installationstechnik für Gebäude wird man meist auf ein Stromstoßrelais zurückgreifen, dort wird die Umschaltung über die Mechanik im Relais erreicht. Dort reicht dann auch ein einfacher Schließer als Taster. Diese Relais benötigen nur zum Umschalten Strom und halten dabei den Schaltzustand auch bei Stromausfall.&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.ridleyengineering.com/snubber.htm Entwicklungshilfe für Snubber, englisch]&lt;br /&gt;
* [http://www.schrackrelays.com/appnotes/app_pdfs/13c3264.pdf Coil Suppression Can Reduce Relay Life (pdf)]&lt;br /&gt;
* [http://www.kilovac.com/appnotes/app_pdfs/13c3311.pdf The application of relay coil suppression with DC relays (pdf)]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/193291 Fachbegriffe bei Relais] (Forumbeitrag)&lt;br /&gt;
* [http://www.panasonic-electric-works.at/pewat/de/downloads/ds_x61_de_relay_technical_information.pdf Technische Informationen zu Relais], Panasonic (PDF)&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/147610#new Forumsbeitrag]: Toggle mit Relais&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Xilinx_ISE:_Hinweise_zu_Versionen&amp;diff=54571</id>
		<title>Xilinx ISE: Hinweise zu Versionen</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Xilinx_ISE:_Hinweise_zu_Versionen&amp;diff=54571"/>
		<updated>2011-01-29T09:49:55Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: /* Kurz und Knapp */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hinweise zu den aktuellen Versionen der Xilinx-Entwicklungsumgebung ISE und deren Probleme:&lt;br /&gt;
&lt;br /&gt;
== Allgemein ==&lt;br /&gt;
* Der Webinstaller hat oftmals Probleme mit Firewalls und läuft generell nicht sonderlich gut, am Besten gleich den Komplettdownload starten.&lt;br /&gt;
* Leerzeichen in Dateipfaden vermeiden&lt;br /&gt;
&lt;br /&gt;
== ISE 11.2 ==&lt;br /&gt;
&lt;br /&gt;
=== Vorteile ===&lt;br /&gt;
&lt;br /&gt;
* Projektdateien als XML File (.xise) ermöglichen das manuelle Bearbeiten und bessere Versionskontrolle&lt;br /&gt;
* Kürzere Laufzeiten der Synthese und Implementierung&lt;br /&gt;
* Wesentlich weniger RAM-Verbrauch&lt;br /&gt;
* ChipScope Pro jetzt immer im Paket enthalten, Debugging über JTAG möglich&lt;br /&gt;
&lt;br /&gt;
=== Nachteile ===&lt;br /&gt;
&lt;br /&gt;
* Teurer als die Vorgänger durch neue Paket-Ordnung&lt;br /&gt;
* Noch größer als Vorversionen&lt;br /&gt;
* &amp;quot;Export Project&amp;quot; ist weggefallen und wurde durch &amp;quot;Copy Project&amp;quot; ersetzt, Versionierung hier wieder erschwert&lt;br /&gt;
&lt;br /&gt;
=== Bugs ===&lt;br /&gt;
&lt;br /&gt;
* Im Schematic Editor werden Leitungen beim verschieben fast nie angezeigt&lt;br /&gt;
* Bugs im ImPact, das &amp;quot;Programming Properties&amp;quot; Menü ist selten verfügbar (Workaround: Auf SVF Ausgabe stellen, dann ist es da. Alles einstellen und wieder zurück stellen, dann gilt das auch für Boundary Scan)&lt;br /&gt;
&lt;br /&gt;
== ISE 9.2 ==&lt;br /&gt;
&lt;br /&gt;
=== Probleme ===&lt;br /&gt;
&lt;br /&gt;
* Bei der Verwendung von mem-Dateien im Projekt bekommt man bei der Bitstream-Erzeugung eine Fehlermeldung, wenn im Pfad der Datei Leerzeichen enthalten sind.&lt;br /&gt;
* Manchmal versucht ISE nach dem Ersetzen einer Design Unit durch eine andere mit gleichem Namen noch die alte Architecture zu synthetisieren, auch wenn sie nicht mehr vorhanden ist, und bricht mit einer Fehlermeldung ab. Lösung: alle temporären Dateien löschen und nochmal versuchen.&lt;br /&gt;
&lt;br /&gt;
== ISE 9.0 ==&lt;br /&gt;
&lt;br /&gt;
=== Probleme ===&lt;br /&gt;
&lt;br /&gt;
Die vorhandenen Projekte der Versionen 8,x werden meist reibungslos importiert (5 Testversionen) - sie funktionieren jedoch nicht vollständig. Abhilfe schafft teilweise das vollständige Löschen alter Projektdateiein und das Anwerfen einer neuen vollständigen Synthese. Vereinzelt war es nötig, Schematics updates durchzuführen, bzw nicht erkannte HDL-Files einmalig zu laden und wieder zu speichern.&lt;br /&gt;
&lt;br /&gt;
=== Verbesserungen ===&lt;br /&gt;
&lt;br /&gt;
Vereinzelt kleinere Design / bessere FPGA-Ausnuntzung im Falle von Virtex 4. Kaum Verbesserungen bei Spartan3 beobachtet.&lt;br /&gt;
&lt;br /&gt;
=== Nachteile ===&lt;br /&gt;
&lt;br /&gt;
Geringfügig längere Syntheselaufzeiten bei großen Projekten.&lt;br /&gt;
&lt;br /&gt;
== Xilinx ISE 8.2 ==&lt;br /&gt;
&lt;br /&gt;
=== Kurz und Knapp ===&lt;br /&gt;
Falls es nicht unbedingt nötig ist, sollte man bei der Vorgängerversion 8.1SP3 bleiben:&lt;br /&gt;
*Das Synthesetool XST verändert heftigst Instanzennamen, sodass viele Constraints (UCF-file) angepasst werden müssen &lt;br /&gt;
*Die Probleme mit Records sind zahlreicher; Code, der in der 8.1. problemlos durchlief, führt bei der Version 8.2. zu Abbrüchen &lt;br /&gt;
*Die Größe von nun 1 GByte führt zu vermehrten Problemen beim Xilinx-Server - die 8.1. hatte nur ca. 740 MByte.&lt;br /&gt;
*Das Design wird u.U marginal kleiner, kaum Vorteile&lt;br /&gt;
&lt;br /&gt;
=== Probleme ===&lt;br /&gt;
Das Problemkind heisst in der 8.2. XST, also das erste Glied der Kette:&lt;br /&gt;
&lt;br /&gt;
Es fängt mit angeblichen doppelten Bibliotheken an, work (klein) und WORK (gross) erscheinen, wo es nur eine Bibliothek gibt. Glücklicherweise hat die Fehlermeldung auch einen workaround parat: in skripten den Schalter -work_lib verwenden.&lt;br /&gt;
&lt;br /&gt;
Weiter gehts mit heftigen Umbennen der Instanzennamen. dann steigt ngdbuild aus, da die Netznamen dort nicht mehr zu Netzliste aus dem XST passen. Da hilft nur Editieren des ucf files (was aber dann nicht mehr abwärtskompatibel ist).&lt;br /&gt;
&lt;br /&gt;
Der XST hatte schon immer Problem mit Records. jetzt habe ich eines aus einem std_logic und einem Integer-array. das benutzt ich in einem generic. bei 8.1. alles in Ordnung, die 8.2 meckert irgenwas wie &amp;quot;Kann Feldindex nicht auflösen&amp;quot;.&lt;br /&gt;
Also behält man den record, benutzt aber als generic die Elemente einzeln. Hier ein generic für den std_logic und ein anderes für das Feld. In der generic map weisst man diesen beiden jeweils das element aus dem record zu.&lt;br /&gt;
&lt;br /&gt;
Auch Felder werden zum Problem. Hat man eins definiert in dessen Indexbereich eine Konstante benutzt wird (type mein_feld is array C_obere_grenze Downto 0 of integer) raucht XST mit Fatal Error ab, obwohl die Konstante deklariert und i.O. ist. Schreibt man statt der Konstanten die Zahl (z.&amp;amp;nbsp;B. 4 downto 0) ist alles i.O.. An irregulärem VHDL kann es nicht liegen, modelsim vetarbeitet es anstandslos.&lt;br /&gt;
&lt;br /&gt;
=== Vorteile ===&lt;br /&gt;
*Der Projektnavigator soll seltener Projekte &amp;quot;zerschiessen&amp;quot;.&lt;br /&gt;
*Der Router liefert &amp;quot;brauchbare&amp;quot; Ergebnisse.&lt;br /&gt;
*designs werden u.U. ca. 3 Promill kleiner.&lt;br /&gt;
&lt;br /&gt;
==Xilinx ISE 8.1==&lt;br /&gt;
Seit Januar 2006 ist eine neue Versionen der Tools für die FPGA Programmierung der Xilinx Tools verfügbar. Ebenfalls im Januar wurde der erste Patch auf www.xilinx.com veröffentlicht. Im folgenden eine Liste der Vor- und Nachteile. Diese Erfahrungen wurden mit der WebPack- und Voll-Variante auf Linux und Microsoft Windows gemacht. Zum Teil entstammen sie dem Forum &amp;quot;Programmierbare Logik&amp;quot; von www.mikrocontroller.net. Manche der genannten Punkte sind bereits in der Version 7.1 neu hinzugekommen.&lt;br /&gt;
&lt;br /&gt;
Das ServicePack2 liegt seit 14.02.06 bei xilinx auf der website. Das Download-Tool (Impact) scheint nach dem Update unzuverlässiger (aber vielleicht liegts auch an Hardware). Ansonsten kaum Änderungen zum SP1.&lt;br /&gt;
&lt;br /&gt;
Die folgende Version Version (8.2) kame Ende März 2006, das zur 8.* passende EDK Ende Februar 2006 heraus.&lt;br /&gt;
&lt;br /&gt;
Laut Xilinxdistributor für Österreich, Silica wien, kommt anfang 2007 eine völlig neue und komplett überarbeitete Version 9.0 heraus.&lt;br /&gt;
&lt;br /&gt;
===Bugs===&lt;br /&gt;
====Zerstörung von VHDL-Files in Projekten von Vorgängerversionen====&lt;br /&gt;
*tritt meist auf, wenn das Projekt mehrere &amp;quot;Snapshots&amp;quot; erhält&lt;br /&gt;
*die Projekteinstellungen werden aus dem *.npl File (ISE 6.3) in das File *.ise (ab ISE 7.1) konvertiert.&lt;br /&gt;
&lt;br /&gt;
====Sonderzeichen deutsche Tastatur====&lt;br /&gt;
*im Editor keine Eingabe von &#039;|&#039; möglich (Problem mit der &amp;quot;AltGr&amp;quot;-Taste)&lt;br /&gt;
====Tastatur HotKeys====&lt;br /&gt;
Die &amp;quot;alten&amp;quot; HotKeys und Cut/Paste geht gelegentlich nur wenn das Editorfenster im &amp;quot;float&amp;quot; modus ist.&lt;br /&gt;
====Impact (FPGA Download)====&lt;br /&gt;
*Impact hat Probleme mit Bitfiles etc. aus älteren versionen, als workaround sollte man ältere Versionen benutzen.&lt;br /&gt;
*Impact bleibt gelegentlich bei solchen Files stehen, ohne das Programmieren zu beenden&lt;br /&gt;
*es wird ein neues Format der Konfigurationsdatei verwendet (jetzt (*.ipf), -konvertiert aus der aus Vorgängerversionen (war *.cdf)&lt;br /&gt;
*Impact findet die JTAG-Kette nicht und sucht unendlich nach devices&lt;br /&gt;
&lt;br /&gt;
====Linux map Absturz====&lt;br /&gt;
*mit Servicepack2 Absturz vor Schreiben Netzliste (*_map.ngd)&lt;br /&gt;
*Meldung (&amp;quot;error loading shared object file&amp;quot; oder &amp;quot;Illegal OPCode&amp;quot;)&lt;br /&gt;
*unbekannt ob Fehler auch ohne oder mit älteren ServicePack auftritt&lt;br /&gt;
*workaround: ISE7.1 nutzen, Mischung Flow (Synthese,ngbuilt mit 8.1, ab Mapper mit 7.1) funktioniert&lt;br /&gt;
====Änderungen====&lt;br /&gt;
*neues Format der Projektdatei *.ise (bis 6.3 *.npl)&lt;br /&gt;
Das *.ise ist nich lesbar, zumindest nicht für Menschen. Damit  sind Pfade nicht per Edit der&lt;br /&gt;
Projektdatei bequen anpassbar. Verschiebung der Quelltexte erfordert Neuaufsetzen des Projektnavigators.&lt;br /&gt;
&lt;br /&gt;
*Aufruf der Binaries aus dem EDK 6.3 (mit &amp;quot;_&amp;quot; als erstes Zeichen des Namens des Executables, workaround möglich?, zwingend update EDK nötig ?&lt;br /&gt;
&lt;br /&gt;
====Pathseperator====&lt;br /&gt;
ngdbuild wollte erst nicht, im ucf gabs Instanznamen die er nicht&lt;br /&gt;
gefunden hat. Problem war wohl eine Änderung in der Defaulteinstellung&lt;br /&gt;
wegen Preserve Hierarchie. Nachdem im ucf die Instanznamen mit /&lt;br /&gt;
getrennt worden, liefs auch wieder.&lt;br /&gt;
Version 6.3: INST toplevel_instanzname -&amp;gt;&lt;br /&gt;
Version 8.1: INST toplevel/instanzname&lt;br /&gt;
&lt;br /&gt;
====Error statt Warning: Taktnetzwerk aus nicht GlobalClock Pin gespeist====&lt;br /&gt;
Wird ein Taktnetzerk (DCM Eingang oder VHDL: clk_signal&#039;event) nicht über ein GlobalClockPin in den FPGA geführt brechen die Tools (map oder PAR?)&lt;br /&gt;
mit einem Fehler ab. Durch Setzen einer Variable (XIL_PLACE_ALLOW_LOCAL_BUFG_ROUTING) wird ein solches Design wie in den vorigen Versionen nur mit einer Warning angemeckert und die tools laufen bis&lt;br /&gt;
zur Erstellung des Downloadfiles durch. &lt;br /&gt;
&lt;br /&gt;
====Syntax VHDL-Konstrukte====&lt;br /&gt;
*Error bei ungenutzen FSM-Zuständen&lt;br /&gt;
*Probleme in der unsigned Bibliothek (explizite Typumwandlung nach unsigned)&lt;br /&gt;
&lt;br /&gt;
===Verbesserungen===&lt;br /&gt;
*bessere Darstellung der Infos über Taktnetzwerke und Timing Constraints in Logfiles des PAR&lt;br /&gt;
*Angabe Logiklevel im PAR-Report scheint jetzt stimmig zu sein&lt;br /&gt;
*buntere Darstellung der Logfiles in der ISE&lt;br /&gt;
*mehr automatische Optimierung der Tools (kleinere Designs (bis zu 5%)), höhere Taktfrequenzen möglich, längere Laufzeiten tools)&lt;br /&gt;
*anderes Layout für Projectnavigator und impact&lt;br /&gt;
*Linux: Vorteile von ISE 8.1 gegebenüber 7.1: deutlich schnelleres und hübscheres Fenster-Layout; die Console funktioniert jetzt&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Xilinx ISE]]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Umbau_des_DMM_M9803_mit_Bluetooth&amp;diff=54314</id>
		<title>Umbau des DMM M9803 mit Bluetooth</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Umbau_des_DMM_M9803_mit_Bluetooth&amp;diff=54314"/>
		<updated>2011-01-16T19:16:03Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: /* Schaltungsidee */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Warhinweise ==&lt;br /&gt;
{{Warnung|;Achtung!:Bei Schäden, die durch Nichtbeachten der Anleitung verursacht werden, wird keinerlei Haftung übernommen.&lt;br /&gt;
&lt;br /&gt;
: Durch den Umbau, speziell das Anlöten eines Steckers auf einen der inneren Leiterplatten des Multimeters erlischt die Garantie des Herstellers! Für den Umbau sollten Sie sehr gute Kenntnisse in der Elektronik und Erfahrung im Löten haben. Gehen Sie bitte Schritt für Schritt durch die Anleitung, nur so wird dieser Umbau erfolgreich sein.&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&#039;Elektronische Kleinteile gehören nicht in Kinderhände!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
: Es wird keinerlei Haftung für Schäden, die aus einer falschen Bestückung, Handhabung oder Anschlussfehler am/im Multimeter oder an der Adapterplatine übernommen.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Sicherheitshinweise ==&lt;br /&gt;
Ziehen sie unbedingt vor Umbau den Netzstecker des Multimeters, sonst besteht die Gefahr eines lebensgefährlichen, elektrischen Schlages! Bitte beachten Sie die VDE Sicherheitsvorschriften und -hinweise zu elektrischen Geräten und spezielle die Sicherheitshinweise des Herstellers.&lt;br /&gt;
Beim Arbeiten mit dem fertigen Modul ist zu beachten, dass die Anschlusspins etwas scharfkantig sind und somit bei unsachgemäßer Handhabung leichte Verletzungen verursachen können.&lt;br /&gt;
&lt;br /&gt;
== Schaltungsidee ==&lt;br /&gt;
Die Idee des Umbaus besteht darin, dass man eine fertige, mit dem BTM222 bestückte Leiterplatte auf die vorhandene RS232 Buchse steckt und mit einem Kippschalter die Betriebsspannung für das Modul einschaltet. Damit kann das Multimeter über Bluetooth seine Messdaten übermitteln. Die Versorgungsspannung wird von der einzulötenden Stiftleiste „VDD VSS“ entnommen.&lt;br /&gt;
Will man mit einem seriellen Kabel wiederum arbeiten, so schaltet man mit dem Kippschalter die Spannungsversorgung wieder aus.&lt;br /&gt;
Es handelt sich also größtenteils um ein Hardware-Projekt. Um die Messdaten von Multimetern zu übermitteln, ist die Verkabelung mittels RS232 oder USB teilweise störend oder nicht erwünscht. Das Bluetoothmodul BTM-222 bietet sich daher an, zumindest für die Multimeter mit RS232-Schnittstelle einen Kabelersatz zu schaffen. Beispielhaft soll hier das Multimeter M9803R für diesen Umbau herangezogen werden.  &lt;br /&gt;
&lt;br /&gt;
=== Schritt 1: Anlöten eines 2-poligen Steckers ===&lt;br /&gt;
&lt;br /&gt;
Zunächst muss das Multimeter aufgeschraubt, und die Leiterplatte M9803-1, die sich hinter den Batteriefächern befindet, ausgebaut werden. Dann wird unterhalb der Dioden D107/D108 der 2-polige Stecker des Leiterplattenverbinders so angelötet,  dass das schwarze Kabel an VSS und das braune Kabel an VDD verbunden ist. Dies ist unbedingt einzuhalten, siehe dazu die nächsten drei Abbildungen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery widths=&amp;quot;180&amp;quot; heights=&amp;quot;135&amp;quot;&amp;gt;&lt;br /&gt;
File:DMM9803 Verdrahtung.jpg|Schematik des Aufbaus innen&lt;br /&gt;
File:01 VDD-VSS Stecker anlöten.jpg|VDD-VSS Anschlusspins&lt;br /&gt;
File:02 VDD-VSS Stecker angeschlossen.jpg|Schwarze Leitung: VSS&amp;lt;br/&amp;gt;braune Leitung: VDD&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nach erfolgtem Anlöten des Steckers wird die Leiterplatte wieder angeschraubt.&lt;br /&gt;
&lt;br /&gt;
=== Schritt 2: Bohrung Rückwand für Umschalter ===&lt;br /&gt;
Als nächstes wird an der Rückwand mittig über dem Netzschalter eine Bohrung von 5,0mm für den Kippschalter gebohrt. Anschließend werden die Leitungen des Leiterplattenverbinders und die Verbindung Kippschalter (Mitte) ↔ RS232-Buchse angelötet, der Kippschalter eingebaut und mit der Mutter festgeschraubt:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;gallery widths=&amp;quot;220&amp;quot; heights=&amp;quot;165&amp;quot;&amp;gt;&lt;br /&gt;
Datei:04 Bohrung Rückwand.jpg|Bohrung über dem Netzschalter&lt;br /&gt;
Datei:03 Kippschalter an der Rückwand montieren.jpg|Kippschalter montieren&lt;br /&gt;
Datei:Kippschalter an RS232.jpg|Kippschalter anlöten&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Schritt 3: Anlöten des Schalters an die RS232-Buchse ===&lt;br /&gt;
Nun wird der Kippschalter an Pin 9 (+) und 8 (-) der RS232 Buchse angeschlossen (siehe Bilden oben rechts).&lt;br /&gt;
&lt;br /&gt;
=== Schritt 4: Testen der Anschlussbelegung ===&lt;br /&gt;
Als nächstes muss unbedingt überprüft werden, ob das Ein- und Ausschalten der Betriebsspannung an der RS232-Buchse funktioniert und ob die Polarität richtig ist. Dazu wird ein weiteres, kleines Multimeter benötigt, welches die Spannung im ein- und ausgeschaltetem Zustand an den Pins 8/9 der RS232-Buchse misst. Der eingebaute Kippschalter ist zunächst in der linken Position („B“, RS232-Betrieb). An der RS232-Buchse wird die rote Messleitung an Pin 9, die schwarze an Pin 8 angeschlossen („A“). Das M9803 wird nun eingeschaltet (Frontschalter), das Handmessgerät sollte nun 0V anzeigen.&lt;br /&gt;
&lt;br /&gt;
Wird der Kippschalter nun in die rechte Position gestellt, sollte die Ausgangsspannung von ca. +9V angezeigt werden. Damit sind die Umbauarbeiten am Tischmultimeter M9803 abgeschlossen. Das Gerät kann nun wieder verschlossen werden. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;table&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;[[Datei:06 RS232BuchseAUS.jpg]]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[[Datei:06 RS232BuchseEIN.jpg]]&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Schritt 5: Bestücken der Leiterplatte für das BTM-222 ===&lt;br /&gt;
&lt;br /&gt;
# Nun wird die Leiterplatte* für das Bluetoothmodul bestückt. Zunächst wird das BTM222 an einer Ecke angelötet und ausgerichtet. Nach dem Ausrichten folgt die diagonal gegenüberliegende Ecke. Dann werden die restlichen Pins angelötet.&lt;br /&gt;
# Anschließend werden die Drahtbrücken gebogen und angelötet.&lt;br /&gt;
# Nun folgen die kleinen und flachen Bauteile, also die 100nF Kondensatoren, der Widerstand und die IC-Fassung.&lt;br /&gt;
# Die Elkos und der Spannungsregler LE33CZ werden danach angelötet.&lt;br /&gt;
# Nachdem die Stiftleisten angelötet wurden, erfolgt zunächst die Montage des D-Sub Steckers. Dieser wird mit Abstandsbolzen montiert, anschließend werden die Pins des Stecker angelötet. Das fertige Modul sieht nun wie folgt aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;[[Datei:BT9803-fertig1.jpg]]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[[Datei:BT9803-fertig2.jpg]]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[[Datei:BT9803-fertig3.jpg]]&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
* Die derzeit entwickelte Leiterplatte &amp;quot;BT-9803&amp;quot; von mir ist derzeit im Prototypenstatus. Wenn Bedarf an der Leiterplatte besteht, am besten melden.&lt;br /&gt;
&lt;br /&gt;
=== Schritt 6: BTM-222 Konfigurieren ===&lt;br /&gt;
Als nächstes muss das fertige Modul konfiguriert werden. &lt;br /&gt;
atn=BT9803	// Neuer sinnvoller Name&lt;br /&gt;
atl1		//9600bps&lt;br /&gt;
Dazu wird ein Adapter aus einem D-SUB 9 m/w zusammengelötet (siehe unten).&lt;br /&gt;
&lt;br /&gt;
Nach dem Einschalten der Betriebsspannung für das BT9803-Modul wird über den PC (Nullmodemkabel) das Modul wie oben angeben konfiguriert. Nach erfolgter Konfiguration kann nun das Modul auf die RS232-Buchse des M9803 gesteckt, und in Betrieb genommen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;[[Datei:Adapterkabel.jpg]]&amp;lt;br /&amp;gt;Adapterkabel zur Konfiguration des BTM-222&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;[[Datei:BT9803 an Multimeter.jpg]]&amp;lt;br /&amp;gt;Modul am Multimeter&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Test der Bluetoothverbindung etc. auf dem PC ==&lt;br /&gt;
Es hat sich herausgestellt, dass nur die Originalsoftware DMM Version 1.1 unter Windows vernünftig funktioniert. Unter Linux kann die Opensource Software QTDMM verwendet werden.&lt;br /&gt;
&lt;br /&gt;
== Weitere Ideen ==&lt;br /&gt;
Dies ist sicherlich nur eine Möglichkeit, dieses Multimeter mit Bluetooth auszustatten. Wenn man ganz auf die Möglichkeit verzichten will, per RS232 Kabel das Multimeter an den PC anzuschließen, so macht es durchaus Sinn, die RS232 Buchse komplett in das Innere des Multimeters zu verlegen und dort auch das Bluetoothmodul anzuschließen. Die Möglichkeiten sind hier sicherlich unbegrenzt.&lt;br /&gt;
&lt;br /&gt;
==Stückliste ==&lt;br /&gt;
{| {{Tabelle}}&lt;br /&gt;
! Bauteil(e) || Wert&lt;br /&gt;
|-&lt;br /&gt;
| C2 || 1µ   (RM2)&lt;br /&gt;
|-&lt;br /&gt;
| C1 || 10µ  (RM2)&lt;br /&gt;
|-&lt;br /&gt;
| R1 || 100k (0204)&lt;br /&gt;
|-&lt;br /&gt;
| C3, C4, C5, C6, C7, C8 || 100n (RM2,5)&lt;br /&gt;
|-&lt;br /&gt;
| U1 || BTM-222&lt;br /&gt;
|-&lt;br /&gt;
| X1 || D-SUB9 Male&lt;br /&gt;
|-&lt;br /&gt;
| IC1 || LE33CZ oder ähnlicher 3,3 V Regler&lt;br /&gt;
|-&lt;br /&gt;
| IC2 || MAX3232 (Siehe Beschreibungstext)&lt;br /&gt;
|-&lt;br /&gt;
| JP2 || Pinheader für RESET&lt;br /&gt;
|-&lt;br /&gt;
| JP1 || Pinheader für RESET-UART&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Beschreibung der Schaltung ==&lt;br /&gt;
Als Bluetoothmodul wird das BTM-222 von Rayson in einer Minimalbeschaltung verwendet. Außer den Spannungsversorgungspins (3,3V und GND) werden nur die Pins UART_RX, UART_TX, PIO4 und RESET verwendet.&lt;br /&gt;
&lt;br /&gt;
PIO 4 kann lt. Applicationsheet und Datenblatt des Herstellers dazu verwendet werden, die UART zurückzusetzen, dies geschieht mit JP3. Da dieser Eingang high-aktiv ist wird ein Pull-Down Widerstand R1 benötigt. Der normale Resetpin ist low-aktiv, daher die Beschaltung des JP2 gegen GND. Durch einen internen Pull-Up Widerstand ist hier keine Beschaltung notwendig. Der Kondensator C6 dient dazu, beim / nach Einschalten eine definierten Zustand zu erreichen, d.h.&lt;br /&gt;
der Pin ist beim Einschalten auf &amp;quot;low&amp;quot; und geht dann kurz danach auf &amp;quot;high&amp;quot; (Aufladung des Kondensators C6).&lt;br /&gt;
&lt;br /&gt;
Die Spannungsversorgung, die aus dem Multimeter ca. 10-12V beträgt, wird mittelst Spannungsregler (IC1) und die dazugehörigen Elkos (C1, C2) auf 3,3V stabilisiert. C3 ist möglichst nahe am BTM-222 platziert worden.&lt;br /&gt;
&lt;br /&gt;
Um die vorhandene RS232 des Multimeters nutzen zu können, wird ein Pegelwandler in Form eines MAX3232 eingesetzt. Dieser ist für 3,3V ausgelegt. Es hat sich gezeigt, dass man durchaus auch einen ST232CN einsetzen kann, allerdings wird dieser durch die 3,3V außerhalb der Spezifikation betrieben. Sollte es beim Einsatz eines &amp;quot;normalen&amp;quot; MAX232 o.ä. zu Problemen kommen, dann lieber einen MAX3232 einsetzen. Der Einsatz eines MAX232N (10µF Variante) ist nicht möglich.&lt;br /&gt;
&lt;br /&gt;
== Stromlaufplan und Layout ==&lt;br /&gt;
* [[Datei:BT9803.zip]] (Eagle 4.16)&lt;br /&gt;
&lt;br /&gt;
== Technische Daten ==&lt;br /&gt;
* Betriebsspannung: 9 V DC&lt;br /&gt;
* Ruhestromaufnahme (bei 9V): ca. 70mA&lt;br /&gt;
* Modulabmessungen (B x H x T): 53mm x 19mm x 33mm&lt;br /&gt;
&lt;br /&gt;
== Links im Internet ==&lt;br /&gt;
*[http://http://www.p-mastech.com/products/04_dm/m9803r.html Mastech Multimeter M9803R]&lt;br /&gt;
* [http://http://www.mtoussaint.de/qtdmm.html qtdmm / Linuxsoftware]&lt;br /&gt;
* [http://www.rayson.com Rayson, BTM-222 Datenblatt]&lt;br /&gt;
* [http://www.b-redemann.de Webseite des Autors Bernhard Redemann]&lt;br /&gt;
* [https://ssl-id.de/b-redemann.de/sp-project-rs232-ttl.shtml RS232-TTL Converter, B.Redemann]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Funk]]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Zeitgesteuerte_Pflanzenbew%C3%A4sserung&amp;diff=52720</id>
		<title>Zeitgesteuerte Pflanzenbewässerung</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Zeitgesteuerte_Pflanzenbew%C3%A4sserung&amp;diff=52720"/>
		<updated>2010-11-12T13:34:20Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: /* [Fotos] Link-Textder Hardware */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;von Philipp Kälin [[Benutzer:philippk]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Einleitung =&lt;br /&gt;
Die zeitgesteuerte Bewässerungsanlage ist für alle geeignet, die zu faul sind um Pflanzen selber zu giessen oder es immer wieder mal vergessen. Ziel des Projektes ist einen einfachen Aufbau zu haben, der per PC konfigurierbar und batteriebetrieben ist.&lt;br /&gt;
Ein Taster ist vorhanden um die Kommunikation mit dem PC zu aktivieren. Ist die Kommunikation aktiv leuchtet eine LED konstant. Im normalbetrieb ist die LED aus und fängt an zu blinken, wenn die Spannung der Batterie unter einen bestimmten Wert fällt.&lt;br /&gt;
Um die Pumpe für Testzwecke oder manuell einzuschalten ist der Taster S2 vorgesehen.&lt;br /&gt;
&lt;br /&gt;
= Features =&lt;br /&gt;
* Batteriebetrieben&lt;br /&gt;
* Über PC konfigurierbar&lt;br /&gt;
* Einfacher Aufbau ohne komplizierte Feuchtemessung&lt;br /&gt;
&lt;br /&gt;
= Aufbau =&lt;br /&gt;
== Mechanisch ==&lt;br /&gt;
Der Hauptteilbesteht aus einer Membranpume, die mit einem Wasser-Vorratsbehälter verbunden ist. Es ist darauf zu achten, dass eine Membranpumpe von sich aus nicht sperrt, das heisst wenn der Wasserspiegel im Vorratsbehälter höher ist als der in der Pfalnze so fliesst Wasser von alleine! Als Wasserverteiler dient ein festes Kunststoffröhrchen mit seitlich gebohrten Löchern.&lt;br /&gt;
&lt;br /&gt;
=== Fotos des Aufbaus ===&lt;br /&gt;
[[Bild:Bewaesserung_Aufbau.jpg|center|thumb|200px|Aufbau]]&lt;br /&gt;
[[Bild:Bewaesserung_Wasserverteiler.jpg|center|thumb|200px|Wasserverteiler]]&lt;br /&gt;
&lt;br /&gt;
Die Schwedenflaggen gibt übrigens wie auch den Wasserbehälter bei Ikea (Ursprünglicher Verwendungszweck: Aufbewahrungsbox für Zucker usw.)&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
Die generelle Funktion sollte aus dem Schema erkennbar sein, hier wird nur auf ein paar spezielle Sachen hingewiesen. Generell kann die Schaltung in folgende Teile unterteilt werden:&lt;br /&gt;
* Spannungsregelung 5V&lt;br /&gt;
* Schalter, Taster und LED&lt;br /&gt;
* Prozessor mit Uhrenquarz&lt;br /&gt;
* RS232 Kommunikation&lt;br /&gt;
* Ansteuerung der Pumpe mit StepUp Konverter&lt;br /&gt;
&lt;br /&gt;
=== Schema ===&lt;br /&gt;
[[Bild:Bewaesserung_Schema.png|center|thumb|200px|Schema]]&lt;br /&gt;
&lt;br /&gt;
=== Spezialitäten der Schaltung ===&lt;br /&gt;
Im Betrieb ist der grösste Stromverbraucher der MAX232, deshalb kann diesem die Betriebsspannung mit dem Schalter S1 weggenommen werden, zugleich wird auch die Kommunikation softwaremässig deaktiviert.&lt;br /&gt;
&lt;br /&gt;
Um die Akkuspannung zu messen ist ein spezieller Spannungsteiler (R1, R6) vorhanden. R1 wird nur während der Messung auf Low gezogen. Dadurch wird erreicht dass der Ruhestrom nur (Vbatt – 5V) / R6 beträgt und nicht Vbatt / (R1 + R6) wenn der Widerstand konstant auf GND wäre, was einen erheblichen Unterschied macht.&lt;br /&gt;
&lt;br /&gt;
=== Eventuelle Anpassungen der Hardware ===&lt;br /&gt;
Der StepUp Wandler muss natürlich an die Pumpenspannung angepasst werden. Falls man eine genügend hohe Spannung zur verfügung hat kann man auch den FET Q2 durch einen Leistungsfet ersetzen und die Pumpe oder ein Relais direkt schalten.&lt;br /&gt;
&lt;br /&gt;
=== Fotos der Hardware ===&lt;br /&gt;
[[Bild:Bewaesserung_Frontplatte.jpg|center|thumb|200px|Frontplatte]]&lt;br /&gt;
[[Bild:Bewaesserung_Rueckplatte.jpg|center|thumb|200px|Rückplatte]]&lt;br /&gt;
[[Bild:Bewaesserung_Innenleben.jpg|center|thumb|200px|Innenleben]]&lt;br /&gt;
&lt;br /&gt;
= Software =&lt;br /&gt;
Die Software ist komplett in C geschrieben und mehr auf Einfachheit als auf volle Optimierung ausgerichtet. Das erklärt auch dass die 4K des Atmega48 randvoll sind. Alle Einstellungen ausser der aktuellen Zeit und dem aktuellen Wochentag werden im EEPROM abgespeichet und sind nach einem Stomausfall wieder vorhanden.&lt;br /&gt;
&lt;br /&gt;
= Kommunikation =&lt;br /&gt;
Die Kommunikation verläuft über RS232 und kann mit jedem &amp;quot;anständigen&amp;quot; Terminalprogramm konfiguriert werden. Ich empfehle für diesen Zweck das kostenlose Termite [http://www.compuphase.com/software_termite.htm Termite] für Windows oder [http://cutecom.sourceforge.net/ CuteCom] für Linux.&lt;br /&gt;
&lt;br /&gt;
== Terminaleinstellungen ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! Baudrate&lt;br /&gt;
| 2400&lt;br /&gt;
|- &lt;br /&gt;
! Daten Bits&lt;br /&gt;
| 8&lt;br /&gt;
|- &lt;br /&gt;
! Stop Bits&lt;br /&gt;
| 1&lt;br /&gt;
|- &lt;br /&gt;
! Parity Bit&lt;br /&gt;
| keins&lt;br /&gt;
|- &lt;br /&gt;
! Flusssteuerung&lt;br /&gt;
| keine&lt;br /&gt;
|- &lt;br /&gt;
! Zeilenumbruch&lt;br /&gt;
| CR &amp;lt;nowiki&amp;gt;0x0d&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|- &lt;br /&gt;
|}&lt;br /&gt;
[[Bild:Bewaesserung_Termite_Settings.png|center|thumb|200px|Terminaleinstellungen]]&lt;br /&gt;
&lt;br /&gt;
== Kommunikation starten ==&lt;br /&gt;
Die Kommunikation wird gestartet indem man den Befehl &amp;quot;status&amp;quot; sendet, danach sollte etwa folgendes zurückkommen:&lt;br /&gt;
[[Bild:Bewaesserung_Termite_Window.png|center|thumb|200px|Kommunikation]]&lt;br /&gt;
&lt;br /&gt;
== Parameter ==&lt;br /&gt;
::{|  class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
! Befehl || Parameter || Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;time&amp;lt;/nowiki&amp;gt;    || &amp;lt;nowiki&amp;gt;hh:mm&amp;lt;/nowiki&amp;gt; || Aktuelle Uhrzeit&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;weekday&amp;lt;/nowiki&amp;gt;    || &amp;lt;nowiki&amp;gt;x&amp;lt;/nowiki&amp;gt; || Wochentag (1=Mo 7=So)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;days&amp;lt;/nowiki&amp;gt;    || &amp;lt;nowiki&amp;gt;xxxxxxx&amp;lt;/nowiki&amp;gt; || Wochentage an denen die Pumpe aktiv ist. 0 oder 1 für jeden Wochentag Mo – So&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;active&amp;lt;/nowiki&amp;gt;    || &amp;lt;nowiki&amp;gt;sss&amp;lt;/nowiki&amp;gt; || Einschaltzeit in Sekunden in der die Pumpe aktiv ist&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;daytime&amp;lt;/nowiki&amp;gt;    || &amp;lt;nowiki&amp;gt;hh:mm&amp;lt;/nowiki&amp;gt; || Tageszeit zu der die Pumpe beginnt zu laufen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Wichtig ist, dass man die Anzahl Zeichen einhält, will man also eine Einschaltzzeit vo 2 Sekunden erreichen, so muss &amp;lt;nowiki&amp;gt;active 002&amp;lt;/nowiki&amp;gt; gesendet werden.&lt;br /&gt;
&lt;br /&gt;
= Alternativen / Erweiterungen =&lt;br /&gt;
Natürlich kann dieses Projekt nicht nur als Steuerung für eine Pumpe dienen, sondern als beliebige Tageszeitschaltuhr.&lt;br /&gt;
&lt;br /&gt;
= Downloads =&lt;br /&gt;
Schema und Software sind OpenSource und können vom SVN heruntergeladen werden. Die Ordnerstruktur ist in der README Datei im Rootverzeichnis erklärt. http://www.mikrocontroller.net/svnbrowser/bewaesserung/&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:AVR-Projekte]]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=RFM12&amp;diff=52658</id>
		<title>RFM12</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=RFM12&amp;diff=52658"/>
		<updated>2010-11-09T13:16:49Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: /* Interrupt nIRQ klappt nicht bei 868MHz */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Beschreibung der Funkmodule RFM01, RFM02 und RFM12.&lt;br /&gt;
&lt;br /&gt;
Benötigt werden in der Minimal-Version im FIFO-Modus nur die Anschlüsse nSEL, SDO, SDI und SCK, eben das komplette SPI-Interface. Der Zugriff auf das Sende- und Empfangs-FIFO ist per Software möglich, ebenso die Abfrage der Statusbits. Deshalb werden z.&amp;amp;nbsp;B. nIRQ und nFFS nicht unbedingt benötigt. nIRQ signalisiert unter anderem, dass das Modul bereit ist Daten zu empfangen. Wenn Daten empfangen wurden, kann dies über den FFIT-Pin abgefragt werden (falls die Füllschwelle eingestellt wurde). nFFS dient dazu das FIFO direkt anzusprechen (es ist quasi der Chipselect für das FIFO), davon wird in der Minimalversion aber kein Gebrauch gemacht. Der Pin muss daher auf high-Pegel gelegt werden!&lt;br /&gt;
An CLK kann eine Frequenz von 1MHz bis 10MHz eingestellt werden. Hiermit kann dann z.&amp;amp;nbsp;B. der Mikrocontroller versorgt werden.&lt;br /&gt;
Reset ist ein Open-Collector-Ausgang und gleichzeitig der Reset-Eingang. Er sollte daher entweder gar nicht, oder aber hochohmig angeschlossen werden.&lt;br /&gt;
&lt;br /&gt;
Im FIFO-Mode kann das Modul konfiguriert werden mit dem Empfang zu warten, bis die Daten 0x2DD4 empfangen wurden. Sobald dieses Bitmuster empfangen wurde, werden Daten in das FIFO geschrieben, bis man das FIFO abschaltet und die Mustererkennung neu startet.&lt;br /&gt;
&lt;br /&gt;
Als weitere Modi stehen unter anderem ein synchroner Modus zur Verfügung (no FIFO mode), in dem der Sender/Empfänger den Bittakt ausgibt, und synchron dazu die zu sendenden Daten einliest bzw. die empfangenen Daten ausgibt. Der SPI Bus ist trotzdem zur Initialisierung des Moduls notwendig.&lt;br /&gt;
&lt;br /&gt;
== FAQ ==&lt;br /&gt;
&lt;br /&gt;
=== SPI Interface ===&lt;br /&gt;
&lt;br /&gt;
* Maximale Datenrate: 2,5MHz (10MHz Quarz / 4)&lt;br /&gt;
&lt;br /&gt;
=== CLK-Ausgang bleibt bei 1 MHz ===&lt;br /&gt;
&lt;br /&gt;
* Vor dem Umschalten (mit 0xC0E0) länger warten.&lt;br /&gt;
&lt;br /&gt;
=== RFM12 empfängt ein paar Bytes, dann nur Müll ===&lt;br /&gt;
&lt;br /&gt;
* Es wird zu langsam gesendet (TX FIFO underrun)&lt;br /&gt;
* Es wird zu langsam empfangen (RX FIFO overrun)&lt;br /&gt;
&lt;br /&gt;
Die Status-Bits helfen hier beim Debuggen. SPI sollte auf maximaler Transferrate stehen.&lt;br /&gt;
&lt;br /&gt;
=== RFM empfängt nur Müll ===&lt;br /&gt;
&lt;br /&gt;
http://www.mikrocontroller.net/topic/73560#605528&lt;br /&gt;
&lt;br /&gt;
Deine Module verhalten sich normal. Man muß mit den Gain- und AFC-Bits&lt;br /&gt;
eine ganze Weile spielen, bis die Module korrekt laufen (kommt auf die&lt;br /&gt;
Anwendung an). Fakt ist: der Empfänger empfängt ständig Datenmüll als&lt;br /&gt;
Rauschen. Wenn der FIFO durch die Präambel getriggert wird, sind die&lt;br /&gt;
Daten im FIFO ziemlich korrekt, wenn alles &amp;quot;gut&amp;quot; eingestellt ist. Der&lt;br /&gt;
FIFO sollte per Interrupt dann auch sofort abgeholt werden, da sonst das&lt;br /&gt;
nächste Byte das alte direkt überschreibt. Jeder zusammenhängende&lt;br /&gt;
Datensatz (mehrere Bytes an einem Stück) muß von einer Präambel&lt;br /&gt;
eingeleitet werden. Nach dem kompletten Einlesen eines Datensatzes muß&lt;br /&gt;
der FIFO abgeschaltet, wieder eingeschaltet und für den Empfang der&lt;br /&gt;
nächsten Präambel neu scharf gemacht werden.&lt;br /&gt;
&lt;br /&gt;
=== RFM hängt sich auf ===&lt;br /&gt;
&lt;br /&gt;
Wenn man die AFC nicht begrenzt, also keinen Wertebereich vorgibt, die eine maximale Abweichung korrigiert wird passiert es nach einer Weile, dass sich der Empfänger aufhängt, die Offsetbits im Status werden maximal und dann geht gar nichts mehr, er hängt fest.&lt;br /&gt;
&lt;br /&gt;
edit: Leider bringt die Beschränkung der AFC auf Minimum bei mir keine Verbesserung. Zumindest ist obige Aussage nicht allgemein gültig.&lt;br /&gt;
&lt;br /&gt;
Siehe auch &lt;br /&gt;
* Forenbeitrag [http://www.mikrocontroller.net/topic/82456#689660 RFM12: Erfahrungen ]&lt;br /&gt;
&lt;br /&gt;
=== Kommunikation mit RFM funktioniert nur sporadisch ===&lt;br /&gt;
&lt;br /&gt;
* Ist die Versorgungsspannung stabil? (evtl. Kondensator einbauen)&lt;br /&gt;
&lt;br /&gt;
=== Interrupt nIRQ klappt nicht bei 868MHz ===&lt;br /&gt;
&lt;br /&gt;
Wenn bei der Verwendung der 868er Module die üblichen Sourcen (dasLabor, etc) verwendet werden, müssen einige Änderungen gemacht werden, die sich leicht finden lassen. Ohne weiteres funktionierte der blockierende Empfang, der Interruptbetriebene (nIRQ) machte in mindestens einem Fall Probleme. Hier half die Anpassung des FIFO IT Level . In vorhandenen Sourcen ist 0xCA83 zu finden, eine Änderung auf 0xCAF3 hilft dabei.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Register ==&lt;br /&gt;
&lt;br /&gt;
Von https://www.mikrocontroller.net/attachment/24947/RFM12.txt&lt;br /&gt;
&lt;br /&gt;
Dieses Dokument beschreibt die Nutzung des RFM12 TRX Moduls!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039; WICHTIG &#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Dieses Dokument wurde aus mehreren Quellen zusammengestellt, und kann Fehler enthalten!&lt;br /&gt;
Es können Abweichungen in Bezug auf RF01 / RF02 / RF12 / RFM01 / RFM02 und andere Module auftreten!&lt;br /&gt;
Es wurde das Datenblatt vom RFM12B und RF12 von www.hoperf.com als Basis genuzt. Zusätzlich wurden diese Informationen mit Hilfe von Forums-Nutzern (https://www.mikrocontroller.net/topic/71682) weiter vervollständigt!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039; WICHTIG &#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Hinweis:&#039;&#039;&#039; Die LNA-Eingangsimpedanz beträgt 250 Ohm, und muss beim Anschluss einer 50-Ohm-Antenne entsprechend angepasst werden, um das Rauschen zu minimieren! &#039;&#039; -- (Auf den Pollin-Modulen bereits vorhanden)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Configuration Setting ===&lt;br /&gt;
 Hex = 80 &amp;amp; xx&lt;br /&gt;
 Bit-Syntax: &lt;br /&gt;
{| cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
!width=&amp;quot;20%&amp;quot;| Byte ||width=&amp;quot;40%&amp;quot;| 1 || 2&lt;br /&gt;
|-&lt;br /&gt;
!Bits&lt;br /&gt;
|{{8Bit|width=100%| 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 }}||{{8Bit|width=100%| el | ef | b1 | b0 | x3 | x2 | x1 | x0}}|}&lt;br /&gt;
 el (TX FIFO) = Sendepuffer für Datentransfer nutzen (1 = An / 0 = Aus)&lt;br /&gt;
 ef (RX FIFO) = Empfangspuffer für Datenspeicherung nutzen (1 = An / 0 = Aus)&lt;br /&gt;
 b... = Zu nutzende Basisfrequenz (00=315MHz / 01=433MHz / 10=868MHz / 11=915MHz)&lt;br /&gt;
 x... = Interner Clock des Chips kann durch verschieben einer Kondensator-Anpass-Stufe bestimmt werden.&lt;br /&gt;
        0,5pF pro Schritt. Basis ist 8,5pF -&amp;gt; (0000=8,5 / 0001=9,0 / 0010=9,5 / ...)&lt;br /&gt;
&lt;br /&gt;
=== Power-Management ===&lt;br /&gt;
 Hex = 82 &amp;amp; xx&lt;br /&gt;
 Bit-Syntax: 10000010 | er | ebb | et | es | ex | eb | ew | dc&lt;br /&gt;
 er = Empfänger einschalten (1 = an / 0 = Aus)&lt;br /&gt;
 ebb = ... (Synthesizer muss aktiv sein!) (1 = an / 0 = aus)&lt;br /&gt;
 et = Sender einschalten (1 = an / 0 = Aus) (Wenn das TX-Register aktiv und mit Daten gefüllt ist/wurde,&lt;br /&gt;
      werden diese Daten sofort gesendet) (1 = an / 0 = aus)&lt;br /&gt;
 es = Schaltet den Synthesizer ein. (1 = an / 0 = aus)&lt;br /&gt;
 ex = Schaltet den Quarz-Oszilator ein. (1 = an / 0 = aus)&lt;br /&gt;
 eb = Vergleichbar mit BrownOutDetection -&amp;gt; Erkennt eine zu geringe Betriebsspannung und erzeugt einen Interrupt,&lt;br /&gt;
      um einen drohenden Spannungsaufall anzukündigen (1 = An / 0 = Aus)&lt;br /&gt;
 ew = Aktiviert den WakeUpTimer des Prozessors. (1 = an / 0 = aus)&lt;br /&gt;
 dc = Deaktiviert die Ausgabe des SystemClocks auf dem CLK Pin am Chip (1 = Keine ClockAusgabe / 0 = Clock ausgeben)&lt;br /&gt;
&lt;br /&gt;
=== PLL Setting ===&lt;br /&gt;
 Hex = 198 + y&lt;br /&gt;
 Bit-Syntax: 110011000 | ob1 | ob0 | lpx | ddy | ddit | bw1 | bw0&lt;br /&gt;
 ob... = ... (00= 5 oder 10MHz [standard] / 01=3.3MHz / 1x=2.5MHz oder weniger)&lt;br /&gt;
 lpx = Wählt den Low-Power-Mode für den Quarz-Oszilator aus. (0=1ms [620µA] / 1=2ms [460µA])&lt;br /&gt;
 ddy = ...&lt;br /&gt;
 ddi = Schaltet das Dithering in PLL-Schleife ab. (1=abgeschaltet / 0=eingeschaltet)&lt;br /&gt;
 bw... = Wählt die Bandbreite des PLL-Signals aus. (00=86.2kbps [-107dBc/Hz] / 01=256kbps [-102dBc/Hz]) Bei 1MHz Offset Phasenrauschen.&lt;br /&gt;
&lt;br /&gt;
=== LowBatt / µC Clock Control ===&lt;br /&gt;
 Hex = c0 &amp;amp; xx&lt;br /&gt;
 Bit-Syntax: 11000000 | d2 | d1 | d0 | v4 | v3 | v2 | v1 | v0&lt;br /&gt;
 d... = Bestimmt den Teilungsfaktor für die Clockausgabe am CLK-Pin in Abhängigkeit des Internen SystemTakts.&lt;br /&gt;
        (000=1 / 001=1.25 / 010=1.66 / 011=2 / 100=2.5 / 101=3.33 / 110=5 / 111=10)&lt;br /&gt;
 v... = Bestimmt die Minimalspannung, ab der ein Interrupt durchgeführt werden&lt;br /&gt;
 muss. (Ähnlich einer BrownOutDetection). Im Power-Managment muss das eb-Bit&lt;br /&gt;
 aktiv sein, damit dies funktioniert.&lt;br /&gt;
&lt;br /&gt;
=== Frequency-setting ===&lt;br /&gt;
Bestimmt den Offset der Sende- und Empfangsfrequenz. Dieser Offset wird auf das Basisband im Configuration Setting hinzu gerechnet.&lt;br /&gt;
 Hex = a &amp;amp; xxx&lt;br /&gt;
 Bit-Syntax:&lt;br /&gt;
{| cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
!width=&amp;quot;20%&amp;quot;| Byte ||width=&amp;quot;40%&amp;quot;| 1 || 2&lt;br /&gt;
|-&lt;br /&gt;
!Bits&lt;br /&gt;
|{{8Bit|width=100%| 1 | 0 | 1 | 0 | f11 | f10 | f9 | f8 }}||{{8Bit|width=100%| f7 | f6 | f5 | f4 | f3 | f2 | f1 | f0}}|}&lt;br /&gt;
&lt;br /&gt;
 f... = Bestimmt den Offsetwert der Frequenz.&lt;br /&gt;
        Als Basis gilt das eingestellte Band im Configuration-Settings-Kommando&lt;br /&gt;
&lt;br /&gt;
freq = 10 * C1 * (C2 + f/4000) [MHz]&lt;br /&gt;
&lt;br /&gt;
{| cellspacing=&amp;quot;0&amp;quot; border=&amp;quot;1&amp;quot; style=&amp;quot;text-align:center;&amp;quot;&lt;br /&gt;
! Band || C1 || C2&lt;br /&gt;
|-&lt;br /&gt;
| 315 || 1 || 31&lt;br /&gt;
|-&lt;br /&gt;
| 433 || 1 || 43&lt;br /&gt;
|-&lt;br /&gt;
| 868 || 2 || 43&lt;br /&gt;
|-&lt;br /&gt;
| 915 || 3 || 30&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Data-Rate ===&lt;br /&gt;
 Hex = c6 &amp;amp; xx&lt;br /&gt;
 Bit-Syntax: 11000110 | cs | r6 | r5 | r4 | r3 | r2 | r1 | r0&lt;br /&gt;
 cs =  Vorteiler, Faktor 7. Hiermit kann ein Vorteiler aktiviert werden,&lt;br /&gt;
       der die errechnete Baudrate (r...) durch 7 teilt.&lt;br /&gt;
 r... = Baudratenteilerfaktor&lt;br /&gt;
&lt;br /&gt;
=== RX Control ===&lt;br /&gt;
 Hex = 94 &amp;amp; xx&lt;br /&gt;
 Bit-Syntax: 10010 | p20 | d1 | d2 | i2 | i1 | i0 | g1 | g0 | r2 | r1 | r0&lt;br /&gt;
 p20 = Bestimmt die Funktion des Pin20 (nINT / VDI) am RFM12 Chip (1 = VDI-Ausgang / 0 = Interrupt-Eingang)&lt;br /&gt;
 d... = (Valid Data Indicator). Definiert die Geschwindigkeit, mit der bestimmt wird, ob ein Signal korrekt ist, oder nicht.&lt;br /&gt;
        (00=schnell / 01=mittel / 10=langsam / 11=immer an). Je nach eingestellter Variante werden&lt;br /&gt;
        unterschiedliche Hardware- und Software-Kombinationen genuzt.&lt;br /&gt;
        Fast:  CR_Lock  OR  DQD  ... Medium:  CR_Lock  AND ( DRSSI  OR  DQD ) ... &lt;br /&gt;
        SLOW: R/S FlipFlop aus (SET)  DRSSI  OR  DQD  OR  CR_Lock  und (CLR)  DRSSI  AND  DQD  AND  CR_Lock .&lt;br /&gt;
 i... = Bestimmt die Bandbreite des Empfängers in KHz (KiloHertz).&lt;br /&gt;
        (000=Reserviert / 001=400 / 010=340 / 011=270 / 100=200 / 101=134 / 110=67 / 111=Reserviert)&lt;br /&gt;
 g... = (LNA-Gain) Verstärkungsfaktor des Rauscharmen-Eingangs-Signal-Verstärkers (LNA Low Noise Amplifier).&lt;br /&gt;
        Werte in dBm (Dezibel [Grösse: Milliwatt]) Mögliche Werte sind: 0 / -6 / -14 / -20&lt;br /&gt;
 r... = (DRSSI = Digital Received Signal Strength Indication) Minimale Empfangssignalfeldstärke.&lt;br /&gt;
        6 dBm pro Schritt: (000=-103 / 001=-97 / 010=-91 / ...)&lt;br /&gt;
&lt;br /&gt;
=== Synchron Pattern ===&lt;br /&gt;
 Hex = ce &amp;amp; xx&lt;br /&gt;
 Bit-Syntax: 11001110 | b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0&lt;br /&gt;
 b... = Legt den Wert fest, der als Synchronisations-Byte für die Datenfilterung verwendet werden soll.&lt;br /&gt;
&lt;br /&gt;
=== Data Filter ===&lt;br /&gt;
 Hex = c2 &amp;amp; xx&lt;br /&gt;
 Bit-Syntax: 11000010 | al | ml | -unknow- (1) | s | -unknow- (1) | f2 | f1 | f0&lt;br /&gt;
 al = Baudratenregenerator schaltet automatisch in den langsamen Modus, &lt;br /&gt;
      sobald er einen Takt erkannt hat.&lt;br /&gt;
 ml = schneller/langsamer Modus&lt;br /&gt;
 -unknown- (1) = ??? (Standard = 1) (Auch im Datenblatt von IA4420 so beschrieben)&lt;br /&gt;
 s = (DataFilter) Typ des Datenfilters (0=DigitalFilter / 1=AnalogFilter).&lt;br /&gt;
     Bei Nutzung des Analog-Filters kann kein FIFO sowie kein ClockRecovery genuzt werden.&lt;br /&gt;
 -unknown- (1) = ??? (Standard = 1) (Auch im Datenblatt von IA4420 so beschrieben)&lt;br /&gt;
 f... = (DQD Threshold) Bestimmt den Schwellwert, ab dem ein Signal als gut empfunden wird,&lt;br /&gt;
         und der Empfänger dieses weiterverarbeiten soll.&lt;br /&gt;
         DQD (data quality detection) zählt die &amp;quot;Spikes&amp;quot; des ungefilterten Signals, und bestimmt darüber die Qualität der Daten.&lt;br /&gt;
&lt;br /&gt;
=== FIFO und RESET-Mode ===&lt;br /&gt;
 Hex = ca &amp;amp; xx&lt;br /&gt;
 Bit-Syntax: 11001010 | f3 | f2 | f1 | f0 | sp | al | ff | dr&lt;br /&gt;
 f... = (FIFO interrupt Level)&lt;br /&gt;
 sp = (Sync-Pattern length) Legt die Länge des Synchron-Patterns fest&lt;br /&gt;
      (0 = 2Byte / 1 = 1Byte)&lt;br /&gt;
 al = (FIFO Fill Condition) Legt den Wert fest, ab dem das Füllen des FIFOs beginnt.&lt;br /&gt;
      (0=Synchron / 1=Ständig). Bei Nutzung des Synchron-Modus, werden erst dann Daten in den FIFO geschrieben,&lt;br /&gt;
      wenn eine definierte 8-Bit od. 16-Bit lange Datenfolge empfangen wurde (Standard ist Hex: 2dd4,&lt;br /&gt;
      das LSB kann geändert werden und stellt das 8-Bit Synchron-Pattern dar).&lt;br /&gt;
 ff = (FIFO Fill) Startet das Einlesen der empfangenen Daten in den FIFO-Puffer.&lt;br /&gt;
      Wenn al (FIFO Fill Condition) auf synchron steht, dann startet das Setzen dieses Bits die Synchronisation-Bit-Erkennung.&lt;br /&gt;
 dr = (Sens Reset Mode) Wenn dieses Bit auf 0 steht, wird bei einer Schwankung von 200mV auf&lt;br /&gt;
      der VCC-Leitung (Spannungsversorgung des Chips), ein System-Reset ausgelöst.&lt;br /&gt;
&lt;br /&gt;
=== Automatic Frequency Control ===&lt;br /&gt;
 Hex = c4 &amp;amp; xx&lt;br /&gt;
 Bit-Syntax: 11000100 | a1 | a0 | rl1 | rl0 | st | fi | oe | en&lt;br /&gt;
 a... = Modus der AFC-Schaltung, 0=Auto off, 1=einmalig nach Einschalten, 2=Solange VDI low ist, 3=unabhängig von VDI&lt;br /&gt;
 r... = (Range Limit) Frequenzraster (00=KeineBegrenzung / 01=+15 &amp;gt; -16 / 10=+7 &amp;gt; -8 / 11=+3 &amp;gt; -4)&lt;br /&gt;
 st = Berechneten Offset-Wert übernehmen&lt;br /&gt;
 fi = Genauer Berechnungsmodus (besser aber lansgamer)&lt;br /&gt;
 oe = AFC-Offset freischalten&lt;br /&gt;
 en = AFC-Berechnung aktivieren&lt;br /&gt;
&lt;br /&gt;
=== TX Configuration Control ===&lt;br /&gt;
 Hex = 98 &amp;amp; xx&lt;br /&gt;
 Bit-Syntax: 1001100 | mp | m3 | m2 | m1 | m0 | -unknow- (0) | p2 | p1 | p0&lt;br /&gt;
 mp = (Modulation Polarity) Bestimmt die Richtung der FSK-Erzeugung (invertiert das Spektrum).&lt;br /&gt;
 m... = (fDeviation) Bestimmt den Frequenzabstand des High- und Low-Wertes bei der Ubertragung im FSK-Betrieb. Basis ist der mp-Wert.&lt;br /&gt;
 -unknown- (0) = ??? (Standard = 0) (Auch im Datenblatt von IA4420 so beschrieben)&lt;br /&gt;
 p... = Bestimmt die relative Ausgangsleistung des Senders anhand des dBm-Wertes (Dezibel [Grösse: Milliwat]) 3-dBm-Schritte.&lt;br /&gt;
        (000=0 / 001=-3 / 010=-6 / ...). Der Wert steht im Zusammenhang mit der angeschlossenen Antennen-Impedanz.&lt;br /&gt;
&lt;br /&gt;
=== Wake-Up Timer ===&lt;br /&gt;
 Bestimmt die Zeitperiode der zyklischen Einschaltung des WakeUp-Timers&lt;br /&gt;
 Hex = e &amp;amp; xxx&lt;br /&gt;
 Bit-Syntax: 111 | R4 | R3 | R2 | R1 | R0 | M7 | M6 | M5 | M4 | M3 | M2 | M1 | M0&lt;br /&gt;
 R = Exponent der Zeit&lt;br /&gt;
 M = Zeit&lt;br /&gt;
&lt;br /&gt;
=== Low Duty-Cycle ===&lt;br /&gt;
&lt;br /&gt;
Bestimmt die maximale Sendezeit pro Stunde. Dies ist wichtig, um sich an gesetzliche Frequenzzuteilungsrichtlinien zu halten, die bestimmen, wie lang jemand mit einer definierten Sendeleistung auf einer bestimmten Frequenz (mit eventuell definierter Betriebsart [Modulationstyp]) senden darf.)&lt;br /&gt;
&lt;br /&gt;
 hex = 6400 + Bits&lt;br /&gt;
 Bit-Syntax: 11001000 | d6 | d5 | d4 | d3 | d2 | d1 | d0 | en&lt;br /&gt;
 d... = Einschaltdauer während der zyklischen Einschaltung&lt;br /&gt;
 en = zyklische Einschaltung aktivieren&lt;br /&gt;
&lt;br /&gt;
=== RX FIFO Read ===&lt;br /&gt;
 Hex = b000&lt;br /&gt;
 Bit-Syntax: 1011000000000000&lt;br /&gt;
&lt;br /&gt;
Dieses Kommando löst die Rückgabe eines Datenbytes (synchron mit dem 8. Bit) aus. Es ist nötig, dass das ef-Bit (RX-FIFO) im Configuration Setting gesetzt wurde, um diese Funktion nutzen zu können!&lt;br /&gt;
&lt;br /&gt;
=== TX Register Write ===&lt;br /&gt;
Dieses Kommando schreibt Daten in den TX-Puffer. Wenn der Sender aktiv ist, wird dieses sofort gesendet. el (TX-Register) muss im Configuration-Setting-Kommando aktiv sein.&lt;br /&gt;
 Hex = b8 &amp;amp; xx&lt;br /&gt;
 Bit-Syntax: 10111000 | DataByteToSend&lt;br /&gt;
 DataByteToSend = Das Datenbyte, welches gesendet werden soll.&lt;br /&gt;
&lt;br /&gt;
(Senden Funktioniert nur wenn zuvor der Status abgefragt wurde)&lt;br /&gt;
&lt;br /&gt;
=== Status Read ===&lt;br /&gt;
Dieses Kommando löst die Rückgabe des Statusregisters aus, welches nach der ersten 0 im ersten Bit synchron übertragen wird.&lt;br /&gt;
 Hex = 0000&lt;br /&gt;
 Bit-Syntax: 0000000000000000&amp;lt;000&amp;gt;&lt;br /&gt;
 Rückgabe-Syntax: x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | x10 | x11 | x12 | x13 | x14 | x15 | x16 | x17 | x18&lt;br /&gt;
 x0 -&amp;gt; x5 = Interrupt bits&lt;br /&gt;
 x6 -&amp;gt; x15 = Status Bits&lt;br /&gt;
 x16 -&amp;gt; x18 = FIFO&lt;br /&gt;
 x0 = FFIT / RGIT (RGIT = TX-Register ist bereit neue Daten zu senden ... kann mit dem TX-Register gelöscht werden)&lt;br /&gt;
     (FFIT = Die Anzahl der Datenbits im FIFO-Puffer hat das eingestellte Limit erreicht.&lt;br /&gt;
      Kann mit einer der FIFO-Lesemethoden gelöscht werden)&lt;br /&gt;
 x1 = POR (PowerOnReset)&lt;br /&gt;
 x2 = FFOV / RGUR (RGUR = Der Datenstrom beim Senden ist abgerissen, da nicht schnell genug Daten nachgeladen wurden)&lt;br /&gt;
      (FFOV = Der RX-FIFO ist übergelaufen)&lt;br /&gt;
 x3 = WKUP&lt;br /&gt;
 x4 = EXT (Externer IRq vom nINT-Pin)&lt;br /&gt;
 x5 = LBD (Low Battery Detected)&lt;br /&gt;
 x6 = FFEM (Der FIFO-Puffer ist leer/EMpty)&lt;br /&gt;
 x7 = RSSI/ATS (ATS = )(RSSI = Die Signalstärke ist über dem eingestelltem Limit)&lt;br /&gt;
 x8 = DQD&lt;br /&gt;
 x9 = CRL&lt;br /&gt;
 x10 = ATGL&lt;br /&gt;
 x11 = OFFS_6 (sign of offset)&lt;br /&gt;
 x12 = OFFS_3&lt;br /&gt;
 x13 = OFFS_2&lt;br /&gt;
 x14 = OFFS_1&lt;br /&gt;
 x15 = OFFS_0&lt;br /&gt;
 x16 = FO&lt;br /&gt;
 x17 = FO+1&lt;br /&gt;
 x18 = FO+2&lt;br /&gt;
&lt;br /&gt;
== Einstellungen für maximale Reichweite ==&lt;br /&gt;
&lt;br /&gt;
Für eine maximale Reichweite eignen sich folgende Einstellungen:&lt;br /&gt;
* Bitrate: 2k - 10kBit/s.&lt;br /&gt;
* Receiver Baseband Bandwidth: 134kHz&lt;br /&gt;
* RSSI Threshold: -97dBm&lt;br /&gt;
* LNA gain: 0dB. Falls in der Gegend Störer im gleichen Frequenzbereich sind, dann -6dB, ansonsten kann die Eingangsstufe übersteuern.&lt;br /&gt;
* FSK frequency deviation: +/-90kHz&lt;br /&gt;
* Output Power: 0dB&lt;br /&gt;
&lt;br /&gt;
Und vor allem: Eine gute (Richt-) Antenne.&lt;br /&gt;
&lt;br /&gt;
== Quarzfrequenz ändern==&lt;br /&gt;
Im Datenblatt wird die Verwendung eines 10 MHz-Quarzes empfohlen. Man darf die Frequenz aber nach oben und unten variieren, wie Messungen mit einem DDS-Generators anstelle des Quarzes zeigen: [[Media:PLL-Rastbereich_log.pdf|PLL-Einrast-Tabelle]]. Eine [[Media:RFM12Quarz.pdf|Tabelle: Quarzfrequenzen von 8,5-11 MHz]] zeigt die damit erreichbaren Frequenzen. Quarze für 3. oder auch 5.Oberton sollten auch auf ihrer Grundfrequenz verwendbar sein, dafür bieten sich u.a. CB-Funk- und 10m-Amateurbandquarze an. &lt;br /&gt;
&lt;br /&gt;
Den Einfluß der vier unteren Bits im Configuration Setting Register und des mp-Bits (Modulations-Polarität?) auf die PLL-Frequenz zeigt diese [[Media:Varicap_RFM12.pdf|Kapazitäts-Tabelle]]. Pro Stufe sind es hier etwa 4 kHz, das kann je nach Quarz schwanken. Möglicherweise ist so auch Schmalband-FSK möglich, ohne Änderung des PLL-Teilers.&lt;br /&gt;
&lt;br /&gt;
Was können wir damit anfangen? Neben dem regulären Einsatz auf den beiden zugelassenen Bändern 433 und 868 MHz sind das unter anderem (bitte weitere Ideen einfügen):&lt;br /&gt;
&lt;br /&gt;
* Packet-Radio mit 9600 Baud im 70cm-Amateurband 430-440 MHz. Die einfachste Möglichkeit ist das Programm [http://www.baycom.org/~tom/ham/soundmodem/ Soundmodem], das für Windows und Linux existiert. Wer es komfortabler haben will findet [http://www.dj4uf.de/funktechnik/soundmodem/soundmodem.htm hier] eine Beschreibung wie Soundmodem mit den Programmen [http://www.flexnet.info/ Flexnet] und [http://www.paxon.de Paxon] zusammenarbeitet. Eine Karte der Packet-Radio-Digipeater im 70cm-Band kann man mittels [http://www.hammap.de Hammap] erstellen. Leider werden die Daten in den letzten Jahren nicht mehr sehr gepflegt, es dürften einige Karteileichen enthalten sein.&lt;br /&gt;
&lt;br /&gt;
* Empfang der [http://www.adacom.org/projekte/funkruf/ POCSAG-Funkrufsender] am oberen Ende des Amateurbandes auf  439,9875 MHz 2-FSK mit 4kHz Hub und 1200 bit/s im POCSAG Radio Paging Code 1 [http://home.arcor.de/norbert_n/samsfaq/sams.txt (Liste der Sender, Stand 18.09.07)]. Zur Decodierung existieren mehrere Programme, aufbauend auf [http://www.baycom.org/~tom/ham/linux/multimon.html Multimon] die Weiterentwicklungen [http://www.monitor.mgrohmann.de/ Monitor] und [http://monitord.de/ MonitorD]. Im Prinzip könnte man damit auch die verschlüsselten Wettermeldungen auf 466,23 MHz mitschreiben, aber nicht decodieren.&lt;br /&gt;
&lt;br /&gt;
* Empfang der [http://www.darc.de/vus/digital.html D-Star-Relais]. Das ist eine patentierte digitale Sprach- und Datenübertragung, deren Eigentümer dafür sorgt, dass kein käufliches oder Selbstbaufunkgerät ohne den &amp;quot;AMBE&amp;quot;-Modemchip D-Star senden und empfangen darf. Es gibt eine kleine Ausnahme, das [http://www.darc.de/vus/down/dstar_decode_v02a.zip Programm r00t&#039;s D-Star Decoder V0.2a] für die Soundkarte, das nur Rufzeichen und Datentelegramme der beteiligten Funkamateure darstellt.&lt;br /&gt;
&lt;br /&gt;
* Panoramaempfänger (die Bezeichnung Spektrumanalysator wäre etwas übertrieben) unter Verwendung des analogen RSSI Ausgangs (Anschluß am Kondensator in der Ecke). Damit ließe sich z.&amp;amp;nbsp;B. auch die Bandbelegung im PMR-Bereich 446,0-446,2 MHz oder im Mobilfunkband um 900 MHz anzeigen.&lt;br /&gt;
&lt;br /&gt;
* Pegelanzeige für Mobilfunksender. Im 900 MHz Mobilfunkbereich könnte man mit dem RSSI-Ausgang die umliegenden Funkmasten anpeilen und ihre Pegel anzeigen. Laut Datenblatt nur ein Anzeigeumfang von 35 dB, aber mit umschaltbarem Grundpegel.&lt;br /&gt;
&lt;br /&gt;
* In Verbindung mit einem Frequenzumsetzer lassen sich weitere Frequenzbereiche erschließen, z.&amp;amp;nbsp;B. Packet-Radio im 23cm- (1240-1200 MHz)  und 13cm- (2320-2450 MHz) Amateurband. Leider liegt die Zwischenfrequenz der Satellitentuner (479,5 MHz) schon am oberen Ende des PLL-VCO-Einrastbereiches. Damit wäre ein preiswerter Konverter für 23cm möglich, meistens schon mit I2C-Bus PLL.&lt;br /&gt;
&lt;br /&gt;
* Local Oscillator für einen Empfänger. Mir den ca. 5 Milliwatt des RFM12 läßt sich ein [http://www.mini-circuits.com/products/fm_sm_main.html passiver Diodenringmischer] ansteuern. Damit kann man einen Überlagerungsempfänger oder -sender mit hoher erster Zwischenfrequenz bauen.&lt;br /&gt;
&lt;br /&gt;
== Antennen-Anpaßnetzwerk==&lt;br /&gt;
[[Image:Antennenanpassung.png|thumb|right|400px|Antennen-Anpassnetzwerk im Datenblatt]]&lt;br /&gt;
Soll das RFM12 auf anderen Frequenzen betrieben werden, ist nur eine Änderung des Antennennetzwerks nötig. Das Datenblatt bietet knappe aber ausreichende Informationen.  &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zwischen Pin 12 und 13 liegt eine Spannungsquelle, die ihre maximale Sendeleistung in eine komplexe Last nach der Tabelle &amp;quot;Note4&amp;quot; abgibt. Das bedeutet, ihr Innenwiderstand ist konjugiert-komplex zu dieser Last, also dieselben Zahlenwerte, nur mit Minuszeichen vor dem &amp;quot;j&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Anpassnetzwerk läßt sich auf zwei Bauteile reduzieren: von der Antenne ausgehend, die als reeller 50 Ohm- Widerstand angenommen wird, ist ein Kondensator in Reihe geschaltet. C8 und C9 (in der Tabelle C9 und C10 bezeichnet) liegen in Reihe und sind gleich groß, dürfen also in einem Kondensator mit der halben Kapazität zusammengefasst werden. Dann liegt noch L1 parallel zur Quelle, L3 hat mehr als den 20-fachen Wert und kann vernachlässigt werden.&lt;br /&gt;
Das ganze läßt sich im Smith-Diagramm gut darstellen.&lt;br /&gt;
&lt;br /&gt;
[[Image:SmithDiagramm.png|thumb|right|400px|Anpassnetzwerk im Smith-Diagramm]]&lt;br /&gt;
&lt;br /&gt;
Von der Antenne im Mittelpunkt ausgehend bewegen wir uns mit dem Serien-C Cs auf einem Kreisbogen nach unten (kapazitive Halbebene) auf den Punkt &amp;quot;Unendlich&amp;quot; rechts außen zu. Ungefähr senkrecht unter dem Zielpunkt, hier für 433 MHz gezeichnet, biegen wir ab auf eine Kreisbahn für die Parallelinduktivität Lp. Sie führt in die obere (induktive) Halbebene auf den Nullpunkt links zu. Der genaue Schnittpunkt beider Kreise kann &amp;quot;mit Zirkel und Lineal&amp;quot; oder einem der [http://www.mikrocontroller.net/articles/Schaltungssimulation#Hochfrequenztechnik Hochfrequenz-Berechnungsprogramme] ermittelt werden.&lt;br /&gt;
&lt;br /&gt;
Die Kreise für Lp oder Cp sind im Smith-Diagramm nicht eingezeichnet , um die Übersicht zu wahren. Man könnte ein gespiegeltes Diagramm darüberlegen, aber stattdessen spiegelt man die Kurve am Diagramm-Mittelpunkt (dünne blaue Kurven). Am Rand kann man jetzt die auf 50 Ohm (bzw. 1/50Ohm für die gespiegelte Kurve) normierten Blindwiderstände ablesen. Für Cs lesen wir eine Differenz zwischen Start und Zielpunkt von etwa Xc=(3,2-0) * 50 Ohm ab, für Lp sind es (0,25 +0,32) = 0,57*(1/50 Ohm). Damit erhalten wir Cs=1/(2*Pi*f*Xc)=2,3 pF das war wie gesagt die halbe Kapazität der beiden hintereinandergeschalteten Kondensatoren, Tabellenwert ist 4,7pF und Lp=1/(2*Pi*f*0,57*(1/50))= 32,2 nH, der Tabellenwert ist 27nH.&lt;br /&gt;
&lt;br /&gt;
[[Image:Antennenanpassung_RF12.png|thumb|right|400px|Anpassnetzwerk im Datenblatt zu RF12]]&lt;br /&gt;
[[Image:Smith-Diagramm-RF12.png|thumb|right|400px|Smith-Diagramm zum RF12]]&lt;br /&gt;
Im RF12 wird ein um zwei Bauteile (im Bild C2 und L1 genannt) erweitertes Netzwerk empfohlen, das macht man um eine breitbandigere Anpassung zu erreichen.&lt;br /&gt;
&lt;br /&gt;
== Betriebsspannung==&lt;br /&gt;
Achtung nicht alle Module sind für 5V geeignet, alle Typen mit &amp;quot;B&amp;quot; am Ende sind nur für 3,3V. Man muß dann entweder den Mikrocontroller ebenfalls mit 3,3V betreiben, oder [http://www.mikrocontroller.net/articles/Pegelwandler Pegelwandler] verwenden.&lt;br /&gt;
&lt;br /&gt;
== Messungen ==&lt;br /&gt;
Drei Messungen am RFM12 zeigen den Einfluß von Eingangpegel, Frequenzhub und Mittenfrequenz auf das Ausgangssignal, gemessen am Filterkondensator CFIL. Zwei weitere Kurven zeigen die ARSSI-Spannung (Anschluß am Kondensator in der Ecke) und die damit gemessene Filterkurve.&lt;br /&gt;
[[Image:RFM12_Eingangspegel.png|thumb|right|800px|Messungen am RFM12 Änderung des Eingangspegels]]&lt;br /&gt;
[[Image:RFM12_Frequenzhub.png|thumb|right|800px|Messungen am RFM12 Änderung des Frequenzhubs]]&lt;br /&gt;
[[Image:RFM12_Mittenfrequenz.png|thumb|right|800px|Messungen am RFM12 Änderung der Mittenfrequenz]]&lt;br /&gt;
[[Image:RFM12_ARSSI_und_Filterkurve.png|thumb|right|200px|Messungen am RFM12 ARSSI_und_Filterkurve]]&lt;br /&gt;
&lt;br /&gt;
Was folgt aus diesen Messungen?&lt;br /&gt;
* Der ARRSI-Anschluß zeigt uns über mehr als 100 kHz ein Sendesignal an. Decodierbar ist es aber nur im Abstand von weniger als 5 kHz von der Mittenfrequenz. Ohne Abgleich von Sender und Empfänger ist also die AFC unverzichtbar.&lt;br /&gt;
* Das &amp;quot;Loch&amp;quot; in der Mitte der Durchlaßkurve stammt von dem im Datenblatt gezeigten Hochpass &amp;quot;&amp;gt; 7 kHz&amp;quot;. Für ein unmoduliertes Sendesignal geht die ARSSI-Spannung fast auf den Rauschpegel herunter, hier wurde mit +/-15kHz moduliert. &lt;br /&gt;
* Damit läßt sich der Empfänger abgleichen. Man braucht dazu nur ein unmoduliertes Sendesignal auf der Sollfrequenz. Das kann ein mittels Frequenzzähler abgeglichenes zweites RFM12 sein. Der Empfängerquarz wird mit den 4 Bit für die Oszillatorkapazität genau auf dieses &amp;quot;Loch&amp;quot; der ARRSI-Spannung eingestellt.&lt;br /&gt;
&lt;br /&gt;
Die AFC-Messdauer ist im Datenblatt nicht genannt, eine schnelle Abfrage des ATGL-Bit im Statusregister im &amp;quot;Auto-AFC&amp;quot; - Modus liefert minimale Pulsbreiten von ca. 250..270 µsec, entsprechend einer Messfolgefrequenz von 4 kHz - leider nicht ausreichend um 9600 Baud Schmalband-FM zu demodulieren. Im Auto-Modus werden zwei Messungen zusammengefasst, damit beträgt die Updaterate sogar nur 2 kHz. Weitere Messung : ab etwa +/-10 kHz Hub synchronisiert sich das ATGL-Bit auf der Mittenfrequenz mit einem bis zu 1,8...2 kHz FM-modulierten Signal.&lt;br /&gt;
&lt;br /&gt;
Neue Idee: &amp;quot;Dithering und FM-Flankendemodulator&amp;quot;: &amp;lt;br&amp;gt; &lt;br /&gt;
Wenn das Empfangssignal nicht weit genug FM-moduliert ist, müssen wir eben den Empfänger modulieren. Im Timer-Interrupt wird die Quarzkapazität oder die PLL z.&amp;amp;nbsp;B. mit 38,4 oder 76,8 kHz und mindestens +/-15kHz Hub umgeschaltet, sodaß bei Empfang eines unmodulierten Signals am CFIL-Ausgang ein symmetrisches Rechteck dieser Frequenz erscheint. Ist das Empfangssignal schmalbandig FM-moduliert, und man stimmt den Empfänger leicht daneben ab, so sollte das CFIL-Signal mit dieser Modulation PWM-moduliert sein. Ein Tiefpass filtert die Dithering-Frequenz weg und übrig bleibt (wenns funktioniert) die Modulation, vielleicht sogar analoger Sprechfunk...&lt;br /&gt;
Motto &amp;quot;Engineering is the art of making what you want from things you can get.&amp;quot; (von http://www.dsprelated.com)&lt;br /&gt;
&lt;br /&gt;
== Bezugsquellen ==&lt;br /&gt;
* [[Elektronikversender#csd-electronics|csd-electronics]]&lt;br /&gt;
* [[Elektronikversender#IT-WNS|IT-WNS]]&lt;br /&gt;
* [[Elektronikversender#Pollin_Electronic|Pollin Electronic]]&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
* [[AVR RFM12]]&lt;br /&gt;
* [[RFM12 Protokoll Stack]]&lt;br /&gt;
* [[ Pollin_Funk-AVR-Evaluationsboard]]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/93801 Bezugsquellen]&lt;br /&gt;
* [http://www.das-labor.org/storage/LaborLib/rfm12/ Library zur Ansteuerung des RFM12]&lt;br /&gt;
* [http://www.compotron.com/daten/any/IA4420.pdf Datenblatt des Chipherstellers Integration IA4420.pdf]&lt;br /&gt;
* [https://www.silabs.com/Support%20Documents/TechnicalDocs/Si4420.pdf Silabs hat Integration im Juni 2008 gekauft, Chipbezeichnung jetzt Si4420]&lt;br /&gt;
Folgende Links sind mit Vorsicht zu genießen, da die Datenblätter teilweise  fehlerbehaftet sind. Es empfiehlt sich, direkt mit dem Datenblatt des RF12 (das ist das IC auf dem Modul) zu arbeiten. Dieses ist so gut wie fehlerfrei.&lt;br /&gt;
&lt;br /&gt;
* [http://www.hoperf.com/upfile/RF12.pdf Datenblatt des ICs RF12] (PDF)&lt;br /&gt;
* [http://www.hoperf.com/upfile/RFM12.pdf Datenblatt des Moduls RFM12] (PDF)&lt;br /&gt;
* [http://www.hoperf.com/upfile/RF12_code.pdf Programming Guide] (PDF)&lt;br /&gt;
* [http://www.hoperf.com/upfile/RF12TOOLS.pdf Demo Kit User Manual] (PDF)&lt;br /&gt;
* [http://www.pollin.de/shop/downloads/D810047S.ZIP Beispielprogramm von Pollin] (ZIP)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Bauteile]]&lt;br /&gt;
[[Kategorie:Funk]]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=GoFlexHome&amp;diff=52229</id>
		<title>GoFlexHome</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=GoFlexHome&amp;diff=52229"/>
		<updated>2010-10-24T19:39:33Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: /* SATA */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hier sollen Daten gesammelt werden zur Seagate GoFlex &#039;&#039;&#039;Home&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Überblick ==&lt;br /&gt;
&lt;br /&gt;
Die Hardware der Seagate GoFlex &#039;&#039;&#039;Home&#039;&#039;&#039; gleicht der [http://www.mikrocontroller.net/articles/Dockstar DockStar] bzw. der [http://www.mikrocontroller.net/articles/GoFlexNet GoFlex Net].&lt;br /&gt;
Unterschied: Nur ein USB-Port vorhanden, dafür aber ein SATA Port ;)&lt;br /&gt;
&lt;br /&gt;
Es gibt die GoFlex Home in zwei Ausführungen:&lt;br /&gt;
* mit 1TB Platte ab ca. 115€&lt;br /&gt;
* mit 2TB Platte ab ca. 155€&lt;br /&gt;
&lt;br /&gt;
siehe: http://www.heise.de/preisvergleich/?cat=hdxnas&amp;amp;asuch=GoFlex%20Home&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Beitrag im Forum =&lt;br /&gt;
[http://www.mikrocontroller.net/topic/187115#new 20Euro Embedded System mit ARM, 128MB RAM und 256MB Flash ]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Technische Daten =&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| CPU  || Marvell &amp;quot;Kirkwood&amp;quot; 88F6281, 1.2GHz (ARM926EJ-S &lt;br /&gt;
|-&lt;br /&gt;
| Speicher || 128 MB (Nanya NT5TU64M16DG-AC)&lt;br /&gt;
|-&lt;br /&gt;
| Flash || 512 MB&lt;br /&gt;
|-&lt;br /&gt;
| Netzwerk || Marvell 88E1116R Gigabit Ethernet port&lt;br /&gt;
|-&lt;br /&gt;
| Schnittstellen || 1x USB 2.0 Marvell Orion EHCI&lt;br /&gt;
|-&lt;br /&gt;
| Platte || Seagate ST31000528AS (1TB Version)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== cpuinfo ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Processor	: ARM926EJ-S rev 1 (v5l)&lt;br /&gt;
BogoMIPS	: 1192.75&lt;br /&gt;
Features	: swp half thumb fastmult edsp &lt;br /&gt;
CPU implementer	: 0x56&lt;br /&gt;
CPU architecture: 5TE&lt;br /&gt;
CPU variant	: 0x2&lt;br /&gt;
CPU part	: 0x131&lt;br /&gt;
CPU revision	: 1&lt;br /&gt;
Cache type	: write-back&lt;br /&gt;
Cache clean	: cp15 c7 ops&lt;br /&gt;
Cache lockdown	: format C&lt;br /&gt;
Cache format	: Harvard&lt;br /&gt;
I size		: 16384&lt;br /&gt;
I assoc		: 4&lt;br /&gt;
I line length	: 32&lt;br /&gt;
I sets		: 128&lt;br /&gt;
D size		: 16384&lt;br /&gt;
D assoc		: 4&lt;br /&gt;
D line length	: 32&lt;br /&gt;
D sets		: 128&lt;br /&gt;
&lt;br /&gt;
Hardware	: Feroceon-KW&lt;br /&gt;
Revision	: 0000&lt;br /&gt;
Serial		: 0000000000000000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== /proc/mtd ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
dev:    size   erasesize  name&lt;br /&gt;
mtd0: 00100000 00020000 &amp;quot;u-boot&amp;quot;&lt;br /&gt;
mtd1: 00600000 00020000 &amp;quot;uImage&amp;quot;&lt;br /&gt;
mtd2: 0f900000 00020000 &amp;quot;root&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= original Software =&lt;br /&gt;
&lt;br /&gt;
=== HipServ 2.0 OS ===&lt;br /&gt;
&lt;br /&gt;
Auf der GoFlex &#039;&#039;&#039;Home&#039;&#039;&#039; läuft &#039;&#039;&#039;HipServ 2.0 OS&#039;&#039;&#039; von &#039;&#039;Axentra&#039;&#039; und nicht [http://www.pogoplug.com pogoplug] wie auf der Dochstar oder der GoFlex &#039;&#039;&#039;Net&#039;&#039;&#039;. (Siehe [http://www.smallnetbuilder.com/nas/nas-reviews/31227-seagate-goflex-home-reviewed GoFlex Home Review auf smallnetbuilder.com])&lt;br /&gt;
&lt;br /&gt;
HipServ OS läuft auch auf anderen NAS, z.B.:&lt;br /&gt;
* [http://www.smallnetbuilder.com/nas/nas-reviews/31050-netgear-stora-reviewed NETGEAR Stora]&lt;br /&gt;
* &#039;&#039;LaCie Ethernet Disk mini – Home Edition&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Auf der GoFlexHome läuft (uname -a):&lt;br /&gt;
&lt;br /&gt;
  Linux axentraserver.USERNAME.seagateshare.com 2.6.22.18 #16 Thu Jun 17 01:37:53 EDT 2010 armv5tejl armv5tejl armv5tejl GNU/Linux&lt;br /&gt;
&lt;br /&gt;
Einige Modifikationen und Erweiterung der Original Software ist hier beschrieben:&lt;br /&gt;
* http://www.openstora.com/wiki/ (Wiki über die NETGEAR Stora)&lt;br /&gt;
&lt;br /&gt;
=== Dienste ===&lt;br /&gt;
&lt;br /&gt;
Auf der Box laufen einige Dienste:&lt;br /&gt;
&amp;lt;pre&amp;gt;~$ nmap -sT 169.254.xxx.yyy&lt;br /&gt;
&lt;br /&gt;
PORT      STATE SERVICE&lt;br /&gt;
21/tcp    open  ftp&lt;br /&gt;
22/tcp    open  ssh&lt;br /&gt;
80/tcp    open  http&lt;br /&gt;
139/tcp   open  netbios-ssn&lt;br /&gt;
443/tcp   open  https&lt;br /&gt;
445/tcp   open  microsoft-ds&lt;br /&gt;
548/tcp   open  afp&lt;br /&gt;
631/tcp   open  ipp&lt;br /&gt;
6689/tcp  open  unknown &amp;lt;- &amp;quot;Firefly Media Server&amp;quot; s.unten&lt;br /&gt;
8200/tcp  open  unknown&lt;br /&gt;
49152/tcp open  unknown&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Hacking ==&lt;br /&gt;
&lt;br /&gt;
=== root login ===&lt;br /&gt;
&lt;br /&gt;
Ähnlich wie bei der [http://www.openstora.com/wiki/index.php?title=Easy_Root_Access Netgear Stora] kann man sich so einloggen!&lt;br /&gt;
&lt;br /&gt;
Als erstes muß man einen User über die normale GoFlex Weboberfläche einrichten.&lt;br /&gt;
&lt;br /&gt;
Dann kann man sich damit einloggen:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ssh &#039;&#039;USERNAME&#039;&#039;_hipserv2_seagateplug_&#039;&#039;XXXX-XXXX-XXXX-XXXX&#039;&#039;@&#039;&#039;IP_ADDRESSE&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Dabei ist XXXX-XXXX-XXXX-XXXX der Produkt-Schlüssel (sieh &#039;&#039;&#039;PK:&#039;&#039;&#039; auf Geräte Unterseite). Das Passwort ist das normale Benutzerpasswort, welches man bei der Einrichtung vergeben hat.&lt;br /&gt;
&lt;br /&gt;
=== updates deaktivieren ===&lt;br /&gt;
&lt;br /&gt;
Nach dem mal sich eingeloggt hat, ist es wohl eine gute Idee, die Update Dienste zu deaktivieren.&lt;br /&gt;
&lt;br /&gt;
In Kürze:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
chmod -x /usr/bin/oe-update-checker&lt;br /&gt;
chmod -x /etc/cron.daily/update-checker&lt;br /&gt;
chmod -x /etc/cron.hourly/update-checker&lt;br /&gt;
chmod -x /etc/init.d/openvpn&lt;br /&gt;
chmod -x /usr/sbin/openvpn&lt;br /&gt;
chmod -x /var/www/admin/sshtunnel.pl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
siehe: http://www.openstora.com/wiki/index.php?title=Disabling_updates_and_external_access&lt;br /&gt;
&lt;br /&gt;
=== firefly ===&lt;br /&gt;
&lt;br /&gt;
Auf der GoFlex Home läuft &amp;quot;Firefly Media Server&amp;quot; auf Port 6689.&lt;br /&gt;
Man kann sich einloggen mit:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| Username: || &#039;&#039;&#039;root&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| Passwort: || &#039;&#039;&#039;sLPoe243&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Damit ist es möglich alle Dateien auf der Box einzusehen. Dazu stellt man in der Konfiguration von Firefly den Document Root auf &amp;quot;/&amp;quot;&lt;br /&gt;
Nun kann man Dateien per URL einsehen, z.B.: &#039;&#039;http://192.168.xx.xx:6689/var/log/dmesg&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Nach dem ändern von DocRoot kommt man allerdings nicht mehr an die Konfiguration von Firefly ran, weil die Seiten nicht mehr Aufrufbar sind.&lt;br /&gt;
Abhilfe schafft hier nur ein reset per Nadel in die Seite vom Gerät, was alle Einstellungen rücksetzt.&lt;br /&gt;
&lt;br /&gt;
Interessante Dateien sind u.a.:&lt;br /&gt;
* /etc/init.d/oe-bootinit&lt;br /&gt;
* /etc/init.d/oe-bootfinish&lt;br /&gt;
* /etc/oe-release&lt;br /&gt;
* /etc/samba/smb.conf&lt;br /&gt;
* /etc/mtab&lt;br /&gt;
* /etc/crontab&lt;br /&gt;
* /usr/sbin/oe-check-daemons&lt;br /&gt;
* /etc/branding.conf&lt;br /&gt;
* /etc/features.conf&lt;br /&gt;
* /var/www/.ssh/id_dsa.pub&lt;br /&gt;
* /var/www/.ssh/id_dsa&lt;br /&gt;
* /etc/vsftpd/vsftpd.pem&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==UART-Stecker==&lt;br /&gt;
Auf der Platine befindet sich eine 10-polige Stiftleiste im 2mm Rastermass (J1).&lt;br /&gt;
&lt;br /&gt;
Die Belegung ist wahrscheinlich identisch zur Dockstar bzw. GoFlex Net, siehe auch: [[Dockstar#UART.2FJTAG-Stecker]]&lt;br /&gt;
&lt;br /&gt;
Zumindest die Pins GND, UART TxD und UART RxD sind gleich:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  9  7  5  3  1&lt;br /&gt;
 10  8  6  4  2&lt;br /&gt;
       RX TX GND&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Pin 1 ist auf der Platine mit einem kleine weißen Dreieck gekennzeichnet!&lt;br /&gt;
&lt;br /&gt;
Am einfachsten man beschafft sich ein sog. &amp;quot;PL-2303 USB-to-Serial Port Adapter&amp;quot;, z.B. ein Handy-Kabel, mehr dazu: [[UART/JTAG auf USB]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Verbindung unter Linux ===&lt;br /&gt;
&lt;br /&gt;
USB Stecker rein und auf Konsole eine screen session starten, mit:&lt;br /&gt;
  screen /dev/ttyUSB0 115200&lt;br /&gt;
&lt;br /&gt;
Danach Box anmachen und so was in der Art sollte erscheinen:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
U-Boot 2010.09-dirty (Oct 19 2010 - 12:17:56)&lt;br /&gt;
Marvell-GoflexNet by Jeff Doozan, Peter Carmichael&lt;br /&gt;
&lt;br /&gt;
SoC:   Kirkwood 88F6281_A0&lt;br /&gt;
DRAM:  128 MiB&lt;br /&gt;
NAND:  256 MiB&lt;br /&gt;
In:    serial&lt;br /&gt;
Out:   serial&lt;br /&gt;
Err:   serial&lt;br /&gt;
Net:   egiga0&lt;br /&gt;
88E1116 Initialized on egiga0&lt;br /&gt;
Using egiga0 device&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= debian installieren =&lt;br /&gt;
&lt;br /&gt;
Die installation ist genau wie auf der Dockstar möglich, siehe:&lt;br /&gt;
* http://www.mikrocontroller.net/articles/DockstarDebianSqueeze&lt;br /&gt;
* http://jeff.doozan.com/debian/&lt;br /&gt;
&lt;br /&gt;
== nach der installation ==&lt;br /&gt;
&lt;br /&gt;
=== netconsole - uBoot ===&lt;br /&gt;
&lt;br /&gt;
Wie auf http://jeff.doozan.com/debian/uboot/ beschrieben ist es möglich, ähnlich wie mit einer Seriellen Verbindung, eine netconsole aufzubauen:&lt;br /&gt;
&lt;br /&gt;
Auf der Box die netconsole in uBoot aktivieren:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
fw_setenv serverip 192.168.xxx.xxx&lt;br /&gt;
fw_setenv ipaddr 192.168.1.100&lt;br /&gt;
fw_setenv if_netconsole &#039;ping $serverip&#039;&lt;br /&gt;
fw_setenv start_netconsole &#039;setenv ncip $serverip; setenv bootdelay 10; setenv stdin nc; setenv stdout nc; setenv stderr nc; version;&#039;&lt;br /&gt;
fw_setenv preboot &#039;run if_netconsole start_netconsole&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Danach die Box rebooten&lt;br /&gt;
&lt;br /&gt;
Auf dem Host system muß netcat (kurz &#039;&#039;nc&#039;&#039;) installiert sein, z.b.:&lt;br /&gt;
&lt;br /&gt;
  apt-get install netcat&lt;br /&gt;
&lt;br /&gt;
Man startet nun das lauschen, während die Box hochfährt, mit:&lt;br /&gt;
(Das &#039;&#039;netconsole&#039;&#039; Skript von jeff doozan tut es bei mir nicht, siehe: http://forum.doozan.com/read.php?3,1784 )&lt;br /&gt;
&lt;br /&gt;
  nc -u -p 6666 -v 192.168.1.100 6666&lt;br /&gt;
&lt;br /&gt;
(Die IP Adresse wurde vorher mit &#039;&#039;fw_setenv ipaddr&#039;&#039; festgelegt, siehe oben.)&lt;br /&gt;
&lt;br /&gt;
Wenn alles klappt, landet in einer interaktiven uBoot Shell. Sieht in etwa so aus:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
U-Boot 2010.06-00695-gbd23130-dirty (Aug 30 2010 - 23:04:56)&lt;br /&gt;
Marvell-Dockstar/Pogoplug by Jeff Doozan&lt;br /&gt;
Hit any key to stop autoboot:&lt;br /&gt;
Marvell&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== alternative ====&lt;br /&gt;
&lt;br /&gt;
Netzwerk Alias erzeugen mit:&lt;br /&gt;
  sudo ifconfig eth0:0 10.0.0.1&lt;br /&gt;
&lt;br /&gt;
Netz-Konsole starten mit:&lt;br /&gt;
  nc -luk 10.0.0.1 6666&lt;br /&gt;
&lt;br /&gt;
=== anderes uBoot Image testen via NFS ===&lt;br /&gt;
&lt;br /&gt;
Man kann in der uBoot shell auch einen anderen uBoot nachladen. Das geht über tftp oder NFS. Hier ein Beispiel mit NFS:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Marvell&amp;gt;&amp;gt; setenv bootfile &amp;quot;/share/uboot-sata-090903.bin&amp;quot;&lt;br /&gt;
setenv bootfile &amp;quot;/share/uboot-sata-090903.bin&amp;quot;&lt;br /&gt;
Marvell&amp;gt;&amp;gt; setenv serverip 192.168.1.1&lt;br /&gt;
setenv serverip 192.168.1.1&lt;br /&gt;
Marvell&amp;gt;&amp;gt; nfs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Wichtig dabei: Bei &#039;&#039;bootfile&#039;&#039; muß der volle Pfad angegeben werden. Dies schließt auch den Teil in /etc/exports mit ein!&lt;br /&gt;
&lt;br /&gt;
Bsp &#039;&#039;&#039;/etc/exports&#039;&#039;&#039;:&lt;br /&gt;
  /share       192.168.0.0/255.255.0.0(rw,no_root_squash,sync)&lt;br /&gt;
&lt;br /&gt;
Wird die Datei nicht gefunden, weil Pfad/Dateiname bei &#039;&#039;bootfile&#039;&#039; falsch geschrieben ist, kommt sowas:&lt;br /&gt;
  Loading: *** ERROR: Cannot mount&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== anderes uBoot Image via TFTP testen ===&lt;br /&gt;
&lt;br /&gt;
==== TFTP server einrichten ====&lt;br /&gt;
&lt;br /&gt;
Als erstes diese Pakete installieren:&lt;br /&gt;
  aptitude install tftpd-hpa tftp-hpa&lt;br /&gt;
&lt;br /&gt;
In Datei &#039;&#039;/etc/default/tftpd-hpa&#039;&#039; das folgende anhängen:&lt;br /&gt;
  RUN_DAEMON=&amp;quot;yes&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Dienst startet man mit &#039;&#039;&#039;start tftpd-hpa&#039;&#039;&#039; bzw. neustart mit &#039;&#039;&#039;restart tftpd-hpa&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Dann braucht man noch ein uBoot Image und packt es in bsp. &#039;&#039;/var/lib/tftpboot/&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==== TFTP testen ====&lt;br /&gt;
&lt;br /&gt;
Man kann den tftp server testen, in dem man auf einem anderen Rechner das installiert:&lt;br /&gt;
  aptitude install tftp-hpa&lt;br /&gt;
&lt;br /&gt;
Dann im Terminal verbinden, bsp:&lt;br /&gt;
  tftp -v 192.168.1.1&lt;br /&gt;
  Connected to 192.168.1.1 (192.168.1.1), port 69&lt;br /&gt;
  tftp&amp;gt; help&lt;br /&gt;
&lt;br /&gt;
Danach kann man versuchen, eine Datei zu ziehen, bsp:&lt;br /&gt;
  tftp&amp;gt; get my_uboot_image.mtd0.kwb&lt;br /&gt;
&lt;br /&gt;
Ein lokaler test auf der selben Maschine ist aber auch möglich, bsp:&lt;br /&gt;
  tftp localhost -c get my_uboot_image.mtd0.kwb&lt;br /&gt;
&lt;br /&gt;
Bekommt man &amp;quot;File Not Found&amp;quot; oder &amp;quot;Permission Denied&amp;quot;, kann das nicht nur am falsch geschriebenen Pfad liegen, sondern auch an falschen Rechten, das sollte helfen:&lt;br /&gt;
  sudo chmod 777 -R /var/lib/tftpboot&lt;br /&gt;
&lt;br /&gt;
==== uBoot chainload via tftp ====&lt;br /&gt;
&lt;br /&gt;
Auf der Box macht man nun folgendes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Marvell&amp;gt;&amp;gt; setenv serverip 192.168.1.1&lt;br /&gt;
setenv serverip 192.168.1.1&lt;br /&gt;
Marvell&amp;gt;&amp;gt; tftp 0x800000 my_uboot_image.mtd0.kwb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== SATA ===&lt;br /&gt;
&lt;br /&gt;
Der Zugriff auf die SATA Platte ist offenbar nicht out-of-the-box gegeben. Was man machen muß, damit es geht, steht noch nicht fest. Es reicht nicht aus die [http://www.arm.linux.org.uk/developer/machines/ arcNumber] zu ändern.&lt;br /&gt;
&lt;br /&gt;
Siehe Forum Thread ab: http://www.mikrocontroller.net/topic/187115?page=5#1901270&lt;br /&gt;
&lt;br /&gt;
=== LEDs ===&lt;br /&gt;
&lt;br /&gt;
Wer möchte, das die LEDs nach dem booten aktiv ist (statt aus), kann beispielsweise das machen:&lt;br /&gt;
&lt;br /&gt;
  fw_setenv led_exit green on&lt;br /&gt;
&lt;br /&gt;
Es gibt drei trigger Variablen (hier mit den default Werten):&lt;br /&gt;
&lt;br /&gt;
  led_init=green blinking&lt;br /&gt;
  led_exit=green off&lt;br /&gt;
  led_error=orange blinking&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/Dockstar DockStar] Wiki Seite&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/GoFlexNet GoFlex Net] Wiki Seite&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
&lt;br /&gt;
* http://www.heise.de/preisvergleich/?cat=hdxnas&amp;amp;asuch=GoFlex%20Home&lt;br /&gt;
* http://www.smallnetbuilder.com/nas/nas-reviews/31227-seagate-goflex-home-reviewed&lt;br /&gt;
* http://www.testfreaks.com/blog/review/review-of-seagate-goflex-home-network-storage-system/&lt;br /&gt;
* http://www.marvell.com/products/processors/embedded/kirkwood&lt;br /&gt;
&lt;br /&gt;
Bilder:&lt;br /&gt;
&lt;br /&gt;
* [http://www.smallnetbuilder.com/myincludes/image_page.php?/images/stories/nas/seagate_goflex_home/seagate_goflex_home_board.jpg seagate_goflex_home_board.jpg]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:ARM-Boards]]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Dockstar_Extension_Board&amp;diff=51344</id>
		<title>Dockstar Extension Board</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Dockstar_Extension_Board&amp;diff=51344"/>
		<updated>2010-10-13T18:09:13Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: /* Mikrocontroller */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Das Dockstart Extension Board (Dockext) ist als Aufsteckplatine für die Seagate [[Dockstar]] gedacht und erweitert diese um ein Display und vier Taster.&lt;br /&gt;
&lt;br /&gt;
= Features =&lt;br /&gt;
* Anzeige der aktuellen IP-Adresse&lt;br /&gt;
* Anzeige des freien Speicherplatzes ausgewählter Mountpoints&lt;br /&gt;
* Herunterfahren des Systems&lt;br /&gt;
&lt;br /&gt;
= Hardware =&lt;br /&gt;
&lt;br /&gt;
[[Bild:Dockext.jpg]]&lt;br /&gt;
&lt;br /&gt;
[[Bild:Dockext.png|600px]]&lt;br /&gt;
&lt;br /&gt;
[[Media:Dockext.zip|Kicad Projekt]]&lt;br /&gt;
&lt;br /&gt;
== Stückliste ==&lt;br /&gt;
Alle Teile gibts bei Reichelt: [http://www.reichelt.de/?ACTION=20;AWKID=294595;PROVID=2084 Reichelt Warenkorb]&lt;br /&gt;
Die Mini-Usb Buchse fehlt noch im Warenkorb: [http://www.reichelt.de/?;ACTION=3;LA=5;GROUP=C126;GROUPID=3213;ARTICLE=52003;START=0;SORT=user;OFFSET=500 USB BWM SMD]&lt;br /&gt;
&lt;br /&gt;
Inzwischen würde ich das Display mit schwarzer Schrift nicht nochmal mit blauer Hintergrundbeleuchtung kaufen, die Ablesbarkeit ist zu schlecht.&lt;br /&gt;
&lt;br /&gt;
= Software =&lt;br /&gt;
== Mikrocontroller ==&lt;br /&gt;
Die Software auf dem Mikrocontroller ist minimalistisch gehalten. Über die serielle Schnittstelle wird der darzustellende Text in Klartext empfangen. Wurde ein Taste betätigt, wird die Nummer des Tasters gesendet (1-4). Eingestellte Baudrate ist 19200. Außer der Klartextübertragung wurden noch Befehle für das Löschen des Displays, setzen des Cursors und Ansteuerung der Hintergrundbeleuchtung implementiert.&lt;br /&gt;
&lt;br /&gt;
[[Media:dockext_code_0_11.tar.gz]]&lt;br /&gt;
&lt;br /&gt;
== Daemon (dockextd) ==&lt;br /&gt;
Der Daemon kommuniziert mit dem Dockstar Extension Board über die virtuelle serielle Schnittstelle. Derzeit ist das Device /dev/dockext hart-codiert. Die Zuordnung geschieht mithilfe von udev. Auf diese Weise ist gewährleistet, dass das Board immer den gleichen Namen im System bekommt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Media:dockextd_0_11.tar.gz]]&lt;br /&gt;
&lt;br /&gt;
=== Kompilieren ===&lt;br /&gt;
Um den Daemon auf der Dockstar zu übersetzen, habe ich eine standart Debian Installation zusammen mit folgenden Paketen verwendet:&lt;br /&gt;
* build-essential&lt;br /&gt;
* libglib2.0-dev&lt;br /&gt;
* pkg-config&lt;br /&gt;
&lt;br /&gt;
= Bilder =&lt;br /&gt;
[[Bild:df.jpg]] [[Bild:ip.jpg]]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=AVR_Bootloader_FastBoot_von_Peter_Dannegger&amp;diff=51228</id>
		<title>AVR Bootloader FastBoot von Peter Dannegger</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=AVR_Bootloader_FastBoot_von_Peter_Dannegger&amp;diff=51228"/>
		<updated>2010-10-09T07:40:37Z</updated>

		<summary type="html">&lt;p&gt;Frankalicious: /* Was ist ein Bootloader? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;von Karsten Donat&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Was ist ein Bootloader? ==&lt;br /&gt;
&lt;br /&gt;
Der Bootloader ist selbst ein kleines Programm. Es wird beim Start des Controllers zuerst ausgeführt. Damit sich das PC-Programm für das Firmware-Update melden kann, wartet der Bootloader  eine gewisse Zeit (hier 0,33 Sekunden) auf ein Zeichen über die serielle Schnittstelle (UART RS232, USB). Kommt dies Zeichen, wird die neue Firmware gebrannt. Andernfalls wird das eigentliche Programm des Controllers ausgeführt.&lt;br /&gt;
&lt;br /&gt;
Dem eigentlichen Anwendungsprogramm geht natürlich der Platz verloren, den der Bootloader benötigt. Da Peters Bootloader jedoch in ein 512Bytes (256 Worte!) großes Segment passt, stört das nicht weiter.&lt;br /&gt;
&lt;br /&gt;
Normalerweise wird der Programmcode des Mikrocontrollers mit einem ISP-Dongle in den Flash gebrannt. Aus verschiedenen Gründen kann dies jedoch nicht möglich/ gewünscht sein:&lt;br /&gt;
* Geschwindigkeit: Der ISP-Dongle kann langsam sein (z.&amp;amp;nbsp;B. myAVR mit aktuellem AVRDude)&lt;br /&gt;
* PINs: Man braucht die PINs und will ISP abschalten (Fuses, aber Vorsicht!, danach kann man nur mit dem Bootloader oder einem [[AVR HV-Programmer]] noch an den Flash-Speicher)&lt;br /&gt;
* Komfort: Man möchte dem Kunden/Nutzer die Möglichkeit geben, eine neue Firmware selbst einzuspielen. In der Regel hat dieser jedoch keinen ISP-Dongle zur Hand. Eine RS232- oder USB-Schnittstelle ist aber oftmals vorhanden.&lt;br /&gt;
* Sicherheit: Man möchte dem Kunden nicht die Firmware in deassemblierbarer Form geben (über geänderten Bootloader kann die Datei verschlüsselt sein).&lt;br /&gt;
&lt;br /&gt;
== Features ==&lt;br /&gt;
* Automatische Erkennung der vom PC verwendeten Baudrate&lt;br /&gt;
* Ein oder zwei Wire Betrieb&lt;br /&gt;
* Support für viele verschiedene AVRs wie: tiny13, tiny2313, tiny25, tiny261, tiny44, tiny45, tiny461, tiny84, tiny85, tiny861, mega48, mega8, mega8515, mega8525, mega88, mega16, mega162, mega168, mega32, mega64, mega644, mega128, mega1281, mega2561.&lt;br /&gt;
* Passwortschutz gegen unberechtigtes Umprogrammieren (aber keine Verschlüsselung des Programms).&lt;br /&gt;
* Freie Software - unter GPL lizenziert ([http://www.mikrocontroller.net/topic/73196#848377 Link]). Das eigentliche Anwendungsprogramm, das über den Bootloader geladen wird muß deswegen *nicht* unter der GPL stehen und dessen Quelltext auch *nicht* veröffentlicht werden ([http://www.mikrocontroller.net/topic/73196#950943 Link]).&lt;br /&gt;
&lt;br /&gt;
== Anforderungen an das zu ladende Programm ==&lt;br /&gt;
Bei AVRs ohne &amp;quot;boot reset vector fuse&amp;quot; (BOOTRST) wie beispielsweise ATtinys und kleinen ATmegas (ATmega48) muß der erste Befehl ein RJMP sein. Für C-Programme ist das automatisch sichergestellt (und für Assembler-Programme leicht selbst sicherzustellen).&lt;br /&gt;
&lt;br /&gt;
== Downloads ==&lt;br /&gt;
&lt;br /&gt;
* Thread zum Bootloader: [http://www.mikrocontroller.net/topic/73196 http://www.mikrocontroller.net/topic/73196]&lt;br /&gt;
&lt;br /&gt;
* Version 2.1 des Bootloaders incl. DOS Host-Software (Forumsbeitrag): [http://www.mikrocontroller.net/topic/73196?goto=850650#850843]&lt;br /&gt;
* Version 2.1 des Bootloaders für AVR-GCC-Toolchain (Forumsbeitrag): [http://www.mikrocontroller.net/topic/146638#1824790]&lt;br /&gt;
* Protokollbeschreibung Host&amp;lt;-&amp;gt;Target (Forumsbeitrag): [http://www.mikrocontroller.net/topic/73196?goto=685654#685654]&lt;br /&gt;
* Schaltbild für One-Wire-Betrieb (Forumsbeitrag): [http://www.mikrocontroller.net/topic/73196?goto=610574#610574]&lt;br /&gt;
&lt;br /&gt;
* Linux Host-SW für Version 2.1 mit One-Wire (Forumsbeitrag): [http://www.mikrocontroller.net/topic/73196?goto=1067153#1067153]&lt;br /&gt;
* Linux und MAC-OSX Host-SW für V2.1 ohne One-Wire (nur mit Anmeldung zu erreichen): [http://www.avrfreaks.net/index.php?module=Freaks%20Academy&amp;amp;func=viewItem&amp;amp;item_type=project&amp;amp;item_id=1927 http://www.avrfreaks.net/index.php?module=Freaks%20Academy&amp;amp;func=viewItem&amp;amp;item_type=project&amp;amp;item_id=1927]&lt;br /&gt;
* Host-SW in Python für Version 1.7: [http://www.kreatives-chaos.com/artikel/fastboot17-frontend-python http://www.kreatives-chaos.com/artikel/fastboot17-frontend-python]&lt;br /&gt;
* Host-SW Win32 für Version 1.7: [http://www.mikrocontroller.net/topic/73196?goto=698193#698193]&lt;br /&gt;
&lt;br /&gt;
* Atmel AVR-Studio (um Bootloader zu assemblieren): [http://www.atmel.com/dyn/products/tools_card.asp?tool_id=2725 http://www.atmel.com/dyn/products/tools_card.asp?tool_id=2725]&lt;br /&gt;
* ATMega IDE 2007: [http://www.KarstenDonat.de/AVR http://www.KarstenDonat.de/AVR]&lt;br /&gt;
&lt;br /&gt;
* Ältere Version dieser Anleitung als PDF: [http://www.KarstenDonat.de/AVR/Bootloader.pdf http://www.KarstenDonat.de/AVR/Bootloader.pdf]&lt;br /&gt;
&lt;br /&gt;
== Bootloader anpassen ==&lt;br /&gt;
&lt;br /&gt;
=== CPU auswählen – BOOTLOAD.ASM ===&lt;br /&gt;
&lt;br /&gt;
Die CPU (der Atmel auf dem der Bootloader laufen soll) wird durch Einkommentieren der zugehörigen Include-Files ausgewählt. Im Beispiel für einen ATtiny45.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;avrasm&amp;gt;&lt;br /&gt;
;           select the appropriate include file:&lt;br /&gt;
;.include &amp;quot;tn13def.inc&amp;quot;&lt;br /&gt;
;.include &amp;quot;tn2313def.inc&amp;quot;&lt;br /&gt;
;.include &amp;quot;tn25def.inc&amp;quot;&lt;br /&gt;
;.include &amp;quot;tn261def.inc&amp;quot;&lt;br /&gt;
;.include &amp;quot;tn44def.inc&amp;quot;&lt;br /&gt;
.include &amp;quot;tn45def.inc&amp;quot;&lt;br /&gt;
;.include &amp;quot;tn461def.inc&amp;quot;&lt;br /&gt;
;.include &amp;quot;m48def.inc&amp;quot;&lt;br /&gt;
;.include &amp;quot;tn84def.inc&amp;quot;&lt;br /&gt;
;.include &amp;quot;tn85def.inc&amp;quot;&lt;br /&gt;
;.include &amp;quot;tn861def.inc&amp;quot;&lt;br /&gt;
&amp;lt;/avrasm&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei nicht vergessen, die bisher (per Default) ausgewählte CPU ATmega168 auszukommentieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;avrasm&amp;gt;&lt;br /&gt;
;.include &amp;quot;m168def.inc&amp;quot;&lt;br /&gt;
&amp;lt;/avrasm&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== UART Port und Pins festlegen – BOOTLOAD.ASM ===&lt;br /&gt;
&lt;br /&gt;
Da die verwendeten Pins für die Schnittstelle frei wählbar sind, müssen diese noch eingestellt werden.&lt;br /&gt;
&lt;br /&gt;
STX_PORT: Hier den Sendeport angeben. Für die Pins des Hardware-UARTs des M8 wäre das Port D. Es müssen zwar nicht dieselben Pins sein, wenn man sie aber ohnehin als Schnittstelle nutzt, ist es sinnvoll, sie auszuwählen.  Verwendet wird immer ein im Bootloader integrierter Software-UART, der auf beliebigen I/O-Pins lauschen kann.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;avrasm&amp;gt;&lt;br /&gt;
.equ    STX_PORT        = PORTD&lt;br /&gt;
.equ    STX             = PD1&lt;br /&gt;
&lt;br /&gt;
.equ    SRX_PORT        = PORTD&lt;br /&gt;
.equ    SRX             = PD0&lt;br /&gt;
&amp;lt;/avrasm&amp;gt;&lt;br /&gt;
&#039;&#039;Beispiel für gleiche Bepinnung wie Hardware-UART im ATMega 8, 48, 168&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Für One-Wire-Betrieb muß für TX und RX zweimal der gleiche Pin angeben werden. Beim Assemblieren wird das erkannt und One-Wire aktiviert - es ist keine weitere Änderung nötig.&lt;br /&gt;
&lt;br /&gt;
=== CPU-Frequenz und Wartezeit festlegen - FASTLOAD.H ===&lt;br /&gt;
&lt;br /&gt;
Bei XTAL die benutzte Frequenz des Controllers einstellen (jungfräuliche AVRs haben oft intern 1MHz aktiviert!).&lt;br /&gt;
Im Standard Makefile von WinAVR steht die Frequenz unter F_CPU&lt;br /&gt;
&lt;br /&gt;
&amp;lt;avrasm&amp;gt;&lt;br /&gt;
.equ	XTAL		= 8000000   ; 8MHz, not critical&lt;br /&gt;
&amp;lt;/avrasm&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Um die Wartezeit auf das Firmware-Update beim Booten anzupassen:&lt;br /&gt;
&amp;lt;avrasm&amp;gt;&lt;br /&gt;
.equ	BootDelay	= XTAL / 3  ; 0.33s&lt;br /&gt;
&amp;lt;/avrasm&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Assemblieren des Bootloaders ==&lt;br /&gt;
&lt;br /&gt;
Da der Bootloader in Assembler geschrieben ist, kann WinAVR nicht so ohne weiteres damit umgehen.&lt;br /&gt;
Das einfachste ist, sich das AVRStudio von Atmel herunterzuladen [http://www.atmel.com/dyn/products/tools_card.asp?tool_id=2725 http://www.atmel.com/dyn/products/tools_card.asp?tool_id=2725]&lt;br /&gt;
&lt;br /&gt;
Im Unterverzeichnis AvrAssembler2 befindet sich der benötigte Assembler. Das Einfachste ist, sich die unter &amp;quot;Appnotes&amp;quot; benötigte Include Datei des jeweiligen Controllers (oder das komplette Verzeichnis) und die avrasm2.exe ins Verzeichnis des Bootloaders zu kopieren.&lt;br /&gt;
&lt;br /&gt;
Danach wird der Assembler aufgerufen (m8.asm für ATMega 8) und der Bootloader kompiliert:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
avrasm2 -fI BOOTLOAD.ASM&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es ist wichtig, dass die Includes des avrasm2 und nicht die der alten Version verwendet werden, da es sonst beim Assemblieren zu dem Fehler &lt;br /&gt;
&amp;quot;&#039;&#039;fastload.h(112): error: Use of undefined or forward referenced symbol &#039;SRAM_START&#039; in .org&#039;&#039;&amp;quot;&lt;br /&gt;
kommt.&lt;br /&gt;
&lt;br /&gt;
Das AVRStudio lässt sich unter Linux auch mit WINE installieren (die IDE des AVR Studio 4 geht allerdings nur mit ein paar Tricks aus der AppDB - ist für das Assemblieren des Bootloaders aber nicht nötig). Wenn &amp;quot;avrasm2.exe&amp;quot; und die zum AVR passende Include-Datei (beispielsweise &amp;quot;tn45def.inc&amp;quot; für ATtiny45) im gleichen Verzeichnis wie die restlichen Dateien des Bootloaders liegen, kann der Bootloader mit folgendem Befehl assembliert werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
wine avrasm2.exe -fI BOOTLOAD.ASM&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Brennen des Bootloaders ==&lt;br /&gt;
&lt;br /&gt;
Der nun erzeugte Bootloader wird mit dem vorhanden ISP Dongle in den AVR gebrannt (Intel Hex Format):&lt;br /&gt;
&lt;br /&gt;
 &amp;quot;avrdude&amp;quot; -p m8 -c avr910 -P com1 -U flash:w:&amp;quot;C:\Test\m8 3686400.hex&amp;quot;:i -U flash:v:&amp;quot;C:\Test\m8 3686400.hex&amp;quot;:i -y&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Brennen mit AVRDude auf COM 1 und einem AVR910 kompatiblen Dongle (z.&amp;amp;nbsp;B. myAVR USB)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Einstellen der Fuses ==&lt;br /&gt;
&lt;br /&gt;
Damit der Bootloader zu Beginn gestartet wird, müssen die entsprechenden Fuses gesetzt werden. Möglich ist dies u.a. mit der AVRDude GUI.&lt;br /&gt;
* BOOTRST muss auf 0 gestellt werden (aktiviert den Bootloader)&lt;br /&gt;
* BOOTSZ muss auf 256 Worte (= 512 Byte) (oder dem minimal möglichen Wert, wenn AVR nur größere Bootloader Regionen unterstützt) gestellt werden. Beispielsweise ist für den ATMega8 der Wert 10.&lt;br /&gt;
&lt;br /&gt;
Bei einigen Controllern wie z.&amp;amp;nbsp;B. dem ATMega 48 wird das Flag&lt;br /&gt;
* Selfprogramming enabled gesetzt.&lt;br /&gt;
&lt;br /&gt;
Auf dieser [http://www.engbedded.com/fusecalc/ Website (Fusecalc)] kann man sich die Fuses elegant zusammenstellen und erhält gleich die Parameter für avrdude. Eine schnelle und *sichere* Alternative zum fehlerträchtigen &amp;quot;Kaputtflashen&amp;quot; von Atmels.&lt;br /&gt;
&lt;br /&gt;
=== Fuses mit myAVR ändern ===&lt;br /&gt;
&lt;br /&gt;
Der myAVR Dongle unterstützt mit AVRDude leider keine Fuses. Abhilfe liefert hier jedoch das myAVR Workpad Plus. Die Demo-Version (reicht hierfür) kann unter&lt;br /&gt;
&lt;br /&gt;
[http://www.myavr.info/download/myAVR_WorkpadPLUS_Demo.exe http://www.myavr.info/download/myAVR_WorkpadPLUS_Demo.exe]&lt;br /&gt;
&lt;br /&gt;
heruntergeladen werden. Nach dem Installieren und Starten im Menü Extras – Fuse- und Lock-Bits wählen. Das Programm ermittelt automatisch den aktuellen Status. Je nach Controller steht der Bootloader Support unter High oder Extended Fuses.&lt;br /&gt;
&lt;br /&gt;
== Brennen des eigentlichen Programmes ==&lt;br /&gt;
&lt;br /&gt;
Damit das Programm mit Peters Tool in den Controller geladen werden kann, muss es im Intel HEX Format vorliegen. Im makefile Template von WinAVR (und auch der ATMegaIDE) ist dies standardmäßig eingestellt.&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
# Output format. (can be srec, ihex, binary)&lt;br /&gt;
FORMAT = ihex&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Danach wird Peters Firmware-Update Tool aufgerufen (hier COM2)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
fboot /C2 /Pmain.hex&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&#039;&#039;hier wird die main.hex als Hauptprogramm gebrannt&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Wichtig hierbei ist, dass der Dateiname der alten DOS Konvention entspricht. Also keine langen Dateinamen.&lt;br /&gt;
&lt;br /&gt;
Peters Firmware-Update Tool lässt sich unter Linux leider nicht mit WINE starten, dafür aber mit DOSBOX. Der Aufruf ist dann der gleiche wie unter Windows.&lt;br /&gt;
&lt;br /&gt;
Wenn noch keine Firmware im Controller ist (direkt nach dem Installieren des Bootloaders), startet der Brennvorgang automatisch. Andernfalls wartet das Programm auf den Reset des Controllers. Peters Tool arbeitet nur mit COM1 bis COM4 zusammen. Also ggf. den USB Adapter im Gerätemanager umstellen.&lt;br /&gt;
&lt;br /&gt;
Die Ausgabe sieht dann wie folgt aus:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
C:\DOCUME~1\zzzzzz\Desktop\avr\_soft\fboot18&amp;gt;fboot18 /Ptest.hex /b9600 /c1&lt;br /&gt;
COM 1 at 9600 Baud: Connected (One wire)&lt;br /&gt;
Bootloader V1.8&lt;br /&gt;
Target: 1E9108&lt;br /&gt;
Buffer: 32 Byte&lt;br /&gt;
Size available: 1534 Byte&lt;br /&gt;
Program test.hex: 00000 - 00073 successful&lt;br /&gt;
CRC: o.k.&lt;br /&gt;
Elapsed time: 1.43 seconds&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für Linux steht ebenfalls ein [http://www.mikrocontroller.net/attachment/43211/lboot.tgz Programmiertool] (aus diesem [http://www.mikrocontroller.net/topic/73196#1067153 Beitrag]) für die aktuelle Version 2.1 des Bootloaders für die Kommandozeile zur Verfügung, das auch den One-Wire-Betrieb unterstützt.&lt;br /&gt;
&lt;br /&gt;
Es lässt sich nach dem Entpacken durch ein simples &amp;quot;make&amp;quot; übersetzen. Die Verwendung ist analog zum DOS-Tool:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./bootloader -d /dev/ttyS0 -b 115200 -p tiny45test.hex&lt;br /&gt;
&lt;br /&gt;
=================================================&lt;br /&gt;
|           BOOTLOADER, Target: V2.1            |&lt;br /&gt;
=================================================&lt;br /&gt;
Port    : /dev/ttyS0&lt;br /&gt;
Baudrate: 115200&lt;br /&gt;
File    : tiny45test.hex&lt;br /&gt;
Reading : tiny45test.hex... File read.&lt;br /&gt;
Size    : 2717 Bytes&lt;br /&gt;
Program device.&lt;br /&gt;
-------------------------------------------------&lt;br /&gt;
Waiting for device... connected (one wire)!&lt;br /&gt;
Bootloader    : V2.1&lt;br /&gt;
Target        : 1E9206 ATtiny45&lt;br /&gt;
Buffer        : 64 Byte&lt;br /&gt;
Size available: 3582 Byte&lt;br /&gt;
CRC enabled and OK.&lt;br /&gt;
Programming   : 00000 - 00A9D&lt;br /&gt;
Writing | ##################################### | 100%&lt;br /&gt;
Elapsed time: 0.79 seconds, 3439 Bytes/sec.&lt;br /&gt;
&lt;br /&gt;
 ++++++++++ Device successfully programmed! ++++++++++&lt;br /&gt;
&lt;br /&gt;
...starting application&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bootloader-Support in ATMegaIDE 2007 ==&lt;br /&gt;
&lt;br /&gt;
Die IDE kann wahlweise mit AVRDude und einem entsprechenden ISP-Dongle oder mit dem Bootloader das Programm in den Flash brennen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Anpassen des Programms ===&lt;br /&gt;
Um das Firmware Update komfortabler zu gestalten, kann ein Software-Reset eingebaut werden, der per RS232- bzw. USB-Schnittstelle oder Tastendruck ausgelöst wird.&lt;br /&gt;
&lt;br /&gt;
==== Tastendruck ====&lt;br /&gt;
In der mitgelieferten Standard.h gibt es den Befehl void Reset();. Er löst mit Hilfe des Watchdog-Timers einen Hardwarereset aus. Man kann jetzt z.&amp;amp;nbsp;B. auf einen bestimmten Tastendruck (-kombination) hin diesen Reset ausführen.&lt;br /&gt;
&lt;br /&gt;
==== RS232/USB ====&lt;br /&gt;
Alternativ kann ein entsprechender Befehl über die RS232 gesendet werden. Standardmäßig ist dies 0xFF ‚R‘.&lt;br /&gt;
&lt;br /&gt;
=== Einstellungen in der IDE ===&lt;br /&gt;
&lt;br /&gt;
Der Bootloader Support kann bei den Projekt-Eigenschaften eingestellt werden. Beim Brennen wird er dann automatisch benutzt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
== ToDo ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Komfortables Stand-Alone Firmware-Update ===&lt;br /&gt;
&lt;br /&gt;
Basierend auf dem Code der IDE wird es im September noch ein Standalone-Programm für das Firmware-Update geben. Es wird auch ein entsprechendes Protokoll zur Versionskontrolle haben (die bisherige Soft- und viel wichtiger Hardwareversion wird überprüft). Eine Verschlüsselung der Firmware-Datei ist in Planung.&lt;br /&gt;
&lt;br /&gt;
=== Automatisches Erzeugen des Bootloaders ===&lt;br /&gt;
Sobald ich Zeit habe kommt in die IDE auch die Möglichkeit, die Anpassungen des Bootloaders von der IDE durchführen zu lassen.&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:AVR-Programmer und -Bootloader]]&lt;/div&gt;</summary>
		<author><name>Frankalicious</name></author>
	</entry>
</feed>