<?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=213.61.222.21</id>
	<title>Mikrocontroller.net - Benutzerbeiträge [de]</title>
	<link rel="self" type="application/atom+xml" href="https://www.mikrocontroller.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=213.61.222.21"/>
	<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/articles/Spezial:Beitr%C3%A4ge/213.61.222.21"/>
	<updated>2026-04-10T21:47:33Z</updated>
	<subtitle>Benutzerbeiträge</subtitle>
	<generator>MediaWiki 1.39.7</generator>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=8051_Timer_0/1&amp;diff=82762</id>
		<title>8051 Timer 0/1</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=8051_Timer_0/1&amp;diff=82762"/>
		<updated>2014-04-23T09:36:46Z</updated>

		<summary type="html">&lt;p&gt;213.61.222.21: Geiz ist Geil entfernt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Timer 0/1 bei 8051-Controllern==&lt;br /&gt;
===Einleitung===&lt;br /&gt;
Die Timer 0 und 1 sind bei jedem 8051-Kompatiblen vorhanden, bei allen gleich, und sie unterscheiden sich nur gering (Mode 3). Der Timer 2 ist erst ab 8052 enthalten und kann abweichende Register und Funktionen haben.&lt;br /&gt;
Die Timer 0/1 sind Aufwärtszähler. Bei Zählerüberlauf wird ein Flag gesetzt (TF0 bzw. TF1), das aber nicht unbedigt ausgewertet werden muss (z.B Baudratengenerator). Die Timer laufen nach Überlauf einfach weiter.&lt;br /&gt;
Der Zählerstand kann jederzeit gelesen und auch geändert werden. Beim 16-Bit Mode muss der Zählerstand aus 2 Bytes TH0:TL0 gebildet werden. Im 8-Bit Mode erfolgt ein automatischer Reload aus dem TH-Register in das TL-Register.&lt;br /&gt;
Die Quelle der Timer ist umschaltbar zwischen Oszillator/12 (Maschinentakte) und externem Eingang. Dies geschieht mit dem Bit C/T im TMOD-Register. C/T auf 0 bedeutet Timer-Betrieb (bekannte Frequenz wird gezählt -&amp;gt; Zeit), C/T auf 1 bedeutet Counter-Betrieb (externe Ereignisse werden gezählt -&amp;gt; z.B. Abfüllen von Werkstücken, Besucherzähler etc.)&lt;br /&gt;
Die Timer müssen gestartet werden. Dazu muss das TR0 (bzw. TR1) Bit gesetzt werden. Sie können jederzeit angehalten und wieder gestartet werden. Der Zählerstand bleibt gespeichert. Mit gesetztem Gate-Bit läuft der Timer nur dann, wenn zusätzlich der Gate-Eingang auf 1 liegt. Damit können z.B: Impulslägen gemessen werden. Praktischerweise ist dieser Eingang auch gleichzeitig ein Interrupt-Eingang, so dass man die fallende Flanke (Puls zu Ende, Timer steht, Ergebnis kann gelesen werden) per Interrupt auswerten kann.&lt;br /&gt;
===Betriebsarten===&lt;br /&gt;
Das Einstellen der Betriebsart erfolgt in einem Register (TMOD) für beide Timer! Die unteren 4 Bit gelten für Timer 0, die oberen für Timer 1. Die Bedeutung ist für beide gleich (ausser Mode 3).&amp;lt;br&amp;gt;&lt;br /&gt;
Das TMOD-Register ist nicht Bitadressierbar und sollte daher mit UND/ODER-Maskierung verändert werden. &#039;Harte&#039; Schreibzugriffe konfigurieren beide Timer gleichzeitig.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;TMOD-Register&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
! Bit7 || Bit6 || Bit5 || Bit4 || Bit3 || Bit2 || Bit1 || Bit0&lt;br /&gt;
|-&lt;br /&gt;
|  G   || C/T  ||  M1  ||  M0  ||  G   || C/T  ||  M1  ||  M0  &lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Timer Betriebsarten&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
! M1 || M0 || Betriebsart&lt;br /&gt;
|-&lt;br /&gt;
|  0 ||  0 || Mode 0: 13-Bit Timer/Counter (!!)&lt;br /&gt;
|-&lt;br /&gt;
|  0 ||  1 || Mode 1: 16-Bit Timer/Counter&lt;br /&gt;
|-&lt;br /&gt;
|  1 ||  0 || Mode 2: 8-Bit Timer/Counter mit Auto-Reload&lt;br /&gt;
|-&lt;br /&gt;
|  1 ||  1 || Mode 3: 2x 8-Bit Timer/Counter (nur Timer0, wenn Timer1 Baudrate erzeugt)&lt;br /&gt;
|}&lt;br /&gt;
Erklärung:&amp;lt;br&amp;gt;&lt;br /&gt;
Mode 0 existiert noch aus Kompatibilität zum 8048 und gehört daher ins Museum. Trotzdem schaltet man den Mode leicht unbeabsichtigt ein, wenn man TMOD falsch konfiguriert.&amp;lt;br&amp;gt;&lt;br /&gt;
Mode 1 konfiguriert einen 16-Bit Timer/Counter, der Zählerstand ist auf 2 Register aufgeteilt.&amp;lt;br&amp;gt;&lt;br /&gt;
Mode 2 konfiguriert einen 8-Bit Timer/Counter mit Auto-Reload, gezählt wird im Register TL0 bzw. TL1, der Reload erfolgt bei Überlauf aus TH0 bzw. TH1. &amp;lt;br&amp;gt;&lt;br /&gt;
Mode 3: hier wird der Timer 0 in 2 8-Bit Timer/Counter aufgeteilt. Überläufe von TL0 sezten TF0, Überläufe von TH0 setzen TF1 (nur für Timer 0, Timer 1 macht dann z.B. Baudrate. Nur bei CPUs ohne Timer 2 oder Baudratengenerator interessant -&amp;gt; Museum!!)&amp;lt;br&amp;gt;&lt;br /&gt;
Es bleiben also effektiv nur die beiden Betriebsarten 1 und 2 übrig.&lt;br /&gt;
==== Timer oder Counter ====&lt;br /&gt;
Mit den Bits C/T wird zwischen Timer-Betrieb und Counter-Betrieb umgeschaltet. Als Timer (C/T = 0) zählt die Baugruppe Maschinenzyklen, daher entspricht der Zählerstand einer Zeit. Als Counter (C/T = 1) wird ein Signal von einem externen Zähleingang (P3.4 für Timer 0 und P3.5 für Timer 1) gezählt. &lt;br /&gt;
==== Gate-Betrieb ====&lt;br /&gt;
Wenn das Bit 0 ist, läuft der entsprechende Timer, wenn das zugehörige Timer-Run-Flag gesetzt ist (TR0 bzw. TR1). Wenn das Bit 1 ist muss &#039;&#039;&#039;zusätzlich&#039;&#039;&#039; noch der Gate-Eingang auf 1 sein. Dies ist P3.2 für Timer 0 bzw. P3.3 für Timer 1. Damit kann man einfach Pulsdauern ausmessen oder auch Betriebsstunden (mit Hilfszählern für die Überläufe).&lt;br /&gt;
==== Timer-Kontroll-Register ====&lt;br /&gt;
Die Überlauf-Flags und die Run-Bits der beiden Timer befinden sich im Register TCON. Dort sind zusätzlich noch je 2 Bits für die Konfiguration der beiden externen Interrupts untergebracht (der reinste Gemischtwarenladen...)&amp;lt;br&amp;gt;&lt;br /&gt;
Dies ist nicht tragisch, weil das Register Bitadressierbar ist. Um einen Timer zu starten schreibt man also einfach:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;TR0 = 1;   // Timer 0 starten&lt;br /&gt;
TR1 = 1;   // Timer 1 starten&lt;br /&gt;
bzw. in Assembler&lt;br /&gt;
setb TR0   ; Timer 0 starten&lt;br /&gt;
setb TR1   ; Timer 1 starten&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Beim Überlauf (im 8-Bit Mode nach 2^8 = 256 Maschinenzyklen, im 16-Bit Mode nach 2^16 = 65536 Maschinenzyklen) wird das Überlauf-Flag TF0 bzw. TF1 gesetzt. Damit erkennt man, dass der Timer überglaufen ist. Bei der Bearbeitung muss man das Flag zur Bestätigung löschen, im Interrupt-Betrieb werden die Flags automatisch gelöscht.&lt;br /&gt;
&lt;br /&gt;
===Schnelleinstieg für ungeduldige===&lt;br /&gt;
Von den Timern beim 8051 nimmst Du am Anfang nur Timer0/1 im 16-Bit Mode.&lt;br /&gt;
=&amp;gt; TMOD = 0x11; setzt beide Timer in den Mode 1. Nur wenn du serielle &lt;br /&gt;
Schnittstelle verwendest, brauchst Du evtl. den Timer 1 für die &lt;br /&gt;
Baudrate.&lt;br /&gt;
Wenn Du keinen Startwert und keinen Reload-Wert setzt, dann läuft der &lt;br /&gt;
Timer 65536 Maschinenzyklen (also bei 12MHz ohne X2-Mode 65,5ms). Bei &lt;br /&gt;
jedem Timerüberlauf musst Du das Timer-Flag wieder löschen (entfällt im &lt;br /&gt;
Interrupt-Betrieb, aber zunächst erstmal ohne) und dann kann man etwas tun.&amp;lt;br&amp;gt;&lt;br /&gt;
====Grundgerüst====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void main (void)&lt;br /&gt;
// Initialisierung&lt;br /&gt;
TMOD = 0x11;       // setzt beide Timer in den 16-Bit Mode&lt;br /&gt;
                   // für andere Modi musst du doch noch oben lesen&lt;br /&gt;
TR0 = 1;           // Timer 0 läuft jetzt, mit jedem Maschinenzyklus&lt;br /&gt;
                   // wird jetzt TH0:TL0 um 1 hochgezählt&lt;br /&gt;
