<?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=Stefan1971</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=Stefan1971"/>
	<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/articles/Spezial:Beitr%C3%A4ge/Stefan1971"/>
	<updated>2026-04-21T22:01:33Z</updated>
	<subtitle>Benutzerbeiträge</subtitle>
	<generator>MediaWiki 1.39.7</generator>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Codeschloss&amp;diff=64406</id>
		<title>Codeschloss</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Codeschloss&amp;diff=64406"/>
		<updated>2012-02-19T14:41:04Z</updated>

		<summary type="html">&lt;p&gt;Stefan1971: /* Software */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;von Stefan1971&lt;br /&gt;
&lt;br /&gt;
=== Einleitung ===&lt;br /&gt;
&lt;br /&gt;
Im Folgenden geht es um ein Haustür-Codeschloss, das als kleines AVR-Projekt in Hard- und Software umgesetzt ist und seit 2009 seinen Dienst am Klingelschild einer Haustüre versieht. Durch Eingabe des richtigen Codes lässt sich damit die Haustüre ohne Schlüssel öffnen.&lt;br /&gt;
&lt;br /&gt;
=== Merkmale ===&lt;br /&gt;
* Codeschloss mit ATtiny2313 zum Schalten eines elektrischen Türöffners über Relais&lt;br /&gt;
* Programmierbarer Tastencode zum Öffnen der Haustür kann aus bis zu 12 Tasten bestehen&lt;br /&gt;
* Aktivierdauer des Türöffners ist einstellbar&lt;br /&gt;
* Einzelne Taster oder alternativ eine 4x3-Matrixtastatur können angeschlossen werden&lt;br /&gt;
* Rote LED, wenn Codeeingabe läuft (leuchtet, sobald erste richtige Codetaste gedrückt wurde; verlöscht bei Zeitablauf in der Codeeingabe bzw. zusammen mit Abschalten des Türöffners)&lt;br /&gt;
* Gelbe LED leuchtet, wenn Codeschloss in Programmiermodus ist (=Lernen eines Codes) und blinkt, wenn Aktivierzeit für den Türöffner eingestellt wird&lt;br /&gt;
* Grüne LED zur Anzeige, ob Türöffner gerade geschaltet ist&lt;br /&gt;
* Wenn der Türöffner gerade aktiv ist, kann er durch Drücken einer beliebigen Codetaste vor Ablauf des Timers abgeschaltet werden&lt;br /&gt;
* Anschlüsse sind vorgesehen für die 12 Volt-Stromversorgung (Wechselspannung), eine LED als Türschildbeleuchtung und den Türöffner. Für die Codetasten gibt es eine Anschlussbuchse.&lt;br /&gt;
&lt;br /&gt;
=== Programmierung zur Nutzung ===&lt;br /&gt;
==== Programmieren des Codes ====&lt;br /&gt;
Durch Drücken des Programmiertasters auf der Schaltung wird in den Programmiermodus gewechselt. Das wird durch Leuchten der gelben LED angezeigt. Nun sind die Tasten in der gewünschten Reihenfolge zu betätigen. Der Code kann aus bis zu zwölf Tastendrücken bestehen. Die Programmierung wird durch erneutes Drücken des Programmiertasters abgeschlossen. Damit ist der Tastencode gespeichert. Werden bei der Programmierung die maximal möglichen Tasten gedrückt (derzeit 12), beendet sich der Programmiermodus ohne Betätigen des Programmiertasters; der Code wird auch dann gespeichert.&lt;br /&gt;
&lt;br /&gt;
==== Programmieren der Aktivierdauer des Türöffners ====&lt;br /&gt;
Wird der Programmiertaster im Programmiermodus (d.h. die gelbe LED leuchtet) gedrückt, ohne dass eine Codetaste zum Lernen eines neuen Codes betätigt wurde, so wechselt das Codeschloss in die Programmierung für die Aktivierdauer des Türöffners. Die gelbe LED zeigt dies durch Blinken an. In diesem Modus erfolgt mit der Taste 1 eine Testauslösung des Türöffners, mit der Taste 2 kann die Dauer verlängert, mit Taste 3 die Dauer verkürzt werden.&lt;br /&gt;
&lt;br /&gt;
Ist eine Matrixtastatur angeschlossen, werden andere Tasten verwendet: Hier erfolgt die Testauslösung mit der Taste (*). Die Taste (7) verlängert und die Taste (4) verkürzt die Dauer.&lt;br /&gt;
&lt;br /&gt;
Die Dauer wird in Stufen von ca. 0,2 Sekunden eingestellt. &lt;br /&gt;
&lt;br /&gt;
Erneutes Drücken des Programmiertasters speichert die Einstellung, die gelbe LED erlischt. Jede andere Taste als 1, 2, 3 bzw. (*), (7) oder (4) bricht die Programmierung ab und verwirft evtl. gemachte Änderungen an der Aktivierdauer.&lt;br /&gt;
&lt;br /&gt;
=== Software ===&lt;br /&gt;
Das Steuerprogramm ist in Assembler geschrieben. Über bedingte Assemblierung im Quelltext kann auf die Zielplattformen ATmega8 oder ATtiny2313 assembliert werden. Hintergrund ist, dass zuerst auf einem [http://www.myavr.de myAVR Board] mit ATmega8 entwickelt und später für den Selbstbau auf den ATtiny2313 umgeschwenkt wurde.&amp;lt;br /&amp;gt;&lt;br /&gt;
Mittlerweile (November 2011) gibt es auch eine funktional gleiche Version in C (siehe Abschnitt [[#Download|Download]]).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Folgende interne Zustände werden in der Firmware unterschieden:&lt;br /&gt;
! Status  !! Beschreibung&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;SCAN&#039;&#039;&#039;|| SCAN ist der Default-Modus im laufenden Betrieb. Warten auf Tasten in der richtigen Reihenfolge. Tastendruck gilt als erfolgt, wenn Taste losgelassen wurde. Mit Loslassen der ersten richtigen Taste wird (Software-) Timer gestartet. Rote LED leuchtet.&amp;lt;br /&amp;gt;Nächste Taste war richtig: Zeiger wird auf nächste zu erwartende Taste weiter gestellt, Timer wird zurückgesetzt.&amp;lt;br /&amp;gt;Taste war falsch: Zeiger auf Anfang, LED aus, Timer deaktivieren.&amp;lt;br /&amp;gt;Timer abgelaufen: Zeiger auf Anfang, LED aus; wie bei falscher Taste&amp;lt;br /&amp;gt;Anzeigen des SCAN-Modus durch Leuchten der roten LED, sobald die erste richtige Taste betätigt (d.h. losgelassen) wurde.&amp;lt;br /&amp;gt;Wenn alle Tasten in der richtigen Reihenfolge richtig gedrückt wurden, erfolgt Wechsel in Status OPEN.&amp;lt;br /&amp;gt;Wenn Programmierkontakt erkannt wurde, Wechsel in den PROG-Modus.&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;OPEN&#039;&#039;&#039; || Timer für Türöffner mit programmiertem Wert (aus Status PROG_DOOR) starten, grüne LED leuchtet, rote LED ebenfalls, Türöffner aktiv&amp;lt;br /&amp;gt;Timer abgelaufen: Türöffner aus, LEDs aus, zurück in SCAN-Modus&amp;lt;br /&amp;gt;Beliebige Taste wird gedrückt (Schließen ist relevant, nicht Öffnen): Türöffner aus, grüne und rote LED aus; zurück in SCAN-Modus: wie Timer-Ablauf&amp;lt;br /&amp;gt;Der Abbruch des OPEN-Modus durch Drücken einer beliebigen Taste ist realisiert, indem das Drücken einer falschen Taste simuliert wird.&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PROG&#039;&#039;&#039; || Programmiermodus: Tritt ein, wenn im SCAN-Modus der Programmierkontakt betätigt (=losgelassen) wurde. Ende des Programmiermodus, wenn Programmierkontakt erneut betätigt wird. Im Programmiermodus werden die betätigten Tasten (Loslassen der Taste, wie im SCAN-Modus) nacheinander im SRAM festgehalten. Hierzu wird Index auf SRAM-Tastenspeicher zunächst auf Null gesetzt. Bei Ende des Programmiermodus wird die im SRAM festgehaltene Tastenfolge ins EEPROM übernommen. Beenden des Programmiermodus, ohne dass eine Taste während des Programmiermodus betätigt wurde, erhält den bisher eingestellten Code; dann keine Übernahme ins EEPROM. Beenden des Programmiermodus führt dann in die Programmierung der Aktivierdauer des Türöffners; Wechsel in Modus PROG_DOOR.&amp;lt;br /&amp;gt;Eine begonnene Programmierung, bei der irrtümlich falsche Tasten gedrückt wurden, kann nicht storniert werden, sondern muss erneut durchgeführt werden. Im Programmiermodus leuchtet die gelbe LED.&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PROG_DOOR&#039;&#039;&#039; || Dient zur Programmierung der Aktivierdauer des Türöffners.&amp;lt;br /&amp;gt;Um in diesen Modus zu gelangen, muss der Programmierkontakt zweimal betätigt werden, d.h. der Code-Programmiermodus muss ohne Druck einer Codetaste beendet (übersprungen) werden. Im PROG_DOOR-Modus blinkt die gelbe LED.&amp;lt;br /&amp;gt;Die Tasten des Codeschlosses erhalten im PROG_DOOR-Modus folgende Bedeutung:&amp;lt;br /&amp;gt;Taste 1: löst den Türöffner für die eingestellte Zeit zum Test aus (per Timer)&amp;lt;br /&amp;gt;Taste 2: verlängert mit jedem Tastendruck die eingestellte Zeit&amp;lt;br /&amp;gt;Taste 3: verkürzt mit jedem Tastendruck die eingestellte Zeit&amp;lt;br /&amp;gt;Jede andere Taste: Verwirft die Änderungen und verlässt den PROG_DOOR-Modus, Rückkehr in den SCAN-Modus.&amp;lt;br /&amp;gt;Abschließendes Betätigen des Programmierkontakts führt zu Übernahme des neuen Timer-Ladewerts ins EEPROM und beendet den PROG_DOOR-Modus. Wechsel in den SCAN-Modus.&lt;br /&gt;
Ist eine 4x3-Matrixtastatur angeschlossen, ist die Tastenbelegung für die Programmierung der Türöffneraktivierdauer wie folgt:&amp;lt;br /&amp;gt;Taste (*): Türöffner testhalber auslösen&amp;lt;br /&amp;gt;Taste (7): Aktivierdauer verlängern&amp;lt;br /&amp;gt;Taste (4): Aktivierdauer verkürzen&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;STARTUP&#039;&#039;&#039; || Beim Start der Anwendung wird zunächst in diesen Modus gewechselt. Er hat den Zweck, die drei LEDs des Codeschlosses dreimal blinken zu lassen um anzuzeigen, dass der Controller arbeitet und auf Eingaben wartet. Wenn diese Phase abgelaufen ist, wird in den SCAN-Modus gewechselt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Hardware ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Belegung der Ports beim ATtiny2313:&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;PB0 ... PB7&#039;&#039;&#039; || IN || 8 Tasten zur Codeeingabe&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD6&#039;&#039;&#039; || IN || Programmierkontakt&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD0&#039;&#039;&#039; || OUT || Türöffner&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD1&#039;&#039;&#039; || OUT || Rote LED (laufende Codeeingabe)&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD2&#039;&#039;&#039; || OUT || Gelbe LED (Programmiermodus)&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD3&#039;&#039;&#039; || OUT || Grüne LED (Türöffner ist aktiv)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Einzelne Tasten werden mit jeweils einem Kontakt an Pin0 bis Pin7 angeschlossen, mit dem anderen Kontakt an Masse. Welche Tastatur (einzelne Tasten oder 4x3-Matrixtastatur) angeschlossen ist, wird über den bei der Matrixtastatur nicht benötigten Pin acht (PB7) gesteuert. Ist dieser beim Anwendungsstart auf Masse geschlossen, wird auf Abtastung einer Matrixtastatur umgestellt.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot; width=&amp;quot;25%&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Anschlussschema für 4x3-Matrixtastatur:&lt;br /&gt;
| width=&amp;quot;40%&amp;quot; | &#039;&#039;&#039;IN / OUT&#039;&#039;&#039; || style=&amp;quot;text-align:center&amp;quot; width=&amp;quot;20%&amp;quot; | &#039;&#039;&#039;Pin4&#039;&#039;&#039; || style=&amp;quot;text-align:center&amp;quot; width=&amp;quot;20%&amp;quot; | &#039;&#039;&#039;Pin5&#039;&#039;&#039; || style=&amp;quot;text-align:center&amp;quot; width=&amp;quot;20%&amp;quot; | &#039;&#039;&#039;Pin6&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin0&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | 1 || style=&amp;quot;text-align:center&amp;quot; | 2 || style=&amp;quot;text-align:center&amp;quot; | 3&lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin1&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | 4 || style=&amp;quot;text-align:center&amp;quot; | 5 || style=&amp;quot;text-align:center&amp;quot; | 6&lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin2&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | 7 || style=&amp;quot;text-align:center&amp;quot; | 8 || style=&amp;quot;text-align:center&amp;quot; | 9  &lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin3&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | * || style=&amp;quot;text-align:center&amp;quot; | 0 || style=&amp;quot;text-align:center&amp;quot; | #  &lt;br /&gt;
|} Pin7 und Pin8 (Masse) sind dann dauerhaft miteinander verbunden.&lt;br /&gt;
&lt;br /&gt;
Bei Nutzung eines Reed-Relais als Schaltelement muss der Türöffner erfahrungsgemäß einen Widerstand von mindestens 20Ω haben.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Die Fuses des Controllers sind folgendermaßen gesetzt:&lt;br /&gt;
! Fuse !! Einstellung&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;SPIEN:&#039;&#039;&#039;|| Enabled&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;BODLEVEL:&#039;&#039;&#039; || Brown-out detection disabled&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;CKDIV8:&#039;&#039;&#039; || Enabled&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;SUT_CKSEL:&#039;&#039;&#039; || Int. RC Osc. 4 MHz; Startup-time: 14 CK + 65 ms&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;alle anderen:&#039;&#039;&#039; || Disabled&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Schaltplan und Platinenlayout wurden mit Target3001 erstellt.&lt;br /&gt;
&lt;br /&gt;
=== Bilder ===&lt;br /&gt;
[[Bild:Codeschloss_Platine_beschriftet.jpg|thumb|550px|none|Codeschloss-Platine]]&lt;br /&gt;
[[Bild:Codeschloss_Platine_Keypad_Ausschnitt.jpg|thumb|220px|none|Anschluss einer Matrixtastatur]]&lt;br /&gt;
&lt;br /&gt;
=== Download ===&lt;br /&gt;
* [[Media:Codeschloss.zip | Codeschloss.zip ]]&amp;lt;br /&amp;gt;enthält ASM-Source, XLS-Rechenhilfe für Interrupt-Timing, Schaltplan-/Layout-Ausdruck&lt;br /&gt;
* [[Media:Codeschloss_C.zip | Codeschloss_C.zip]]&amp;lt;br /&amp;gt;Version in C (WinAVR-20100110), mit .hex- und .epp-Datei&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:AVR-Projekte]]&lt;/div&gt;</summary>
		<author><name>Stefan1971</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Codeschloss&amp;diff=64405</id>
		<title>Codeschloss</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Codeschloss&amp;diff=64405"/>
		<updated>2012-02-19T14:38:09Z</updated>

		<summary type="html">&lt;p&gt;Stefan1971: /* Programmieren des Codes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;von Stefan1971&lt;br /&gt;
&lt;br /&gt;
=== Einleitung ===&lt;br /&gt;
&lt;br /&gt;
Im Folgenden geht es um ein Haustür-Codeschloss, das als kleines AVR-Projekt in Hard- und Software umgesetzt ist und seit 2009 seinen Dienst am Klingelschild einer Haustüre versieht. Durch Eingabe des richtigen Codes lässt sich damit die Haustüre ohne Schlüssel öffnen.&lt;br /&gt;
&lt;br /&gt;
=== Merkmale ===&lt;br /&gt;
* Codeschloss mit ATtiny2313 zum Schalten eines elektrischen Türöffners über Relais&lt;br /&gt;
* Programmierbarer Tastencode zum Öffnen der Haustür kann aus bis zu 12 Tasten bestehen&lt;br /&gt;
* Aktivierdauer des Türöffners ist einstellbar&lt;br /&gt;
* Einzelne Taster oder alternativ eine 4x3-Matrixtastatur können angeschlossen werden&lt;br /&gt;
* Rote LED, wenn Codeeingabe läuft (leuchtet, sobald erste richtige Codetaste gedrückt wurde; verlöscht bei Zeitablauf in der Codeeingabe bzw. zusammen mit Abschalten des Türöffners)&lt;br /&gt;
* Gelbe LED leuchtet, wenn Codeschloss in Programmiermodus ist (=Lernen eines Codes) und blinkt, wenn Aktivierzeit für den Türöffner eingestellt wird&lt;br /&gt;
* Grüne LED zur Anzeige, ob Türöffner gerade geschaltet ist&lt;br /&gt;
* Wenn der Türöffner gerade aktiv ist, kann er durch Drücken einer beliebigen Codetaste vor Ablauf des Timers abgeschaltet werden&lt;br /&gt;
* Anschlüsse sind vorgesehen für die 12 Volt-Stromversorgung (Wechselspannung), eine LED als Türschildbeleuchtung und den Türöffner. Für die Codetasten gibt es eine Anschlussbuchse.&lt;br /&gt;
&lt;br /&gt;
=== Programmierung zur Nutzung ===&lt;br /&gt;
==== Programmieren des Codes ====&lt;br /&gt;
Durch Drücken des Programmiertasters auf der Schaltung wird in den Programmiermodus gewechselt. Das wird durch Leuchten der gelben LED angezeigt. Nun sind die Tasten in der gewünschten Reihenfolge zu betätigen. Der Code kann aus bis zu zwölf Tastendrücken bestehen. Die Programmierung wird durch erneutes Drücken des Programmiertasters abgeschlossen. Damit ist der Tastencode gespeichert. Werden bei der Programmierung die maximal möglichen Tasten gedrückt (derzeit 12), beendet sich der Programmiermodus ohne Betätigen des Programmiertasters; der Code wird auch dann gespeichert.&lt;br /&gt;
&lt;br /&gt;
==== Programmieren der Aktivierdauer des Türöffners ====&lt;br /&gt;
Wird der Programmiertaster im Programmiermodus (d.h. die gelbe LED leuchtet) gedrückt, ohne dass eine Codetaste zum Lernen eines neuen Codes betätigt wurde, so wechselt das Codeschloss in die Programmierung für die Aktivierdauer des Türöffners. Die gelbe LED zeigt dies durch Blinken an. In diesem Modus erfolgt mit der Taste 1 eine Testauslösung des Türöffners, mit der Taste 2 kann die Dauer verlängert, mit Taste 3 die Dauer verkürzt werden.&lt;br /&gt;
&lt;br /&gt;
Ist eine Matrixtastatur angeschlossen, werden andere Tasten verwendet: Hier erfolgt die Testauslösung mit der Taste (*). Die Taste (7) verlängert und die Taste (4) verkürzt die Dauer.&lt;br /&gt;
&lt;br /&gt;
Die Dauer wird in Stufen von ca. 0,2 Sekunden eingestellt. &lt;br /&gt;
&lt;br /&gt;
Erneutes Drücken des Programmiertasters speichert die Einstellung, die gelbe LED erlischt. Jede andere Taste als 1, 2, 3 bzw. (*), (7) oder (4) bricht die Programmierung ab und verwirft evtl. gemachte Änderungen an der Aktivierdauer.&lt;br /&gt;
&lt;br /&gt;
=== Software ===&lt;br /&gt;
Das Steuerprogramm ist in Assembler programmiert. Über bedingte Assemblierung im Quelltext kann auf die Zielplattformen ATmega8 oder ATtiny2313 assembliert werden. Hintergrund ist, dass zuerst auf einem [http://www.myavr.de myAVR Board] mit ATmega8 entwickelt und später für den Selbstbau auf den ATtiny2313 umgeschwenkt wurde.&amp;lt;br /&amp;gt;&lt;br /&gt;
Mittlerweile (November 2011) gibt es auch eine funktional gleiche Version in C (siehe Abschnitt [[#Download|Download]]).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Folgende interne Zustände werden in der Firmware unterschieden:&lt;br /&gt;
! Status  !! Beschreibung&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;SCAN&#039;&#039;&#039;|| SCAN ist der Default-Modus im laufenden Betrieb. Warten auf Tasten in der richtigen Reihenfolge. Tastendruck gilt als erfolgt, wenn Taste losgelassen wurde. Mit Loslassen der ersten richtigen Taste wird (Software-) Timer gestartet. Rote LED leuchtet.&amp;lt;br /&amp;gt;Nächste Taste war richtig: Zeiger wird auf nächste zu erwartende Taste weiter gestellt, Timer wird zurückgesetzt.&amp;lt;br /&amp;gt;Taste war falsch: Zeiger auf Anfang, LED aus, Timer deaktivieren.&amp;lt;br /&amp;gt;Timer abgelaufen: Zeiger auf Anfang, LED aus; wie bei falscher Taste&amp;lt;br /&amp;gt;Anzeigen des SCAN-Modus durch Leuchten der roten LED, sobald die erste richtige Taste betätigt (d.h. losgelassen) wurde.&amp;lt;br /&amp;gt;Wenn alle Tasten in der richtigen Reihenfolge richtig gedrückt wurden, erfolgt Wechsel in Status OPEN.&amp;lt;br /&amp;gt;Wenn Programmierkontakt erkannt wurde, Wechsel in den PROG-Modus.&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;OPEN&#039;&#039;&#039; || Timer für Türöffner mit programmiertem Wert (aus Status PROG_DOOR) starten, grüne LED leuchtet, rote LED ebenfalls, Türöffner aktiv&amp;lt;br /&amp;gt;Timer abgelaufen: Türöffner aus, LEDs aus, zurück in SCAN-Modus&amp;lt;br /&amp;gt;Beliebige Taste wird gedrückt (Schließen ist relevant, nicht Öffnen): Türöffner aus, grüne und rote LED aus; zurück in SCAN-Modus: wie Timer-Ablauf&amp;lt;br /&amp;gt;Der Abbruch des OPEN-Modus durch Drücken einer beliebigen Taste ist realisiert, indem das Drücken einer falschen Taste simuliert wird.&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PROG&#039;&#039;&#039; || Programmiermodus: Tritt ein, wenn im SCAN-Modus der Programmierkontakt betätigt (=losgelassen) wurde. Ende des Programmiermodus, wenn Programmierkontakt erneut betätigt wird. Im Programmiermodus werden die betätigten Tasten (Loslassen der Taste, wie im SCAN-Modus) nacheinander im SRAM festgehalten. Hierzu wird Index auf SRAM-Tastenspeicher zunächst auf Null gesetzt. Bei Ende des Programmiermodus wird die im SRAM festgehaltene Tastenfolge ins EEPROM übernommen. Beenden des Programmiermodus, ohne dass eine Taste während des Programmiermodus betätigt wurde, erhält den bisher eingestellten Code; dann keine Übernahme ins EEPROM. Beenden des Programmiermodus führt dann in die Programmierung der Aktivierdauer des Türöffners; Wechsel in Modus PROG_DOOR.&amp;lt;br /&amp;gt;Eine begonnene Programmierung, bei der irrtümlich falsche Tasten gedrückt wurden, kann nicht storniert werden, sondern muss erneut durchgeführt werden. Im Programmiermodus leuchtet die gelbe LED.&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PROG_DOOR&#039;&#039;&#039; || Dient zur Programmierung der Aktivierdauer des Türöffners.&amp;lt;br /&amp;gt;Um in diesen Modus zu gelangen, muss der Programmierkontakt zweimal betätigt werden, d.h. der Code-Programmiermodus muss ohne Druck einer Codetaste beendet (übersprungen) werden. Im PROG_DOOR-Modus blinkt die gelbe LED.&amp;lt;br /&amp;gt;Die Tasten des Codeschlosses erhalten im PROG_DOOR-Modus folgende Bedeutung:&amp;lt;br /&amp;gt;Taste 1: löst den Türöffner für die eingestellte Zeit zum Test aus (per Timer)&amp;lt;br /&amp;gt;Taste 2: verlängert mit jedem Tastendruck die eingestellte Zeit&amp;lt;br /&amp;gt;Taste 3: verkürzt mit jedem Tastendruck die eingestellte Zeit&amp;lt;br /&amp;gt;Jede andere Taste: Verwirft die Änderungen und verlässt den PROG_DOOR-Modus, Rückkehr in den SCAN-Modus.&amp;lt;br /&amp;gt;Abschließendes Betätigen des Programmierkontakts führt zu Übernahme des neuen Timer-Ladewerts ins EEPROM und beendet den PROG_DOOR-Modus. Wechsel in den SCAN-Modus.&lt;br /&gt;
Ist eine 4x3-Matrixtastatur angeschlossen, ist die Tastenbelegung für die Programmierung der Türöffneraktivierdauer wie folgt:&amp;lt;br /&amp;gt;Taste (*): Türöffner testhalber auslösen&amp;lt;br /&amp;gt;Taste (7): Aktivierdauer verlängern&amp;lt;br /&amp;gt;Taste (4): Aktivierdauer verkürzen&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;STARTUP&#039;&#039;&#039; || In diesen Modus wird beim Start der Anwendung zunächst gewechselt. Er hat den Zweck, die drei LEDs des Codeschlosses dreimal blinken zu lassen um anzuzeigen, dass der Controller arbeitet und auf Eingaben wartet. Wenn diese Phase abgelaufen ist, wird in den SCAN-Modus gewechselt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Hardware ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Belegung der Ports beim ATtiny2313:&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;PB0 ... PB7&#039;&#039;&#039; || IN || 8 Tasten zur Codeeingabe&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD6&#039;&#039;&#039; || IN || Programmierkontakt&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD0&#039;&#039;&#039; || OUT || Türöffner&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD1&#039;&#039;&#039; || OUT || Rote LED (laufende Codeeingabe)&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD2&#039;&#039;&#039; || OUT || Gelbe LED (Programmiermodus)&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD3&#039;&#039;&#039; || OUT || Grüne LED (Türöffner ist aktiv)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Einzelne Tasten werden mit jeweils einem Kontakt an Pin0 bis Pin7 angeschlossen, mit dem anderen Kontakt an Masse. Welche Tastatur (einzelne Tasten oder 4x3-Matrixtastatur) angeschlossen ist, wird über den bei der Matrixtastatur nicht benötigten Pin acht (PB7) gesteuert. Ist dieser beim Anwendungsstart auf Masse geschlossen, wird auf Abtastung einer Matrixtastatur umgestellt.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot; width=&amp;quot;25%&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Anschlussschema für 4x3-Matrixtastatur:&lt;br /&gt;
| width=&amp;quot;40%&amp;quot; | &#039;&#039;&#039;IN / OUT&#039;&#039;&#039; || style=&amp;quot;text-align:center&amp;quot; width=&amp;quot;20%&amp;quot; | &#039;&#039;&#039;Pin4&#039;&#039;&#039; || style=&amp;quot;text-align:center&amp;quot; width=&amp;quot;20%&amp;quot; | &#039;&#039;&#039;Pin5&#039;&#039;&#039; || style=&amp;quot;text-align:center&amp;quot; width=&amp;quot;20%&amp;quot; | &#039;&#039;&#039;Pin6&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin0&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | 1 || style=&amp;quot;text-align:center&amp;quot; | 2 || style=&amp;quot;text-align:center&amp;quot; | 3&lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin1&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | 4 || style=&amp;quot;text-align:center&amp;quot; | 5 || style=&amp;quot;text-align:center&amp;quot; | 6&lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin2&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | 7 || style=&amp;quot;text-align:center&amp;quot; | 8 || style=&amp;quot;text-align:center&amp;quot; | 9  &lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin3&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | * || style=&amp;quot;text-align:center&amp;quot; | 0 || style=&amp;quot;text-align:center&amp;quot; | #  &lt;br /&gt;
|} Pin7 und Pin8 (Masse) sind dann dauerhaft miteinander verbunden.&lt;br /&gt;
&lt;br /&gt;
Bei Nutzung eines Reed-Relais als Schaltelement muss der Türöffner erfahrungsgemäß einen Widerstand von mindestens 20Ω haben.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Die Fuses des Controllers sind folgendermaßen gesetzt:&lt;br /&gt;
! Fuse !! Einstellung&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;SPIEN:&#039;&#039;&#039;|| Enabled&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;BODLEVEL:&#039;&#039;&#039; || Brown-out detection disabled&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;CKDIV8:&#039;&#039;&#039; || Enabled&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;SUT_CKSEL:&#039;&#039;&#039; || Int. RC Osc. 4 MHz; Startup-time: 14 CK + 65 ms&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;alle anderen:&#039;&#039;&#039; || Disabled&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Schaltplan und Platinenlayout wurden mit Target3001 erstellt.&lt;br /&gt;
&lt;br /&gt;
=== Bilder ===&lt;br /&gt;
[[Bild:Codeschloss_Platine_beschriftet.jpg|thumb|550px|none|Codeschloss-Platine]]&lt;br /&gt;
[[Bild:Codeschloss_Platine_Keypad_Ausschnitt.jpg|thumb|220px|none|Anschluss einer Matrixtastatur]]&lt;br /&gt;
&lt;br /&gt;
=== Download ===&lt;br /&gt;
* [[Media:Codeschloss.zip | Codeschloss.zip ]]&amp;lt;br /&amp;gt;enthält ASM-Source, XLS-Rechenhilfe für Interrupt-Timing, Schaltplan-/Layout-Ausdruck&lt;br /&gt;
* [[Media:Codeschloss_C.zip | Codeschloss_C.zip]]&amp;lt;br /&amp;gt;Version in C (WinAVR-20100110), mit .hex- und .epp-Datei&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:AVR-Projekte]]&lt;/div&gt;</summary>
		<author><name>Stefan1971</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Codeschloss&amp;diff=64404</id>
		<title>Codeschloss</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Codeschloss&amp;diff=64404"/>
		<updated>2012-02-19T14:34:44Z</updated>

		<summary type="html">&lt;p&gt;Stefan1971: /* Einleitung */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;von Stefan1971&lt;br /&gt;
&lt;br /&gt;
=== Einleitung ===&lt;br /&gt;
&lt;br /&gt;
Im Folgenden geht es um ein Haustür-Codeschloss, das als kleines AVR-Projekt in Hard- und Software umgesetzt ist und seit 2009 seinen Dienst am Klingelschild einer Haustüre versieht. Durch Eingabe des richtigen Codes lässt sich damit die Haustüre ohne Schlüssel öffnen.&lt;br /&gt;
&lt;br /&gt;
=== Merkmale ===&lt;br /&gt;
* Codeschloss mit ATtiny2313 zum Schalten eines elektrischen Türöffners über Relais&lt;br /&gt;
* Programmierbarer Tastencode zum Öffnen der Haustür kann aus bis zu 12 Tasten bestehen&lt;br /&gt;
* Aktivierdauer des Türöffners ist einstellbar&lt;br /&gt;
* Einzelne Taster oder alternativ eine 4x3-Matrixtastatur können angeschlossen werden&lt;br /&gt;
* Rote LED, wenn Codeeingabe läuft (leuchtet, sobald erste richtige Codetaste gedrückt wurde; verlöscht bei Zeitablauf in der Codeeingabe bzw. zusammen mit Abschalten des Türöffners)&lt;br /&gt;
* Gelbe LED leuchtet, wenn Codeschloss in Programmiermodus ist (=Lernen eines Codes) und blinkt, wenn Aktivierzeit für den Türöffner eingestellt wird&lt;br /&gt;
* Grüne LED zur Anzeige, ob Türöffner gerade geschaltet ist&lt;br /&gt;
* Wenn der Türöffner gerade aktiv ist, kann er durch Drücken einer beliebigen Codetaste vor Ablauf des Timers abgeschaltet werden&lt;br /&gt;
* Anschlüsse sind vorgesehen für die 12 Volt-Stromversorgung (Wechselspannung), eine LED als Türschildbeleuchtung und den Türöffner. Für die Codetasten gibt es eine Anschlussbuchse.&lt;br /&gt;
&lt;br /&gt;
=== Programmierung zur Nutzung ===&lt;br /&gt;
==== Programmieren des Codes ====&lt;br /&gt;
Durch Drücken des Programmiertasters auf der Schaltung wird in den Programmiermodus gewechselt. Dieser wird durch Leuchten der gelben LED angezeigt. Nun sind die Tasten in der gewünschten Reihenfolge zu betätigen. Der Code kann aus bis zu zwölf Tastendrücken bestehen. Die Programmierung ist durch erneutes Drücken des Programmiertasters abzuschließen. Damit ist der Tastencode gespeichert. Werden bei der Programmierung die maximal möglichen Tasten gedrückt (derzeit 12), beendet sich der Programmiermodus ohne Betätigen des Programmiertasters.&lt;br /&gt;
&lt;br /&gt;
==== Programmieren der Aktivierdauer des Türöffners ====&lt;br /&gt;
Wird der Programmiertaster im Programmiermodus (d.h. die gelbe LED leuchtet) gedrückt, ohne dass eine Codetaste zum Lernen eines neuen Codes betätigt wurde, so wechselt das Codeschloss in die Programmierung für die Aktivierdauer des Türöffners. Die gelbe LED zeigt dies durch Blinken an. In diesem Modus erfolgt mit der Taste 1 eine Testauslösung des Türöffners, mit der Taste 2 kann die Dauer verlängert, mit Taste 3 die Dauer verkürzt werden.&lt;br /&gt;
&lt;br /&gt;
Ist eine Matrixtastatur angeschlossen, werden andere Tasten verwendet: Hier erfolgt die Testauslösung mit der Taste (*). Die Taste (7) verlängert und die Taste (4) verkürzt die Dauer.&lt;br /&gt;
&lt;br /&gt;
Die Dauer wird in Stufen von ca. 0,2 Sekunden eingestellt. &lt;br /&gt;
&lt;br /&gt;
Erneutes Drücken des Programmiertasters speichert die Einstellung, die gelbe LED erlischt. Jede andere Taste als 1, 2, 3 bzw. (*), (7) oder (4) bricht die Programmierung ab und verwirft evtl. gemachte Änderungen an der Aktivierdauer.&lt;br /&gt;
&lt;br /&gt;
=== Software ===&lt;br /&gt;
Das Steuerprogramm ist in Assembler programmiert. Über bedingte Assemblierung im Quelltext kann auf die Zielplattformen ATmega8 oder ATtiny2313 assembliert werden. Hintergrund ist, dass zuerst auf einem [http://www.myavr.de myAVR Board] mit ATmega8 entwickelt und später für den Selbstbau auf den ATtiny2313 umgeschwenkt wurde.&amp;lt;br /&amp;gt;&lt;br /&gt;
Mittlerweile (November 2011) gibt es auch eine funktional gleiche Version in C (siehe Abschnitt [[#Download|Download]]).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Folgende interne Zustände werden in der Firmware unterschieden:&lt;br /&gt;
! Status  !! Beschreibung&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;SCAN&#039;&#039;&#039;|| SCAN ist der Default-Modus im laufenden Betrieb. Warten auf Tasten in der richtigen Reihenfolge. Tastendruck gilt als erfolgt, wenn Taste losgelassen wurde. Mit Loslassen der ersten richtigen Taste wird (Software-) Timer gestartet. Rote LED leuchtet.&amp;lt;br /&amp;gt;Nächste Taste war richtig: Zeiger wird auf nächste zu erwartende Taste weiter gestellt, Timer wird zurückgesetzt.&amp;lt;br /&amp;gt;Taste war falsch: Zeiger auf Anfang, LED aus, Timer deaktivieren.&amp;lt;br /&amp;gt;Timer abgelaufen: Zeiger auf Anfang, LED aus; wie bei falscher Taste&amp;lt;br /&amp;gt;Anzeigen des SCAN-Modus durch Leuchten der roten LED, sobald die erste richtige Taste betätigt (d.h. losgelassen) wurde.&amp;lt;br /&amp;gt;Wenn alle Tasten in der richtigen Reihenfolge richtig gedrückt wurden, erfolgt Wechsel in Status OPEN.&amp;lt;br /&amp;gt;Wenn Programmierkontakt erkannt wurde, Wechsel in den PROG-Modus.&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;OPEN&#039;&#039;&#039; || Timer für Türöffner mit programmiertem Wert (aus Status PROG_DOOR) starten, grüne LED leuchtet, rote LED ebenfalls, Türöffner aktiv&amp;lt;br /&amp;gt;Timer abgelaufen: Türöffner aus, LEDs aus, zurück in SCAN-Modus&amp;lt;br /&amp;gt;Beliebige Taste wird gedrückt (Schließen ist relevant, nicht Öffnen): Türöffner aus, grüne und rote LED aus; zurück in SCAN-Modus: wie Timer-Ablauf&amp;lt;br /&amp;gt;Der Abbruch des OPEN-Modus durch Drücken einer beliebigen Taste ist realisiert, indem das Drücken einer falschen Taste simuliert wird.&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PROG&#039;&#039;&#039; || Programmiermodus: Tritt ein, wenn im SCAN-Modus der Programmierkontakt betätigt (=losgelassen) wurde. Ende des Programmiermodus, wenn Programmierkontakt erneut betätigt wird. Im Programmiermodus werden die betätigten Tasten (Loslassen der Taste, wie im SCAN-Modus) nacheinander im SRAM festgehalten. Hierzu wird Index auf SRAM-Tastenspeicher zunächst auf Null gesetzt. Bei Ende des Programmiermodus wird die im SRAM festgehaltene Tastenfolge ins EEPROM übernommen. Beenden des Programmiermodus, ohne dass eine Taste während des Programmiermodus betätigt wurde, erhält den bisher eingestellten Code; dann keine Übernahme ins EEPROM. Beenden des Programmiermodus führt dann in die Programmierung der Aktivierdauer des Türöffners; Wechsel in Modus PROG_DOOR.&amp;lt;br /&amp;gt;Eine begonnene Programmierung, bei der irrtümlich falsche Tasten gedrückt wurden, kann nicht storniert werden, sondern muss erneut durchgeführt werden. Im Programmiermodus leuchtet die gelbe LED.&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PROG_DOOR&#039;&#039;&#039; || Dient zur Programmierung der Aktivierdauer des Türöffners.&amp;lt;br /&amp;gt;Um in diesen Modus zu gelangen, muss der Programmierkontakt zweimal betätigt werden, d.h. der Code-Programmiermodus muss ohne Druck einer Codetaste beendet (übersprungen) werden. Im PROG_DOOR-Modus blinkt die gelbe LED.&amp;lt;br /&amp;gt;Die Tasten des Codeschlosses erhalten im PROG_DOOR-Modus folgende Bedeutung:&amp;lt;br /&amp;gt;Taste 1: löst den Türöffner für die eingestellte Zeit zum Test aus (per Timer)&amp;lt;br /&amp;gt;Taste 2: verlängert mit jedem Tastendruck die eingestellte Zeit&amp;lt;br /&amp;gt;Taste 3: verkürzt mit jedem Tastendruck die eingestellte Zeit&amp;lt;br /&amp;gt;Jede andere Taste: Verwirft die Änderungen und verlässt den PROG_DOOR-Modus, Rückkehr in den SCAN-Modus.&amp;lt;br /&amp;gt;Abschließendes Betätigen des Programmierkontakts führt zu Übernahme des neuen Timer-Ladewerts ins EEPROM und beendet den PROG_DOOR-Modus. Wechsel in den SCAN-Modus.&lt;br /&gt;
Ist eine 4x3-Matrixtastatur angeschlossen, ist die Tastenbelegung für die Programmierung der Türöffneraktivierdauer wie folgt:&amp;lt;br /&amp;gt;Taste (*): Türöffner testhalber auslösen&amp;lt;br /&amp;gt;Taste (7): Aktivierdauer verlängern&amp;lt;br /&amp;gt;Taste (4): Aktivierdauer verkürzen&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;STARTUP&#039;&#039;&#039; || In diesen Modus wird beim Start der Anwendung zunächst gewechselt. Er hat den Zweck, die drei LEDs des Codeschlosses dreimal blinken zu lassen um anzuzeigen, dass der Controller arbeitet und auf Eingaben wartet. Wenn diese Phase abgelaufen ist, wird in den SCAN-Modus gewechselt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Hardware ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Belegung der Ports beim ATtiny2313:&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;PB0 ... PB7&#039;&#039;&#039; || IN || 8 Tasten zur Codeeingabe&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD6&#039;&#039;&#039; || IN || Programmierkontakt&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD0&#039;&#039;&#039; || OUT || Türöffner&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD1&#039;&#039;&#039; || OUT || Rote LED (laufende Codeeingabe)&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD2&#039;&#039;&#039; || OUT || Gelbe LED (Programmiermodus)&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD3&#039;&#039;&#039; || OUT || Grüne LED (Türöffner ist aktiv)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Einzelne Tasten werden mit jeweils einem Kontakt an Pin0 bis Pin7 angeschlossen, mit dem anderen Kontakt an Masse. Welche Tastatur (einzelne Tasten oder 4x3-Matrixtastatur) angeschlossen ist, wird über den bei der Matrixtastatur nicht benötigten Pin acht (PB7) gesteuert. Ist dieser beim Anwendungsstart auf Masse geschlossen, wird auf Abtastung einer Matrixtastatur umgestellt.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot; width=&amp;quot;25%&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Anschlussschema für 4x3-Matrixtastatur:&lt;br /&gt;
| width=&amp;quot;40%&amp;quot; | &#039;&#039;&#039;IN / OUT&#039;&#039;&#039; || style=&amp;quot;text-align:center&amp;quot; width=&amp;quot;20%&amp;quot; | &#039;&#039;&#039;Pin4&#039;&#039;&#039; || style=&amp;quot;text-align:center&amp;quot; width=&amp;quot;20%&amp;quot; | &#039;&#039;&#039;Pin5&#039;&#039;&#039; || style=&amp;quot;text-align:center&amp;quot; width=&amp;quot;20%&amp;quot; | &#039;&#039;&#039;Pin6&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin0&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | 1 || style=&amp;quot;text-align:center&amp;quot; | 2 || style=&amp;quot;text-align:center&amp;quot; | 3&lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin1&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | 4 || style=&amp;quot;text-align:center&amp;quot; | 5 || style=&amp;quot;text-align:center&amp;quot; | 6&lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin2&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | 7 || style=&amp;quot;text-align:center&amp;quot; | 8 || style=&amp;quot;text-align:center&amp;quot; | 9  &lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin3&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | * || style=&amp;quot;text-align:center&amp;quot; | 0 || style=&amp;quot;text-align:center&amp;quot; | #  &lt;br /&gt;
|} Pin7 und Pin8 (Masse) sind dann dauerhaft miteinander verbunden.&lt;br /&gt;
&lt;br /&gt;
Bei Nutzung eines Reed-Relais als Schaltelement muss der Türöffner erfahrungsgemäß einen Widerstand von mindestens 20Ω haben.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Die Fuses des Controllers sind folgendermaßen gesetzt:&lt;br /&gt;
! Fuse !! Einstellung&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;SPIEN:&#039;&#039;&#039;|| Enabled&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;BODLEVEL:&#039;&#039;&#039; || Brown-out detection disabled&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;CKDIV8:&#039;&#039;&#039; || Enabled&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;SUT_CKSEL:&#039;&#039;&#039; || Int. RC Osc. 4 MHz; Startup-time: 14 CK + 65 ms&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;alle anderen:&#039;&#039;&#039; || Disabled&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Schaltplan und Platinenlayout wurden mit Target3001 erstellt.&lt;br /&gt;
&lt;br /&gt;
=== Bilder ===&lt;br /&gt;
[[Bild:Codeschloss_Platine_beschriftet.jpg|thumb|550px|none|Codeschloss-Platine]]&lt;br /&gt;
[[Bild:Codeschloss_Platine_Keypad_Ausschnitt.jpg|thumb|220px|none|Anschluss einer Matrixtastatur]]&lt;br /&gt;
&lt;br /&gt;
=== Download ===&lt;br /&gt;
* [[Media:Codeschloss.zip | Codeschloss.zip ]]&amp;lt;br /&amp;gt;enthält ASM-Source, XLS-Rechenhilfe für Interrupt-Timing, Schaltplan-/Layout-Ausdruck&lt;br /&gt;
* [[Media:Codeschloss_C.zip | Codeschloss_C.zip]]&amp;lt;br /&amp;gt;Version in C (WinAVR-20100110), mit .hex- und .epp-Datei&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:AVR-Projekte]]&lt;/div&gt;</summary>
		<author><name>Stefan1971</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=FAQ&amp;diff=61553</id>
		<title>FAQ</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=FAQ&amp;diff=61553"/>
		<updated>2011-11-09T19:39:31Z</updated>

		<summary type="html">&lt;p&gt;Stefan1971: /* Was hat es mit volatile auf sich */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ein Verzeichnis von im Forum oft gestellten und immer wieder beantworteten Fragen und den zugehörigen Antworten:&lt;br /&gt;
&lt;br /&gt;
=Wie kann ich Zahlen auf [[LCD]]/[[UART]] ausgeben?=&lt;br /&gt;
&lt;br /&gt;
Aber die Bibliothek, die du benutzt, stellt nur eine Funktion zur Verfügung, mit der man einen String ausgeben kann... Was tun? &lt;br /&gt;
&lt;br /&gt;
In den folgenden Beispielen wird eine selbstgeschriebene Funktion zur Stringausgabe auf LCD - die Funktion lcd_string() - aus dem [[AVR-GCC-Tutorial/LCD-Ansteuerung|LCD-Teil des AVR-GCC-Tutorials]] verwendet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
lcd_string( &amp;quot;Hallo Welt&amp;quot; );  // ggf. auch lcd_out() o.ä. in anderen Libraries&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Um also eine Zahl (numerische Konstante oder Variableninhalt) auszugeben, muss von dieser Zahl zunächst ihre String-Repräsentation ermittelt werden. Hier geht es aber nur darum, zu zeigen wie man diese String Repräsenation erzeugen kann. Was man dann mit diesem String weiter macht, ob das dann eine LCD-Ausgabe oder eine UART-Übertragung oder das Abspeichern auf SD-Karte oder ... ist, spielt eine untergeordnete Rolle.&lt;br /&gt;
&lt;br /&gt;
Es gibt mehrere Möglichkeiten, sich die Stringrepräsentation zu erzeugen:&lt;br /&gt;
&lt;br /&gt;
===itoa() (utoa(), ltoa(), ultoa(), ftoa() )===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;itoa()&amp;lt;/b&amp;gt; ist keine C-Standardfunktion (wohl aber ihre Umkehrung &amp;lt;b&amp;gt;atoi()&amp;lt;/b&amp;gt; ). Auf manchen Compilern heisst diese Funktion dann folgerichtig &amp;lt;b&amp;gt;_itoa()&amp;lt;/b&amp;gt;, wobei der führende _ eben anzeigt, dass es sich um eine Erweiterung des C-Standards handelt. Bei [[WinAVR]] ist itoa() Bestandteil der mitgelieferten Library avr-libc, in der Libary [http://www.nongnu.org/avr-libc/user-manual/group__avr__stdlib.html&#039;&#039;stdlib.h&#039;&#039;].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
  #include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
  char Buffer[20];&lt;br /&gt;
  int i = 25;&lt;br /&gt;
&lt;br /&gt;
  itoa( i, Buffer, 10 );&lt;br /&gt;
  lcd_string( Buffer ); // ggf. auch lcd_out() o.ä. in anderen Libraries&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;itoa( i, Buffer, 10 );&amp;lt;/b&amp;gt; - Die Zahl i wird nach ASCII gewandelt und die String Repräsentierung davon wird in Buffer abgelegt. Die Basis, in der diese Wandlung erfolgt, ist das 10-er System. Wird das dritte Argument von 10 in zb. 2 oder auch 16 abgewandelt, erhält man die binäre oder eben eine hexadezimale Repräsentierung des Wertes. Auch wenn 10, 2 und 16 die häufigsten Angaben an dieser Stelle sind, kann itoa aber grundsätzlich in jedes beliebige Zahlensystem wandlen.&lt;br /&gt;
&lt;br /&gt;
Wichtig ist, darauf zu achten, dass das Array &amp;lt;i&amp;gt;Buffer&amp;lt;/i&amp;gt; groß genug dimensioniert wird, um alle Zeichen der Textrepräsentation der Zahl aufzunehmen - inklusive der 0, die den String abschließt, sowie ein mögliches Vorzeichen.&lt;br /&gt;
&lt;br /&gt;
Anzumerken bleibt weiter, dass es normalerweise für alle Datentypen entsprechende Umwandlungsfunktionen gibt, wenn es sie für einen Datentyp gibt. Die Namensgebung lehnt sich an das Schema an: &#039;&#039;Kürzel_für_den_Datentyp to a&#039;&#039;. Eine Funktion die einen unsigned int wandelt, heißt dann utoa (oder _utoa), Floating Point heißt dann ftoa (oder _ftoa), etc.&lt;br /&gt;
&lt;br /&gt;
===sprintf()===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
  char Buffer[20];&lt;br /&gt;
  int i = 25;&lt;br /&gt;
&lt;br /&gt;
  sprintf( Buffer, &amp;quot;%d&amp;quot;, i );&lt;br /&gt;
  lcd_string( Buffer ); // ggf. auch lcd_out() o.ä. in anderen Libraries&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Methode funktioniert auch bei long oder float Werten. Unbedingt beachtet werden muss allerdings, dass die Typkennzeichnungen im sog. Format-String (hier &amp;quot;%d&amp;quot;) mit den tatsächlichen Typen der auszugebenden Werten übereinstimmt. Und dass der Buffer, der den Text aufnimmt, auch groß genug dimensioniert wird. Dabei sollte die 0, die den String terminiert, nicht vergessen werden.&lt;br /&gt;
&lt;br /&gt;
Mit sprintf() hat man dieselben Möglichkeiten zur Formatierung wie bei &amp;lt;b&amp;gt;printf()&amp;lt;/b&amp;gt; (siehe unten). Insbesondere gibt es natürlich die Möglichkeit die Zahl gleich in einen umgebenden Text einzubetten bzw. Formatierungen anzugeben:&lt;br /&gt;
  &lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
  char Buffer[20];&lt;br /&gt;
  int i = 25;&lt;br /&gt;
&lt;br /&gt;
  sprintf( Buffer, &amp;quot;Anzahl: %d Stueck&amp;quot;, i );&lt;br /&gt;
  lcd_out( Buffer );&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der &amp;quot;Haken&amp;quot; an der mächtigen Funktion sprintf() ist, daß sie auch bei minimalisierter Konfiguration verhältnismäßig viel Programmspeicher (Flash-ROM) belegt und relativ viel Prozesszeit benötigt. Daher sollte man sprintf() nur verwenden, wenn kein Speicher- und Prozesszeitmangel besteht. Sonst sollte itoa() oder eine eigene, auf die Bedürfnisse optimierte Implementierung auf jeden Fall vorgezogen werden.&lt;br /&gt;
&lt;br /&gt;
====Formatierungen mit printf====&lt;br /&gt;
&lt;br /&gt;
Für jedes auszugebende Argument muss es im Formatstring einen entsprechenden Formatbezeichner geben. Der Aufbau eines Formatbezeichners ist immer&lt;br /&gt;
&lt;br /&gt;
  %[Modifizierer][Feldbreite][.Präzision]Typ&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Typ&amp;lt;/b&amp;gt; ist dabei eine Kennung, der mit dem Datentyp des jeweiligen auszugebenden Argumentes übereinstimmen muss. Einige oft benutzte Kennungen, ohne Anspruch auf Vollständigkeit, sind:&lt;br /&gt;
  &amp;lt;b&amp;gt;c&amp;lt;/b&amp;gt;    char&lt;br /&gt;
  &amp;lt;b&amp;gt;d&amp;lt;/b&amp;gt;    int&lt;br /&gt;
  &amp;lt;b&amp;gt;f&amp;lt;/b&amp;gt;    float, double&lt;br /&gt;
  &amp;lt;b&amp;gt;ld&amp;lt;/b&amp;gt;   long&lt;br /&gt;
  &amp;lt;b&amp;gt;u&amp;lt;/b&amp;gt;    unsigned int&lt;br /&gt;
  &amp;lt;b&amp;gt;lu&amp;lt;/b&amp;gt;   unsigned long&lt;br /&gt;
  &amp;lt;b&amp;gt;p&amp;lt;/b&amp;gt;    pointer&lt;br /&gt;
  &amp;lt;b&amp;gt;s&amp;lt;/b&amp;gt;    string&lt;br /&gt;
  &amp;lt;b&amp;gt;x&amp;lt;/b&amp;gt;    ein int wird ausgegeben, die Ausgabe erfolgt&lt;br /&gt;
       aber als Hexadezimalzahl&lt;br /&gt;
  &amp;lt;b&amp;gt;X&amp;lt;/b&amp;gt;    ein int wird ausgegeben, die Ausgabe erfolgt&lt;br /&gt;
       aber als Hexadezimalzahl, wobei Grossbuchstaben verwendet werden&lt;br /&gt;
&lt;br /&gt;
Der&#039;&#039;Modifizierer&#039;&#039; bestimmt, wie und womit nicht benutzte Felder des Ausgabefeldes gefüllt werden sollen, wie die Ausrichtung innerhalb des Feldes erfolgen soll und ob ein Vorzeichen auch dann ausgegeben werden soll wenn die auszugebende Zahl positiv ist. Wird kein Modifizierer angegeben, so werden nicht benutzte Felder mit einem Leerzeichen gefüllt, positive Vorzeichen unterdrückt und die Ausgabe im Feld rechts ausgerichtet.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;b&amp;gt;+&amp;lt;/b&amp;gt;    Vorzeichen wird immer ausgegeben&lt;br /&gt;
  &amp;lt;b&amp;gt;-&amp;lt;/b&amp;gt;    Die Ausgabe wird im Ausgabefeld linksbündig ausgerichtet&lt;br /&gt;
  &amp;lt;b&amp;gt;0&amp;lt;/b&amp;gt;    anstelle von Leerzeichen werden führende 0-en ausgegeben&lt;br /&gt;
&lt;br /&gt;
Die &#039;&#039;Feldbreite&#039;&#039; gibt die Breite des Ausgabefeldes an, in die die Ausgabe durchgeführt werden soll. Reicht die angegebene Feldbreite nicht aus, so vergrößert printf diese Breite eigenmächtig. Die Feldbreite muß nicht angegeben werden. In diesem Fall bestimmt printf selbst die Feldbreite, so dass die Ausgabe darin Platz findet. Mit der Feldbreite hat man eine simple Möglichkeit dafür zu sorgen, dass der erzeugte String immer eine konstante Länge hat, selbst wenn die auszugebende Zahl diese Länge gar nicht benötigen würde (wichtig zb. bei Tabellen).&lt;br /&gt;
&lt;br /&gt;
Die &#039;&#039;Präzision&#039;&#039; kommt nur bei float oder double Zahlen zum Einsatz. Sie legt fest, wieviele Positionen der kompletten Feldbreite für die Ausgabe von Nachkommastellen reserviert werden sollen. Auch sie muss wiederrum nicht angegeben werden und printf benutzt in so einem Fall Standardvorgaben.&lt;br /&gt;
&lt;br /&gt;
===== Beispiele =====&lt;br /&gt;
;&amp;lt;tt&amp;gt;&amp;quot;%d&amp;quot;&amp;lt;/tt&amp;gt;: Ausgabe eines Integer&lt;br /&gt;
;&amp;lt;tt&amp;gt;&amp;quot;%5d&amp;quot;&amp;lt;/tt&amp;gt;: Ausgabe eines Integer in einem Feld mit 5 Zeichen Breite&lt;br /&gt;
;&amp;lt;tt&amp;gt;&amp;quot;%05d&amp;quot;&amp;lt;/tt&amp;gt;: Ausgabe eines Integer in einem Feld mit 5 Zeichen Breite, wobei das Feld links mit führenden Nullen auf 5 Zeichen aufgefüllt wird&lt;br /&gt;
;&amp;lt;tt&amp;gt;&amp;quot;%-5d&amp;quot;&amp;lt;/tt&amp;gt;: Ausgabe eines Integer in einem Feld mit 5 Zeichen Breite. Die Zahl wird linksbündig in das Feld gestellt.&lt;br /&gt;
;&amp;lt;tt&amp;gt;&amp;quot;%6.3f&amp;quot;&amp;lt;/tt&amp;gt;: Ausgabe eines float (oder double). Die Ausgabe erfolgt in einem Feld mit 6 Zeichen Breite, wobei 3 Nachkommastellen ausgegeben werden. Achtung: In der Feldbreite ist auch ein eventuelles Vorzeichen sowie der Dezimalpunkt enthalten. Bei einer Feldbreite von 6 Zeichen und 3 Nachkommastellen, bleiben bei einer positiven Zahl daher nur 2 Positionen für den Vorkommaanteil, bei negativen sogar nur 1 Stelle (6 - 3 Nachkommastellen - 1 Dezimalpunkt - 1 Vorzeichen = 1)&lt;br /&gt;
&lt;br /&gt;
===Eigene Umwandlungsfunktionen===&lt;br /&gt;
&lt;br /&gt;
Möchte man &amp;lt;b&amp;gt;itoa()&amp;lt;/b&amp;gt; nicht benutzen oder hat es gar auf seinem System nicht zur Verfügung, dann ist es auch nicht schwer, sich selbst eine Funktion dafür zu schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
void ItoA( int z, char* Buffer )&lt;br /&gt;
{&lt;br /&gt;
  int i = 0;&lt;br /&gt;
  int j;&lt;br /&gt;
  char tmp;&lt;br /&gt;
  unsigned u;    // In u bearbeiten wir den Absolutbetrag von z.&lt;br /&gt;
  &lt;br /&gt;
    // ist die Zahl negativ?&lt;br /&gt;
    // gleich mal ein - hinterlassen und die Zahl positiv machen&lt;br /&gt;
    if( z &amp;lt; 0 ) {&lt;br /&gt;
      Buffer[0] = &#039;-&#039;;&lt;br /&gt;
      Buffer++;&lt;br /&gt;
      // -INT_MIN ist idR. größer als INT_MAX und nicht mehr &lt;br /&gt;
      // als int darstellbar! Man muss daher bei der Bildung &lt;br /&gt;
      // des Absolutbetrages aufpassen.&lt;br /&gt;
      u = ( (unsigned)-(z+1) ) + 1; &lt;br /&gt;
    }&lt;br /&gt;
    else { &lt;br /&gt;
      u = (unsigned)z;&lt;br /&gt;
    }&lt;br /&gt;
    // die einzelnen Stellen der Zahl berechnen&lt;br /&gt;
    do {&lt;br /&gt;
      Buffer[i++] = &#039;0&#039; + u % 10;&lt;br /&gt;
      u /= 10;&lt;br /&gt;
    } while( u &amp;gt; 0 );&lt;br /&gt;
&lt;br /&gt;
    // den String in sich spiegeln&lt;br /&gt;
    for( j = 0; j &amp;lt; i / 2; ++j ) {&lt;br /&gt;
      tmp = Buffer[j];&lt;br /&gt;
      Buffer[j] = Buffer[i-j-1];&lt;br /&gt;
      Buffer[i-j-1] = tmp;&lt;br /&gt;
    }&lt;br /&gt;
    Buffer[i] = &#039;\0&#039;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Grundprinzip ist einfach:&amp;lt;br&amp;gt;&lt;br /&gt;
Die Ermittlung der einzelnen Stellen erfolgt in der zentralen Schleife&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
    do {&lt;br /&gt;
      Buffer[i++] = &#039;0&#039; + u % 10;&lt;br /&gt;
      u /= 10;&lt;br /&gt;
    } while( u &amp;gt; 0 );&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
durch fortgesetzte Division durch 10 und Restbildung.&lt;br /&gt;
&lt;br /&gt;
    8392&lt;br /&gt;
&lt;br /&gt;
    8392 % 10           -&amp;gt; &amp;lt;b&amp;gt;2&amp;lt;/b&amp;gt;&lt;br /&gt;
    8392 / 10  -&amp;gt; 839&lt;br /&gt;
&lt;br /&gt;
     839 % 10           -&amp;gt; &amp;lt;b&amp;gt;9&amp;lt;/b&amp;gt;&lt;br /&gt;
     839 / 10  -&amp;gt; 83&lt;br /&gt;
&lt;br /&gt;
      83 % 10           -&amp;gt; &amp;lt;b&amp;gt;3&amp;lt;/b&amp;gt;&lt;br /&gt;
      83 / 10  -&amp;gt; 8&lt;br /&gt;
&lt;br /&gt;
       8 % 10           -&amp;gt; &amp;lt;b&amp;gt;8&amp;lt;/b&amp;gt;&lt;br /&gt;
       8 / 10  -&amp;gt; 0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nur leider erhält man dadurch die einzelnen Ziffern der Zahl in umgekehrter Reihenfolge im String (&#039;2&#039; &#039;9&#039; &#039;3&#039; &#039;8&#039; anstelle von &#039;8&#039; &#039;3&#039; &#039;9&#039; &#039;2&#039;). Dies ist aber kein Problem, die nachfolgende Schleife&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
  for( j = 0; j &amp;lt; i / 2; ++j ) {&lt;br /&gt;
    tmp = Buffer[j];&lt;br /&gt;
    Buffer[j] = Buffer[i-j-1];&lt;br /&gt;
    Buffer[i-j-1] = tmp;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
spiegelt den String in sich, sodass danach der String eine korrekte Repräsentation der ursprünglichen Zahl darstellt. Der Funktionsteil vor der &#039;Zerlegeschleife&#039; behandelt den Sonderfall daß die Zahl negativ ist. Negative Zahlen werden behandelt indem im Endergebnis ein &#039;-&#039; vermerkt wird und danach die Zahl positiv gemacht wird.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Siehe auch:&lt;br /&gt;
* Forenbeitrag [http://www.mikrocontroller.net/topic/67405#541885 Integer-Zahl in String mit bestimmter Zeichenlänge]&lt;br /&gt;
* Forenbeitrag [http://www.mikrocontroller.net/topic/84005#704736 (Resourcenschonend) Wert einer Variable am LCD ausgeben] von Niels Hüsken &lt;br /&gt;
* [[Festkommaarithmetik]]&lt;br /&gt;
&lt;br /&gt;
=Datentypen in Operationen=&lt;br /&gt;
Ein häufiges Problem betrifft die Auswertung von Ausdrücken. Konkret die Frage nach den beteiligten Datentypen.&lt;br /&gt;
zb&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
double i;&lt;br /&gt;
int j, k;&lt;br /&gt;
&lt;br /&gt;
i = j / k;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
Die Frage lautet dann: Warum erhalte ich keine Kommastellen, ich weise doch das Ergebnis einem double zu?&lt;br /&gt;
&lt;br /&gt;
Dazu ist zu sagen, dass C nicht so funktioniert. Die Tatsache dass i eine double Variable ist, ist für die Auswahl der Operation, welche die Division durchführt, völlig irrelevant. C orientiert sich ausschliesslich an den &lt;br /&gt;
Datentypen der beteiligten Operanden, um zu entscheiden ob die Division als Integer- oder als Gleitkommadivision durchzuführen ist. Und da sowohl j als auch k ein Integer sind, wird die Division als Integerdivision durchgeführt&lt;br /&gt;
unabhängig davon, was mit dem Ergebnis weiter passiert. Erst nach der Division wird das Ergebnis in einen double überführt, um es an i zuweisen zu können. Zu diesem Zeitpunkt gibt es aber keine Kommastellen mehr, eine Integerdivision erzeugt keine. Und damit tauchen klarerweise auch im Ergebnis keine auf.&lt;br /&gt;
&lt;br /&gt;
Aus genau diesem Grund ist zb das Ergebnis von&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
double i;&lt;br /&gt;
i = 5 / 8;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
eine glatte 0 und nicht 0.625. Die Division 5 / 8 wird als Integer Division gemacht und liefert als solche keine Nachkommastellen. Wird das Ergebnis der Division in einen double umgewandelt, um es an i zuweisen zu können, ist das Kind schon in den Brunnen gefallen: Die Nachkommastellen sind schon längst weg bzw. waren nie vorhanden.&lt;br /&gt;
&lt;br /&gt;
Will man den Compiler dazu zwingen, die Division als Gleitkommadivision durchzuführen, so muss man daher dafür sorgen, dass mindestens einer der beteiligten Operanden ein double Wert ist. Dann bleibt dem Compiler nichts anderes übrig, als auch den zweiten Operanden ebenfalls zu einem double zu machen und die Operation als Gleitkommaoperation durchzuführen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
double i;&lt;br /&gt;
i = 5.0 / 8.0;&lt;br /&gt;
&lt;br /&gt;
i = (double)j / k;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generell implementiert der Compiler eine Operation immer im &#039;höchsten&#039; Datentyp, der in dieser Operation vorkommenden Operanden. Operanden in einem &#039;niedrigeren&#039; Datentyp werden automatisch immer in diesen &#039;höchsten&#039; Datentyp umgewandelt, zumindest aber int. Die Reihung orientiert sich dabei an der Regel: Ein &#039;höherer&#039; Datentyp kann alle Werte eines &#039;niedrigeren&#039; Datentyps aufnehmen.&lt;br /&gt;
&lt;br /&gt;
    int&lt;br /&gt;
    unsigned int&lt;br /&gt;
    long&lt;br /&gt;
    unsigned long&lt;br /&gt;
    long long&lt;br /&gt;
    unsigned long long&lt;br /&gt;
    double&lt;br /&gt;
    &lt;br /&gt;
float kommt in dieser Tabelle gar nicht vor, da Gleitkommaoperationen grundsätzlich immer als double-Operationen durchgeführt werden. Wohl kann es aber sein, dass double und float dieselbe Anzahl an Bits benutzen. Damit reduziert sich eine double Operation effektiv auf eine float Operation. (Anmerkung: mit dem C99-Standard hat sich dieses geändert. Dort gibt es dann auch echte float Operationen)&lt;br /&gt;
&lt;br /&gt;
Hat man also in einer Operation 2 Operanden der Datentypen int und long, so wird der int implizit zu einem long gemacht und die Operation als long Operation durchgeführt. Das Ergebnis hat dann den Datentyp long.&lt;br /&gt;
&lt;br /&gt;
==Welche Datentypen haben Konstante?==&lt;br /&gt;
&lt;br /&gt;
Auch Zahlenkonstante besitzen einen Datentyp, der selbstverständlich vom Compiler bei der Auswahl der Operation berücksichtigt wird. Hier gilt die Regel: Benutzt wird der Datentyp, der die Zahl gerade noch aufnehmen kann. Eine Zahlenkonstante 5 hat daher den Datentyp int. Die Zahl 32767 passt gerade noch in einen int, und hat daher den Datentyp int. 32768 ist für einen int bereits zu groß und hat daher den Datentyp long. 5.0 ist hingegem immer eine double-Konstante. Der Dezimalpunkt erzwingt dieses.&lt;br /&gt;
&lt;br /&gt;
Eine kleine Feinheit gibt es noch zu beachten. Konstanten in dezimaler Schreibweise haben immer einen signed Datentyp, während Konstante in hexadezimaler bzw. oktaler Schreibweise immer einen unsigned Datentyp haben.&lt;br /&gt;
&lt;br /&gt;
Möchte man einer Konstanten einen bestimmten Datentyp aufzwingen, so gibt es dazu 2 (ein halb) Möglichkeiten:&lt;br /&gt;
* Entweder man castet die Konstante in den gewünschten Datentyp&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
   (long)5&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
* oder man benutzt die in C dafür vorgesehene Schreibweise, indem man der Konstanten einen Suffix anhängt, der den gewünschten Datentyp beschreibt&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
    5L&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
Beides ergibt eine dezimale 5, die vom Datentyp long ist.&lt;br /&gt;
&lt;br /&gt;
* eine Zahl in mit einem Dezimalkomma&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
    5.0&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
ist immer eine double Zahl. Es sei denn sie hat explizit eien Suffix&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
    5.0F&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
dann hat man es mit einer float Zahl zu tun.&lt;br /&gt;
&lt;br /&gt;
Die gültigen Suffixe für Zahlen sind U, L, UL und F:&lt;br /&gt;
&lt;br /&gt;
* U wie unsigned; dabei wird zuerst int angenommen. Es erfolgt eine automatische Ausweitung auf long, wenn die Zahl den Wertebereich eines unsigned int überschreitet. &lt;br /&gt;
* L wie long; die Zahl selbst kann int oder double sein.&lt;br /&gt;
* UL wie unsigned long. Eigentlich eine Zusammensetzung aus U und L&lt;br /&gt;
* F wie float.&lt;br /&gt;
&lt;br /&gt;
=Aktivieren der Floating Point Version von sprintf beim WinAVR mit AVR-Studio=&lt;br /&gt;
[[Bild:AVR_Studio_float1.gif|thumb|right|300px|Project → Configuration Options  → Libraries → Available Link Objects]]&lt;br /&gt;
[[Bild:AVR_Studio_float2.gif|thumb|right|300px|Custom Options → Custom Compilation Options → Linker Options]]&lt;br /&gt;
Beim WinAVR/AVR-Studio wird standardmässig eine Version der printf-Bibliothek verwendet, die keine Floatingpoint-Verarbeitung unterstützt. Die meisten Programme benötigen keine Floatingpoint-Unterstützung, so dass dadurch wertvoller Programmspeicherplatz gespart werden kann.&lt;br /&gt;
&lt;br /&gt;
Benutzt man allerdings eine printf-Variante für die Ausgabe von Floatingpoint-Zahlen, so erscheint an Stelle der korrekt formatierten Zahl lediglich ein &#039;?&#039;. Dies ist ein Indiz dafür, dass die Floatingpoint-Verarbeitung im Projekt aktiviert werden muss.&lt;br /&gt;
&lt;br /&gt;
Um die Floatingpoint-Verarbeitung zu aktivieren, geht man im &#039;&#039;&#039;AVR Studio 4&#039;&#039;&#039; wie folgt vor: &lt;br /&gt;
* Menüpunkt: &#039;&#039;Project → Configuration Options&#039;&#039;&lt;br /&gt;
* Im sich öffnenden Dialog wird in der linken Navigationsleiste der Eintrag &#039;&#039;Libraries&#039;&#039; ausgewählt.&lt;br /&gt;
* Unter &#039;&#039;Available Link Objects&#039;&#039; werden Bibliotheken angeboten. Für die Aktivierung der Floatingpoint-Unterstützung sind 2 interessant&amp;lt;ref&amp;gt;&amp;lt;tt&amp;gt;libc.a&amp;lt;/tt&amp;gt; sollte nicht zu den Bibliotheken hinzugefügt werden, da sie automatisch eingebunden wird. Etwas Hintergrundinformationen gibt es in [http://www.mikrocontroller.net/topic/173630 diesem Thread.]&lt;br /&gt;
&amp;lt;/ref&amp;gt;:&lt;br /&gt;
** &amp;lt;tt&amp;gt;libprintf_flt.a&amp;lt;/tt&amp;gt;&lt;br /&gt;
** &amp;lt;tt&amp;gt;libm.a&amp;lt;/tt&amp;gt;&lt;br /&gt;
* Beide Bibliotheken werden durch Aktivieren und einen Druck auf &#039;&#039;Add Library → &#039;&#039; in die rechte Spalte übernommen.&lt;br /&gt;
* Danach wählt man in der Navigationsleiste den Eintrag &#039;&#039;Custom Options&#039;&#039;.&lt;br /&gt;
* Unter &#039;&#039;Custom Compilation Options&#039;&#039; wird &#039;&#039;Linker Options&#039;&#039; ausgewählt und in das Textfeld rechts/unten folgender Text eingetragen:&lt;br /&gt;
         -Wl,-u,vfprintf&lt;br /&gt;
* Ein Druck auf &#039;&#039;Add&#039;&#039; befördert die Zeile in das Listenfeld darüber, welches Optionen für den Linker enthält.&lt;br /&gt;
* Mit &#039;&#039;OK&#039;&#039; wird die Konfiguration abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Bei &#039;&#039;&#039;AVR Studio 5&#039;&#039;&#039; trägt man die Optionen an anderen Stellen ein ([http://www.mikrocontroller.net/topic/221583#2219612 Beitrag von Hal Smith]): &lt;br /&gt;
*&#039;&#039;Project Properties → Toolchain → AVR/GNU C-Linker → Libraries&#039;&#039;&amp;lt;br/&amp;gt;In &#039;&#039;Libraries&#039;&#039; &amp;lt;tt&amp;gt;(-WI, -I), libprintf_flt.a libm.a&amp;lt;/tt&amp;gt; eintragen.&lt;br /&gt;
* &#039;&#039;Project Properties → Toolchain → AVR/GNU C-Linker → Miscellaneous&#039;&#039;&amp;lt;br/&amp;gt;In &#039;&#039;Other Linker Flags&#039;&#039; &amp;lt;tt&amp;gt;-Wl,-u,vfprintf&amp;lt;/tt&amp;gt; eintragen.&lt;br /&gt;
{{Absatz}}&lt;br /&gt;
&lt;br /&gt;
= Wie funktioniert String-Verarbeitung in C? =&lt;br /&gt;
: → Siehe: &#039;&#039;[[String-Verarbeitung in C]]&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
= Funktionszeiger =&lt;br /&gt;
&lt;br /&gt;
: → Siehe: &#039;&#039;[[Funktionszeiger in C]]&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
= Ich hab da mehrere *.c und *.h Dateien. Was mache ich damit? =&lt;br /&gt;
&lt;br /&gt;
[[Bild:c-flow.svg|right|thumb|260px|C-Programmierung: Workflow]]&lt;br /&gt;
Zunächst ist es wichtig, sich zu vergegenwärtigen, wie C-Compiler und Linker zusammenarbeiten. Ein komplettes Programmier-Projekt kann und wird im Normalfall aus mehreren Quelldateien bestehen, die alle zusammengenommen das komplette Programm bilden.&lt;br /&gt;
&lt;br /&gt;
Der Prozess des Erstellens des Programmes geschieht in mehrerern Schritten:&lt;br /&gt;
;Compilieren: zunächst werden alle Einzelteile (jede *.c Datei) für sich &#039;&#039;compiliert&#039;&#039;. Dabei ensteht aus jeder c-Datei eine sogenannte Object-Datei, in der bereits der Maschinencode für die im c-File programmierten Funktionen enthalten ist&lt;br /&gt;
;Linken: die einzelnen Object-Dateien werdenmit zusätzlichen Bibliotheken und dem Startup-Code zum fertigen Programm &#039;&#039;gelinkt&#039;&#039;.&lt;br /&gt;
{{Absatz}}&lt;br /&gt;
Angenommen, das komplette Projekt besteht aus 2 Dateien:&lt;br /&gt;
&lt;br /&gt;
;main.c:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
int twice (int);&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  twice (5);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;func.c:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
int twice (int number)&lt;br /&gt;
{&lt;br /&gt;
  return 2 * number;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dann werden &amp;lt;tt&amp;gt;main.c&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;func.c&amp;lt;/tt&amp;gt; &#039;&#039;unabhängig&#039;&#039; voneinander compiliert. Als Ergebnis erhält man die Dateien &amp;lt;tt&amp;gt;main.o&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;func.o&amp;lt;/tt&amp;gt;, die den besagten Object-Code enthalten.&lt;br /&gt;
Diese beiden Zwischenergebnisse werden dann zusammen mit Bibliotheken zum fertigen Programm gebunden (gelinkt), das dann ausgeführt werden kann.&lt;br /&gt;
&lt;br /&gt;
Bekommt man also von irgendwo bereits fertige *.c (und zugehörige *.h) Dateien, so genügt es, die *.c Dateien in das Projekt mit aufzunehmen. Dadurch wird das entsprechende C-File compiliert und das Ergebnis davon, das Object-file, wird dann in das fertige Programm mit eingelinkt.&lt;br /&gt;
&lt;br /&gt;
;Achtung: Da jede der C-Dateien unabhängig von allen anderen compiliert wird, bedeutet das auch, dass jede der C-Dateien in sich vollständig sein muss!&lt;br /&gt;
&lt;br /&gt;
Wie eine C-Datei in das Projekt mit aufgenommen wird, hängt im wesentlichen von der benutzten Entwicklungsumgebung ab.&lt;br /&gt;
&lt;br /&gt;
== Makefile ==&lt;br /&gt;
&lt;br /&gt;
Die zusätzliche *.c Datei wird in die SRC Zeile im makefile eingetragen.&lt;br /&gt;
&lt;br /&gt;
== AVR-Studio ==&lt;br /&gt;
&lt;br /&gt;
Hier ist es besonders einfach, eine Datei in das Projekt mit aufzunehmen. Dazu wird im Projektbaum der Knoten &amp;quot;Source Files&amp;quot; aktiviert und mit der rechten Maustaste das Kontextmenü geöffnet. Im Menü wird der Punkt &amp;quot;Add existing Source File(s)&amp;quot; ausgewählt, und anschliessend zeigt man AVR-Studio das zusätzliche C-File. AVR-Studio berücksicht dann diese Datei bei der Projekterzeugung, compiliert es und sorgt dafür, daß es zum fertigen Programm dazugelinkt wird.&lt;br /&gt;
&lt;br /&gt;
=Globale Variablen über mehrere Dateien=&lt;br /&gt;
Ein häufiger Problemkreis in der C Programmierung sind auch globale Variablen, die von mehreren *.c Dateien aus benutzt werden sollen. Was hat es damit auf sich?&lt;br /&gt;
&lt;br /&gt;
Zunächst mal muß man bei der Vereinbarung von Variablen zwischen &#039;&#039;Definition&#039;&#039; und &#039;&#039;Deklaration&#039;&#039; unterscheiden:&lt;br /&gt;
;Definition: Mit einer Definition wird der Compiler angewiesen, eine Variable tatsächlich zu erzeugen. Damit er das kann, muß ihm selbstverständlich der exakte Datentyp und auch der Name der Variablen zur Verfügung stehen. Eine Definition sorgt also dafür, dass im späteren Programm Speicherplatz für diese Variable reserviert wird&lt;br /&gt;
;Deklaration: Mit einer Deklaration teilt man dem Compiler lediglich mit, dass eine Variable existiert. An dieser Stelle soll der Compiler also keinen Speicherplatz reservieren, sondern der Compiler soll einfach nur zur Kenntniss nehmen, daß es eine Variable mit einem bestimmten Namen gibt und von welchem Datentyp sie ist.&lt;br /&gt;
&lt;br /&gt;
Aus obigem folgt sofort, dass eine Definition auch immer eine Deklaration ist. Denn dadurch, daß der Compiler angewiesen wird eine Variable auch tatsächlich zu erzeugen, folgt, dass er dazu auch dieselben Informationen benötigt, die auch in einer Deklaration angegeben werden müssen. Der einzige Unterschied: Bei einer Deklaration trägt der Compiler nur in seinen internen Tabellen ein, dass es diese Variable tatsächlich gibt, während er bei einer Definition zusätzlich auch noch dafür sorgt, dass im fertigen Programm auch Speicher für diese Variable bereitgestellt wird.&lt;br /&gt;
&lt;br /&gt;
Warum ist diese Unterscheidung wichtig?&lt;br /&gt;
&lt;br /&gt;
Weil es in C die sog. &#039;&#039;One Definition Rule&#039;&#039; (ODR). Sie besagt, dass in einem vollständigen Programm, also über alle *.c Dateien gesehen, es für eine Variable nur &amp;lt;b&amp;gt;eine&amp;lt;/b&amp;gt; Definition geben darf. Es darf allerdings beliebig viele Deklarationen geben, solange diese Deklarationen alle im Datentyp übereinstimmen. Kurz gesagt: Man darf den Compiler nur einmal auffordern, eine Variable zu erzeugen (Definition), kann sich aber beliebig oft auf diese eine Variable beziehen (Deklarationen). Aber Vorsicht! Da der Compiler jede einzelne *.c Datei für sich alleine übersetzt und dabei kein Wissen von ausserhalb benutzt, obliegt es der Verantwortung des Programmierers dafür zu sorgen, dass alle Deklarationen im Datentyp übereinstimmen. Der Compiler kann diese Einhaltung prinzipbedingt nicht überwachen!&lt;br /&gt;
&lt;br /&gt;
Woran erkennt man eine Definition bzw. Deklaration?&lt;br /&gt;
&lt;br /&gt;
Eine Definition einer globalen Variable steht immer ausserhalb eines Funktionsblocks. Zb.&lt;br /&gt;
&amp;lt;C&amp;gt;&lt;br /&gt;
int  MyData;         // Globale Variable namens MyData. Sie ist vom Typ int&lt;br /&gt;
char Name[30];       // Globales Array&lt;br /&gt;
long NrElements = 5; // Globale Variable, die auch noch initialisiert wird&lt;br /&gt;
&amp;lt;/C&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Deklaration unterscheidet sich von einer Definition in 2 Punkten&lt;br /&gt;
* Es wird das Schlüsselwort &amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt; vorangestellt.&lt;br /&gt;
* Es kann keine Initialisierung geben. Sobald eine Initialisierung vorhanden ist, wird das Schlüsselwort &amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt; ignoriert und aus der Deklaration wird eine Definition.&lt;br /&gt;
&lt;br /&gt;
Beispiele für Deklarationen&lt;br /&gt;
&amp;lt;C&amp;gt;&lt;br /&gt;
extern int  MyData;&lt;br /&gt;
extern char Name[30];&lt;br /&gt;
extern long NrElements;&lt;br /&gt;
extern long NrElements = 5;  // Achtung: Dies ist eine Definition!&lt;br /&gt;
&amp;lt;/C&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Besitzt man also 2 *.c Dateien, main.c und helpers.c, und sollen sich diese beiden Dateien eine globale Variable teilen, so muss in eine Datei eine Definition hinein, während in die andere Datei eine Deklaration derselben Variablen erfolgen muß. Traditionell werden die Definitionen in der *.c-Datei gemacht, die als Hauptdatei des Moduls fungiert, zu der diese Variable konzeptionell gehört. Im Zweifel ist das die *.c Datei, in der main() enthalten ist. Das muss nicht so sein, ist aber eine Konvention, die oft Sinn macht. Alternativ wird auch gerne oft eine eigene *.c Datei (zb. globals.c) gemacht, die einzig und alleine die Defintionen der globalen Variablen enthält.&lt;br /&gt;
&lt;br /&gt;
main.c&lt;br /&gt;
&amp;lt;C&amp;gt;&lt;br /&gt;
int  AnzahlElemente;        // Dies ist die Definition. Hier wird die globale&lt;br /&gt;
                            // Variable AnzahlElemente tatsächlich erzeugt.&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  AnzahlElemente = 8;&lt;br /&gt;
  ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/C&amp;gt;&lt;br /&gt;
&lt;br /&gt;
helpers.c&lt;br /&gt;
&amp;lt;C&amp;gt;&lt;br /&gt;
extern int AnzahlElemente;   // Dies ist die Deklaration die auf die globale&lt;br /&gt;
                             // Variable AnzahlElemente in main.c verweist.&lt;br /&gt;
                             // Wichtig: Der Datentyp muss mit dem in main.c&lt;br /&gt;
                             // angegebenen übereinstimmen&lt;br /&gt;
&lt;br /&gt;
void foo()&lt;br /&gt;
{&lt;br /&gt;
   ...&lt;br /&gt;
  j = AnzahlElemente;&lt;br /&gt;
  AnzahlElemente = 9;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/C&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Praktische Durchführung==&lt;br /&gt;
Besteht ein vollständiges Programm aus mehreren *.c Dateien, dann kann man sich vorstellen, daß es mühsam ist, alle Deklarationen immer auf gleich zu halten. Hier bietet sich der Einsatz eines Header Files an, in der die Deklarationen stehen und welches in die jeweiligen *.c Dateien inkludiert wird&lt;br /&gt;
&lt;br /&gt;
Bsp:&lt;br /&gt;
&lt;br /&gt;
Global.h&lt;br /&gt;
&amp;lt;C&amp;gt;&lt;br /&gt;
extern int Anzahl;&lt;br /&gt;
&amp;lt;/C&amp;gt;&lt;br /&gt;
&lt;br /&gt;
main.c&lt;br /&gt;
&amp;lt;C&amp;gt;&lt;br /&gt;
#include &amp;quot;Global.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int Anzahl;      // auch wenn Global.h inkludiert wurde, so muss es eine&lt;br /&gt;
                 // Definition der Variablen geben. In Global.h sind ja nur&lt;br /&gt;
                 // Deklarationen.&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  ...&lt;br /&gt;
  Anzahl = 5;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/C&amp;gt;&lt;br /&gt;
&lt;br /&gt;
foo.c&lt;br /&gt;
&amp;lt;C&amp;gt;&lt;br /&gt;
#include &amp;quot;Global.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
void foo()&lt;br /&gt;
{&lt;br /&gt;
  ...&lt;br /&gt;
  Anzahl = 8;&lt;br /&gt;
  ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/C&amp;gt;&lt;br /&gt;
&lt;br /&gt;
bar.c&lt;br /&gt;
&amp;lt;C&amp;gt;&lt;br /&gt;
#include &amp;quot;Global.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
void bar()&lt;br /&gt;
{&lt;br /&gt;
  ...&lt;br /&gt;
  j = Anzahl;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/C&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auf diese Art kann man erreichen, dass zumindest alle Deklarationen ein und derselben Variablen in einem Programm übereinstimmen. Die Datei Global.h wird auch in main.c inkludiert, obwohl man das eigentlich nicht müsste, denn dort wird die Variable ja definiert. Durch die Inclusion ermöglicht man aber dem Compiler die Überprüfung ob die Deklaration auch tatsächlich mit der Definition übereinstimmt.&lt;br /&gt;
&lt;br /&gt;
Solange kein Initialisierungen der globalen Variablen notwendig sind, gibt es noch einen weiteren Trick, um sich selbst das Leben und die Verwaltung der globalen Variablen zu erleichtern.&lt;br /&gt;
Worin besteht das Problem?&lt;br /&gt;
Das Problem besteht darin, dass man bei Einführung einer neuen globalen Variablen an 2 Stellen erweitern muss: Zum einen in der Header-Datei, die die &#039;extern&#039;-Deklaration der Variablen enthält, zum anderen muss in einer C-Datei die Definition der Variablen erfolgen. Das kann man sich mit etwas Präprozessorarbeit auch einfacher machen:&lt;br /&gt;
&lt;br /&gt;
Global.h&lt;br /&gt;
&amp;lt;C&amp;gt;&lt;br /&gt;
#ifndef EXTERN&lt;br /&gt;
#define EXTERN extern&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
EXTERN int Anzahl;&lt;br /&gt;
&amp;lt;/C&amp;gt;&lt;br /&gt;
&lt;br /&gt;
main.c&lt;br /&gt;
&amp;lt;C&amp;gt;&lt;br /&gt;
#define EXTERN&lt;br /&gt;
#include &amp;quot;Global.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  ...&lt;br /&gt;
  Anzahl = 5;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/C&amp;gt;&lt;br /&gt;
&lt;br /&gt;
foo.c&lt;br /&gt;
&amp;lt;C&amp;gt;&lt;br /&gt;
#include &amp;quot;Global.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
void foo()&lt;br /&gt;
{&lt;br /&gt;
  ...&lt;br /&gt;
  Anzahl = 8;&lt;br /&gt;
  ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/C&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie funktioniert das Ganze? Im Grunde muss man nur dafür sorgen, dass der Compiler an &#039;&#039;einer&#039;&#039; Stelle das Schlüsselwort &#039;&#039;&#039;extern&#039;&#039;&#039; ignoriert (hier in main.c) und bei allen anderen Inclusionen beibehält. Dadurch das ein Präprozessor-ifndef benutzt wird, kann dieses erreicht werden. Wird das Header File includiert und ist zu diesem Zeitpunkt das Makro &#039;&#039;&#039;EXTERN&#039;&#039;&#039; noch nicht definiert, so wird innerhalb des Header Files &#039;&#039;&#039;EXTERN&#039;&#039;&#039; zu &#039;&#039;&#039;extern&#039;&#039;&#039; definiert und damit in weiterer Folge im Quelltext &#039;&#039;&#039;EXTERN&#039;&#039;&#039; durch &#039;&#039;&#039;extern&#039;&#039;&#039; ersetzt. Wenn daher foo.c das Header File inkludiert, wird die Zeile&lt;br /&gt;
&amp;lt;C&amp;gt;&lt;br /&gt;
EXTERN int Anzahl;&lt;br /&gt;
&amp;lt;/C&amp;gt;&lt;br /&gt;
vom Präprozessor zu&lt;br /&gt;
&amp;lt;C&amp;gt;&lt;br /&gt;
extern int Anzahl;&lt;br /&gt;
&amp;lt;/C&amp;gt;&lt;br /&gt;
umgewandelt.&lt;br /&gt;
&lt;br /&gt;
In main.c hingegen sieht die Include-Sequenz so aus&lt;br /&gt;
&amp;lt;C&amp;gt;&lt;br /&gt;
#define EXTERN&lt;br /&gt;
#include &amp;quot;Global.h&amp;quot;&lt;br /&gt;
&amp;lt;/C&amp;gt;&lt;br /&gt;
Wenn Global.h bearbeitet wird, existiert bereits ein Makro &#039;&#039;&#039;EXTERN&#039;&#039;&#039;, das auf einen leeren Text expandiert. Dadurch wird verhindert, dass innerhalb von Global.h das Makro &#039;&#039;&#039;EXTERN&#039;&#039;&#039; mit dem Text &#039;&#039;&#039;extern&#039;&#039;&#039; belegt wird und&lt;br /&gt;
&amp;lt;C&amp;gt;&lt;br /&gt;
EXTERN int Anzahl;&lt;br /&gt;
&amp;lt;/C&amp;gt;&lt;br /&gt;
wird daher vom Präprozessor zu&lt;br /&gt;
&amp;lt;C&amp;gt;&lt;br /&gt;
int Anzahl;&lt;br /&gt;
&amp;lt;/C&amp;gt;&lt;br /&gt;
erweitert, genau wie es benötigt wird.&lt;br /&gt;
&lt;br /&gt;
= Was hat es mit volatile auf sich =&lt;br /&gt;
Immer wieder hört man im Forum die pauschale Aussage &amp;quot;Variablen die in einer ISR verwendet werden, müssen volatile sein&amp;quot;. Nun, das ist so nicht ganz richtig.&lt;br /&gt;
Welches Problem löst denn eigentlich volatile? Was ist denn das eigentliche Problem, das einer Lösung bedarf?&lt;br /&gt;
&lt;br /&gt;
Das Problem findet sich diesmal im Optimierer eines C Compilers. C Compiler übersetzen, wenn sie optimieren dürfen, den C Code nicht direkt so, wie ihn der Programmierer geschrieben hat, sondern sie versuchen Ressourcen einzusparen. Das kann sowohl Programmspeicher als auch Laufzeit, häufig auch beides gemeinsam sein. Zu diesem Zweck untersuchen sie das Programm und versuchen in der funktional gleichwertigen, in Maschinensprache übersetzen Version, Anweisungen einzusparen. Das dürfen sie auch. Der C-Standard erlaubt Optimierungen, solange die &#039;As-If&#039;-Regel eingehalten wird. Das bedeutet: Der Compiler darf das Programm umstellen und verändern, solange die Programmergebnisse dieselben bleiben. Eben &amp;quot;As-if&amp;quot; die Optimierung nie stattgefunden hätte.&lt;br /&gt;
&lt;br /&gt;
Nehmen wir ein Beispiel&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
  i = 2;&lt;br /&gt;
&lt;br /&gt;
  if( i == 5 )&lt;br /&gt;
    j = 8;&lt;br /&gt;
  else&lt;br /&gt;
    j = 6;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
In diesem Programmausschnitt darf der Compiler seine Kenntnisse ausnutzen. Er weiß an dieser Stelle, dass i den Wert 2 hat. Damit ist aber auch klar, dass die Bedingung niemals wahr sein kann, denn 2 kann niemals gleich 5 sein. Wenn die Bedingung aber niemals wahr sein kann, dann kann auch die Zuweisung von 8 an j niemals ausgeführt werden. Der Compiler kann also diesen Programmtext zu diesem hier kürzen&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
  i = 2;&lt;br /&gt;
  j = 6;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
ohne das sich an den Programmergebnissen etwas ändert. Die zweite Version ist aber kürzer und wird, wegen des Wegfalles des Vergleiches, auch schneller ausgeführt.&lt;br /&gt;
&lt;br /&gt;
Eine andere Form der Optimierung betrifft die Verwaltung von µC-Ressourcen und da wieder ganz speziell die Register. Variablen werden ja erst mal im SRAM-Speicher des µC angelegt. Um mit den Werten von Variablen arbeiten zu können, müssen diese Wert aber vom SRAM-Speicher in µC-Register überführt werden (Register kann man sich wie Speicherstellen in der eigentlichen CPU vorstellen). Nur dort können diese Werte mittels Maschinenbefehlen manipuliert werden.&lt;br /&gt;
Jetzt haben aber µC nicht beliebig viele Register. Das bedeutet aber auch, der Compiler muss darüber Buch führen, welche Werte (welche Variablen) gerade in welchen Registern liegen und wenn alle Register belegt sind, muss ein anderes Register freigeräumt werden, in dem der Wert aus dem Register wieder ins SRAM zurück übertragen wird.&lt;br /&gt;
Allerdings kostet das auch Zeit. Der Compiler wird daher versuchen, Variablen, die in einem Programmstück oft benötigt werden, für längere Zeit in den Registern zu halten, um das Registerladen bzw. -zurückschreiben einzusparen. Die Grundannahme lautet dabei immer: In Anweisungen, in denen eine Variable nicht vorkommt, kann diese Variable auch nicht verändert werden. Im Programmstück&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
  while( 1 ) {&lt;br /&gt;
    if( i == 5 )&lt;br /&gt;
      j = 8;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
gibt es für i keine Möglichkeit, verändert zu werden. Der Compiler kann daher entscheiden, dass er diese Variable, *an dieser Stelle*, gar nicht aus dem SRAM laden muss, sondern sich den entsprechenden Wert in einem Register vorhält und dieses Register ausschließlich dafür reserviert. (Er könnte auch entscheiden, dass der Code nie ausgeführt werden kann, aber das ist eine andere Geschichte)&lt;br /&gt;
&lt;br /&gt;
Der springende Punkt ist nun, dass der Compiler hier eine zu kleine Sicht der Dinge hat. Betrachtet man nur dieses Code Stück, dann gibt es tatsächlich für i keine Möglichkeit, seinen Wert zu verändern. Aber die Dinge ändern sich, wenn Interrupts ins Spiel kommen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
int i;&lt;br /&gt;
&lt;br /&gt;
ISR( irgendein_Interrupt )&lt;br /&gt;
{&lt;br /&gt;
  i = 5;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  ...&lt;br /&gt;
&lt;br /&gt;
  while( 1 ) {&lt;br /&gt;
    if( i == 5 )&lt;br /&gt;
      j = 8;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
Jetzt gibt es plötzlich eine Möglichkeit, wie i seinen Wert ändern kann: Wenn der entsprechende Interrupt ausgelöst wird, dann wird i auf den Wert 5 gesetzt. i, das ist aber nichts anderes als ein bestimmter Speicherbereich im SRAM. D.h. im SRAM wird die Variable tatsächlich korrekt auf den Wert 5 gesetzt. Nur: Als der Compiler die while-Schleife übersetzt hat, wusste er nichts davon, dass diese Möglichkeit existiert. Er hat entschieden, dass er an dieser Stelle den Wert der Variablen in einem CPU-Register halten wird, um Zugriffe einzusparen. Nur wird diese Kopie des Wertes im Register natürlich nicht verändert, wenn in der ISR das Original von i im SRAM verändert wird.&lt;br /&gt;
Fazit: Obwohl die ISR die Variable tatsächlich verändert, kriegt das der Code im while nicht mit, weil der Compiler es mit der Optimierung an dieser Stelle übertrieben hat. In der while-Schleife wird mit einer Kopie des Wertes von i in einem Register gearbeitet und nicht mit dem originalen Wert von i im SRAM.&lt;br /&gt;
&lt;br /&gt;
Und an dieser Stelle kommt jetzt volatile ins Spiel.&lt;br /&gt;
&lt;br /&gt;
volatile teilt dem Compiler mit, dass ausnahmslos alle Zugriffe auf eine Variable auch tatsächlich auszuführen sind und keine Optimierungen gemacht werden dürfen, weil sich eine Variable auf Wegen ändern kann, die für den Compiler prinzipiell nicht einsichtig sind. Im obigen Beispiel könnte man argumentieren, dass der Compiler ja wohl die ISR bemerken könne und daher feststellen könnte, dass i tatsächlich verändert wird. Aber das stimmt so in der allgemeinen Form nicht. Niemand sagt, dass der Compiler die ISR überhaupt zu Gesicht bekommen muss, die könnte ja auch in einem ganz anderen C File stecken.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
volatile int i;&lt;br /&gt;
&lt;br /&gt;
ISR( irgendein_Interrupt )&lt;br /&gt;
{&lt;br /&gt;
  i = 5;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  ...&lt;br /&gt;
&lt;br /&gt;
  while( 1 ) {&lt;br /&gt;
    if( i == 5 )&lt;br /&gt;
      j = 8;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
wird i volatile gemacht, so verbietet man damit dem Compiler explizit, Annahmen über den Datenfluss von i zu treffen. Innerhalb der Schleife muss also tatsächlich jedes Mal wieder erneut i aus dem SRAM geholt werden und mit 5 verglichen werden. Abkürzungen durch Mehrfachverwendung von Registern oder sonstigen Optimierungstricks sind nicht erlaubt. Und damit ist das Problem gelöst. Wird i in der ISR verändert, so bekommt das auch die Abfrage mit, weil ja jetzt auf jeden Fall auf das Original im SRAM zurückgegriffen wird.&lt;br /&gt;
&lt;br /&gt;
Ein anderes Problem (das ebenfalls mittels volatile gelöst wird) sind Variablen, die tatsächlich im Code überhaupt nie aktiv verändert werden, sondern es sich um Zusatzhardware handelt, die so verschaltet ist, dass sie im Programm in Form einer Variablen auftaucht, z.B. ein Uhren-IC. In diesem Fall wird z.B. die Variable für Sekunden vom Programm gar nicht vom Programm selber verändert, ändert aber trotzdem ihren Inhalt. Die Zusatzhardware selbst macht das. Aus Programmsicht handelt es sich um Speicherzellen, die magisch selbsttätig ihren Wert ändern.&lt;br /&gt;
Man nennt so etwas memory-mapped, wenn eine externe Hardware in dieser Form im Speicher auftaucht.&lt;br /&gt;
&lt;br /&gt;
= Konstanten an fester Flash-Adresse =&lt;br /&gt;
&lt;br /&gt;
Wie kann man eine Konstante an entsprechender Adresse im Flash ablegen?&lt;br /&gt;
&lt;br /&gt;
Mehmet Kendi hat eine Lösung für [[AVR Studio]] &amp;amp; [[WinAVR]] in &lt;br /&gt;
[http://www.mikrocontroller.net/topic/142704#1453079] angegeben.&lt;br /&gt;
&lt;br /&gt;
= Timer =&lt;br /&gt;
== Was macht ein Timer? ==&lt;br /&gt;
Oft hört man im Forum die Aussage: Timer sind so kompliziert!&lt;br /&gt;
&lt;br /&gt;
Aber eigentlich stimmt das nicht. Ganz im Gegenteil, Timer sind eigentlich eine sehr einfache Sache. Was genau macht eigentlich ein Timer? Die Antwort lautet: er zählt unabhängig vom restlichen Programmfluss vor sich hin. Und? Was macht er noch? Nichts. Das wars schon. Im Kern ist genau das auch schon alles was ein Timer macht.&lt;br /&gt;
[[Bild:Timer_Basis.gif|framed|center|ein 8-Bit Timer bei der Arbeit]]&lt;br /&gt;
&lt;br /&gt;
== Wie schnell macht er es? ==&lt;br /&gt;
Aber so einfach ist die Sache dann doch wieder nicht. Da erhebt sich zunächst mal die Frage: wie schnell zählt denn eigentlich so ein Timer? Normalerweise ist der Timer mit der Taktfrequenz des Prozessors gekoppelt, so dass zb bei einer Taktfrequnz von 1Mhz der Timer auch genau so schnell zählt. In 1 Sekunde zählt ein Timer also von 0 bis 999999, also 1 Mio - 1 Zählschritte. Nun kann aber ein beispielsweise 8-Bit Timer nicht bis 999999 zählen, dazu ist er nicht groß genug. Mit 8 Bit kann man bis 255 zählen. Zählt man da dann noch 1 dazu, dann läuft der Timer über und beginnt wieder bei 0. Man kann daher ruhigen Gewissens sagen: In 1 Sekunde zählt dieser Timer 3906 mal den Bereich von 0 bis 255 (und weiter auf 0) durch (das sind 256 Zählschritte) und zuätzlich schafft er es danach noch bis 64 zu zählen. Denn 3906 * 256 + 64 = 1000000.&lt;br /&gt;
&lt;br /&gt;
Das ist ganz schön schnell. Und weil das oft zu schnell ist, hat jeder Timer noch die Möglichkeit sogenannte Vorteiler (Prescaler) vor den Zähltakt zu schalten. Zb einen Vorteiler von 8. Anstelle von 1Mhz bekommt der Teiler dann eine Frequenz von 1Mhz / 8 (= 125kHz) präsentiert. Und dementsprechend würde er in 1 Sekunde dann nur noch von 0 bis 124999 (= 1000000 / 8) zählen. Als 8 Bit Timer bedeutet das, dass er in 1 Sekunde jetzt nur noch 488 komplette Zyklen 0 bis 255 schafft und dann noch bis 72 zählen kann. Denn 488 * 256 + 72 = 125000&lt;br /&gt;
&lt;br /&gt;
== Das kann aber nicht alles gewesen sein? ==&lt;br /&gt;
Bis jetzt ist das alles noch unspektakulär und man fragt sich: Was hab ich jetzt davon, wenn der Timer vor sich hinzählt? Nun, die Situation ändert sich, wenn man weiß, dass man bei bestimmten Ereignissen und/oder Zählerständen etwas auslösen lassen kann. So ist zb. dieser Überlauf von 255 auf 0 so ein Ereignis. Mittels eines Interrupts kann man auf dieses Ereignis reagieren lassen und als Folge davon wird eine Funktion vollautomatisch aufgerufen. Und zwar unabhängig davon, was der µC gerade sonst so tut. Und das ist schon recht cool, denn es bedeutet, dass man regelmässig zu erfolgende Dinge in so eine ISR (Interrupt Service Routine, die Funktion die aufgerufen wird) stecken kann und der Timer sorgt ganz von alleine dafür, dass diese Funktionalität auch tatsächlich regelmässig ausgeführt wird. Gut, beispielsweise 488 mal in der Sekunde mag für so manchen Zweck zu oft sein, aber es gibt ja auch noch andere Vorteiler (welche steht im Datenblatt) und dann kann man ja auch innerhalb der ISR in einer lokalen Variablen mitzählen und zb nur bei jedem 2.ten Aufruf eine Aktion machen, die dann nur noch 244 mal in der Sekunde ausgeführt wird. Hier gibt es also mehrere Möglichkeiten, wie man die Aufrufhäufigkeit weiter herunterteilen kann, so dass man sich der Zahl annähert, die man benötigt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;C&amp;gt;&lt;br /&gt;
// Für einen Mega16.&lt;br /&gt;
// Andere Prozessoren: siehe Datenblatt wie die Timerkonfiguration einzustellen ist&lt;br /&gt;
&lt;br /&gt;
#define F_CPU 1000000UL&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;
//&lt;br /&gt;
// der Timer wird mit 1Mhz getaktet. Vorteiler ist 8&lt;br /&gt;
// d.h. der Timer läuft mit 125kHz und würde daher in 1 Sekunde&lt;br /&gt;
// von 0 bis 124999 zaehlen.&lt;br /&gt;
// Aber nach jeweils 256 Zaehlungen erfolgt ein Overflow.&lt;br /&gt;
// Daher werden in 1 Sekunde 125000 / 256 = 488.28125 Overflows erzeugt&lt;br /&gt;
// Oder anders ausgedrückt:  1 / 488.2815 = 0.002048&lt;br /&gt;
// alle 0.002048 Sekunden erfolgt ein Overflow&lt;br /&gt;
//&lt;br /&gt;
ISR( TIMER0_OVF_vect )       // Overflow Interrupt Vector&lt;br /&gt;
{&lt;br /&gt;
  static uint8_t swTeiler = 0;&lt;br /&gt;
&lt;br /&gt;
  swTeiler++;&lt;br /&gt;
  if( swTeiler == 200 ) {    // nur bei jedem 200.ten Aufruf. Effektiv teilt dieses die&lt;br /&gt;
                             // die Aufruffrequenz des nachfolgenden Codes nochmal um&lt;br /&gt;
    swTeiler = 0;            // einen Faktor 200. Der nachfolgende Code wird daher nicht&lt;br /&gt;
                             // alle 0.002 Sekunden sondern alle 0.4096 Sekunden ausgeführt.&lt;br /&gt;
                             // Das reicht, dass man eine LED am Port schon blinken sieht.&lt;br /&gt;
    PORTD = PORTD ^ 0xFF;    // alle Bits am Port umdrehen, einfach damit sich was tut&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  DDRD = 0xFF;          // irgendein Port, damit wir auch was sehen&lt;br /&gt;
&lt;br /&gt;
  TCCR0 = (1&amp;lt;&amp;lt;CS01);    // Vorteiler 8, jetzt zählt der Timer bereits&lt;br /&gt;
  TIMSK |= (1&amp;lt;&amp;lt;TOIE0);  // den Overflow Interrupt des Timers freigeben&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  sei();                // und Interrupts generell freigeben&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  while( 1 )&lt;br /&gt;
  {                     // hier braucht nichts mehr gemacht werden.&lt;br /&gt;
  }                     // der Timer selbst sorgt dafür, dass die ISR Funktion&lt;br /&gt;
}                       // regelmässig aufgerufen wird&lt;br /&gt;
&amp;lt;/C&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== CTC Modus ==&lt;br /&gt;
Manchmal reicht das aber nicht. Benötigt man zb nicht 488 sondern möglichst genau 500 ISR Aufrufe in der Sekunde, so wird man weder mit Vorteiler noch durch Softwaremässiges Weiterteilen in der ISR zum Ziel kommen. Man kann natürlich die Taktfrequenz des kompletten Systems soweit umstellen, dass sich das alles ausgeht, aber oft ist das einfach nicht möglich. Was tun?&lt;br /&gt;
&lt;br /&gt;
Die Sache wäre einfacher, wenn man dem Timer vorschreiben könnte, nicht einfach nur von 0 bis 255 zu zählen, sondern wenn man ihm eine Obergrenze vorgeben könnte. Denn dann könnte man sich eine Obergrenze so bestimmen, dass dieser neue Zählbereich in 1 Sekunde ganz genau so oft durchlaufen werden kann, wie man es benötigt. Und hier kommt der sog. &amp;lt;b&amp;gt;CTC&amp;lt;/b&amp;gt; Modus ins Spiel. Denn genau darin besteht sein Wesen: Man gibt dem Timer eine Obergrenze vor. Erreicht seine Zählung diesen Wert, so wird der Timer auf 0 zurückgesetzt und beginnt wieder von vorne. Genau das was wir benötigen. Wollen wir exakt 500 ISR Ausfrufe in der Sekunde haben (bei 1 Mhz Systemtakt), dann wählen wir einen Vorteiler von 8 und setzen die Obergrenze auf 250-1 (nicht vergessen: wir brauchen 250 Zählschritte, das bedeutet der Timer muss von 0 bis 249 zählen, denn auch der Überlauf von 249 zurück auf 0 ist ein Zählschritt). Der Timer taktet dann mit 1Mhz / 8 = 125kHz und da nach jeweils 250 Zählschritten die Obergrenze erreicht ist, wird diese Obergrenze in 1 Sekunde 125000 / 250 = 500 mal erreicht. Genau so wie wir das wollten.&lt;br /&gt;
Wie wird dem Timer nun mitgeteilt, dass er eine spezielle Obergrenze benutzen soll? Nun, jeder Timer hat verschiedene Modi. Welche das bei einem konkreten µC und bei einem konkreten Timer genau sind, findet sich im Datenblatt im Abschnitt über die Timer. Normalerweise ist immer der letzte Abschnitt eines Kapitels im Datenblatt das interessantere: Register Summary. So auch hier. In jedem Atmel Datenblatt findet sich bei jedem Timer immer auch eine Tabelle, aus der hervorgeht, welche Modi es gibt, welche Bits dazu in den Konfigurationsregistern gesetzt werden müssen, wie sich dann die Obergrenze des Timer-Zählbereichs zusammensetzt und noch ein paar Angaben mehr. Beim Mega16 findet sich diese Tabelle für den Timer 0 zb auf Seite 83 und dort ist es die Tabelle 14.2. Diese Tabelle sieht im Datenblatt so aus&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;
! Mode || WGM01 || WGM00 || Timer/Counter || TOP || Update of || TOV0 Flag&lt;br /&gt;
|-  style=&amp;quot;background-color:#ffddcc&amp;quot;&lt;br /&gt;
!      || (CTC0) || (PWM0) || Mode of Operation || || OCR0 || Set-on&lt;br /&gt;
|-&lt;br /&gt;
| 0 || 0 || 0 || Normal || 0xFF || Immediate || MAX&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 0 || 1 || PWM, Phase Correct || 0xFF || TOP|| BOTTOM&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 1 || 0 || CTC || OCR0 || Immediate || MAX&lt;br /&gt;
|-&lt;br /&gt;
| 3 || 1 || 1 || Fast PWM || 0xFF || BOTTOM || MAX&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dort beginnt man mit der Recherche und sucht sich die Bits für den gewünschten Modus raus. Mit diesen Bits sieht man dann in den Konfigurationsregistern nach, welches Bit zu welchem Register gehört und setzt es ganz einfach. In unserem Fall möchten wir den CTC Modus, also den Modus 2. Dazu muss das Bit WGM01 gesetzt werden und WGM00 muss auf 0 bleiben. Im Datenblatt ein wenig zurückscrollen bringt ans Licht, dass das Bit WGM01 im Konfigurationsregister TCCR0 angesiedelt ist. Weiters entnehmen wir der Tabelle, dass der Timer bis zum Wert in OCR0 zählen wird. Dort hinein müssen also die 250-1 als Obergrenze geschrieben werden.&lt;br /&gt;
&lt;br /&gt;
Wichtig ist auch noch: Dieser Spezialmodus CTC löst keinen Overflow Interrupt aus, sondern einen sog. Compare Match Interrupt. Dies deshalb, weil die gewünschte Obergrenze in eines der sog. Compare Match Register geschrieben werden muss. Das sind Spezialregister, die nach jedem Zählvorgang mit dem Zählregister verglichen werden. Stimmt ihr Inhalt mit dem des Zählrgisters überein, so hat man einen Compare-Match und kann daran wieder eine Aktion (ISR) knüpfen. In diesem speziellen Fall des CTC Modus beinhaltet dieser Compare Match dann auch noch das automatische Rücksetzen des Timers auf 0.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
// Für einen Mega16.&lt;br /&gt;
// Andere Prozessoren: siehe Datenblatt wie die Timerkonfiguration einzustellen ist&lt;br /&gt;
 &lt;br /&gt;
#define F_CPU 1000000UL&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;
ISR( TIMER0_COMP_vect )    // Compare Match Interrupt Vector&lt;br /&gt;
{&lt;br /&gt;
  static uint8_t swTeiler = 0;&lt;br /&gt;
 &lt;br /&gt;
  swTeiler++;&lt;br /&gt;
  if( swTeiler == 200 ) {&lt;br /&gt;
    swTeiler = 0;&lt;br /&gt;
    PORTD = PORTD ^ 0xFF;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  DDRD = 0xFF;          // irgendein Port, damit wir auch was sehen&lt;br /&gt;
 &lt;br /&gt;
  TIMSK = (1&amp;lt;&amp;lt;OCIE0);               // den Output Compare Interrupt des Timers freigeben&lt;br /&gt;
  OCR0  = 250 - 1;                    // nach 250 Zaehlschritten -&amp;gt; Interrupt und Timer auf 0&lt;br /&gt;
  TCCR0 = (1&amp;lt;&amp;lt;WGM01) | (1&amp;lt;&amp;lt;CS01);    // Vorteiler 8, CTC Modus&lt;br /&gt;
 &lt;br /&gt;
  &lt;br /&gt;
  sei();                // und Interrupts generell freigeben&lt;br /&gt;
 &lt;br /&gt;
  &lt;br /&gt;
  while( 1 )&lt;br /&gt;
  {                     // hier braucht nichts mehr gemacht werden.&lt;br /&gt;
  }                     // der Timer selbst sorgt dafür, dass die ISR Funktion&lt;br /&gt;
}                       // regelmässig aufgerufen wird &lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:C]]&lt;br /&gt;
[[Kategorie:avr-gcc]]&lt;/div&gt;</summary>
		<author><name>Stefan1971</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Codeschloss&amp;diff=61525</id>
		<title>Codeschloss</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Codeschloss&amp;diff=61525"/>
		<updated>2011-11-08T15:33:43Z</updated>

		<summary type="html">&lt;p&gt;Stefan1971: /* Software */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;von Stefan1971&lt;br /&gt;
&lt;br /&gt;
=== Einleitung ===&lt;br /&gt;
&lt;br /&gt;
Im Folgenden beschreibe ich ein Haustür-Codeschloss, das als kleines AVR-Projekt in Hard- und Software umgesetzt ist und mittlerweile seinen Dienst am Klingelschild einer Haustüre versieht. Durch Eingabe des richtigen Codes lässt sich damit die Haustüre ohne Schlüssel öffnen.&lt;br /&gt;
&lt;br /&gt;
=== Merkmale ===&lt;br /&gt;
* Codeschloss mit ATtiny2313 zum Schalten eines elektrischen Türöffners über Relais&lt;br /&gt;
* Programmierbarer Tastencode zum Öffnen der Haustür kann aus bis zu 12 Tasten bestehen&lt;br /&gt;
* Aktivierdauer des Türöffners ist einstellbar&lt;br /&gt;
* Einzelne Taster oder alternativ eine 4x3-Matrixtastatur können angeschlossen werden&lt;br /&gt;
* Rote LED, wenn Codeeingabe läuft (leuchtet, sobald erste richtige Codetaste gedrückt wurde; verlöscht bei Zeitablauf in der Codeeingabe bzw. zusammen mit Abschalten des Türöffners)&lt;br /&gt;
* Gelbe LED leuchtet, wenn Codeschloss in Programmiermodus ist (=Lernen eines Codes) und blinkt, wenn Aktivierzeit für den Türöffner eingestellt wird&lt;br /&gt;
* Grüne LED zur Anzeige, ob Türöffner gerade geschaltet ist&lt;br /&gt;
* Wenn der Türöffner gerade aktiv ist, kann er durch Drücken einer beliebigen Codetaste vor Ablauf des Timers abgeschaltet werden&lt;br /&gt;
* Anschlüsse sind vorgesehen für die 12 Volt-Stromversorgung (Wechselspannung), eine LED als Türschildbeleuchtung und den Türöffner. Für die Codetasten gibt es eine Anschlussbuchse.&lt;br /&gt;
&lt;br /&gt;
=== Programmierung zur Nutzung ===&lt;br /&gt;
==== Programmieren des Codes ====&lt;br /&gt;
Durch Drücken des Programmiertasters auf der Schaltung wird in den Programmiermodus gewechselt. Dieser wird durch Leuchten der gelben LED angezeigt. Nun sind die Tasten in der gewünschten Reihenfolge zu betätigen. Der Code kann aus bis zu zwölf Tastendrücken bestehen. Die Programmierung ist durch erneutes Drücken des Programmiertasters abzuschließen. Damit ist der Tastencode gespeichert. Werden bei der Programmierung die maximal möglichen Tasten gedrückt (derzeit 12), beendet sich der Programmiermodus ohne Betätigen des Programmiertasters.&lt;br /&gt;
&lt;br /&gt;
==== Programmieren der Aktivierdauer des Türöffners ====&lt;br /&gt;
Wird der Programmiertaster im Programmiermodus (d.h. die gelbe LED leuchtet) gedrückt, ohne dass eine Codetaste zum Lernen eines neuen Codes betätigt wurde, so wechselt das Codeschloss in die Programmierung für die Aktivierdauer des Türöffners. Die gelbe LED zeigt dies durch Blinken an. In diesem Modus erfolgt mit der Taste 1 eine Testauslösung des Türöffners, mit der Taste 2 kann die Dauer verlängert, mit Taste 3 die Dauer verkürzt werden.&lt;br /&gt;
&lt;br /&gt;
Ist eine Matrixtastatur angeschlossen, werden andere Tasten verwendet: Hier erfolgt die Testauslösung mit der Taste (*). Die Taste (7) verlängert und die Taste (4) verkürzt die Dauer.&lt;br /&gt;
&lt;br /&gt;
Die Dauer wird in Stufen von ca. 0,2 Sekunden eingestellt. &lt;br /&gt;
&lt;br /&gt;
Erneutes Drücken des Programmiertasters speichert die Einstellung, die gelbe LED erlischt. Jede andere Taste als 1, 2, 3 bzw. (*), (7) oder (4) bricht die Programmierung ab und verwirft evtl. gemachte Änderungen an der Aktivierdauer.&lt;br /&gt;
&lt;br /&gt;
=== Software ===&lt;br /&gt;
Das Steuerprogramm ist in Assembler programmiert. Über bedingte Assemblierung im Quelltext kann auf die Zielplattformen ATmega8 oder ATtiny2313 assembliert werden. Hintergrund ist, dass zuerst auf einem [http://www.myavr.de myAVR Board] mit ATmega8 entwickelt und später für den Selbstbau auf den ATtiny2313 umgeschwenkt wurde.&amp;lt;br /&amp;gt;&lt;br /&gt;
Mittlerweile (November 2011) gibt es auch eine funktional gleiche Version in C (siehe Abschnitt [[#Download|Download]]).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Folgende interne Zustände werden in der Firmware unterschieden:&lt;br /&gt;
! Status  !! Beschreibung&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;SCAN&#039;&#039;&#039;|| SCAN ist der Default-Modus im laufenden Betrieb. Warten auf Tasten in der richtigen Reihenfolge. Tastendruck gilt als erfolgt, wenn Taste losgelassen wurde. Mit Loslassen der ersten richtigen Taste wird (Software-) Timer gestartet. Rote LED leuchtet.&amp;lt;br /&amp;gt;Nächste Taste war richtig: Zeiger wird auf nächste zu erwartende Taste weiter gestellt, Timer wird zurückgesetzt.&amp;lt;br /&amp;gt;Taste war falsch: Zeiger auf Anfang, LED aus, Timer deaktivieren.&amp;lt;br /&amp;gt;Timer abgelaufen: Zeiger auf Anfang, LED aus; wie bei falscher Taste&amp;lt;br /&amp;gt;Anzeigen des SCAN-Modus durch Leuchten der roten LED, sobald die erste richtige Taste betätigt (d.h. losgelassen) wurde.&amp;lt;br /&amp;gt;Wenn alle Tasten in der richtigen Reihenfolge richtig gedrückt wurden, erfolgt Wechsel in Status OPEN.&amp;lt;br /&amp;gt;Wenn Programmierkontakt erkannt wurde, Wechsel in den PROG-Modus.&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;OPEN&#039;&#039;&#039; || Timer für Türöffner mit programmiertem Wert (aus Status PROG_DOOR) starten, grüne LED leuchtet, rote LED ebenfalls, Türöffner aktiv&amp;lt;br /&amp;gt;Timer abgelaufen: Türöffner aus, LEDs aus, zurück in SCAN-Modus&amp;lt;br /&amp;gt;Beliebige Taste wird gedrückt (Schließen ist relevant, nicht Öffnen): Türöffner aus, grüne und rote LED aus; zurück in SCAN-Modus: wie Timer-Ablauf&amp;lt;br /&amp;gt;Der Abbruch des OPEN-Modus durch Drücken einer beliebigen Taste ist realisiert, indem das Drücken einer falschen Taste simuliert wird.&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PROG&#039;&#039;&#039; || Programmiermodus: Tritt ein, wenn im SCAN-Modus der Programmierkontakt betätigt (=losgelassen) wurde. Ende des Programmiermodus, wenn Programmierkontakt erneut betätigt wird. Im Programmiermodus werden die betätigten Tasten (Loslassen der Taste, wie im SCAN-Modus) nacheinander im SRAM festgehalten. Hierzu wird Index auf SRAM-Tastenspeicher zunächst auf Null gesetzt. Bei Ende des Programmiermodus wird die im SRAM festgehaltene Tastenfolge ins EEPROM übernommen. Beenden des Programmiermodus, ohne dass eine Taste während des Programmiermodus betätigt wurde, erhält den bisher eingestellten Code; dann keine Übernahme ins EEPROM. Beenden des Programmiermodus führt dann in die Programmierung der Aktivierdauer des Türöffners; Wechsel in Modus PROG_DOOR.&amp;lt;br /&amp;gt;Eine begonnene Programmierung, bei der irrtümlich falsche Tasten gedrückt wurden, kann nicht storniert werden, sondern muss erneut durchgeführt werden. Im Programmiermodus leuchtet die gelbe LED.&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PROG_DOOR&#039;&#039;&#039; || Dient zur Programmierung der Aktivierdauer des Türöffners.&amp;lt;br /&amp;gt;Um in diesen Modus zu gelangen, muss der Programmierkontakt zweimal betätigt werden, d.h. der Code-Programmiermodus muss ohne Druck einer Codetaste beendet (übersprungen) werden. Im PROG_DOOR-Modus blinkt die gelbe LED.&amp;lt;br /&amp;gt;Die Tasten des Codeschlosses erhalten im PROG_DOOR-Modus folgende Bedeutung:&amp;lt;br /&amp;gt;Taste 1: löst den Türöffner für die eingestellte Zeit zum Test aus (per Timer)&amp;lt;br /&amp;gt;Taste 2: verlängert mit jedem Tastendruck die eingestellte Zeit&amp;lt;br /&amp;gt;Taste 3: verkürzt mit jedem Tastendruck die eingestellte Zeit&amp;lt;br /&amp;gt;Jede andere Taste: Verwirft die Änderungen und verlässt den PROG_DOOR-Modus, Rückkehr in den SCAN-Modus.&amp;lt;br /&amp;gt;Abschließendes Betätigen des Programmierkontakts führt zu Übernahme des neuen Timer-Ladewerts ins EEPROM und beendet den PROG_DOOR-Modus. Wechsel in den SCAN-Modus.&lt;br /&gt;
Ist eine 4x3-Matrixtastatur angeschlossen, ist die Tastenbelegung für die Programmierung der Türöffneraktivierdauer wie folgt:&amp;lt;br /&amp;gt;Taste (*): Türöffner testhalber auslösen&amp;lt;br /&amp;gt;Taste (7): Aktivierdauer verlängern&amp;lt;br /&amp;gt;Taste (4): Aktivierdauer verkürzen&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;STARTUP&#039;&#039;&#039; || In diesen Modus wird beim Start der Anwendung zunächst gewechselt. Er hat den Zweck, die drei LEDs des Codeschlosses dreimal blinken zu lassen um anzuzeigen, dass der Controller arbeitet und auf Eingaben wartet. Wenn diese Phase abgelaufen ist, wird in den SCAN-Modus gewechselt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Hardware ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Belegung der Ports beim ATtiny2313:&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;PB0 ... PB7&#039;&#039;&#039; || IN || 8 Tasten zur Codeeingabe&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD6&#039;&#039;&#039; || IN || Programmierkontakt&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD0&#039;&#039;&#039; || OUT || Türöffner&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD1&#039;&#039;&#039; || OUT || Rote LED (laufende Codeeingabe)&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD2&#039;&#039;&#039; || OUT || Gelbe LED (Programmiermodus)&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD3&#039;&#039;&#039; || OUT || Grüne LED (Türöffner ist aktiv)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Einzelne Tasten werden mit jeweils einem Kontakt an Pin0 bis Pin7 angeschlossen, mit dem anderen Kontakt an Masse. Welche Tastatur (einzelne Tasten oder 4x3-Matrixtastatur) angeschlossen ist, wird über den bei der Matrixtastatur nicht benötigten Pin acht (PB7) gesteuert. Ist dieser beim Anwendungsstart auf Masse geschlossen, wird auf Abtastung einer Matrixtastatur umgestellt.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot; width=&amp;quot;25%&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Anschlussschema für 4x3-Matrixtastatur:&lt;br /&gt;
| width=&amp;quot;40%&amp;quot; | &#039;&#039;&#039;IN / OUT&#039;&#039;&#039; || style=&amp;quot;text-align:center&amp;quot; width=&amp;quot;20%&amp;quot; | &#039;&#039;&#039;Pin4&#039;&#039;&#039; || style=&amp;quot;text-align:center&amp;quot; width=&amp;quot;20%&amp;quot; | &#039;&#039;&#039;Pin5&#039;&#039;&#039; || style=&amp;quot;text-align:center&amp;quot; width=&amp;quot;20%&amp;quot; | &#039;&#039;&#039;Pin6&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin0&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | 1 || style=&amp;quot;text-align:center&amp;quot; | 2 || style=&amp;quot;text-align:center&amp;quot; | 3&lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin1&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | 4 || style=&amp;quot;text-align:center&amp;quot; | 5 || style=&amp;quot;text-align:center&amp;quot; | 6&lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin2&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | 7 || style=&amp;quot;text-align:center&amp;quot; | 8 || style=&amp;quot;text-align:center&amp;quot; | 9  &lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin3&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | * || style=&amp;quot;text-align:center&amp;quot; | 0 || style=&amp;quot;text-align:center&amp;quot; | #  &lt;br /&gt;
|} Pin7 und Pin8 (Masse) sind dann dauerhaft miteinander verbunden.&lt;br /&gt;
&lt;br /&gt;
Bei Nutzung eines Reed-Relais als Schaltelement muss der Türöffner erfahrungsgemäß einen Widerstand von mindestens 20 Ohm haben.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Die Fuses des Controllers sind folgendermaßen gesetzt:&lt;br /&gt;
! Fuse !! Einstellung&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;SPIEN:&#039;&#039;&#039;|| Enabled&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;BODLEVEL:&#039;&#039;&#039; || Brown-out detection disabled&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;CKDIV8:&#039;&#039;&#039; || Enabled&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;SUT_CKSEL:&#039;&#039;&#039; || Int. RC Osc. 4 MHz; Startup-time: 14 CK + 65 ms&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;alle anderen:&#039;&#039;&#039; || Disabled&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Schaltplan und Platinenlayout wurden mit Target3001 erstellt.&lt;br /&gt;
&lt;br /&gt;
=== Bilder ===&lt;br /&gt;
[[Bild:Codeschloss_Platine_beschriftet.jpg|thumb|550px|none|Codeschloss-Platine]]&lt;br /&gt;
[[Bild:Codeschloss_Platine_Keypad_Ausschnitt.jpg|thumb|220px|none|Anschluss einer Matrixtastatur]]&lt;br /&gt;
&lt;br /&gt;
=== Download ===&lt;br /&gt;
* [[Media:Codeschloss.zip | Codeschloss.zip ]]&amp;lt;br /&amp;gt;enthält ASM-Source, XLS-Rechenhilfe für Interrupt-Timing, Schaltplan-/Layout-Ausdruck&lt;br /&gt;
* [[Media:Codeschloss_C.zip | Codeschloss_C.zip]]&amp;lt;br /&amp;gt;Version in C (WinAVR-20100110), mit .hex- und .epp-Datei&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:AVR-Projekte]]&lt;/div&gt;</summary>
		<author><name>Stefan1971</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Codeschloss&amp;diff=61524</id>
		<title>Codeschloss</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Codeschloss&amp;diff=61524"/>
		<updated>2011-11-08T15:28:26Z</updated>

		<summary type="html">&lt;p&gt;Stefan1971: /* Software */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;von Stefan1971&lt;br /&gt;
&lt;br /&gt;
=== Einleitung ===&lt;br /&gt;
&lt;br /&gt;
Im Folgenden beschreibe ich ein Haustür-Codeschloss, das als kleines AVR-Projekt in Hard- und Software umgesetzt ist und mittlerweile seinen Dienst am Klingelschild einer Haustüre versieht. Durch Eingabe des richtigen Codes lässt sich damit die Haustüre ohne Schlüssel öffnen.&lt;br /&gt;
&lt;br /&gt;
=== Merkmale ===&lt;br /&gt;
* Codeschloss mit ATtiny2313 zum Schalten eines elektrischen Türöffners über Relais&lt;br /&gt;
* Programmierbarer Tastencode zum Öffnen der Haustür kann aus bis zu 12 Tasten bestehen&lt;br /&gt;
* Aktivierdauer des Türöffners ist einstellbar&lt;br /&gt;
* Einzelne Taster oder alternativ eine 4x3-Matrixtastatur können angeschlossen werden&lt;br /&gt;
* Rote LED, wenn Codeeingabe läuft (leuchtet, sobald erste richtige Codetaste gedrückt wurde; verlöscht bei Zeitablauf in der Codeeingabe bzw. zusammen mit Abschalten des Türöffners)&lt;br /&gt;
* Gelbe LED leuchtet, wenn Codeschloss in Programmiermodus ist (=Lernen eines Codes) und blinkt, wenn Aktivierzeit für den Türöffner eingestellt wird&lt;br /&gt;
* Grüne LED zur Anzeige, ob Türöffner gerade geschaltet ist&lt;br /&gt;
* Wenn der Türöffner gerade aktiv ist, kann er durch Drücken einer beliebigen Codetaste vor Ablauf des Timers abgeschaltet werden&lt;br /&gt;
* Anschlüsse sind vorgesehen für die 12 Volt-Stromversorgung (Wechselspannung), eine LED als Türschildbeleuchtung und den Türöffner. Für die Codetasten gibt es eine Anschlussbuchse.&lt;br /&gt;
&lt;br /&gt;
=== Programmierung zur Nutzung ===&lt;br /&gt;
==== Programmieren des Codes ====&lt;br /&gt;
Durch Drücken des Programmiertasters auf der Schaltung wird in den Programmiermodus gewechselt. Dieser wird durch Leuchten der gelben LED angezeigt. Nun sind die Tasten in der gewünschten Reihenfolge zu betätigen. Der Code kann aus bis zu zwölf Tastendrücken bestehen. Die Programmierung ist durch erneutes Drücken des Programmiertasters abzuschließen. Damit ist der Tastencode gespeichert. Werden bei der Programmierung die maximal möglichen Tasten gedrückt (derzeit 12), beendet sich der Programmiermodus ohne Betätigen des Programmiertasters.&lt;br /&gt;
&lt;br /&gt;
==== Programmieren der Aktivierdauer des Türöffners ====&lt;br /&gt;
Wird der Programmiertaster im Programmiermodus (d.h. die gelbe LED leuchtet) gedrückt, ohne dass eine Codetaste zum Lernen eines neuen Codes betätigt wurde, so wechselt das Codeschloss in die Programmierung für die Aktivierdauer des Türöffners. Die gelbe LED zeigt dies durch Blinken an. In diesem Modus erfolgt mit der Taste 1 eine Testauslösung des Türöffners, mit der Taste 2 kann die Dauer verlängert, mit Taste 3 die Dauer verkürzt werden.&lt;br /&gt;
&lt;br /&gt;
Ist eine Matrixtastatur angeschlossen, werden andere Tasten verwendet: Hier erfolgt die Testauslösung mit der Taste (*). Die Taste (7) verlängert und die Taste (4) verkürzt die Dauer.&lt;br /&gt;
&lt;br /&gt;
Die Dauer wird in Stufen von ca. 0,2 Sekunden eingestellt. &lt;br /&gt;
&lt;br /&gt;
Erneutes Drücken des Programmiertasters speichert die Einstellung, die gelbe LED erlischt. Jede andere Taste als 1, 2, 3 bzw. (*), (7) oder (4) bricht die Programmierung ab und verwirft evtl. gemachte Änderungen an der Aktivierdauer.&lt;br /&gt;
&lt;br /&gt;
=== Software ===&lt;br /&gt;
Das Steuerprogramm ist in Assembler programmiert. Über bedingte Assemblierung im Quelltext kann auf die Zielplattformen ATmega8 oder ATtiny2313 assembliert werden. Hintergrund ist, dass zuerst auf einem [http://www.myavr.de myAVR Board] mit ATmega8 entwickelt und später für den Selbstbau auf den ATtiny2313 umgeschwenkt wurde.&amp;lt;br /&amp;gt;&lt;br /&gt;
Mittlerweile (November 2011) gibt es auch eine funktional gleiche Version in C (siehe Abschnitt [[#=== Download ===|Download]]).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Folgende interne Zustände werden in der Firmware unterschieden:&lt;br /&gt;
! Status  !! Beschreibung&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;SCAN&#039;&#039;&#039;|| SCAN ist der Default-Modus im laufenden Betrieb. Warten auf Tasten in der richtigen Reihenfolge. Tastendruck gilt als erfolgt, wenn Taste losgelassen wurde. Mit Loslassen der ersten richtigen Taste wird (Software-) Timer gestartet. Rote LED leuchtet.&amp;lt;br /&amp;gt;Nächste Taste war richtig: Zeiger wird auf nächste zu erwartende Taste weiter gestellt, Timer wird zurückgesetzt.&amp;lt;br /&amp;gt;Taste war falsch: Zeiger auf Anfang, LED aus, Timer deaktivieren.&amp;lt;br /&amp;gt;Timer abgelaufen: Zeiger auf Anfang, LED aus; wie bei falscher Taste&amp;lt;br /&amp;gt;Anzeigen des SCAN-Modus durch Leuchten der roten LED, sobald die erste richtige Taste betätigt (d.h. losgelassen) wurde.&amp;lt;br /&amp;gt;Wenn alle Tasten in der richtigen Reihenfolge richtig gedrückt wurden, erfolgt Wechsel in Status OPEN.&amp;lt;br /&amp;gt;Wenn Programmierkontakt erkannt wurde, Wechsel in den PROG-Modus.&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;OPEN&#039;&#039;&#039; || Timer für Türöffner mit programmiertem Wert (aus Status PROG_DOOR) starten, grüne LED leuchtet, rote LED ebenfalls, Türöffner aktiv&amp;lt;br /&amp;gt;Timer abgelaufen: Türöffner aus, LEDs aus, zurück in SCAN-Modus&amp;lt;br /&amp;gt;Beliebige Taste wird gedrückt (Schließen ist relevant, nicht Öffnen): Türöffner aus, grüne und rote LED aus; zurück in SCAN-Modus: wie Timer-Ablauf&amp;lt;br /&amp;gt;Der Abbruch des OPEN-Modus durch Drücken einer beliebigen Taste ist realisiert, indem das Drücken einer falschen Taste simuliert wird.&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PROG&#039;&#039;&#039; || Programmiermodus: Tritt ein, wenn im SCAN-Modus der Programmierkontakt betätigt (=losgelassen) wurde. Ende des Programmiermodus, wenn Programmierkontakt erneut betätigt wird. Im Programmiermodus werden die betätigten Tasten (Loslassen der Taste, wie im SCAN-Modus) nacheinander im SRAM festgehalten. Hierzu wird Index auf SRAM-Tastenspeicher zunächst auf Null gesetzt. Bei Ende des Programmiermodus wird die im SRAM festgehaltene Tastenfolge ins EEPROM übernommen. Beenden des Programmiermodus, ohne dass eine Taste während des Programmiermodus betätigt wurde, erhält den bisher eingestellten Code; dann keine Übernahme ins EEPROM. Beenden des Programmiermodus führt dann in die Programmierung der Aktivierdauer des Türöffners; Wechsel in Modus PROG_DOOR.&amp;lt;br /&amp;gt;Eine begonnene Programmierung, bei der irrtümlich falsche Tasten gedrückt wurden, kann nicht storniert werden, sondern muss erneut durchgeführt werden. Im Programmiermodus leuchtet die gelbe LED.&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PROG_DOOR&#039;&#039;&#039; || Dient zur Programmierung der Aktivierdauer des Türöffners.&amp;lt;br /&amp;gt;Um in diesen Modus zu gelangen, muss der Programmierkontakt zweimal betätigt werden, d.h. der Code-Programmiermodus muss ohne Druck einer Codetaste beendet (übersprungen) werden. Im PROG_DOOR-Modus blinkt die gelbe LED.&amp;lt;br /&amp;gt;Die Tasten des Codeschlosses erhalten im PROG_DOOR-Modus folgende Bedeutung:&amp;lt;br /&amp;gt;Taste 1: löst den Türöffner für die eingestellte Zeit zum Test aus (per Timer)&amp;lt;br /&amp;gt;Taste 2: verlängert mit jedem Tastendruck die eingestellte Zeit&amp;lt;br /&amp;gt;Taste 3: verkürzt mit jedem Tastendruck die eingestellte Zeit&amp;lt;br /&amp;gt;Jede andere Taste: Verwirft die Änderungen und verlässt den PROG_DOOR-Modus, Rückkehr in den SCAN-Modus.&amp;lt;br /&amp;gt;Abschließendes Betätigen des Programmierkontakts führt zu Übernahme des neuen Timer-Ladewerts ins EEPROM und beendet den PROG_DOOR-Modus. Wechsel in den SCAN-Modus.&lt;br /&gt;
Ist eine 4x3-Matrixtastatur angeschlossen, ist die Tastenbelegung für die Programmierung der Türöffneraktivierdauer wie folgt:&amp;lt;br /&amp;gt;Taste (*): Türöffner testhalber auslösen&amp;lt;br /&amp;gt;Taste (7): Aktivierdauer verlängern&amp;lt;br /&amp;gt;Taste (4): Aktivierdauer verkürzen&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;STARTUP&#039;&#039;&#039; || In diesen Modus wird beim Start der Anwendung zunächst gewechselt. Er hat den Zweck, die drei LEDs des Codeschlosses dreimal blinken zu lassen um anzuzeigen, dass der Controller arbeitet und auf Eingaben wartet. Wenn diese Phase abgelaufen ist, wird in den SCAN-Modus gewechselt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Hardware ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Belegung der Ports beim ATtiny2313:&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;PB0 ... PB7&#039;&#039;&#039; || IN || 8 Tasten zur Codeeingabe&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD6&#039;&#039;&#039; || IN || Programmierkontakt&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD0&#039;&#039;&#039; || OUT || Türöffner&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD1&#039;&#039;&#039; || OUT || Rote LED (laufende Codeeingabe)&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD2&#039;&#039;&#039; || OUT || Gelbe LED (Programmiermodus)&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD3&#039;&#039;&#039; || OUT || Grüne LED (Türöffner ist aktiv)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Einzelne Tasten werden mit jeweils einem Kontakt an Pin0 bis Pin7 angeschlossen, mit dem anderen Kontakt an Masse. Welche Tastatur (einzelne Tasten oder 4x3-Matrixtastatur) angeschlossen ist, wird über den bei der Matrixtastatur nicht benötigten Pin acht (PB7) gesteuert. Ist dieser beim Anwendungsstart auf Masse geschlossen, wird auf Abtastung einer Matrixtastatur umgestellt.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot; width=&amp;quot;25%&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Anschlussschema für 4x3-Matrixtastatur:&lt;br /&gt;
| width=&amp;quot;40%&amp;quot; | &#039;&#039;&#039;IN / OUT&#039;&#039;&#039; || style=&amp;quot;text-align:center&amp;quot; width=&amp;quot;20%&amp;quot; | &#039;&#039;&#039;Pin4&#039;&#039;&#039; || style=&amp;quot;text-align:center&amp;quot; width=&amp;quot;20%&amp;quot; | &#039;&#039;&#039;Pin5&#039;&#039;&#039; || style=&amp;quot;text-align:center&amp;quot; width=&amp;quot;20%&amp;quot; | &#039;&#039;&#039;Pin6&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin0&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | 1 || style=&amp;quot;text-align:center&amp;quot; | 2 || style=&amp;quot;text-align:center&amp;quot; | 3&lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin1&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | 4 || style=&amp;quot;text-align:center&amp;quot; | 5 || style=&amp;quot;text-align:center&amp;quot; | 6&lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin2&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | 7 || style=&amp;quot;text-align:center&amp;quot; | 8 || style=&amp;quot;text-align:center&amp;quot; | 9  &lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin3&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | * || style=&amp;quot;text-align:center&amp;quot; | 0 || style=&amp;quot;text-align:center&amp;quot; | #  &lt;br /&gt;
|} Pin7 und Pin8 (Masse) sind dann dauerhaft miteinander verbunden.&lt;br /&gt;
&lt;br /&gt;
Bei Nutzung eines Reed-Relais als Schaltelement muss der Türöffner erfahrungsgemäß einen Widerstand von mindestens 20 Ohm haben.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Die Fuses des Controllers sind folgendermaßen gesetzt:&lt;br /&gt;
! Fuse !! Einstellung&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;SPIEN:&#039;&#039;&#039;|| Enabled&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;BODLEVEL:&#039;&#039;&#039; || Brown-out detection disabled&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;CKDIV8:&#039;&#039;&#039; || Enabled&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;SUT_CKSEL:&#039;&#039;&#039; || Int. RC Osc. 4 MHz; Startup-time: 14 CK + 65 ms&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;alle anderen:&#039;&#039;&#039; || Disabled&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Schaltplan und Platinenlayout wurden mit Target3001 erstellt.&lt;br /&gt;
&lt;br /&gt;
=== Bilder ===&lt;br /&gt;
[[Bild:Codeschloss_Platine_beschriftet.jpg|thumb|550px|none|Codeschloss-Platine]]&lt;br /&gt;
[[Bild:Codeschloss_Platine_Keypad_Ausschnitt.jpg|thumb|220px|none|Anschluss einer Matrixtastatur]]&lt;br /&gt;
&lt;br /&gt;
=== Download ===&lt;br /&gt;
* [[Media:Codeschloss.zip | Codeschloss.zip ]]&amp;lt;br /&amp;gt;enthält ASM-Source, XLS-Rechenhilfe für Interrupt-Timing, Schaltplan-/Layout-Ausdruck&lt;br /&gt;
* [[Media:Codeschloss_C.zip | Codeschloss_C.zip]]&amp;lt;br /&amp;gt;Version in C (WinAVR-20100110), mit .hex- und .epp-Datei&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:AVR-Projekte]]&lt;/div&gt;</summary>
		<author><name>Stefan1971</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Codeschloss&amp;diff=61523</id>
		<title>Codeschloss</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Codeschloss&amp;diff=61523"/>
		<updated>2011-11-08T15:13:07Z</updated>

		<summary type="html">&lt;p&gt;Stefan1971: /* Download */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;von Stefan1971&lt;br /&gt;
&lt;br /&gt;
=== Einleitung ===&lt;br /&gt;
&lt;br /&gt;
Im Folgenden beschreibe ich ein Haustür-Codeschloss, das als kleines AVR-Projekt in Hard- und Software umgesetzt ist und mittlerweile seinen Dienst am Klingelschild einer Haustüre versieht. Durch Eingabe des richtigen Codes lässt sich damit die Haustüre ohne Schlüssel öffnen.&lt;br /&gt;
&lt;br /&gt;
=== Merkmale ===&lt;br /&gt;
* Codeschloss mit ATtiny2313 zum Schalten eines elektrischen Türöffners über Relais&lt;br /&gt;
* Programmierbarer Tastencode zum Öffnen der Haustür kann aus bis zu 12 Tasten bestehen&lt;br /&gt;
* Aktivierdauer des Türöffners ist einstellbar&lt;br /&gt;
* Einzelne Taster oder alternativ eine 4x3-Matrixtastatur können angeschlossen werden&lt;br /&gt;
* Rote LED, wenn Codeeingabe läuft (leuchtet, sobald erste richtige Codetaste gedrückt wurde; verlöscht bei Zeitablauf in der Codeeingabe bzw. zusammen mit Abschalten des Türöffners)&lt;br /&gt;
* Gelbe LED leuchtet, wenn Codeschloss in Programmiermodus ist (=Lernen eines Codes) und blinkt, wenn Aktivierzeit für den Türöffner eingestellt wird&lt;br /&gt;
* Grüne LED zur Anzeige, ob Türöffner gerade geschaltet ist&lt;br /&gt;
* Wenn der Türöffner gerade aktiv ist, kann er durch Drücken einer beliebigen Codetaste vor Ablauf des Timers abgeschaltet werden&lt;br /&gt;
* Anschlüsse sind vorgesehen für die 12 Volt-Stromversorgung (Wechselspannung), eine LED als Türschildbeleuchtung und den Türöffner. Für die Codetasten gibt es eine Anschlussbuchse.&lt;br /&gt;
&lt;br /&gt;
=== Programmierung zur Nutzung ===&lt;br /&gt;
==== Programmieren des Codes ====&lt;br /&gt;
Durch Drücken des Programmiertasters auf der Schaltung wird in den Programmiermodus gewechselt. Dieser wird durch Leuchten der gelben LED angezeigt. Nun sind die Tasten in der gewünschten Reihenfolge zu betätigen. Der Code kann aus bis zu zwölf Tastendrücken bestehen. Die Programmierung ist durch erneutes Drücken des Programmiertasters abzuschließen. Damit ist der Tastencode gespeichert. Werden bei der Programmierung die maximal möglichen Tasten gedrückt (derzeit 12), beendet sich der Programmiermodus ohne Betätigen des Programmiertasters.&lt;br /&gt;
&lt;br /&gt;
==== Programmieren der Aktivierdauer des Türöffners ====&lt;br /&gt;
Wird der Programmiertaster im Programmiermodus (d.h. die gelbe LED leuchtet) gedrückt, ohne dass eine Codetaste zum Lernen eines neuen Codes betätigt wurde, so wechselt das Codeschloss in die Programmierung für die Aktivierdauer des Türöffners. Die gelbe LED zeigt dies durch Blinken an. In diesem Modus erfolgt mit der Taste 1 eine Testauslösung des Türöffners, mit der Taste 2 kann die Dauer verlängert, mit Taste 3 die Dauer verkürzt werden.&lt;br /&gt;
&lt;br /&gt;
Ist eine Matrixtastatur angeschlossen, werden andere Tasten verwendet: Hier erfolgt die Testauslösung mit der Taste (*). Die Taste (7) verlängert und die Taste (4) verkürzt die Dauer.&lt;br /&gt;
&lt;br /&gt;
Die Dauer wird in Stufen von ca. 0,2 Sekunden eingestellt. &lt;br /&gt;
&lt;br /&gt;
Erneutes Drücken des Programmiertasters speichert die Einstellung, die gelbe LED erlischt. Jede andere Taste als 1, 2, 3 bzw. (*), (7) oder (4) bricht die Programmierung ab und verwirft evtl. gemachte Änderungen an der Aktivierdauer.&lt;br /&gt;
&lt;br /&gt;
=== Software ===&lt;br /&gt;
Das Steuerprogramm ist in Assembler programmiert. Über bedingte Assemblierung im Quelltext kann auf die Zielplattformen ATmega8 oder ATtiny2313 assembliert werden. Hintergrund ist, dass zuerst auf einem [http://www.myavr.de myAVR Board] mit ATmega8 entwickelt und später für den Selbstbau auf den ATtiny2313 umgeschwenkt wurde.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Folgende interne Zustände werden in der Firmware unterschieden:&lt;br /&gt;
! Status  !! Beschreibung&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;SCAN&#039;&#039;&#039;|| SCAN ist der Default-Modus im laufenden Betrieb. Warten auf Tasten in der richtigen Reihenfolge. Tastendruck gilt als erfolgt, wenn Taste losgelassen wurde. Mit Loslassen der ersten richtigen Taste wird (Software-) Timer gestartet. Rote LED leuchtet.&amp;lt;br /&amp;gt;Nächste Taste war richtig: Zeiger wird auf nächste zu erwartende Taste weiter gestellt, Timer wird zurückgesetzt.&amp;lt;br /&amp;gt;Taste war falsch: Zeiger auf Anfang, LED aus, Timer deaktivieren.&amp;lt;br /&amp;gt;Timer abgelaufen: Zeiger auf Anfang, LED aus; wie bei falscher Taste&amp;lt;br /&amp;gt;Anzeigen des SCAN-Modus durch Leuchten der roten LED, sobald die erste richtige Taste betätigt (d.h. losgelassen) wurde.&amp;lt;br /&amp;gt;Wenn alle Tasten in der richtigen Reihenfolge richtig gedrückt wurden, erfolgt Wechsel in Status OPEN.&amp;lt;br /&amp;gt;Wenn Programmierkontakt erkannt wurde, Wechsel in den PROG-Modus.&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;OPEN&#039;&#039;&#039; || Timer für Türöffner mit programmiertem Wert (aus Status PROG_DOOR) starten, grüne LED leuchtet, rote LED ebenfalls, Türöffner aktiv&amp;lt;br /&amp;gt;Timer abgelaufen: Türöffner aus, LEDs aus, zurück in SCAN-Modus&amp;lt;br /&amp;gt;Beliebige Taste wird gedrückt (Schließen ist relevant, nicht Öffnen): Türöffner aus, grüne und rote LED aus; zurück in SCAN-Modus: wie Timer-Ablauf&amp;lt;br /&amp;gt;Der Abbruch des OPEN-Modus durch Drücken einer beliebigen Taste ist realisiert, indem das Drücken einer falschen Taste simuliert wird.&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PROG&#039;&#039;&#039; || Programmiermodus: Tritt ein, wenn im SCAN-Modus der Programmierkontakt betätigt (=losgelassen) wurde. Ende des Programmiermodus, wenn Programmierkontakt erneut betätigt wird. Im Programmiermodus werden die betätigten Tasten (Loslassen der Taste, wie im SCAN-Modus) nacheinander im SRAM festgehalten. Hierzu wird Index auf SRAM-Tastenspeicher zunächst auf Null gesetzt. Bei Ende des Programmiermodus wird die im SRAM festgehaltene Tastenfolge ins EEPROM übernommen. Beenden des Programmiermodus, ohne dass eine Taste während des Programmiermodus betätigt wurde, erhält den bisher eingestellten Code; dann keine Übernahme ins EEPROM. Beenden des Programmiermodus führt dann in die Programmierung der Aktivierdauer des Türöffners; Wechsel in Modus PROG_DOOR.&amp;lt;br /&amp;gt;Eine begonnene Programmierung, bei der irrtümlich falsche Tasten gedrückt wurden, kann nicht storniert werden, sondern muss erneut durchgeführt werden. Im Programmiermodus leuchtet die gelbe LED.&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PROG_DOOR&#039;&#039;&#039; || Dient zur Programmierung der Aktivierdauer des Türöffners.&amp;lt;br /&amp;gt;Um in diesen Modus zu gelangen, muss der Programmierkontakt zweimal betätigt werden, d.h. der Code-Programmiermodus muss ohne Druck einer Codetaste beendet (übersprungen) werden. Im PROG_DOOR-Modus blinkt die gelbe LED.&amp;lt;br /&amp;gt;Die Tasten des Codeschlosses erhalten im PROG_DOOR-Modus folgende Bedeutung:&amp;lt;br /&amp;gt;Taste 1: löst den Türöffner für die eingestellte Zeit zum Test aus (per Timer)&amp;lt;br /&amp;gt;Taste 2: verlängert mit jedem Tastendruck die eingestellte Zeit&amp;lt;br /&amp;gt;Taste 3: verkürzt mit jedem Tastendruck die eingestellte Zeit&amp;lt;br /&amp;gt;Jede andere Taste: Verwirft die Änderungen und verlässt den PROG_DOOR-Modus, Rückkehr in den SCAN-Modus.&amp;lt;br /&amp;gt;Abschließendes Betätigen des Programmierkontakts führt zu Übernahme des neuen Timer-Ladewerts ins EEPROM und beendet den PROG_DOOR-Modus. Wechsel in den SCAN-Modus.&lt;br /&gt;
Ist eine 4x3-Matrixtastatur angeschlossen, ist die Tastenbelegung für die Programmierung der Türöffneraktivierdauer wie folgt:&amp;lt;br /&amp;gt;Taste (*): Türöffner testhalber auslösen&amp;lt;br /&amp;gt;Taste (7): Aktivierdauer verlängern&amp;lt;br /&amp;gt;Taste (4): Aktivierdauer verkürzen&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;STARTUP&#039;&#039;&#039; || In diesen Modus wird beim Start der Anwendung zunächst gewechselt. Er hat den Zweck, die drei LEDs des Codeschlosses dreimal blinken zu lassen um anzuzeigen, dass der Controller arbeitet und auf Eingaben wartet. Wenn diese Phase abgelaufen ist, wird in den SCAN-Modus gewechselt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Hardware ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Belegung der Ports beim ATtiny2313:&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;PB0 ... PB7&#039;&#039;&#039; || IN || 8 Tasten zur Codeeingabe&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD6&#039;&#039;&#039; || IN || Programmierkontakt&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD0&#039;&#039;&#039; || OUT || Türöffner&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD1&#039;&#039;&#039; || OUT || Rote LED (laufende Codeeingabe)&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD2&#039;&#039;&#039; || OUT || Gelbe LED (Programmiermodus)&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD3&#039;&#039;&#039; || OUT || Grüne LED (Türöffner ist aktiv)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Einzelne Tasten werden mit jeweils einem Kontakt an Pin0 bis Pin7 angeschlossen, mit dem anderen Kontakt an Masse. Welche Tastatur (einzelne Tasten oder 4x3-Matrixtastatur) angeschlossen ist, wird über den bei der Matrixtastatur nicht benötigten Pin acht (PB7) gesteuert. Ist dieser beim Anwendungsstart auf Masse geschlossen, wird auf Abtastung einer Matrixtastatur umgestellt.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot; width=&amp;quot;25%&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Anschlussschema für 4x3-Matrixtastatur:&lt;br /&gt;
| width=&amp;quot;40%&amp;quot; | &#039;&#039;&#039;IN / OUT&#039;&#039;&#039; || style=&amp;quot;text-align:center&amp;quot; width=&amp;quot;20%&amp;quot; | &#039;&#039;&#039;Pin4&#039;&#039;&#039; || style=&amp;quot;text-align:center&amp;quot; width=&amp;quot;20%&amp;quot; | &#039;&#039;&#039;Pin5&#039;&#039;&#039; || style=&amp;quot;text-align:center&amp;quot; width=&amp;quot;20%&amp;quot; | &#039;&#039;&#039;Pin6&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin0&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | 1 || style=&amp;quot;text-align:center&amp;quot; | 2 || style=&amp;quot;text-align:center&amp;quot; | 3&lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin1&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | 4 || style=&amp;quot;text-align:center&amp;quot; | 5 || style=&amp;quot;text-align:center&amp;quot; | 6&lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin2&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | 7 || style=&amp;quot;text-align:center&amp;quot; | 8 || style=&amp;quot;text-align:center&amp;quot; | 9  &lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin3&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | * || style=&amp;quot;text-align:center&amp;quot; | 0 || style=&amp;quot;text-align:center&amp;quot; | #  &lt;br /&gt;
|} Pin7 und Pin8 (Masse) sind dann dauerhaft miteinander verbunden.&lt;br /&gt;
&lt;br /&gt;
Bei Nutzung eines Reed-Relais als Schaltelement muss der Türöffner erfahrungsgemäß einen Widerstand von mindestens 20 Ohm haben.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Die Fuses des Controllers sind folgendermaßen gesetzt:&lt;br /&gt;
! Fuse !! Einstellung&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;SPIEN:&#039;&#039;&#039;|| Enabled&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;BODLEVEL:&#039;&#039;&#039; || Brown-out detection disabled&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;CKDIV8:&#039;&#039;&#039; || Enabled&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;SUT_CKSEL:&#039;&#039;&#039; || Int. RC Osc. 4 MHz; Startup-time: 14 CK + 65 ms&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;alle anderen:&#039;&#039;&#039; || Disabled&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Schaltplan und Platinenlayout wurden mit Target3001 erstellt.&lt;br /&gt;
&lt;br /&gt;
=== Bilder ===&lt;br /&gt;
[[Bild:Codeschloss_Platine_beschriftet.jpg|thumb|550px|none|Codeschloss-Platine]]&lt;br /&gt;
[[Bild:Codeschloss_Platine_Keypad_Ausschnitt.jpg|thumb|220px|none|Anschluss einer Matrixtastatur]]&lt;br /&gt;
&lt;br /&gt;
=== Download ===&lt;br /&gt;
* [[Media:Codeschloss.zip | Codeschloss.zip ]]&amp;lt;br /&amp;gt;enthält ASM-Source, XLS-Rechenhilfe für Interrupt-Timing, Schaltplan-/Layout-Ausdruck&lt;br /&gt;
* [[Media:Codeschloss_C.zip | Codeschloss_C.zip]]&amp;lt;br /&amp;gt;Version in C (WinAVR-20100110), mit .hex- und .epp-Datei&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:AVR-Projekte]]&lt;/div&gt;</summary>
		<author><name>Stefan1971</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Datei:Codeschloss_C.zip&amp;diff=61522</id>
		<title>Datei:Codeschloss C.zip</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Datei:Codeschloss_C.zip&amp;diff=61522"/>
		<updated>2011-11-08T15:08:19Z</updated>

		<summary type="html">&lt;p&gt;Stefan1971: Codeschloss (C-Source, .hex- und .eep-Datei)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Codeschloss (C-Source, .hex- und .eep-Datei)&lt;/div&gt;</summary>
		<author><name>Stefan1971</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Datei:Codeschloss.zip&amp;diff=38676</id>
		<title>Datei:Codeschloss.zip</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Datei:Codeschloss.zip&amp;diff=38676"/>
		<updated>2009-09-03T19:59:42Z</updated>

		<summary type="html">&lt;p&gt;Stefan1971: hat eine neue Version von „Bild:Codeschloss.zip“ hochgeladen: ASM-Source, XLS-Rechenhilfe für Interrupt-Timing, Schaltplan-/Layout-Ausdrucke&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;ASM-Source, XLS-Rechenhilfe für Interrupt-Timing, Schaltplan-/Layout-Ausdrucke&lt;/div&gt;</summary>
		<author><name>Stefan1971</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Codeschloss&amp;diff=38642</id>
		<title>Codeschloss</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Codeschloss&amp;diff=38642"/>
		<updated>2009-09-02T20:11:52Z</updated>

		<summary type="html">&lt;p&gt;Stefan1971: /* Ergänzung der Fuses-Tabelle */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;von Stefan1971&lt;br /&gt;
&lt;br /&gt;
=== Einleitung ===&lt;br /&gt;
&lt;br /&gt;
Im Folgenden beschreibe ich ein Haustür-Codeschloss, das als kleines AVR-Projekt in Hard- und Software umgesetzt ist und mittlerweile seinen Dienst am Klingelschild einer Haustüre versieht. Durch Eingabe des richtigen Codes lässt sich damit die Haustüre ohne Schlüssel öffnen.&lt;br /&gt;
&lt;br /&gt;
=== Merkmale ===&lt;br /&gt;
* Codeschloss mit ATtiny2313 zum Schalten eines elektrischen Türöffners über Relais&lt;br /&gt;
* Programmierbarer Tastencode zum Öffnen der Haustür kann aus bis zu 12 Tasten bestehen&lt;br /&gt;
* Aktivierdauer des Türöffners ist einstellbar&lt;br /&gt;
* Einzelne Taster oder alternativ eine 4x3-Matrixtastatur können angeschlossen werden&lt;br /&gt;
* Rote LED, wenn Codeeingabe läuft (leuchtet, sobald erste richtige Codetaste gedrückt wurde; verlöscht bei Zeitablauf in der Codeeingabe bzw. zusammen mit Abschalten des Türöffners)&lt;br /&gt;
* Gelbe LED leuchtet, wenn Codeschloss in Programmiermodus ist (=Lernen eines Codes) und blinkt, wenn Aktivierzeit für den Türöffner eingestellt wird&lt;br /&gt;
* Grüne LED zur Anzeige, ob Türöffner gerade geschaltet ist&lt;br /&gt;
* Wenn der Türöffner gerade aktiv ist, kann er durch Drücken einer beliebigen Codetaste vor Ablauf des Timers abgeschaltet werden&lt;br /&gt;
* Anschlüsse sind vorgesehen für die 12 Volt-Stromversorgung (Wechselspannung), eine LED als Türschildbeleuchtung und den Türöffner. Für die Codetasten gibt es eine Anschlussbuchse.&lt;br /&gt;
&lt;br /&gt;
=== Programmierung zur Nutzung ===&lt;br /&gt;
==== Programmieren des Codes ====&lt;br /&gt;
Durch Drücken des Programmiertasters auf der Schaltung wird in den Programmiermodus gewechselt. Dieser wird durch Leuchten der gelben LED angezeigt. Nun sind die Tasten in der gewünschten Reihenfolge zu betätigen. Der Code kann aus bis zu zwölf Tastendrücken bestehen. Die Programmierung ist durch erneutes Drücken des Programmiertasters abzuschließen. Damit ist der Tastencode gespeichert. Werden bei der Programmierung die maximal möglichen Tasten gedrückt (derzeit 12), beendet sich der Programmiermodus ohne Betätigen des Programmiertasters.&lt;br /&gt;
&lt;br /&gt;
==== Programmieren der Aktivierdauer des Türöffners ====&lt;br /&gt;
Wird der Programmiertaster im Programmiermodus (d.h. die gelbe LED leuchtet) gedrückt, ohne dass eine Codetaste zum Lernen eines neuen Codes betätigt wurde, so wechselt das Codeschloss in die Programmierung für die Aktivierdauer des Türöffners. Die gelbe LED zeigt dies durch Blinken an. In diesem Modus erfolgt mit der Taste 1 eine Testauslösung des Türöffners, mit der Taste 2 kann die Dauer verlängert, mit Taste 3 die Dauer verkürzt werden.&lt;br /&gt;
&lt;br /&gt;
Ist eine Matrixtastatur angeschlossen, werden andere Tasten verwendet: Hier erfolgt die Testauslösung mit der Taste (*). Die Taste (7) verlängert und die Taste (4) verkürzt die Dauer.&lt;br /&gt;
&lt;br /&gt;
Die Dauer wird in Stufen von ca. 0,2 Sekunden eingestellt. &lt;br /&gt;
&lt;br /&gt;
Erneutes Drücken des Programmiertasters speichert die Einstellung, die gelbe LED erlischt. Jede andere Taste als 1, 2, 3 bzw. (*), (7) oder (4) bricht die Programmierung ab und verwirft evtl. gemachte Änderungen an der Aktivierdauer.&lt;br /&gt;
&lt;br /&gt;
=== Software ===&lt;br /&gt;
Das Steuerprogramm ist in Assembler programmiert. Über bedingte Assemblierung im Quelltext kann auf die Zielplattformen ATmega8 oder ATtiny2313 assembliert werden. Hintergrund ist, dass zuerst auf einem [http://www.myavr.de myAVR Board] mit ATmega8 entwickelt und später für den Selbstbau auf den ATtiny2313 umgeschwenkt wurde.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Folgende interne Zustände werden in der Firmware unterschieden:&lt;br /&gt;
! Status  !! Beschreibung&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;SCAN&#039;&#039;&#039;|| SCAN ist der Default-Modus im laufenden Betrieb. Warten auf Tasten in der richtigen Reihenfolge. Tastendruck gilt als erfolgt, wenn Taste losgelassen wurde. Mit Loslassen der ersten richtigen Taste wird (Software-) Timer gestartet. Rote LED leuchtet.&amp;lt;br /&amp;gt;Nächste Taste war richtig: Zeiger wird auf nächste zu erwartende Taste weiter gestellt, Timer wird zurückgesetzt.&amp;lt;br /&amp;gt;Taste war falsch: Zeiger auf Anfang, LED aus, Timer deaktivieren.&amp;lt;br /&amp;gt;Timer abgelaufen: Zeiger auf Anfang, LED aus; wie bei falscher Taste&amp;lt;br /&amp;gt;Anzeigen des SCAN-Modus durch Leuchten der roten LED, sobald die erste richtige Taste betätigt (d.h. losgelassen) wurde.&amp;lt;br /&amp;gt;Wenn alle Tasten in der richtigen Reihenfolge richtig gedrückt wurden, erfolgt Wechsel in Status OPEN.&amp;lt;br /&amp;gt;Wenn Programmierkontakt erkannt wurde, Wechsel in den PROG-Modus.&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;OPEN&#039;&#039;&#039; || Timer für Türöffner mit programmiertem Wert (aus Status PROG_DOOR) starten, grüne LED leuchtet, rote LED ebenfalls, Türöffner aktiv&amp;lt;br /&amp;gt;Timer abgelaufen: Türöffner aus, LEDs aus, zurück in SCAN-Modus&amp;lt;br /&amp;gt;Beliebige Taste wird gedrückt (Schließen ist relevant, nicht Öffnen): Türöffner aus, grüne und rote LED aus; zurück in SCAN-Modus: wie Timer-Ablauf&amp;lt;br /&amp;gt;Der Abbruch des OPEN-Modus durch Drücken einer beliebigen Taste ist realisiert, indem das Drücken einer falschen Taste simuliert wird.&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PROG&#039;&#039;&#039; || Programmiermodus: Tritt ein, wenn im SCAN-Modus der Programmierkontakt betätigt (=losgelassen) wurde. Ende des Programmiermodus, wenn Programmierkontakt erneut betätigt wird. Im Programmiermodus werden die betätigten Tasten (Loslassen der Taste, wie im SCAN-Modus) nacheinander im SRAM festgehalten. Hierzu wird Index auf SRAM-Tastenspeicher zunächst auf Null gesetzt. Bei Ende des Programmiermodus wird die im SRAM festgehaltene Tastenfolge ins EEPROM übernommen. Beenden des Programmiermodus, ohne dass eine Taste während des Programmiermodus betätigt wurde, erhält den bisher eingestellten Code; dann keine Übernahme ins EEPROM. Beenden des Programmiermodus führt dann in die Programmierung der Aktivierdauer des Türöffners; Wechsel in Modus PROG_DOOR.&amp;lt;br /&amp;gt;Eine begonnene Programmierung, bei der irrtümlich falsche Tasten gedrückt wurden, kann nicht storniert werden, sondern muss erneut durchgeführt werden. Im Programmiermodus leuchtet die gelbe LED.&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PROG_DOOR&#039;&#039;&#039; || Dient zur Programmierung der Aktivierdauer des Türöffners.&amp;lt;br /&amp;gt;Um in diesen Modus zu gelangen, muss der Programmierkontakt zweimal betätigt werden, d.h. der Code-Programmiermodus muss ohne Druck einer Codetaste beendet (übersprungen) werden. Im PROG_DOOR-Modus blinkt die gelbe LED.&amp;lt;br /&amp;gt;Die Tasten des Codeschlosses erhalten im PROG_DOOR-Modus folgende Bedeutung:&amp;lt;br /&amp;gt;Taste 1: löst den Türöffner für die eingestellte Zeit zum Test aus (per Timer)&amp;lt;br /&amp;gt;Taste 2: verlängert mit jedem Tastendruck die eingestellte Zeit&amp;lt;br /&amp;gt;Taste 3: verkürzt mit jedem Tastendruck die eingestellte Zeit&amp;lt;br /&amp;gt;Jede andere Taste: Verwirft die Änderungen und verlässt den PROG_DOOR-Modus, Rückkehr in den SCAN-Modus.&amp;lt;br /&amp;gt;Abschließendes Betätigen des Programmierkontakts führt zu Übernahme des neuen Timer-Ladewerts ins EEPROM und beendet den PROG_DOOR-Modus. Wechsel in den SCAN-Modus.&lt;br /&gt;
Ist eine 4x3-Matrixtastatur angeschlossen, ist die Tastenbelegung für die Programmierung der Türöffneraktivierdauer wie folgt:&amp;lt;br /&amp;gt;Taste (*): Türöffner testhalber auslösen&amp;lt;br /&amp;gt;Taste (7): Aktivierdauer verlängern&amp;lt;br /&amp;gt;Taste (4): Aktivierdauer verkürzen&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;STARTUP&#039;&#039;&#039; || In diesen Modus wird beim Start der Anwendung zunächst gewechselt. Er hat den Zweck, die drei LEDs des Codeschlosses dreimal blinken zu lassen um anzuzeigen, dass der Controller arbeitet und auf Eingaben wartet. Wenn diese Phase abgelaufen ist, wird in den SCAN-Modus gewechselt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Hardware ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Belegung der Ports beim ATtiny2313:&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;PB0 ... PB7&#039;&#039;&#039; || IN || 8 Tasten zur Codeeingabe&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD6&#039;&#039;&#039; || IN || Programmierkontakt&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD0&#039;&#039;&#039; || OUT || Türöffner&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD1&#039;&#039;&#039; || OUT || Rote LED (laufende Codeeingabe)&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD2&#039;&#039;&#039; || OUT || Gelbe LED (Programmiermodus)&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD3&#039;&#039;&#039; || OUT || Grüne LED (Türöffner ist aktiv)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Einzelne Tasten werden mit jeweils einem Kontakt an Pin0 bis Pin7 angeschlossen, mit dem anderen Kontakt an Masse. Welche Tastatur (einzelne Tasten oder 4x3-Matrixtastatur) angeschlossen ist, wird über den bei der Matrixtastatur nicht benötigten Pin acht (PB7) gesteuert. Ist dieser beim Anwendungsstart auf Masse geschlossen, wird auf Abtastung einer Matrixtastatur umgestellt.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot; width=&amp;quot;25%&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Anschlussschema für 4x3-Matrixtastatur:&lt;br /&gt;
| width=&amp;quot;40%&amp;quot; | &#039;&#039;&#039;IN / OUT&#039;&#039;&#039; || style=&amp;quot;text-align:center&amp;quot; width=&amp;quot;20%&amp;quot; | &#039;&#039;&#039;Pin4&#039;&#039;&#039; || style=&amp;quot;text-align:center&amp;quot; width=&amp;quot;20%&amp;quot; | &#039;&#039;&#039;Pin5&#039;&#039;&#039; || style=&amp;quot;text-align:center&amp;quot; width=&amp;quot;20%&amp;quot; | &#039;&#039;&#039;Pin6&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin0&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | 1 || style=&amp;quot;text-align:center&amp;quot; | 2 || style=&amp;quot;text-align:center&amp;quot; | 3&lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin1&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | 4 || style=&amp;quot;text-align:center&amp;quot; | 5 || style=&amp;quot;text-align:center&amp;quot; | 6&lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin2&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | 7 || style=&amp;quot;text-align:center&amp;quot; | 8 || style=&amp;quot;text-align:center&amp;quot; | 9  &lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin3&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | * || style=&amp;quot;text-align:center&amp;quot; | 0 || style=&amp;quot;text-align:center&amp;quot; | #  &lt;br /&gt;
|} Pin7 und Pin8 (Masse) sind dann dauerhaft miteinander verbunden.&lt;br /&gt;
&lt;br /&gt;
Bei Nutzung eines Reed-Relais als Schaltelement muss der Türöffner erfahrungsgemäß einen Widerstand von mindestens 20 Ohm haben.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Die Fuses des Controllers sind folgendermaßen gesetzt:&lt;br /&gt;
! Fuse !! Einstellung&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;SPIEN:&#039;&#039;&#039;|| Enabled&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;BODLEVEL:&#039;&#039;&#039; || Brown-out detection disabled&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;CKDIV8:&#039;&#039;&#039; || Enabled&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;SUT_CKSEL:&#039;&#039;&#039; || Int. RC Osc. 4 MHz; Startup-time: 14 CK + 65 ms&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;alle anderen:&#039;&#039;&#039; || Disabled&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Schaltplan und Platinenlayout wurden mit Target3001 erstellt.&lt;br /&gt;
&lt;br /&gt;
=== Bilder ===&lt;br /&gt;
[[Bild:Codeschloss_Platine_beschriftet.jpg|thumb|550px|none|Codeschloss-Platine]]&lt;br /&gt;
[[Bild:Codeschloss_Platine_Keypad_Ausschnitt.jpg|thumb|220px|none|Anschluss einer Matrixtastatur]]&lt;br /&gt;
&lt;br /&gt;
=== Download ===&lt;br /&gt;
* [[Media:Codeschloss.zip | Codeschloss.zip ]]&amp;lt;br /&amp;gt;enthält ASM-Source, XLS-Rechenhilfe für Interrupt-Timing, Schaltplan-/Layout-Ausdruck&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Projekte]]&lt;br /&gt;
[[Category:AVR]]&lt;/div&gt;</summary>
		<author><name>Stefan1971</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Codeschloss&amp;diff=38595</id>
		<title>Codeschloss</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Codeschloss&amp;diff=38595"/>
		<updated>2009-08-30T17:37:14Z</updated>

		<summary type="html">&lt;p&gt;Stefan1971: / * Bilderlayout korrigiert (none-Tag eingesetzt) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;von Stefan1971&lt;br /&gt;
&lt;br /&gt;
=== Einleitung ===&lt;br /&gt;
&lt;br /&gt;
Im Folgenden beschreibe ich ein Haustür-Codeschloss, das als kleines AVR-Projekt in Hard- und Software umgesetzt ist und mittlerweile seinen Dienst am Klingelschild einer Haustüre versieht. Durch Eingabe des richtigen Codes lässt sich damit die Haustüre ohne Schlüssel öffnen.&lt;br /&gt;
&lt;br /&gt;
=== Merkmale ===&lt;br /&gt;
* Codeschloss mit ATtiny2313 zum Schalten eines elektrischen Türöffners über Relais&lt;br /&gt;
* Programmierbarer Tastencode zum Öffnen der Haustür kann aus bis zu 12 Tasten bestehen&lt;br /&gt;
* Aktivierdauer des Türöffners ist einstellbar&lt;br /&gt;
* Einzelne Taster oder alternativ eine 4x3-Matrixtastatur können angeschlossen werden&lt;br /&gt;
* Rote LED, wenn Codeeingabe läuft (leuchtet, sobald erste richtige Codetaste gedrückt wurde; verlöscht bei Zeitablauf in der Codeeingabe bzw. zusammen mit Abschalten des Türöffners)&lt;br /&gt;
* Gelbe LED leuchtet, wenn Codeschloss in Programmiermodus ist (=Lernen eines Codes) und blinkt, wenn Aktivierzeit für den Türöffner eingestellt wird&lt;br /&gt;
* Grüne LED zur Anzeige, ob Türöffner gerade geschaltet ist&lt;br /&gt;
* Wenn der Türöffner gerade aktiv ist, kann er durch Drücken einer beliebigen Codetaste vor Ablauf des Timers abgeschaltet werden&lt;br /&gt;
* Anschlüsse sind vorgesehen für die 12 Volt-Stromversorgung (Wechselspannung), eine LED als Türschildbeleuchtung und den Türöffner. Für die Codetasten gibt es eine Anschlussbuchse.&lt;br /&gt;
&lt;br /&gt;
=== Programmierung zur Nutzung ===&lt;br /&gt;
==== Programmieren des Codes ====&lt;br /&gt;
Durch Drücken des Programmiertasters auf der Schaltung wird in den Programmiermodus gewechselt. Dieser wird durch Leuchten der gelben LED angezeigt. Nun sind die Tasten in der gewünschten Reihenfolge zu betätigen. Der Code kann aus bis zu zwölf Tastendrücken bestehen. Die Programmierung ist durch erneutes Drücken des Programmiertasters abzuschließen. Damit ist der Tastencode gespeichert. Werden bei der Programmierung die maximal möglichen Tasten gedrückt (derzeit 12), beendet sich der Programmiermodus ohne Betätigen des Programmiertasters.&lt;br /&gt;
&lt;br /&gt;
==== Programmieren der Aktivierdauer des Türöffners ====&lt;br /&gt;
Wird der Programmiertaster im Programmiermodus (d.h. die gelbe LED leuchtet) gedrückt, ohne dass eine Codetaste zum Lernen eines neuen Codes betätigt wurde, so wechselt das Codeschloss in die Programmierung für die Aktivierdauer des Türöffners. Die gelbe LED zeigt dies durch Blinken an. In diesem Modus erfolgt mit der Taste 1 eine Testauslösung des Türöffners, mit der Taste 2 kann die Dauer verlängert, mit Taste 3 die Dauer verkürzt werden.&lt;br /&gt;
&lt;br /&gt;
Ist eine Matrixtastatur angeschlossen, werden andere Tasten verwendet: Hier erfolgt die Testauslösung mit der Taste (*). Die Taste (7) verlängert und die Taste (4) verkürzt die Dauer.&lt;br /&gt;
&lt;br /&gt;
Die Dauer wird in Stufen von ca. 0,2 Sekunden eingestellt. &lt;br /&gt;
&lt;br /&gt;
Erneutes Drücken des Programmiertasters speichert die Einstellung, die gelbe LED erlischt. Jede andere Taste als 1, 2, 3 bzw. (*), (7) oder (4) bricht die Programmierung ab und verwirft evtl. gemachte Änderungen an der Aktivierdauer.&lt;br /&gt;
&lt;br /&gt;
=== Software ===&lt;br /&gt;
Das Steuerprogramm ist in Assembler programmiert. Über bedingte Assemblierung im Quelltext kann auf die Zielplattformen ATmega8 oder ATtiny2313 assembliert werden. Hintergrund ist, dass zuerst auf einem [http://www.myavr.de myAVR Board] mit ATmega8 entwickelt und später für den Selbstbau auf den ATtiny2313 umgeschwenkt wurde.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Folgende interne Zustände werden in der Firmware unterschieden:&lt;br /&gt;
! Status  !! Beschreibung&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;SCAN&#039;&#039;&#039;|| SCAN ist der Default-Modus im laufenden Betrieb. Warten auf Tasten in der richtigen Reihenfolge. Tastendruck gilt als erfolgt, wenn Taste losgelassen wurde. Mit Loslassen der ersten richtigen Taste wird (Software-) Timer gestartet. Rote LED leuchtet.&amp;lt;br /&amp;gt;Nächste Taste war richtig: Zeiger wird auf nächste zu erwartende Taste weiter gestellt, Timer wird zurückgesetzt.&amp;lt;br /&amp;gt;Taste war falsch: Zeiger auf Anfang, LED aus, Timer deaktivieren.&amp;lt;br /&amp;gt;Timer abgelaufen: Zeiger auf Anfang, LED aus; wie bei falscher Taste&amp;lt;br /&amp;gt;Anzeigen des SCAN-Modus durch Leuchten der roten LED, sobald die erste richtige Taste betätigt (d.h. losgelassen) wurde.&amp;lt;br /&amp;gt;Wenn alle Tasten in der richtigen Reihenfolge richtig gedrückt wurden, erfolgt Wechsel in Status OPEN.&amp;lt;br /&amp;gt;Wenn Programmierkontakt erkannt wurde, Wechsel in den PROG-Modus.&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;OPEN&#039;&#039;&#039; || Timer für Türöffner mit programmiertem Wert (aus Status PROG_DOOR) starten, grüne LED leuchtet, rote LED ebenfalls, Türöffner aktiv&amp;lt;br /&amp;gt;Timer abgelaufen: Türöffner aus, LEDs aus, zurück in SCAN-Modus&amp;lt;br /&amp;gt;Beliebige Taste wird gedrückt (Schließen ist relevant, nicht Öffnen): Türöffner aus, grüne und rote LED aus; zurück in SCAN-Modus: wie Timer-Ablauf&amp;lt;br /&amp;gt;Der Abbruch des OPEN-Modus durch Drücken einer beliebigen Taste ist realisiert, indem das Drücken einer falschen Taste simuliert wird.&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PROG&#039;&#039;&#039; || Programmiermodus: Tritt ein, wenn im SCAN-Modus der Programmierkontakt betätigt (=losgelassen) wurde. Ende des Programmiermodus, wenn Programmierkontakt erneut betätigt wird. Im Programmiermodus werden die betätigten Tasten (Loslassen der Taste, wie im SCAN-Modus) nacheinander im SRAM festgehalten. Hierzu wird Index auf SRAM-Tastenspeicher zunächst auf Null gesetzt. Bei Ende des Programmiermodus wird die im SRAM festgehaltene Tastenfolge ins EEPROM übernommen. Beenden des Programmiermodus, ohne dass eine Taste während des Programmiermodus betätigt wurde, erhält den bisher eingestellten Code; dann keine Übernahme ins EEPROM. Beenden des Programmiermodus führt dann in die Programmierung der Aktivierdauer des Türöffners; Wechsel in Modus PROG_DOOR.&amp;lt;br /&amp;gt;Eine begonnene Programmierung, bei der irrtümlich falsche Tasten gedrückt wurden, kann nicht storniert werden, sondern muss erneut durchgeführt werden. Im Programmiermodus leuchtet die gelbe LED.&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PROG_DOOR&#039;&#039;&#039; || Dient zur Programmierung der Aktivierdauer des Türöffners.&amp;lt;br /&amp;gt;Um in diesen Modus zu gelangen, muss der Programmierkontakt zweimal betätigt werden, d.h. der Code-Programmiermodus muss ohne Druck einer Codetaste beendet (übersprungen) werden. Im PROG_DOOR-Modus blinkt die gelbe LED.&amp;lt;br /&amp;gt;Die Tasten des Codeschlosses erhalten im PROG_DOOR-Modus folgende Bedeutung:&amp;lt;br /&amp;gt;Taste 1: löst den Türöffner für die eingestellte Zeit zum Test aus (per Timer)&amp;lt;br /&amp;gt;Taste 2: verlängert mit jedem Tastendruck die eingestellte Zeit&amp;lt;br /&amp;gt;Taste 3: verkürzt mit jedem Tastendruck die eingestellte Zeit&amp;lt;br /&amp;gt;Jede andere Taste: Verwirft die Änderungen und verlässt den PROG_DOOR-Modus, Rückkehr in den SCAN-Modus.&amp;lt;br /&amp;gt;Abschließendes Betätigen des Programmierkontakts führt zu Übernahme des neuen Timer-Ladewerts ins EEPROM und beendet den PROG_DOOR-Modus. Wechsel in den SCAN-Modus.&lt;br /&gt;
Ist eine 4x3-Matrixtastatur angeschlossen, ist die Tastenbelegung für die Programmierung der Türöffneraktivierdauer wie folgt:&amp;lt;br /&amp;gt;Taste (*): Türöffner testhalber auslösen&amp;lt;br /&amp;gt;Taste (7): Aktivierdauer verlängern&amp;lt;br /&amp;gt;Taste (4): Aktivierdauer verkürzen&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;STARTUP&#039;&#039;&#039; || In diesen Modus wird beim Start der Anwendung zunächst gewechselt. Er hat den Zweck, die drei LEDs des Codeschlosses dreimal blinken zu lassen um anzuzeigen, dass der Controller arbeitet und auf Eingaben wartet. Wenn diese Phase abgelaufen ist, wird in den SCAN-Modus gewechselt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Hardware ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Belegung der Ports beim ATtiny2313:&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;PB0 ... PB7&#039;&#039;&#039; || IN || 8 Tasten zur Codeeingabe&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD6&#039;&#039;&#039; || IN || Programmierkontakt&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD0&#039;&#039;&#039; || OUT || Türöffner&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD1&#039;&#039;&#039; || OUT || Rote LED (laufende Codeeingabe)&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD2&#039;&#039;&#039; || OUT || Gelbe LED (Programmiermodus)&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD3&#039;&#039;&#039; || OUT || Grüne LED (Türöffner ist aktiv)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Einzelne Tasten werden mit jeweils einem Kontakt an Pin0 bis Pin7 angeschlossen, mit dem anderen Kontakt an Masse. Welche Tastatur (einzelne Tasten oder 4x3-Matrixtastatur) angeschlossen ist, wird über den bei der Matrixtastatur nicht benötigten Pin acht (PB7) gesteuert. Ist dieser beim Anwendungsstart auf Masse geschlossen, wird auf Abtastung einer Matrixtastatur umgestellt.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot; width=&amp;quot;25%&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Anschlussschema für 4x3-Matrixtastatur:&lt;br /&gt;
| width=&amp;quot;40%&amp;quot; | &#039;&#039;&#039;IN / OUT&#039;&#039;&#039; || style=&amp;quot;text-align:center&amp;quot; width=&amp;quot;20%&amp;quot; | &#039;&#039;&#039;Pin4&#039;&#039;&#039; || style=&amp;quot;text-align:center&amp;quot; width=&amp;quot;20%&amp;quot; | &#039;&#039;&#039;Pin5&#039;&#039;&#039; || style=&amp;quot;text-align:center&amp;quot; width=&amp;quot;20%&amp;quot; | &#039;&#039;&#039;Pin6&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin0&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | 1 || style=&amp;quot;text-align:center&amp;quot; | 2 || style=&amp;quot;text-align:center&amp;quot; | 3&lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin1&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | 4 || style=&amp;quot;text-align:center&amp;quot; | 5 || style=&amp;quot;text-align:center&amp;quot; | 6&lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin2&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | 7 || style=&amp;quot;text-align:center&amp;quot; | 8 || style=&amp;quot;text-align:center&amp;quot; | 9  &lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin3&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | * || style=&amp;quot;text-align:center&amp;quot; | 0 || style=&amp;quot;text-align:center&amp;quot; | #  &lt;br /&gt;
|} Pin7 und Pin8 (Masse) sind dann dauerhaft miteinander verbunden.&lt;br /&gt;
&lt;br /&gt;
Schaltplan und Platinenlayout wurden mit Target3001 erstellt.&lt;br /&gt;
&lt;br /&gt;
Bei Nutzung eines Reed-Relais als Schaltelement muss der Türöffner erfahrungsgemäß einen Widerstand von mindestens 20 Ohm haben.&lt;br /&gt;
&lt;br /&gt;
=== Bilder ===&lt;br /&gt;
[[Bild:Codeschloss_Platine_beschriftet.jpg|thumb|550px|none|Codeschloss-Platine]]&lt;br /&gt;
[[Bild:Codeschloss_Platine_Keypad_Ausschnitt.jpg|thumb|220px|none|Anschluss einer Matrixtastatur]]&lt;br /&gt;
&lt;br /&gt;
=== Download ===&lt;br /&gt;
* [[Media:Codeschloss.zip | Codeschloss.zip ]]&amp;lt;br /&amp;gt;enthält ASM-Source, XLS-Rechenhilfe für Interrupt-Timing, Schaltplan-/Layout-Ausdruck&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Projekte]]&lt;br /&gt;
[[Category:AVR]]&lt;/div&gt;</summary>
		<author><name>Stefan1971</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Codeschloss&amp;diff=38592</id>
		<title>Codeschloss</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Codeschloss&amp;diff=38592"/>
		<updated>2009-08-30T16:49:33Z</updated>

		<summary type="html">&lt;p&gt;Stefan1971: /* Download */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;von Stefan1971&lt;br /&gt;
&lt;br /&gt;
=== Einleitung ===&lt;br /&gt;
&lt;br /&gt;
Im Folgenden beschreibe ich ein Haustür-Codeschloss, das als kleines AVR-Projekt in Hard- und Software umgesetzt ist und mittlerweile seinen Dienst am Klingelschild einer Haustüre versieht. Durch Eingabe des richtigen Codes lässt sich damit die Haustüre ohne Schlüssel öffnen.&lt;br /&gt;
&lt;br /&gt;
=== Merkmale ===&lt;br /&gt;
* Codeschloss mit ATtiny2313 zum Schalten eines elektrischen Türöffners über Relais&lt;br /&gt;
* Programmierbarer Tastencode zum Öffnen der Haustür kann aus bis zu 12 Tasten bestehen&lt;br /&gt;
* Aktivierdauer des Türöffners ist einstellbar&lt;br /&gt;
* Einzelne Taster oder alternativ eine 4x3-Matrixtastatur können angeschlossen werden&lt;br /&gt;
* Rote LED, wenn Codeeingabe läuft (leuchtet, sobald erste richtige Codetaste gedrückt wurde; verlöscht bei Zeitablauf in der Codeeingabe bzw. zusammen mit Abschalten des Türöffners)&lt;br /&gt;
* Gelbe LED leuchtet, wenn Codeschloss in Programmiermodus ist (=Lernen eines Codes) und blinkt, wenn Aktivierzeit für den Türöffner eingestellt wird&lt;br /&gt;
* Grüne LED zur Anzeige, ob Türöffner gerade geschaltet ist&lt;br /&gt;
* Wenn der Türöffner gerade aktiv ist, kann er durch Drücken einer beliebigen Codetaste vor Ablauf des Timers abgeschaltet werden&lt;br /&gt;
* Anschlüsse sind vorgesehen für die 12 Volt-Stromversorgung (Wechselspannung), eine LED als Türschildbeleuchtung und den Türöffner. Für die Codetasten gibt es eine Anschlussbuchse.&lt;br /&gt;
&lt;br /&gt;
=== Programmierung zur Nutzung ===&lt;br /&gt;
==== Programmieren des Codes ====&lt;br /&gt;
Durch Drücken des Programmiertasters auf der Schaltung wird in den Programmiermodus gewechselt. Dieser wird durch Leuchten der gelben LED angezeigt. Nun sind die Tasten in der gewünschten Reihenfolge zu betätigen. Der Code kann aus bis zu zwölf Tastendrücken bestehen. Die Programmierung ist durch erneutes Drücken des Programmiertasters abzuschließen. Damit ist der Tastencode gespeichert. Werden bei der Programmierung die maximal möglichen Tasten gedrückt (derzeit 12), beendet sich der Programmiermodus ohne Betätigen des Programmiertasters.&lt;br /&gt;
&lt;br /&gt;
==== Programmieren der Aktivierdauer des Türöffners ====&lt;br /&gt;
Wird der Programmiertaster im Programmiermodus (d.h. die gelbe LED leuchtet) gedrückt, ohne dass eine Codetaste zum Lernen eines neuen Codes betätigt wurde, so wechselt das Codeschloss in die Programmierung für die Aktivierdauer des Türöffners. Die gelbe LED zeigt dies durch Blinken an. In diesem Modus erfolgt mit der Taste 1 eine Testauslösung des Türöffners, mit der Taste 2 kann die Dauer verlängert, mit Taste 3 die Dauer verkürzt werden.&lt;br /&gt;
&lt;br /&gt;
Ist eine Matrixtastatur angeschlossen, werden andere Tasten verwendet: Hier erfolgt die Testauslösung mit der Taste (*). Die Taste (7) verlängert und die Taste (4) verkürzt die Dauer.&lt;br /&gt;
&lt;br /&gt;
Die Dauer wird in Stufen von ca. 0,2 Sekunden eingestellt. &lt;br /&gt;
&lt;br /&gt;
Erneutes Drücken des Programmiertasters speichert die Einstellung, die gelbe LED erlischt. Jede andere Taste als 1, 2, 3 bzw. (*), (7) oder (4) bricht die Programmierung ab und verwirft evtl. gemachte Änderungen an der Aktivierdauer.&lt;br /&gt;
&lt;br /&gt;
=== Software ===&lt;br /&gt;
Das Steuerprogramm ist in Assembler programmiert. Über bedingte Assemblierung im Quelltext kann auf die Zielplattformen ATmega8 oder ATtiny2313 assembliert werden. Hintergrund ist, dass zuerst auf einem [http://www.myavr.de myAVR Board] mit ATmega8 entwickelt und später für den Selbstbau auf den ATtiny2313 umgeschwenkt wurde.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Folgende interne Zustände werden in der Firmware unterschieden:&lt;br /&gt;
! Status  !! Beschreibung&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;SCAN&#039;&#039;&#039;|| SCAN ist der Default-Modus im laufenden Betrieb. Warten auf Tasten in der richtigen Reihenfolge. Tastendruck gilt als erfolgt, wenn Taste losgelassen wurde. Mit Loslassen der ersten richtigen Taste wird (Software-) Timer gestartet. Rote LED leuchtet.&amp;lt;br /&amp;gt;Nächste Taste war richtig: Zeiger wird auf nächste zu erwartende Taste weiter gestellt, Timer wird zurückgesetzt.&amp;lt;br /&amp;gt;Taste war falsch: Zeiger auf Anfang, LED aus, Timer deaktivieren.&amp;lt;br /&amp;gt;Timer abgelaufen: Zeiger auf Anfang, LED aus; wie bei falscher Taste&amp;lt;br /&amp;gt;Anzeigen des SCAN-Modus durch Leuchten der roten LED, sobald die erste richtige Taste betätigt (d.h. losgelassen) wurde.&amp;lt;br /&amp;gt;Wenn alle Tasten in der richtigen Reihenfolge richtig gedrückt wurden, erfolgt Wechsel in Status OPEN.&amp;lt;br /&amp;gt;Wenn Programmierkontakt erkannt wurde, Wechsel in den PROG-Modus.&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;OPEN&#039;&#039;&#039; || Timer für Türöffner mit programmiertem Wert (aus Status PROG_DOOR) starten, grüne LED leuchtet, rote LED ebenfalls, Türöffner aktiv&amp;lt;br /&amp;gt;Timer abgelaufen: Türöffner aus, LEDs aus, zurück in SCAN-Modus&amp;lt;br /&amp;gt;Beliebige Taste wird gedrückt (Schließen ist relevant, nicht Öffnen): Türöffner aus, grüne und rote LED aus; zurück in SCAN-Modus: wie Timer-Ablauf&amp;lt;br /&amp;gt;Der Abbruch des OPEN-Modus durch Drücken einer beliebigen Taste ist realisiert, indem das Drücken einer falschen Taste simuliert wird.&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PROG&#039;&#039;&#039; || Programmiermodus: Tritt ein, wenn im SCAN-Modus der Programmierkontakt betätigt (=losgelassen) wurde. Ende des Programmiermodus, wenn Programmierkontakt erneut betätigt wird. Im Programmiermodus werden die betätigten Tasten (Loslassen der Taste, wie im SCAN-Modus) nacheinander im SRAM festgehalten. Hierzu wird Index auf SRAM-Tastenspeicher zunächst auf Null gesetzt. Bei Ende des Programmiermodus wird die im SRAM festgehaltene Tastenfolge ins EEPROM übernommen. Beenden des Programmiermodus, ohne dass eine Taste während des Programmiermodus betätigt wurde, erhält den bisher eingestellten Code; dann keine Übernahme ins EEPROM. Beenden des Programmiermodus führt dann in die Programmierung der Aktivierdauer des Türöffners; Wechsel in Modus PROG_DOOR.&amp;lt;br /&amp;gt;Eine begonnene Programmierung, bei der irrtümlich falsche Tasten gedrückt wurden, kann nicht storniert werden, sondern muss erneut durchgeführt werden. Im Programmiermodus leuchtet die gelbe LED.&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PROG_DOOR&#039;&#039;&#039; || Dient zur Programmierung der Aktivierdauer des Türöffners.&amp;lt;br /&amp;gt;Um in diesen Modus zu gelangen, muss der Programmierkontakt zweimal betätigt werden, d.h. der Code-Programmiermodus muss ohne Druck einer Codetaste beendet (übersprungen) werden. Im PROG_DOOR-Modus blinkt die gelbe LED.&amp;lt;br /&amp;gt;Die Tasten des Codeschlosses erhalten im PROG_DOOR-Modus folgende Bedeutung:&amp;lt;br /&amp;gt;Taste 1: löst den Türöffner für die eingestellte Zeit zum Test aus (per Timer)&amp;lt;br /&amp;gt;Taste 2: verlängert mit jedem Tastendruck die eingestellte Zeit&amp;lt;br /&amp;gt;Taste 3: verkürzt mit jedem Tastendruck die eingestellte Zeit&amp;lt;br /&amp;gt;Jede andere Taste: Verwirft die Änderungen und verlässt den PROG_DOOR-Modus, Rückkehr in den SCAN-Modus.&amp;lt;br /&amp;gt;Abschließendes Betätigen des Programmierkontakts führt zu Übernahme des neuen Timer-Ladewerts ins EEPROM und beendet den PROG_DOOR-Modus. Wechsel in den SCAN-Modus.&lt;br /&gt;
Ist eine 4x3-Matrixtastatur angeschlossen, ist die Tastenbelegung für die Programmierung der Türöffneraktivierdauer wie folgt:&amp;lt;br /&amp;gt;Taste (*): Türöffner testhalber auslösen&amp;lt;br /&amp;gt;Taste (7): Aktivierdauer verlängern&amp;lt;br /&amp;gt;Taste (4): Aktivierdauer verkürzen&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;STARTUP&#039;&#039;&#039; || In diesen Modus wird beim Start der Anwendung zunächst gewechselt. Er hat den Zweck, die drei LEDs des Codeschlosses dreimal blinken zu lassen um anzuzeigen, dass der Controller arbeitet und auf Eingaben wartet. Wenn diese Phase abgelaufen ist, wird in den SCAN-Modus gewechselt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Hardware ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Belegung der Ports beim ATtiny2313:&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;PB0 ... PB7&#039;&#039;&#039; || IN || 8 Tasten zur Codeeingabe&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD6&#039;&#039;&#039; || IN || Programmierkontakt&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD0&#039;&#039;&#039; || OUT || Türöffner&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD1&#039;&#039;&#039; || OUT || Rote LED (laufende Codeeingabe)&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD2&#039;&#039;&#039; || OUT || Gelbe LED (Programmiermodus)&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD3&#039;&#039;&#039; || OUT || Grüne LED (Türöffner ist aktiv)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Einzelne Tasten werden mit jeweils einem Kontakt an Pin0 bis Pin7 angeschlossen, mit dem anderen Kontakt an Masse. Welche Tastatur (einzelne Tasten oder 4x3-Matrixtastatur) angeschlossen ist, wird über den bei der Matrixtastatur nicht benötigten Pin acht (PB7) gesteuert. Ist dieser beim Anwendungsstart auf Masse geschlossen, wird auf Abtastung einer Matrixtastatur umgestellt.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot; width=&amp;quot;25%&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Anschlussschema für 4x3-Matrixtastatur:&lt;br /&gt;
| width=&amp;quot;40%&amp;quot; | &#039;&#039;&#039;IN / OUT&#039;&#039;&#039; || style=&amp;quot;text-align:center&amp;quot; width=&amp;quot;20%&amp;quot; | &#039;&#039;&#039;Pin4&#039;&#039;&#039; || style=&amp;quot;text-align:center&amp;quot; width=&amp;quot;20%&amp;quot; | &#039;&#039;&#039;Pin5&#039;&#039;&#039; || style=&amp;quot;text-align:center&amp;quot; width=&amp;quot;20%&amp;quot; | &#039;&#039;&#039;Pin6&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin0&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | 1 || style=&amp;quot;text-align:center&amp;quot; | 2 || style=&amp;quot;text-align:center&amp;quot; | 3&lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin1&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | 4 || style=&amp;quot;text-align:center&amp;quot; | 5 || style=&amp;quot;text-align:center&amp;quot; | 6&lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin2&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | 7 || style=&amp;quot;text-align:center&amp;quot; | 8 || style=&amp;quot;text-align:center&amp;quot; | 9  &lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin3&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | * || style=&amp;quot;text-align:center&amp;quot; | 0 || style=&amp;quot;text-align:center&amp;quot; | #  &lt;br /&gt;
|} Pin7 und Pin8 (Masse) sind dann dauerhaft miteinander verbunden.&lt;br /&gt;
&lt;br /&gt;
Schaltplan und Platinenlayout wurden mit Target3001 erstellt.&lt;br /&gt;
&lt;br /&gt;
Bei Nutzung eines Reed-Relais als Schaltelement muss der Türöffner erfahrungsgemäß einen Widerstand von mindestens 20 Ohm haben.&lt;br /&gt;
&lt;br /&gt;
=== Bilder ===&lt;br /&gt;
[[Bild:Codeschloss_Platine_beschriftet.jpg|thumb|550px|left|Codeschloss-Platine]]&lt;br /&gt;
[[Bild:Codeschloss_Platine_Keypad_Ausschnitt.jpg|thumb|220px|left|Anschluss einer Matrixtastatur]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Download ===&lt;br /&gt;
* [[Media:Codeschloss.zip | Codeschloss.zip ]]&amp;lt;br /&amp;gt;enthält ASM-Source, XLS-Rechenhilfe für Interrupt-Timing, Schaltplan-/Layout-Ausdruck&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Projekte]]&lt;br /&gt;
[[Category:AVR]]&lt;/div&gt;</summary>
		<author><name>Stefan1971</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Codeschloss&amp;diff=38591</id>
		<title>Codeschloss</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Codeschloss&amp;diff=38591"/>
		<updated>2009-08-30T16:44:13Z</updated>

		<summary type="html">&lt;p&gt;Stefan1971: /* Bilder - Layout geändert */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;von Stefan1971&lt;br /&gt;
&lt;br /&gt;
=== Einleitung ===&lt;br /&gt;
&lt;br /&gt;
Im Folgenden beschreibe ich ein Haustür-Codeschloss, das als kleines AVR-Projekt in Hard- und Software umgesetzt ist und mittlerweile seinen Dienst am Klingelschild einer Haustüre versieht. Durch Eingabe des richtigen Codes lässt sich damit die Haustüre ohne Schlüssel öffnen.&lt;br /&gt;
&lt;br /&gt;
=== Merkmale ===&lt;br /&gt;
* Codeschloss mit ATtiny2313 zum Schalten eines elektrischen Türöffners über Relais&lt;br /&gt;
* Programmierbarer Tastencode zum Öffnen der Haustür kann aus bis zu 12 Tasten bestehen&lt;br /&gt;
* Aktivierdauer des Türöffners ist einstellbar&lt;br /&gt;
* Einzelne Taster oder alternativ eine 4x3-Matrixtastatur können angeschlossen werden&lt;br /&gt;
* Rote LED, wenn Codeeingabe läuft (leuchtet, sobald erste richtige Codetaste gedrückt wurde; verlöscht bei Zeitablauf in der Codeeingabe bzw. zusammen mit Abschalten des Türöffners)&lt;br /&gt;
* Gelbe LED leuchtet, wenn Codeschloss in Programmiermodus ist (=Lernen eines Codes) und blinkt, wenn Aktivierzeit für den Türöffner eingestellt wird&lt;br /&gt;
* Grüne LED zur Anzeige, ob Türöffner gerade geschaltet ist&lt;br /&gt;
* Wenn der Türöffner gerade aktiv ist, kann er durch Drücken einer beliebigen Codetaste vor Ablauf des Timers abgeschaltet werden&lt;br /&gt;
* Anschlüsse sind vorgesehen für die 12 Volt-Stromversorgung (Wechselspannung), eine LED als Türschildbeleuchtung und den Türöffner. Für die Codetasten gibt es eine Anschlussbuchse.&lt;br /&gt;
&lt;br /&gt;
=== Programmierung zur Nutzung ===&lt;br /&gt;
==== Programmieren des Codes ====&lt;br /&gt;
Durch Drücken des Programmiertasters auf der Schaltung wird in den Programmiermodus gewechselt. Dieser wird durch Leuchten der gelben LED angezeigt. Nun sind die Tasten in der gewünschten Reihenfolge zu betätigen. Der Code kann aus bis zu zwölf Tastendrücken bestehen. Die Programmierung ist durch erneutes Drücken des Programmiertasters abzuschließen. Damit ist der Tastencode gespeichert. Werden bei der Programmierung die maximal möglichen Tasten gedrückt (derzeit 12), beendet sich der Programmiermodus ohne Betätigen des Programmiertasters.&lt;br /&gt;
&lt;br /&gt;
==== Programmieren der Aktivierdauer des Türöffners ====&lt;br /&gt;
Wird der Programmiertaster im Programmiermodus (d.h. die gelbe LED leuchtet) gedrückt, ohne dass eine Codetaste zum Lernen eines neuen Codes betätigt wurde, so wechselt das Codeschloss in die Programmierung für die Aktivierdauer des Türöffners. Die gelbe LED zeigt dies durch Blinken an. In diesem Modus erfolgt mit der Taste 1 eine Testauslösung des Türöffners, mit der Taste 2 kann die Dauer verlängert, mit Taste 3 die Dauer verkürzt werden.&lt;br /&gt;
&lt;br /&gt;
Ist eine Matrixtastatur angeschlossen, werden andere Tasten verwendet: Hier erfolgt die Testauslösung mit der Taste (*). Die Taste (7) verlängert und die Taste (4) verkürzt die Dauer.&lt;br /&gt;
&lt;br /&gt;
Die Dauer wird in Stufen von ca. 0,2 Sekunden eingestellt. &lt;br /&gt;
&lt;br /&gt;
Erneutes Drücken des Programmiertasters speichert die Einstellung, die gelbe LED erlischt. Jede andere Taste als 1, 2, 3 bzw. (*), (7) oder (4) bricht die Programmierung ab und verwirft evtl. gemachte Änderungen an der Aktivierdauer.&lt;br /&gt;
&lt;br /&gt;
=== Software ===&lt;br /&gt;
Das Steuerprogramm ist in Assembler programmiert. Über bedingte Assemblierung im Quelltext kann auf die Zielplattformen ATmega8 oder ATtiny2313 assembliert werden. Hintergrund ist, dass zuerst auf einem [http://www.myavr.de myAVR Board] mit ATmega8 entwickelt und später für den Selbstbau auf den ATtiny2313 umgeschwenkt wurde.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Folgende interne Zustände werden in der Firmware unterschieden:&lt;br /&gt;
! Status  !! Beschreibung&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;SCAN&#039;&#039;&#039;|| SCAN ist der Default-Modus im laufenden Betrieb. Warten auf Tasten in der richtigen Reihenfolge. Tastendruck gilt als erfolgt, wenn Taste losgelassen wurde. Mit Loslassen der ersten richtigen Taste wird (Software-) Timer gestartet. Rote LED leuchtet.&amp;lt;br /&amp;gt;Nächste Taste war richtig: Zeiger wird auf nächste zu erwartende Taste weiter gestellt, Timer wird zurückgesetzt.&amp;lt;br /&amp;gt;Taste war falsch: Zeiger auf Anfang, LED aus, Timer deaktivieren.&amp;lt;br /&amp;gt;Timer abgelaufen: Zeiger auf Anfang, LED aus; wie bei falscher Taste&amp;lt;br /&amp;gt;Anzeigen des SCAN-Modus durch Leuchten der roten LED, sobald die erste richtige Taste betätigt (d.h. losgelassen) wurde.&amp;lt;br /&amp;gt;Wenn alle Tasten in der richtigen Reihenfolge richtig gedrückt wurden, erfolgt Wechsel in Status OPEN.&amp;lt;br /&amp;gt;Wenn Programmierkontakt erkannt wurde, Wechsel in den PROG-Modus.&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;OPEN&#039;&#039;&#039; || Timer für Türöffner mit programmiertem Wert (aus Status PROG_DOOR) starten, grüne LED leuchtet, rote LED ebenfalls, Türöffner aktiv&amp;lt;br /&amp;gt;Timer abgelaufen: Türöffner aus, LEDs aus, zurück in SCAN-Modus&amp;lt;br /&amp;gt;Beliebige Taste wird gedrückt (Schließen ist relevant, nicht Öffnen): Türöffner aus, grüne und rote LED aus; zurück in SCAN-Modus: wie Timer-Ablauf&amp;lt;br /&amp;gt;Der Abbruch des OPEN-Modus durch Drücken einer beliebigen Taste ist realisiert, indem das Drücken einer falschen Taste simuliert wird.&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PROG&#039;&#039;&#039; || Programmiermodus: Tritt ein, wenn im SCAN-Modus der Programmierkontakt betätigt (=losgelassen) wurde. Ende des Programmiermodus, wenn Programmierkontakt erneut betätigt wird. Im Programmiermodus werden die betätigten Tasten (Loslassen der Taste, wie im SCAN-Modus) nacheinander im SRAM festgehalten. Hierzu wird Index auf SRAM-Tastenspeicher zunächst auf Null gesetzt. Bei Ende des Programmiermodus wird die im SRAM festgehaltene Tastenfolge ins EEPROM übernommen. Beenden des Programmiermodus, ohne dass eine Taste während des Programmiermodus betätigt wurde, erhält den bisher eingestellten Code; dann keine Übernahme ins EEPROM. Beenden des Programmiermodus führt dann in die Programmierung der Aktivierdauer des Türöffners; Wechsel in Modus PROG_DOOR.&amp;lt;br /&amp;gt;Eine begonnene Programmierung, bei der irrtümlich falsche Tasten gedrückt wurden, kann nicht storniert werden, sondern muss erneut durchgeführt werden. Im Programmiermodus leuchtet die gelbe LED.&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PROG_DOOR&#039;&#039;&#039; || Dient zur Programmierung der Aktivierdauer des Türöffners.&amp;lt;br /&amp;gt;Um in diesen Modus zu gelangen, muss der Programmierkontakt zweimal betätigt werden, d.h. der Code-Programmiermodus muss ohne Druck einer Codetaste beendet (übersprungen) werden. Im PROG_DOOR-Modus blinkt die gelbe LED.&amp;lt;br /&amp;gt;Die Tasten des Codeschlosses erhalten im PROG_DOOR-Modus folgende Bedeutung:&amp;lt;br /&amp;gt;Taste 1: löst den Türöffner für die eingestellte Zeit zum Test aus (per Timer)&amp;lt;br /&amp;gt;Taste 2: verlängert mit jedem Tastendruck die eingestellte Zeit&amp;lt;br /&amp;gt;Taste 3: verkürzt mit jedem Tastendruck die eingestellte Zeit&amp;lt;br /&amp;gt;Jede andere Taste: Verwirft die Änderungen und verlässt den PROG_DOOR-Modus, Rückkehr in den SCAN-Modus.&amp;lt;br /&amp;gt;Abschließendes Betätigen des Programmierkontakts führt zu Übernahme des neuen Timer-Ladewerts ins EEPROM und beendet den PROG_DOOR-Modus. Wechsel in den SCAN-Modus.&lt;br /&gt;
Ist eine 4x3-Matrixtastatur angeschlossen, ist die Tastenbelegung für die Programmierung der Türöffneraktivierdauer wie folgt:&amp;lt;br /&amp;gt;Taste (*): Türöffner testhalber auslösen&amp;lt;br /&amp;gt;Taste (7): Aktivierdauer verlängern&amp;lt;br /&amp;gt;Taste (4): Aktivierdauer verkürzen&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;STARTUP&#039;&#039;&#039; || In diesen Modus wird beim Start der Anwendung zunächst gewechselt. Er hat den Zweck, die drei LEDs des Codeschlosses dreimal blinken zu lassen um anzuzeigen, dass der Controller arbeitet und auf Eingaben wartet. Wenn diese Phase abgelaufen ist, wird in den SCAN-Modus gewechselt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Hardware ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Belegung der Ports beim ATtiny2313:&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;PB0 ... PB7&#039;&#039;&#039; || IN || 8 Tasten zur Codeeingabe&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD6&#039;&#039;&#039; || IN || Programmierkontakt&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD0&#039;&#039;&#039; || OUT || Türöffner&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD1&#039;&#039;&#039; || OUT || Rote LED (laufende Codeeingabe)&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD2&#039;&#039;&#039; || OUT || Gelbe LED (Programmiermodus)&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD3&#039;&#039;&#039; || OUT || Grüne LED (Türöffner ist aktiv)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Einzelne Tasten werden mit jeweils einem Kontakt an Pin0 bis Pin7 angeschlossen, mit dem anderen Kontakt an Masse. Welche Tastatur (einzelne Tasten oder 4x3-Matrixtastatur) angeschlossen ist, wird über den bei der Matrixtastatur nicht benötigten Pin acht (PB7) gesteuert. Ist dieser beim Anwendungsstart auf Masse geschlossen, wird auf Abtastung einer Matrixtastatur umgestellt.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot; width=&amp;quot;25%&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Anschlussschema für 4x3-Matrixtastatur:&lt;br /&gt;
| width=&amp;quot;40%&amp;quot; | &#039;&#039;&#039;IN / OUT&#039;&#039;&#039; || style=&amp;quot;text-align:center&amp;quot; width=&amp;quot;20%&amp;quot; | &#039;&#039;&#039;Pin4&#039;&#039;&#039; || style=&amp;quot;text-align:center&amp;quot; width=&amp;quot;20%&amp;quot; | &#039;&#039;&#039;Pin5&#039;&#039;&#039; || style=&amp;quot;text-align:center&amp;quot; width=&amp;quot;20%&amp;quot; | &#039;&#039;&#039;Pin6&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin0&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | 1 || style=&amp;quot;text-align:center&amp;quot; | 2 || style=&amp;quot;text-align:center&amp;quot; | 3&lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin1&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | 4 || style=&amp;quot;text-align:center&amp;quot; | 5 || style=&amp;quot;text-align:center&amp;quot; | 6&lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin2&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | 7 || style=&amp;quot;text-align:center&amp;quot; | 8 || style=&amp;quot;text-align:center&amp;quot; | 9  &lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin3&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | * || style=&amp;quot;text-align:center&amp;quot; | 0 || style=&amp;quot;text-align:center&amp;quot; | #  &lt;br /&gt;
|} Pin7 und Pin8 (Masse) sind dann dauerhaft miteinander verbunden.&lt;br /&gt;
&lt;br /&gt;
Schaltplan und Platinenlayout wurden mit Target3001 erstellt.&lt;br /&gt;
&lt;br /&gt;
Bei Nutzung eines Reed-Relais als Schaltelement muss der Türöffner erfahrungsgemäß einen Widerstand von mindestens 20 Ohm haben.&lt;br /&gt;
&lt;br /&gt;
=== Bilder ===&lt;br /&gt;
[[Bild:Codeschloss_Platine_beschriftet.jpg|thumb|550px|left|Codeschloss-Platine]]&lt;br /&gt;
[[Bild:Codeschloss_Platine_Keypad_Ausschnitt.jpg|thumb|220px|left|Anschluss einer Matrixtastatur]]&lt;br /&gt;
&lt;br /&gt;
=== Download ===&lt;br /&gt;
* [[Media:Codeschloss.zip | Codeschloss.zip ]]&amp;lt;br /&amp;gt;enthält ASM-Source, XLS-Rechenhilfe für Interrupt-Timing, Schaltplan-/Layout-Ausdruck&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Projekte]]&lt;br /&gt;
[[Category:AVR]]&lt;/div&gt;</summary>
		<author><name>Stefan1971</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Codeschloss&amp;diff=38590</id>
		<title>Codeschloss</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Codeschloss&amp;diff=38590"/>
		<updated>2009-08-30T16:42:21Z</updated>

		<summary type="html">&lt;p&gt;Stefan1971: /* Download ergänzt */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;von Stefan1971&lt;br /&gt;
&lt;br /&gt;
=== Einleitung ===&lt;br /&gt;
&lt;br /&gt;
Im Folgenden beschreibe ich ein Haustür-Codeschloss, das als kleines AVR-Projekt in Hard- und Software umgesetzt ist und mittlerweile seinen Dienst am Klingelschild einer Haustüre versieht. Durch Eingabe des richtigen Codes lässt sich damit die Haustüre ohne Schlüssel öffnen.&lt;br /&gt;
&lt;br /&gt;
=== Merkmale ===&lt;br /&gt;
* Codeschloss mit ATtiny2313 zum Schalten eines elektrischen Türöffners über Relais&lt;br /&gt;
* Programmierbarer Tastencode zum Öffnen der Haustür kann aus bis zu 12 Tasten bestehen&lt;br /&gt;
* Aktivierdauer des Türöffners ist einstellbar&lt;br /&gt;
* Einzelne Taster oder alternativ eine 4x3-Matrixtastatur können angeschlossen werden&lt;br /&gt;
* Rote LED, wenn Codeeingabe läuft (leuchtet, sobald erste richtige Codetaste gedrückt wurde; verlöscht bei Zeitablauf in der Codeeingabe bzw. zusammen mit Abschalten des Türöffners)&lt;br /&gt;
* Gelbe LED leuchtet, wenn Codeschloss in Programmiermodus ist (=Lernen eines Codes) und blinkt, wenn Aktivierzeit für den Türöffner eingestellt wird&lt;br /&gt;
* Grüne LED zur Anzeige, ob Türöffner gerade geschaltet ist&lt;br /&gt;
* Wenn der Türöffner gerade aktiv ist, kann er durch Drücken einer beliebigen Codetaste vor Ablauf des Timers abgeschaltet werden&lt;br /&gt;
* Anschlüsse sind vorgesehen für die 12 Volt-Stromversorgung (Wechselspannung), eine LED als Türschildbeleuchtung und den Türöffner. Für die Codetasten gibt es eine Anschlussbuchse.&lt;br /&gt;
&lt;br /&gt;
=== Programmierung zur Nutzung ===&lt;br /&gt;
==== Programmieren des Codes ====&lt;br /&gt;
Durch Drücken des Programmiertasters auf der Schaltung wird in den Programmiermodus gewechselt. Dieser wird durch Leuchten der gelben LED angezeigt. Nun sind die Tasten in der gewünschten Reihenfolge zu betätigen. Der Code kann aus bis zu zwölf Tastendrücken bestehen. Die Programmierung ist durch erneutes Drücken des Programmiertasters abzuschließen. Damit ist der Tastencode gespeichert. Werden bei der Programmierung die maximal möglichen Tasten gedrückt (derzeit 12), beendet sich der Programmiermodus ohne Betätigen des Programmiertasters.&lt;br /&gt;
&lt;br /&gt;
==== Programmieren der Aktivierdauer des Türöffners ====&lt;br /&gt;
Wird der Programmiertaster im Programmiermodus (d.h. die gelbe LED leuchtet) gedrückt, ohne dass eine Codetaste zum Lernen eines neuen Codes betätigt wurde, so wechselt das Codeschloss in die Programmierung für die Aktivierdauer des Türöffners. Die gelbe LED zeigt dies durch Blinken an. In diesem Modus erfolgt mit der Taste 1 eine Testauslösung des Türöffners, mit der Taste 2 kann die Dauer verlängert, mit Taste 3 die Dauer verkürzt werden.&lt;br /&gt;
&lt;br /&gt;
Ist eine Matrixtastatur angeschlossen, werden andere Tasten verwendet: Hier erfolgt die Testauslösung mit der Taste (*). Die Taste (7) verlängert und die Taste (4) verkürzt die Dauer.&lt;br /&gt;
&lt;br /&gt;
Die Dauer wird in Stufen von ca. 0,2 Sekunden eingestellt. &lt;br /&gt;
&lt;br /&gt;
Erneutes Drücken des Programmiertasters speichert die Einstellung, die gelbe LED erlischt. Jede andere Taste als 1, 2, 3 bzw. (*), (7) oder (4) bricht die Programmierung ab und verwirft evtl. gemachte Änderungen an der Aktivierdauer.&lt;br /&gt;
&lt;br /&gt;
=== Software ===&lt;br /&gt;
Das Steuerprogramm ist in Assembler programmiert. Über bedingte Assemblierung im Quelltext kann auf die Zielplattformen ATmega8 oder ATtiny2313 assembliert werden. Hintergrund ist, dass zuerst auf einem [http://www.myavr.de myAVR Board] mit ATmega8 entwickelt und später für den Selbstbau auf den ATtiny2313 umgeschwenkt wurde.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Folgende interne Zustände werden in der Firmware unterschieden:&lt;br /&gt;
! Status  !! Beschreibung&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;SCAN&#039;&#039;&#039;|| SCAN ist der Default-Modus im laufenden Betrieb. Warten auf Tasten in der richtigen Reihenfolge. Tastendruck gilt als erfolgt, wenn Taste losgelassen wurde. Mit Loslassen der ersten richtigen Taste wird (Software-) Timer gestartet. Rote LED leuchtet.&amp;lt;br /&amp;gt;Nächste Taste war richtig: Zeiger wird auf nächste zu erwartende Taste weiter gestellt, Timer wird zurückgesetzt.&amp;lt;br /&amp;gt;Taste war falsch: Zeiger auf Anfang, LED aus, Timer deaktivieren.&amp;lt;br /&amp;gt;Timer abgelaufen: Zeiger auf Anfang, LED aus; wie bei falscher Taste&amp;lt;br /&amp;gt;Anzeigen des SCAN-Modus durch Leuchten der roten LED, sobald die erste richtige Taste betätigt (d.h. losgelassen) wurde.&amp;lt;br /&amp;gt;Wenn alle Tasten in der richtigen Reihenfolge richtig gedrückt wurden, erfolgt Wechsel in Status OPEN.&amp;lt;br /&amp;gt;Wenn Programmierkontakt erkannt wurde, Wechsel in den PROG-Modus.&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;OPEN&#039;&#039;&#039; || Timer für Türöffner mit programmiertem Wert (aus Status PROG_DOOR) starten, grüne LED leuchtet, rote LED ebenfalls, Türöffner aktiv&amp;lt;br /&amp;gt;Timer abgelaufen: Türöffner aus, LEDs aus, zurück in SCAN-Modus&amp;lt;br /&amp;gt;Beliebige Taste wird gedrückt (Schließen ist relevant, nicht Öffnen): Türöffner aus, grüne und rote LED aus; zurück in SCAN-Modus: wie Timer-Ablauf&amp;lt;br /&amp;gt;Der Abbruch des OPEN-Modus durch Drücken einer beliebigen Taste ist realisiert, indem das Drücken einer falschen Taste simuliert wird.&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PROG&#039;&#039;&#039; || Programmiermodus: Tritt ein, wenn im SCAN-Modus der Programmierkontakt betätigt (=losgelassen) wurde. Ende des Programmiermodus, wenn Programmierkontakt erneut betätigt wird. Im Programmiermodus werden die betätigten Tasten (Loslassen der Taste, wie im SCAN-Modus) nacheinander im SRAM festgehalten. Hierzu wird Index auf SRAM-Tastenspeicher zunächst auf Null gesetzt. Bei Ende des Programmiermodus wird die im SRAM festgehaltene Tastenfolge ins EEPROM übernommen. Beenden des Programmiermodus, ohne dass eine Taste während des Programmiermodus betätigt wurde, erhält den bisher eingestellten Code; dann keine Übernahme ins EEPROM. Beenden des Programmiermodus führt dann in die Programmierung der Aktivierdauer des Türöffners; Wechsel in Modus PROG_DOOR.&amp;lt;br /&amp;gt;Eine begonnene Programmierung, bei der irrtümlich falsche Tasten gedrückt wurden, kann nicht storniert werden, sondern muss erneut durchgeführt werden. Im Programmiermodus leuchtet die gelbe LED.&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PROG_DOOR&#039;&#039;&#039; || Dient zur Programmierung der Aktivierdauer des Türöffners.&amp;lt;br /&amp;gt;Um in diesen Modus zu gelangen, muss der Programmierkontakt zweimal betätigt werden, d.h. der Code-Programmiermodus muss ohne Druck einer Codetaste beendet (übersprungen) werden. Im PROG_DOOR-Modus blinkt die gelbe LED.&amp;lt;br /&amp;gt;Die Tasten des Codeschlosses erhalten im PROG_DOOR-Modus folgende Bedeutung:&amp;lt;br /&amp;gt;Taste 1: löst den Türöffner für die eingestellte Zeit zum Test aus (per Timer)&amp;lt;br /&amp;gt;Taste 2: verlängert mit jedem Tastendruck die eingestellte Zeit&amp;lt;br /&amp;gt;Taste 3: verkürzt mit jedem Tastendruck die eingestellte Zeit&amp;lt;br /&amp;gt;Jede andere Taste: Verwirft die Änderungen und verlässt den PROG_DOOR-Modus, Rückkehr in den SCAN-Modus.&amp;lt;br /&amp;gt;Abschließendes Betätigen des Programmierkontakts führt zu Übernahme des neuen Timer-Ladewerts ins EEPROM und beendet den PROG_DOOR-Modus. Wechsel in den SCAN-Modus.&lt;br /&gt;
Ist eine 4x3-Matrixtastatur angeschlossen, ist die Tastenbelegung für die Programmierung der Türöffneraktivierdauer wie folgt:&amp;lt;br /&amp;gt;Taste (*): Türöffner testhalber auslösen&amp;lt;br /&amp;gt;Taste (7): Aktivierdauer verlängern&amp;lt;br /&amp;gt;Taste (4): Aktivierdauer verkürzen&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;STARTUP&#039;&#039;&#039; || In diesen Modus wird beim Start der Anwendung zunächst gewechselt. Er hat den Zweck, die drei LEDs des Codeschlosses dreimal blinken zu lassen um anzuzeigen, dass der Controller arbeitet und auf Eingaben wartet. Wenn diese Phase abgelaufen ist, wird in den SCAN-Modus gewechselt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Hardware ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Belegung der Ports beim ATtiny2313:&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;PB0 ... PB7&#039;&#039;&#039; || IN || 8 Tasten zur Codeeingabe&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD6&#039;&#039;&#039; || IN || Programmierkontakt&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD0&#039;&#039;&#039; || OUT || Türöffner&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD1&#039;&#039;&#039; || OUT || Rote LED (laufende Codeeingabe)&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD2&#039;&#039;&#039; || OUT || Gelbe LED (Programmiermodus)&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD3&#039;&#039;&#039; || OUT || Grüne LED (Türöffner ist aktiv)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Einzelne Tasten werden mit jeweils einem Kontakt an Pin0 bis Pin7 angeschlossen, mit dem anderen Kontakt an Masse. Welche Tastatur (einzelne Tasten oder 4x3-Matrixtastatur) angeschlossen ist, wird über den bei der Matrixtastatur nicht benötigten Pin acht (PB7) gesteuert. Ist dieser beim Anwendungsstart auf Masse geschlossen, wird auf Abtastung einer Matrixtastatur umgestellt.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot; width=&amp;quot;25%&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Anschlussschema für 4x3-Matrixtastatur:&lt;br /&gt;
| width=&amp;quot;40%&amp;quot; | &#039;&#039;&#039;IN / OUT&#039;&#039;&#039; || style=&amp;quot;text-align:center&amp;quot; width=&amp;quot;20%&amp;quot; | &#039;&#039;&#039;Pin4&#039;&#039;&#039; || style=&amp;quot;text-align:center&amp;quot; width=&amp;quot;20%&amp;quot; | &#039;&#039;&#039;Pin5&#039;&#039;&#039; || style=&amp;quot;text-align:center&amp;quot; width=&amp;quot;20%&amp;quot; | &#039;&#039;&#039;Pin6&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin0&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | 1 || style=&amp;quot;text-align:center&amp;quot; | 2 || style=&amp;quot;text-align:center&amp;quot; | 3&lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin1&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | 4 || style=&amp;quot;text-align:center&amp;quot; | 5 || style=&amp;quot;text-align:center&amp;quot; | 6&lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin2&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | 7 || style=&amp;quot;text-align:center&amp;quot; | 8 || style=&amp;quot;text-align:center&amp;quot; | 9  &lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin3&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | * || style=&amp;quot;text-align:center&amp;quot; | 0 || style=&amp;quot;text-align:center&amp;quot; | #  &lt;br /&gt;
|} Pin7 und Pin8 (Masse) sind dann dauerhaft miteinander verbunden.&lt;br /&gt;
&lt;br /&gt;
Schaltplan und Platinenlayout wurden mit Target3001 erstellt.&lt;br /&gt;
&lt;br /&gt;
Bei Nutzung eines Reed-Relais als Schaltelement muss der Türöffner erfahrungsgemäß einen Widerstand von mindestens 20 Ohm haben.&lt;br /&gt;
&lt;br /&gt;
=== Bilder ===&lt;br /&gt;
[[Bild:Codeschloss_Platine_beschriftet.jpg|thumb|550px|left|Codeschloss-Platine]]&lt;br /&gt;
[[Bild:Codeschloss_Platine_Keypad_Ausschnitt.jpg|thumb|220px|Anschluss einer Matrixtastatur]]&lt;br /&gt;
&lt;br /&gt;
=== Download ===&lt;br /&gt;
* [[Media:Codeschloss.zip | Codeschloss.zip ]]&amp;lt;br /&amp;gt;enthält ASM-Source, XLS-Rechenhilfe für Interrupt-Timing, Schaltplan-/Layout-Ausdruck&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Projekte]]&lt;br /&gt;
[[Category:AVR]]&lt;/div&gt;</summary>
		<author><name>Stefan1971</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Codeschloss&amp;diff=38589</id>
		<title>Codeschloss</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Codeschloss&amp;diff=38589"/>
		<updated>2009-08-30T16:38:58Z</updated>

		<summary type="html">&lt;p&gt;Stefan1971: /* Hardware: Hinweis zu Reed-Relais ergänzt */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;von Stefan1971&lt;br /&gt;
&lt;br /&gt;
=== Einleitung ===&lt;br /&gt;
&lt;br /&gt;
Im Folgenden beschreibe ich ein Haustür-Codeschloss, das als kleines AVR-Projekt in Hard- und Software umgesetzt ist und mittlerweile seinen Dienst am Klingelschild einer Haustüre versieht. Durch Eingabe des richtigen Codes lässt sich damit die Haustüre ohne Schlüssel öffnen.&lt;br /&gt;
&lt;br /&gt;
=== Merkmale ===&lt;br /&gt;
* Codeschloss mit ATtiny2313 zum Schalten eines elektrischen Türöffners über Relais&lt;br /&gt;
* Programmierbarer Tastencode zum Öffnen der Haustür kann aus bis zu 12 Tasten bestehen&lt;br /&gt;
* Aktivierdauer des Türöffners ist einstellbar&lt;br /&gt;
* Einzelne Taster oder alternativ eine 4x3-Matrixtastatur können angeschlossen werden&lt;br /&gt;
* Rote LED, wenn Codeeingabe läuft (leuchtet, sobald erste richtige Codetaste gedrückt wurde; verlöscht bei Zeitablauf in der Codeeingabe bzw. zusammen mit Abschalten des Türöffners)&lt;br /&gt;
* Gelbe LED leuchtet, wenn Codeschloss in Programmiermodus ist (=Lernen eines Codes) und blinkt, wenn Aktivierzeit für den Türöffner eingestellt wird&lt;br /&gt;
* Grüne LED zur Anzeige, ob Türöffner gerade geschaltet ist&lt;br /&gt;
* Wenn der Türöffner gerade aktiv ist, kann er durch Drücken einer beliebigen Codetaste vor Ablauf des Timers abgeschaltet werden&lt;br /&gt;
* Anschlüsse sind vorgesehen für die 12 Volt-Stromversorgung (Wechselspannung), eine LED als Türschildbeleuchtung und den Türöffner. Für die Codetasten gibt es eine Anschlussbuchse.&lt;br /&gt;
&lt;br /&gt;
=== Programmierung zur Nutzung ===&lt;br /&gt;
==== Programmieren des Codes ====&lt;br /&gt;
Durch Drücken des Programmiertasters auf der Schaltung wird in den Programmiermodus gewechselt. Dieser wird durch Leuchten der gelben LED angezeigt. Nun sind die Tasten in der gewünschten Reihenfolge zu betätigen. Der Code kann aus bis zu zwölf Tastendrücken bestehen. Die Programmierung ist durch erneutes Drücken des Programmiertasters abzuschließen. Damit ist der Tastencode gespeichert. Werden bei der Programmierung die maximal möglichen Tasten gedrückt (derzeit 12), beendet sich der Programmiermodus ohne Betätigen des Programmiertasters.&lt;br /&gt;
&lt;br /&gt;
==== Programmieren der Aktivierdauer des Türöffners ====&lt;br /&gt;
Wird der Programmiertaster im Programmiermodus (d.h. die gelbe LED leuchtet) gedrückt, ohne dass eine Codetaste zum Lernen eines neuen Codes betätigt wurde, so wechselt das Codeschloss in die Programmierung für die Aktivierdauer des Türöffners. Die gelbe LED zeigt dies durch Blinken an. In diesem Modus erfolgt mit der Taste 1 eine Testauslösung des Türöffners, mit der Taste 2 kann die Dauer verlängert, mit Taste 3 die Dauer verkürzt werden.&lt;br /&gt;
&lt;br /&gt;
Ist eine Matrixtastatur angeschlossen, werden andere Tasten verwendet: Hier erfolgt die Testauslösung mit der Taste (*). Die Taste (7) verlängert und die Taste (4) verkürzt die Dauer.&lt;br /&gt;
&lt;br /&gt;
Die Dauer wird in Stufen von ca. 0,2 Sekunden eingestellt. &lt;br /&gt;
&lt;br /&gt;
Erneutes Drücken des Programmiertasters speichert die Einstellung, die gelbe LED erlischt. Jede andere Taste als 1, 2, 3 bzw. (*), (7) oder (4) bricht die Programmierung ab und verwirft evtl. gemachte Änderungen an der Aktivierdauer.&lt;br /&gt;
&lt;br /&gt;
=== Software ===&lt;br /&gt;
Das Steuerprogramm ist in Assembler programmiert. Über bedingte Assemblierung im Quelltext kann auf die Zielplattformen ATmega8 oder ATtiny2313 assembliert werden. Hintergrund ist, dass zuerst auf einem [http://www.myavr.de myAVR Board] mit ATmega8 entwickelt und später für den Selbstbau auf den ATtiny2313 umgeschwenkt wurde.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Folgende interne Zustände werden in der Firmware unterschieden:&lt;br /&gt;
! Status  !! Beschreibung&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;SCAN&#039;&#039;&#039;|| SCAN ist der Default-Modus im laufenden Betrieb. Warten auf Tasten in der richtigen Reihenfolge. Tastendruck gilt als erfolgt, wenn Taste losgelassen wurde. Mit Loslassen der ersten richtigen Taste wird (Software-) Timer gestartet. Rote LED leuchtet.&amp;lt;br /&amp;gt;Nächste Taste war richtig: Zeiger wird auf nächste zu erwartende Taste weiter gestellt, Timer wird zurückgesetzt.&amp;lt;br /&amp;gt;Taste war falsch: Zeiger auf Anfang, LED aus, Timer deaktivieren.&amp;lt;br /&amp;gt;Timer abgelaufen: Zeiger auf Anfang, LED aus; wie bei falscher Taste&amp;lt;br /&amp;gt;Anzeigen des SCAN-Modus durch Leuchten der roten LED, sobald die erste richtige Taste betätigt (d.h. losgelassen) wurde.&amp;lt;br /&amp;gt;Wenn alle Tasten in der richtigen Reihenfolge richtig gedrückt wurden, erfolgt Wechsel in Status OPEN.&amp;lt;br /&amp;gt;Wenn Programmierkontakt erkannt wurde, Wechsel in den PROG-Modus.&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;OPEN&#039;&#039;&#039; || Timer für Türöffner mit programmiertem Wert (aus Status PROG_DOOR) starten, grüne LED leuchtet, rote LED ebenfalls, Türöffner aktiv&amp;lt;br /&amp;gt;Timer abgelaufen: Türöffner aus, LEDs aus, zurück in SCAN-Modus&amp;lt;br /&amp;gt;Beliebige Taste wird gedrückt (Schließen ist relevant, nicht Öffnen): Türöffner aus, grüne und rote LED aus; zurück in SCAN-Modus: wie Timer-Ablauf&amp;lt;br /&amp;gt;Der Abbruch des OPEN-Modus durch Drücken einer beliebigen Taste ist realisiert, indem das Drücken einer falschen Taste simuliert wird.&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PROG&#039;&#039;&#039; || Programmiermodus: Tritt ein, wenn im SCAN-Modus der Programmierkontakt betätigt (=losgelassen) wurde. Ende des Programmiermodus, wenn Programmierkontakt erneut betätigt wird. Im Programmiermodus werden die betätigten Tasten (Loslassen der Taste, wie im SCAN-Modus) nacheinander im SRAM festgehalten. Hierzu wird Index auf SRAM-Tastenspeicher zunächst auf Null gesetzt. Bei Ende des Programmiermodus wird die im SRAM festgehaltene Tastenfolge ins EEPROM übernommen. Beenden des Programmiermodus, ohne dass eine Taste während des Programmiermodus betätigt wurde, erhält den bisher eingestellten Code; dann keine Übernahme ins EEPROM. Beenden des Programmiermodus führt dann in die Programmierung der Aktivierdauer des Türöffners; Wechsel in Modus PROG_DOOR.&amp;lt;br /&amp;gt;Eine begonnene Programmierung, bei der irrtümlich falsche Tasten gedrückt wurden, kann nicht storniert werden, sondern muss erneut durchgeführt werden. Im Programmiermodus leuchtet die gelbe LED.&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PROG_DOOR&#039;&#039;&#039; || Dient zur Programmierung der Aktivierdauer des Türöffners.&amp;lt;br /&amp;gt;Um in diesen Modus zu gelangen, muss der Programmierkontakt zweimal betätigt werden, d.h. der Code-Programmiermodus muss ohne Druck einer Codetaste beendet (übersprungen) werden. Im PROG_DOOR-Modus blinkt die gelbe LED.&amp;lt;br /&amp;gt;Die Tasten des Codeschlosses erhalten im PROG_DOOR-Modus folgende Bedeutung:&amp;lt;br /&amp;gt;Taste 1: löst den Türöffner für die eingestellte Zeit zum Test aus (per Timer)&amp;lt;br /&amp;gt;Taste 2: verlängert mit jedem Tastendruck die eingestellte Zeit&amp;lt;br /&amp;gt;Taste 3: verkürzt mit jedem Tastendruck die eingestellte Zeit&amp;lt;br /&amp;gt;Jede andere Taste: Verwirft die Änderungen und verlässt den PROG_DOOR-Modus, Rückkehr in den SCAN-Modus.&amp;lt;br /&amp;gt;Abschließendes Betätigen des Programmierkontakts führt zu Übernahme des neuen Timer-Ladewerts ins EEPROM und beendet den PROG_DOOR-Modus. Wechsel in den SCAN-Modus.&lt;br /&gt;
Ist eine 4x3-Matrixtastatur angeschlossen, ist die Tastenbelegung für die Programmierung der Türöffneraktivierdauer wie folgt:&amp;lt;br /&amp;gt;Taste (*): Türöffner testhalber auslösen&amp;lt;br /&amp;gt;Taste (7): Aktivierdauer verlängern&amp;lt;br /&amp;gt;Taste (4): Aktivierdauer verkürzen&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;STARTUP&#039;&#039;&#039; || In diesen Modus wird beim Start der Anwendung zunächst gewechselt. Er hat den Zweck, die drei LEDs des Codeschlosses dreimal blinken zu lassen um anzuzeigen, dass der Controller arbeitet und auf Eingaben wartet. Wenn diese Phase abgelaufen ist, wird in den SCAN-Modus gewechselt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Hardware ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Belegung der Ports beim ATtiny2313:&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;PB0 ... PB7&#039;&#039;&#039; || IN || 8 Tasten zur Codeeingabe&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD6&#039;&#039;&#039; || IN || Programmierkontakt&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD0&#039;&#039;&#039; || OUT || Türöffner&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD1&#039;&#039;&#039; || OUT || Rote LED (laufende Codeeingabe)&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD2&#039;&#039;&#039; || OUT || Gelbe LED (Programmiermodus)&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD3&#039;&#039;&#039; || OUT || Grüne LED (Türöffner ist aktiv)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Einzelne Tasten werden mit jeweils einem Kontakt an Pin0 bis Pin7 angeschlossen, mit dem anderen Kontakt an Masse. Welche Tastatur (einzelne Tasten oder 4x3-Matrixtastatur) angeschlossen ist, wird über den bei der Matrixtastatur nicht benötigten Pin acht (PB7) gesteuert. Ist dieser beim Anwendungsstart auf Masse geschlossen, wird auf Abtastung einer Matrixtastatur umgestellt.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot; width=&amp;quot;25%&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Anschlussschema für 4x3-Matrixtastatur:&lt;br /&gt;
| width=&amp;quot;40%&amp;quot; | &#039;&#039;&#039;IN / OUT&#039;&#039;&#039; || style=&amp;quot;text-align:center&amp;quot; width=&amp;quot;20%&amp;quot; | &#039;&#039;&#039;Pin4&#039;&#039;&#039; || style=&amp;quot;text-align:center&amp;quot; width=&amp;quot;20%&amp;quot; | &#039;&#039;&#039;Pin5&#039;&#039;&#039; || style=&amp;quot;text-align:center&amp;quot; width=&amp;quot;20%&amp;quot; | &#039;&#039;&#039;Pin6&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin0&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | 1 || style=&amp;quot;text-align:center&amp;quot; | 2 || style=&amp;quot;text-align:center&amp;quot; | 3&lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin1&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | 4 || style=&amp;quot;text-align:center&amp;quot; | 5 || style=&amp;quot;text-align:center&amp;quot; | 6&lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin2&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | 7 || style=&amp;quot;text-align:center&amp;quot; | 8 || style=&amp;quot;text-align:center&amp;quot; | 9  &lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin3&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | * || style=&amp;quot;text-align:center&amp;quot; | 0 || style=&amp;quot;text-align:center&amp;quot; | #  &lt;br /&gt;
|} Pin7 und Pin8 (Masse) sind dann dauerhaft miteinander verbunden.&lt;br /&gt;
&lt;br /&gt;
Schaltplan und Platinenlayout wurden mit Target3001 erstellt.&lt;br /&gt;
&lt;br /&gt;
Bei Nutzung eines Reed-Relais als Schaltelement muss der Türöffner erfahrungsgemäß einen Widerstand von mindestens 20 Ohm haben.&lt;br /&gt;
&lt;br /&gt;
=== Bilder ===&lt;br /&gt;
[[Bild:Codeschloss_Platine_beschriftet.jpg|thumb|550px|left|Codeschloss-Platine]]&lt;br /&gt;
[[Bild:Codeschloss_Platine_Keypad_Ausschnitt.jpg|thumb|220px|Anschluss einer Matrixtastatur]]&lt;br /&gt;
&lt;br /&gt;
=== Download ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;... wird fortgesetzt ...&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Category:Projekte]]&lt;br /&gt;
[[Category:AVR]]&lt;/div&gt;</summary>
		<author><name>Stefan1971</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Datei:Codeschloss.zip&amp;diff=38588</id>
		<title>Datei:Codeschloss.zip</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Datei:Codeschloss.zip&amp;diff=38588"/>
		<updated>2009-08-30T16:31:59Z</updated>

		<summary type="html">&lt;p&gt;Stefan1971: ASM-Source, XLS-Rechenhilfe für Interrupt-Timing, Schaltplan-/Layout-Ausdrucke&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;ASM-Source, XLS-Rechenhilfe für Interrupt-Timing, Schaltplan-/Layout-Ausdrucke&lt;/div&gt;</summary>
		<author><name>Stefan1971</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Diskussion:Codeschloss&amp;diff=38576</id>
		<title>Diskussion:Codeschloss</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Diskussion:Codeschloss&amp;diff=38576"/>
		<updated>2009-08-29T15:12:07Z</updated>

		<summary type="html">&lt;p&gt;Stefan1971: /* Sicherheitsleck in Zustand SCAN */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Sicherheitsleck in Zustand SCAN=&lt;br /&gt;
meinst du, es ist Klug, erst nach der ersten richtigen Taste die led leuchten zu lassen?&lt;br /&gt;
Das reduziert deinen effektiven zugangscode um eine Stelle, da man für die erste Ziffer nur einmal auf jede Taste zu drücken braucht, um zu sehen, wie die Zahl anfängt.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
Stimmt schon&lt;br /&gt;
Hallo!&lt;br /&gt;
Ja, Dein Einwand ist richtig. Eigentlich darf man aus Sicherheitsgründen gar keine kompromittierende Anzeige darüber haben, ob eine gedrückte Taste im Code richtig oder falsch war. Die LED leuchtet ja, solange die zuletzt gedrückte Taste stimmte und man noch &amp;quot;in time&amp;quot; ist. Ich habs trotzdem mal so umgesetzt, weil die alte Haustürschaltung (war was mit einem Schieberegister, von vor über 30 Jahren aus einer Elektronikzeitschrift) auch so eine LED hatte und das Ding in einem Kasten hinter dem Klingelschild steckt, der natürlich weder einsehbar noch von außen erreichbar sein darf. Sonst könnte man das Ding gleich kurzschließen.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
oh das ist ja noch schlimmer,&lt;br /&gt;
die elektronik muss weit weg von dem pad, sonst brauch man ja (wie du ja selbst schreibst) nur das panel abmachen und die Drähte zusammen halten.&lt;br /&gt;
Ich würd auch aus versicherungstechnischen Gründen sehr vorsichtig mit so einer Anlage sein. Wenn eingebrochen wird sollte man der Versicherung schon nachweisen können, dass die Anlage genause sicher ist, wie eine Professionelle.&lt;br /&gt;
Eine LED sollte das Pad trotzdem haben, sie sollte aber nur anzeigen, dass man sich im Eingabemodus befindet, nix weiter.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
Um versicherungsrechtliche Fragen habe ich mir bei dieser Lösung noch nie Gedanken gemacht. Da erwischt Du mich tatsächlich auf dem falschen Fuß. Nun sitze ich hier allerdings auch nicht in der Bronx, sondern in Badisch-Sibirischer Provinz, wo die soziale Kontrolle halt noch funktioniert. Man kann den Müll nicht rausbringen, ohne dass die Gardinen beim Nachbarn wackeln.&lt;br /&gt;
Davon abgesehen ist hier aber auch nichts zu holen.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
----&lt;br /&gt;
Der bracuht ja nur programmier und dann 1 drücken dann komt err ein.&lt;br /&gt;
----&lt;br /&gt;
Verstehe den Einwand nicht... Wer den Taster auf der Schaltung drücken kann, ist doch eh schon drin?!&lt;/div&gt;</summary>
		<author><name>Stefan1971</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Diskussion:Codeschloss&amp;diff=38571</id>
		<title>Diskussion:Codeschloss</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Diskussion:Codeschloss&amp;diff=38571"/>
		<updated>2009-08-28T19:05:58Z</updated>

		<summary type="html">&lt;p&gt;Stefan1971: /* Sicherheitsleck in Zustand SCAN */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Sicherheitsleck in Zustand SCAN=&lt;br /&gt;
meinst du, es ist Klug, erst nach der ersten richtigen Taste die led leuchten zu lassen?&lt;br /&gt;
Das reduziert deinen effektiven zugangscode um eine Stelle, da man für die erste Ziffer nur einmal auf jede Taste zu drücken braucht, um zu sehen, wie die Zahl anfängt.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
Stimmt schon&lt;br /&gt;
Hallo!&lt;br /&gt;
Ja, Dein Einwand ist richtig. Eigentlich darf man aus Sicherheitsgründen gar keine kompromittierende Anzeige darüber haben, ob eine gedrückte Taste im Code richtig oder falsch war. Die LED leuchtet ja, solange die zuletzt gedrückte Taste stimmte und man noch &amp;quot;in time&amp;quot; ist. Ich habs trotzdem mal so umgesetzt, weil die alte Haustürschaltung (war was mit einem Schieberegister, von vor über 30 Jahren aus einer Elektronikzeitschrift) auch so eine LED hatte und das Ding in einem Kasten hinter dem Klingelschild steckt, der natürlich weder einsehbar noch von außen erreichbar sein darf. Sonst könnte man das Ding gleich kurzschließen.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
oh das ist ja noch schlimmer,&lt;br /&gt;
die elektronik muss weit weg von dem pad, sonst brauch man ja (wie du ja selbst schreibst) nur das panel abmachen und die Drähte zusammen halten.&lt;br /&gt;
Ich würd auch aus versicherungstechnischen Gründen sehr vorsichtig mit so einer Anlage sein. Wenn eingebrochen wird sollte man der Versicherung schon nachweisen können, dass die Anlage genause sicher ist, wie eine Professionelle.&lt;br /&gt;
Eine LED sollte das Pad trotzdem haben, sie sollte aber nur anzeigen, dass man sich im Eingabemodus befindet, nix weiter.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
Um versicherungsrechtliche Fragen habe ich mir bei dieser Lösung noch nie Gedanken gemacht. Da erwischt Du mich tatsächlich auf dem falschen Fuß. Nun sitze ich hier allerdings auch nicht in der Bronx, sondern in Badisch-Sibirischer Provinz, wo die soziale Kontrolle halt noch funktioniert. Man kann den Müll nicht rausbringen, ohne dass die Gardinen beim Nachbarn wackeln.&lt;br /&gt;
Davon abgesehen ist hier aber auch nichts zu holen.&lt;/div&gt;</summary>
		<author><name>Stefan1971</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Codeschloss&amp;diff=38570</id>
		<title>Codeschloss</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Codeschloss&amp;diff=38570"/>
		<updated>2009-08-28T17:53:03Z</updated>

		<summary type="html">&lt;p&gt;Stefan1971: /* Bilder korrigiert */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;von Stefan1971&lt;br /&gt;
&lt;br /&gt;
=== Einleitung ===&lt;br /&gt;
&lt;br /&gt;
Im Folgenden beschreibe ich ein Haustür-Codeschloss, das als kleines AVR-Projekt in Hard- und Software umgesetzt ist und mittlerweile seinen Dienst am Klingelschild einer Haustüre versieht. Durch Eingabe des richtigen Codes lässt sich damit die Haustüre ohne Schlüssel öffnen.&lt;br /&gt;
&lt;br /&gt;
=== Merkmale ===&lt;br /&gt;
* Codeschloss mit ATtiny2313 zum Schalten eines elektrischen Türöffners über Relais&lt;br /&gt;
* Programmierbarer Tastencode zum Öffnen der Haustür kann aus bis zu 12 Tasten bestehen&lt;br /&gt;
* Aktivierdauer des Türöffners ist einstellbar&lt;br /&gt;
* Einzelne Taster oder alternativ eine 4x3-Matrixtastatur können angeschlossen werden&lt;br /&gt;
* Rote LED, wenn Codeeingabe läuft (leuchtet, sobald erste richtige Codetaste gedrückt wurde; verlöscht bei Zeitablauf in der Codeeingabe bzw. zusammen mit Abschalten des Türöffners)&lt;br /&gt;
* Gelbe LED leuchtet, wenn Codeschloss in Programmiermodus ist (=Lernen eines Codes) und blinkt, wenn Aktivierzeit für den Türöffner eingestellt wird&lt;br /&gt;
* Grüne LED zur Anzeige, ob Türöffner gerade geschaltet ist&lt;br /&gt;
* Wenn der Türöffner gerade aktiv ist, kann er durch Drücken einer beliebigen Codetaste vor Ablauf des Timers abgeschaltet werden&lt;br /&gt;
* Anschlüsse sind vorgesehen für die 12 Volt-Stromversorgung (Wechselspannung), eine LED als Türschildbeleuchtung und den Türöffner. Für die Codetasten gibt es eine Anschlussbuchse.&lt;br /&gt;
&lt;br /&gt;
=== Programmierung zur Nutzung ===&lt;br /&gt;
==== Programmieren des Codes ====&lt;br /&gt;
Durch Drücken des Programmiertasters auf der Schaltung wird in den Programmiermodus gewechselt. Dieser wird durch Leuchten der gelben LED angezeigt. Nun sind die Tasten in der gewünschten Reihenfolge zu betätigen. Der Code kann aus bis zu zwölf Tastendrücken bestehen. Die Programmierung ist durch erneutes Drücken des Programmiertasters abzuschließen. Damit ist der Tastencode gespeichert. Werden bei der Programmierung die maximal möglichen Tasten gedrückt (derzeit 12), beendet sich der Programmiermodus ohne Betätigen des Programmiertasters.&lt;br /&gt;
&lt;br /&gt;
==== Programmieren der Aktivierdauer des Türöffners ====&lt;br /&gt;
Wird der Programmiertaster im Programmiermodus (d.h. die gelbe LED leuchtet) gedrückt, ohne dass eine Codetaste zum Lernen eines neuen Codes betätigt wurde, so wechselt das Codeschloss in die Programmierung für die Aktivierdauer des Türöffners. Die gelbe LED zeigt dies durch Blinken an. In diesem Modus erfolgt mit der Taste 1 eine Testauslösung des Türöffners, mit der Taste 2 kann die Dauer verlängert, mit Taste 3 die Dauer verkürzt werden.&lt;br /&gt;
&lt;br /&gt;
Ist eine Matrixtastatur angeschlossen, werden andere Tasten verwendet: Hier erfolgt die Testauslösung mit der Taste (*). Die Taste (7) verlängert und die Taste (4) verkürzt die Dauer.&lt;br /&gt;
&lt;br /&gt;
Die Dauer wird in Stufen von ca. 0,2 Sekunden eingestellt. &lt;br /&gt;
&lt;br /&gt;
Erneutes Drücken des Programmiertasters speichert die Einstellung, die gelbe LED erlischt. Jede andere Taste als 1, 2, 3 bzw. (*), (7) oder (4) bricht die Programmierung ab und verwirft evtl. gemachte Änderungen an der Aktivierdauer.&lt;br /&gt;
&lt;br /&gt;
=== Software ===&lt;br /&gt;
Das Steuerprogramm ist in Assembler programmiert. Über bedingte Assemblierung im Quelltext kann auf die Zielplattformen ATmega8 oder ATtiny2313 assembliert werden. Hintergrund ist, dass zuerst auf einem [http://www.myavr.de myAVR Board] mit ATmega8 entwickelt und später für den Selbstbau auf den ATtiny2313 umgeschwenkt wurde.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Folgende interne Zustände werden in der Firmware unterschieden:&lt;br /&gt;
! Status  !! Beschreibung&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;SCAN&#039;&#039;&#039;|| SCAN ist der Default-Modus im laufenden Betrieb. Warten auf Tasten in der richtigen Reihenfolge. Tastendruck gilt als erfolgt, wenn Taste losgelassen wurde. Mit Loslassen der ersten richtigen Taste wird (Software-) Timer gestartet. Rote LED leuchtet.&amp;lt;br /&amp;gt;Nächste Taste war richtig: Zeiger wird auf nächste zu erwartende Taste weiter gestellt, Timer wird zurückgesetzt.&amp;lt;br /&amp;gt;Taste war falsch: Zeiger auf Anfang, LED aus, Timer deaktivieren.&amp;lt;br /&amp;gt;Timer abgelaufen: Zeiger auf Anfang, LED aus; wie bei falscher Taste&amp;lt;br /&amp;gt;Anzeigen des SCAN-Modus durch Leuchten der roten LED, sobald die erste richtige Taste betätigt (d.h. losgelassen) wurde.&amp;lt;br /&amp;gt;Wenn alle Tasten in der richtigen Reihenfolge richtig gedrückt wurden, erfolgt Wechsel in Status OPEN.&amp;lt;br /&amp;gt;Wenn Programmierkontakt erkannt wurde, Wechsel in den PROG-Modus.&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;OPEN&#039;&#039;&#039; || Timer für Türöffner mit programmiertem Wert (aus Status PROG_DOOR) starten, grüne LED leuchtet, rote LED ebenfalls, Türöffner aktiv&amp;lt;br /&amp;gt;Timer abgelaufen: Türöffner aus, LEDs aus, zurück in SCAN-Modus&amp;lt;br /&amp;gt;Beliebige Taste wird gedrückt (Schließen ist relevant, nicht Öffnen): Türöffner aus, grüne und rote LED aus; zurück in SCAN-Modus: wie Timer-Ablauf&amp;lt;br /&amp;gt;Der Abbruch des OPEN-Modus durch Drücken einer beliebigen Taste ist realisiert, indem das Drücken einer falschen Taste simuliert wird.&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PROG&#039;&#039;&#039; || Programmiermodus: Tritt ein, wenn im SCAN-Modus der Programmierkontakt betätigt (=losgelassen) wurde. Ende des Programmiermodus, wenn Programmierkontakt erneut betätigt wird. Im Programmiermodus werden die betätigten Tasten (Loslassen der Taste, wie im SCAN-Modus) nacheinander im SRAM festgehalten. Hierzu wird Index auf SRAM-Tastenspeicher zunächst auf Null gesetzt. Bei Ende des Programmiermodus wird die im SRAM festgehaltene Tastenfolge ins EEPROM übernommen. Beenden des Programmiermodus, ohne dass eine Taste während des Programmiermodus betätigt wurde, erhält den bisher eingestellten Code; dann keine Übernahme ins EEPROM. Beenden des Programmiermodus führt dann in die Programmierung der Aktivierdauer des Türöffners; Wechsel in Modus PROG_DOOR.&amp;lt;br /&amp;gt;Eine begonnene Programmierung, bei der irrtümlich falsche Tasten gedrückt wurden, kann nicht storniert werden, sondern muss erneut durchgeführt werden. Im Programmiermodus leuchtet die gelbe LED.&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PROG_DOOR&#039;&#039;&#039; || Dient zur Programmierung der Aktivierdauer des Türöffners.&amp;lt;br /&amp;gt;Um in diesen Modus zu gelangen, muss der Programmierkontakt zweimal betätigt werden, d.h. der Code-Programmiermodus muss ohne Druck einer Codetaste beendet (übersprungen) werden. Im PROG_DOOR-Modus blinkt die gelbe LED.&amp;lt;br /&amp;gt;Die Tasten des Codeschlosses erhalten im PROG_DOOR-Modus folgende Bedeutung:&amp;lt;br /&amp;gt;Taste 1: löst den Türöffner für die eingestellte Zeit zum Test aus (per Timer)&amp;lt;br /&amp;gt;Taste 2: verlängert mit jedem Tastendruck die eingestellte Zeit&amp;lt;br /&amp;gt;Taste 3: verkürzt mit jedem Tastendruck die eingestellte Zeit&amp;lt;br /&amp;gt;Jede andere Taste: Verwirft die Änderungen und verlässt den PROG_DOOR-Modus, Rückkehr in den SCAN-Modus.&amp;lt;br /&amp;gt;Abschließendes Betätigen des Programmierkontakts führt zu Übernahme des neuen Timer-Ladewerts ins EEPROM und beendet den PROG_DOOR-Modus. Wechsel in den SCAN-Modus.&lt;br /&gt;
Ist eine 4x3-Matrixtastatur angeschlossen, ist die Tastenbelegung für die Programmierung der Türöffneraktivierdauer wie folgt:&amp;lt;br /&amp;gt;Taste (*): Türöffner testhalber auslösen&amp;lt;br /&amp;gt;Taste (7): Aktivierdauer verlängern&amp;lt;br /&amp;gt;Taste (4): Aktivierdauer verkürzen&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;STARTUP&#039;&#039;&#039; || In diesen Modus wird beim Start der Anwendung zunächst gewechselt. Er hat den Zweck, die drei LEDs des Codeschlosses dreimal blinken zu lassen um anzuzeigen, dass der Controller arbeitet und auf Eingaben wartet. Wenn diese Phase abgelaufen ist, wird in den SCAN-Modus gewechselt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Hardware ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Belegung der Ports beim ATtiny2313:&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;PB0 ... PB7&#039;&#039;&#039; || IN || 8 Tasten zur Codeeingabe&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD6&#039;&#039;&#039; || IN || Programmierkontakt&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD0&#039;&#039;&#039; || OUT || Türöffner&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD1&#039;&#039;&#039; || OUT || Rote LED (laufende Codeeingabe)&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD2&#039;&#039;&#039; || OUT || Gelbe LED (Programmiermodus)&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD3&#039;&#039;&#039; || OUT || Grüne LED (Türöffner ist aktiv)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Einzelne Tasten werden mit jeweils einem Kontakt an Pin0 bis Pin7 angeschlossen, mit dem anderen Kontakt an Masse. Welche Tastatur (einzelne Tasten oder 4x3-Matrixtastatur) angeschlossen ist, wird über den bei der Matrixtastatur nicht benötigten Pin acht (PB7) gesteuert. Ist dieser beim Anwendungsstart auf Masse geschlossen, wird auf Abtastung einer Matrixtastatur umgestellt.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot; width=&amp;quot;25%&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Anschlussschema für 4x3-Matrixtastatur:&lt;br /&gt;
| width=&amp;quot;40%&amp;quot; | &#039;&#039;&#039;IN / OUT&#039;&#039;&#039; || style=&amp;quot;text-align:center&amp;quot; width=&amp;quot;20%&amp;quot; | &#039;&#039;&#039;Pin4&#039;&#039;&#039; || style=&amp;quot;text-align:center&amp;quot; width=&amp;quot;20%&amp;quot; | &#039;&#039;&#039;Pin5&#039;&#039;&#039; || style=&amp;quot;text-align:center&amp;quot; width=&amp;quot;20%&amp;quot; | &#039;&#039;&#039;Pin6&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin0&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | 1 || style=&amp;quot;text-align:center&amp;quot; | 2 || style=&amp;quot;text-align:center&amp;quot; | 3&lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin1&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | 4 || style=&amp;quot;text-align:center&amp;quot; | 5 || style=&amp;quot;text-align:center&amp;quot; | 6&lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin2&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | 7 || style=&amp;quot;text-align:center&amp;quot; | 8 || style=&amp;quot;text-align:center&amp;quot; | 9  &lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin3&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | * || style=&amp;quot;text-align:center&amp;quot; | 0 || style=&amp;quot;text-align:center&amp;quot; | #  &lt;br /&gt;
|} Pin7 und Pin8 (Masse) sind dann dauerhaft miteinander verbunden.&lt;br /&gt;
&lt;br /&gt;
Schaltplan und Platinenlayout wurden mit Target3001 erstellt.&lt;br /&gt;
&lt;br /&gt;
=== Bilder ===&lt;br /&gt;
[[Bild:Codeschloss_Platine_beschriftet.jpg|thumb|550px|left|Codeschloss-Platine]]&lt;br /&gt;
[[Bild:Codeschloss_Platine_Keypad_Ausschnitt.jpg|thumb|220px|Anschluss einer Matrixtastatur]]&lt;br /&gt;
&lt;br /&gt;
=== Download ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;... wird fortgesetzt ...&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Category:Projekte]]&lt;br /&gt;
[[Category:AVR]]&lt;/div&gt;</summary>
		<author><name>Stefan1971</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Codeschloss&amp;diff=38569</id>
		<title>Codeschloss</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Codeschloss&amp;diff=38569"/>
		<updated>2009-08-28T17:52:02Z</updated>

		<summary type="html">&lt;p&gt;Stefan1971: /* Bilder ergänzt */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;von Stefan1971&lt;br /&gt;
&lt;br /&gt;
=== Einleitung ===&lt;br /&gt;
&lt;br /&gt;
Im Folgenden beschreibe ich ein Haustür-Codeschloss, das als kleines AVR-Projekt in Hard- und Software umgesetzt ist und mittlerweile seinen Dienst am Klingelschild einer Haustüre versieht. Durch Eingabe des richtigen Codes lässt sich damit die Haustüre ohne Schlüssel öffnen.&lt;br /&gt;
&lt;br /&gt;
=== Merkmale ===&lt;br /&gt;
* Codeschloss mit ATtiny2313 zum Schalten eines elektrischen Türöffners über Relais&lt;br /&gt;
* Programmierbarer Tastencode zum Öffnen der Haustür kann aus bis zu 12 Tasten bestehen&lt;br /&gt;
* Aktivierdauer des Türöffners ist einstellbar&lt;br /&gt;
* Einzelne Taster oder alternativ eine 4x3-Matrixtastatur können angeschlossen werden&lt;br /&gt;
* Rote LED, wenn Codeeingabe läuft (leuchtet, sobald erste richtige Codetaste gedrückt wurde; verlöscht bei Zeitablauf in der Codeeingabe bzw. zusammen mit Abschalten des Türöffners)&lt;br /&gt;
* Gelbe LED leuchtet, wenn Codeschloss in Programmiermodus ist (=Lernen eines Codes) und blinkt, wenn Aktivierzeit für den Türöffner eingestellt wird&lt;br /&gt;
* Grüne LED zur Anzeige, ob Türöffner gerade geschaltet ist&lt;br /&gt;
* Wenn der Türöffner gerade aktiv ist, kann er durch Drücken einer beliebigen Codetaste vor Ablauf des Timers abgeschaltet werden&lt;br /&gt;
* Anschlüsse sind vorgesehen für die 12 Volt-Stromversorgung (Wechselspannung), eine LED als Türschildbeleuchtung und den Türöffner. Für die Codetasten gibt es eine Anschlussbuchse.&lt;br /&gt;
&lt;br /&gt;
=== Programmierung zur Nutzung ===&lt;br /&gt;
==== Programmieren des Codes ====&lt;br /&gt;
Durch Drücken des Programmiertasters auf der Schaltung wird in den Programmiermodus gewechselt. Dieser wird durch Leuchten der gelben LED angezeigt. Nun sind die Tasten in der gewünschten Reihenfolge zu betätigen. Der Code kann aus bis zu zwölf Tastendrücken bestehen. Die Programmierung ist durch erneutes Drücken des Programmiertasters abzuschließen. Damit ist der Tastencode gespeichert. Werden bei der Programmierung die maximal möglichen Tasten gedrückt (derzeit 12), beendet sich der Programmiermodus ohne Betätigen des Programmiertasters.&lt;br /&gt;
&lt;br /&gt;
==== Programmieren der Aktivierdauer des Türöffners ====&lt;br /&gt;
Wird der Programmiertaster im Programmiermodus (d.h. die gelbe LED leuchtet) gedrückt, ohne dass eine Codetaste zum Lernen eines neuen Codes betätigt wurde, so wechselt das Codeschloss in die Programmierung für die Aktivierdauer des Türöffners. Die gelbe LED zeigt dies durch Blinken an. In diesem Modus erfolgt mit der Taste 1 eine Testauslösung des Türöffners, mit der Taste 2 kann die Dauer verlängert, mit Taste 3 die Dauer verkürzt werden.&lt;br /&gt;
&lt;br /&gt;
Ist eine Matrixtastatur angeschlossen, werden andere Tasten verwendet: Hier erfolgt die Testauslösung mit der Taste (*). Die Taste (7) verlängert und die Taste (4) verkürzt die Dauer.&lt;br /&gt;
&lt;br /&gt;
Die Dauer wird in Stufen von ca. 0,2 Sekunden eingestellt. &lt;br /&gt;
&lt;br /&gt;
Erneutes Drücken des Programmiertasters speichert die Einstellung, die gelbe LED erlischt. Jede andere Taste als 1, 2, 3 bzw. (*), (7) oder (4) bricht die Programmierung ab und verwirft evtl. gemachte Änderungen an der Aktivierdauer.&lt;br /&gt;
&lt;br /&gt;
=== Software ===&lt;br /&gt;
Das Steuerprogramm ist in Assembler programmiert. Über bedingte Assemblierung im Quelltext kann auf die Zielplattformen ATmega8 oder ATtiny2313 assembliert werden. Hintergrund ist, dass zuerst auf einem [http://www.myavr.de myAVR Board] mit ATmega8 entwickelt und später für den Selbstbau auf den ATtiny2313 umgeschwenkt wurde.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Folgende interne Zustände werden in der Firmware unterschieden:&lt;br /&gt;
! Status  !! Beschreibung&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;SCAN&#039;&#039;&#039;|| SCAN ist der Default-Modus im laufenden Betrieb. Warten auf Tasten in der richtigen Reihenfolge. Tastendruck gilt als erfolgt, wenn Taste losgelassen wurde. Mit Loslassen der ersten richtigen Taste wird (Software-) Timer gestartet. Rote LED leuchtet.&amp;lt;br /&amp;gt;Nächste Taste war richtig: Zeiger wird auf nächste zu erwartende Taste weiter gestellt, Timer wird zurückgesetzt.&amp;lt;br /&amp;gt;Taste war falsch: Zeiger auf Anfang, LED aus, Timer deaktivieren.&amp;lt;br /&amp;gt;Timer abgelaufen: Zeiger auf Anfang, LED aus; wie bei falscher Taste&amp;lt;br /&amp;gt;Anzeigen des SCAN-Modus durch Leuchten der roten LED, sobald die erste richtige Taste betätigt (d.h. losgelassen) wurde.&amp;lt;br /&amp;gt;Wenn alle Tasten in der richtigen Reihenfolge richtig gedrückt wurden, erfolgt Wechsel in Status OPEN.&amp;lt;br /&amp;gt;Wenn Programmierkontakt erkannt wurde, Wechsel in den PROG-Modus.&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;OPEN&#039;&#039;&#039; || Timer für Türöffner mit programmiertem Wert (aus Status PROG_DOOR) starten, grüne LED leuchtet, rote LED ebenfalls, Türöffner aktiv&amp;lt;br /&amp;gt;Timer abgelaufen: Türöffner aus, LEDs aus, zurück in SCAN-Modus&amp;lt;br /&amp;gt;Beliebige Taste wird gedrückt (Schließen ist relevant, nicht Öffnen): Türöffner aus, grüne und rote LED aus; zurück in SCAN-Modus: wie Timer-Ablauf&amp;lt;br /&amp;gt;Der Abbruch des OPEN-Modus durch Drücken einer beliebigen Taste ist realisiert, indem das Drücken einer falschen Taste simuliert wird.&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PROG&#039;&#039;&#039; || Programmiermodus: Tritt ein, wenn im SCAN-Modus der Programmierkontakt betätigt (=losgelassen) wurde. Ende des Programmiermodus, wenn Programmierkontakt erneut betätigt wird. Im Programmiermodus werden die betätigten Tasten (Loslassen der Taste, wie im SCAN-Modus) nacheinander im SRAM festgehalten. Hierzu wird Index auf SRAM-Tastenspeicher zunächst auf Null gesetzt. Bei Ende des Programmiermodus wird die im SRAM festgehaltene Tastenfolge ins EEPROM übernommen. Beenden des Programmiermodus, ohne dass eine Taste während des Programmiermodus betätigt wurde, erhält den bisher eingestellten Code; dann keine Übernahme ins EEPROM. Beenden des Programmiermodus führt dann in die Programmierung der Aktivierdauer des Türöffners; Wechsel in Modus PROG_DOOR.&amp;lt;br /&amp;gt;Eine begonnene Programmierung, bei der irrtümlich falsche Tasten gedrückt wurden, kann nicht storniert werden, sondern muss erneut durchgeführt werden. Im Programmiermodus leuchtet die gelbe LED.&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PROG_DOOR&#039;&#039;&#039; || Dient zur Programmierung der Aktivierdauer des Türöffners.&amp;lt;br /&amp;gt;Um in diesen Modus zu gelangen, muss der Programmierkontakt zweimal betätigt werden, d.h. der Code-Programmiermodus muss ohne Druck einer Codetaste beendet (übersprungen) werden. Im PROG_DOOR-Modus blinkt die gelbe LED.&amp;lt;br /&amp;gt;Die Tasten des Codeschlosses erhalten im PROG_DOOR-Modus folgende Bedeutung:&amp;lt;br /&amp;gt;Taste 1: löst den Türöffner für die eingestellte Zeit zum Test aus (per Timer)&amp;lt;br /&amp;gt;Taste 2: verlängert mit jedem Tastendruck die eingestellte Zeit&amp;lt;br /&amp;gt;Taste 3: verkürzt mit jedem Tastendruck die eingestellte Zeit&amp;lt;br /&amp;gt;Jede andere Taste: Verwirft die Änderungen und verlässt den PROG_DOOR-Modus, Rückkehr in den SCAN-Modus.&amp;lt;br /&amp;gt;Abschließendes Betätigen des Programmierkontakts führt zu Übernahme des neuen Timer-Ladewerts ins EEPROM und beendet den PROG_DOOR-Modus. Wechsel in den SCAN-Modus.&lt;br /&gt;
Ist eine 4x3-Matrixtastatur angeschlossen, ist die Tastenbelegung für die Programmierung der Türöffneraktivierdauer wie folgt:&amp;lt;br /&amp;gt;Taste (*): Türöffner testhalber auslösen&amp;lt;br /&amp;gt;Taste (7): Aktivierdauer verlängern&amp;lt;br /&amp;gt;Taste (4): Aktivierdauer verkürzen&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;STARTUP&#039;&#039;&#039; || In diesen Modus wird beim Start der Anwendung zunächst gewechselt. Er hat den Zweck, die drei LEDs des Codeschlosses dreimal blinken zu lassen um anzuzeigen, dass der Controller arbeitet und auf Eingaben wartet. Wenn diese Phase abgelaufen ist, wird in den SCAN-Modus gewechselt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Hardware ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Belegung der Ports beim ATtiny2313:&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;PB0 ... PB7&#039;&#039;&#039; || IN || 8 Tasten zur Codeeingabe&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD6&#039;&#039;&#039; || IN || Programmierkontakt&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD0&#039;&#039;&#039; || OUT || Türöffner&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD1&#039;&#039;&#039; || OUT || Rote LED (laufende Codeeingabe)&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD2&#039;&#039;&#039; || OUT || Gelbe LED (Programmiermodus)&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PD3&#039;&#039;&#039; || OUT || Grüne LED (Türöffner ist aktiv)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Einzelne Tasten werden mit jeweils einem Kontakt an Pin0 bis Pin7 angeschlossen, mit dem anderen Kontakt an Masse. Welche Tastatur (einzelne Tasten oder 4x3-Matrixtastatur) angeschlossen ist, wird über den bei der Matrixtastatur nicht benötigten Pin acht (PB7) gesteuert. Ist dieser beim Anwendungsstart auf Masse geschlossen, wird auf Abtastung einer Matrixtastatur umgestellt.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot; width=&amp;quot;25%&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Anschlussschema für 4x3-Matrixtastatur:&lt;br /&gt;
| width=&amp;quot;40%&amp;quot; | &#039;&#039;&#039;IN / OUT&#039;&#039;&#039; || style=&amp;quot;text-align:center&amp;quot; width=&amp;quot;20%&amp;quot; | &#039;&#039;&#039;Pin4&#039;&#039;&#039; || style=&amp;quot;text-align:center&amp;quot; width=&amp;quot;20%&amp;quot; | &#039;&#039;&#039;Pin5&#039;&#039;&#039; || style=&amp;quot;text-align:center&amp;quot; width=&amp;quot;20%&amp;quot; | &#039;&#039;&#039;Pin6&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin0&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | 1 || style=&amp;quot;text-align:center&amp;quot; | 2 || style=&amp;quot;text-align:center&amp;quot; | 3&lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin1&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | 4 || style=&amp;quot;text-align:center&amp;quot; | 5 || style=&amp;quot;text-align:center&amp;quot; | 6&lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin2&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | 7 || style=&amp;quot;text-align:center&amp;quot; | 8 || style=&amp;quot;text-align:center&amp;quot; | 9  &lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039;Pin3&#039;&#039;&#039;  || style=&amp;quot;text-align:center&amp;quot; | * || style=&amp;quot;text-align:center&amp;quot; | 0 || style=&amp;quot;text-align:center&amp;quot; | #  &lt;br /&gt;
|} Pin7 und Pin8 (Masse) sind dann dauerhaft miteinander verbunden.&lt;br /&gt;
&lt;br /&gt;
Schaltplan und Platinenlayout wurden mit Target3001 erstellt.&lt;br /&gt;
&lt;br /&gt;
=== Bilder ===&lt;br /&gt;
[[Bild:Codeschloss_Platine_beschriftet.jpg|thumb|550px|left|Codeschloss-Platine]]&lt;br /&gt;
[[Bild:Codeschloss_Platine_Keypad_Ausschnitt.jpg|thumb|220px|right|Anschluss einer Matrixtastatur]]&lt;br /&gt;
&lt;br /&gt;
=== Download ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;... wird fortgesetzt ...&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Category:Projekte]]&lt;br /&gt;
[[Category:AVR]]&lt;/div&gt;</summary>
		<author><name>Stefan1971</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Datei:Codeschloss_Platine_Keypad_Ausschnitt.jpg&amp;diff=38567</id>
		<title>Datei:Codeschloss Platine Keypad Ausschnitt.jpg</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Datei:Codeschloss_Platine_Keypad_Ausschnitt.jpg&amp;diff=38567"/>
		<updated>2009-08-28T17:30:48Z</updated>

		<summary type="html">&lt;p&gt;Stefan1971: Bildausschnitt Codeschloss: Anschluss einer Matrixtastatur&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Bildausschnitt Codeschloss: Anschluss einer Matrixtastatur&lt;/div&gt;</summary>
		<author><name>Stefan1971</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Datei:Codeschloss_Platine_beschriftet.jpg&amp;diff=38565</id>
		<title>Datei:Codeschloss Platine beschriftet.jpg</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Datei:Codeschloss_Platine_beschriftet.jpg&amp;diff=38565"/>
		<updated>2009-08-28T17:24:41Z</updated>

		<summary type="html">&lt;p&gt;Stefan1971: Bild der Codeschloss-Platine&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Bild der Codeschloss-Platine&lt;/div&gt;</summary>
		<author><name>Stefan1971</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Diskussion:Codeschloss&amp;diff=38402</id>
		<title>Diskussion:Codeschloss</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Diskussion:Codeschloss&amp;diff=38402"/>
		<updated>2009-08-19T20:40:56Z</updated>

		<summary type="html">&lt;p&gt;Stefan1971: /* Sicherheitsleck in Zustand SCAN */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Sicherheitsleck in Zustand SCAN=&lt;br /&gt;
meinst du, es ist Klug, erst nach der ersten richtigen Taste die led leuchten zu lassen?&lt;br /&gt;
Das reduziert deinen effektiven zugangscode um eine Stelle, da man für die erste Ziffer nur einmal auf jede Taste zu drücken braucht, um zu sehen, wie die Zahl anfängt.&lt;br /&gt;
&lt;br /&gt;
=Stimmt schon=&lt;br /&gt;
Hallo!&lt;br /&gt;
Ja, Dein Einwand ist richtig. Eigentlich darf man aus Sicherheitsgründen gar keine kompromittierende Anzeige darüber haben, ob eine gedrückte Taste im Code richtig oder falsch war. Die LED leuchtet ja, solange die zuletzt gedrückte Taste stimmte und man noch &amp;quot;in time&amp;quot; ist. Ich habs trotzdem mal so umgesetzt, weil die alte Haustürschaltung (war was mit einem Schieberegister, von vor über 30 Jahren aus einer Elektronikzeitschrift) auch so eine LED hatte und das Ding in einem Kasten hinter dem Klingelschild steckt, der natürlich weder einsehbar noch von außen erreichbar sein darf. Sonst könnte man das Ding gleich kurzschließen.&lt;/div&gt;</summary>
		<author><name>Stefan1971</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Codeschloss&amp;diff=38377</id>
		<title>Codeschloss</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Codeschloss&amp;diff=38377"/>
		<updated>2009-08-18T18:58:42Z</updated>

		<summary type="html">&lt;p&gt;Stefan1971: /* Ergänzung Statusübersicht der Software */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;von Stefan1971&lt;br /&gt;
&lt;br /&gt;
=== Einleitung ===&lt;br /&gt;
&lt;br /&gt;
Im Folgenden beschreibe ich ein Haustür-Codeschloss, das als kleines AVR-Projekt in Hard- und Software umgesetzt ist und mittlerweile seinen Dienst am Klingelschild einer Haustüre versieht. Durch Eingabe des richtigen Codes lässt sich damit die Haustüre ohne Schlüssel öffnen.&lt;br /&gt;
&lt;br /&gt;
=== Merkmale ===&lt;br /&gt;
* Codeschloss mit ATtiny2313 zum Schalten eines elektrischen Türöffners über Relais&lt;br /&gt;
* Programmierbarer Tastencode zum Öffnen der Haustür kann aus bis zu 12 Tasten bestehen&lt;br /&gt;
* Aktivierdauer des Türöffners ist einstellbar&lt;br /&gt;
* Einzelne Taster oder alternativ eine 4x3-Matrixtastatur können angeschlossen werden&lt;br /&gt;
* Rote LED, wenn Codeeingabe läuft (leuchtet, sobald erste richtige Codetaste gedrückt wurde; verlöscht bei Zeitablauf in der Codeeingabe bzw. zusammen mit Abschalten des Türöffners)&lt;br /&gt;
* Gelbe LED leuchtet, wenn Codeschloss in Programmiermodus ist (=Lernen eines Codes) und blinkt, wenn Aktivierzeit für den Türöffner eingestellt wird&lt;br /&gt;
* Grüne LED zur Anzeige, ob Türöffner gerade geschaltet ist&lt;br /&gt;
* Wenn der Türöffner gerade aktiv ist, kann er durch Drücken einer beliebigen Codetaste vor Ablauf des Timers abgeschaltet werden&lt;br /&gt;
* Anschlüsse sind vorgesehen für die 12 Volt-Stromversorgung (Wechselspannung), eine LED als Türschildbeleuchtung und den Türöffner. Für die Codetasten gibt es eine Anschlussbuchse.&lt;br /&gt;
&lt;br /&gt;
=== Programmierung zur Nutzung ===&lt;br /&gt;
==== Programmieren des Codes ====&lt;br /&gt;
Durch Drücken des Programmiertasters auf der Schaltung wird in den Programmiermodus gewechselt. Dieser wird durch Leuchten der gelben LED angezeigt. Nun sind die Tasten in der gewünschten Reihenfolge zu betätigen. Der Code kann aus bis zu zwölf Tastendrücken bestehen. Die Programmierung ist durch erneutes Drücken des Programmiertasters abzuschließen. Damit ist der Tastencode gespeichert. Werden bei der Programmierung die maximal möglichen Tasten gedrückt (derzeit 12), beendet sich der Programmiermodus ohne Betätigen des Programmiertasters.&lt;br /&gt;
&lt;br /&gt;
==== Programmieren der Aktivierdauer des Türöffners ====&lt;br /&gt;
Wird der Programmiertaster im Programmiermodus (d.h. die gelbe LED leuchtet) gedrückt, ohne dass eine Codetaste zum Lernen eines neuen Codes betätigt wurde, so wechselt das Codeschloss in die Programmierung für die Aktivierdauer des Türöffners. Die gelbe LED zeigt dies durch Blinken an. In diesem Modus erfolgt mit der Taste 1 eine Testauslösung des Türöffners, mit der Taste 2 kann die Dauer verlängert, mit Taste 3 die Dauer verkürzt werden.&lt;br /&gt;
&lt;br /&gt;
Ist eine Matrixtastatur angeschlossen, werden andere Tasten verwendet: Hier erfolgt die Testauslösung mit der Taste (*). Die Taste (7) verlängert und die Taste (4) verkürzt die Dauer.&lt;br /&gt;
&lt;br /&gt;
Die Dauer wird in Stufen von ca. 0,2 Sekunden eingestellt. &lt;br /&gt;
&lt;br /&gt;
Erneutes Drücken des Programmiertasters speichert die Einstellung, die gelbe LED erlischt. Jede andere Taste als 1, 2, 3 bzw. (*), (7) oder (4) bricht die Programmierung ab und verwirft evtl. gemachte Änderungen an der Aktivierdauer.&lt;br /&gt;
&lt;br /&gt;
=== Software ===&lt;br /&gt;
Das Steuerprogramm ist in Assembler programmiert. Über bedingte Assemblierung im Quelltext kann auf die Zielplattformen ATmega8 oder ATtiny2313 assembliert werden. Hintergrund ist, dass zuerst auf einem [http://www.myavr.de myAVR Board] mit ATmega8 entwickelt und später für den Selbstbau auf den ATtiny2313 umgeschwenkt wurde.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:left&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:left&amp;quot; | Folgende interne Zustände werden in der Firmware unterschieden:&lt;br /&gt;
! Status  !! Beschreibung&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;SCAN&#039;&#039;&#039;|| SCAN ist der Default-Modus im laufenden Betrieb. Warten auf Tasten in der richtigen Reihenfolge. Tastendruck gilt als erfolgt, wenn Taste losgelassen wurde. Mit Loslassen der ersten richtigen Taste wird (Software-) Timer gestartet. Rote LED leuchtet.&amp;lt;br /&amp;gt;Nächste Taste war richtig: Zeiger wird auf nächste zu erwartende Taste weiter gestellt, Timer wird zurückgesetzt.&amp;lt;br /&amp;gt;Taste war falsch: Zeiger auf Anfang, LED aus, Timer deaktivieren.&amp;lt;br /&amp;gt;Timer abgelaufen: Zeiger auf Anfang, LED aus; wie bei falscher Taste&amp;lt;br /&amp;gt;Anzeigen des SCAN-Modus durch Leuchten der roten LED, sobald die erste richtige Taste betätigt (d.h. losgelassen) wurde.&amp;lt;br /&amp;gt;Wenn alle Tasten in der richtigen Reihenfolge richtig gedrückt wurden, erfolgt Wechsel in Status OPEN.&amp;lt;br /&amp;gt;Wenn Programmierkontakt erkannt wurde, Wechsel in den PROG-Modus.&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;OPEN&#039;&#039;&#039; || Timer für Türöffner mit programmiertem Wert (aus Status PROG_DOOR) starten, grüne LED leuchtet, rote LED ebenfalls, Türöffner aktiv&amp;lt;br /&amp;gt;Timer abgelaufen: Türöffner aus, LEDs aus, zurück in SCAN-Modus&amp;lt;br /&amp;gt;Beliebige Taste wird gedrückt (Schließen ist relevant, nicht Öffnen): Türöffner aus, grüne und rote LED aus; zurück in SCAN-Modus: wie Timer-Ablauf&amp;lt;br /&amp;gt;Der Abbruch des OPEN-Modus durch Drücken einer beliebigen Taste ist realisiert, indem das Drücken einer falschen Taste simuliert wird.&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PROG&#039;&#039;&#039; || Programmiermodus: Tritt ein, wenn im SCAN-Modus der Programmierkontakt betätigt (=losgelassen) wurde. Ende des Programmiermodus, wenn Programmierkontakt erneut betätigt wird. Im Programmiermodus werden die betätigten Tasten (Loslassen der Taste, wie im SCAN-Modus) nacheinander im SRAM festgehalten. Hierzu wird Index auf SRAM-Tastenspeicher zunächst auf Null gesetzt. Bei Ende des Programmiermodus wird die im SRAM festgehaltene Tastenfolge ins EEPROM übernommen. Beenden des Programmiermodus, ohne dass eine Taste während des Programmiermodus betätigt wurde, erhält den bisher eingestellten Code; dann keine Übernahme ins EEPROM. Beenden des Programmiermodus führt dann in die Programmierung der Aktivierdauer des Türöffners; Wechsel in Modus PROG_DOOR.&amp;lt;br /&amp;gt;Eine begonnene Programmierung, bei der irrtümlich falsche Tasten gedrückt wurden, kann nicht storniert werden, sondern muss erneut durchgeführt werden. Im Programmiermodus leuchtet die gelbe LED.&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;PROG_DOOR&#039;&#039;&#039; || Dient zur Programmierung der Aktivierdauer des Türöffners.&amp;lt;br /&amp;gt;Um in diesen Modus zu gelangen, muss der Programmierkontakt zweimal betätigt werden, d.h. der Code-Programmiermodus muss ohne Druck einer Codetaste beendet (übersprungen) werden. Im PROG_DOOR-Modus blinkt die gelbe LED.&amp;lt;br /&amp;gt;Die Tasten des Codeschlosses erhalten im PROG_DOOR-Modus folgende Bedeutung:&amp;lt;br /&amp;gt;Taste 1: löst den Türöffner für die eingestellte Zeit zum Test aus (per Timer)&amp;lt;br /&amp;gt;Taste 2: verlängert mit jedem Tastendruck die eingestellte Zeit&amp;lt;br /&amp;gt;Taste 3: verkürzt mit jedem Tastendruck die eingestellte Zeit&amp;lt;br /&amp;gt;Jede andere Taste: Verwirft die Änderungen und verlässt den PROG_DOOR-Modus, Rückkehr in den SCAN-Modus.&amp;lt;br /&amp;gt;Abschließendes Betätigen des Programmierkontakts führt zu Übernahme des neuen Timer-Ladewerts ins EEPROM und beendet den PROG_DOOR-Modus. Wechsel in den SCAN-Modus.&lt;br /&gt;
Ist eine 4x3-Matrixtastatur angeschlossen, ist die Tastenbelegung für die Programmierung der Türöffneraktivierdauer wie folgt:&amp;lt;br /&amp;gt;Taste (*): Türöffner testhalber auslösen&amp;lt;br /&amp;gt;Taste (7): Aktivierdauer verlängern&amp;lt;br /&amp;gt;Taste (4): Aktivierdauer verkürzen&lt;br /&gt;
|- style=&amp;quot;vertical-align:top&amp;quot; &lt;br /&gt;
| &#039;&#039;&#039;STARTUP&#039;&#039;&#039; || In diesen Modus wird beim Start der Anwendung zunächst gewechselt. Er hat den Zweck, die drei LEDs des Codeschlosses dreimal blinken zu lassen um anzuzeigen, dass der Controller arbeitet und auf Eingaben wartet. Wenn diese Phase abgelaufen ist, wird in den SCAN-Modus gewechselt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;... wird fortgesetzt ...&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Category:Projekte]]&lt;br /&gt;
[[Category:AVR]]&lt;/div&gt;</summary>
		<author><name>Stefan1971</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Codeschloss&amp;diff=38371</id>
		<title>Codeschloss</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Codeschloss&amp;diff=38371"/>
		<updated>2009-08-18T16:17:59Z</updated>

		<summary type="html">&lt;p&gt;Stefan1971: /* Ersterstellung und Entwurf */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;von Stefan1971&lt;br /&gt;
&lt;br /&gt;
=== Einleitung ===&lt;br /&gt;
&lt;br /&gt;
Im Folgenden beschreibe ich ein Haustür-Codeschloss, das als kleines AVR-Projekt in Hard- und Software umgesetzt ist und mittlerweile seinen Dienst am Klingelschild einer Haustüre versieht. Durch Eingabe des richtigen Codes lässt sich damit die Haustüre ohne Schlüssel öffnen.&lt;br /&gt;
&lt;br /&gt;
=== Merkmale ===&lt;br /&gt;
* Codeschloss mit ATtiny2313 zum Schalten eines elektrischen Türöffners über Relais&lt;br /&gt;
* Programmierbarer Tastencode zum Öffnen der Haustür kann aus bis zu 12 Tasten bestehen&lt;br /&gt;
* Aktivierdauer des Türöffners ist einstellbar&lt;br /&gt;
* Einzelne Taster oder alternativ eine 4x3-Matrixtastatur können angeschlossen werden&lt;br /&gt;
* Rote LED, wenn Codeeingabe läuft (leuchtet, sobald erste richtige Codetaste gedrückt wurde; verlöscht bei Zeitablauf in der Codeeingabe bzw. zusammen mit Abschalten des Türöffners)&lt;br /&gt;
* Gelbe LED leuchtet, wenn Codeschloss in Programmiermodus ist (=Lernen eines Codes) und blinkt, wenn Aktivierzeit für den Türöffner eingestellt wird&lt;br /&gt;
* Grüne LED zur Anzeige, ob Türöffner gerade geschaltet ist&lt;br /&gt;
* Wenn der Türöffner gerade aktiv ist, kann er durch Drücken einer beliebigen Codetaste vor Ablauf des Timers abgeschaltet werden&lt;br /&gt;
* Anschlüsse sind vorgesehen für die 12 Volt-Stromversorgung (Wechselspannung), eine LED als Türschildbeleuchtung und den Türöffner. Für die Codetasten gibt es eine Anschlussbuchse.&lt;br /&gt;
&lt;br /&gt;
=== Programmierung zur Nutzung ===&lt;br /&gt;
==== Programmieren des Codes ====&lt;br /&gt;
Durch Drücken des Programmiertasters auf der Schaltung wird in den Programmiermodus gewechselt. Dieser wird durch Leuchten der gelben LED angezeigt. Nun sind die Tasten in der gewünschten Reihenfolge zu betätigen. Der Code kann aus bis zu zwölf Tastendrücken bestehen. Die Programmierung ist durch erneutes Drücken des Programmiertasters abzuschließen. Damit ist der Tastencode gespeichert. Werden bei der Programmierung die maximal möglichen Tasten gedrückt (derzeit 12), beendet sich der Programmiermodus ohne Betätigen des Programmiertasters.&lt;br /&gt;
&lt;br /&gt;
==== Programmieren der Aktivierdauer des Türöffners ====&lt;br /&gt;
Wird der Programmiertaster im Programmiermodus (d.h. die gelbe LED leuchtet) gedrückt, ohne dass eine Codetaste zum Lernen eines neuen Codes betätigt wurde, so wechselt das Codeschloss in die Programmierung für die Aktivierdauer des Türöffners. Die gelbe LED zeigt dies durch Blinken an. In diesem Modus erfolgt mit der Taste 1 eine Testauslösung des Türöffners, mit der Taste 2 kann die Dauer verlängert, mit Taste 3 die Dauer verkürzt werden.&lt;br /&gt;
&lt;br /&gt;
Ist eine Matrixtastatur angeschlossen, werden andere Tasten verwendet: Hier erfolgt die Testauslösung mit der Taste (*). Die Taste (7) verlängert und die Taste (4) verkürzt die Dauer.&lt;br /&gt;
&lt;br /&gt;
Die Dauer wird in Stufen von ca. 0,2 Sekunden eingestellt. &lt;br /&gt;
&lt;br /&gt;
Erneutes Drücken des Programmiertasters speichert die Einstellung, die gelbe LED erlischt. Jede andere Taste als 1, 2, 3 bzw. (*), (7) oder (4) bricht die Programmierung ab und verwirft evtl. gemachte Änderungen an der Aktivierdauer.&lt;br /&gt;
&lt;br /&gt;
=== Software ===&lt;br /&gt;
Das Steuerprogramm ist in Assembler programmiert. Über bedingte Assemblierung im Quelltext kann auf die Zielplattformen ATmega8 oder ATtiny2313 assembliert werden. Hintergrund ist, dass zuerst auf einem [http://www.myavr.de myAVR Board] mit ATMega8 entwickelt und später für den Selbstbau auf den ATtiny2313 umgeschwenkt wurde.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;... wird fortgesetzt ...&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Category:Projekte]]&lt;br /&gt;
[[Category:AVR]]&lt;/div&gt;</summary>
		<author><name>Stefan1971</name></author>
	</entry>
</feed>