<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
		<id>https://rn-wissen.de/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Freak</id>
		<title>RN-Wissen.de - Benutzerbeiträge [de]</title>
		<link rel="self" type="application/atom+xml" href="https://rn-wissen.de/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Freak"/>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Spezial:Beitr%C3%A4ge/Freak"/>
		<updated>2026-04-11T21:50:37Z</updated>
		<subtitle>Benutzerbeiträge</subtitle>
		<generator>MediaWiki 1.25.1</generator>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=TWI&amp;diff=12277</id>
		<title>TWI</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=TWI&amp;diff=12277"/>
				<updated>2007-06-22T14:02:13Z</updated>
		
		<summary type="html">&lt;p&gt;Freak: /* Merkmale */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;TWI ('''T'''wo-'''w'''ire Serial '''I'''nterface) ist eine Bezeichnung von [[Atmel|Atmel]] für die auf vielen [[AVR|AVR]] Megas vorhandene  [[I2C|I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C]]-Hardware.&lt;br /&gt;
&lt;br /&gt;
In diesem Artikel soll nur auf Besonderheiten der [[AVR]]-[[Microcontroller]] eingegangen werden, Einzelheiten zu [[I2C|I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C]] finden sich in den entsprechenden Artikeln.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Merkmale =&lt;br /&gt;
&lt;br /&gt;
* Master- und Slavemodus&lt;br /&gt;
* Multimaster&lt;br /&gt;
* 7-Bit Adressierung (als Master auch 10-Bit Adressierung möglich)&lt;br /&gt;
* Übertragungsrate von bis zu 400kBit/s&lt;br /&gt;
&lt;br /&gt;
= TWI verwenden =&lt;br /&gt;
Um TWI mit dem [[AVR]] verwenden zu können sind einige Einstellungen nötig, die hier in Abhängigkeit der Anwendung aufgezeigt werden.&lt;br /&gt;
&lt;br /&gt;
== TWI-Register ==&lt;br /&gt;
Hier eine kurze Beschreibung der für den TWI Betrieb notwendigen Register&lt;br /&gt;
&lt;br /&gt;
==== TWBR ====&lt;br /&gt;
:Bit Rate Register, alle 8 bit&lt;br /&gt;
:dient zum einstellen des Bus-Taktes als Master, siehe [[#Bit_Rate_Generator|Bit Rate Generator]]&lt;br /&gt;
&lt;br /&gt;
==== TWCR ====&lt;br /&gt;
:Control Register&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;{{Registertabelle8BitFix|TWINT|TWEA|TWSTA|TWSTO|TWWC|TWEN|&amp;amp;ndash;|TWIE}}&amp;lt;/div&amp;gt;&lt;br /&gt;
:die Hauptschaltstelle befindet sich hier,&lt;br /&gt;
:*'''TWINT''' TWI Interrupt Flag&lt;br /&gt;
::Nach Abarbeitung der letzten Aktion wird dieses Flag gesetzt, und ein Interrupt ausgelöst falls ''TWIE'' gesetzt ist.&lt;br /&gt;
::Es sollte anschliessend das Datenregister und das Statusregister ausgelesen werden und darauf entsprechend reagiert werden.&lt;br /&gt;
::Um das Flag zurückzusetzen muss es gesetzt werden.&lt;br /&gt;
::Mit dem zurücksetzen (löschen) von ''TWINT'' wird die nächste Aktion ausgelöst, es müssen deshalb vorher alle notwendigen Flags und Register (zB. ''TWDR'') entsprechend gesetzt werden.&lt;br /&gt;
:*'''TWEA''' TWI Enable Acknowledge Bit&lt;br /&gt;
::Sendet ein ACK nach einer Übertragung wenn&lt;br /&gt;
:::*als Slave die eigene Slaveadresse (''TWAR'') erkannt wurde,&lt;br /&gt;
:::*ein General Call erkannt wurde und das ''TWGCE''-Flag in ''TWAR'' gesetzt ist,&lt;br /&gt;
:::*ein ganz normales Byte als Slave oder als Master empfangen wurde.&lt;br /&gt;
:*'''TWSTA''' TWI Start Sequenz senden&lt;br /&gt;
::Die TWI-Hardware überprüft ob der Bus frei ist, und gibt die Startsequenz aus.&lt;br /&gt;
::Ist der Bus nicht frei, wartet das TWI-Modul bis eine Stopsequenz erkannt wurde und sendet die Startsequenz erneut.&lt;br /&gt;
::Dieses Flag muss per Software wieder gelöscht werden.&lt;br /&gt;
:*'''TWSTO''' TWI Stop Sequenz senden&lt;br /&gt;
::Als Master wird durch setzen eine Stopsequenz ausgegeben. Ist die Stopsequenz gesendet wird das Flag automatisch gelöscht.&lt;br /&gt;
::Als Slave kann dieses Flag zum zurücksetzen nach einem Fehler verwendet werden. Es wird keine Stopsequenz ausgegeben, aber das Modul beeinflusst anschliessend nicht mehr die Leitungen SCL oder SDA, das TWI-Modul befindet sich in einem definierten unadressierten Zustand.&lt;br /&gt;
:*'''TWWC''' TWI Write Collision Flag&lt;br /&gt;
::In das Datenregister ''TWDR'' sollte man nur schreiben, wenn ''TWINT'' High ist, ist ''TWINT'' Low, wird dieses Flag gesetzt und zeigt einen Fehler an.&lt;br /&gt;
:*'''TWEN''' TWI Enable&lt;br /&gt;
::Aktivieren des TWI-Moduls. Das TWI-Modul übernimmt u.a. die Steuerung über die Leitungen SCL und SDA.&lt;br /&gt;
:*'''TWIE''' TWI Interrupt Anforderung erlauben&lt;br /&gt;
::Interruptanforderung aktivieren, wenn eine Aktion durchgeführt wurde und global Interrupts erlaubt sind, wird ein Interrupt ausgelöst.&lt;br /&gt;
&lt;br /&gt;
==== TWSR ====&lt;br /&gt;
:Status Register&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;{{Registertabelle8BitFix|TWS7|TWS6|TWS5|TWS4|TWS3|&amp;amp;ndash;|TWPS1|TWPS0}}&amp;lt;/div&amp;gt;&lt;br /&gt;
:*'''TWSx''' TWI Status&lt;br /&gt;
::die oberen 5 Bit geben den Status der letzten Aktion wieder&lt;br /&gt;
:*'''TWPSx''' TWI Prescaler&lt;br /&gt;
::die zwei niederwertigen Bit zum einstellen des Prescaler als Master, siehe [[#Bit_Rate_Generator|Bit Rate Generator]]&lt;br /&gt;
&lt;br /&gt;
==== TWDR ====&lt;br /&gt;
:Data Register, alle 8 bit&lt;br /&gt;
:Beim Senden: nächstes Byte, das auf den Bus ausgegeben werden soll&lt;br /&gt;
:Beim Empfangen: letztes Byte, das über den Bus gekommen ist&lt;br /&gt;
:Die Daten sind gültig, solange das Bit ''TWINT'' in ''TWCR'' gesetzt ist&lt;br /&gt;
&lt;br /&gt;
==== TWAR ====&lt;br /&gt;
:Slave Address Register&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;{{Registertabelle8BitFix|TWA6|TWA5|TWA4|TWA3|TWA2|TWA1|TWA0|TWGCE}}&amp;lt;/div&amp;gt;&lt;br /&gt;
:*'''TWAx''' Slave Adresse&lt;br /&gt;
::Wird der [[AVR]] als Slave eingesetzt, wird in den oberen 7 Bit die Adresse eingetragen, auf die reagiert werden soll.&lt;br /&gt;
:*'''TWGCE''' General Call Enable&lt;br /&gt;
::Setzt man Bit0, kann zusätzlich auf einen ''General Call'' reagiert werden.&lt;br /&gt;
:als Master ist es unbenutzt&lt;br /&gt;
&lt;br /&gt;
==== TWAMR ====&lt;br /&gt;
:Slave Address Mask Register&lt;br /&gt;
:Zus&amp;amp;auml;tzlich zu den schon geannten Registern, kann es bei einigen ATMegas, wie dem [[ATMega168]], dieses Register geben, in der Regel hat es aber den Standardwert von $00, wobei sich das TWI-Modul verh&amp;amp;auml;lt wie bei den anderen ATMegas.&lt;br /&gt;
:Mit dem setzen von einzelnen Bits werden beim vergleich der Slaveadresse (die vom Master gesendet wurde) mit ''TWAR'' diese Bits ausmaskiert, dH. treffen immer zu, was bedeutet, dass der ATMega auf mehr als nur einer bestimmten Slaveadresse (''TWAR'') angesprochen werden kann.&lt;br /&gt;
:Werden zB. alle Bits gesetzt, fühlt sich der [[AVR]] immer angesprochen, egal welche Slaveadresse über den Bus gesendet wurde.&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;{{Registertabelle8BitFix|TWAM6|TWAM5|TWAM4|TWAM3|TWAM2|TWAM1|TWAM0|&amp;amp;ndash;}}&amp;lt;/div&amp;gt;&lt;br /&gt;
:Wird der [[AVR]] als Slave eingesetzt, kann in den oberen 7 Bit die Adressmaske eingetragen werden,&lt;br /&gt;
:als Master ist es unbenutzt&lt;br /&gt;
&lt;br /&gt;
== Übertragungsarten ==&lt;br /&gt;
Bei TWI gibt es diese Übertragungsarten&lt;br /&gt;
* Master Transmitter (nur Senden)&lt;br /&gt;
* Master Receiver (nur Empfangen)&lt;br /&gt;
* Slave Transmitter (auf Abruf Senden)&lt;br /&gt;
* Slave Receiver (nur Empfangen)&lt;br /&gt;
Abhängig von der Anwendung kann der [[AVR]] alle Arten der Übertragung im gleichen Programm ausführen.&lt;br /&gt;
&lt;br /&gt;
== Master ==&lt;br /&gt;
Ist der AVR Master, bestimmt er was und wie schnell es auf dem [[I2C|I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C]]-Bus zugeht. (Ausnahme: [[Clock_Stretching]] )&lt;br /&gt;
&lt;br /&gt;
Zur Bestimmung der Bus-Geschwindigkeit ist der ''Bit Rate Generator'' zuständig.&lt;br /&gt;
&lt;br /&gt;
=== Bit Rate Generator ===&lt;br /&gt;
Zur Übertragung gibt es die Bitraten ''Standard'', mit bis zu 100kBit/s, und ''FastMode'', mit bis zu 400kBit/s.&lt;br /&gt;
Der Master muss immer den Takt erzeugen, der bei Bedarf auf der Leitung SCL angelegt wird.&lt;br /&gt;
Der SCL-Takt ist beim AVR abhängig von der CPU-Frequenz.&lt;br /&gt;
Da [[I2C]], im Gegensatz zu [[RS232]], ein synchrones Protokoll ist, das mit dem Taktsignal SCL arbeitet, muss man nicht exakt auf eine Frequenz von 100kHz bzw. 400kHz kommen.&lt;br /&gt;
&lt;br /&gt;
Im TWI-Modul des AVR gibt es zwei Stellen, an denen man die Teilung der Frequenz einstellen kann:&lt;br /&gt;
* die ''Prescaler Bits'' (TWPS), diese 2 Bits befinden sich im ''TWI Status Register'' (TWSR)&lt;br /&gt;
* für die genauere Einstellung das ''TWI Bit Rate Register'' (TWBR)&lt;br /&gt;
&lt;br /&gt;
'''Formel zur Berechnung der SCL-Frequenz:'''&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\mathrm{SCL{-}Frequenz =  \frac{CPU{-}Frequenz}{16 + 2 \cdot TWBR \cdot 4^{TWPS} } }&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da ein AVR zur Zeit max. mit 20MHz getaktet werden kann, ist es nicht nötig, den Prescaler zu benutzen, bzw. er wird auf den Teiler 1 gestellt, was keiner Teilung entspricht. Mit diesem Teiler können alle CPU-Frequenzen und TWI-Takte abgedeckt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ '''Mögliche&amp;amp;nbsp;Prescaler-Werte'''&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Bit-Wert || Teiler&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
|00 ||1&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
|01 ||4&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
|10 ||16&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
|11 ||64&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
Die Werte von TWBR gehen von theoretisch 0 bis 255. Laut [[Atmel]] soll der Wert aber mind. 10 Betragen, da es sonst zu Problemen bei der Übertragung kommen kann.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel-Berechnung''':&lt;br /&gt;
&lt;br /&gt;
Es soll eine SCL-Frequenz von 100kHz erzeugt werden, die CPU-Frequenz beträgt 8MHz, der Teiler (Prescaler) ist &amp;amp;ndash; wie oben erwähnt &amp;amp;ndash; auf 1 (TWPS = 0).&lt;br /&gt;
&lt;br /&gt;
Laut der Formel ergibt das dann:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
100kHz = 8.0MHz / (16 + 2 * x * 4^0 )    / 1 fällt weg&lt;br /&gt;
100kHz = 8.0MHz / (16 + 2 * x )          / *(16 + 2 * x )&lt;br /&gt;
100kHz * (16 + 2 * x ) = 8000kHz         / kürzen  / : 100&lt;br /&gt;
16 + 2 * x  = 80                         / -16&lt;br /&gt;
2 * x  = 64                              / :2&lt;br /&gt;
x = 32&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
;Ergebnis: Der Wert für TWBR muss 32 sein, damit die SCL-Frequenz 100kHz ergibt, bei 8MHz CPU-Frequenz.&lt;br /&gt;
&lt;br /&gt;
'''Es Ergibt sich somit folgende Formel zum Berechnen von TWBR:'''&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\mathrm{TWBR = \frac{ \frac {CPU{-}Frequenz}{SCL{-}Frequenz} - 16}{2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Kommt ein Wert kleiner 10 heraus, kann ein höherer CPU-Takt gewählt werden, oder falls das nicht möglich ist, wird der Bus mit einem geringeren Takt betrieben, was trotzdem innerhalb der Spezifikation liegt. Wird eine krumme CPU-Frequenz verwendet, die kein ganzzahliges Ergebnis zur Folge hat, kann man mit der ersten Formel überprüfen, ob der Wert auf- oder abgerundet wird. Auf der sicheren Seite ist man, wenn der Wert aufgerundet wird. Das entspricht einer grösseren Teilung, also eine geringfügig kleinere Bitrate und liegt deshalb im Standard.&lt;br /&gt;
&lt;br /&gt;
== Slave ==&lt;br /&gt;
Um den AVR als Slave zu konfigurieren sind nur diese wenigen Schritte notwendig:&lt;br /&gt;
*gewünschte Slaveadresse im ''Address Register'' (TWAR) setzen&lt;br /&gt;
*im ''Control Register'' (TWCR)&lt;br /&gt;
**mit TWEN das TWI Modul aktivieren&lt;br /&gt;
**mit TWEA das Senden des Bestätigungsbits (ACK) zulassen&lt;br /&gt;
&lt;br /&gt;
anschliessend als Slave&lt;br /&gt;
*warten, bis im ''Control Register'' (TWCR) das Bit TWINT gesetzt ist, welches anzeigt, daß auf dem Bus was los ist&lt;br /&gt;
*das ''Status Register'' (TWSR) abfragen und entsprechend darauf reagieren&lt;br /&gt;
&lt;br /&gt;
=== Anmerkung zur CPU-Frequenz ===&lt;br /&gt;
&lt;br /&gt;
Da der Master den Takt vorgibt, muss der Slave nur mit dessen Takt am Bus mitlauschen. Um zu gewährleisten, daß der Slave dem Takt folgen kann sollte laut [[Atmel]] die CPU-Frequenz eines ATMega-Slave mind. das 16-fache der Bus-Frequenz betragen.&lt;br /&gt;
&lt;br /&gt;
das ergibt folgende Werte :&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Bus-Frequenz || minimale CPU-Frequenz&lt;br /&gt;
|-&lt;br /&gt;
|100 kHz || 1,6 MHz&lt;br /&gt;
|-&lt;br /&gt;
|400 kHz || 6,4 MHz&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Quellen =&lt;br /&gt;
[http://www.atmel.com/dyn/products/devices.asp?family_id=607 Atmel-AVR-Datenblätter]&lt;br /&gt;
&lt;br /&gt;
= Siehe auch =&lt;br /&gt;
* [[I2C|I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C]] - Details zu I2C&lt;br /&gt;
* [[RS232]] - serielle Schnittstelle&lt;br /&gt;
* [[RS485]] - serieller (asynchroner) Bus&lt;br /&gt;
* [[TWI Praxis]] - Programmbeispiele&lt;br /&gt;
* [[TWI_Slave_mit_avr-gcc|TWI-Slave mit avr-gcc]]&lt;br /&gt;
* [[USI (Avr)]] - USI Modul mit dem TWI nachgebildet werden kann, ist bei den meisten ATTinys und einigen ATMegas vorhanden.&lt;br /&gt;
* [[RN-Slave ID Übersicht]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:Linux 80|Linux 80]] 00:52, 6. Jan 2006 (CET)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Abkürzung]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;br /&gt;
[[Kategorie:Kommunikation]]&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Elektronik]]&lt;br /&gt;
[[Kategorie:Praxis]]&lt;/div&gt;</summary>
		<author><name>Freak</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=AVR_Assembler_Einf%C3%BChrung&amp;diff=10479</id>
		<title>AVR Assembler Einführung</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=AVR_Assembler_Einf%C3%BChrung&amp;diff=10479"/>
				<updated>2007-03-24T17:36:01Z</updated>
		
		<summary type="html">&lt;p&gt;Freak: /* Beispiel */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==AVR Assembler Einführung==&lt;br /&gt;
Es gibt mehrere Gründe, sich mit dem AVR-Assembler zu beschäftigen: &lt;br /&gt;
* reines Interesse&lt;br /&gt;
* Man hat eben keinen anderen Compiler, Bascom kostet ja was und GCC-C kann man möglicherweise genausowenig, also warum nicht gleich. &lt;br /&gt;
* Endlich Programmieren ohne Sprach-Restriktionen&lt;br /&gt;
* (theoretisch) sagenhaft schneller und kurzer Code&lt;br /&gt;
&lt;br /&gt;
Dadurch ergeben sich aber auch verschiedene Haupt-Zielgruppen für eine Einführung. Die eine ist in einer oder mehreren anderen Sprachen durchaus versiert, und möchte endlich auch mal richtig in die Tiefen der Hardware steigen. Die andere ist totaler Neueinsteiger und hat gehört, daß man Micro-Controller am besten mit Assembler programmiert.&lt;br /&gt;
&lt;br /&gt;
Es soll hier nur eine Starthilfe zum Einstieg gegeben werden. Viele Details und Varianten werden hier bei weitem nicht erschöpfend behandelt.&lt;br /&gt;
&lt;br /&gt;
==Unterschiede zu anderen Sprachen==&lt;br /&gt;
Man kann Assembler nicht direkt mit anderen Hochsprachen vergleichen. Es ist falsch gesagt Assembler ist viel besser als C, oder C ist viel besser als Assembler.&lt;br /&gt;
Hochsprachen haben generell ihren Vorteil in kürzerer (Programmier-) Zeit viel mehr erreichen zu können. Während man in Assembler jedes Detail programmieren muss schreibt man in der Hochsprache was man genau möchte und der Compiler erledigt das dann für einen, indem er den Code dann in Assembler übersetzt.&lt;br /&gt;
Der Vorteil liegt also klar auf der Hand, man spart sich eine Menge (unnötiger) Arbeit in dem man schneller sagen kann was man eigentlich machen möchte. Wie das jetzt genau funktioniert und was man dabei beachten muss übernimmt der Compiler.&lt;br /&gt;
Da gibts dann aber auch schon den ersten Nachteil. Fängt man mit einer Hochsprache an, braucht man sich hardwaremäßig kaum mit dem µC auseinander zu setzen und weiß deshalb auch nicht genau drüber Bescheid. Funktioniert dann etwas nicht sitzt man auf dem Schlauch.&lt;br /&gt;
Die Compiler werden aber immer besser, so kommen immer seltener Fehler zustande.&lt;br /&gt;
&lt;br /&gt;
Ein weiterer Nachteil ist eine Glaubens Frage, da man sich kaum mehr mit der Hardware auseinander setzt und nicht wissen muss wie ein µC eigentlich funktioniert geht die &amp;quot;Kultur&amp;quot; verloren. Man lernt gar nicht zu schätzen was das Ding jetzt eigentlich leistet. Die Ansprüche werden immer höher gesetzt und jeder Aussetzer ist umso schlimmer.&lt;br /&gt;
&lt;br /&gt;
Ein extremes Beispiel:&lt;br /&gt;
Ein eiserner Geschäftsmann geht nach Spanien und braucht Arbeiter, er schickt einen Gehilfen auf die Suche nach Arbeiter und schickt diese dann aufs Feld arbeiten. Ohne auch nur irgend etwas über deren Kultur zu wissen verlangt er das hart gearbeitet wird.&lt;br /&gt;
Doch schon in der ersten Woche gibt es Probleme, die Arbeiter möchten Mittags eine Pause. &amp;quot;Was, eine 3 Stündige Siesta? Seit ihr verrückt? Die in Japan arbeiten die Mittagszeit ja auch durch! Wie kommt ihr auf die Idee 3 Stunden Pause zu machen?&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Vorteile von Assembler sind also dass man weiß, was der µC genau macht (bzw. für Anfänger &amp;quot;was er tun sollte&amp;quot;).&lt;br /&gt;
Man hat die volle Kontrolle und fast jeder Befehl wird bei einem AVR mit einem Takt ausgeführt.&lt;br /&gt;
Man kann immer noch auf eine andere Hochsprache umsteigen, diese beherrscht man dann um so besser.&lt;br /&gt;
&lt;br /&gt;
Einziger Nachteil, man muss alles genau definieren, so wie es der µC haben möchte und kann nicht direkt auf fertige Funktionen zurück greifen.&lt;br /&gt;
Man schafft in der selben Zeit zwar genau so viel Code, der Code macht dann aber weniger als in C.&lt;br /&gt;
&lt;br /&gt;
Bildhaft ist der Unterschied der: Beim Assembler hat man ein weißes Stück Papier (ohne Linien) und ein Alphabet von A-Z. Aus diesen Buchstaben soll man nun erstmal Worte suchen und dann damit einen sinnvollen Text verfassen.  &lt;br /&gt;
&lt;br /&gt;
Bei &amp;quot;höheren&amp;quot; Sprachen ist das Papier zumindest mal liniert, und dazu kriegt man auch ein Wörterbuch und die Grammatik. Teile des Textes sind schon vorgeschrieben und ich muß nurmehr bei den ..... Punkten was einsetzen.   &lt;br /&gt;
&lt;br /&gt;
Anders kann man auch sagen, Hochsprachen sind wie ein Baukasten, man muss nur nach seinen Bedürfnissen sich die Teile zusammen &amp;quot;stecken&amp;quot;, ab und zu fertigt man sich auch eigene Teile. Aber das meiste ist vorgefertigt und nach eigenen Bedürfnissen schnell angepasst.&lt;br /&gt;
In Assembler muss man sich alles selber anfertigen, fertige Module gibt es nicht, es sei denn man hat es schon einmal gemacht und zufällig da.&lt;br /&gt;
&lt;br /&gt;
* Daten&lt;br /&gt;
Höhere Sprachen kennen alle möglichen Datentypen in allen möglichen Längen, integer, floating point, Strings. Dadurch sind aber auch gleich die möglichen und zulässigen Operationen schon eingeschränkt. &lt;br /&gt;
&lt;br /&gt;
Beim (AVR) Assembler gibt auch einige Datentypen. Sie unterscheiden sich aber nur durch die Größe, d.h. die Anzahl der Bytes, die sie belegen. Es gibt aber keine Einschränkungen bezüglich der Befehle, die man darauf anwenden kann.&lt;br /&gt;
&lt;br /&gt;
* Vor- und Nachteile&lt;br /&gt;
Wenn man den Assembler mit höheren Sprachen vergleicht, um vielleicht Vor- und Nachteile herausarbeiten zu können, kommt man schnell drauf, daß in jedem Vorteil für eine der Seiten auch schon der Nachteil drinnen steckt. Was ich beim Assembler an Performance heraushole, weil ich z.B. &amp;quot;Goodies&amp;quot; eines Controllers ausnutze, bezahle ich, wenn ich mir einen anderen kaufe und dann das ganze Programm umbauen muß.&lt;br /&gt;
&lt;br /&gt;
==Installation AVR-Studio==&lt;br /&gt;
Die Installation des ATMEL AVR Studios ist herzergreifend einfach. &lt;br /&gt;
* Man bekommt von Atmel das AStudio4b01.exe (oder was halt gerade aktuell ist) , das man einfach startet und schon ist es passiert. &lt;br /&gt;
* Wenn man nun das Käferchen doppelklickt und startet, &lt;br /&gt;
**erzeugt man am besten gleich mal ein neues Project. &lt;br /&gt;
**Man wählt den Pfad des Projects, und &lt;br /&gt;
**Wenn man seinen Brennadapter im Menü nicht findet, wählt man eben den Simulator und verwendet dann halt das PonyProg, oder was man halt hat. &lt;br /&gt;
**avrstudio erzeugt ein leeres Projekt und eine leere Assemblersource, die so heißt wie das Projekt. Das Gewurstel mit der Make-file nimmt uns AvrStudio ab. &lt;br /&gt;
==Struktur eines AVR-Maschinenprogrammes==&lt;br /&gt;
Bei höheren Sprachen wird diese Struktur vom Compiler/Linker erzeugt, beim Assembler muß man sich selbst darum kümmern. &lt;br /&gt;
&lt;br /&gt;
[[Bild:Asm_Flow.jpg]]&lt;br /&gt;
&lt;br /&gt;
Der Controller beginnt mit der Abarbeitung links oben bei der Programmspeicheradresse 0000. Wenn man Interrupts verwenden will, muß man gleich das nächste Bereich (ISR-Vectoren) überspringen (mit &amp;quot;JMP&amp;quot;). Wenn nicht, kann man sich diese Vektoren aber auch wegdenken. &lt;br /&gt;
&lt;br /&gt;
Man landet so oder so bei den Befehlen, die der Initialisierung dienen (Setzen der Startbedingung). Das ist zumindest die Festlegung des Stack-Pointers, sonst kann man keine &amp;quot;CALLS&amp;quot; oder Interrupts durchführen.  &lt;br /&gt;
&lt;br /&gt;
Danach kommt man von oben in die Haupt-Programm-Schleife, die (üblicherweise) immer wieder ohne Ende durchlaufen wird.  &lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;End&amp;quot; ist bei Microcontrollern daher auch kaum wirklich notwendig. Wenn es da ist, ist das eine ewige Wiederholung eines einzigen Befehls.&lt;br /&gt;
&lt;br /&gt;
==Source-Code Muster==&lt;br /&gt;
Das folgende Codebeispiel ist eine reine Basis-Initialisierung ohne irgendeine erkennbare Funktion. Für den Einstieg ist es am besten, das einfach abzuschreiben, wie es ist, und dann an den bezeichnenten Stellen mit eigenen Befehlen nach und nach zu erweitern. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 .NOLIST                    ; List-Output unterdrücken&lt;br /&gt;
 .INCLUDE &amp;lt;m8def.inc&amp;gt;       ; das gibt es für jeden Controllertyp&lt;br /&gt;
 .LIST                      ; List-Output wieder aufdrehen&lt;br /&gt;
 .CSEG                      ; was nun folgt, gehört in den FLASH-Speicher&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 ;------------------------------------------------------&lt;br /&gt;
 ;     Start Adresse 0000&lt;br /&gt;
 ;------------------------------------------------------&lt;br /&gt;
 RESET:&lt;br /&gt;
     jmp INIT           ; springen nach &amp;quot;INIT&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 ;------------------------------------------------------&lt;br /&gt;
 ;     ISR VECTORS&lt;br /&gt;
 ;------------------------------------------------------&lt;br /&gt;
 ;    .....    hier kommen dann die Sprungadressen für die Interrupts rein&lt;br /&gt;
 ;             dazu kommen wir noch&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 .ORG INT_VECTORS_SIZE    ; dadurch haben wir für die Vektoren Platz gelassen&lt;br /&gt;
 INIT:  &lt;br /&gt;
 ;------------------------------------------------------&lt;br /&gt;
 ;     INITIALIZE&lt;br /&gt;
 ;------------------------------------------------------&lt;br /&gt;
     ldi r24,high(RAMEND)     ;Stack Pointer setzen &lt;br /&gt;
     out SPH,r24              ; &amp;quot;RAMEND&amp;quot; ist in m8def.inc (s.o.) festgelegt&lt;br /&gt;
     ldi r24,low(RAMEND)      ; &lt;br /&gt;
     out SPL,r24              ;&lt;br /&gt;
&lt;br /&gt;
 ;------------------------------------------------------&lt;br /&gt;
 ;   eigene Initialisierungen&lt;br /&gt;
 ;------------------------------------------------------&lt;br /&gt;
 ;....&lt;br /&gt;
 ;....&lt;br /&gt;
 ;....&lt;br /&gt;
&lt;br /&gt;
 ;------------------------------------------------------&lt;br /&gt;
 ;   HAUPTSCHLEIFE&lt;br /&gt;
 ;------------------------------------------------------&lt;br /&gt;
 Hauptschleife: &lt;br /&gt;
 ;....   eigene befehle&lt;br /&gt;
 ;....   eigene befehle&lt;br /&gt;
 ;....   eigene befehle&lt;br /&gt;
        rjmp Hauptschleife         ; immer wiederholen &lt;br /&gt;
&lt;br /&gt;
 ;------------------------------------------------------&lt;br /&gt;
 ;   ENDE&lt;br /&gt;
 ;------------------------------------------------------&lt;br /&gt;
 Ende:  &lt;br /&gt;
        rjmp Ende&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Der Ablauf der Übersetzung===&lt;br /&gt;
Der Assembler ist ja selbst auch nur ein Programm und zu Beginn recht spartanisch ausgestattet: Er hat einen Daten-Buffer zur Verfügung, in den er den Maschinencode hineinschreiben soll, einen Pointer (Zeiger) dazu, damit er immer weiß, wo er grad ist, und eine allgemeine Tabelle, wo er Texte mit Zahlen verknüpfen kann. Alles ist zu Beginn leer bzw. auf NULL. &lt;br /&gt;
Mit diesen Voraussetzungen fängt er an, unseren Source-Text zeilenweise zu lesen. Und in jeder Zeile (die nicht leer ist) erwartet er eine Anweisung, was zu tun ist&lt;br /&gt;
====Assembler Direktiven/Präprozessor====&lt;br /&gt;
Das sind Anweisungen an den Assembler selbst und erzeugen keine Maschinenbefehle. Im obigen Source-Beispiel sind einige enthalten.&lt;br /&gt;
 .NOLIST                    &lt;br /&gt;
Normalerweise schreibt der Assembler ja eine Übersetzungsliste. Nach dieser Anweisung läßt er das bleiben&lt;br /&gt;
 .INCLUDE &amp;lt;m8def.inc&amp;gt;       ; das gibt es für jeden Controllertyp&lt;br /&gt;
sagt ihm, er soll jetzt erstmal die (text) datei &amp;quot;m8def.inc&amp;quot; lesen und genauso behandeln, als wäre diese Datei mit dem Editor hier reinkopiert worden. &lt;br /&gt;
 .LIST&lt;br /&gt;
Ab nun wird wieder alles in der Übersetzungsliste protokolliert. &lt;br /&gt;
 .CSEG&lt;br /&gt;
was danach folgt, bezieht sich auf den FLASH-Programm-Speicher&lt;br /&gt;
&lt;br /&gt;
 Gleich ein Hinweis: Der &amp;quot;AVR Assembler 2&amp;quot; geht dazu über, die C-Syntax für &lt;br /&gt;
 Präprozessoranweisungen zu verwenden. Diese haben dann als Kennzeichen ein &amp;quot;#&amp;quot; vorangestellt.&lt;br /&gt;
&lt;br /&gt;
====Bemerkungen / Kommentare====&lt;br /&gt;
 ;------------------------------------------------------&lt;br /&gt;
Alles, was NACH einem Strichpunkt steht, schreibt er einfach nur in die Übersetzungsliste, sonst macht er nix.&lt;br /&gt;
====Label (Sprungmarke)====&lt;br /&gt;
 RESET:&lt;br /&gt;
Was gleich ganz links in der Zeile beginnt (und mit einem Doppelpunkt abgeschlossen ist) schreibt er einfach in die genannte Tabelle und den momentanen Wert des Instruction Pointers (IP) dazu. Sonst hat das im Moment keine weitere Bedeutung. Natürlich, wenn er den gleichen Text schon mal hatte, gibt es eine Fehlermeldung, denn '''ein Label muss eindeutig sein'''&lt;br /&gt;
&lt;br /&gt;
====Commands====&lt;br /&gt;
     jmp INIT           ; springen nach &amp;quot;INIT&amp;quot;&lt;br /&gt;
Alles, was nicht ganz links steht und auch nix anderes ist, betrachtet der Assembler als &amp;quot;Command&amp;quot;. Normalerweise ist das eben eine AVR-Instruktion aus dem &amp;quot;Instruction Set&amp;quot;. Hier ist das &amp;quot;JMP&amp;quot;, also im Programm einfach woanders weitermachen. Gut, aber wo ? Der Rechner braucht nun unbedingt eine Zahl, denn &amp;quot;INIT&amp;quot; sagt ihm ja nichts. Also sieht er nun in der Tabelle nach, ob er den Text &amp;quot;INIT&amp;quot; schon mal hatte. Hatte er nicht, den zu der Stelle weiter hinten, wo &amp;quot;INIT:&amp;quot; als Sprungmarke steht (s.o) ist er ja noch garnicht gekommen. &lt;br /&gt;
&lt;br /&gt;
Ich kann leider nicht genau sagen, welche Strategie der AVR-Assembler nun anwendet, dazu gibt es keine Doku. Manche Assembler lesen erstmal überhaupt nur den Sourcetext von vorn bis hinten durch, um alle &amp;quot;Sprungmarken&amp;quot; zu sammeln (Pass I) und fangen dann nochmal von vorne an (Pass II), diesmal mit schon gefüllter Tabelle. Andere machen das etwas gefinkelter. Ist uns aber eigentlich egal. &lt;br /&gt;
&lt;br /&gt;
Jedenfalls findet er letztlich den Text &amp;quot;INIT&amp;quot; und daneben steht die Nummer der Speicherstelle, wo wir eben &amp;quot;INIT:&amp;quot; hingeschrieben haben. Und nun schreibt der Assembler also den Maschinencode für &amp;quot;JMP&amp;quot; in den Buffer und dazu die Zahl aus der Tabelle. Das war mal ein Befehl, also addiert er auf seinen Zeiger eins drauf und ist mit diesem Befehl fertig.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====ORG / JMP====&lt;br /&gt;
Das, was für den Controller beim Ablauf dann ein &amp;quot;JMP&amp;quot; ist, ist das &amp;quot;.ORG&amp;quot; für den Compiler. Wenn also bislang der Assembler den FLASH-Speicher von 0 - nn mit Befehlen befüllt hat, macht er durch &lt;br /&gt;
 .ORG INT_VECTORS_SIZE    &lt;br /&gt;
mit der Stelle weiter, die er über die gleiche Tabelle unter &amp;quot;INT_VECTORS_SIZE&amp;quot; gefunden hat. Dieser Tabelleneintrag, genauso wie &amp;quot;RAMEND&amp;quot; an anderer Stelle, entsteht aus der Datei &amp;quot;m8def.inc&amp;quot;. Wie im vorliegenen Fall macht man diese &amp;quot;Assembler-Jumps&amp;quot;, um Speicherstellen freizuhalten.&lt;br /&gt;
&lt;br /&gt;
==Merkwürdiges==&lt;br /&gt;
===Befehlsadressen / Byteadressen ===&lt;br /&gt;
[[Atmel Controller Mega16 und Mega32#Maschinen-Code|Ein Maschinenbefehl besteht aus maximal drei, bit-mäßig verschachtelten Teilen]]. Die meisten Befehle brauchen dafür genau 16 Bit (also zwei Byte), manchmal reicht das nicht, da gehören dann nochmal 16 Bit dazu. Kleiner als 16 Bit ist aber keiner. Aus diesem Grund wäre es natürlich sinnlos, Adressen für Befehle in Bytes auszudrücken, wenn es eh immer Vielfache von 2 sein müssen, das kleinste Bit einer solchen Adresse wäre ja immer null. &lt;br /&gt;
&lt;br /&gt;
 Also adressiert man Commands in &amp;quot;Worten&amp;quot; von 16 - Bit bzw. 2 Bytes&lt;br /&gt;
&lt;br /&gt;
Beim Ablegen eines Labels (Sprungmarke) werden also Wortadressen in der Tabelle angelegt. Solange der Wert auch als Befehls-Adresse verwendet wird (z.B. &amp;quot;JMP ''Label''&amp;quot;), braucht das nicht zu kümmern, denn genauso will es der AVR ja dann auch haben. '''Wenn dort aber Daten stehen''' und wir wollen diese adressieren, müssen wird '''den Wert mal 2 nehmen''' (oder einmal nach links schieben, was dasselbe ist), sonst landen wir im Nirwana.   &lt;br /&gt;
===3 ist nicht gleich 3 ===&lt;br /&gt;
Eine Zahl bedeutet also bei der Maschinensprache unter Umständen ganz was anderes, je nachdem, in welchem Zusammenhang sie verwendet wird. Bei allen Befehlen, die nur für die Register 16 - 31 gehen, steht im Maschinencode für das Register 16 nicht 16 drin, sondern 0. die &amp;quot;16&amp;quot; addiert er dann bei der Befehlsausführung drauf (für den Techniker: er braucht ja nur das Bit 2&amp;lt;sup&amp;gt;4&amp;lt;/sup&amp;gt; hochzuziehen)&lt;br /&gt;
===GPR ist nicht gleich GPR===&lt;br /&gt;
Was auch beim Einstieg leicht irritieren kann ist der Umstand, daß die 32 sogenannten &amp;quot;'''G'''eneral '''P'''urpose '''R'''egister&amp;quot; irgendwie so gar nicht generell und gleich sind. Manche Befehle kann ich mit allen 32 Registern machen, einige nur mit R16-R31, andere von R24 aufwärts und dann sind da noch R26 bis R31, die heissen dann manchmal auch noch X, Y und Z &lt;br /&gt;
===SFR ist gar nicht gleich GPR===&lt;br /&gt;
'''S'''pecial '''F'''unction '''R'''egister sind überhaupt seltsam, die meisten GPR-Befehle gehen da gleich garnicht, dafür gibt es andererseits ein paar Bit-Manipulationen, die gehen wiederum nur mit diesen. Dann gibt es auch Bit-Abfragen, die gehen da wie dort und bewirken auch das Gleiche, aber dafür heissen sie dann anders. &lt;br /&gt;
===Assembler-Befehle===&lt;br /&gt;
Viele dieser Probleme nimmt uns der Assembler ab, viele aber nicht. Dort erscheinen die Instruktionen immer so&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
 | ''' '''&lt;br /&gt;
 | '''CMD'''&lt;br /&gt;
 | '''ARG&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;'''&lt;br /&gt;
 | '''ARG&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;'''&lt;br /&gt;
 |}&lt;br /&gt;
wobei die Argumente 1 u. 2 optionell, d.h. bei Bedarf erscheinen. Command ist natürlich immer da.&lt;br /&gt;
Trotz der Hilfe des Assemblers durch &amp;quot;Warnings&amp;quot; und &amp;quot;Errors&amp;quot; ist bei den Argumenten aber immer Vorsicht geboten. Wir haben gehört, daß Arg 1 und Arg 2 im Grunde einfach nur zwei Zahlen sind, die dann zusammen mit dem Command-Code zum Maschinenbefehl werden. Wenn es dem Assembler also auch nur irgendwie gelingt, aus dem, was wir da hinschreiben, Zahlen zu machen die er umwandeln kann, nimmt er sie auch.   &lt;br /&gt;
&lt;br /&gt;
===Zwischenbilanz===&lt;br /&gt;
Einige dieser sonderbaren Dinge lassen sich leicht erklären, manche schwer, manche mangels Unterlagen darüber gar nicht. Deswegen versuch ich es hier auch gleich gar nicht. &lt;br /&gt;
&lt;br /&gt;
So oder so sind es Fakten, an die man sich am besten einfach gewöhnt. Das scheint und ist am Anfang sicher schwer, solange man noch mit den einzelnen Befehlen kämpft. RISC-Befehle werden aber erst in bestimmten Gruppierungen überhaupt wirklich sinnvoll, und durch diese sich immer wieder wiederholenden Gruppen wird es sehr schnell leichter. &lt;br /&gt;
&lt;br /&gt;
Beim Briefe schreiben denkt man ja auch nicht in Buchstaben, das wäre mühsam, sondern in Worten oder in ganzen Sätzen.&lt;br /&gt;
&lt;br /&gt;
==Load &amp;amp; Store==&lt;br /&gt;
Die meisten Befehle für den AVR laufen nach dem Load &amp;amp; Store (Laden und Speichern) Prinzip ab. Das heißt, die Daten werden zuerst aus dem SRAM-Speicher (oder den I/O bzw. SFR Registern) in die allgemeinen Register (GPR) geladen, dort verarbeitet, und danach wieder in den SRAM oder die SFR zurückgestellt.  &lt;br /&gt;
&lt;br /&gt;
[[Bild:Asm_cmd.jpg]]&lt;br /&gt;
&lt;br /&gt;
Das ist natürlich eine recht allgemeine Darstellung, aber es hilft, das Instruction Set des AVR schon ein wenig besser zu verstehen. &lt;br /&gt;
&lt;br /&gt;
Es bedeutet, um z.B. ein Byte aus der einen Ecke des SRAM in eine andere zu kopieren, brauchen wir wenigstens 2 Maschineninstruktionen, einmal Load und einmal Store. Und wenn wir was an dem Byte ändern wollen, kommt diese Befehle natürlich dazu. &lt;br /&gt;
&lt;br /&gt;
Es gibt zu (fast) jeder Art &amp;quot;Load&amp;quot;-Befehl ein Äquivalent als &amp;quot;Store&amp;quot;, und zum Finden genügt es meist, statt &amp;quot;L&amp;quot; an der selben Stelle ein &amp;quot;S&amp;quot; zu nehmen. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  LDS    GPR, adresse  ; lade das Byte von der Adresse in ein GPR  &lt;br /&gt;
  STS    adresse, GPR  ; speichere den Inhalt von GPR in der Adresse&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Wenn es um die I/O Register (SFR) geht:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  IN     GPR, I/O-Register    ; GPR &amp;lt;-----I/O Register &lt;br /&gt;
  OUT    I/O-Register, GPR    ; I/O Register &amp;lt;---- GPR&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Für feste Werte (Literals) gibt es natürlich keine Store-Variante, denn diese Werte stehen ja im FLASH (Programm) Speicher, und da kann man nicht einfach einzelne Bytes verändern.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  LDI    GPR, wert&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Beispiel===&lt;br /&gt;
&lt;br /&gt;
An PORTC haben wir (mit Vorwiderständen) ein paar LEDs angeschlossen. Und die sollen einfach nur zeigen, welche 0-er und 1-er am PORTB anliegen. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ; Eigene Initialisierungen&lt;br /&gt;
  LDI R24, 0            ; der wert &amp;quot;0&amp;quot; ins allgemeine Register R24&lt;br /&gt;
  OUT DDRB, R24         ; das kommt ins Controll-register f. PortB&lt;br /&gt;
                        ; dadurch sind diese PINs als INPUT festgelegt&lt;br /&gt;
  LDI R24, 255          ; der wert &amp;quot;255&amp;quot; = FF ins allgemeine Register R24&lt;br /&gt;
  OUT DDRC, R24         ; das kommt ins Controll-register f. PortC&lt;br /&gt;
                        ; dadurch ist das Port auf OUTPUT gestellt&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 ; Eigene Befehle (in der Hauptschleife)&lt;br /&gt;
  IN  R24, PINB         ; die Bits vom PortB ins allgemeine Register R24&lt;br /&gt;
  OUT PORTC, r24        ; schreiben wir nach PortC&lt;br /&gt;
                        ; wo ein 1-er ist, leuchtet nun die LED&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn wir diese Befehle in das Programm-Schema oben einfügen, haben wir also das erste Assemblerprogramm schon geschrieben.&lt;br /&gt;
====Programm-Map====&lt;br /&gt;
Eine interessanter Output, wenn wir dieses Programm mit F7 übersetzen lassen, ist die Map-File. Sie ist ein Abbild der oben genannten &amp;quot;Text &amp;lt;--&amp;gt; Adresse&amp;quot;-Tabelle&lt;br /&gt;
&lt;br /&gt;
(gekürzt)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
AVRASM ver. 2.0.28  D:\avr_c\avrstudio\Dokutest\Dokutest.asm Sat Dec 10 11:23:45 2005&lt;br /&gt;
....&lt;br /&gt;
EQU  sram_start   00000060&lt;br /&gt;
EQU  sram_size    00000800&lt;br /&gt;
EQU  ramend       0000085f&lt;br /&gt;
......&lt;br /&gt;
EQU  sph          0000003e&lt;br /&gt;
EQU  spl          0000003d&lt;br /&gt;
EQU  portb        00000018&lt;br /&gt;
EQU  ddrb         00000017&lt;br /&gt;
EQU  pinb         00000016&lt;br /&gt;
EQU  portc        00000015&lt;br /&gt;
EQU  ddrc         00000014&lt;br /&gt;
EQU  pinc         00000013&lt;br /&gt;
EQU  int_vectors_size 0000002a&lt;br /&gt;
CSEG reset        00000000&lt;br /&gt;
CSEG init         0000002a&lt;br /&gt;
CSEG hauptschleife 00000032&lt;br /&gt;
CSEG ende         00000035&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Wir finden darin alle Sprungadressen und alle sonstigen Werte, die wir verwendet haben. Tatsächlich in den Maschinencode eingesetzt werden vom Assembler immer die Zahlen, die daneben stehen&lt;br /&gt;
&lt;br /&gt;
===Pointer-Register===&lt;br /&gt;
In vielen Fällen ist es nicht sinnvoll, für Load &amp;amp; Store explizit jedesmal die Speicheradresse dazuschreiben zu müssen. Es können auch die Pointer Register X, Y und Z verwendet werden. Das sind die Register &lt;br /&gt;
 R26:R27 = X &lt;br /&gt;
 R28:R29 = Y &lt;br /&gt;
 R30:R31 = Z &lt;br /&gt;
Da wir ja oft mehr Speicher haben als 256 Byte, werden immer zwei Register zusammengefaßt und können dadurch die Bereiche 0 - 65535 abdecken (64k). Gut, aber wie kriegen wir so große Zahlen da rein ? Wir haben ja nur einen 8-Bit Processor und nicht 16. &lt;br /&gt;
&lt;br /&gt;
Wir müssen also die Adresse 8-Bit-weise übergeben, aber der Assembler hilft uns ja dabei. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 LDI   R26, LOW(Adresse)        ; R28 für &amp;quot;Y&amp;quot; u. R30 für &amp;quot;Z&amp;quot;&lt;br /&gt;
 LDI   R27, HIGH(Adresse)       ; R29 für &amp;quot;Y&amp;quot; u. R31 für &amp;quot;Z&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit diesem &amp;quot;LOW&amp;quot; und &amp;quot;HIGH&amp;quot; teilt uns der Assembler die Adresse genau in die richtigen 8-Bit Portionen, die wir also so in den &amp;quot;X&amp;quot; Pointer laden können.&lt;br /&gt;
&lt;br /&gt;
Noch eine Hilfe gibt es: Wir können, besser zu merken, auch schreiben:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 LDI   XL, LOW(Adresse)        ; YL für &amp;quot;Y&amp;quot; u. ZL für &amp;quot;Z&amp;quot;&lt;br /&gt;
 LDI   XH, HIGH(Adresse)       ; YH für &amp;quot;Y&amp;quot; u. ZH für &amp;quot;Z&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Also &amp;quot;LOW&amp;quot; für &amp;quot;L&amp;quot; und &amp;quot;HIGH&amp;quot; für &amp;quot;H&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Indirekte Adressierung====&lt;br /&gt;
Mit den Pointer-Register kann man also Indirekte Adressieren(=einmal um die Ecke). Statt:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  LDS    GPR, adresse  ; lade das Byte von der Adresse in ein GPR  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Schreiben wir&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  LDI   XL, LOW(Adresse)&lt;br /&gt;
  LDI   XH, HIGH(Adresse)&lt;br /&gt;
  LD    GPR, X        ; '''Indirekt''': lade das Byte, wo der Pointer X hinzeigt&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
beziehungsweise &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  LDI   XL, LOW(Adresse)&lt;br /&gt;
  LDI   XH, HIGH(Adresse)&lt;br /&gt;
  ST    X, GPR        ; '''Indirekt''': speichern, wo der Pointer X hinzeigt&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Warum sollte man sowas kompliziertes tun ? Nun, zum Beispiel dann, &lt;br /&gt;
* wenn man an einer Stelle im Programm die Adresse festlegt, aber ganz woanders braucht (Subroutinen) &lt;br /&gt;
* wenn man für mehrere Folge-Befehle die gleiche Adresse wieder braucht&lt;br /&gt;
* wenn man mit der Adresse (als Zahl) rechnen will&lt;br /&gt;
&lt;br /&gt;
====Post-Increment/Pre-Decrement====&lt;br /&gt;
Wenn ich zum Beispiel 4 Byte hintereinander im Speicher auf &amp;quot;0&amp;quot; löschen will&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  LDI   XL, LOW(Adresse)&lt;br /&gt;
  LDI   XH, HIGH(Adresse)&lt;br /&gt;
  LDI   GPR, 0&lt;br /&gt;
  ST    X+, GPR   ;speichern, wo X hinzeigt, und dann 1 auf X addieren&lt;br /&gt;
  ST    X+, GPR   ;das 2.Byte dahinter&lt;br /&gt;
  ST    X+, GPR   ;das 3.Byte dahinter&lt;br /&gt;
  ST    X+, GPR   ;das 4.Byte dahinter&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Durch das automatische Addieren brauche ich nichts weiter zu tun. Als Gegenstück dazu kann man auch jedesmal 1 abziehen lassen, das aber immer '''vorher'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ST    -X, GPR   ;1 von X abziehen und dann speichern, wo X hinzeigt&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All das gibt's für X, Y und Z. Es geht aber immer nur &lt;br /&gt;
* Load &amp;amp; Store und '''dann''' addieren&lt;br /&gt;
* '''erst''' subtrahieren und '''dann''' Load &amp;amp; Store &lt;br /&gt;
Diese Kombinationen werden einfach am häufigsten gebraucht&lt;br /&gt;
&lt;br /&gt;
====Displacement====&lt;br /&gt;
Für die beiden Pointer Y und Z kann man auch mit Displacement arbeiten&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  LDD   GPR, Y+4   ; wo Y hinzeigt, aber 4 Byte dahinter&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Welches Register ?==&lt;br /&gt;
Bei den Load &amp;amp; Store Befehlen könnten als GPR alle 32 Allgemeinen Register beliebig verwendet werden, um das entsprechende Byte aufzunehmen oder abzugeben. Aber als Zwischenspeicher oder Arbeitsregister ist es am besten, Registern wie r26-&amp;gt;r31, die möglicherweise als Pointer gebraucht werden, eher auszuweichen. &lt;br /&gt;
&lt;br /&gt;
 Wird das Assemblerprogramm durch inline oder libraries in eine Hochsprache &lt;br /&gt;
 eingebunden, muß man bei sich natürlich an die Register-Konventionen dieser&lt;br /&gt;
 Umgebung halten. &lt;br /&gt;
&lt;br /&gt;
 Schreibt man ein &amp;quot;stand-alone&amp;quot; Programm, kann (und sollte) man sich seinen eigenen&lt;br /&gt;
 Konventionen und Regeln schaffen. Das ist das, was der Assembler-Fan so liebt.&lt;br /&gt;
&lt;br /&gt;
==Benutzerdaten==&lt;br /&gt;
Daten wie Variable oder Felder werden üblicherweise im SRAM abgelegt und (s.o) von dort auch geholt. Bei allen Compilern und natürlich auch beim Assembler können zum Programmierzeitpunkt nur die Adressen davon festgelegt werden, aber keine Inhalte. Erst zur Laufzeit des Programmes kommen hier Werte rein. Manche Compiler gaukeln es zwar vor, aber (ein C-Beispiel):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 char  MeinName[] = &amp;quot;Sepp Meier&amp;quot; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
bewirkt in Wirklichkeit drei Dinge: Im SRAM wird die nächste, noch nicht benutzte Adresse dem Text &amp;quot;MeinName&amp;quot; in der oben genannten Tabelle abgelegt, der String &amp;quot;Sepp Meier&amp;quot; wird im FLASH Programmspeicher bereitgestellt, und es wird eine Transfer-Routine generiert, die beim tatsächlichen Start des fertigen Programmes diesen String in das Feld &amp;quot;MeinName&amp;quot; transferiert. &lt;br /&gt;
&lt;br /&gt;
Im Assembler ist es eben genauso: Wir können durch die Anfangsadressen und einen Namen dazu Felder festlegen, die dann zur Laufzeit benützt werden. Mehr eigentlich nicht. Und erst, wenn wir Befehle schreiben, die diese Daten verwenden, ergibt sich daraus ein Datentyp. Vorher sind das einfach nur Bytes.&lt;br /&gt;
&lt;br /&gt;
Das ist bei Hochsprachen anders: Schon in der Source legen wir durch verschiedene Angaben den Datentyp (char, integer, etc.) fest und daraus entscheidet dann der Compiler, welche Maschinen-Instruktionen er dafür verwenden wird. Wir können das nurmehr eingeschränkt beeinflussen. &lt;br /&gt;
&lt;br /&gt;
===Daten im SRAM===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.DSEG           ; Das ist eine Datensegment, d.h. es werden SRAM-Adressen festgelegt&lt;br /&gt;
CharBuf: 	.byte 24&lt;br /&gt;
OtherData: 	.byte 4 &lt;br /&gt;
....     &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
'''Anmerkung:''' Standardgemäß beginnt der Assembler mit der kleinsten SRAM Adresse. Bei den meisten AVRs ist das die tatsächliche Byte-Adresse 0x0060 (d.i. 96 dezimal). &lt;br /&gt;
[[Atmel_Controller_Mega16_und_Mega32#Adressen_Mapping|Siehe Adress-Mapping]]&lt;br /&gt;
&lt;br /&gt;
Dadurch, daß wir geschrieben haben &amp;quot;.byte 24&amp;quot; bestimmen wir, daß als nächste Datenadresse automatisch dann 96 + 24 = 120 gilt. Also ist mit &amp;quot;OtherData&amp;quot; dann 0x0078 (dez. 120) verknüpft. &lt;br /&gt;
&lt;br /&gt;
'''Noch eins:''' Wir haben ja gesagt, für den Assembler ist alles letztlich eine Zahl. Wir können daher auch damit rechnen. Wenn wir also die &amp;quot;24&amp;quot; nicht selbst wo hinschreiben wollen, verwenden wir einfach den Ausdruck &lt;br /&gt;
 LDI R10 , Otherdata - CharBuf &lt;br /&gt;
und laden damit das Register 10 mit der Zahl 24 &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
===Daten im FLASH (Literale)===&lt;br /&gt;
Literale sind Werte, die schon in der Source festgelegt werden können. Das geht im Prinzip ähnlich, nur müssen wir nun auch Datentypen festlegen&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
OneByte: 	.db   1             ; ein byte mit dem inhalt 0x01   &lt;br /&gt;
MeinName:       .db   &amp;quot;Sepp Meier&amp;quot;  ; mehrere Bytes mit Text&lt;br /&gt;
OneWord: 	.dw   1,2           ; zwei WORDs (16 Bit) mit dem inhalt 0x0001 u.  0x0002&lt;br /&gt;
....     &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Definitionen können wir auch direkt in den Programmcode reinmischen. Wir müssen aber natürlich schauen, daß der AVR zum Laufzeitpunkt nicht versucht, diese Zeichen als Befehl auszuführen.&lt;br /&gt;
&lt;br /&gt;
===Daten im EEPROM (ERAM)===&lt;br /&gt;
genauso geht es, wenn man für den EEPROM feste Werte vorgeben will:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.ESEG           ; Das ist ein EEPROM-Segment&lt;br /&gt;
OneByte: 	.db   1             ; ein byte mit dem inhalt 0x01   &lt;br /&gt;
MeinName:       .db   &amp;quot;Sepp Meier&amp;quot;  ; mehrere Bytes mit Text&lt;br /&gt;
OneWord: 	.dw   1,2           ; zwei WORDs (16 Bit) mit dem inhalt 0x0001 u.  0x0002&lt;br /&gt;
....     &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Verzweigungen==&lt;br /&gt;
Es gibt zwei Arten, bedingte Programm-Sprünge zu formulieren:&lt;br /&gt;
* Durch irgendwelche Befehle, meistens durch Vergleichsoperationen, erst die Bits im Statusregister (SREG) zu setzen, und diese Status-Bits abzufragen und je nachdem einen Programmsprung durchzuführen oder nicht. &lt;br /&gt;
* Man kann aber auch abhängig von Datenbits in GPRs und SFRs den Folgebefehl überspringen (Skippen) lassen. Dieser Folgebefehl kann, muß aber nicht, ein Sprung- oder Callbefehl sein. &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
==Zusammenfassung==&lt;br /&gt;
Da dieser Artikel kein Assembler Tutorial sein kann und soll, soll hier auf die &amp;quot;eigentlichen&amp;quot; Instruktionen nicht eingegangen werden. Ich wollte nur versuchen, die &amp;quot;Denkweise&amp;quot; des Assembler und der AVR-Micros ein wenig näherzubringen und einige ermuntern, doch die ersten Operationen direkt am offenen Herzen des Kontrollers zu wagen. &lt;br /&gt;
&lt;br /&gt;
In manchen Fällen habe ich aber sicher einige Leser endgültig verschreckt.  &lt;br /&gt;
&lt;br /&gt;
==Noch ein Tip==&lt;br /&gt;
Gut abgeschrieben ist am Anfang besser als schlecht ausgedacht. Gerade die verschiedenen Geräte-Initialisierungen (SFR) in den zahlreichen GCC Codeschnipsel können fast direkt abgeschrieben werden (Baudrate, Input/Output, etc), da der C-Compiler das ja auch nicht anders machen kann. &lt;br /&gt;
&lt;br /&gt;
==Autor==&lt;br /&gt;
[[User:PicNick|PicNick]]&lt;br /&gt;
&lt;br /&gt;
==Weblinks==&lt;br /&gt;
[http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=11488 Ausführlicher Foren-Beitrag zum Thema Assembler-Programmierung] &amp;amp;ndash; Lang aber lehrreich&lt;br /&gt;
==Siehe auch==&lt;br /&gt;
*[[AVR]]&lt;br /&gt;
*[[Sourcevergleich]]&lt;br /&gt;
*[[GNU Assembler]]&lt;br /&gt;
*[[Assembler_Einf%C3%BChrung_f%C3%BCr_Bascom-User|Assembler Einführung für Bascom-User]]&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Robotikeinstieg]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Quellcode Assembler AVR]]&lt;/div&gt;</summary>
		<author><name>Freak</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Diskussion:Pulsweitenmodulation&amp;diff=10478</id>
		<title>Diskussion:Pulsweitenmodulation</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Diskussion:Pulsweitenmodulation&amp;diff=10478"/>
				<updated>2007-03-24T17:05:52Z</updated>
		
		<summary type="html">&lt;p&gt;Freak: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Folgendes Fragment hab ich vom Artikel hierhin verschoben, weil die Aussage so nicht zutreffend ist.&lt;br /&gt;
:''&amp;quot;Damit sich dieser Mittelwert einstellen kann, muss eine entsprechende Glättung des Signals vorliegen. Beim Motor ist das die Wicklung des Ankers, bei Schaltnetzteilen sind das die Kondensatoren am Ausgang.&amp;quot;''&lt;br /&gt;
Was genau damit gemeint sein soll ist unklar. Der Mittelwert der Spannung stellt sich immer ein, unabhängig davon, ob geglättet wird oder nicht. Im Artikel ist zudem nur angedeutet, auf was geregelt wird (Leistung/Strom via Spannung) und dem, was gestellt wird (das Tastverhältnis der PWM).&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:SprinterSB|SprinterSB]] 16:40, 26. Jan 2006 (CET)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Du hast recht. Kann gelöscht werden.&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:Ogni42|Ogni42]] 20:09, 26. Jan 2006 (CET)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nicht gleich löschen, wir sind keine Perfektionisten. Kann ja einfach jemand entsprechend bearbeiten falls er eine bessere Darstellung hin bringt.&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:Frank|Frank]] 01:22, 27. Jan 2006 (CET)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Schwierig wird es, wenn man nicht weiß, was überhaupt gemeint sein sollte oder das Gesagte so versimpelt, daß es falsch wird...&lt;br /&gt;
&lt;br /&gt;
Bei einem Motor mit PWM-Ansteuerung ist einem die Effektivspannung je relativ egal, was eher interressiert ist der effektive Strom. Der wiederum ist nicht nur abhängig vom der Spannung. Ohne Freilaufdiode etwa bringt PWM nicht das gewünschte Resultat, wie träge ein Motor auch sein mag.&lt;br /&gt;
&lt;br /&gt;
Ein Schaltnetzteil, bei dem die Spannung anderes Vorzeichen haben kann als die Eingangsspannung, oder dessen Ausgangsspannung betragsmässig grösser sein kann, ist mit einer PWM-Erklärung so nicht zu verstehen. Im Resultat ist die Ansteuerung meist eine PPM (keine PWM), und wenn man die Effektiv-Eingangsspannung als Gleichspannung anlegte, würde nix passieren, ausser evtl was durchzukokeln.&lt;br /&gt;
&lt;br /&gt;
Und LEDs über PWM anzusteuern bringt nicht weniger Verluste (bei gleichem Effektivstrom, also gleicher Helligkeit). Wer's nicht glaubt, rechne nach: Die Verlustleistung ist ''unabhängig'' vom Tastverhältnis.  &lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:SprinterSB|SprinterSB]] 09:36, 30. Jan 2006 (CET)&lt;br /&gt;
&lt;br /&gt;
Fehler im Bild!!!&lt;br /&gt;
&lt;br /&gt;
Der Text betreffend des ersten Bildes stimmt; nur passt das Bild nicht ganz dazu.&lt;br /&gt;
Die Grundfrequenz der Schwingungen bleibt gleich (mit Pfeilen dargestellt &amp;lt;== Fehler?? Die Grundfrequenz bezieht sich auf den Anfang jedes Impulses(oder auch das Ende; aber immer auf den selben Punkt jedes Impulses); beim ersten Impuls geht der Pfeil aber von Anfang des 1. bis zum Ende des 2.Impulses (die andren 2 Darstellungen sind richitg))&lt;br /&gt;
Soll ich das ausbessern, oder macht das der Verfasser dieses Artikels?&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:Freak|Freak]] 18:05, 24. Mär 2007 (CET)&lt;/div&gt;</summary>
		<author><name>Freak</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Diskussion:Pulsweitenmodulation&amp;diff=10477</id>
		<title>Diskussion:Pulsweitenmodulation</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Diskussion:Pulsweitenmodulation&amp;diff=10477"/>
				<updated>2007-03-24T17:05:06Z</updated>
		
		<summary type="html">&lt;p&gt;Freak: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Folgendes Fragment hab ich vom Artikel hierhin verschoben, weil die Aussage so nicht zutreffend ist.&lt;br /&gt;
