<?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=93.184.187.21</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=93.184.187.21"/>
	<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/articles/Spezial:Beitr%C3%A4ge/93.184.187.21"/>
	<updated>2026-04-11T01:27:58Z</updated>
	<subtitle>Benutzerbeiträge</subtitle>
	<generator>MediaWiki 1.39.7</generator>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Mini-Jakobsleiter&amp;diff=67719</id>
		<title>Mini-Jakobsleiter</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Mini-Jakobsleiter&amp;diff=67719"/>
		<updated>2012-08-03T17:00:45Z</updated>

		<summary type="html">&lt;p&gt;93.184.187.21: /* Hochspannung erzeugen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;----&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|[[Bild:High voltage warning.svg|100px]]&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;big&amp;gt;&#039;&#039;&#039;Achtung, hier wird mit lebensgefährlicher Netzspannung gearbeitet. Dieses Projekt ist nur für Personen geeignet, die mit den notwendigen Sicherheitsvorkehrungen vertraut sind.&#039;&#039;&#039;&lt;br /&gt;
|[[Bild:High voltage warning.svg|100px]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/big&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
[[Bild:Jakobsleiter in Aktion.jpg|thumb|Jakobsleiter in Aktion (Aufbau entspricht nicht exakt den Angaben)]]&lt;br /&gt;
&lt;br /&gt;
Schlagen Funken über hat man die Aufmerksamkeit aller Anwesenden und jeder versteht: hier fließt Strom. Besonders faszinierend sind die kletternden Lichtbögen der Jakobsleiter. Doch Hochspannung erzeugen, das trauen sich die wenigsten zu. Dabei macht es gar nicht so viel Aufwand, sobald der richtige Weg bekannt ist. Grundstein dieses Projekts bildete das Datenblatt für den Zündtrafo ZS&amp;amp;nbsp;1052 auf Conrad.de. Das Ergebnis ist ein Mini-Jakobsleiter im Lochrasteraufbau.&lt;br /&gt;
&lt;br /&gt;
== Funktionsprinzip ==&lt;br /&gt;
&lt;br /&gt;
=== Hochspannung erzeugen ===&lt;br /&gt;
&lt;br /&gt;
Der Brückengleichrichter mit dem Elko erzeugt eine Gleichspannung in Höhe von 315 Volt. Der Widerstand (≈560&amp;amp;nbsp;k&amp;amp;Omega;) parallel zum Elko entlädt diesen nach dem Ausschalten des Hochspannungsgenerators zügig. Bei offenem Schalter lädt sich der Schwingkreiskondensator über den Widerstand auf und bei geschlossenem Schalter bildet der Kondensator mit der Induktivität des Trafos einen Parallelschwingkreis und transformiert die Netzspannung zu etwa 11&amp;amp;nbsp;kV Hochspannung. Der Ladewiderstand hängt an 315&amp;amp;nbsp;Volt und hat keinen Einfluss auf den Schwingkreis.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Hochspannungsschwingkreis.svg]]&lt;br /&gt;
&lt;br /&gt;
Dass der Ladewiderstand mit dem Kondensator direkt gegen Masse geschaltet wird, vereinfacht den Aufbau erheblich, so ist kein Wechselschalter von Nöten. Dafür darf der Schalter nur kurz geschlossen werden. Da Elektronik zum Einsatz kommt, ist das aber kein nennenswertes Problem. &lt;br /&gt;
&lt;br /&gt;
Die Resonanz spielt für die Funktion keine Rolle und stellt nur einen Nebeneffekt dar. Der Kondensator bietet zwei wesentliche Vorteile: er wird mit einer definierten Energiemenge aufgeladen und liefert eine definierte Spannung. Dadurch haben Kurzschlüsse, dazu zählen auch Lichtbögen, keine gravierenden Auswirkungen auf den Trafo. Der Trafo übersetzt die Kondensatorspannung gemäß seines Übersetzungsverhältnisses auf die Sekundärseite.&lt;br /&gt;
&lt;br /&gt;
Eine genauen Berechnung der Bauteile im voraus ist nicht möglich, denn für Jakobsleitern gibt es keine spezielle Theorie. Die Ausgangsbasis bildet der Zündtrafo, dessen Datenblatt legt einen Kondensator mit Kapazität 47 nF fest. Ein Oszillogramm zeigt, dass bis zum Abklingen der Resonanz etwa 100 µs vergehen. Solange sollte also der Schalter mindestens geschlossen bleiben, aber auch nicht länger um den Ladewiderstand zu schonen. Die Ladespannung für den Kondensator wird dort mit 300 Volt angegeben, also im Bereich des Gleichrichtwerts der Netzspannung. Somit war klar, woraus die Spannungsversorgung erzeugt wird.&lt;br /&gt;
&lt;br /&gt;
Nun kommt der wesentliche Praxiswert: eine Kondensatorladung enthält eine definierte Energiemenge. Daher kommt es bei der Leistungsbemessung nur noch auf die Schaltfrequenz an. Die minimale Ladezeit, Schalter offen, für den Kondensator beträgt 3*&amp;amp;nbsp;&amp;amp;tau;, sprich 3 *Ladewiderstand*Schwingkreiskondensator. Anfangs war dies ein 22&amp;amp;nbsp;k&amp;amp;Omega;/1&amp;amp;nbsp;W Widerstand. Ein kleiner Funke sprang über, es reichte aber nicht für eine Jakobsleiter und so kamen 22&amp;amp;nbsp;k&amp;amp;Omega; Parallel dazu, womit die Ladezeit sank. Jetzt zeigte der Aufbau seine volle Pracht.&lt;br /&gt;
&lt;br /&gt;
Der Geruch verriet allerdings, die Widerstände wurden zu heiß, denn beim Materialeinkauf wurde großzügig mit einem Tastverhältnis von 1:100 gerechnet und erst bei der Praxiserprobung auf 1:10 reduziert, wodurch wesentlich mehr Ladezyklen pro Zeit erfolgten mit wesentlich höhere Verlusten am Widerstand. Daher sei hier das Parallelschalten von drei bis vier 33&amp;amp;nbsp;k&amp;amp;Omega;/1&amp;amp;nbsp;W Widerständen  empfohlen (genaue Berechnungen stehen noch aus). Insgesamt ergibt sich damit eine Ladezeit von 1&amp;amp;nbsp;ms und eine Schwingzeit von 100&amp;amp;nbsp;µs.&lt;br /&gt;
&lt;br /&gt;
Statt eines richtigen Schalters befindet sich in der Schaltung ein MOSFET (z.&amp;amp;nbsp;B. BUZ91A) der für 300 Volt ausgelegt ist. Eine Zeitgeberelektronik steuert die Gatespannung, siehe nächster Abschnitt.&lt;br /&gt;
&lt;br /&gt;
Die Experimentierfreude soll jedem selbst überlassen bleiben in Form weiterer Tuningmaßnahmen durch mehr Widerstände und in Folge geringer Ladezeit nach dem Prinzip mehr Leistung = mehr Spaß. Eine Halbierung sollte noch drin sein, die Verlustleistung steigt aber mit der Schaltfrequenz weiter und der Wert der einzelnen Widerstände sollte auf 39&amp;amp;nbsp;k&amp;amp;Omega; oder 39&amp;amp;nbsp;k&amp;amp;Omega; erhöht werden.&lt;br /&gt;
&lt;br /&gt;
Statt eines Trafos können sekundärseitig auch zwei in Serie geschaltet werden und die Spannung verdoppelt sich. Mehrere geht nicht, da ansonsten die Potentialdifferenz zur Primärseite zu hoch wird und der Trafo durchschlägt.&lt;br /&gt;
&lt;br /&gt;
=== Zeitgeber NE555 ===&lt;br /&gt;
&lt;br /&gt;
Als Zeitgeber kommt der allseits-bekannte NE555 als astabiler Multivibrator zum Einsatz. Der obere Teil bildet die Spannungsversorgung mit 78xx in Standardschaltung.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Hochspannung ne555.svg]]&lt;br /&gt;
&lt;br /&gt;
Zur Spannungsversorgung muss nichts weiter erklärt werden.&lt;br /&gt;
&lt;br /&gt;
Die Schaltung an Output dient als Inverter da die Multivibratorschaltung lange Pulse mit kurzen Pausen erzeugt, der MOSFET genau umgekehrt lange aus und kurz ein sein soll. Der Arbeitswiderstand beträgt 470&amp;amp;nbsp;&amp;amp;Omega; der Basisvorwiderstand 10&amp;amp;nbsp;k&amp;amp;Omega;. Der Kondensator parallel beträgt 500 pF und soll die Basis-Emitter-Kapazität füllen, damit der Transistor schneller durchschaltet. Keine Ahnung, ob das überhaupt notwendig ist, aber wer will schon sein Oszi mit Hochspannungsmessungen zerstören? Der Bipolar-Transistor ist ein BC557B also pnp. Signal-Masse ist mit der Source vom MOSFET verbunden der Inverter-Ausgang mit Gate.&lt;br /&gt;
&lt;br /&gt;
Der Kern des Multivibrators besteht aus zwei Widerständen und einem Kondensator. Die Puls und Pausenzeit ergibt sich grob nach folgender Formel:&lt;br /&gt;
:&amp;lt;math&amp;gt;t = 0{,}7 \cdot R \cdot C&amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt;R = \frac {t}{0{,}7 \cdot C} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Kapazität beträgt 100 nF. Bei 1 ms Pausenzeit beträgt der Widerstand an Versorgungsspannung 14 k&amp;amp;Omega; und der zum Disch-Eingang 1,4 k&amp;amp;Omega;. Letztenlich zum Einsatz kam die Paarung 10 k&amp;amp;Omega;/1 k&amp;amp;Omega;.&lt;br /&gt;
&lt;br /&gt;
=== Jakobsleiter ===&lt;br /&gt;
&lt;br /&gt;
Aufgrund der geringen Leistung wird die Jakobsleiter nicht überdimensional groß. Als Leiter genügt der für den Lochrasteraufbau übliche Silberdraht. Das untere Ende muss einen sanften Übergang zu den Versorgungsleitungen bilden, ein scharfer Knick führt zu Verzerrungen im elektrischen Feld und der Lichtbogen kommt nicht vom Fleck. Damit der Lichtbogen genug beschleunigt, das er auch am oberen Ende abreißt muss er genug Anlauf bekommen. Die Jakobsleiter darf dabei nicht zuweit auseinander gehen, da sonst kein Speed zustande kommt. Ein leichtes öffnen ist trotzdem wichtig, denn es hat sich gezeigt, dass ansonsten der Lichtbogen gerne zu weit oben zündet. Die Abriss sollte nicht zu lange sein, sonst tritt wieder der Effekt des einschlafenden Lichtbogens auf, aber auch nicht zu schroff, denn ein Knick bewirkt Zündungen an der falschen Stelle. Nicht nur aus ästetischen Gründen ist daher das obere Ende bei manchen Aufbauten gekringelt. Einfacher gebogene Konstruktionen funktionieren auch.&lt;br /&gt;
&lt;br /&gt;
Insgesamt ist die Konstruktion der Jakobsleiter der fieseligste Teil des Aufbau. Bevor die Funken dauerhaft steigen und nicht ständig einschlafen braucht es eine gewisse Probier- und Lernphase.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Jakobsleiter.svg]]&lt;br /&gt;
&lt;br /&gt;
=== Inbetriebnahme ===&lt;br /&gt;
&lt;br /&gt;
Für das Lochraster-Layout sei hier kein Plan vorgegeben und kann sich jeder selbst zusammenreimen. &lt;br /&gt;
&lt;br /&gt;
Hochspannungsteil aufbauen und Gate, Drain und Source mit Lötbrücke kurzschließen. Wenn alles in Ordnung ist leuchtet die LED permanent. Lötbrücke zwischen Drain und Gate auftrennen dann darf die LED nicht mehr leuchten. Ansonsten ist der MOSFET defekt.&lt;br /&gt;
&lt;br /&gt;
Nun den Schaltungsteil für den Zeitgeber aufbauen, aber noch nicht mit dem MOSFET verbinden. Leuchtet die LED der Versorgungsspannung ist alles in Ordnung. Jetzt Zeitgeber und MOSFET verbinden und Lötbrücke auftrennen. Der Luftspalt zwischen der Jakobsleiter sollte anfangs eher klein sein. Nach dem einstecken leuchten beide LEDs und Funken schlagen über, die Schaltung ist Einsatzbereit.&lt;br /&gt;
&lt;br /&gt;
Bei der Fehlersuche helfen zusätzliche LEDs etwa mit Vorwiderstand Parallel zum Arbeitswiderstand des Inverters oder am Output vom NE555.&lt;br /&gt;
&lt;br /&gt;
Die gesamte Schaltung ist mit der Netzspannung verbunden vor dem Berühren der Schaltung immer Netzstecker ziehen, da Kabelschalter meist nur ein-polig Trennen.&lt;br /&gt;
&lt;br /&gt;
==Material==&lt;br /&gt;
* Schraubklemme RM 5,0 zum Netzkabel anschließen&lt;br /&gt;
* Sicherung&lt;br /&gt;
* Lochrasterplatine ca. 10cm x 10cm&lt;br /&gt;
* Netzkabel (Vorsicht: Kabelschalter trennen meist nur einpolig)&lt;br /&gt;
* 4x M3 Schraube 25mm und Mutter als Füßchen&lt;br /&gt;
&lt;br /&gt;
=== Hochspannungsteil ===&lt;br /&gt;
&lt;br /&gt;
* 5x 33 kOhm 1W Metallschichtwiderstände zum Kondensatoraufladen&lt;br /&gt;
* LED mit 10mA Nennstrom in Reihe zu einem der Ladewiderstände als Funktionsanzeige&lt;br /&gt;
* [[FET]] (BUZ90, BUZ91, IRF730 o.ä)&lt;br /&gt;
* Zündspule (ZS 1052, Conrad/Voelkner) und passenden Kondensator mit 47 nF/X2 für Schwingkreis&lt;br /&gt;
* Brückengleichrichter (B250C800 o.ä.)&lt;br /&gt;
* Siebkondensator ≈ 4,7µF/350V&lt;br /&gt;
* Entladewiderstand mit ≈ 560 k&amp;amp;Omega; für den Siebkondensator &lt;br /&gt;
&lt;br /&gt;
=== Taktgenerator ===&lt;br /&gt;
* NE555&lt;br /&gt;
* Brückengleichrichter (B250C800 o.ä.)&lt;br /&gt;
* Siebkondensator ≈ 100 µF&lt;br /&gt;
* LED mit passendem Vorwiderstand als Betriebsanzeige&lt;br /&gt;
* Stabi LM7812&lt;br /&gt;
* Kondensator 0.1µF für Stabi-Ausgang&lt;br /&gt;
* Trafo 12V/30 mA o.ä.&lt;br /&gt;
* Zeitgeber-Kondensator 0.1 µF &lt;br /&gt;
* Zeitgeber-Widerstände 1k&amp;amp;Omega; + 10k&amp;amp;Omega;&lt;br /&gt;
* BC557B als Inverter für NE555 Ausgang&lt;br /&gt;
* Boostkondensator für BC557B 500 pF&lt;br /&gt;
* 10 k&amp;amp;Omega; Basisvorwiderstand für BC557B&lt;br /&gt;
* 560 &amp;amp;Omega; Arbeitswiderstand  für BC557B&lt;br /&gt;
&lt;br /&gt;
== Sicherheitshinweise ==&lt;br /&gt;
&lt;br /&gt;
* Trotz Trafo hängt die gesamte Schaltung an Netzpotential.&lt;br /&gt;
* Nach dem Ausstecken noch 10 Sekunden warten bis die Kondensatoren sicher entladen sind.&lt;br /&gt;
* Kabelschalter trennen nicht immer allpolig, also lieber den Stecker ziehen.&lt;br /&gt;
* Um den Hochspannungsanschluss herum die überflüssigen Lötaugen entfernen, sonst verkürzt sich die Funkenstrecke zur Primärseite.&lt;br /&gt;
* Vor der Erstinbetriebnahme den Hochspannungsbereich mit Spiritus gründlich von Lötfett befreien&lt;br /&gt;
* Beim Lochrasteraufbau ist darauf zu achten, das genügen Abstand zwischen Primär und Hochspannungsseite eingehalten wird.&lt;br /&gt;
* Für Schäden durch Hochspannung ist jeder selbst verantwortlich&lt;br /&gt;
&lt;br /&gt;
== Alternativen ==&lt;br /&gt;
* Zeilentrafo aus dem Fernseher&lt;br /&gt;
* Kfz-Zündspule vom Schrottplatz&lt;br /&gt;
* Hochspannungskaskade&lt;br /&gt;
* Zwei Mikrowellentrafos (MOT) für ca. 4 kV, vom Schrott&lt;br /&gt;
* Neon Sign Transformer (NST), bei Ebay&lt;br /&gt;
* Messwandler für Hochspannungsmessung (Potential-Transformer), wenn man sowas hat&lt;br /&gt;
* Elektor-Projekt Jakobsleiter (03/2006), für Leute mit Geld&lt;br /&gt;
* (Netzteil einer Kaltkathodenröhre (CCFL), meist aber zu schwach)&lt;br /&gt;
* Labornetzgerät für Hochspannung, für Leute mit ganz viel Geld&lt;br /&gt;
&lt;br /&gt;
Zündkabel, Anodenkabel, und Laborleitungen haben eine hohe Isolationsspannung, so kann Spannung sicher transportiert werden.&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
* [http://www.hcrs.at/TVLINE.HTM Hochspannung erzeugen mit Zeilentrafo]&lt;br /&gt;
* [http://geocities.com/CapeCanaveral/Lab/5322/hv2.html Snock&#039;s High Voltage Page]&lt;br /&gt;
;Videos&lt;br /&gt;
* &#039;&#039;&#039;[http://de.youtube.com/watch?v=DhWgCMReGKk&amp;amp;feature=channel_page Dieses Projekt in Aktion]&#039;&#039;&#039;&lt;br /&gt;
* [http://de.youtube.com/watch?v=GNbvg9jfDr8&amp;amp;feature=related Jakobsleiter mit NST]&lt;br /&gt;
* [http://de.youtube.com/watch?v=CUxbIuxqQl8&amp;amp;feature=related CD mit Hochspannungsbehandlung]&lt;br /&gt;
* [http://de.youtube.com/watch?v=CRLCW6alEwc&amp;amp;feature=related Hochspannungslabor]&lt;br /&gt;
* [http://de.youtube.com/watch?v=aAYGNcA34UI&amp;amp;feature=related Zeilentrafo im Einsatz]&lt;br /&gt;
* [http://www.andreas-kilchenmann.ag.vu/jakobsleiter.html Mikrowellentrafo]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Projekte]]&lt;br /&gt;
[[Kategorie:Spannungsversorgung und Energiequellen]]&lt;/div&gt;</summary>
		<author><name>93.184.187.21</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Belichter&amp;diff=59432</id>
		<title>Belichter</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Belichter&amp;diff=59432"/>
		<updated>2011-08-11T10:12:30Z</updated>

		<summary type="html">&lt;p&gt;93.184.187.21: /* UV-LEDs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Einleitung==&lt;br /&gt;
Ein Belichter ist nötig, wenn man reproduzierbare Ergebnisse bei der Platinenherstellung nach der Photo-Methode erzielen möchte.&lt;br /&gt;
Es gibt mehrere Quellen von UV-Licht, von denen hier erstmal zwei angesprochen werden, weil sie sich in einem Belichter verbauen lassen.&lt;br /&gt;
&lt;br /&gt;
Ein guter Belichter muss mehrere Aufgaben erfüllen, damit mann auch kleinere Strukturen zuverlässig übertragen kann.&lt;br /&gt;
&lt;br /&gt;
Die Helligkeitsverteilung muss über die gesamte Belichtungsfläche so gleichmässig wie möglich sein. Das verhindert, dass z.b. bei einem Teil des Photolacks schon die abgedeckten Stellen anfangen zu reagieren, während andere, nicht abgedeckte Flächen noch nicht fertig belichtet sind. ( Extrembeispiel )&lt;br /&gt;
&lt;br /&gt;
Das Licht muss möglichst paralell sein und sollte möglichst senkrecht auf die Layoutvorlage treffen, um Unterstrahlungen zu verhindern. Es ist Empfehlenswert, die Vorlage Spiegelverkehrt auszudrucken, sodass die bedruckte Seite direkt am Photolack anliegt. Dadurch wird Unschärfe vermieden.&lt;br /&gt;
&lt;br /&gt;
===UV-Röhren===&lt;br /&gt;
&lt;br /&gt;
Diese stammen meist aus alten Gesichtsbräunern, weil diese im Internet relativ günstig zu ersteigern sind und ausserdem alle anderen Bauteile zum Betrieb wie Vorschaltgerät, Drossel und Starter mitbringen.&lt;br /&gt;
Sie können aber z.b. auch bei Reichelt gekauft werden, sind dort aber meist deutlich teurer als ein kompletter gebrauchter Gesichtsbräuner.&lt;br /&gt;
&lt;br /&gt;
Beliebt ist es auch, das innenleben eines Gesichtsbräuners in ein gehäuse eines ausgeschlachteten Scanners zu bauen. Ältere Paralellport-Scanner sind meist ausreichend dick, um alles unterbringen zu können. So hat mann auch gleich eine Glasscheibe und eine Vorrichtung zum andrücken.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===UV-LEDs===&lt;br /&gt;
&lt;br /&gt;
[[LED-Belichter]]&lt;br /&gt;
&lt;br /&gt;
Man kann sie Tütenweise im Internet ersteigern, und so einen relativ guten Preis erzielen.&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Platinen]]&lt;/div&gt;</summary>
		<author><name>93.184.187.21</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=AVR-Tutorial:_Schieberegister&amp;diff=57310</id>
		<title>AVR-Tutorial: Schieberegister</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=AVR-Tutorial:_Schieberegister&amp;diff=57310"/>
		<updated>2011-05-21T15:01:33Z</updated>

		<summary type="html">&lt;p&gt;93.184.187.21: /* Schaltung */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ab und an stellt sich folgendes Problem: Man würde wesentlich mehr Ausgangspins oder Eingangspins benötigen als der [[Mikrocontroller]] zur Verfügung stellt. Ein möglicher Ausweg ist eine Porterweiterung mit einem Schieberegister. Zwei beliebte Schieberegister sind beispielsweise der 74xx595 bzw. der 74xx165.&lt;br /&gt;
