{"id":86,"date":"2017-02-05T18:22:45","date_gmt":"2017-02-05T17:22:45","guid":{"rendered":"http:\/\/skunklog.de\/?p=86"},"modified":"2021-01-24T20:15:49","modified_gmt":"2021-01-24T19:15:49","slug":"blink-bitgeschubst","status":"publish","type":"post","link":"https:\/\/skunklog.de\/?p=86","title":{"rendered":"Blink &#8211; bitgeschubst"},"content":{"rendered":"<p>&#8222;Warum geschickt, wenns umst\u00e4ndlich geht?&#8220; Das hat einmal einer meiner Mathelehrer gesagt. Ich finde den Spruch noch heute gut aber wie immer kommt es dabei auf die Sichtweise an. Diese Frage kann man sich auch beim Beispielprogramm Blink stellen. Ob sinnvoll, oder nicht. Interessant allemal. <!--more weiter lesen--><\/p>\n<p>Vielleicht ist es auch nicht immer der Unterschied zwischen geschickt und umst\u00e4ndlich oder gut und schlecht. Sondern die Frage nach dem pers\u00f6nlichen Geschmack, wie man tickt oder ob man durch andere Wege nicht pl\u00f6tzlich auch die Chance hat, unerwartet Neues zu entdecken. Und deswegen ganz bewu\u00dft die Dinge anders macht, eben nicht am einfachsten bzw was andere daf\u00fcr halten, am einfachsten zu sein. Eben beschwerlicher. Zun\u00e4chst.<\/p>\n<p>Blink. Ein gelernter Programmierer bin ich nicht. Faszinierend fand ich es aber schon immer, sowas zu k\u00f6nnen, und ja &#8211; ich hatte einen C64 und ich bildete mir ein, darauf Maschinensprache zu lernen. Quasi das Grunzen unter den Programmiersprachen. Ich scheiterte. Da muss man ganz neu denken lernen und verstehen, wie ein Computer von innen funktioniert. Das wei\u00df ich bis heute nicht wirklich und es w\u00fcrde mir bei der t\u00e4glichen Arbeit an einem der modernen Nachkommen vom C64 ohnehin keinen Meter weiterhelfen. Ganz tief unten jedoch sind es noch immer irgendwelche Zust\u00e4nde von AN und AUS, EINS und NULL, die unerm\u00fcdlich ihre Arbeit tun. Soviel ist sicher und ich glaube, daran wird sich auch so bald nichts \u00e4ndern.<\/p>\n<p>Was aber kann das mit dem Blinken einer LED zu tun haben? Meine Antwort darauf ist: Weil man es so oder so machen kann. Oder so. Oder ganz anders.<\/p>\n<p>Die, wie ich finde, Hardcore-Variante von Blink ist die M\u00f6glichkeit, direkt bestimmte Bits in den sogenannten Registern zu setzen und damit eine LED blinken zu lassen. Nicht, dass man das daf\u00fcr unbedingt br\u00e4uchte. Aber ich bin fasziniert davon. Hat so seine ganz eigene \u00c4sthetik. Je nach Sichtweise.<\/p>\n<figure id=\"attachment_95\" aria-describedby=\"caption-attachment-95\" style=\"width: 290px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/skunklog.de\/wp-content\/uploads\/2017\/02\/blink_bitgeschubst.gif\"><img loading=\"lazy\" class=\"size-full wp-image-95\" src=\"https:\/\/skunklog.de\/wp-content\/uploads\/2017\/02\/blink_bitgeschubst.gif\" alt=\"\" width=\"290\" height=\"140\"><\/a><figcaption id=\"caption-attachment-95\" class=\"wp-caption-text\">Blink &#8211; bitgeschubst<\/figcaption><\/figure>\n<p>Zaubercode. Was passiert hier? Wie liest man das? Genau das habe ich mich selber schon oft gefragt. Einmal mehr ist etwas Hintergrundwissen gefragt. Aber wieviel davon? Ich denke, ein wenig sollte hier reichen um bereits eine T\u00fcr zu einer ganz anderen Welt aufzusto\u00dfen.<\/p>\n<p>Viele Angelegenheiten werden in einem Mikrocontroller in Registern organisiert. Dort ist eine Anzahl von Bits zusammengefasst, von denen jedes Bit ein AN\/AUS-Schalter f\u00fcr eine bestimmte Aufgabe darstellt. Ein Register hat einen Namen, den man im Programmcode wie eine Variable aufrufen kann. Zwei Register davon sind im gezeigten Blink-Code genannt:<\/p>\n<p><strong>DDRB<\/strong>: &#8222;Port B Data Direction Register&#8220;<br \/>\n<strong>PORTB<\/strong>: &#8222;Port B Data Register&#8220;<\/p>\n<p>Die Bits im <strong>DDRB<\/strong> sind daf\u00fcr zust\u00e4ndig, einen bestimmten Digital-Pin grunds\u00e4tzlich entweder als Ausgang (TRUE) oder als Eingang (FALSE) zu definieren. Sofern ein bestimmter Pin als Ausgang definiert wurde, legt das entsprechende Bit im Register <strong>PORTB<\/strong> dann fest, ob am Pin eine Spannung anliegt (TRUE) und damit z.B. eine LED betrieben werden kann, oder ob keine Spannung anliegt (FALSE), d.h. die LED w\u00e4re dann aus.<\/p>\n<p>Umgekehrt, also wenn im <strong>DDRB<\/strong> ein Pin als Eingang definiert ist (FALSE), kann gepr\u00fcft werden, ob von au\u00dfen ein bestimmter Spannungspegel anliegt. Das wird f\u00fcr andere Aufgaben ben\u00f6tigt, nicht jedoch f\u00fcr eine blinkende LED.<\/p>\n<p>Die beiden Register haben je 8 Bits und sind dem sogenannten Port B des Mikrocontrollers zugeordnet. Dieser Port B ist f\u00fcr 8 der insgesamt 28 Pins zust\u00e4ndig. In sofern: es gibt noch weitere Ports, n\u00e4mlich Port C und Port D. Ich habe keinen Schimmer, warum es keinen Port A gibt. Was nicht schlimm ist. Manche Pins werden f\u00fcr andere Dinge gebraucht, zum Beispiel um einen Quarz anzuschlie\u00dfen (siehe Pins 9\/10 bzw PB6\/PB7) und stehen <em>nicht<\/em> f\u00fcr den Anschlu\u00df etwa einer LED zur Verf\u00fcgung. Man kann nicht alles haben. Der Mikrocontroller beim Arduino ist \u00fcbrigens ein ATmega328. Das Kerlchen gibt es f\u00fcr ganz kleines Geld auch separat zu kaufen. Und ab da wird es dann f\u00fcr Selbstbauprojekte so richtig interessant. Das ist aber eine andere Geschichte&#8230;<\/p>\n<p>Im folgenden Bild ist zu sehen, welche Pins am Microcontroller zu welchem Register geh\u00f6ren und zu welchem Steckplatz am Arduino (UNO):<\/p>\n<figure id=\"attachment_129\" aria-describedby=\"caption-attachment-129\" style=\"width: 700px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/skunklog.de\/wp-content\/uploads\/2017\/02\/ATmega328_Ports.gif\"><img loading=\"lazy\" class=\"size-large wp-image-129\" src=\"https:\/\/skunklog.de\/wp-content\/uploads\/2017\/02\/ATmega328_Ports-700x505.gif\" alt=\"\" width=\"700\" height=\"505\" srcset=\"https:\/\/skunklog.de\/wp-content\/uploads\/2017\/02\/ATmega328_Ports-700x505.gif 700w, https:\/\/skunklog.de\/wp-content\/uploads\/2017\/02\/ATmega328_Ports-300x217.gif 300w, https:\/\/skunklog.de\/wp-content\/uploads\/2017\/02\/ATmega328_Ports-768x554.gif 768w, https:\/\/skunklog.de\/wp-content\/uploads\/2017\/02\/ATmega328_Ports-200x144.gif 200w, https:\/\/skunklog.de\/wp-content\/uploads\/2017\/02\/ATmega328_Ports-831x600.gif 831w\" sizes=\"(max-width: 700px) 100vw, 700px\" \/><\/a><figcaption id=\"caption-attachment-129\" class=\"wp-caption-text\">Ports am ATmega328<\/figcaption><\/figure>\n<p>Sicher gibt es gute Gr\u00fcnde, weshalb die dargestellte Zuordnung der Pins zu den drei Ports in dieser Form gew\u00e4hlt und festgelegt wurde. Ich denke, es hat mit der inneren Architektur zu tun. Verwirrend ist das nur auf den ersten Blick. Richtig konfus wird es erst, wenn noch die weiteren Nummerierungen und Aufgabenbezeichnungen der Pins hinzukommen. Was f\u00fcr den Moment jedoch \u00fcberfl\u00fcssig ist und einfach weggelassen wurde. Immerhin ist die Nummerierung der physikalischen (Metall-) Pins in einer strengen Reihenfolge von 1 bis 28 gehalten. Gez\u00e4hlt von oben links gegen den Uhrzeigersinn. Bemerkenswerterweise wird hier \u00fcbrigens nicht von 0 bis 27 gez\u00e4hlt.<\/p>\n<p>Also&#8230;die LED am Arduino-Pin9 (alias ATmega-Pin15) soll leuchten? Dann muss im Register <strong>DDRB<\/strong> das zweite Bit (was der Bitnummer 1 entspricht, da von 0 an gez\u00e4hlt wird) gesetzt sein, also auf &#8222;TRUE&#8220; bzw &#8222;1&#8220; stehen und das korrespondierende Bit im Register <strong>PORTB<\/strong> ebenfalls. Alles klar?<\/p>\n<figure id=\"attachment_138\" aria-describedby=\"caption-attachment-138\" style=\"width: 700px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/skunklog.de\/wp-content\/uploads\/2017\/02\/ATmega328_Ports_LED9.gif\"><img loading=\"lazy\" class=\"size-large wp-image-138\" src=\"https:\/\/skunklog.de\/wp-content\/uploads\/2017\/02\/ATmega328_Ports_LED9-700x322.gif\" alt=\"\" width=\"700\" height=\"322\" srcset=\"https:\/\/skunklog.de\/wp-content\/uploads\/2017\/02\/ATmega328_Ports_LED9-700x322.gif 700w, https:\/\/skunklog.de\/wp-content\/uploads\/2017\/02\/ATmega328_Ports_LED9-300x138.gif 300w, https:\/\/skunklog.de\/wp-content\/uploads\/2017\/02\/ATmega328_Ports_LED9-768x353.gif 768w, https:\/\/skunklog.de\/wp-content\/uploads\/2017\/02\/ATmega328_Ports_LED9-200x92.gif 200w, https:\/\/skunklog.de\/wp-content\/uploads\/2017\/02\/ATmega328_Ports_LED9-900x414.gif 900w\" sizes=\"(max-width: 700px) 100vw, 700px\" \/><\/a><figcaption id=\"caption-attachment-138\" class=\"wp-caption-text\">ATmega328, seine Ports und eine LED<\/figcaption><\/figure>\n<p>In Zaubercode verpackt sieht das vollst\u00e4ndige(!) Programm dann so aus:<\/p>\n<figure id=\"attachment_150\" aria-describedby=\"caption-attachment-150\" style=\"width: 207px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/skunklog.de\/wp-content\/uploads\/2017\/02\/LED_AN.gif\"><img loading=\"lazy\" class=\"size-full wp-image-150\" src=\"https:\/\/skunklog.de\/wp-content\/uploads\/2017\/02\/LED_AN.gif\" alt=\"\" width=\"207\" height=\"103\"><\/a><figcaption id=\"caption-attachment-150\" class=\"wp-caption-text\">LED einschalten<\/figcaption><\/figure>\n<p>Die LED an Pin 9 wird schon im Setup eingeschaltet. Und das wars dann auch schon, denn im Loop bleibt nichts zu tun. Was etwas langweilig ist. Die LED leuchtet. Sofern sie nicht kaputt ist. Und richtig angeschlossen ist (Pin9 an Widerstand die eine Seite, Widerstand die andere Seite ans lange Beinchen (+) der LED, kurzes Beinchen der LED an GND). F\u00fcr eine rote 5mm Standard LED mag ein Widerstand von 330 Ohm keine schlechte Wahl sein. Es gilt, den Strom zu begrenzen.<\/p>\n<p>Spannend ist jetzt die Frage, wie man die Geschichte zum Blinken bringt. Ganz oben stand der Code bereits. Das wunderbare daran ist, dass man mit den Bits verschiedene Operationen durchf\u00fchren kann. Zwei bestimmte Operationen sind hier von besonderem Interesse: bitweises OR und bitweises XOR.<\/p>\n<figure id=\"attachment_171\" aria-describedby=\"caption-attachment-171\" style=\"width: 351px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/skunklog.de\/wp-content\/uploads\/2017\/02\/bitwise_OR_XOR.gif\"><img loading=\"lazy\" class=\"size-full wp-image-171\" src=\"https:\/\/skunklog.de\/wp-content\/uploads\/2017\/02\/bitwise_OR_XOR.gif\" alt=\"\" width=\"351\" height=\"116\"><\/a><figcaption id=\"caption-attachment-171\" class=\"wp-caption-text\">bitweises OR und XOR<\/figcaption><\/figure>\n<p>Gesehen hat man sowas ja sicher schon irgendwo und oft. Mein Problem dabei ist, ich kann es mir nicht merken. Deswegen ist es gut, dass solche Verkn\u00fcpfungsregeln aufgeschrieben werden. Oder man kann es in Worte fassen und versuchen, es sich auf diese Weise zu behalten. Kommt halt darauf an, wie man so tickt:<\/p>\n<p><strong>OR<\/strong>: nur wenn beide zu verkn\u00fcpfende Bits FALSE sind, bleibt es bei FALSE. Ansonsten kommt immer TRUE dabei heraus.<br \/>\n<strong>XOR<\/strong>: sofern beide zu verkn\u00fcpfende Werte gleich sind kommt FALSE dabei heraus. Sind sie unterschiedlich, ist das Ergebnis TRUE.<\/p>\n<p>Damit kann man nun loslegen. Zun\u00e4chst w\u00e4re sicherzustellen, dass das Bit f\u00fcr Pin 9 (am Arduino) auf TRUE gesetzt wird. Grunds\u00e4tzlich k\u00f6nnte es sein, dass die anderen Bits aus bestimmten Gr\u00fcnden nicht auf FALSE stehen und dass dies auch so bleiben soll. M\u00f6glicherweise weil neben dem Blinken noch andere Dinge geschehen sollen und entsprechend codiert sind. In diesem Fall w\u00e4re es ungeschickt, das gesamte Register einfach mit<\/p>\n<p><code>DDRB = B00000010;<\/code><\/p>\n<p>einzustellen, wie wir das oben gemacht haben. Der Trick ist nun, bitweise eine OR-Verkn\u00fcpfung zwischen dem wie auch immer zuf\u00e4llig gerade gef\u00fcllten Register und den (konstanten) 8 Bits [00000010] durchzuf\u00fchren. Mit dem folgenden Bild wird das klar, wie ich denke:<\/p>\n<figure id=\"attachment_177\" aria-describedby=\"caption-attachment-177\" style=\"width: 700px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/skunklog.de\/wp-content\/uploads\/2017\/02\/bitwise_OR_XOR_DDRB.gif\"><img loading=\"lazy\" class=\"size-large wp-image-177\" src=\"https:\/\/skunklog.de\/wp-content\/uploads\/2017\/02\/bitwise_OR_XOR_DDRB-700x196.gif\" alt=\"\" width=\"700\" height=\"196\" srcset=\"https:\/\/skunklog.de\/wp-content\/uploads\/2017\/02\/bitwise_OR_XOR_DDRB-700x196.gif 700w, https:\/\/skunklog.de\/wp-content\/uploads\/2017\/02\/bitwise_OR_XOR_DDRB-300x84.gif 300w, https:\/\/skunklog.de\/wp-content\/uploads\/2017\/02\/bitwise_OR_XOR_DDRB-768x215.gif 768w, https:\/\/skunklog.de\/wp-content\/uploads\/2017\/02\/bitwise_OR_XOR_DDRB-200x56.gif 200w\" sizes=\"(max-width: 700px) 100vw, 700px\" \/><\/a><figcaption id=\"caption-attachment-177\" class=\"wp-caption-text\">bitweise OR<\/figcaption><\/figure>\n<p>Wie man leicht sieht, wird <em>sichergestellt<\/em>, dass an der gew\u00fcnschten Stelle das Bit auf TRUE gesetzt wird (die rote Eins). Alles andere bleibt, wie es ist. Cool! Im Code wird jedoch nicht das &#8222;OR&#8220; hingeschrieben, sondern ein senkrechter Strich &#8222;|&#8220;. Im Code wird den Bits, mit denen &#8222;gerechnet&#8220; wird einfach ein B vorangestellt.<\/p>\n<p><code>DDRB = DDRB | B00000010;<\/code><\/p>\n<p>Und jetzt das Blinken. Was muss gemacht werden? In jedem Loop muss das Bit an der zweiten Stelle im Register <strong>PORTB<\/strong> von dem einen auf den anderen Zustand gesetzt werden. Es macht die Sache etwas leichter, dass es nur zwei Zust\u00e4nde gibt. Hin &#8211; und herschalten. Toggeln. Sch\u00f6nes Wort.<\/p>\n<figure id=\"attachment_189\" aria-describedby=\"caption-attachment-189\" style=\"width: 700px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/skunklog.de\/wp-content\/uploads\/2017\/02\/LED_XOR_AN_AUS.gif\"><img loading=\"lazy\" src=\"https:\/\/skunklog.de\/wp-content\/uploads\/2017\/02\/LED_XOR_AN_AUS-700x176.gif\" alt=\"\" class=\"size-large wp-image-189\" width=\"700\" height=\"176\" srcset=\"https:\/\/skunklog.de\/wp-content\/uploads\/2017\/02\/LED_XOR_AN_AUS-700x176.gif 700w, https:\/\/skunklog.de\/wp-content\/uploads\/2017\/02\/LED_XOR_AN_AUS-300x75.gif 300w, https:\/\/skunklog.de\/wp-content\/uploads\/2017\/02\/LED_XOR_AN_AUS-768x193.gif 768w, https:\/\/skunklog.de\/wp-content\/uploads\/2017\/02\/LED_XOR_AN_AUS-200x50.gif 200w, https:\/\/skunklog.de\/wp-content\/uploads\/2017\/02\/LED_XOR_AN_AUS-900x226.gif 900w\" sizes=\"(max-width: 700px) 100vw, 700px\" \/><\/a><figcaption id=\"caption-attachment-189\" class=\"wp-caption-text\">der Trick mit XOR<\/figcaption><\/figure>\n<p>Im Code wird f\u00fcr das &#8222;XOR&#8220; dann ein &#8222;^&#8220; geschrieben. Was schlie\u00dflich so aussieht:<br \/>\n<code>PORTB = PORTB ^ B00000010;<\/code><\/p>\n<p>Das muss im Loop stehen, so dass dies immer und immer wieder gemacht wird. Und weil der Microcontroller das ziemlich schnell umschaltet, muss er quasi k\u00fcnstlich eingebremst werden und darf solange nichts anderes machen als Millisekunden z\u00e4hlen. Andernfalls w\u00fcrden wir nur eine leuchtende LED sehen, da es unseren Augen nicht m\u00f6glich ist, die unterschiedlichen Zust\u00e4nde von AN und AUS sauber zu unterscheiden. Und w\u00e4hrend die Milliselkunden also gez\u00e4hlt werden, bleibt der zuvor eingestelte Zustand eben so lange erhalten. Es blinkt und zwar mit mit gleichlangen Phasen AN und AUS.<br \/>\n<code><br \/>\nvoid setup() {<br \/>\nDDRB = DDRB | B00000010;<br \/>\n}<br \/>\nvoid loop(){<br \/>\nPORTB = PORTB ^ B00000010;<br \/>\ndelay(1000);<br \/>\n}<br \/>\n<\/code><\/p>\n<p>Geschafft! Die LED blinkt wieder im Sekundentakt. Geschickt oder umst\u00e4ndlich? Kommt auf die Sichtweise an. Unn\u00f6tig zu erw\u00e4hnen, dass mein Mathelehrer mich gemeint hatte&#8230;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>&#8222;Warum geschickt, wenns umst\u00e4ndlich geht?&#8220; Das hat einmal einer meiner Mathelehrer gesagt. Ich finde den Spruch noch heute gut aber wie immer kommt es dabei auf die Sichtweise an. Diese Frage kann man sich auch beim Beispielprogramm Blink stellen. Ob sinnvoll, oder nicht. Interessant allemal.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[10],"tags":[11,17,30,29,21,19,20,18,12,23,24,25,4,26,27,28,22],"_links":{"self":[{"href":"https:\/\/skunklog.de\/index.php?rest_route=\/wp\/v2\/posts\/86"}],"collection":[{"href":"https:\/\/skunklog.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/skunklog.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/skunklog.de\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/skunklog.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=86"}],"version-history":[{"count":102,"href":"https:\/\/skunklog.de\/index.php?rest_route=\/wp\/v2\/posts\/86\/revisions"}],"predecessor-version":[{"id":964,"href":"https:\/\/skunklog.de\/index.php?rest_route=\/wp\/v2\/posts\/86\/revisions\/964"}],"wp:attachment":[{"href":"https:\/\/skunklog.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=86"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/skunklog.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=86"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/skunklog.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=86"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}