:''&amp;quot;Damit sich dieser Mittelwert einstellen kann, muss eine entsprechende Glättung des Signals vorliegen. Beim Motor ist das die Wicklung des Ankers, bei Schaltnetzteilen sind das die Kondensatoren am Ausgang.&amp;quot;''&lt;br /&gt;
Was genau damit gemeint sein soll ist unklar. Der Mittelwert der Spannung stellt sich immer ein, unabhängig davon, ob geglättet wird oder nicht. Im Artikel ist zudem nur angedeutet, auf was geregelt wird (Leistung/Strom via Spannung) und dem, was gestellt wird (das Tastverhältnis der PWM).&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:SprinterSB|SprinterSB]] 16:40, 26. Jan 2006 (CET)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Du hast recht. Kann gelöscht werden.&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:Ogni42|Ogni42]] 20:09, 26. Jan 2006 (CET)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nicht gleich löschen, wir sind keine Perfektionisten. Kann ja einfach jemand entsprechend bearbeiten falls er eine bessere Darstellung hin bringt.&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:Frank|Frank]] 01:22, 27. Jan 2006 (CET)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Schwierig wird es, wenn man nicht weiß, was überhaupt gemeint sein sollte oder das Gesagte so versimpelt, daß es falsch wird...&lt;br /&gt;
&lt;br /&gt;
Bei einem Motor mit PWM-Ansteuerung ist einem die Effektivspannung je relativ egal, was eher interressiert ist der effektive Strom. Der wiederum ist nicht nur abhängig vom der Spannung. Ohne Freilaufdiode etwa bringt PWM nicht das gewünschte Resultat, wie träge ein Motor auch sein mag.&lt;br /&gt;
&lt;br /&gt;
Ein Schaltnetzteil, bei dem die Spannung anderes Vorzeichen haben kann als die Eingangsspannung, oder dessen Ausgangsspannung betragsmässig grösser sein kann, ist mit einer PWM-Erklärung so nicht zu verstehen. Im Resultat ist die Ansteuerung meist eine PPM (keine PWM), und wenn man die Effektiv-Eingangsspannung als Gleichspannung anlegte, würde nix passieren, ausser evtl was durchzukokeln.&lt;br /&gt;
&lt;br /&gt;
Und LEDs über PWM anzusteuern bringt nicht weniger Verluste (bei gleichem Effektivstrom, also gleicher Helligkeit). Wer's nicht glaubt, rechne nach: Die Verlustleistung ist ''unabhängig'' vom Tastverhältnis.  &lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:SprinterSB|SprinterSB]] 09:36, 30. Jan 2006 (CET)&lt;br /&gt;
&lt;br /&gt;
Fehler im Bild!!!&lt;br /&gt;
&lt;br /&gt;
Der Text betreffend des ersten Bildes stimmt; nur passt das Bild nicht ganz dazu.&lt;br /&gt;
Die Grundfrequenz der Schwingungen bleibt gleich (mit Pfeilen dargestellt &amp;lt;== Fehler?? Die Grundfrequenz bezieht sich auf den Anfang jedes Impulses(oder auch das Ende; aber immer auf den selben Punkt jedes Impulses); beim ersten Impuls geht der Pfeil aber von Anfang des 1. bis zum Ende des 2.Impulses (die andren 2 Darstellungen sind richitg))&lt;br /&gt;
Soll ich das ausbessern, oder macht das der Verfasser dieses Artikels?&lt;/div&gt;</summary>
		<author><name>Freak</name></author>	</entry>

	</feed>