&lt;br /&gt;
== Porterweiterung für Ausgänge ==&lt;br /&gt;
&lt;br /&gt;
Um neue Ausgangspins zu gewinnen kann der [[74xx | 74xx595]] verwendet werden. Dabei handelt es sich um ein &#039;&#039;8-Bit 3-state Serial-in/Serial-out or Parallel-Out Schieberegister mit einem Ausgangsregister und einem asynchronen Reset&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Hinter dieser kompliziert anmutenden Beschreibung verbirgt sich eine einfache Funktionalität: Das Schieberegister besteht aus zwei Funktionseinheiten: Dem eigentlichen Schieberegister und dem Ausgangsregister. In das Schieberegister können die Daten seriell hineingetaktet werden und durch ein bestimmtes Signal werden die Daten des Schieberegisters in das Ausgangsregister übernommen und können von dort auf die Ausgangspins geschaltet werden.&lt;br /&gt;
&lt;br /&gt;
Im Einzelnen bedeuten die Begriffe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Tabelle}}&lt;br /&gt;
|-  style=&amp;quot;background-color:#ffddcc&amp;quot;&lt;br /&gt;
! Begriff || Erklärung&lt;br /&gt;
|-&lt;br /&gt;
||8-Bit&lt;br /&gt;
|align=&amp;quot;left&amp;quot;| Acht Ausgangs[[Bit|bit]]s&lt;br /&gt;
|-&lt;br /&gt;
||3-state&lt;br /&gt;
|align=&amp;quot;left&amp;quot;| Die acht Registerausgänge können drei Zustände, Low, High und High-Impedanz annehmen.&amp;lt;BR&amp;gt;Siehe [[Ausgangsstufen Logik-ICs]]&lt;br /&gt;
|-&lt;br /&gt;
||Serial-in&lt;br /&gt;
|align=&amp;quot;left&amp;quot;| Serieller Eingang des Schieberegisters&lt;br /&gt;
|-&lt;br /&gt;
||Serial-out&lt;br /&gt;
|align=&amp;quot;left&amp;quot;| Serieller Ausgang des Schieberegisters&lt;br /&gt;
|-&lt;br /&gt;
||Parallel-Out&lt;br /&gt;
|align=&amp;quot;left&amp;quot;| Parallele Ausgänge des Ausgangsregisters&lt;br /&gt;
|-&lt;br /&gt;
||Schieberegister&lt;br /&gt;
|align=&amp;quot;left&amp;quot;| Serielle Daten werden durch den Baustein durchgeschoben&lt;br /&gt;
|-&lt;br /&gt;
|Ausgangsregister&lt;br /&gt;
|align=&amp;quot;left&amp;quot;| Ein Speicher, welcher die Daten des Schieberegisters zwischenspeichern kann.&amp;lt;BR&amp;gt;Dieses besteht aus acht [[FlipFlop]]s.&lt;br /&gt;
|-&lt;br /&gt;
|Asynchroner Reset&lt;br /&gt;
|align=&amp;quot;left&amp;quot;| Die Daten im Schieberegister können asynchron zurückgesetzt werden.&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Aufbau ===&lt;br /&gt;
&lt;br /&gt;
[[Bild:74xx595-1.png|framed|center|Pinbelegung eines 595]]&lt;br /&gt;
&lt;br /&gt;
Hinweis: Die Benennung der Pins in den Datenblättern verschiedener Hersteller unterscheidet sich zum Teil. Die Funktionen der Pins sind jedoch gleich.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Tabelle}}&lt;br /&gt;
|-  style=&amp;quot;background-color:#ffddcc&amp;quot;&lt;br /&gt;
! DIL Pin-Nummer || Funktion || Dieses Tutorial || Motorola / ON Semi || Philips / NXP         || Fairchild     || SGS|| Texas Instruments&lt;br /&gt;
|-&lt;br /&gt;
|  1 || Ausgang B           || QB || Q&amp;lt;sub&amp;gt;B&amp;lt;/sub&amp;gt;  || Q&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;   || Q&amp;lt;sub&amp;gt;B&amp;lt;/sub&amp;gt;  || QB|| Q&amp;lt;sub&amp;gt;B&amp;lt;/sub&amp;gt;  &lt;br /&gt;
|-&lt;br /&gt;
|  2 || Ausgang C           || QC || Q&amp;lt;sub&amp;gt;C&amp;lt;/sub&amp;gt;  || Q&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;   || Q&amp;lt;sub&amp;gt;C&amp;lt;/sub&amp;gt;  || QC|| Q&amp;lt;sub&amp;gt;C&amp;lt;/sub&amp;gt;  &lt;br /&gt;
|-&lt;br /&gt;
|  3 || Ausgang D           || QD || Q&amp;lt;sub&amp;gt;D&amp;lt;/sub&amp;gt;  || Q&amp;lt;sub&amp;gt;3&amp;lt;/sub&amp;gt;   || Q&amp;lt;sub&amp;gt;D&amp;lt;/sub&amp;gt;  || QD|| Q&amp;lt;sub&amp;gt;D&amp;lt;/sub&amp;gt;  &lt;br /&gt;
|-&lt;br /&gt;
|  4 || Ausgang E           || QE || Q&amp;lt;sub&amp;gt;E&amp;lt;/sub&amp;gt;  || Q&amp;lt;sub&amp;gt;4&amp;lt;/sub&amp;gt;   || Q&amp;lt;sub&amp;gt;E&amp;lt;/sub&amp;gt;  || QE|| Q&amp;lt;sub&amp;gt;E&amp;lt;/sub&amp;gt;  &lt;br /&gt;
|-&lt;br /&gt;
|  5 || Ausgang F           || QF || Q&amp;lt;sub&amp;gt;F&amp;lt;/sub&amp;gt;  || Q&amp;lt;sub&amp;gt;5&amp;lt;/sub&amp;gt;   || Q&amp;lt;sub&amp;gt;F&amp;lt;/sub&amp;gt;  || QF|| Q&amp;lt;sub&amp;gt;F&amp;lt;/sub&amp;gt;  &lt;br /&gt;
|-&lt;br /&gt;
|  6 || Ausgang G           || QG || Q&amp;lt;sub&amp;gt;G&amp;lt;/sub&amp;gt;  || Q&amp;lt;sub&amp;gt;6&amp;lt;/sub&amp;gt;   || Q&amp;lt;sub&amp;gt;G&amp;lt;/sub&amp;gt;  || QG|| Q&amp;lt;sub&amp;gt;G&amp;lt;/sub&amp;gt;  &lt;br /&gt;
|-&lt;br /&gt;
|  7 || Ausgang H           || QH || Q&amp;lt;sub&amp;gt;H&amp;lt;/sub&amp;gt;  || Q&amp;lt;sub&amp;gt;7&amp;lt;/sub&amp;gt;   || Q&amp;lt;sub&amp;gt;H&amp;lt;/sub&amp;gt;  || QH|| Q&amp;lt;sub&amp;gt;H&amp;lt;/sub&amp;gt;  &lt;br /&gt;
|-&lt;br /&gt;
|  8 || Masse, 0 V || [nicht dargestellt] || GND            || GND             || GND             || GND|| GND&lt;br /&gt;
|-&lt;br /&gt;
|  9 || Serieller Ausgang || QH* || SQ&amp;lt;sub&amp;gt;H&amp;lt;/sub&amp;gt; || Q&amp;lt;sub&amp;gt;7&amp;lt;/sub&amp;gt;´  ||Q&#039;&amp;lt;sub&amp;gt;H&amp;lt;/sub&amp;gt;  ||  QH´||Q&amp;lt;sub&amp;gt;H&#039;&amp;lt;/sub&amp;gt;  &lt;br /&gt;
|-&lt;br /&gt;
| 10 || Reset für Schieberegister             || SCL || RESET          || /MR             || /SCLR        || /SCLR || /SRCLR&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Schiebetakt        || SCK || SHIFT CLOCK    || SH&amp;lt;sub&amp;gt;CP&amp;lt;/sub&amp;gt; || SCK          || SCK || SRCLK&lt;br /&gt;
|-&lt;br /&gt;
| 12 || Speichertakt        || RCK || LATCH CLOCK    || ST&amp;lt;sub&amp;gt;CP&amp;lt;/sub&amp;gt; || RCK          || RCK || RCLK&lt;br /&gt;
|-&lt;br /&gt;
| 13 || Ausgangssteuerung      || G || OUTPUT ENABLE  || /OE             || /G           || /G || /OE&lt;br /&gt;
|-&lt;br /&gt;
| 14 || Serieller Dateneingang  || SER || A              || D&amp;lt;sub&amp;gt;S&amp;lt;/sub&amp;gt;   || SER          || SI || SER&lt;br /&gt;
|-&lt;br /&gt;
| 15 || Ausgang A           || QA || Q&amp;lt;sub&amp;gt;A&amp;lt;/sub&amp;gt;  || Q&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt;   || Q&amp;lt;sub&amp;gt;A&amp;lt;/sub&amp;gt;  || QA|| Q&amp;lt;sub&amp;gt;A&amp;lt;/sub&amp;gt;  &lt;br /&gt;
|-&lt;br /&gt;
| 16 || Betriebsspannung || [nicht dargestellt] || V&amp;lt;sub&amp;gt;CC&amp;lt;/sub&amp;gt; || V&amp;lt;sub&amp;gt;CC&amp;lt;/sub&amp;gt;  || V&amp;lt;sub&amp;gt;CC&amp;lt;/sub&amp;gt;  || V&amp;lt;sub&amp;gt;CC&amp;lt;/sub&amp;gt;|| V&amp;lt;sub&amp;gt;CC&amp;lt;/sub&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Baustein besteht aus zwei Einheiten:&lt;br /&gt;
* dem Schieberegister&lt;br /&gt;
* dem Ausgangsregister&lt;br /&gt;
&lt;br /&gt;
Im Schieberegister werden die einzelnen Bits durchgeschoben. Mit jeder positiven Taktflanke(LOW -&amp;gt; HIGH) an &#039;&#039;&#039;SCK&#039;&#039;&#039; wird eine Schiebeoperation durchgeführt.&lt;br /&gt;
&lt;br /&gt;
Das Ausgangsregister hat die Aufgabe die Ausgangspins des Bausteins anzusteuern. Durch dieses Ausgangsregister ist es möglich, die Schiebeoperationen im Hintergrund durchzuführen, ohne dass IC Pins ihren Wert ändern. Erst wenn die Schiebeoperation abgeschlossen ist, wird der aktuelle Zustand der Schieberegisterkette durch einen Puls an &#039;&#039;&#039;RCK&#039;&#039;&#039; in das Ausgangsregister übernommen.&lt;br /&gt;
&lt;br /&gt;
===Funktionsweise===&lt;br /&gt;
&lt;br /&gt;
Am Eingang &#039;&#039;&#039;SER&#039;&#039;&#039; (Pin 14) wird das gewünschte nächste Datum (0 oder 1) angelegt. Durch einen positiven Puls an &#039;&#039;&#039;SCK&#039;&#039;&#039; (Pin 11) wird der momentan an &#039;&#039;&#039;SER&#039;&#039;&#039; anliegende Wert als neuer Wert für Bit 0, das unterste Bit des Schieberegisters, übernommen. Gleichzeitig werden alle anderen Bits im Schieberegister um eine Stelle verschoben: Das Bit 6 wird ins Bit 7 übernommen, Bit 5 ins Bit 6, Bit 4 ins Bit 5, etc. sodass das Bit 0 zur Aufnahme des &#039;&#039;&#039;SER&#039;&#039;&#039; Bits frei wird.&lt;br /&gt;
&lt;br /&gt;
[[Bild:74xx595-2.png|center]]&lt;br /&gt;
&lt;br /&gt;
Eine Sonderstellung nimmt das ursprüngliche Bit 7 ein. Dieses Bit steht direkt auch am Ausgang &#039;&#039;&#039;QH*&#039;&#039;&#039; (Pin 9) zur Verfügung. Dadurch ist es möglich an ein Schieberegister einen weiteren Baustein 74xxx595 anzuschliessen und so beliebig viele Schieberegister hintereinander zu schalten (kaskadieren). Auf diese Art lassen sich Schieberegister mit beliebig vielen Stufen aufbauen.&lt;br /&gt;
&lt;br /&gt;
Wurde das Schieberegister mit den Daten gefüllt, so wird mit einem LOW-HIGH Puls am Pin 12, &#039;&#039;&#039;RCK&#039;&#039;&#039; der Inhalt des Schieberegisters in das Ausgangsregister übernommen.&lt;br /&gt;
&lt;br /&gt;
[[Bild:74xx595-3.png|center]]&lt;br /&gt;
&lt;br /&gt;
Mit dem Eingang &#039;&#039;&#039;G&#039;&#039;&#039; (Pin 13) kann das Ausgangsregister freigegeben werden. Liegt &#039;&#039;&#039;G&#039;&#039;&#039; auf 0, so führen die Ausgänge &#039;&#039;&#039;QA&#039;&#039;&#039; bis &#039;&#039;&#039;QH&#039;&#039;&#039; entsprechende Pegel. Liegt &#039;&#039;&#039;G&#039;&#039;&#039; auf 1, so schalten die Ausgänge &#039;&#039;&#039;QA&#039;&#039;&#039; bis &#039;&#039;&#039;QH&#039;&#039;&#039; auf [[Ausgangsstufen Logik-ICs |Tristate]]. D.h. sie treiben aktiv weder LOW oder HIGH, sondern sind hochohmig wie ein Eingang und nehmen jeden Pegel an, der ihnen von aussen aufgezwungen wird.&lt;br /&gt;
&lt;br /&gt;
Bleibt nur noch der Eingang &#039;&#039;&#039;SCL&#039;&#039;&#039;(Pin 10). Mit ihm kann das Schieberegister im Baustein gelöscht, also auf eine definierte 0, gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Die Programmierung eines 74xxx595 Schieberegisters gestaltet sich sehr einfach. Im Grunde gibt es 2 Möglichkeiten:&lt;br /&gt;
* Mittels [[SPI]] kann der [[AVR]] das Schieberegister direkt und autark ansteuern. Das ist sehr schnell und verbraucht nur wenig CPU-Leistung&lt;br /&gt;
* Sind die entsprechenden SPI-Pins am AVR nicht frei, so ist auch eine softwaremässige Ansteuerung des Schieberegisters mit einfachen Mitteln durchführbar.&lt;br /&gt;
&lt;br /&gt;
=== Ansteuerung per Software===&lt;br /&gt;
&lt;br /&gt;
[[Bild:Mega8-595.gif|framed|right|Anschluss eines 595]]&lt;br /&gt;
Für eine komplette Softwarelösung kann das Schieberegister an jede beliebige Port-Pin Kombination angeschlossen werden. Wir wählen die Pins &#039;&#039;&#039;PB0&#039;&#039;&#039;, &#039;&#039;&#039;PB1&#039;&#039;&#039;, &#039;&#039;&#039;PB2&#039;&#039;&#039; und &#039;&#039;&#039;PB3&#039;&#039;&#039; um dort die Schieberegisteranschlüsse &#039;&#039;&#039;SER&#039;&#039;&#039;, &#039;&#039;&#039;SCK&#039;&#039;&#039;, &#039;&#039;&#039;SCL&#039;&#039;&#039; und &#039;&#039;&#039;RCK&#039;&#039;&#039; anzuschliessen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Die Programmierung gestaltet sich dann nach folgendem Schema: Die 8 Bits eines Bytes werden nacheinander an den Ausgang &#039;&#039;&#039;PB0&#039;&#039;&#039; (&#039;&#039;&#039;SER&#039;&#039;&#039;) ausgegeben. Durch Generierung eines Pulses 0-1-0 an Pin &#039;&#039;&#039;PB1&#039;&#039;&#039; (&#039;&#039;&#039;SCK&#039;&#039;&#039;) übernimmt das Schieberegister nacheinander die einzelnen Bits. Dabei ist zu beachten, dass die Ausgabe mit dem höherwertigen Bit beginnen muss, denn dieses Bit wandert ja am weitesten zur Stelle &#039;&#039;&#039;QH&#039;&#039;&#039;. Sind alle 8 Bits ausgegeben, so wird durch einen weiteren 0-1-0 Impuls am Pin &#039;&#039;&#039;PB3&#039;&#039;&#039; (&#039;&#039;&#039;RCK&#039;&#039;&#039;) der Inhalt der Schieberegisterbits 0 bis 7 in die Ausgaberegister &#039;&#039;&#039;QA&#039;&#039;&#039; bis &#039;&#039;&#039;QH&#039;&#039;&#039; übernommen. Dadurch, dass am Schieberegister der Eingang &#039;&#039;&#039;G&#039;&#039;&#039; konstant auf 0-Pegel gehalten wird, erscheint dann auch die Ausgabe sofort an den entsprechenden Pins und kann zb. mit LEDs (low-current LEDs + Vorwiderstand verwenden) sichtbar gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Der Schieberegistereingang &#039;&#039;&#039;SCL&#039;&#039;&#039; wird auf einer 1 gehalten. Würde er&lt;br /&gt;
auf 0 gehen, so würde die Schieberegisterkette gelöscht. Möchte man einen weiteren Prozessorpin einsparen, so kann man diesen Pin auch generell auf Vcc legen. Das Schieberegister könnte man in so einem Fall durch Einschreiben von 0x00 immer noch löschen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;avrasm&amp;gt;&lt;br /&gt;
.include &amp;quot;m8def.inc&amp;quot;&lt;br /&gt;
&lt;br /&gt;
.def temp1 = r16&lt;br /&gt;
.def temp2 = r17&lt;br /&gt;
&lt;br /&gt;
.equ SCHIEBE_DDR  = DDRB&lt;br /&gt;
.equ SCHIEBE_PORT = PORTB&lt;br /&gt;
.equ RCK          = 3&lt;br /&gt;
.equ SCK          = 1&lt;br /&gt;
.equ SCL          = 2&lt;br /&gt;
.equ SIN          = 0&lt;br /&gt;
&lt;br /&gt;
    ldi   temp1, LOW(RAMEND)     ; Stackpointer initialisieren&lt;br /&gt;
    out   SPL, temp1&lt;br /&gt;
    ldi   temp1, HIGH(RAMEND)&lt;br /&gt;
    out   SPH, temp1&lt;br /&gt;