&lt;br /&gt;
while(1)&lt;br /&gt;
{&lt;br /&gt;
// in der Endlosschleife&lt;br /&gt;
   if (TF0 == 1)   // Flag wird beim Überlauf auf 1 gesetzt&lt;br /&gt;
   {   TF0 = 0;    // Flag erstmal löschen, der Timer zählt bereits munter weiter&lt;br /&gt;
       Tu_Was( );  // für was wolltest Du die Zeit nochmal nutzen??&lt;br /&gt;
   }&lt;br /&gt;
   Weitere_Aktionen( );&lt;br /&gt;
}&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Für den Timer 1 änderst/ergänzt Du TR0 -&amp;gt; TR1, TF0 -&amp;gt; TF1.&amp;lt;br&amp;gt;&lt;br /&gt;
Was soll jetzt mit dem Timer gesteuert werden? Lassen wir zunächst mal die LED an P2.0 blinken. Statt Tu_Was(); kommt jetzt also P2_0 = ~P2_0; hin. Wie groß ist jetzt die Blinkfrequenz? Der Timer läuft im 16-Bit Mode. Also ist die Zeit zwischen 2 Überlaufen 2^16 Maschinenzyklen. Der dauert bei den meisten 8051-Controllern 12 Oszillatortakte. Mit einem 12MHz Oszillator kommt man also auf genau 1µs pro Maschinenzyklus und damit auf 65536µs zwischen 2 Überläufen.&amp;lt;br&amp;gt;&lt;br /&gt;
Doch zurück zur LED. Die ist jetzt also für 65,5ms an und danach für 65,5ms aus. Die Periodendauer beträgt hier also die &#039;&#039;&#039;doppelte&#039;&#039;&#039; Timerzeit, die Frequenz ergibt sich also zu&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;f = \frac 1 T = \frac 1 {2 \cdot Timerzeit}&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Hier also ein symmetrisches Rechtecksignal mit einer Periodendauer von 131,072ms und einer Frequenz von 7,63Hz.&lt;br /&gt;
&lt;br /&gt;
====Variable Timerzeit====&lt;br /&gt;
Auf Dauer ist das Geblinke aber langweilig... Also müssen die Zeiten verändert werden.&amp;lt;br&amp;gt;Länger geht beim 8051 nur mit einem Hilfszähler (der ATMega und andere Controller haben hier ja einen Vorteiler). Für kürzere Zeiten kann nur der &#039;&#039;&#039;Startwert&#039;&#039;&#039; verändert werden, weil der Überlauf immer nach dem Zählerstand 65535=0xFFFF stattfindet. Wenn man also bei 15536 beginnt zu zählen sind es nur noch 50000 Maschinenzyklen bis zum Überlauf. Dieser Startwert muss nun auf 2 8-Bit Zählregister THx und TLx aufgeteilt werden. Dafür gibt es verschiedene Möglichkeiten von der Berechnung im Kopf, Taschenrechner, Tabellenkalkulation etc...&amp;lt;br&amp;gt;&lt;br /&gt;
Der (meiner Meinung nach) eleganteste Weg ist aber, den Compiler die Berechnung erledigen zu lassen (wozu hat man denn einen PC). Es muss also die Differenz zwischen Maximalwert 65536 und gewünschter Dauer (hier 50000) gebildet und aufgeteilt werden. Dazu schreibt man einfach:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;// Beispiel für Timer 0, für Timer 1 TH1 und TL1 einsetzen&lt;br /&gt;
TH0 = (65536 - 50000)/256;  // gibt das High-Byte von 15536 =&amp;gt; 0x3C&lt;br /&gt;
TL0 = (65536 - 50000)%256;  // gibt das Low-Byte von 15536 =&amp;gt; 0xB0&lt;br /&gt;
oder in Assembler:&lt;br /&gt;
mov TH0, #HIGH(65536-50000) ; ausprobieren, ob der eigene Assembler&lt;br /&gt;
mov TL0, #LOW(65536-50000)  ; dies unterstützt!&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Durch diese Schreibweise sieht man sofort die erzeugte Timerzeit und die Umrechnung erfolgt durch den Compiler (es wird also auf dem Controller keine Berechnung mehr durchgeführt). Etwas anders ist es, wenn keine Konstanten sondern Variablen dastehen. Dann sollte man etwas anders schreiben:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;unsigned short Timerzeit, Reloadwert;&lt;br /&gt;
Timerzeit = irgendeine_Berechnung( );&lt;br /&gt;
Reloadwert = 65536 - Timerzeit;&lt;br /&gt;
TH0 = Reloadwert / 256;&lt;br /&gt;
TL0 = Reloadwert % 256;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Auf den ersten Blick etwas umständlich, aber so erkennt der Compiler, dass nur eine Aufteilung in Low- und High-Byte gewünscht ist und weist einfach die Register zu statt Division und Modulo zu berechnen. Bei der Programmierung in Assembler muss man hier 16-Bit Arithmetik berechnen, für Anfänger hört hier der Spass auf (=&amp;gt; erstmal bei konstanten Zeiten bleiben).&lt;br /&gt;
&lt;br /&gt;
====Längere Wartezeiten erzeugen====&lt;br /&gt;
&#039;&#039;(zum größten Teil aus meinen Beiträgen hier übernommen: http://www.mikrocontroller.net/topic/264647#2752818 )&#039;&#039; &amp;lt;br&amp;gt;&lt;br /&gt;
Dazu zählst du eine Variable hoch. Nimm mal &amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;unsigned int Ticks;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Bei jedem Überlauf wird Ticks erhöht und wenn die benötigte Anzahl &lt;br /&gt;
(=Zeit in s / 65,5ms) erreicht ist, machst Du was und setzt Ticks wieder &lt;br /&gt;
auf 0.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void main (void)&lt;br /&gt;
{&lt;br /&gt;
  // Timer-Initialisierung&lt;br /&gt;
  TMOD = 0x11;&lt;br /&gt;
  //TH0 = (65536 - Benoetigte_Zeit)/256;  // für Startwert oder Reload &lt;br /&gt;
  //TL0 = (65536 - Benoetigte_Zeit)%256;  // für Startwert oder Reload &lt;br /&gt;
  TR0 = 1;    // Timer 0 starten  - TR1 für Timer 1&lt;br /&gt;
&lt;br /&gt;
  while(1)  // Endlosschleife&lt;br /&gt;
  {&lt;br /&gt;
     if (TF0 == 1) // Timer 0 ist überglaufen&lt;br /&gt;
     {  Ticks++;   // sonst braucht man erstmal nix.&lt;br /&gt;
        TF0 = 0;   // Flag löschen&lt;br /&gt;
     }&lt;br /&gt;
     if (Ticks == 0)&lt;br /&gt;
     {  Schalte_Ein( ); //einschalten -&amp;gt; wird mehrfach ausgeführt &lt;br /&gt;
                        // oder du fügst ein Merker-Flag ein&lt;br /&gt;
     }&lt;br /&gt;
     if (Ticks == Ausschaltzeit)&lt;br /&gt;
     {  Schalte_Aus( ); // ausschalten -&amp;gt; wird nur einmal ausgeführt &lt;br /&gt;
        Ticks = 0;      // wenn Ticks gelöscht wird&lt;br /&gt;
     }&lt;br /&gt;
  }&lt;br /&gt;
} &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit kannst Du zunächst einen Vorgang realisieren. Wenn Du die Ticks &lt;br /&gt;
einfach weiterlaufen lässt, dann kann man auch sowas machen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
if (Taster1 == 1) &lt;br /&gt;
{  Ausschaltzeit1 = Ticks + Dauer1; //zur aktuellen Zeit die Dauer addieren&lt;br /&gt;
   Einschalten(1);&lt;br /&gt;
}&lt;br /&gt;
if (Ticks == Ausschaltzeit1)&lt;br /&gt;
{  Ausschalten(1);&lt;br /&gt;
}&lt;br /&gt;
if (Taster2 == 1) &lt;br /&gt;
{  Ausschaltzeit2 = Ticks + Dauer2; //zur aktuellen Zeit die Dauer addieren&lt;br /&gt;
   Einschalten(2);&lt;br /&gt;
}&lt;br /&gt;
if (Ticks == Ausschaltzeit2)&lt;br /&gt;
{  Ausschalten(2);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Das funktioniert mit (fast) beliebig vielen Signalen und es ist auch kein Problem, wenn es einen Überlauf gibt. Wenn Ticks z.B. auf 65000 steht und du willst eine Dauer von 60 Sekunden (= 60000ms/65,536ms = 915 Ticks), dann ergibt die Addition für die Ausschaltzeit 379 (gleicher Datentyp für alle Schaltzeiten!).&lt;br /&gt;
&lt;br /&gt;
====kurze Zeiten erzeugen====&lt;br /&gt;
Die Timer zählen nach dem Überlauf sofort ab 0x0000 weiter. Also muss man wieder einen Startwert (Reload) laden, so dass der Timer nach einer kürzeren Zeit überläuft. Die Formeln im Quelltext kann man problemlos mit Konstanten füllen, die Division und Modulo wird dabei nicht wirklich berechnet, sondern der Compiler fügt die Ergebniswerte in den Code ein. (anders sieht es für variable Zeiten aus, dazu später mehr) Für einen Grundtakt von 1ms schreibt man also einfach nach jedem Überlauf wieder in die Zählregister:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;TH0 = (65536 - 1000)/256;  // 1ms = 1000MZ, davon das High-Byte in TH0&lt;br /&gt;
TL0 = (65536 - 1000)%256;  // das Low-Byte in TL0&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
Da der 8051 bei den Timern 0 und 1 keine getrennten Zähl- und Reload-Register hat, muss man diesen Wert nach jedem Überlauf möglichst schnell wieder in die Register schreiben (daher nimmt man da dann meist Interrupts).&amp;lt;br&amp;gt;&lt;br /&gt;
Programmausschnitt:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;while(1)  // Endlosschleife&lt;br /&gt;
{&lt;br /&gt;
     if (TF0 == 1) // Timer 0 ist überglaufen&lt;br /&gt;
     {  TH0 = (65536 - 1000)/256;  // 1ms = 1000MZ, Hih-Byte&lt;br /&gt;
        TL0 = (65536 - 1000)%256;  // Low-Byte in TL0&lt;br /&gt;
        TF0 = 0;   // Flag löschen&lt;br /&gt;
        Ticks++;   // sonst braucht man erstmal nix.&lt;br /&gt;
     }&lt;br /&gt;
     // Rest des Programms&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
Bei einer Millisekunde läuft die Variable Ticks bereits nach 65536ms, also etwa einer Minute über. Wenn man längere Zeiten benötigt, dann entweder die Ticks alle 10, 20 oder 50ms einstellen oder (in C ja kein echtes Problem) unsigned long Ticks; verwenden. Damit kannst Du in ms-Auflösung Zeiten bis 1193 Stunden erzeugen, bevor der Zähler überläuft... Braucht aber natürlich mehr Speicher (auch für die Schaltzeiten!). Ohne Interrupts kann es aber passieren, dass die Bearbeitung des restlichen Programms länger als die Timer-Zeit dauert. Dann werden die Zeiten sehr ungenau. Also erstmal nicht wundern...&lt;br /&gt;
&lt;br /&gt;
====Reload mit variablen Zeiten====&lt;br /&gt;
Für variable Zeiten (z.B. PWM für Modellbau-Servo mit 1-2ms Impuls und 20ms Periodendauer) darf man die (16Bit) Variablen nicht einfach in die obige Zeile einsetzen. Dabei wird sonst die Division und die Modulo-Operation wirklich ausgeführt (die sich ergebenden Zeiten sind dann für die Tonne...). Hier muss man (am besten eine Phase vorher, wenn der Timer gerade übergelaufen war) die Variable berechnen.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;while(1)  // Endlosschleife&lt;br /&gt;
{&lt;br /&gt;
     if (TF0 == 1) // Timer 0 ist überglaufen&lt;br /&gt;
     {  TH0 = (65536 - Pulszeit)/256;  // Hih-Byte&lt;br /&gt;
        TL0 = (65536 - Pulszeit)%256;  // Low-Byte in TL0&lt;br /&gt;
        TF0 = 0;   // Flag löschen&lt;br /&gt;
        Ticks++;   // sonst braucht man erstmal nix.&lt;br /&gt;
        Pulszeit = 1000 + 4 * Dip_Schalter; // ergibt 1-2ms&lt;br /&gt;
     }&lt;br /&gt;
     // Rest des Programms&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===Timer-Interrupt ohne Schrecken===&lt;br /&gt;
Mit Interrupt vermeidet man die Ungenauigkeiten beim Timer-Reload. Sobald der Timer bei aktiviertem Interrupt überläuft, springt der Prozessor in die Interrupt-Service-Routine und führt den dortigen Code aus. Danach geht es an der alten Stelle im Hauptprogramm weiter. (der sollte daher möglichst kurz sein)&lt;br /&gt;
Interrupts aktiviert man erstmal einzeln für jede Quelle, danach noch den Hauptschalter EA.&amp;lt;br&amp;gt;&lt;br /&gt;
Zum Thema [[Interrupts]] gibt es ein extra Kapitel.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;TMOD = 0x11;&lt;br /&gt;
TH0 = (65536 - 1000)/256;  // für Startwert &lt;br /&gt;
TL0 = (65536 - 1000)%256;  // für Startwert &lt;br /&gt;
TR0 = 1;    // Timer 0 starten  - TR1 für Timer 1&lt;br /&gt;
ET0 = 1;    // Interrupt für Timer 0 aktivieren&lt;br /&gt;
EA  = 1;    // Globalen Interrupt aktivieren -- ab jetzt geht&#039;s rund&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Interrupt-Service-Routine ersetzt die if(TF0)-Abfrage aus dem Hauptprogramm. Das ist kein Hexenwerk, es kommt nur ein Schlüsselwort hinter den Funktionsnamen und eine Nummer, die die Quelle angibt. (gilt für den Compiler RC51 aus RIDE)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;void ISR_Timer0 (void) interrupt 1&lt;br /&gt;
{&lt;br /&gt;
   TH0 = (65536 - 1000)/256;  // Reload&lt;br /&gt;
   TL0 = (65536 - 1000)%256;  // Reload&lt;br /&gt;
   // TF0 = 0;   // Flag löschen geht jetzt automatisch! Der reine Luxus!&lt;br /&gt;
   Ticks++;   // sonst braucht man erstmal nix.&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
Ticks muss jetzt als globale Variable deklariert werden, damit sowohl &lt;br /&gt;
die ISR als auch main() darauf zugreifen können. Erbsenzähler rechnen natürlich noch aus, wieviele µs es bis zum Relaod dauert und korrigieren damit den Reload-Wert:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;// wenn es z.B. 6us bis zum Sprung in die ISR dauert:&lt;br /&gt;
   TH0 = (65536 - 1000 + 6)/256;  // korrigiert um 6us&lt;br /&gt;
   TL0 = (65536 - 1000 + 6)%256;  // korrigiert&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
Es ist aber nicht immer möglich, exakt auf 1µs genau zu arbeiten (ein &lt;br /&gt;
laufender ASM-Befehl kann nicht unterbrochen werden und dauert 1, 2 oder &lt;br /&gt;
4 MZ). Aber zuviel überlegungen nutzen eh nichts, weil der Quarztakt ja &lt;br /&gt;
auch nicht exakt ist. (eine Uhr mit Timer-Interrupt läuft aber trotzdem &lt;br /&gt;
mit einer Abweichung von wenigen Sekunden/Woche)&amp;lt;br&amp;gt;&lt;br /&gt;
=== Timer im 8-Bit Modus===&lt;br /&gt;
ToDo.&lt;br /&gt;
=== Counter-Betrieb===&lt;br /&gt;
ToDo.&lt;br /&gt;
===Kritische Betrachtung, Fallstricke===&lt;br /&gt;
Jetzt werden viele &amp;quot;Aber...&amp;quot; rufen. Wenn man genau hinschaut, gibt es natürlich den Fall, dass das Low-Byte übergelaufen ist, bis man das High-Byte geschrieben hat. Ebenso können die Timer-Zeiten daneben liegen, wenn in der Hauptschleife andere zeitaufwändige Aktionen drinstehen. Daher kann man in kritischen Fällen den Timer von dem Reload stoppen und anschliessend wieder starten. In dieser einfachen Einführung habe ich auf solche Details aber für die Übersicht verzichtet...&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Nachricht an den Autor&#039;&#039;&#039; &lt;br /&gt;
[http://www.mikrocontroller.net/user/show/b_spitzer B. Spitzer]&lt;br /&gt;
[[Kategorie:8051]]&lt;/div&gt;</summary>
		<author><name>213.61.222.21</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=AVR-Simulation&amp;diff=68887</id>
		<title>AVR-Simulation</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=AVR-Simulation&amp;diff=68887"/>
		<updated>2012-10-29T07:16:24Z</updated>

		<summary type="html">&lt;p&gt;213.61.222.21: /* Starten von SimulAVR */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:AVR]]&lt;br /&gt;
== SimulAVR ==&lt;br /&gt;
&lt;br /&gt;
[http://www.nongnu.org/simulavr/ SimulAVR] ist ein Simulator, der einige Prozessoren der AVR-Familie auf einem PC-Hostsystem simulieren kann. Dieser Simulator ist im [[WinAVR]]-Paket enthalten (/WinAVR/bin/simulavr.exe).&lt;br /&gt;
&lt;br /&gt;
SimulAVR wird über ein dazu passendes Frontend bedient. GDB und Insight sind zwei, ebenfalls in WinAVR enthaltene, Programme, die ein solches Frontend bilden. &lt;br /&gt;
&lt;br /&gt;
Wer &amp;quot;textorientiertes&amp;quot; Debugging mag, oder beispielsweise &#039;&#039;emacs&#039;&#039; als Frontend verwenden möchte, der nutzt den [[GDB]], den GNU Debugger. Er ist im WinAVR-Paket enthalten (/WinAVR/bin/avr-gdb.exe). Wer gleich eine grafische Benutzeroberfläche (GUI) verwenden möchte, nutzt Insight (welches intern ebenfalls den GDB verwendet). &lt;br /&gt;
&lt;br /&gt;
Beide Debugger, also GDB oder Insight, benötigen ein Backend. Entweder handelt es sich dabei um einen ICE/[[JTAG]]-Debugger wie z.&amp;amp;nbsp;B. [http://avarice.sourceforge.net/ AVaRICE] als Interface zu einem realen AVR-Mikrocontroller oder um einen Simulator.&lt;br /&gt;
&lt;br /&gt;
=== Starten von SimulAVR ===&lt;br /&gt;
&lt;br /&gt;
[[Datei:SimulAVR-Display.png|right|220px]]&lt;br /&gt;
Um SimulAVR mit default-Parametern zu starten, reicht es aus, folgende Zeile in einer Shell/Eingabeaufforderung einzugeben:&lt;br /&gt;
&lt;br /&gt;
 $ simulavr -g -d &amp;lt;AVR-Prozessortyp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
SimulAVR startet dann mit den defaultparametern und stellt einen GDBServer-Prozess auf dem lokalen oder entfernten Host auf Port 1212 zur Verfügung.&lt;br /&gt;
Das &#039;&#039;Backend&#039;&#039; der Simulation ist nun Einsatzbereit.&lt;br /&gt;
&lt;br /&gt;
Eine weitere Möglichkeit ist, SimulAVR mit Display zu starten. Dann werden während der Ausführung die Werte der Register und dem RAM angezeigt (siehe Bild).&lt;br /&gt;
&lt;br /&gt;
 $ simulavr -g -P simulavr-disp -d &amp;lt;AVR-Prozessortyp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Übersicht der unterstützten AVR-Prozessoren und der SimulAVR spezifischen Parameter bekommt man durch folgende Zeile:&lt;br /&gt;
&lt;br /&gt;
 $ simulavr --help&lt;br /&gt;
&lt;br /&gt;
=== Starten des GDB ===&lt;br /&gt;
&lt;br /&gt;
Um das (vorläufige) Frontend GDB zu starten, reicht folgende Zeile:&lt;br /&gt;
&lt;br /&gt;
 $ avr-gdb&lt;br /&gt;
&lt;br /&gt;
Der GDB meldet sich mit folgendem Bildschirm:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Current directory is c:/WinAVR/testprj4/&lt;br /&gt;
GNU gdb 6.1&lt;br /&gt;
Copyright 2004 Free Software Foundation, Inc.&lt;br /&gt;
GDB is free software, covered by the GNU General Public License, and you are&lt;br /&gt;
welcome to change it and/or distribute copies of it under certain conditions.&lt;br /&gt;
Type &amp;quot;show copying&amp;quot; to see the conditions.&lt;br /&gt;
There is absolutely no warranty for GDB.  Type &amp;quot;show warranty&amp;quot; for details.&lt;br /&gt;
This GDB was configured as &amp;quot;--host=i686-pc-cygwin --target=avr&amp;quot;.&lt;br /&gt;
(gdb) &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;(gdb)&#039;&#039;&#039; ist der Prompt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Soll während dem Debuggen der Quellcode angezeigt werden, der zur Zeit ausgeführt wird, kann GDB wie folgt gestartet werden.&lt;br /&gt;
&lt;br /&gt;
 $ avr-gdb -tui&lt;br /&gt;
&lt;br /&gt;
Beim (gdb) prompt dann das Layout auf Assembler umschalten.,&lt;br /&gt;
&lt;br /&gt;
 (gdb) layout asm&lt;br /&gt;
&lt;br /&gt;
=== Simulieren/Debuggen ===&lt;br /&gt;
&lt;br /&gt;
Im ersten Schritt muss dem GDB die gewünschte Datei (vorher mittels entsprechendem &#039;&#039;Makefile&#039;&#039; erzeugt) bekannt gemacht werden:&lt;br /&gt;
&lt;br /&gt;
 (gdb) file main.elf &lt;br /&gt;
 Reading symbols from main.elf...done.&lt;br /&gt;
&lt;br /&gt;
Als nächstes muss dem GDB mitgeteilt werden, welches Ziel (target) er als Backend verwenden soll:&lt;br /&gt;
&lt;br /&gt;
 (gdb) target remote localhost:1212&lt;br /&gt;
&lt;br /&gt;
oder kürzer:&lt;br /&gt;
&lt;br /&gt;
 (gdb) targ rem :1212&lt;br /&gt;
 Remote debugging using :1212&lt;br /&gt;
 0x00000000 in __vectors ()&lt;br /&gt;
&lt;br /&gt;
Jetzt muss das Programm in den Simulator geladen werden:&lt;br /&gt;
&lt;br /&gt;
 (gdb) load&lt;br /&gt;
 Loading section .data, size 0x32 lma 0x1bc&lt;br /&gt;
 Loading section .text, size 0x1bc lma 0x0&lt;br /&gt;
 Start address 0x0, load size 494&lt;br /&gt;
 Transfer rate: 3952 bits in &amp;lt;1 sec, 30 bytes/write.&lt;br /&gt;
&lt;br /&gt;
Damit der Simulator nicht das gesamte Programm abarbeitet, sollte man &#039;&#039;breakpoints&#039;&#039; setzen.&lt;br /&gt;
Den Ersten am besten bei &#039;&#039;main&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 (gdb) b main&lt;br /&gt;
 Breakpoint 1 at 0xd2: file main.c, line 16.&lt;br /&gt;
&lt;br /&gt;
Jetzt kann man das Programm im Simulator mit &#039;&#039;continue&#039;&#039; starten:&lt;br /&gt;
&lt;br /&gt;
 (gdb) c&lt;br /&gt;
 Continuing.&lt;br /&gt;
&lt;br /&gt;
Bei Erreichen des zuvor gesetzten &#039;&#039;breakpoints&#039;&#039; stoppt GDB und meldet:&lt;br /&gt;
&lt;br /&gt;
 Breakpoint 1, main () at main.c:16&lt;br /&gt;
 (gdb)&lt;br /&gt;
&lt;br /&gt;
Eine Liste der verfügbaren debug-befehle des GDB findet sich durch die Eingabe von &#039;&#039;&#039;help&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[TODO] Einige häufige GDB-Commands als Beispiel einfügen.&lt;br /&gt;
&lt;br /&gt;
== VMLab ==&lt;br /&gt;
&lt;br /&gt;
[http://www.amctools.com/vmlab.htm VMLab] ist eine komplette Freeware-IDE mit Debugger und Simulator für MS-Windows. VMLab arbeitet mit [[WinAVR]] zusammen und kann AVR-Peripheriehardware simulieren. Leider hat der Autor von VMLab die Entwicklung im Jahr 2006 eingestellt, da dem Projekt nicht der gewünschte kommerzielle Erfolg vergönnt war. Die aktuelle Version ist 3.15 von Oktober 2009.&lt;br /&gt;
&lt;br /&gt;
Siehe auch:&lt;br /&gt;
* Forumsbeitrag [http://www.mikrocontroller.net/topic/24494#714662 VMLAB Bug bei Stackpointer/Interrupt?]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/85212#716727 Workaround]&lt;br /&gt;
&lt;br /&gt;
== AVR Studio ==&lt;br /&gt;
&lt;br /&gt;
[[Bild: AVR-Studio_Simulation.png|thumb|right|250px|Simulator-Ansicht in AVR Studio]]&lt;br /&gt;
[[AVR-Studio|AVR Studio]] von Atmel enthält neben dem Übersetzungsteil, dem Debuggingteil auch einen Simulatorteil. Eine Übersicht über alle drei Programmteile gibt der Powerpoint-Vortrag [http://ece353.ecs.umass.edu/lab2/labC-lectureslides.pptx AVR Studio: The comprehensive tutorial] (MS PowerPoint &#039;&#039;2007&#039;&#039;) von Jeremy Gummeson und Brendan Kemp.&lt;br /&gt;
&lt;br /&gt;
Wenn nur ein Breakpoint gesetzt ist, kann mit F5 das Programm einen Abarbeitungszyklus machen. Die Bearbeitung bleibt dann wieder beim Breakpoint stehen. Mit der Stoppuhr kann dann die Zeit für den abgearbeiteten Programmteil gemessen werden. Mit der rechten Mouse-Taste kann die Stoppuhr zurückgesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Ausführliche Anleitung zum Ablauf einer Simulation:  [http://www2.tech.purdue.edu/ecet/courses/ecet309/Reference_Materials/Simulation_AVR_Studio_4.pdf Tutorial der Purdue University] (engl., PDF)&lt;br /&gt;
&lt;br /&gt;
Externe Signale können mit den Tools HAPSIM oder über eine Stimulidatei in den Simulator eingespeist werden. &lt;br /&gt;
&lt;br /&gt;
Zu beachten ist, dass sich mit der Einführung des AVR Simulator 2, welcher  Vorteile wie Unterstützung von [[I2C|TWI]] bietet, das Datenformat für extern zugeführte Stimuli-Files geändert hat. Eine kleine Einführung inkl. Beispiel bietet die im AVR-Studio enthaltene Hilfe:&lt;br /&gt;
:AVR Studio Help → AVR Tools User Guide → Simulator → Simulator2 Stimuli&lt;br /&gt;
&lt;br /&gt;
=== HAPSIM ===&lt;br /&gt;
&lt;br /&gt;
[http://www.helmix.at/hapsim/index.htm HAPSIM] (Helmis AVR Periphery Simulator) ist ein Tool zur graphischen Simulation von Tasten, [[LED]], [[LCD]] und Terminalfunktionen in AVR Studio. (deutsch/engl., Windows, Freeware). Hinweise zur Installation von Hapsim nach einem AVR Studio Update stehen im Forum: http://www.mikrocontroller.net/topic/118668&lt;br /&gt;
&lt;br /&gt;
=== Stimuli ===&lt;br /&gt;
&lt;br /&gt;
Über eine sog. Stimuli-Datei lassen sich von ausserhalb Signale dem AVR Studio zuführen. Informationen zum Aufbau einer Stimulidatei finden sich in obigem &amp;quot;AVR Studio: The comprehensive tutorial&amp;quot; und bei Atmel ([http://support.atmel.com/bin/customer.exe?=&amp;amp;action=viewKbEntry&amp;amp;id=46 What is the format of the AVR Studio simulator stimuli files?]). Der [http://www.hot.ee/nppcsoftware/ Stimuli Generator for AVR Studio] ist eine Freeware für die Erzeugung von Stimulidateien und deren grafischen Darstellung. Für dieses Programm ist .NET 1.1 oder 2.0 erforderlich.&lt;br /&gt;
&lt;br /&gt;
=== LogAnalyser ===&lt;br /&gt;
&lt;br /&gt;
[http://www.dresco.co.uk/LogAnalyser/ LogAnalyser] v1.00 (c) 2008 Jon Escombe is a graphical &amp;quot;logic analyser&amp;quot; style display of Atmel AVR Studio simulator log files. The project is built using the (excellent) zedGraph charting class library, and the source code is made available under GPL license. Requires Windows XP and .NET framework 2.0 to run.&lt;br /&gt;
&lt;br /&gt;
=== TCPSimDBG ===&lt;br /&gt;
&lt;br /&gt;
[http://www.avrfreaks.net/index.php?name=PNphpBB2&amp;amp;file=viewtopic&amp;amp;t=74350 TCPSimDBG] ist ein Plugin für [[AVR-Studio]] um Remote Simulating/Debugging über TCP/IP durchzuführen. Ein TCP/IP-Terminal oder Serverprogramm kann sich mit dem Simulator/Debugger von AVR-Studio verbinden und Informationen aus dem Debugprozess abrufen und ändern. Damit lassen sich virtuelle Geräte (Devices) eingerichten. (Atmel SDK Lizenz, Windows XP, 2003, Vista .NET 3.5 erforderlich)&lt;br /&gt;
&lt;br /&gt;
=== AVR Logic Analyzer ===&lt;br /&gt;
&lt;br /&gt;
[http://www.coynetechsystems.com/avrlogicanalyzer/index.php AVR Logic Analyzer] von Coyne Technology Systems ist ein AVR Studio Plugin zur grafischen Anzeige der simulierten I/O-Ports.&lt;br /&gt;
(kommerziell)&lt;br /&gt;
&lt;br /&gt;
== Avrora ==&lt;br /&gt;
[http://avrora.sourceforge.net/ Avrora], a research project of the UCLA Compilers Group, is a set of simulation and analysis tools for programs written for the AVR microcontroller produced by Atmel and the Mica2 sensor nodes. Avrora contains a flexible framework for simulating and analyzing assembly programs, providing a clean Java API and infrastructure for experimentation, profiling, and analysis.&lt;br /&gt;
&lt;br /&gt;
== Proteus VSM for Atmel AVR ==&lt;br /&gt;
&lt;br /&gt;
[http://www.labcenter-electronics.com/products/avr.cfm Proteus VSM for Atmel AVR] ist ein kommerzieller AVR Simulator. &lt;br /&gt;
&lt;br /&gt;
In der Codesammlung gibt es dafür ein [http://www.mikrocontroller.net/topic/118974#1072449 Virtuelles AVR Funk Pollin Simulationsmodell] von Daniel Cagara.&lt;br /&gt;
&lt;br /&gt;
== CrossWorks for AVR == &lt;br /&gt;
&lt;br /&gt;
[http://rowley.co.uk/avr/index.htm CrossWorks for AVR] besitzt einen &#039;&#039;core simulator&#039;&#039; für AVRs. (Windows, Mac OS X, Linux, Solaris)&lt;br /&gt;
&lt;br /&gt;
== simavr ==&lt;br /&gt;
&lt;br /&gt;
[http://gitorious.org/simavr simavr] is a new AVR simulator from Michel &amp;quot;buserror&amp;quot; Pollet for linux, or any platform that uses avr-gcc. It uses avr-gcc own register definition to simplify creating new targets for supported AVR devices.&lt;br /&gt;
&lt;br /&gt;
The status of the project is the core works at about 98% (ie, it works, but there is a known bug). The supported IOs are eeprom, IO ports (including pin interupts), 8 bits timers (well, one of mode of the myriad) and a simple UART that makes “printf” work.&lt;br /&gt;
&lt;br /&gt;
gdb support is planned next.&lt;br /&gt;
&lt;br /&gt;
Lizenz: GPL v3&amp;lt;br&amp;gt;&lt;br /&gt;
[http://www.avrfreaks.net/index.php?name=PNphpBB2&amp;amp;file=viewtopic&amp;amp;t=86665 Diskussion bei avrfreaks.net]&lt;br /&gt;
&lt;br /&gt;
== avrtest ==&lt;br /&gt;
&lt;br /&gt;
avrtest ist ein freier AVR Core-Simulator, der zur Ausführung der avr-gcc Testsuite verwendet wird. Über spezielle &amp;quot;magische SFRs&amp;quot; können bestimmte Aktionen ausgelöst werden wie z.B. definierter Programmabbruch oder die Ausgabe eines Zeichens auf Console, so daß ein Programm wie&lt;br /&gt;
&amp;lt;c&amp;gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
    printf (&amp;quot;Hallo Welt!\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
analoge Resultate bringt wie ein Programm, das nativ auf dem Rechner ausgeführt wird.&lt;br /&gt;
&lt;br /&gt;
avrtest ist Open Source, einfach gehalten und auf Geschwindigkeit getrimmt. Die Eingabe von Stimuli ist nicht möglich, und interne Peripherie wird nicht unterstützt.&lt;br /&gt;
&lt;br /&gt;
=== Weblinks ===&lt;br /&gt;
&lt;br /&gt;
* [http://winavr.cvs.sourceforge.net/viewvc/winavr/avrtest/ avrtest: Projekt bei sourceforge]&lt;br /&gt;
* [http://winavr.cvs.sourceforge.net/viewvc/winavr/avrtest/README?view=markup README zur Einleitung (en)]&lt;br /&gt;
* [http://lists.gnu.org/archive/html/avr-gcc-list/2011-06/msg00015.html Beschreibung in der avr-gcc-list Mailingliste (en)]&lt;br /&gt;
&lt;br /&gt;
== BASCOM AVR ==&lt;br /&gt;
&lt;br /&gt;
In [http://www.mcselec.com/ BASCOM AVR] ist ein Simulatorteil enthalten und damit ist auch die Simulation von Geräten (LCD, UART) möglich. BASCOM AVR wird von MCS Electronics verkauft (89€) und ist ein unter Windows laufender [[Basic|BASIC]] [[Compiler]] für Atmel AVR Mikrocontroller. Eine auf 4 KB Codegröße eingeschränkte Demoversion ist kostenlos erhältlich.&lt;br /&gt;
&lt;br /&gt;
== AVR Simulator IDE ==&lt;br /&gt;
&lt;br /&gt;
[http://oshonsoft.com/avr.html AVR Simulator IDE] from oshonsoft.com is a powerful application that supplies AVR developers with user-friendly graphical development environment for Windows with integrated simulator (emulator), Basic compiler, assembler, disassembler and debugger. (Kommerziell, Testversion verfügbar)&lt;br /&gt;
&lt;br /&gt;
== MacSim - AVR simulator for OS X ==&lt;br /&gt;
[http://www.fracturedsoftware.com/macsimavr/ MacSim Alpha 4]&lt;br /&gt;
&lt;br /&gt;
Einschränkungen u.A.:  &amp;quot;There are currently no timers, interrupts, or EEPROM. The processor is &#039;generic&#039; and has fixed size data and instruction memories.&amp;quot;&lt;/div&gt;</summary>
		<author><name>213.61.222.21</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Mikrocontroller_Vergleich&amp;diff=47728</id>
		<title>Mikrocontroller Vergleich</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Mikrocontroller_Vergleich&amp;diff=47728"/>
		<updated>2010-05-21T08:37:45Z</updated>

		<summary type="html">&lt;p&gt;213.61.222.21: /* Interrupt-feste Programmierung von I/O-Ports */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ein paar Kriterien für den CPU-Core und die µC-Familie.&lt;br /&gt;
&lt;br /&gt;
==Compiler verfügbar, bzw wieviel will man dafür ausgeben?==&lt;br /&gt;
&lt;br /&gt;
Und wie verbreitet ist der Compiler? Finde ich dafür Hilfe, beispielsweise in Form von Support-Foren?&lt;br /&gt;
&lt;br /&gt;
Für &#039;&#039;&#039;[[ARM]]&#039;&#039;&#039;, &#039;&#039;&#039;[[AVR]]&#039;&#039;&#039; und &#039;&#039;&#039;[[MSP430]]&#039;&#039;&#039; gibt es mit GCC einen guten und kostenlosen Compiler. Bei &#039;&#039;&#039;ARM&#039;&#039;&#039; sind jedoch die Schritte zum fertigen Programm recht komplex und Library/Laufzeitsystem benötigen einige Handarbeit. &lt;br /&gt;
&lt;br /&gt;
Für &#039;&#039;&#039;ARM&#039;&#039;&#039; gibt es von IAR eine auf 32KB begrenzte kostenlose Version eines umgänglicheren kommerziellen Compilers.&lt;br /&gt;
&lt;br /&gt;
Des Weiteren gibt es für &#039;&#039;&#039;[[MSP430]]&#039;&#039;&#039; eine auf 4KB begrenzte kostenlose Version der Entwicklungsumgebung von IAR und eine auf 8KB begrenzte kostenlose Version der Entwicklungsumgebung Code Composer Essentials (basiert auf Eclipse) von Texas Instruments.&lt;br /&gt;
&lt;br /&gt;
Für &#039;&#039;&#039;[[PIC]]&#039;&#039;&#039; und &#039;&#039;&#039;[[8051]]&#039;&#039;&#039; kann man entweder den Open-Source-Compiler [http://www.sf.net/projects/sdcc SDCC] verwenden (brauchbar, aber nicht mit GCC vergleichbar) oder diverse Löhnwares, bis 4-stellige Beträge (Keil: 2600&amp;amp;#8364; , freie Version codegrösseneingeschränkt), teils auch als Demoversion mit Tricks. Auch der offizielle C18-Compiler kann als großzügiges Demo heruntergeladen werden.&lt;br /&gt;
&lt;br /&gt;
Für &#039;&#039;&#039;[[PIC]] 10/12/16&#039;&#039;&#039; gibt es den HI-TECH C-PRO von HI-TECH(Microchip) in einer freien Version. Der CC5X unterstützt zwar keine High-End PICs, dafür die meisten Mid-Range. Die einzige Einschränkung der freien Version des CC5X ist die Limitierung auf 1024 Instruktionen pro Modul, nicht so gute Codeoptimierung und die Begrenzung von Variablen auf 16-Bit.&lt;br /&gt;
&lt;br /&gt;
Für die &#039;&#039;&#039;[[PIC]] 18&#039;&#039;&#039; gibt es den C18 von Microchip. Er ist frei erhältlich und hat ähnliche Einschränkungen wie der C30.&lt;br /&gt;
&lt;br /&gt;
Für die &#039;&#039;&#039;[[PIC24]]&#039;&#039;&#039; und &#039;&#039;&#039;[[dsPIC]]&#039;&#039;&#039; gibt es den C30 von Microchip. Er basiert auf gcc und ist frei erhältlich, wobei nach 6 Wochen nicht mehr alle Optimierungsstufen wählbar sind, dann maximal -O1. Wie für alle PIC ist mit dem MPLAB eine kostenlose IDE mit Debugger und Simulator verfügbar.&lt;br /&gt;
&lt;br /&gt;
Für &#039;&#039;&#039;[[R8C]]/M16C&#039;&#039;&#039; gibt es eine Demoversion des Herstellers und eine noch ziemlich frische (lies: Stand 2005 nicht ausgereifte) Version vom GCC.&lt;br /&gt;
&lt;br /&gt;
Für &#039;&#039;&#039;[[ST7]]&#039;&#039;&#039; gibt es (teils limitierte) C-Compiler, teils mit IDE (z.ß. Cosmic und Ride). Toolchain von ST kostenlos erhältlich.&lt;br /&gt;
&lt;br /&gt;
Von Toshiba gibt es für &#039;&#039;&#039;[[TLCS-870]]&#039;&#039;&#039; mit den Starterkits eine IDE mit C-Compiler und Assembler. Ausserdem gibt es Toshibas eigene &amp;quot;C-Like Language&amp;quot;. Diese Tools sind nicht frei downloadbar.&lt;br /&gt;
&lt;br /&gt;
Zilog stellt für &#039;&#039;&#039;[[Z8_encore!]]&#039;&#039;&#039; eine unbeschränkte IDE mit C-Compiler, Debugger und Simulator kostenlos per Download zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pascal&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Für PIC,DSPIC und AVR gibt es einen sehr guten PASCAL-Compiler &amp;quot;MikroPascal&amp;quot;&lt;br /&gt;
der, in der Downloadversion Code-Size begrenzt ist,&lt;br /&gt;
und den man zu moderaten Preisen zur &amp;quot;Vollversion&amp;quot; aufrüsten kann.&lt;br /&gt;
http://www.mikroelektronika.co.yu/&lt;br /&gt;
( ab 149,- &amp;amp;#8364; )&lt;br /&gt;
&lt;br /&gt;
Elektor-Verlag &#039;Pascal für 8051 und Derivate&#039; Buch+Compiler(Vollversion)&lt;br /&gt;
&lt;br /&gt;
AVRco Pascal Compiler (http://www.e-lab.de/), &lt;br /&gt;
Kostenlose Version für Mega8/88&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;BASIC:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Sowohl für den AVR als auch für die 8051er gibts von MCS-Electronics eine Demoversion eines BASIC-Compilers,&lt;br /&gt;
der leicht im Funktionsumfang und Codegröße eingeschränkt ist. &lt;br /&gt;
[http://www.mcselec.com/]&lt;br /&gt;
&lt;br /&gt;
Darüber hinaus kursieren im Netz Versionen eines BASIC-Interpreters für 8052er mit dem Namen &amp;quot;8052 AH-BASIC&amp;quot;, wobei die Originalversion von INTEL stammt. Dieser Interpreter unterstützt sogar Fließkomma-Arithmetik und ist als Freeware verfügbar.&lt;br /&gt;
&lt;br /&gt;
==Architektur==&lt;br /&gt;
&lt;br /&gt;
Betrifft vor allem Assembler-Programmierung und die Frage, wie einfach oder umständlich sich C-Code in Maschinensprache übersetzen lässt. &lt;br /&gt;
&lt;br /&gt;
Dass für alle Architekturen teils mehrere C-Compiler existieren, hat wenig mit Eignung und viel mit Markt zu tun. Zudem ist meist nur entscheidend, ob ein Controller die Anforderungen erfüllt, nicht jedoch wie gut er das tut.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Manches davon ist durchaus subjektiv. Bei abweichender Meinung bitte als Diskussion starten, nicht einfach löschen.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;8051&#039;&#039;&#039;: Typische Akkumulator-orientierte 8-Bit Architektur. Eine gewisse Komplexität entstand durch die sukzessive Erweiterung auf mehr RAM als ursprünglich vorgesehen war, mit etlichen unterschiedlich adressierten RAM-Bereichen als Folge. Für C-Compiler nur eingeschränkt geeignet.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ARM&#039;&#039;&#039;: 32bit RISC-Architektur. In den gängigen Implementierungen mit dem  ARM7TDMI-Core (Architektur V4 = ARMv4T) stehen 2 Befehlssätze zur Verfügung: 32bit-codiert für Tempo, sofern der Speicherdurchsatz das zulässt, und 16bit-codiert (Thumb) für kompakte Programme. Cortex M3 (ARMv7) kennt ausschliesslich Thumb2 codierte Befehle, wurde gegenüber Thumb erheblich erweitert. Einheitlicher 32bit-Adressraum. Exzellente Zielmaschine für C-Compiler.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;AVR&#039;&#039;&#039;: Register-orientierte, an RISC Prinzipien angelehnte 8-Bit Architektur. Getrennte Adressräume für RAM und ROM. Registersatz nicht einheitlich nutzbar. I/O-Bereich nicht einheitlich adressierbar. Nur ein Teil des I/O-Bereiches ist bitweise manipulierbar. Einheitliche RAM-Adressierung. Für C-Compiler geeignet.Bemerkung: Laut Wikipedia wurde der Controller während der Entwicklungsphase für den Einsatz von C-Compilern optimiert.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MSP430&#039;&#039;&#039;: Register-orientierte 16-Bit RISC-Architektur mit vollständiger Orthogonalität. Einheitlicher Adressraum für RAM und ROM. Exzellente Zielmaschine für C-Compiler. Angelehnt an die legendäre PDP-11, vieles wurde übernommen.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;PIC&#039;&#039;&#039;: Akkumulator-orientierte 8-Bit Architektur. Getrennte Adressräume für RAM und ROM. RAM-Banking, ROM-banking. Umständlicher Zugriff auf Daten im ROM (nur 12/14-Bit Versionen). Viele für C-Compiler wesentliche Elemente sind nur umständlich realisierbar (z.&amp;amp;nbsp;B. Code/Datenadressierung mit Banking, Vergleich mit Vorzeichen).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;PIC24&#039;&#039;&#039;: Register-orientierte 16-Bit Architektur mit getrennten Adressräumen für RAM und ROM, wobei ein Teil des ROM in den RAM-Adressbereich eingeblendet werden kann. Fast alle Befehle sind auf Register und RAM anwendbar, incl. Bitmanipulationen.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dsPIC&#039;&#039;&#039;: wie &#039;&#039;&#039;PIC24&#039;&#039;&#039;, mit zusätzlichen DSP Befehlen.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;R8C&#039;&#039;&#039;: 16-Bit 2-Adress CISC-Architektur. Einheitlicher 64KB Adressraum für RAM und ROM. Gute Zielmaschine für C-Compiler.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;M16C&#039;&#039;&#039;: Unter Bezeichnung M16C existieren zwei verschiedene inkompatible Architekturen. Die Modelle bis /6x sind grundsätzlich identisch mit R8C, die /8x Modelle mit M32C (hier nicht näher betrachtet). Der 64KB RAM-I/O-Adressraum ist ein Teil des 1MB großen Gesamtadressraumes, Daten im ROM liegen jedoch ausserhalb dieser 64KB und sind daher anders als beim R8C nicht mit 16-Bit Zeigern adressierbar. Gute Zielmaschine für spezialisierte C-Compiler, GCC jedoch tut sich etwas schwer mit den Adressräumen.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ST7&#039;&#039;&#039;:Akkumulatorarchitektur, Gemeinsamter Code/Datenadressraum (von-Neumann). 63 Befehle. Einheitlicher 64KB Adressraum für RAM und ROM.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TLCS-870&#039;&#039;&#039;: 8-Bit CISC-Architektur, aus Z80 weiterentwickelt. Gemeinsamer Adressraum für RAM und ROM bis 60KB ROM, darüber getrennt. Adressraum 64/128KB. Serie 870/X mit 1MB Adressraum existiert, aber nur als OTP/Maskenversion.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Z8e&#039;&#039;&#039;: Register-orientierte 8-Bit Architektur, 2-Adress-CISC. Getrennte Adressräume für RAM und ROM. Historisch bedingt 3 RAM-Adressräume (8-Bit, 12-Bit, 16-Bit). Für C-Compiler geeignet&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Kleiner nicht repräsentativer Compiler-Vergleich. Verwendet wurde eine Variante des crc8-Code von Colin O&#039;Flynn. Jeweils kleinstes Speichermodell, auf Platz optimiert:&lt;br /&gt;
{|&lt;br /&gt;
|Compiler&lt;br /&gt;
|  Befehle(1)&lt;br /&gt;
|  Bytes(1)&lt;br /&gt;
|  Befehle(2)&lt;br /&gt;
|  Bytes(2)&lt;br /&gt;
|-&lt;br /&gt;
|GCC AVR&lt;br /&gt;
|24&lt;br /&gt;
|48&lt;br /&gt;
|24&lt;br /&gt;
|48&lt;br /&gt;
|-&lt;br /&gt;
|Keil 8051&lt;br /&gt;
|24&lt;br /&gt;
|38&lt;br /&gt;
|74&lt;br /&gt;
|109&lt;br /&gt;
|-&lt;br /&gt;
|SDCC 8051&lt;br /&gt;
|24&lt;br /&gt;
|40&lt;br /&gt;
|35&lt;br /&gt;
|54&lt;br /&gt;
|-&lt;br /&gt;
|Zilog Z8e&lt;br /&gt;
|21&lt;br /&gt;
|54&lt;br /&gt;
|27&lt;br /&gt;
|73&lt;br /&gt;
|-&lt;br /&gt;
|PIC C18&lt;br /&gt;
|26&lt;br /&gt;
|52&lt;br /&gt;
|95&lt;br /&gt;
|206&lt;br /&gt;
|-&lt;br /&gt;
|SDCC PIC18&lt;br /&gt;
|41&lt;br /&gt;
|112&lt;br /&gt;
|41&lt;br /&gt;
|112&lt;br /&gt;
|-&lt;br /&gt;
|SDCC PIC16&lt;br /&gt;
|26&lt;br /&gt;
|52&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| (for pic16f84)&lt;br /&gt;
|-&lt;br /&gt;
|HEW R8C/M16C&lt;br /&gt;
|20&lt;br /&gt;
|48&lt;br /&gt;
|20&lt;br /&gt;
|48&lt;br /&gt;
|-&lt;br /&gt;
|GCC 68HC11&lt;br /&gt;
|36&lt;br /&gt;
|65&lt;br /&gt;
|36&lt;br /&gt;
|65&lt;br /&gt;
|-&lt;br /&gt;
|GCC MSP430&lt;br /&gt;
|17&lt;br /&gt;
|40&lt;br /&gt;
|17&lt;br /&gt;
|40&lt;br /&gt;
|-&lt;br /&gt;
|GCC ARM7&lt;br /&gt;
|12&lt;br /&gt;
|48&lt;br /&gt;
|12&lt;br /&gt;
|48&lt;br /&gt;
|-&lt;br /&gt;
|GCC ARM7-Thumb&lt;br /&gt;
|20&lt;br /&gt;
|40&lt;br /&gt;
|20&lt;br /&gt;
|40&lt;br /&gt;
|}&lt;br /&gt;
(1): Lokale Daten ggf. statisch gespeichert, nicht reentrant.&lt;br /&gt;
&lt;br /&gt;
(2): Lokale Daten auf dem Stack, also reentrant.&lt;br /&gt;
&lt;br /&gt;
==Sind CPU-spezifische Erweiterungen in C erforderlich?==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;8051&#039;&#039;&#039;: &lt;br /&gt;
* 5-6 Speicherklassen für Datenspeicher (direkt, indirekt, 8-Bit &amp;quot;external&amp;quot;, 16-Bit &amp;quot;external&amp;quot;, Flash, evtl. noch Einzelbits). &lt;br /&gt;
*Außerdem noch Adresserweiterungen durch Mapping, Paging und Banking &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;AVR&#039;&#039;&#039;: &lt;br /&gt;
* 3 Speicherklassen für Datenspeicher (RAM, ROM, EEPROM).&lt;br /&gt;
* In neueren Versionen von avr-libc kommt zwar eine 4. Klasse für die Fuse-Bits hinzu, die aber nur für die Konfiguration des Controllers verwendet wird und für das C-Programm selbst nicht relevant ist.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ARM&#039;&#039;&#039;, &#039;&#039;&#039;MSP430&#039;&#039;&#039;, &#039;&#039;&#039;R8C&#039;&#039;&#039;: nein.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;PIC&#039;&#039;&#039;: &lt;br /&gt;
* 3 Speicherklassen für Datenspeicher (shared RAM, banked RAM, ROM).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Z8e&#039;&#039;&#039;:&lt;br /&gt;
* Für atomic execution (s.u.) notwendig, aber nicht existent.&lt;br /&gt;
* 4 Speicherklassen für Datenspeicher (256B, 4KB, 64KB, Flash).&lt;br /&gt;
&lt;br /&gt;
==Sind Daten in RAM und ROM mit dem gleichen Code benutzbar?==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;8051&#039;&#039;&#039;, &#039;&#039;&#039;AVR&#039;&#039;&#039;, &#039;&#039;&#039;PIC&#039;&#039;&#039;, &#039;&#039;&#039;Z8e&#039;&#039;&#039; wie generell alle [[Harvard-Architektur|Harvard-Architekturen]]: NEIN. Daten im ROM&lt;br /&gt;
erfordern anderen Zugriff als Daten im RAM. Entweder versteckt das der Compiler in Runtime-Routinen für Pointerzugriffe, oder man kann Routinen nicht so schreiben, dass sie beides als Parameter verdauen können. Bei kleinen Programmen von ein paar KB kein Problem, bei größeren jedoch schon. Bei AVR/GCC ziemlich fehlerträchtig.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;PIC24&#039;&#039;&#039; und &#039;&#039;&#039;dsPIC&#039;&#039;&#039; können einen Teil des ROM in den RAM-Adressbereich einblenden.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;M16C&#039;&#039;&#039;: Hängt vom Compiler ab. Mit 16-Bit Zeigern (GCC) nicht, 20-Bit Zeiger sind ineffizient.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ARM&#039;&#039;&#039;, &#039;&#039;&#039;MSP430&#039;&#039;&#039;, &#039;&#039;&#039;R8C&#039;&#039;&#039;, &#039;&#039;&#039;ST7&#039;&#039;&#039;, &#039;&#039;&#039;TLCS-870&#039;&#039;&#039;: [[von Neumann-Architektur]], problemlos.&lt;br /&gt;
&lt;br /&gt;
==Lineare Adressierung vom RAM?==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;8051&#039;&#039;&#039;, &#039;&#039;&#039;ARM&#039;&#039;&#039;, &#039;&#039;&#039;AVR&#039;&#039;&#039;, &#039;&#039;&#039;MSP430&#039;&#039;&#039;, &#039;&#039;&#039;R8C/M16C&#039;&#039;&#039;, &#039;&#039;&#039;ST7&#039;&#039;&#039;, &#039;&#039;&#039;TLCS-870&#039;&#039;&#039;, &#039;&#039;&#039;Z8e&#039;&#039;&#039;: kein Problem.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;PIC&#039;&#039;&#039;: PIC18 ja, PIC16,PIC12,PIC10 nein. RAM-Puffer die größer sind als das RAM in einer Bank sind nur mit Klimmzügen möglich.&lt;br /&gt;
&lt;br /&gt;
==Skalierbarkeit==&lt;br /&gt;
&lt;br /&gt;
Vor allem für jene wichtig, die sich scheuen, für&lt;br /&gt;
verschiedene Aufgaben verschiedene Lösungen zu verwenden. &lt;br /&gt;
&lt;br /&gt;
Spezielle Versionen für LCD-Ansteuerung wurden in dieser Übersicht nicht berücksichtigt.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;8051&#039;&#039;&#039;: 8-Pin/1KB aufwärts, überwiegend 40/44-Pin und 64/68-Pin. Architekturbedingte Grenze bei 64KB Code, 64KB RAM - Versionen mit mehr Flash  nutzbar via Banking (Compiler-Support vorhanden) existieren, Versionen mit bis zu 100 MHz Taktfrequenz verfügbar.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ARM&#039;&#039;&#039;: 48-Pin/32KB, bis 512K mit internem Flash. Versionen mit internem Cache und externem Speicher sind praktisch beliebig weit ausbaufähig.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;AVR&#039;&#039;&#039;: 8-Pin/1KB bis 100-Pin/256KB. Architekturbedingte  Grenze bei 8MB Code, 64KB RAM. GCC/WinAVR derzeit nur bis 128KB Code möglich (in Arbeit).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MSP430&#039;&#039;&#039;: 14-Pin DIP/1KB bis 113-Pin BGA/256KB. DIP, SOIC, TSSOP, QFN, TQFP und BGA erhältlich, in DIP und BGA jedoch nur wenige Typen verfügbar. Architekturbedingte Grenze von 64KB für Code+Daten wird in den großen Versionen durch 20-bittige Adressen umschifft. Taktfrequenz: maximal 8, 16 und 18 MHz je nach Familie. 25 MHz-Versionen in Kürze. Stromaufnahme: Rund 2 uA im LPM3 (real time clock mode) bis ca. 5 mA, typisch 200 µA pro MHz.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;PIC&#039;&#039;&#039;: 6-Pin/512B aufwärts. Im Prinzip großer Bereich, aber innerhalb der Familie deutlich verschiedene inkompatible Architekturen mit unterschiedlichen architekturbedingen Grenzen und unterschiedlichem Compiler-Support.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;PIC24&#039;&#039;&#039; und &#039;&#039;&#039;dsPIC&#039;&#039;&#039;: 18 bis 100-Pin mit 16 bis 256kB Code und bis zu 16kB RAM. Generell sind alle als TQFP und QFN erhältlich, die 18 und 28 Pin Modelle gibt es auch als SDIP und SSOP und SOIC. Es gibt Modelle mit 16 und 40MHz.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ST7:&#039;&#039;&#039; 8 bis 80 Pins. SDIP, SOIC, LQFP, TQFP, QFN. 128 bis 2048 Bytes SRAM, 1 bis 60 kBytes Flash.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TLCS-870&#039;&#039;&#039;: 20pin DIP bis 267FBGA. Daneben SDIP, SOIC, SSOP und (L/T)QFP. Relativ wenige Flash-Typen. RAM: 128 Bytes bis 4kB. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Z8e&#039;&#039;&#039;: 8 bis 80 Pins. DIP, SOIC, SSOP, QFP, TQFP, QFN. Bis 64KB Flash. 256 Bytes bis 4 kBytes RAM.&lt;br /&gt;
&lt;br /&gt;
Empfehlung hier: Auch wenn teilweise mehr möglich ist, sind 8/16-Bit-Controller nur bis maximal 40-60K empfehlenswert. Darüber sollte eine 32-Bit-Architektur — z.&amp;amp;nbsp;B. mit [[ARM]]-Core — in Betracht gezogen werden. Insbesondere auch, weil große Programme zu Programm- und Datenstrukturen neigen, die sich auf 8-Bit-Prozessoren schlecht abbilden lassen.&lt;br /&gt;
&lt;br /&gt;
==Interrupt-feste (atomic) Programmierung von I/O-Ports==&lt;br /&gt;
&lt;br /&gt;
Siehe http://www.mikrocontroller.net/articles/Interrupt.&lt;br /&gt;
&lt;br /&gt;
Das ist besonders bei &#039;&#039;&#039;AVR&#039;&#039;&#039; (ausser den Typen seit 2004: ATtiny2313 usw.) ein Problem. Architekturbedingt ist nur ein Teil der Ports bitweise schaltbar, kein Port kann mehrere Bits gleichzeitig interrupt-fest schalten.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;PIC&#039;&#039;&#039;, &#039;&#039;&#039;8051&#039;&#039;&#039;, &#039;&#039;&#039;MSP430&#039;&#039;&#039;, &#039;&#039;&#039;R8C/M16C&#039;&#039;&#039;, &#039;&#039;&#039;Z8e&#039;&#039;&#039; können AND/OR/XOR zum Port hin, daher ist bei geeigneter Programmierung das Problem auch ohne Abschalten der Interrupts vermeidbar.&lt;br /&gt;
&lt;br /&gt;
Zu &#039;&#039;&#039;ARM&#039;&#039;&#039; ist dazu keine allgemeine Aussage möglich. Je nach Implementierung wird das Problem teilweise durch entsprechend gestaltete I/O-Ports gelöst, in anderen Fällen ist erhebliche Wachsamkeit geboten. Atmel SAM7 bereitet hier weniger Probleme als Philips LPC2000. Bei den  LPC2000 gibt es zwei getrennte Register, eines zum Setzen, das andere zum Löschen einzelner Pins. In einem weiteren Register können Bits ausmaskiert werden. Es gibt also kein read-modify-write. Gut gelöst für Push/Pull-Ausgänge, aber eine äquivalente Steuerung der Richtung wurde vergessen, was Open-Drain Pins erschwert. Implementierungen auf Basis des Cortex M3 oder der ARM Port-Macrocell verwenden statt dessen Adressbits zur Maskierung.&lt;br /&gt;
&lt;br /&gt;
Besonders pfiffig ist das beim &#039;&#039;&#039;Z8e&#039;&#039;&#039; gelöst. Ein Befehl fasst die nächsten 3 Befehle zu einer nicht unterbrechbaren Einheit zusammen (atomic execution). Allerdings wird das vom Zilog Compiler nicht unterstützt.&lt;br /&gt;
&lt;br /&gt;
==Zugriff auf I/O-Ports==&lt;br /&gt;
&lt;br /&gt;
Der &#039;&#039;&#039;8051&#039;&#039;&#039; verfügt weder über eigene Register für die Steuerung der Richtung der I/O-Ports, noch über die Möglichkeit, lesend auf den Sollzustand der Ausgänge zuzugreifen. In Assembler ist das kein Problem, da abhängig vom Befehl entweder vom Zustand der Pins (Leseoperationen) oder vom Sollzustand der Ausgänge (kombinierte Lese/Schreiboperationen) ausgegangen wird. Ein korrekt arbeitender C Compiler kann damit jedoch nicht umgehen, weshalb für die Steuerung von Port-Pins spezielle Zugriffsfunktionen und eine sehr genaue Kenntnis der Arbeitsweise der Ports erforderlich sind.&lt;br /&gt;
&lt;br /&gt;
Anmerkung zum Keil 8051-Compiler: Port-Zugriff erfolgt über Pseudo-Variablen wie bei µC üblich. Infolgedessen ist in C Code nicht ersichtlich, ob beispielsweise die Port-Variable P1 für den Zustand der Pins oder den Sollzustand der Ausgänge steht. Nur der erzeugte Assembler-Code kann hier Klarheit schaffen. So haben die beiden prinzipiell identischen Zeilen&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
P1 = P1 | 0x01;&lt;br /&gt;
P1 = (P1 | 0x01) &amp;amp; ~0;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
völlig unterschiedliche Auswirkung auf den Port. Der Code der ersten Zeile setzt Bit 0 und lässt alle anderen Bits unverändert. Der von der zweiten Zeile erzeugte Code setzt zusätzlich auch alle vorher als Eingang definierten Pins im Zustand 0 auf Ausgang mit Zustand 0. Das ist weder hilfreich, noch mit der Sprachdefinition von C vereinbar.&lt;br /&gt;
&lt;br /&gt;
Auch manche Modelle der &#039;&#039;&#039;PIC&#039;&#039;&#039;-Familie können nur auf den Zustand der Pins zugreifen, nicht auf den Sollzustand der Ausgänge.&lt;br /&gt;
&lt;br /&gt;
In beiden Fällen ist folglich bei Ports, die sowohl für Aus- als auch für Eingänge benutzt werden, besondere Sorgfalt nötig.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ARM&#039;&#039;&#039;, &#039;&#039;&#039;AVR&#039;&#039;&#039;, &#039;&#039;&#039;MSP430&#039;&#039;&#039;, &#039;&#039;&#039;Z8e&#039;&#039;&#039; und neuere Modelle der &#039;&#039;&#039;PIC&#039;&#039;&#039;-Familie besitzen diese Probleme nicht.&lt;br /&gt;
&lt;br /&gt;
==Priorisierte Interrupts==&lt;br /&gt;
&lt;br /&gt;
Unter priorisierten Interrupts versteht man die Fähigkeit, den einzelnen Interrupt-Quellen eine Priorität zuweisen zu können um ohne Reprogrammierung der Interrupt-Quellen einen laufenden Interrupt ausschliesslich durch Interrupts höherer Priorität unterbrechbar machen zu können. Die bei separaten Vektoren selbstverständliche Fähigkeit, anstehende Interrupts nach fester Priorität zu sortieren, ist damit nicht gemeint.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;8051&#039;&#039;&#039;: Ja.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ARM&#039;&#039;&#039;: Der ARM7/9-Core unterstützt 2 Prioritäten mit entsprechenden Vektoren. Oft ist jedoch ein separater priorisierter und vektorisierter Interrupt-Controller mit integriert (Atmel, NXP, Cortex ja, Analog Devices nein). Interrupt-Nesting ist dank eines Designfehlers etwas umständlich.&lt;br /&gt;
&lt;br /&gt;
ARMv7 aka Cortex-M3: Ein priorisierender Interrupt Controller ist Teil des Cores und Nesting ist problemlos möglich.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;AVR:&#039;&#039;&#039; Nein, aber separate Vektoren für die einzelnen Interrupt-Quellen.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Anmerkung: Eine weniger wichtiger Interrupt Handler kann oft sofort nach Ansprung ein SEI ausführen, damit ein möglicherweise wichtigerer Interrupt Handler aufgerufen werden kann, weil bei den meisten Interrupts der Request bereits mit dem Aufruf des Handlers automatisch zurück gesetzt wird. Das trifft aber beispielsweise nicht beim TWI zu.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MSP430:&#039;&#039;&#039; Nein, aber separate Vektoren für die einzelnen Interrupt-Quellen. Keine Priorisierung im Sinne der Präambel.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;PIC12 &amp;amp; PIC16:&#039;&#039;&#039; Nein, nur ein Interruptvektor.  Einfache PIC12 (12F508/509, 16F505) kennen gar keine Interrupts.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;PIC18:&#039;&#039;&#039; Jeder Interruptquelle kann separat eine niedrige oder hohe Priorität zugewiesen werden, die dann auf zwei Interruptvektoren verzweigen. Welche Quelle den Interrupt ausgelöst hat, muss aber immer noch händisch festgestellt werden.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;PIC17:&#039;&#039;&#039; Vier Interruptvektoren mit unterschiedlicher Priorität. Scheint es allerdings nur als OTP zu geben, deswegen wohl eher uninteressant.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;PIC24&#039;&#039;&#039; und &#039;&#039;&#039;dsPIC&#039;&#039;&#039; haben 7 Prioritäten und für jeden Interrupt einen eigenen Interruptvektor.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;R8C/M16C&#039;&#039;&#039;: 7 Prioritäten, vektorisiert.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ST7&#039;&#039;&#039;: Nein. 16 Vektoren mit fixer (absteigender) Priorität.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Z8e&#039;&#039;&#039;: 3 Prioritäten, vektorisiert.&lt;br /&gt;
&lt;br /&gt;
== Spannungsversorgung ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;8051&#039;&#039;&#039;, &#039;&#039;&#039;AVR&#039;&#039;&#039;, &#039;&#039;&#039;PIC&#039;&#039;&#039;: Modellabhängig 2-5V problemlos, ältere ab 3V. PICs für 2-4V sind schlecht verfügbar. Ungeregelter Batteriebetrieb möglich.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ARM&#039;&#039;&#039;: 3,3V-Versorgung, je nach Modell mehr oder weniger 5V-kompatibel. Einige (vor allem ältere) Modelle benötigen eine separate 1,8V-Versorgung für den Core. Kein ungeregelter Batteriebetrieb möglich.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;PIC24&#039;&#039;&#039; und &#039;&#039;&#039;dsPIC33&#039;&#039;&#039;: 2-3,6V. Pins die keine analogen Funktionen übernehmen können sind 5V tolerant.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MSP430&#039;&#039;&#039;: nur 1.8-3.6V. Nicht 5V-kompatibel, 5V-Peripherie für I2C/RS485/CAN/... ist also nur mit Pegelkonvertierung einsetzbar. Ungeregelter Batteriebetrieb möglich.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ST7&#039;&#039;&#039;: 2,4-5,5V&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TLCS-870&#039;&#039;&#039;: 2,7-5,5V. Serie 870/C 1,8-5,5V.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Z8e&#039;&#039;&#039;: 1,8-3,6V, I/Os 5V-tolerant.&lt;br /&gt;
&lt;br /&gt;
==Programmierung in der Schaltung==&lt;br /&gt;
&lt;br /&gt;
Geräte mit Debugging-Interface (s.U.) lassen sich i.d.R. auch damit programmieren. Siehe dazu nächsten Abschnitt.&lt;br /&gt;
&lt;br /&gt;
Die meisten Controller können sich selbst programmieren, Bootloader per RS232,CAN,usw sind dann problemlos realisierbar. Nur müssen solche Bootloader erst einmal auf den Chip programmiert werden.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;8051&#039;&#039;&#039;: Verschieden, je nach Hersteller und Modell. Im Unterschied zu den anderen hier betrachtete Controllern existieren viele nicht in der Schaltung, sondern nur mit speziellen Interfaces programmierbare 8051 Modelle. Modelle mit seriellem Bootloader via UART, SPI, CAN oder USB existieren.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ARM&#039;&#039;&#039;: Am besten über JTAG, je nach Hersteller und Familie auch mit Bootloader, z.&amp;amp;nbsp;B. bei Philips LPC2000 über RS232 und Atmel SAM7 über USB (bei letzterem sehr unbequem und langsam!).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;AVR&#039;&#039;&#039;: Über ein an SPI orientiertes proprietäres Interface. Ist via Parallelport günstig herzustellen; der Adapter ist im besten Fall genau 5 Widerstände teuer, professioneller mit einem [[Ausgangsstufen_Logik-ICs#Tri-state|Tri-State]]-Bustreiber etwa 5-15 EUR. Darüberhinaus auch mit HV-Programmer (z.&amp;amp;nbsp;B. auf dem [[STK500]]), der u.U. auch nötig ist um falsch gesetzte Fuses wieder zu &amp;quot;reparieren&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MSP430&#039;&#039;&#039;: Via JTAG-Interface, TI &amp;quot;Spy BiWire&amp;quot; und über integrierten  Bootloader. (Schaltung zur Ansteuerung via RS232 im Datenblatt)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;PIC&#039;&#039;&#039;: Entweder über die serielle ICSP-Schnittstelle (dafür gibt es Baupläne für billige ParPort-Programmer incl. guter Software) oder mit dem InCircuit-Debugger (~150&amp;amp;#8364;, ICD2 von Microchip). Bootloader müssen generell vorher mit einer der vorher genannten Möglichkeiten auf den Chip geflasht werden.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;R8C&#039;&#039;&#039;: Via UART (RS-232 oder USB-RS-232 Konverter) mit Flash-Tool (Windows, Linux). Variante über Bootloader ebenfalls möglich (wird vom Software Emulator-Debugger benutzt).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ST7&#039;&#039;&#039;: Via ein mit der Schaltung (mittels mindestens 4poligen Kabels) kommunizieredes Debug-Interface. Offenes ST-Protokoll &amp;quot;ICC&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TLCS-870&#039;&#039;&#039;: Flash-Typen besitzen maskenprogrammierten Bootloader.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Z8e&#039;&#039;&#039;: Via Zilogs Debug-Interface &amp;quot;Smart Cable&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==Debugging in der Schaltung==&lt;br /&gt;
&lt;br /&gt;
Ist beispielsweise ein günstiges [[JTAG]]-Interface für In-Circuit&lt;br /&gt;
Debugging verfügbar?&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;8051&#039;&#039;&#039;: Derivate mit JTAG verfügbar. ICEen gebraucht erschwinglich.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ARM&#039;&#039;&#039;: alle mit JTAG.&lt;br /&gt;
* Günstiges Parallel-Port-Interface verfügbar und einfach zu bauen (Wiggler), aber langsam und problematisch im Betrieb unter WinNT+ (besser: ocdremote unter Win9x auf Zweitrechner, via LAN). Kostenlose Debugger ([[GDB]]) unterstützen seit OCDremote 2.14 mit Einschränkungen auch Programme im Flash. &lt;br /&gt;
* Schnelles JTAG Interface basierend auf FT2232C für [[GDB]]/OpenOCD günstig und einfach zu bauen (http://www.fh-augsburg.de/~hhoegl/proj/usbjtag/usbjtag.html) oder fertig erhältlich (http://www.amontec.com/jtagkey.shtml).&lt;br /&gt;
* Kommerzielle Debugger per USB sind besser und schneller, aber recht teuer.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;AVR&#039;&#039;&#039;: für ATmega16/162/32/128 ist JTAG günstig verfügbar&lt;br /&gt;
(Olimex, Erostech) bzw. einfach zu bauen (Evertool). ATmegas ab 2005/2006 mit JTAG sind zu dieser Billigvariante inkompatibel. Für diese und den [[debugWIRE]] der ATtinys und ATmegaX8 existiert das JTAG ICE mkII von Atmel, aber recht teuer, sowie der preiswerte AVR Dragon.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MSP430&#039;&#039;&#039;: alle mit JTAG, Adapter sehr günstig/einfach zu bauen. Neuere Geräte mit Spy-by-Wire (braucht weniger Pins als JTAG).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;PIC&#039;&#039;&#039;: Entweder Microchips MPLAB ICD2 (&amp;amp;#8364;150-200) oder ein kompatibler Nachbau, wie z.&amp;amp;nbsp;B. http://www.stolz.de.be/. Alternativ das PICKit 2 für ~40€, dass neben dem Programmieren und Debuggen über USB auch noch als RS232-Brücke und einfacher Logic-Analyzer benutzt werden kann. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;R8C&#039;&#039;&#039;: On-Chip Debugging ist mit dem E8 Hardware On-Chip Debugging Emulator möglich (kein JTAG). Ausserdem ist Debugging auch über einen normalen RS232 Anschluss möglich. Der E8 verwendet ein syncrones serielles Protokoll, die RS232 ein asyncrones. Daher ermöglicht der E8 das Debugging bei jeder beliebigen Taktfrequenz, bei RS232 gibt es da Einschränkungen.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ST7&#039;&#039;&#039;: Via ein mit der Schaltung (mittels mindestens 4poligen Kabels) kommunizieredes Debug-Interface. Offenes ST-Protokoll &amp;quot;ICC&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Z8e&#039;&#039;&#039;: Debugging möglich mit &amp;quot;Smart Cable&amp;quot; (kein JTAG), Anschluss über USB oder seriell Schnittstelle&lt;br /&gt;
&lt;br /&gt;
==Starterkits==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;8051&#039;&#039;&#039;: Keil MCBx51 http://www.keil.com/mcbx51 (z.&amp;amp;nbsp;B. für ~240&amp;amp;#8364; von [http://de.mouser.com/Search/Refine.aspx?Keyword=830-MCBX51 mouser.com])&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ARM&#039;&#039;&#039;: http://www.olimex.com (z.T. hier im Shop erhältlich), http://www.embeddedartists.com,&lt;br /&gt;
http://www.mct.de&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;AVR&#039;&#039;&#039;: [[STK200]], [[STK500]], [[AVR_Butterfly]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MSP430&#039;&#039;&#039;: http://www.olimex.com (z.T. hier im Shop erhältlich), ez430 (http://www.ti.com/ez430)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;PIC&#039;&#039;&#039;: http://www.microchipdirect.com/ , Velleman-Kit K8048 (www.velleman.be)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;R8C&#039;&#039;&#039;: Mehrere (Google Suche). Am weitesten verbreitet ist vielleicht das R8C/13 Starterkit inkl. Entwickler-CD von Glyn/Elektor (Beilage Elektor 12/2005 (ausverkauft) bzw. diverse Drittanbieter). &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Z8e&#039;&#039;&#039;: Günstig verfügbar [~50&amp;amp;#8364;], teils hier im Shop, komplett inklusive unbeschränktem Compiler und In-System-Debugging. Nachteile: für jede Prozessorklasse ein eigenes Kit; eingelöteter SMD-Chip obwohl viele Typen auch im DIL-Gehäuse existieren.&lt;br /&gt;
&lt;br /&gt;
==Gehäuse==&lt;br /&gt;
&lt;br /&gt;
Mit DIP oder PLCC bastelt es sich leichter als mit *QFP. Die Domäne von&lt;br /&gt;
AVR/PIC/i51. Für MSP430 gibt es günstige fertig bestückte DIP-Adapter hier im Shop (MSP430x2xx gibt es auch in 14-Pin DIP-Gehäuse). Z8e-Chips existieren ebenfalls in DIP, sind aber schlechter verfügbar.&lt;br /&gt;
&lt;br /&gt;
==Beschaltungsaufwand==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;8051, AVR, PIC, MSP430, R8C, ST7, Z8e&#039;&#039;&#039;: gering, i.d.R. sind Versionen mit integriertem Oszillator verfügbar, so dass man praktisch nur die Versorgungsspannung (nebst Abblockkondensator) braucht.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ARM&#039;&#039;&#039;: aufwendigere externe Takt- und Spannungserzeugung, manchmal 2 Betriebsspannungen benötigt; Tendenz aber fallend.&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/forum/read-1-185133.html#new Forum]&lt;br /&gt;
* [[8051]]&lt;br /&gt;
* [[ARM]]&lt;br /&gt;
* [[AVR]]&lt;br /&gt;
* [[MSP430]]&lt;br /&gt;
* [[PIC]]&lt;br /&gt;
* [[R8C]]&lt;br /&gt;
* [[ST7]]&lt;br /&gt;
* [[Z8]]&lt;br /&gt;
* [[Z8_encore!]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Mikrocontroller]]&lt;/div&gt;</summary>
		<author><name>213.61.222.21</name></author>
	</entry>
</feed>