&lt;br /&gt;
;&lt;br /&gt;
; Die Port Pins auf Ausgang konfigurieren&lt;br /&gt;
;&lt;br /&gt;
    ldi   temp1, (1&amp;lt;&amp;lt;RCK) | (1&amp;lt;&amp;lt;SCK) | (1&amp;lt;&amp;lt;SCL) | (1&amp;lt;&amp;lt;SIN) ; Anm.1&lt;br /&gt;
    out   SCHIEBE_DDR, temp1&lt;br /&gt;
&lt;br /&gt;
;&lt;br /&gt;
; die Clear Leitung am Schieberegister auf 1 stellen&lt;br /&gt;
;&lt;br /&gt;
    sbi   SCHIEBE_PORT, SCL&lt;br /&gt;
&lt;br /&gt;
;&lt;br /&gt;
; Ein Datenbyte ausgeben&lt;br /&gt;
;&lt;br /&gt;
    ldi   temp1, 0b10101010&lt;br /&gt;
    rcall Schiebe&lt;br /&gt;
    rcall SchiebeOut&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    rjmp  loop&lt;br /&gt;
&lt;br /&gt;
;-----------------------------------------------------------------------------&lt;br /&gt;
;&lt;br /&gt;
; Die Ausgabe im Schieberegister in das Ausgaberegister übernehmen&lt;br /&gt;
;&lt;br /&gt;
; Dazu am RCK Eingang am Schieberegister einen 0-1-0 Puls erzeugen&lt;br /&gt;
;&lt;br /&gt;
SchiebeOut:&lt;br /&gt;
    sbi   SCHIEBE_PORT, RCK&lt;br /&gt;
    cbi   SCHIEBE_PORT, RCK&lt;br /&gt;
    ret&lt;br /&gt;
&lt;br /&gt;
;-----------------------------------------------------------------------------&lt;br /&gt;
;&lt;br /&gt;
; 8 Bits aus temp1 an das Schieberegister ausgeben&lt;br /&gt;
Schiebe:&lt;br /&gt;
    push  temp2&lt;br /&gt;
    ldi   temp2, 8             ; 8 Bits müssen ausgegeben werden&lt;br /&gt;
&lt;br /&gt;
Schiebe_1:&lt;br /&gt;
     ;&lt;br /&gt;
     ; jeweils das höchstwertige Bit aus temp1 ins Carry-Flag schieben&lt;br /&gt;
     ; Je nach Zustand des Carry-Flags wird die Datenleitung entsprechend&lt;br /&gt;
     ; gesetzt oder gelöscht&lt;br /&gt;
     ;&lt;br /&gt;
    rol  temp1                 ; MSB -&amp;gt; Carry&lt;br /&gt;
    brcs Schiebe_One           ; Carry gesetzt? -&amp;gt; weiter bei Schiebe_One&lt;br /&gt;
    cbi  SCHIEBE_PORT, SIN     ; Eine 0 ausgeben&lt;br /&gt;
    rjmp Schiebe_Clock         ; und Sprung zur Clock Puls Generierung&lt;br /&gt;
Schiebe_One:&lt;br /&gt;
    sbi  SCHIEBE_PORT, SIN     ; Eine 1 ausgeben&lt;br /&gt;
&lt;br /&gt;
     ;&lt;br /&gt;
     ; einen Impuls an SCK zur Übernahme des Bits nachschieben&lt;br /&gt;
     ;&lt;br /&gt;
Schiebe_Clock:&lt;br /&gt;
    sbi   SCHIEBE_PORT, SCK    ; Clock-Ausgang auf 1 ...&lt;br /&gt;
    cbi   SCHIEBE_PORT, SCK    ; und wieder zurück auf 0&lt;br /&gt;
&lt;br /&gt;
    dec   temp2                ; Anzahl der ausgegebenen Bits runterzählen&lt;br /&gt;
    brne  Schiebe_1            ; Wenn noch keine 8 Bits ausgegeben -&amp;gt; Schleife bilden&lt;br /&gt;
&lt;br /&gt;
    pop   temp2&lt;br /&gt;
    ret&lt;br /&gt;
&amp;lt;/avrasm&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anm.1: Siehe [[Bitmanipulation]]&lt;br /&gt;
&lt;br /&gt;
=== Ansteuerung per SPI-Modul===&lt;br /&gt;
[[Bild:Mega8-595-SPI.png|framed|right|Anschluss eines 595 per SPI]]&lt;br /&gt;
Noch schneller geht die Ansteuerung des Schieberegisters mittels [[Serial_Peripheral_Interface | SPI]]-Modul, welches in fast allen AVRs vorhanden ist. Hier wird der Pin &#039;&#039;&#039;SCL&#039;&#039;&#039; nicht benutzt, da das praktisch keinen Sinn hat. Er muss also fest auf VCC gelegt werden. (Oder mit den Reset-Pin des AVRs, das mit einer RC Schaltung versehen ist, verbunden werden. Damit erreicht man einen definierten Anfangszustand des Schieberegisters) Die Pins für &#039;&#039;&#039;SCK&#039;&#039;&#039; und &#039;&#039;&#039;SIN&#039;&#039;&#039; sind duch den jeweiligen AVR fest vorgegeben. &#039;&#039;&#039;SCK&#039;&#039;&#039; vom 74xxx595 wird mit &#039;&#039;&#039;SCK&#039;&#039;&#039; vom AVR verbunden sowie &#039;&#039;&#039;SIN&#039;&#039;&#039; mit &#039;&#039;&#039;MOSI&#039;&#039;&#039; (&#039;&#039;&#039;M&#039;&#039;&#039;aster &#039;&#039;&#039;O&#039;&#039;&#039;ut, &#039;&#039;&#039;S&#039;&#039;&#039;lave &#039;&#039;&#039;I&#039;&#039;&#039;n). &#039;&#039;&#039;MISO&#039;&#039;&#039; (&#039;&#039;&#039;M&#039;&#039;&#039;aster &#039;&#039;&#039;I&#039;&#039;&#039;n, &#039;&#039;&#039;S&#039;&#039;&#039;lave &#039;&#039;&#039;O&#039;&#039;&#039;ut) ist hier ungenutzt. Es kann NICHT als &#039;&#039;&#039;RCK&#039;&#039;&#039; verwendet werden, da es im SPI-Master Modus immer ein Eingang ist! Es kann aber als allgemeiner Eingang verwendet werden. Der AVR-Pin &#039;&#039;&#039;SS&#039;&#039;&#039; wird sinnvollerweise als &#039;&#039;&#039;RCK&#039;&#039;&#039; benutzt, da er sowieso als Ausgang geschaltet werden &#039;&#039;&#039;muss&#039;&#039;&#039;, sonst gibt es böse Überaschungen (siehe Datenblatt &amp;quot;SS Pin Functionality&amp;quot;). Dieser sollte mit einem Widerstand von 10K  nach Masse, während der Start- und Initialisierungsphase, auf L-Potential  gehalten werden. `(&#039;&#039;&#039;SS&#039;&#039;&#039; ist während dieser Zeit noch im Tri-State und es könnte passieren, dass die zufälligen Daten des Schieberegisters in das Ausgangslatch übernommen werden) Je nach Bedarf kann man die Taktrate des SPI-Moduls zwischen 1/2 ... 1/128 des CPU-Taktes wählen. Es spricht kaum etwas dagegen mit maximaler Geschwindigkeit zu arbeiten. Die AVRs können zur Zeit mit maximal 20 MHz getaktet werden, d.h. es sind maximal 10 MHz SPI-Takt möglich. Das ist für ein 74xxx595 kein Problem. Die Übertragung von 8 Bit dauert dann gerade mal 800ns!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;avrasm&amp;gt;&lt;br /&gt;
.include &amp;quot;m8def.inc&amp;quot;&lt;br /&gt;
&lt;br /&gt;
.def temp1 = r16&lt;br /&gt;
&lt;br /&gt;
; Die Definitionen müssen an den jeweiligen AVR angepasst werden&lt;br /&gt;
&lt;br /&gt;
.equ SCHIEBE_DDR  = DDRB&lt;br /&gt;
.equ SCHIEBE_PORT = PORTB&lt;br /&gt;
.equ RCK          = PB2     ; SS&lt;br /&gt;
.equ SCK          = PB5     ; SCK&lt;br /&gt;
.equ SIN          = PB3     ; MOSI&lt;br /&gt;
&lt;br /&gt;
    ldi   temp1, LOW(RAMEND)     ; Stackpointer initialisieren&lt;br /&gt;
    out   SPL, temp1&lt;br /&gt;
    ldi   temp1, HIGH(RAMEND)&lt;br /&gt;
    out   SPH, temp1&lt;br /&gt;
;&lt;br /&gt;
; SCK, MOSI, SS als Ausgänge schalten&lt;br /&gt;
;&lt;br /&gt;
    in    temp1, SCHIEBE_DDR&lt;br /&gt;
    ori   temp1, (1&amp;lt;&amp;lt;SIN) | (1&amp;lt;&amp;lt;SCK) | (1&amp;lt;&amp;lt;RCK) &lt;br /&gt;
    out   SCHIEBE_DDR,temp1     &lt;br /&gt;
;&lt;br /&gt;
; SPI Modul konfigurieren&lt;br /&gt;
;&lt;br /&gt;
    ldi   temp1, (1&amp;lt;&amp;lt;SPE) | (1&amp;lt;&amp;lt;MSTR)&lt;br /&gt;
    out   SPCR, temp1           ; keine Interrupts, MSB first, Master&lt;br /&gt;
                                ; CPOL = 0, CPHA =0&lt;br /&gt;
                                ; SCK Takt = 1/2 XTAL&lt;br /&gt;
    ldi   temp1, (1&amp;lt;&amp;lt;SPI2X)&lt;br /&gt;
    out   SPSR, temp1           ; double speed aktivieren&lt;br /&gt;
    out   SPDR, temp1           ; Dummy Daten, um SPIF zu setzen&lt;br /&gt;
;&lt;br /&gt;
; Ein Datenbyte ausgeben&lt;br /&gt;
;&lt;br /&gt;
    ldi   temp1, 0b10101010&lt;br /&gt;
    rcall Schiebe               ; Daten schieben&lt;br /&gt;
    rcall SchiebeOut            ; Daten in Ausgangsregister übernehmen&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    rjmp  loop&lt;br /&gt;
&lt;br /&gt;
;-----------------------------------------------------------------------------&lt;br /&gt;
;&lt;br /&gt;
; Die Daten im Schieberegister in das Ausgaberegister übernehmen&lt;br /&gt;
;&lt;br /&gt;
; Dazu am RCK Eingang am Schieberegister einen 0-1-0 Puls erzeugen&lt;br /&gt;
;&lt;br /&gt;
SchiebeOut:&lt;br /&gt;
    sbis  SPSR, SPIF            ; prüfe ob eine alte Übertragung beendet ist&lt;br /&gt;
    rjmp  SchiebeOut&lt;br /&gt;
    sbi   SCHIEBE_PORT, RCK&lt;br /&gt;
    cbi   SCHIEBE_PORT, RCK&lt;br /&gt;
    ret&lt;br /&gt;
&lt;br /&gt;
;-----------------------------------------------------------------------------&lt;br /&gt;
;&lt;br /&gt;
; 8 Bits aus temp1 an das Schieberegister ausgeben&lt;br /&gt;
;&lt;br /&gt;
Schiebe:&lt;br /&gt;
    sbis    SPSR, SPIF      ; prüfe ob eine alte Übertragung beendet ist&lt;br /&gt;
    rjmp    Schiebe&lt;br /&gt;
    out     SPDR, temp1     ; Daten ins SPI Modul schreiben, Übertragung beginnt automatisch&lt;br /&gt;
    ret&lt;br /&gt;
&amp;lt;/avrasm&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Kaskadieren von Schieberegistern===&lt;br /&gt;
&lt;br /&gt;
[[Bild:Mega8-595-2.gif|framed|right|Kaskadieren mehrerer 595]]&lt;br /&gt;
Um ein Schieberegister anzuschließen genügen also im einfachsten Fall 4 freie Prozessorpins (3 wenn &#039;&#039;&#039;SCL&#039;&#039;&#039; nicht benutzt wird) um weitere 8 Ausgangsleitungen zu bekommen. Genügen diese 8 Leitungen nicht, so kann ohne Probleme ein weiteres Schieberegister an das bereits Vorhandene angeschlossen werden.&lt;br /&gt;
&lt;br /&gt;
Das nächste Schieberegister wird mit seinem Dateneingang &#039;&#039;&#039;SER&#039;&#039;&#039; einfach an den dafür vorgesehenen Ausgang &#039;&#039;&#039;QH*&#039;&#039;&#039; des vorhergehenden Schieberegisters angeschlossen. Die Steuerleitungen &#039;&#039;&#039;SCK&#039;&#039;&#039;, &#039;&#039;&#039;RCK&#039;&#039;&#039; und &#039;&#039;&#039;SCL&#039;&#039;&#039; werden parallel zu den bereits vorhandenen geschaltet. Konzeptionell erhält man dadurch ein Schieberegister mit einer Breite von 16 Bit. Werden weiter Bausteine in derselben Manier angeschlossen, so erhöht sich die Anzahl der zur Verfügung stehenden Ausgabeleitungen mit jedem Baustein um 8 ohne dass sich die Anzahl der am Prozessor notwendigen Ausgabepins erhöhen würde. Um diese weiteren Register zu nutzen, muss man in der reinen Softwarelösung nur mehrfach die Funktion &#039;&#039;&#039;Schiebe&#039;&#039;&#039; aufrufen, um alle Daten auszugeben. Am Ende werden dann mit &#039;&#039;&#039;SchiebeOut&#039;&#039;&#039; die Daten in die Ausgangsregister übernommen.&lt;br /&gt;
&lt;br /&gt;
Bei der SPI Lösung werden ebenfalls ganz einfach mehrere Bytes über SPI ausgegeben, ehe dann mittels &#039;&#039;&#039;RCK&#039;&#039;&#039; die in die Schieberegisterkette eingetakteten Bits in das Ausgangsregister übernommen werden.&lt;br /&gt;
Um das Ganze ein wenig zu vereinfachen, soll hier eine Funktion zur Ansteuerung mehrerer kaskadierter Schieberegister über das SPI-Modul gezeigt werden. Dabei wird die Ausgabe mehrerer Bytes über eine Schleife realisiert, mehrfache Aufrufe der Funktion sind damit nicht nötig. Statt dessen übergibt man einen Zeiger auf einen Datenblock im RAM sowie die Anzahl der zu übertragenden Bytes. Ausserdem wird die Datenübernahme durch &#039;&#039;&#039;RCK&#039;&#039;&#039; standardkonform integriert. Denn bei nahezu allen ICs mit SPI wird ein sog. CS-Pin verwendet (&#039;&#039;&#039;C&#039;&#039;&#039;hip &#039;&#039;&#039;S&#039;&#039;&#039;elect) Dieser Pin ist meist LOW aktiv, d.h. wenn er HIGH ist, ignoriert der IC alle Signale an &#039;&#039;&#039;SCK&#039;&#039;&#039; und &#039;&#039;&#039;MOSI&#039;&#039;&#039; und gibt keine Daten an MISO aus. Ist er LOW, dann ist der IC aktiv und funktioniert normal. Bei der steigenden Flanke an &#039;&#039;&#039;CS&#039;&#039;&#039; werden die Daten ins Ausgangsregister übernommen. Die Fuktion ist sehr schnell, da die Zeit während der die Übertragung eines Bytes läuft, dazu genutzt wird, den Schleifenzähler zu verringern und zu prüfen sowie neue Sendedaten zu laden. Zwischen den einzelnen Bytes gibt es somit nur eine Pause von max. 6 Systemtakten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;avrasm&amp;gt;&lt;br /&gt;
.include &amp;quot;m8def.inc&amp;quot;&lt;br /&gt;
.def temp1 = r16&lt;br /&gt;
&lt;br /&gt;
; Die Definitionen müssen an den jeweiligen AVR angepasst werden&lt;br /&gt;
&lt;br /&gt;
.equ SCHIEBE_DDR  = DDRB&lt;br /&gt;
.equ SCHIEBE_PORT = PORTB&lt;br /&gt;
.equ RCK          = PB2     ; SS&lt;br /&gt;
.equ SCK          = PB5     ; SCK&lt;br /&gt;
.equ SIN          = PB3     ; MOSI&lt;br /&gt;
&lt;br /&gt;
;-----------------------------------------------------------------------------&lt;br /&gt;
;&lt;br /&gt;
; Datensegment im RAM&lt;br /&gt;
;&lt;br /&gt;
;-----------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
.dseg&lt;br /&gt;
.org $60&lt;br /&gt;
Schiebedaten:       .byte 2&lt;br /&gt;
&lt;br /&gt;
;-----------------------------------------------------------------------------&lt;br /&gt;
;&lt;br /&gt;
; Programmsegment im FLASH&lt;br /&gt;
;&lt;br /&gt;
;-----------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
.cseg&lt;br /&gt;
    ldi     temp1, LOW(RAMEND)     ; Stackpointer initialisieren&lt;br /&gt;
    out     SPL, temp1&lt;br /&gt;
    ldi     temp1, HIGH(RAMEND)&lt;br /&gt;
    out     SPH, temp1&lt;br /&gt;
;&lt;br /&gt;
; SCK, MOSI, SS als Ausgänge schalten&lt;br /&gt;
;&lt;br /&gt;
    in      temp1,SCHIEBE_DDR&lt;br /&gt;
    ori     temp1,(1&amp;lt;&amp;lt;SIN) | (1&amp;lt;&amp;lt;SCK) | (1&amp;lt;&amp;lt;RCK) &lt;br /&gt;
    out     SCHIEBE_DDR,temp1&lt;br /&gt;
&lt;br /&gt;
    sbi     SCHIEBE_PORT, RCK   ; Slave select inaktiv&lt;br /&gt;
;&lt;br /&gt;
; SPI Modul konfigurieren&lt;br /&gt;
;&lt;br /&gt;
    ldi     temp1, 0b01010000&lt;br /&gt;
    out     SPCR, temp1         ; keine Interrupts, MSB first, Master&lt;br /&gt;
                                ; CPOL = 0, CPHA =0&lt;br /&gt;
                                ; SCK Takt = 1/2 XTAL&lt;br /&gt;
    ldi     r16,1&lt;br /&gt;
    out     SPSR,r16            ; Double Speed&lt;br /&gt;
    out     SPDR,temp1          ; Dummy Daten, um SPIF zu setzen&lt;br /&gt;
&lt;br /&gt;
; den Datenblock mit Daten füllen&lt;br /&gt;
&lt;br /&gt;
    ldi     temp1,$F0&lt;br /&gt;
    sts     Schiebedaten,temp1&lt;br /&gt;
    ldi     temp1,$55&lt;br /&gt;
    sts     Schiebedaten+1,temp1&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
; den Datenblock ausgeben&lt;br /&gt;
&lt;br /&gt;
    ldi     r16,2&lt;br /&gt;
    ldi     zl,low(Schiebedaten)&lt;br /&gt;
    ldi     zh, high(Schiebedaten)&lt;br /&gt;
    rcall   Schiebe_alle                    ; Daten ausgeben&lt;br /&gt;
&lt;br /&gt;
    rjmp  loop                              ; nur zur Simulation&lt;br /&gt;
&lt;br /&gt;
;-----------------------------------------------------------------------------&lt;br /&gt;
;&lt;br /&gt;
; N Bytes an das Schieberegister ausgeben und in das Ausgaberegister übernehmen&lt;br /&gt;
;&lt;br /&gt;
; r16: Anzahl der Datenbytes&lt;br /&gt;
; Z: Zeiger auf Datenblock im RAM&lt;br /&gt;
;&lt;br /&gt;
;-----------------------------------------------------------------------------&lt;br /&gt;
Schiebe_alle:&lt;br /&gt;
    cbi     SCHIEBE_PORT, RCK   ; RCK LOW, SPI Standardverfahren&lt;br /&gt;
    push    r17&lt;br /&gt;
&lt;br /&gt;
Schiebe_alle_2:&lt;br /&gt;
    ld      r17,Z+&lt;br /&gt;
Schiebe_alle_3:&lt;br /&gt;
    sbis    SPSR,SPIF           ; prüfe ob eine alte Übertragung beendet ist&lt;br /&gt;
    rjmp    Schiebe_alle_3&lt;br /&gt;
    out     SPDR,r17            ; Daten ins SPI Modul schreiben, Übertragung beginnt automatisch&lt;br /&gt;
    dec     r16&lt;br /&gt;
    brne    Schiebe_alle_2&lt;br /&gt;
&lt;br /&gt;
Schiebe_alle_4:&lt;br /&gt;
    sbis    SPSR,SPIF           ; prüfe ob die letzte Übertragung beendet ist&lt;br /&gt;
    rjmp    Schiebe_alle_4&lt;br /&gt;
&lt;br /&gt;
    pop     r17&lt;br /&gt;
    sbi     SCHIEBE_PORT, RCK   ; RCK inaktiv, Datenübernahme&lt;br /&gt;
    ret&lt;br /&gt;
&amp;lt;/avrasm&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der Nachteil von Schieberegistern ist allerdings, dass sich die Zeit zum Setzten aller Ausgabeleitungen mit jedem weiteren Baustein immer weiter erhöht. Dies deshalb, da ja die einzelnen Bits im Gänsemarsch durch alle Bausteine geschleust werden müssen und für jeden einzelnen Schiebevorgang etwas Zeit notwendig ist. Ein Ausweg ist die Verwendung des SPI-Moduls, welches schneller arbeitet als die reine Softwarelösung. Ist noch mehr Geschwindigkeit gefragt, so sind mehr Port-Pins nötig. Kann ein kompletter Port mit 8 Pins für die Daten genutzt werden, sowie ein paar weitere Steuerleitungen, so können ein oder mehrere 74xxx573 eine Alternative sein, um jeweils ein vollständiges Byte auszugeben. Natürlich kann der 74xxx573 (oder ein ähnliches Schieberegister) auch mit dem 74xxx595 zusammen eingesetzt werden, beispielsweise in dem über das Schieberegister verschiedene 74xxx595 nacheinander aktiviert werden. Weitere Tips und Tricks dazu gibt es vielleicht in einem weiteren Tutorial...&lt;br /&gt;
&lt;br /&gt;
=== Acht LEDs mit je 20mA pro Schieberegister ===&lt;br /&gt;
&lt;br /&gt;
Will man nun acht [[LED]]s mit dem Schieberegister ansteuern, kann man diese direkt über Vorwiderstände anschliessen. Doch ein genauer Blick ins Datenblatt verrät, dass der 74xx595 nur maximal 70mA über VCC bzw. GND ableiten kann. Und wenn man den IC nicht gnadenlos quälen, und damit die Lebensdauer und Zuverlässigkeit drastisch reduzieren will, gibt es nur zwei Auswege.&lt;br /&gt;
&lt;br /&gt;
* Den Strom pro LED auf 70/8 = 8,75mA begrenzen; Das reicht meistens aus um die LEDs schön leuchten zu lassen, vor allem bei low-current und ultrahellen LEDs&lt;br /&gt;
* Wenn doch 20 mA pro LED gebraucht werden, kann man die folgende Trickschaltung anwenden.&lt;br /&gt;
&lt;br /&gt;
[[bild:8x20mA_LED_mit_74xx595.png|framed|center|Mehrere LED anschließen]]&lt;br /&gt;
&lt;br /&gt;
Der Trick besteht darin, dass 4 LEDs ihren Strom über das Schieberegister von VCC beziehen (HIGH aktiv) während die anderen vier ihren Strom über GND leiten (LOW aktiv). Damit bleiben ganz offiziell für jede LED 70/4 = 17,5mA. Um die Handhabung in der Software zu vereinfachen muss nur vor der Ausgabe der Daten das jeweilige Byte mit 0x0F XOR verknüpft werden, bevor es in das Schieberegister getaktet wird. Dadurch werden die LOW-aktiven LEDs richtig angesteuert und die Datenhandhabung in der Software muss nur mit HIGH-aktiven rechnen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;B&amp;gt;Achtung!&amp;lt;/B&amp;gt; Die Widerstände sind auf blaue LEDs mit 3,3V Flusspannung ausgelegt. Bei roten, gelben und grünen [[LED]]s ist die Flusspannung geringer und dementsprechend muss der Vorwiderstand grösser sein.&lt;br /&gt;
&lt;br /&gt;
Ausserdem wird der G Eingang verwendet, um die Helligkeit aller LEDs per [[PWM]] zu steuern. Beachtet werden muss, dass die PWM im invertierten Modus generiert werden muss, da der Eingang G LOW aktiv ist.&lt;br /&gt;
&lt;br /&gt;
== Porterweiterung für Eingänge ==&lt;br /&gt;
&lt;br /&gt;
Ein naher Verwandter des 74xx595 ist der [[74xx | 74xx165]], er ist quasi das Gegenstück. Hierbei handet es sich um ein &#039;&#039;8-bit parallel-in/serial-out shift register&#039;&#039;. Auf Deutsch: Ein 8 Bit Schieberegister mit parallelem Eingang und seriellem Ausgang. Damit kann man eine grosse Anzahl Eingänge sehr einfach und preiswert zu seinem Mikrocontroller hinzufügen.&lt;br /&gt;
&lt;br /&gt;
=== Aufbau ===&lt;br /&gt;
&lt;br /&gt;
[[bild:74xx165-1.png|framed|center|Pinbelegung eines 165]]&lt;br /&gt;
&lt;br /&gt;
Der Aufbau ist sehr ähnlich zum 74xx595. Allerdings gibt es kein Register zum Zwischenspeichern. Das ist auch gar nicht nötig, da der IC ja einen parallelen Eingang hat. Der muss nicht zwischengespeichert werden. Es gibt hier also wirklich nur das Schieberegister. Dieses wird über den Eingang PL mit den parallelen Daten geladen. Dann können die Daten seriell mit Takten an CLK aus dem Ausgang Q7 geschoben werden.&lt;br /&gt;
&lt;br /&gt;
=== Funktionsweise ===&lt;br /&gt;
&lt;br /&gt;
DS ist der serielle Dateneingang, welcher im Falle von kaskadierten Schieberegistern mit dem Ausgang des vorhergehenden ICs verbunden wird.&lt;br /&gt;
&lt;br /&gt;
D0..D7 sind die parallelen Dateneingänge.&lt;br /&gt;
&lt;br /&gt;
Mittels des Eingangs PL (&#039;&#039;&#039;P&#039;&#039;&#039;arallel &#039;&#039;&#039;L&#039;&#039;&#039;oad) werden die Daten vom parallelen Eingang in das Schieberegister übernommen, wenn dieses Signal LOW ist. Hier muss man aber ein klein wenig aufpassen. Auf grund der Schaltungsstruktur ist der Eingang PL mit dem Takt CLK verknüpft (obwohl es dafür keinen logischen Grund gibt :-0). Damit es nicht zu unerwünschten Fehlschaltungen kommt, muss der Takt CLK während des Ladens auf HIGH liegen. Wird PL wieder auf HIGH gesetzt, sind die Daten geladen. Das erste Bit liegt direkt am Ausgang Q7 and. Die restlichen Bits können nach und nach durch das Register geschoben werden.&lt;br /&gt;
&lt;br /&gt;
Der Eingang CE (&#039;&#039;&#039;C&#039;&#039;&#039;lock &#039;&#039;&#039;E&#039;&#039;&#039;nable) steuert, ob das Schieberegister auf den Takt CLK reagieren soll oder nicht. Ist CE gleich HIGH werden alle Takte an CLK ignoriert. Bei LOW werden mit jeder positiven Flanke die Daten um eine Stufe weiter geschoben.&lt;br /&gt;
&lt;br /&gt;
Wird am Eingang CLK eine LOW-HIGH Flanke angelegt und ist dabei CE auf LOW, dann werden die Daten im Schieberegister um eine Position weiter geschoben: DS-&amp;gt;Q0, Q0-&amp;gt;Q1, Q1-&amp;gt;Q2, Q2-&amp;gt;Q3, Q3-&amp;gt;Q4, Q4-&amp;gt;Q5, Q5-&amp;gt;Q6, Q6-&amp;gt;Q7. Q0..Q6 sind interne Signale, siehe [http://www.nxp.com/acrobat/datasheets/74HC_HCT165_CNV_2.pdf Datenblatt].&lt;br /&gt;
&lt;br /&gt;
Q7 ist der serielle Ausgang des Schieberegisters. Dort Werden Takt für Takt die Daten ausgegeben. Hier wird normalerweise der Eingang des Mikrocontrollers oder der Eingang des nächsten Schieberegisters angeschlossen.&lt;br /&gt;
&lt;br /&gt;
Q7\ ist der invertierte Ausgang des Schieberegisters. Er wird meist nicht verwendet.&lt;br /&gt;
&lt;br /&gt;
=== Schaltung ===&lt;br /&gt;
&lt;br /&gt;
Um nun beispielsweise zwei Schieberegister zu kaskadieren um 16 Eingangspins zu erhalten sollte man folgende Verschaltung vornehmen. Beachten sollte man dabei, dass&lt;br /&gt;
&lt;br /&gt;
* der serielle Eingang DS des ersten Schieberegisters (hier IC1) auf einen festen Pegel gelegt wird (LOW oder HIGH).&lt;br /&gt;
* der serielle Datenausgang bei der Benutzung des SPI-Moduls an MISO und nicht an MOSI angeschlossen wird.&lt;br /&gt;
&lt;br /&gt;
[[bild:74xx165-2.png|framed|center|Anschluss eines 165]]&lt;br /&gt;
&lt;br /&gt;
Nachfolgend werden zwei Beispiele gezeigt, welche die Ansteuerung nach bekanntem Muster übernehmen. Nur dass hier eben Daten gelesen anstatt geschrieben werden. Zu beachten ist, dass hier ein anderer Modus der SPI-Ansteuerung verwendet werden muss, weil der Baustein das nötig macht. Das muss beachtet werden, wenn auch Schieberegister für Ausgänge verwendet werden. Dabei muss jeweils vor dem Zugriff auf die Ein- oder Ausgangsregister der Modus des Taktes (CPOL) umgeschaltet werden.&lt;br /&gt;
&lt;br /&gt;
=== Ansteuerung per Software ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;avrasm&amp;gt;&lt;br /&gt;
; Porterweiterung für Eingänge mit Schieberegister 74xx165&lt;br /&gt;
; Ansteuerung per Software&lt;br /&gt;
&lt;br /&gt;
.include &amp;quot;m8def.inc&amp;quot;&lt;br /&gt;
&lt;br /&gt;
.def temp1 = r16&lt;br /&gt;
.def temp2 = r17&lt;br /&gt;
.def temp3 = r18&lt;br /&gt;
&lt;br /&gt;
; Pins anpassen, frei wählbar&lt;br /&gt;
&lt;br /&gt;
.equ SCHIEBE_DDR  = DDRB&lt;br /&gt;
.equ SCHIEBE_PORT = PORTB&lt;br /&gt;
.equ SCHIEBE_PIN  = PINB&lt;br /&gt;
.equ CLK          = PB3&lt;br /&gt;
.equ PL           = PB1&lt;br /&gt;
.equ DIN          = PB2&lt;br /&gt;
&lt;br /&gt;
;-----------------------------------------------------------------------------&lt;br /&gt;
;&lt;br /&gt;
; Datensegment im RAM&lt;br /&gt;
;&lt;br /&gt;
;-----------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
.dseg&lt;br /&gt;
.org 0x60&lt;br /&gt;
Daten:      .byte 2             ; Speicherplatz für Eingangsdaten&lt;br /&gt;
&lt;br /&gt;
;-----------------------------------------------------------------------------&lt;br /&gt;
;&lt;br /&gt;
; Programmsegment im FLASH&lt;br /&gt;
;&lt;br /&gt;
;-----------------------------------------------------------------------------&lt;br /&gt;
.cseg&lt;br /&gt;
    ldi     temp1, LOW(RAMEND)  ; Stackpointer initialisieren&lt;br /&gt;
    out     SPL, temp1&lt;br /&gt;
    ldi     temp1, HIGH(RAMEND)&lt;br /&gt;
    out     SPH, temp1&lt;br /&gt;
&lt;br /&gt;
; CLK und PL als Ausgänge schalten&lt;br /&gt;
&lt;br /&gt;
    ldi     temp1, (1&amp;lt;&amp;lt;clk) | (1&amp;lt;&amp;lt;pl)&lt;br /&gt;
    out     SCHIEBE_DDR, temp1&lt;br /&gt;
&lt;br /&gt;
    sbi     schiebe_port, clk   ; Takt im Ruhezustand immer auf 1&lt;br /&gt;
                                ; komische Schaltung im 74xx165&lt;br /&gt;
&lt;br /&gt;
; Zwei Bytes einlesen&lt;br /&gt;
&lt;br /&gt;
    ldi     ZL,low(Daten)&lt;br /&gt;
    ldi     ZH,high(Daten)&lt;br /&gt;
    ldi     temp1,2&lt;br /&gt;
    rcall   schiebe_eingang&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    rjmp    loop&lt;br /&gt;
&lt;br /&gt;
;-----------------------------------------------------------------------------&lt;br /&gt;
;&lt;br /&gt;
; N Bytes seriell einlesen&lt;br /&gt;
;&lt;br /&gt;
; temp1 : N, Anzahl der Bytes&lt;br /&gt;
; Z     : Zeiger auf einen Datenbereich im SRAM&lt;br /&gt;
;-----------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
schiebe_eingang:&lt;br /&gt;
    push    temp2               ; Register sichern&lt;br /&gt;
    push    temp3&lt;br /&gt;
&lt;br /&gt;
    cbi     schiebe_port, pl    ; Daten parallel laden&lt;br /&gt;
    sbi     schiebe_port, pl&lt;br /&gt;
&lt;br /&gt;
schiebe_eingang_byte_schleife:&lt;br /&gt;
&lt;br /&gt;
    ldi     temp3, 8            ; Bitzähler&lt;br /&gt;
schiebe_eingang_bit_schleife:&lt;br /&gt;
    lsl     temp2               ; Daten weiterschieben&lt;br /&gt;
&lt;br /&gt;
; das IO Bit Din in das niederwerigste Bit von temp2 kopieren&lt;br /&gt;
&lt;br /&gt;
    sbic    schiebe_pin, din    ; wenn Null, nächsten Befehl überspringen&lt;br /&gt;
    ori     temp2,1             ; nein, Bit setzen&lt;br /&gt;
&lt;br /&gt;
    cbi     SCHIEBE_PORT, CLK   ; Taktausgang auf 0&lt;br /&gt;
    sbi     SCHIEBE_PORT, CLK   ; und wieder zurück auf 1, dabei Daten schieben &lt;br /&gt;
&lt;br /&gt;
    dec     temp3               ; Bitzähler um eins verringern&lt;br /&gt;
    brne    schiebe_eingang_bit_schleife ;wenn noch keine 8 Bits ausgegeben, nochmal&lt;br /&gt;
&lt;br /&gt;
    st      z+,temp2            ; Datenbyte speichern&lt;br /&gt;
    dec     temp1               ; Anzahl Bytes um eins verringern&lt;br /&gt;
    brne    schiebe_eingang_byte_schleife   ; wenn noch mehr Bytes zu lesen sind&lt;br /&gt;
&lt;br /&gt;
    pop     temp3&lt;br /&gt;
    pop     temp2&lt;br /&gt;
    ret&lt;br /&gt;
&amp;lt;/avrasm&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ansteuerung per SPI-Modul ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;avrasm&amp;gt;&lt;br /&gt;
; Porterweiterung für Eingänge mit Schieberegister 74xx165&lt;br /&gt;
; Ansteuerung per SPI-Modul&lt;br /&gt;
&lt;br /&gt;
.include &amp;quot;m8def.inc&amp;quot;&lt;br /&gt;
&lt;br /&gt;
.def temp1 = r16&lt;br /&gt;
.def temp2 = r17&lt;br /&gt;
.def temp3 = r18&lt;br /&gt;
&lt;br /&gt;
; Pins anpassen&lt;br /&gt;
; diese müssen mit den SPI-Pins des AVR Typs übereinstimmen!&lt;br /&gt;
&lt;br /&gt;
.equ SCHIEBE_DDR  = DDRB&lt;br /&gt;
.equ SCHIEBE_PORT = PORTB&lt;br /&gt;
.equ PL           = PB2         ; SS&lt;br /&gt;
.equ CLK          = PB5         ; SCK&lt;br /&gt;
.equ DIN          = PB4         ; MISO&lt;br /&gt;
&lt;br /&gt;
;-----------------------------------------------------------------------------&lt;br /&gt;
;&lt;br /&gt;
; Datensegment im RAM&lt;br /&gt;
;&lt;br /&gt;
;-----------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
.dseg&lt;br /&gt;
.org 0x60&lt;br /&gt;
Daten:      .byte 2             ; Speicherplatz für Eingangsdaten&lt;br /&gt;
&lt;br /&gt;
;-----------------------------------------------------------------------------&lt;br /&gt;
;&lt;br /&gt;
; Programmsegment im FLASH&lt;br /&gt;
;&lt;br /&gt;
;-----------------------------------------------------------------------------&lt;br /&gt;
.cseg&lt;br /&gt;
    ldi     temp1, LOW(RAMEND)  ; Stackpointer initialisieren&lt;br /&gt;
    out     SPL, temp1&lt;br /&gt;
    ldi     temp1, HIGH(RAMEND)&lt;br /&gt;
    out     SPH, temp1&lt;br /&gt;
&lt;br /&gt;
; CLK und PL als Ausgänge schalten&lt;br /&gt;
&lt;br /&gt;
    ldi     temp1,(1&amp;lt;&amp;lt;CLK) | (1&amp;lt;&amp;lt;PL)&lt;br /&gt;
    out     SCHIEBE_DDR,temp1     &lt;br /&gt;
;&lt;br /&gt;
; SPI Modul konfigurieren&lt;br /&gt;
;&lt;br /&gt;
    ldi     temp1, 0b01011000&lt;br /&gt;
    out     SPCR, temp1         ; keine Interrupts, MSB first, Master&lt;br /&gt;
                                ; CPOL = 1, CPHA =0&lt;br /&gt;
                                ; SCK Takt = 1/2 XTAL&lt;br /&gt;
    ldi     temp1,1&lt;br /&gt;
    out     SPSR,temp1          ; double speed aktivieren&lt;br /&gt;
    out     SPDR,temp1          ; Dummy Daten, um SPIF zu setzen&lt;br /&gt;
&lt;br /&gt;
; Zwei Bytes einlesen&lt;br /&gt;
&lt;br /&gt;
    ldi     ZL,low(Daten)&lt;br /&gt;
    ldi     ZH,high(Daten)&lt;br /&gt;
    ldi     temp1,2&lt;br /&gt;
    rcall   schiebe_eingang&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    rjmp    loop&lt;br /&gt;
&lt;br /&gt;
;-----------------------------------------------------------------------------&lt;br /&gt;
;&lt;br /&gt;
; N Bytes seriell einlesen&lt;br /&gt;
;&lt;br /&gt;
; temp1 : N, Anzahl der Bytes&lt;br /&gt;
; Z     : Zeiger auf einen Datenbereich im SRAM&lt;br /&gt;
;-----------------------------------------------------------------------------&lt;br /&gt;
schiebe_eingang:&lt;br /&gt;
    push    temp2               ; Register sichern&lt;br /&gt;
&lt;br /&gt;
    ; CLK ist im Ruhezustand schon auf HIGH, CPOL=1&lt;br /&gt;
&lt;br /&gt;
    cbi     schiebe_port, pl    ; Daten parallel laden&lt;br /&gt;
    sbi     schiebe_port, pl&lt;br /&gt;
&lt;br /&gt;
schiebe_eingang_1:&lt;br /&gt;
    sbis    SPSR,7              ; prüfe ob eine alte Übertragung beendet ist&lt;br /&gt;
    rjmp    schiebe_eingang_1&lt;br /&gt;
&lt;br /&gt;
schiebe_eingang_byte_schleife:&lt;br /&gt;
    out     SPDR,temp1          ; beliebige Daten ins SPI Modul schreiben&lt;br /&gt;
                                ; um die Übertragung zu starten&lt;br /&gt;
schiebe_eingang_2:&lt;br /&gt;
    sbis    SPSR,7              ; auf das Ende der Übertragung warten&lt;br /&gt;
    rjmp    schiebe_eingang_2&lt;br /&gt;
&lt;br /&gt;
    in      temp2, spdr         ; Daten lesen&lt;br /&gt;
    st      z+,temp2            ; Datenbyte speichern&lt;br /&gt;
    dec     temp1               ; Anzahl Bytes um eins verringern&lt;br /&gt;
    brne    schiebe_eingang_byte_schleife   ; wenn noch mehr Bytes zu lesen sind&lt;br /&gt;
&lt;br /&gt;
    pop     temp2&lt;br /&gt;
    ret&lt;br /&gt;
&amp;lt;/avrasm&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bekannte Probleme ==&lt;br /&gt;
&lt;br /&gt;
AVR Studio 4.12 (Build 498) hat Probleme bei der korrekten Simulation des SPI-Moduls.&lt;br /&gt;
&lt;br /&gt;
* Der Double-Speed Modus funktioniert nicht.&lt;br /&gt;
&lt;br /&gt;
* Das Bit SPIF im Register SPSR, welches laut Dokumentation nur lesbar ist, ist im Simulator auch schreibbar! Das kann zu Verwirrung und Fehlern in der Simulation führen.&lt;br /&gt;
&lt;br /&gt;
Hardwareprobleme&lt;br /&gt;
&lt;br /&gt;
* Wenn das SPI-Modul aktiviert wird, wird &#039;&#039;&#039;NICHT&#039;&#039;&#039; automatisch SPIF gesetzt, es bleibt auf Null. Damit würde die erste Abfrage in &#039;&#039;Schiebe_alles&#039;&#039; in einer Endlosschleife hängen bleiben. Deshalb muss nach der Initialisierung des SPI-Moduls ein Dummy Byte gesendet werden, damit am Ende der Übertragung SPIF gesetzt wird&lt;br /&gt;
&lt;br /&gt;
* Da das SPI-Modul in Senderichtung nur einfach gepuffert ist, ist es nicht möglich absolut lückenlos Daten zu senden, auch wenn man mit &#039;&#039;&#039;nop&#039;&#039;&#039; eine feste minimale Zeit zwischen zwei Bytes warten würde. Zwischen zwei Bytes muss immer eine Pause von mind. 2 Systemtakten eingehalten werden.&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/doc2585.pdf AVR151: Setup And Use of The SPI] Atmel Application Note (PDF)&lt;br /&gt;
* [http://www.datasheetcatalog.com/datasheets_pdf/7/4/H/C/74HC595.shtml datasheetcatalog.com: 74HC595]&lt;br /&gt;
* [http://www.rn-wissen.de/index.php/Portexpander_am_AVR Roboternetz: Portexpander am AVR]&lt;br /&gt;
* [http://conductiveresistance.com/interactive-595-shift-register-simulator/ Interactive 595 Shift Register Simulator]&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
{{Navigation_zurückhochvor|&lt;br /&gt;
zurücktext=PWM|&lt;br /&gt;
zurücklink=AVR-Tutorial: PWM|&lt;br /&gt;
hochtext=Inhaltsverzeichnis|&lt;br /&gt;
hochlink=AVR-Tutorial|&lt;br /&gt;
vortext=SRAM|&lt;br /&gt;
vorlink=AVR-Tutorial: SRAM}}&lt;br /&gt;
&lt;br /&gt;
[[Category:AVR-Tutorial]]&lt;br /&gt;
[[Category:SPI]]&lt;br /&gt;
[[Category:Portexpander]]&lt;/div&gt;</summary>
		<author><name>93.184.187.21</name></author>
	</entry>
</feed>