Heizölverbrauch - ein Mikroprozessor-Projekt - Projekte\nDie Erfassung und Auswertung des Verbrauchs\neines Heizölbrenners mit einem\nprogrammiert in Bascom,\nSchenefeld, Februar 2012\nInformationen für Interessierte.................................................................................................... 4\nDie Grundidee............................................................................................................................. 5\nSoftware-Installation der Testumgebung.................................................................................... 8\nInstallation von Bascom-AVR................................................................................................. 8\nInstallation des USB-Gerätetreibers CP210x...........................................................................8\nInstallation des myAVR ProgTool...........................................................................................8\nInstallation der Hardware............................................................................................................ 9\nBauteile tauschen..................................................................................................................... 9\nDie Verdrahtung der Komponenten.........................................................................................9\nInbetriebnahme der Testumgebung........................................................................................... 12\nDie Einstellung der Optionen für die IDE............................................................................. 12\nDas Kompilieren des Testprogramms....................................................................................13\nDas Brennen des Testprogramms.......................................................................................... 14\nDie Inbetriebnahme des Testprogramms............................................................................... 15\nDas erste eigene Bascom-Programm: Eine LED „erblinkt“ das Licht der Welt....................... 18\nProgrammunterbrechung auf Tastendruck: Externer Interrupt................................................. 21\nDialog mit dem PC via Bascom-Terminal Emulator................................................................ 24\nProgrammierung des I2C/Serial Display LCD03......................................................................26\nEine Uhr, die nicht stehen bleibt: Programmierung der I2C-Echtzeituhr DS1307.................. 30\nEin Sekunden-Interrupt, abgeleitet vom DS1307..................................................................... 34\nEin Speicher, der nicht vergisst: Programmierung des I2C-Eeprom AT24Cx......................... 35\nAnschluss der Prellunterdrückung via Pin Change Interrupt.................................................... 36\nDas Projekt „Heizölverbrauch“, die End-Version des Programms...........................................44\nEinsatz der Prellunterdrückung mit Timer 555 ....................................................................44\nAnhang 1 ................................................................................................................................. 46\nEine Verdrahtungshilfe für „wire wrap“................................................................................46\nAnhang 2................................................................................................................................... 54\nEine Auswertung der gespeicherten Ölverbräuche und separat erfassten\nAußentemperaturen mit dem Excel Diagramm-Manager.....................................................54\nBei dem vorliegenden Artikel handelt es sich um um die Zusammenfassung einer Dokumentation, die bei der Einarbeitung des Verfassers in das Thema „AVR-Mikroprozessoren“ entstanden ist. Dabei war der konkrete Anwendungs-Hintergrund zunächst eigentlich nebensächlich. Es wurde schließlich die Anwendung „Erfassung und Auswertung des Heizölverbrauchs“\ngewählt, weil diese technisch für jedermann leicht überschaubar ist. Schließlich handelt es\nsich lediglich um die Erfassung der Ein- und Ausschaltzeiten eines Ölbrenners. Hierfür bedarf\nes auf der Eingabeseite nur eines Kontaktes, dessen Schließzeiten im Mikroprozessor erfasst\nwerden müssen. Auf der Ausgangsseite genügt ein Display, um aktuelle Daten wie Betriebsstunden und Tankstand anzuzeigen.\nAndererseits bietet diese kleine Anwendung aber genügend Möglichkeiten, ein recht breites\nSpektrum der verschiedenen Komponenten eines Mikroprozessor-Systems mit einzubeziehen.\nSo behandelt dieser Artikel neben der reinen Mikroprozessor-Programmierung auch die Praxis der Interrupt-Technik, die Kommunikation mit dem PC als Host, die Erfassung von Datum\nund Uhrzeit, die Speicherung von Erfassungsdaten auf nicht-volatilem Speicher sowie die\nDarstellung von Ergebnissen auf einem LCD mit Hilfe von TWI-Komponenten, sowie die\nAnbindung von Funk-Komponenten an das System.\nIn der Praxis der Mikroprozessor-Anwendungen, insbesondere bei der Erfassung von Messwerten aus verschiedenen Quellen, wird man in vielen Fällen diese Daten zu einer zentralen\nStelle übertragen müssen, um sie dort auszuwerten. Dies setzt einerseits voraus, dass eine\nMöglichkeit der Datenübertragung zum PC auch im Mikroprozessor besteht, und andererseits,\ndass auf dem PC ein Auswerteprogramm zur Verfügung steht. In diesem Artikel wird deshalb\nauf eine der möglichen Verbindungen zwischen Mikroprozessor und PC eingegangen, und das\nist auf der Mikroprozessor-Seite der so genannte Bascom-Terminal-Emulator. Man kann mit\ndessen Log-Funktion auf recht bequeme Weise eine Import-Datei für „MS Excel“ erzeugen.\nDamit können auf dem Mikroprozessor erfasste Daten dem „MS Excel“ zugeführt werden und\ndort u.U. auch unter Zuhilfenahme von „VBA für Excel“ ausgewertet werden.\nEntsprechend den zu behandelnden Komponenten ist dieser Artikel in mehrere Kapitel aufgeteilt. Jedes Kapitel beinhaltet jeweils eine in Betrieb zu nehmende Komponente und ein dazu\ngehöriges Programmbeispiel. Dabei wird mit einfachen Beispielen mit niedrigem Schwierigkeitsgrad begonnen. Mit jeder weiteren Komponente steigert sich dann der Grad der Schwierigkeit bzw. der Komplexität. Zum Schluss werden dann die einzelnen Komponentenunterstützungen zusammengefasst, erweitert, und in einer Gesamtanwendung „Erfassung des\nDieser Artikel wendet sich vornehmlich an Lernende und Studierende, geschrieben mit der\nAbsicht, gemachte Erfahrungen weiterzugeben. Eine kommerzielle Verwendung bedarf meiner Zustimmung.\nDieser Artikel setzt einige Grundkenntnisse der Mikroprozessor-Technik sowie der Programmierung voraus. Da der Artikel auf der Anwendung von AVR-Mikroprozessoren basiert, wäre\nz.B. das Studium von Dipl.-Ing. Toralf Riedel und Dipl.-Ing. Päd. Alexander Huwaldt, „myAVR Lehrbuch Mikrocontrollerprogrammierung“ als Voraussetzung wünschenswert, siehe www.myAVR.de.\nDa als Programmiersprache das Bascom verwendet wird, ist eine gewisse Grundkenntnis eines der Basic-Dialekte wünschenswert. Man kann sich aber anhand der vielen kleinen Programm-Beispiele ganz gut mit Hilfe dieses Artikels in dieses Thema einarbeiten. Eine systematische Einführung für den Anfänger bietet Barry de Graaff, „Lehr- und Experimentierbaukasten (EDB)“, siehe www.mcselec.com.\nNaturgemäß enthält die Materie eine Reihe von Kniffeligkeiten und Fallstricken, und ich habe\nmich bemüht, dafür Lösungen zu finden und diese hier zu dokumentieren. Warum sollte jeder\nvon uns das Rad nochmals von neuem erfinden? Ich kann aber nicht ausschließen, dass mir\nselbst hierbei noch Fehler unterlaufen sind, und ich freue mich daher über jeden Hinweis, falls\njemand auf solche Fehler stößt.\nWas die im Artikel erwähnten zehn Beispielprogramme betrifft, so bin ich gern bereit, diese\nzur Verfügung zu stellen, allerdings gegen eine Schutzgebühr, deren Höhe ich derzeit noch\nnicht endgültig festgelegt habe. Das wird von der Frage abhängen, ob ich hierfür ein Gewerbe\nanmelden muss. Insofern kann ich zu diesem Zeitpunkt hierzu noch keine Aussage machen.\nDie Kosten für diese Programme werden ca. 20% der Kosten betragen, die Ihnen die die Anschaffung der Komponenten laut Beschaffungsliste entstehen. Falls Sie an den Programmen\ninteressiert sind, wäre es hilfreich, wenn Sie mit mir Kontakt aufnehmen. Eine Kenntnis der\nMenge der Anfragen wäre hilfreich bei der Entscheidung, ob ein Gewerbe angemeldet werden\nmuss. Wenden Sie sich bitte unter Angabe Ihres Namens und Ihrer Adresse an:\nFalls Sie an dem im Kapitel „Inbetriebnahme der Testumgebung“ erwähnten Programm „Programm_1_Erste_Inbetriebnahme“ interessiert sind, stelle ich dieses jedoch kostenlos als\nQuellcode auf Anfrage zur Verfügung. Sie können dieses Programm dann studieren und ausprobieren, die Testumgebung in Betrieb nehmen und dann entscheiden, ob Sie weitermachen\nZur Erfassung des Heizölverbrauchs wird der Einschaltzustand des Heizölbrenners dem\nMikroprozessorsystem mitgeteilt, hier symbolisch dargestellt durch einen „potentialfreien\nJede Schließzeit dieses Kontaktes wird im Mikroprozessorsystem nach Datum, Uhrzeit und\nSchließdauer des Kontaktes erfasst und gespeichert.\nDie Schließzeiten werden im Mikroprozessor zu einer Gesamt-Betriebsstundenzahl aufsummiert. Über einen konstanten Umrechnungsfaktor wird der zugehörige Heizölverbrauch errechnet.\nHieraus wird schließlich der aktuelle Tankstand in Litern errechnet.\nDer Ein/Ausschaltzustand, die aktuelle Betriebsstundenzahl und der aktuelle Tankstand\nwerden kontinuierlich auf dem LCD dargestellt.\nVon Zeit zu Zeit wird das Mikroprozessorsystem von der Heizunganlage gelöst und via\nUSB an einen PC angeschlossen. Die gespeicherten Daten können nun auf den PC übertragen werden.\nHier können die Daten nun mit einem PC-Programm ausgewertet werden, z.B. mit MS Excel.\nFerner können in einem Dialog zwischen PC und Mikroprozessorsystem verschiedene Einstellungen vorgenommen werden, z.B. das Einstellen von Datum und Uhrzeit der Echtzeituhr,\ndas Einstellen der Betriebsstunden auf einen Startwert und das Einstellen des Tankstandes auf\nDanach kann das Mikroprozessorsystem ohne weiteres wieder an die Heizungsanlage angeschlossen werden. Das System ist restartfest gegenüber Stromausfällen.\n1 Stück BASCOM-AVR Compiler\n1 Stück myAVR Board MK2 USB, bestückt\n1 Stück myTWI Add-On EEPROM\n1 Stück myTWI Add-On Echtzeituhr\n1 Stück ATmega 168-20PU Mikroprozessor\n1 Stück Quarz 20MHz\nKomponenten für die Prellunterdrückung mit Timer 555\n1 Stück RE224-LF Laborkarte Roth, Europaformat\n1 Stück USB Kabeladapter Bulgin, 5-polig, USB-A\n1 Stück Stiftleiste Bulgin, 5-polig, für USB-A, abgewinkelt\n2 Stück NE556, Timer, DIP14\n2 Stück IC Sockel DIP14, wire wrap\n1 Stück IC Sockel, 25-polig, wire wrap\n1 Kondensator MKS, 10 nF\n1 Kondensator MKS, 100 nF\n1 Kondensator MKS, 1 uF\n1 Widerstand 1 MOhm\nEvtl. Wire wrap Verdrahtungsmaterial und Werkzeug\n1 Stück LCD-Modul LCD03\n1 Stück 24C16 I²C Serial EEPROM 16k\n1 Stück Widerstand 10k\nSchaltdraht ,isoliert, Innen-Ø 0,5 mm, verschiedene Farben, siehe Titelbild\n1 Stück Mousepad, als Unterlage für das Board\nSoftware-Installation der Testumgebung\nInstallation von Bascom-AVR\nFür die Kompilation von Bascom-Programmen stellt MCS-Electronics zwei Versionen zur\neine kostenfreie Demo-Version mit der Begrenzung von max. 4k Bascom Quell-Code,\neine kostenpflichtige Voll-Version.\nDa der in diesem Projekt vorgestellte Quell-Code 4k übersteigen wird, benötigen Sie die kostenpflichtige Voll-Version.\nDie Installation der gelieferten CD ist selbsterklärend. Folgen Sie den vorgegebenen Installationsschritten bis das Produkt vollständig installiert ist.\nInstallation des USB-Gerätetreibers CP210x\nDie Installation dieses Gerätetreibers erfolgt von der mit dem myAVR Board MK2 USB mitgelieferten CD. Zu beachten ist, dass die Installation in zwei Schritten erfolgt, was für Ungeübte verwirrend sein mag. Im Zweifel schauen Sie sich bitte die „Kurzdokumentation zur Installation des Gerätetreibers CP210x“ (PDF-Dokument) an. Sie findet sich auf der mitgelieferten CD auf ..\_Fremd\_myAVR-Board_USB-Treiber.\nNach erfolgter Installation sollten Sie in „Arbeitsplatz→ Systemsteuerung → System →\nHardware → Gerätemanager“ unter „Anschlüsse COM und LPT“ die Eintragung „CP210x\nUSB to UART Bridge Controller (COMx)“ finden. COMx ist hier die Nummer des COM-Anschlusses, die Ihnen die Installation automatisch zugewiesen hat. Es sei schon hier darauf verwiesen, dass die Nummer dieses COM-Anschlusses später bei der Inbetriebnahme des Bascom-Compilers mit den „Bascom-AVR IDE Optionen“ übereinstimmen muss.\nInstallation des myAVR ProgTool\nDieses Programm wird u.a. zum Brennen der so genannten „Fuses“ auf dem ATmega168 benötigt. Fuses sind letztlich Konfigurationseinstellungen, die dem Mikroprozessor bestimmte\nBetriebsweisen mitteilen. Das Tool „myAVR ProgTool“ findet man im Download-Bereich\nvon www.myAVR.de unter http://shop.myavr.de/index.php?sp=download.sp.php. Installieren\nSie dieses Tool auf Ihrem Rechner.\nHinweis : Für jedes Board bzw. jede Karte gilt die Orientierung nach der Ausrichtung der\nKartenbeschriftung. In diesem Sinne ist „oben“ die Kartenkante oberhalb der Kartenbeschriftung, in diesem Sinne ergibt sich „unten“, „links“ und „rechts“.\nFolgende ICs bzw. Komponenten müssen ausgetauscht bzw. ergänzt werden:\n1. Auf myAVR Board Atmega 8L rausnehmen, ATmega168 einsetzen (Markierung zeigt\n2. Auf myAVR Board 3,6 MHz-Quarz auslöten, 20 MHz-Quarz einlöten (Orientierung egal).\n3. Auf myTWI Eeprom 24C02 durch 24C16 ersetzen (Markierung zeigt nach oben).\n4. Auf myTWI Echtzeituhr Pullup-Widerstand 10k von SQW/OUT nach +5V einlöten (Widerstand zwischen zweitem Pin von oben rechts nach + , siehe Bild).\nDie Verdrahtung der Komponenten\nStecken Sie die Komponenten wie auf dem Titelbild gezeigt zusammen und platzieren Sie sie\nauf dem Mousepad.\nSie müssen nun folgende Verdrahtungen vornehmen (orientieren Sie sich bitte am Titelbild):\n1. Verbindung (blau) zwischen myTWI Echtzeituhr SQW/OUT und myAVR Board Port D2.\n2. Verbindung (gelb) zwischen Taster 1 und myAVR Board Port D3.\n3. Verbindung (grün) zwischen LED-Grün und myAVR Board Port D4.\n4. Verbindung (rot) zwischen LCD03 4-pol. Steckverbindung ganz oben (+5V) und HI auf\n5. Verbindung (schwarz) zwischen LCD03 4-pol. Steckverbindung ganz unten (0V) und LO\nauf myAVR Board.\n6. Verbindung (blau) zwischen LCD03 4-pol. Steckverbindung zweite von oben (SDA) und\nmyAVR Board Port C4.\n7. Verbindung (grau) zwischen LCD03 4-pol. Steckverbindung dritte von obem (SCL) und\nmyAVR Board Port C5.\n8. Verbindung (rot) zwischen Prellunterdrückung +5V und HI auf myAVR Board.\n9. Verbindung (schwarz) zwischen Prellunterdrückung 0V und LO auf myAVR Board.\n10.Verbindung (grün) zwischen Prellunterdrückung Output und myAVR Board Port B3\nFolgende Jumper müssen entsprechend gesetzt werden:\n1. Am Display LCD03 Jumper auf der Lötseite entfernen.\n2. Auf myTWI Eeprom drei Adress-Jumper entfernen (für 24C16).\n3. Auf myTWI Eeprom zwei Jumper für Pullup SDA, SCL entfernen (die Jumper an der\nmyTWT Echtzeituhr bleiben drin).\nVorab sei hier wegen schlechter Erfahrungen darauf hingewiesen, dass die „Fuse-Brennerei“\neine heikle Sache werden kann, wenn man nicht genau weiß, was das Ändern von Fuses genau bedeutet und welche Auswirkungen die Änderungen auf andere Parameter haben können.\nAber das ist nun einmal die typische Situation eines Anfängers, dass einem die vielfältigen\nAbhängigkeiten und gegenseitigen Bedingtheiten noch nicht klar sind. Erschwerend kommt\nhinzu, dass aufgrund der Vielzahl der Kombinationsmöglichkeiten verschiedener Produkte\nkaum zuverlässige Literatur zu finden ist, die dieses komplexe Thema verständlich behandelt.\nDeshalb sei hier der Rat gegeben, hier zunächst einmal „ausgetretene Pfade“ zu benutzen, bevor man eigene Wege geht. Der folgende Weg hat in der Praxis zum Erfolg geführt, analoges\ngilt auch für die korrespondierenden Parameter im Kapitel „Inbetriebnahme der Testumgebung“.\n1. Schließen Sie das myAVR Board via USB an dem zugewiesenen Port an Ihren Rechner an.\n2. Stellen Sie die DIP-Schalter des mySmartUSB MK2\nProgrammers auf den Modus „Programmierung“, wie\nim Bild dargestellt. (Schalter 4, 3, 2 oben, Schalter 1 unten). Es sollte jetzt die rote LED auf dem Programmer\n3. Starten Sie das myAVR ProgTool.\n4. Wählen Sie unter „Hardware“ das myAVR Board MK2 USB.\n5. Stellen Sie als Controller ATmega168 ein.\n6. Stellen Sie bei „myAVR Board MK2 USB“ Ihren entsprechenden COMx ein, führen Sie\nden Test durch.\n7. Stellen Sie auf „Brennen → Fuses brennen → Low“ ein.\n8. Stellen Sie „Ext Full Swing Osc. PWRDWN/RESET 16k CK/14 CK + 65 ms“\nund „Divide clock by 8 internally“ ein.\n9. Klicken Sie auf „Jetzt schreiben“. Zum Schreiben sollten jetzt die LEDs auf dem USBProgrammer flackern.\n10.Überprüfen Sie das Ergebnis mit „Hardware auslesen“.\nJetzt sollte Ihr ATmega168 den geforderten Umgebungsbedingungen angepasst sein.\nÜbrigens: Fuses vergisst man leicht. Falls Sie jemals einen neuen ATmega168 einsetzen, vergessen Sie bitte nicht, ihn entsprechend zu brennen.\nInbetriebnahme der Testumgebung\nDie Einstellung der Optionen für die IDE\nUnter „Integrated Development Environment“ (IDE) wird die Gesamtheit aller Funktionen\ndes Bascom-Compilers von MCS Electronics verstanden, die zum Editieren, Kompilieren,\nBrennen und Testen der selbst entwickelten Programme zur Verfügung stehen. Dazu zählt\nauch die Möglichkeit einer Simulation des Programmablaufs (ohne Mikroprozessor). Einzelheiten hierzu können z.B. dem Buch Marius Meissner, „BASCOM-AVR IDE – Entwicklungsumgebung“ entnommen werden. Siehe http://www.marius-meissner.de/DE/Buch/IDEBASCOM.htm.\nFür die hier zu diskutierende Inbetriebnahme dieser Entwicklungsumgebung mit dem myAVR\nBoard USB 2.0 und dem USB-Gerätetreiber CP210x beschränken wir uns hier auf die hierzu\n1. Die Festlegung des Programmer-Typs\nNachdem Sie den BascomAVR Compiler aufgerufen\nhaben, wählen Sie „Options\n→ Programmer“. Stellen Sie\nhier sicher, dass „AVR ISP\nProgrammer“ ausgewählt ist\nund das unter „COM Port“\ndiejenige Zahl eingetragen\nist, die Ihnen bei der Installation des des USB-Gerätetreibers CP210x zugewiesen\nworden ist. Als Übertragungsgeschwindigkeit tragen Sie bitte 19200 Baud\n2. Die Festlegung der Communication-Parameter\nHier ist wie im vorigen\nPunkt der zugewiesene\nCOM Port einzutragen. Die\nrestlichen Parameter sind\nwie in der Abbildung einzutragen.\nDamit ist die notwendige\nAnpassung des IDE bereits\nerledigt. Sie können die restlichen, hier nicht erwähnten\nOptionen nochmals durchblättern und, falls abweichend, die Baud-Eintragungen auf 19200 setzen.\n3. Die Festlegung der Environment-Parameter\nBei den Editor-Parametern\nwird hier „Line numbers“\nempfohlen. Zwar ist die\nfortlaufende Zeilennummerierung im Quellprogramm\nsie kann aber beim Auffinden von Fehlern, die der\nCompiler ausgewiesen hat,\nDas Kompilieren des Testprogramms\nZum Kompilieren öffnen Sie das Programm nun über „File → Open“. Obwohl die Einzelheiten des Quellcodes in den weiteren Kapiteln noch diskutiert werden, sollten Sie sich vielleicht\nan dieser Stelle schon etwas damit beschäftigen, dies vor allem auch deshalb, weil dieser\nQuellcode gewissermaßen die Keimzelle der gesamten weiteren Programmierung darstellt.\nAlle Erweiterungen, die zu diesem Projekt gehören, werden in diesen Quellcode eingebaut\nWenn Sie nun auf „Compile\ncurrent file (F7)“ drücken,\nsollte das hier dargestellte\nBild erscheinen. Wie Sie an\nden Fußzeilen sehen, enthält\ndas Programm zwei Fehler.\nDiese Fehler sind selbstverständlich absichtlich eingebaut, um Ihnen einen kleinen\nEinblick zu geben, wie man\nFehler auffindet und korrigiert.\nZunächst ist der Fehler „StoreBit Error“ zugegebenerweise nicht sehr aussagekräftig.\nNun, mit dieser Problematik werden Sie zurande kommen müssen, und es geht hier um das\nSammeln von Erfahrungen. Wenn Sie einen Doppelklick auf eine der Fehlerzeilen machen,\nwird die fehlerhafte Zeile rot unterlegt dargestellt. In diesem Falle handelt es sich offenbar um\neinen Ausgabebefehl auf Portd.4, und zwar in beiden Fehlerfällen.\nWas könnte hier falsch sein ? Nun, ich will Sie hier nicht zu lange auf die Folter spannen: der\nAusdruck „Hi“ ist kein Bascom-Schlüsselwort und muss deswegen vor seinem Gebrauch im\nProgramm mit der Anweisung Const definiert werden. Solche Fehler unterlaufen einem Programmierer häufig mal, wenn er während der Programmierung eine neue Konstante oder Variable einführt und vergisst, diese im Definitionsteil des Programms zu deklarieren.\nWenn Sie nun in den Definitionsteil des Programms gehen, dann werden Sie in der Zeile 103\ndiese fehlende Konstante finden, die aber hier künstlich zur Erzeugung dieses Fehlers „auskommentiert“ worden ist. Entfernen Sie einfach das Kommentarzeichen, und das Programm\nwird jetzt fehlerfrei kompiliert werden.\nDas Brennen des Testprogramms\nBevor Sie mit dem Brennen beginnen, bringen Sie zunächst\ndie DIP-Schalter auf dem Programmer in die im Bild gezeigte Stellung. Die rote LED auf dem Programmer sollte\njetzt brennen. Starten Sie nun den Bascom-AVR Compiler\nund laden Sie das zu brennende „Programm_1_Erste_Inbetriebnahme“ mit „File → Open“. Klicken Sie nun auf „Run\nProgrammer (F4) → Program“. Der Brennvorgang sollte\njetzt starten. Falls die Nachricht „Com Port x not available“ erscheint, sind entweder die DIPSchalter auf dem Programmer nicht richtig eingestellt, das USB-Kabel nicht richtig eingesteckt oder die „Options“ für den Programmer nicht richtig gesetzt. Prüfen Sie aber in diesem\nFalle zunächst über „Arbeitsplatz → Systemsteuerung → System → Hardware → Gerätemanager“, ob unter der Rubrik „Anschlüsse COM und LPT“ der CP210x USB to UART Bridge\nController (COM x) aktiviert ist. Der dort genannte COM Port x sollte mit den Programmer14\nOptionen des Bascom-Compilers übereinstimmen. Wenn hier Übereinstimmung herrscht,\nsollte die Verbindung hergestellt sein. Im Zweifel ziehen Sie nochmals den USB-Stecker ab\nund stecken Sie ihn wieder auf. Die Verbindung sollte dann erneut aktiviert werden. An den\nFortschrittsbalken auf dem Monitor und dem Flackern der grünen LED auf dem Programmer\nkönnen Sie den Fortschritt des Brennens erkennen.\nNach dem erfolgreichen Brennen wird der Mikroprozessor automatisch gestartet.\nDie Inbetriebnahme des Testprogramms\nHinweis: Bitte schließen Sie bei dieser Inbetriebnahme keine externe Stromversorgung an das\nBoard. In dieser Betriebsweise wird das Board über das USB-Kabel mit Strom versorgt.\nZur Inbetriebnahme des Testprogramms ist es erforderlich,\ndass die Datenverbindung zum Terminal-Emulator aktiviert\nwird. Hierzu ist der DIP-Schalter 4 zunächst nach unten zu\nschieben, was die Stromversorgung via USB abschaltet.\nDann ist der DIP-Schalter 2 ebenfalls nach unten zu bewegen. Der Programmer steht nun auf „Datenverkehr“. Nun\nkönnen Sie den DIP-Schalter 4 wie im Bild gezeigt wieder\nnach oben bewegen, und der Mikroprozessor ist wieder eingeschaltet.\nAuf dem LCD in Zeile 1 bis Zeile 3 sollte jetzt eine Start-Nachricht zu sehen sein und die grüne LED auf dem Board sollte im Sekundentakt blinken. Hiermit wäre der Start des Testprogramms jetzt erfolgreich vollzogen.\nSie können jetzt mit Hilfe des Terminal-Emulators einen Echo-Test durchführen. Falls der\nTerminal-Emulator noch nicht automatisch gestartet worden ist, starten Sie ihn jetzt mit „Run\nTerminal Emulator“. Das marineblaue Emulator-Fenster sollte jetzt auf dem Monitor zu sehen sein. Drücken Sie jetzt kurz auf den Taster 1 auf dem Board. Auf dem Terminal-Emulator\nsollte jetzt der Text „Echo_Text eingeben (max. 20 Zeichen):“ zu sehen sein. Ferner sollte die\ngrüne LED auf dem Board erloschen sein und die gelbe LED auf Dauerlicht stehen. Das Programm wartet nun auf eine Eingabe am Terminal-Emulator. Nehmen Sie nun eine entsprechende Eingabe vor und drücken Sie auf die Eingabetaste.\nNun sollte die grüne LED auf dem Board wieder blinken und in Zeile 4 des LCD sollte der\neingegebene Text als Echo zu sehen sein.\nWie Sie sehen, ist Letzteres leider nicht der Fall. Nun, an dieser Stelle ist bewusst ein Fehler\nin das „Programm_1_Erste_Inbetriebnahme“ eingebaut worden, der beim Kompilieren nicht\nerkannt werden kann, sondern der sich erst zur Laufzeit des Programms bemerkbar macht.\nDies bietet die Gelegenheit, Sie mit dem Simulator ein wenig vertraut zu machen.\nMit Hilfe des Simulators kann man den Programmablauf simulieren, ohne dass der Mikroprozessor selbst die Programminstruktionen ausführt. Ein wesentliches Element ist hierbei die\nEinzelschritt-Ausführung. Wenn Sie wiederholt das Feld „Step into code (F8)“ anklicken,\nkönnen Sie auf dem Monitor im Quellcode verfolgen, welche Instruktionen das Programm\nausführt und ob es den gewünschten Weg geht.\nNatürlich kann die „Einzelschritt-Tipperei“ in größeren Programmen recht zeitaufwändig werden. Aus diesem Grunde ist alternativ die Möglichkeit gegeben, das Programm bis zu einem\nbestimmten Punkt, dem „Breakpoint“ durchlaufen zu lassen. Am Breakpoint hält das Programm dann an und man kann ab jetzt mit Einzelschritten sich an die Fehlerstelle „herantasten“.\nWir wollen dies im vorliegenden Fehlerfalle einmal\npraktizieren. Starten Sie\nhierzu den Simulator mit\n„Simulate program (F2)“. Es\nerscheint auf dem Monitor\nein Fenster wie auf dem\nBild dargestellt. Falls das,\nwas Sie auf dem Monitor sehen, nicht ganz dem dargestellten Bild entspricht, verschieben Sie bitte die drei\nTeilfenster so, dass Sie genug Platz zum Eingeben von\ndrei Variablen haben und\nder Inhalt des TerminalEmulators auf ca. 4 Zeilen begrenzt ist. So haben Sie ein Maximum an Platz, um möglichst\nviel vom Quellcode sehen zu können.\nGeben Sie nun, wie im Bild dargestellt, die Namen von drei Variablen ein, jeweils mit Eingabetaste abgeschlossen. Klicken Sie nun auf „Run program (F5)“.\nNach einer kurzen Zeit werden Sie sehen, dass der momentane Programmzeiger zwischen\nzwei „Wait“-Instruktionen hin- und her springt. Die Kommentare in der Quellcode-Umgebung zeigen, dass sich das Programm offenbar in einer Warteschleife befindet und in dieser\nWarteschleife die grüne LED an- und ausgeschaltet wird. Aber bitte beachten Sie: das Board\nist jetzt nicht in Betrieb !\nKlicken Sie jetzt auf „Pauze (F8)“ und danach auf „Step into code (F8)“. Sie können jetzt sehen, wie das Programm in der Warteschleife herum läuft und sich der Zustand der Variablen\nPortd.4 fortlaufend ändert. Das Programm wird diese Schleife nur verlassen, wenn ein Interrupt auftritt. Dieser Interrupt ist normalerweise mit dem Taster 1 auf dem Board assoziert.\nMan kann ihn im Simulator künstlich erzeugen, wenn man den Tabulator „Interrupts“ aufruft\nund dort INT1 anklickt. Tun Sie dies bitte.\nSie sehen jetzt, dass das Programm (im Einzelschritt befindlich) momentan auf Zeile 1 des\nProgramms springt. Dort liegt (in Wirklichkeit) der Verzweigungsvektor für die Interrupts.\nNach ein paar weiteren Klicks auf „Step into code (F8)“ sehen Sie, dass die grüne LED ausgeschaltet wird und die gelbe LED eingeschaltet wird. Es sei an dieser Stelle jedoch nochmals\ndaran erinnert, dass das Board jetzt nicht aktiv ist; Sie können den Zustand der LEDs nur erkennen, indem Sie sich die Variablen PortD.4 und PortD.5 auf dem Simulator ansehen. Als\nnächstes folgt dann im Quellcode eine „Input“-Anweisung. Einen Klick weiter sehen Sie\ndann, dass im marineblauen Feld des Terminal-Emulators der Text zur Eingabe-Aufforderung\nerscheint. Geben Sie nun (im Terminal-Emulator) einen beliebigen Text ein, abgeschlossen\nmit der Eingabetaste. Wenn Sie sich die Variablen ansehen, werden Sie den eingegebenen\nDer nächste Klick auf „Step into code (F8)“ bringt Sie nun auf eine „Return“-Anweisung.\nHier wird offenbar die Interrupt-Routine verlassen und in die Warteschleife zurückgekehrt.\nAber wo ist der notwendige\nCode für die Ausgabe des\nEchos auf dem LCD ? Nun,\nwenn sie sich die Anweisungen\nnach der „Return“-Anweisung\nansehen, werden Sie sie dort\nfinden. Offenbar wird dieser\nTeil des Quellcodes nie ausgeführt. Wie könnte der Fehler\nentstanden sein ? Ganz einfach:\nder Programmierer hatte zunächst in seinem Entwurf die\nAusgabe auf das LCD noch\nnicht implementiert und deswegen an dieser Stelle die „Return“-Anweisung gesetzt. Später hat er den Code für die Ausgabe auf LCD eingefügt, jedoch das „zu frühe Return“ vergessen.\n„Kommentieren“ Sie die zu frühe „Return“-Anweisung heraus, kompilieren und brennen Sie\ndas Programm nun nochmals neu, und Sie werden sehen, dass das Echo nun auf dem LCD\nerscheint. Hiermit ist die erfolgreiche Inbetriebnahme des Testprogramms abgeschlossen.\nDas erste eigene Bascom-Programm:\nEine LED „erblinkt“ das Licht der Welt\nIn den folgenden Kapiteln soll die Programmentwicklung für das Projekt „Heizölverbrauch“ Schritt für Schritt dargestellt werden. Hierbei ist vorgesehen, dass der jeweils\nnächste Schritt auf dem vorigen aufbaut, so dass am Ende das komplette Programm steht.\nDie einzelnen Schritte bestehen im wesentlichen darin, dass jeweils eine weitere Programmiertechnik oder jeweils ein neuer Chip behandelt wird. Wir beginnen mit dem allereinfachsten Programm, einer Art „HalloWelt“-Programm, in dem wir eine an das Board angeschlossene LED periodisch zum Aufleuchten bringen. Typisch für dieses Programm und\nalle folgenden Programme ist dessen Zweiteilung in einen so genannten Deklarationsteil\nund den darauf folgenden eigentlichen Programmteil. Die allermeisten Definitionen im Deklarationsteil müssen zwingend dem Programmteil vorausgehen.\nInsofern ist es gute Programmierpraxis, grundsätzlich alle Definitionen voranzusetzen.\nDie erste ausführbare Programm-Instruktion ist dann damit automatisch der Einsprung in das\nProgramm nach Power On/Reset. Das ist im hier dargestellten Falle die Instruktion „Portd.4 =\nHi“. Es folgt eine kurze, beispielhafte Beschreibung der wesentlichen Definitionen. Näheres\nhierzu siehe bitte die „Help“-Funktion im Bascom-Compiler.\n$regfile = „m168def.dat“\nMit dieser Angabe wird festgelegt, für welchen Mikroprozessor dieses Programm geschrieben\nwird. Mit dieser Angabe werden automatisch eine Reihe von Namen für Register, Ports und\nAdressen festgelegt, die im folgenden dann nicht extra vom Programmierer definiert werden\nmüssen. Ein Beispiel ist die im folgenden verwendete Instruktion Portd.4 = Hi. Es ist gute\nPraxis, diese Definition zu verwenden, da es sehr unterschiedliche Atmel-Mikroprozessoren\ngibt, und nicht alle haben denselben Umfang an Registern, Ports und Adressen.\n$crystal = 2500000\nDer Name „Crystal“ ist in diesem Zusammenhang ein wenig irreführend, weil hiermit suggeriert wird, dass die Frequenz des verwendeten Quarzes auf dem Board gemeint sein könnte.\nGemeint ist aber die Instruktions-Ausführungsgeschwindigkeit bzw. Taktung des Mikroprozessors, und die kann wegen einer „Fuse“ unterschiedlich von der Quarzfrequenz sein. Das\nThema kann hier nicht erschöpfend behandelt werden und es muss auf die „Description“ für\nden betreffenden Mikroprozessor verwiesen werden. Siehe http://www.atmel.com/dyn/resources/prod_documents/doc2545.pdf. Im vorliegenden Falle wird ein 20-MHz-Quarz verwendet,\nund die „divide-by-eight-Fuse“ ist gesetzt. Das führt zu einer Taktfrequenz von 2.500.000 Hz.\nDie Angabe ist für den Compiler wichtig, weil er z.B. hieraus errechnen kann, wie viele\n„NOP“-Instruktionen er ausführen muss, um eine Wartezeit von einer Sekunde („Wait 1“) zu\nerzeugen. Siehe Programmteil.\nSiehe die „Help“-Funktion des Bascom-Compilers. Ich möchte hierzu aber zunächst eingestehen, dass ich die genaue Bedeutung dieser Anweisungen noch nicht voll verstanden habe, das\ngilt insbesondere für $framesize. Die „Help“-Funktion beschreibt diese Anweisungen m.E.\nsehr unzureichend. Das größte Manko hierbei ist, dass nicht klar ist, was passiert, wenn bei\ndiesen Anweisungen versehentlich zu kleine Werte angegeben werden. Ich habe in meiner\nProgrammierpraxis einige Male Laufzeitfehler ganz merkwürdiger Art erlebt. Ich habe dann\nversuchsweise diese Werte auf diejenigen Werte heraufgesetzt, wie sie hier angegeben sind\nund die Fehler waren plötzlich wie durch ein Wunder weg. Allerdings bin ich dem Problem\nnie ganz auf den Grund gegangen. Aber seitdem empfehle ich, die hier ausprobierten Werte zu\nBekanntlich sind die Ein- / Ausgabe-Pins des Mikroprozessors in Gruppen von acht Pins zu\neinem Port zusammengefasst. Die Hardware lässt es zu, die acht Pins eines Ports auch innerhalb eines Ports sowohl zur Eingabe als auch zur Ausgabe, also gemischt, zu verwenden. Vor\nder Programmausführung muss dies allerdings dem Compiler mitgeteilt werden. Die obige\nAnweisung ist ein Beispiel dafür, dass der Pin 4 des Ports D als Ausgabe-Pin verwendet werden soll.\nConst Lo = 0\nMit dieser Anweisung kann eine Konstante definiert werden, d.h. die Konstante bekommt einen Namen, mit dem sie im Programm angesprochen werden kann. Da Namen einen wesentlich größeren Aussagewert als bloße Zahlen haben, wird die Lesbarkeit und damit das bessere\nVerständnis des Programms wesentlich erhöht.\nWir kommen nun zum Programmablauf, also dem ausführbaren Teil des Programm-Codes.\nPortd.4 = Hi\nWie Sie auf dem BoardPhoto sehen können, ist an\nPort D Pin 4 die grüne LED\nangeschlossen (grüne Drahtverbindung). Der Ausdruck\n„Portd.4“ ist ein BascomSchlüsselwort, welches dem\nsolches bekannt ist. Diese\nAnweisung schreibt also\neine „1“ auf diesen Pin,\nschaltet somit die grüne\nDiese Anweisung lässt den Mikroprozessor für eine Sekunde in einer Leerlaufschleife verharren, das ist eine Anzahl von „NOP“- Operationen, deren Ausführung insgesamt eine Sekunde\ndauert. Um die Anzahl dieser „NOP“-Operationen berechnen zu können, muss der Compiler\ndie Taktgeschwindigkeit des Mikroprozessors kennen. Diese hängt vom verwendeten Quarz\noder der Frequenz des internen Oszillators und den gesetzten „Fuses“ ab. Die verwendete\nTaktfrequenz wurde vorher im Definitionsteil mit „$crystal“ definiert.\nDer Rest des Programm-Codes ist nun selbsterklärend: Es ist hier eine Endlosschleife programmiert, in der die grüne LED jeweils für eine Sekunde an- und dann ausgeschaltet wird.\nHierbei handelt es sich um eine so genannte Sprung-Anweisung. Das Programm verlässt an\ndieser Stelle seinen linearen Ablauf und springt zu der Zeile, die vorher mit dem Label „Leerlauf_schleife“ versehen worden ist.\nSo, damit ist das erste Programm erfolgreich zum Laufen gebracht worden. Zur weiteren Einübung können Sie dieses Programm nun nach Lust und Laune mit den hier behandelten Elementen erweitern bzw. modifizieren. Sie können z.B. eine weitere LED zum Leuchten bringen, die Blinkzeiten verändern oder die hier dargestellte „Goto“-Schleife durch eine\n„Do“-Schleife ersetzen (siehe „Help“). Je nach dem Stand Ihrer Vorkenntnisse ist es sehr\nwichtig, dass Sie diese Basiskenntnisse festigen und vertiefen, denn wir werden mit dem Fortschreiten in den weiteren Kapiteln immer größere Schritte tun.\nauf Tastendruck: Externer Interrupt\nIn unserem vorigem Programmierbeispiel hatten wir einen ganz einfachen Anwendungsfall\nkennen gelernt. Es handelte sich hier um einen Vorgang, der sich periodisch wiederholt, das\nAufblinken einer LED. Wir hatten gesehen, dass dies programmtechnisch in einer Endlosschleife realisiert wird, in der der Mikroprozessor wie ein Hamster im Hamsterrad im Kreis\nherum läuft. Der Mikroprozessor verbringt seine Zeit in diesem Beispiel weit über 99% mit\nNichtstun. Er verfügt also über weit mehr Rechenkapazität als ihm hier abverlangt wird.\nWir wollen in diesem zweiten Beispiel diese gewaltige freie Rechenkapazität wenigstens etwas mehr nutzen, indem wir ihn wenigstens eine weitere Aufgabe erledigen lassen. Diese weitere Aufgabe besteht im folgenden: Der Mikroprozessor soll, während er mit dem periodischen Blinken lassen der LED beschäftigt ist, zusätzlich überwachen, ob der Taster 1 auf dem\nBoard gedrückt worden ist. Immer dann, wenn der Taster 1 gedrückt worden ist, soll der Mikroprozessor dafür sorgen, dass die eine (grüne) LED ausgeschaltet wird und die andere (gelbe) LED eingeschaltet wird und umgekehrt.\nGrundsätzlich kann der Programmierer zur Lösung dieses Problems zwei verschiedene Techniken anwenden. Die erste nahe liegende Technik wäre es, in der Endlosschleife den Schaltzustand des betreffenden Pins an dem betreffenden Port abzufragen, an dem der Taster 1 angeschlossen ist. In unserem Fall ist das Pin 3 an Port D. Wenn also Pin 3 an Port D „Hi“ ist,\nmüsste ein Programmzweig angesteuert werden, in dem die bisher blinkende LED ausgeschaltet wird und die andere LED eingeschaltet wird. Die Technik dieses periodischen Abfragens\nnennt man übrigens auch „Polling“.\nDie Architektur der Mikroprozessortechnik stellt dem Programmierer allerdings noch eine\nweitere Methode zur Verfügung, und das ist die „Interrupt“-Technik. Wir entscheiden uns für\ndiese Technik und wollen sie hier näher kennen lernen.\nDie „Interrupt“-Technik ist ein integraler Bestandteil aller Mikroprozessoren und wird als Bestandteil der Hardware zur Verfügung gestellt. Seine Funktionsweise ist so, dass wenn dem\nMikroprozessor mitgeteilt worden ist, dass ein bestimmter Pin an einem Port als „Interrupt“\ndefiniert worden ist, die Hardware des Mikroprozessors den Signalzustand an diesem Pin automatisch überwacht und im Falle eines „Interrupts“ dieses Faktum der Logik des Mikroprozessors meldet. Dies geschieht bis dahin ohne Zutun des Programmierers. Wenn nun die Logik des Mikroprozessors dieses „Interrupt“-Ereignis erkennt, dann unterbricht sie den bisherigen sequentiellen Programmablauf und der Prozessor verzweigt an eine bestimmte, vorher\nfestgelegte Stelle im Hauptspeicher, in der die Ansprungadresse für die (vom Programmierer\nzu programmierende) „Interrupt“-Routine abgelegt ist.\nNachdem in der „Interrupt“-Routine diejenige Arbeit erledigt worden ist, die der Programmierer für dieses Ereignis vorgesehen hat, wird mit einer speziellen Instruktion (RETI) das Ende\ndieser Routine erklärt, und damit kehrt der Prozessor (ohne Zutun des Programmierers) an\ndiejenige Stelle im Programm zurück, an der es unterbrochen worden war.\nDie Verwendung einer „Interrupt“-Routine erfordert also zweierlei:\nIm Deklarationsteil des Programms die Definition, welcher Pin an welchem Port der „Interrupt“-Pin sein soll (der ATmega168 hat zwei solcher Pins, INT1 und INT2), und die Angabe, wohin der Prozessor verzweigen soll, wenn ein „Interrupt“ auftritt, und\nan der eben definierten Adresse im Programm eine „Interrupt“- Routine, in der erledigt\nwird, was im Falle eines „Interrupts“ getan werden soll. Diese Routine muss mit einem\n„Return from Interrupt“ abgeschlossen werden. Im Falle von Bascom heißt diese Anweisung „Return“.\nWir wollen uns dies im Beispielprogramm ansehen.\nHier wird deklariert, dass der\nPin 3 von Port D als Interrupt-Pin benutzt werden soll.\nBeim ATmega168 wird dieser Pin auch INT1 genannt.\nEr ist speziell für externe Interrupts vorgesehen (siehe\ndie „Description“ für den\nATmega168, es ist der Pin 5\nHier wird dem Compiler\n(und dem Prozessor) zusätzlich mitgeteilt, ob der\nder Interrupt mit steigender, fallender Flanke oder bei „Lo“ ausgelöst werden soll. Wir haben\nuns für letzteres entschieden.\nOn Int1 Int1_int_routine\nHier wird, bezogen auf die\nvorige Definition, die Ansprung-Adresse im Programm bekannt gegeben, an\nder die „Interrupt“-Routine\nbeginnt. Im Ausführungsteil\ndes Programms sind gleich\nzu Beginn folgende Anweisungen notwendig:\nUm den Taster1 wie auf\ndem Board vorgesehen, unmittelbar an den Pin 3 anschließen zu können, muss\nmit dieser Instruktion der hardwaremäßig vorgesehene Pull-up-Widerstand aktiviert werden (Open-Collector-Ausgang)\nNach einem „Power ON“ sind zunächst alle Interrupts des ATmega168 nicht zugelassen. Mit\ndieser Anweisung werden grundsätzlich Interrupts hardwaremäßig zugelassen\nMit dieser Anweisung werden speziell für den PIN „INT1“ Interrupts zugelassen. Ohne diese\nbeiden Anweisungen wird der Taster 1 also keinen Interrupt auslösen.\nNach diesen Anweisungen\nläuft das Programm nun in\ndie Leerlaufschleife und es\nbleibt dem Leser überlassen,\ndie leicht veränderte Logik\nzur alternativen Ansteuerung der LEDs selbst zu\nWenn nun auf dem Board\nder Taster 1 kurz gedrückt\nwird und der Mikroprezessor dieses Signal erkannt\nhat, wird die in der Deklaration angegebene „Interrupt“Routine angesteuert.\nFür diesen kleinen Anwendungsfall ist ist die Logik recht einfach. Mit der „Case“-Anweisung\nwird die Farbe der derzeit blinkenden LED abgefragt und auf die jeweilige andere Farbe gewechselt.\nAm Schluss der Routine folgt dann das bereits beschriebene „Return“, welches die „InterruptRoutine“ beendet und eine Rückkehr des Prozessors an die Unterbrechungsstelle in der Leerlaufschleife veranlasst.\nVerbliebe es noch, diese zunächst vielleicht unverständliche Anweisung (an\ndieser Stelle) zu diskutieren.\nEs mag für den Laien überraschend klingen, aber der\nMikroprozessor verbringt in\nso wenig Zeit, dass er in\nMillisekunden wieder zurück in der Leerlaufschleife\nist. Ein „Prellen“ des Tasters 1 kann also leicht zu\nmehreren Interrupts führen.\nMit dieser Anweisung wird die Prellzeit überbrückt.\nDialog mit dem PC via\nBeim Bascom-Terminal Emulator dient kurz gesagt die Tastatur und der Monitor des PC als\nKommunikationsmedium mit dem Mikroprozessor. Mit Hilfe dieser Einrichtung ist es also\nmöglich, Daten, die aus dem Mikroprozessor stammen, auf dem Bildschirm des PC darzustellen, und Eingaben, die von der Tastatur des PC stammen, zum Mikroprozessor zu übertragen.\nDieses Geschehen ist wohlgemerkt beim echten Betrieb des Mikroprozessors möglich, nicht\netwa nur bei einer Simulation. Die Vorteile dieser Einrichtung liegen auf der Hand, gestatten\nsie es doch, unmittelbar zur Laufzeit des Mikroprozessors z.B. den momentanen Wert von\nVariablen des Mikroprozessor-Programms (durch einfaches „Ausdrucken“) auf dem PC darzustellen. Auf dem umgekehrten Wege ist es ebenso einfach möglich, Variablen im Mikroprozessor-Programm jederzeit vom PC her zu verändern. Und selbstverständlich kann man dieses\nVerfahren sowohl vorübergehend beim Testen als auch später für Steuerungszwecke einzusetzen und damit das Manko umgehen, dass Mikroprozessoren ja meistens gerade nicht sehr üppig mit Ein-/Ausgabegeräten ausgestattet sind.\nFür die Kommunikation sind\nzwei Anweisungen vorgesehen, die „Print“-Anweisung\nfür die Ausgabe von Informationen des Mikroprozessors auf dem Monitor, und\ndie „Input“- Anweisung für\ndie Annahme von Informationen von der Tastatur.\nDas Programmbeispiel orientiert sich stark am vorigen\nBeispiel, indem es ebenfalls\nabwechselnd zwei LEDs angesteuert. In der Endlosschleife wird wie bisher je\nnach gewählter Farbe die\nentsprechende LED zum Blinken gebracht.\nIn der „Interrupt“-Routine\nwird dann mit mehreren\n„Print“- Anweisungen ein\nAuswahlmenü auf dem Monitor ausgegeben. Dann wird\nmit „Input“ eine Eingabe\nvon der Tastatur erwartet.\nDie Eingabe bestimmt dann\ndie Farbauswahl („Case“Anweisung).\nEs sei an dieser Stelle darauf\nhingewiesen, dass die hier\ngewählte Programmiertechnik eigentlich eine\n„Todsünde“ ist, denn hier wird in einer „Interrupt“-Routine eine manuelle Eingabe abgewartet, und die hängt natürlich von der menschlichen Reaktion ab. Da der Mikroprozssor gewissermaßen in einer Warteposition „hängt“, während er sich in einer „Interrupt“-Routine befindet, steht er für andere Arbeiten z.B. im Hauptprogramm, aber normalerweise auch nicht für\nandere Interrupts, zur Verfügung. Von „Echtzeit“-Verarbeitung kann hier also wohl nicht\nmehr die Rede sein. Nun, im Falle dieses Anwendungsbeispiels können wir uns diese „Sünde“\nleisten, da der gesamte weitere Anwendungsablauf von der Eingabe via „Input“ abhängig ist.\nFür den Mikroprozessor ist „sonst“ nichts zu tun.\nEine ganz andere Situation hätten wir jedoch beispielsweise, wenn wir auf einer weiteren Interrupt-Leitung sagen wir einen Feuermelder angeschlossen hätten. Dann würde, wenn der\n„Mann am PC“ die Eingabe verschläft, der Feuermelder „nicht durchkommen“. Denn es ist\nso, dass der Mikroprozessor „normalerweise“ keinen anderen Interrupt durchlässt, bevor nicht\ndie „RETI“-Instruktion erreicht worden ist. Es gibt zwar grundsätzlich beim ATmega168 eine\nAbweichung vom „normalerweise“, und das wäre die Zulassung von „nested interrupts“ (also\nein Interrupt kann den anderen momentan unterbrechen), aber das soll hier nicht diskutiert\nsein, weil es den gesteckten Rahmen sprengen würde. Wer will, kann dies in der\n„Description“ für den ATmega168 nachlesen.\nEine Lösung, die leidige Wartezeit auf eine Eingabe in einer „Interrupt“-Routine zu vermeiden, ist die Möglichkeit, in der „Interrupt“-Routine ein Ereignis-“Flag“ zu setzen, das dann in\nder Hauptschleife des Programms abgefragt und abgearbeitet werden kann. Auf diese Weise\nkann die „Interrupt“-Routine auf schnellstem Wege verlassen werden und der Mikroprozessor\nfür andere Interrupts frei werden.\nI2C/Serial Display LCD03\nMit dem „I2C/Serial Display LCD03“ der englischen Firma Devantech Ltd., oder auch Robot\nElectronics genannt, wollen wir nun ein 20*4-zeiliges Display an unseren Mikroprozessor anschließen. Wie man erst beim genauen Hinsehen auf den Namen „I2C/Serial“ erkennt, bietet\ndas LCD03 zwei verschiedene (serielle) Schnittstellen an, eine EIA-232-Schnittstelle und eine\nI2C-Schnittstelle. Dies jedenfalls ist mit dem Namen gemeint. Da beide Schnittstellen an dieselben Pins des LCD03 angeschlossen werden, muss dem LCD03 mitgeteilt werden, welche\nSchnittstelle gewählt wird. Dies geschieht mit einem Jumper auf dem LCD03. Wir entscheiden uns für die I2C-Schnittstelle, weil dies heute die Standard-Schnittstelle für Kommunikationen innerhalb eines Gerätes ist. Diese Schnittstelle kommt mit einer Versorgung von +5V\naus, was für kleinere Geräte ein großer Vorteil ist. Für diesen Fall muss der Jumper, wie bereits erwähnt, gezogen werden. Für die weitere Beschreibung sollten Sie jetzt die „Technical\nDocumentation“ des LCD03 parat haben.\nSie finden sie unter http://www.robot-electronics.co.uk/htm/Lcd03tech.htm .\nUm die I2C-Schnittstelle in AVR-Bascom programmieren zu können, brauchen Sie keine detaillierten Kenntnisse von dessen Architektur. Es ist jedoch ratsam, dass Sie zumindest ein\npaar Grundlagen über diese Schnittstelle kennen. Sie finden diese unter\nWie bereits erwähnt, bietet das LCD03 eine Anzeige von vier Zeilen mit jeweils 20 Zeichen.\nEinmal zum Display geschickt, werden die Zeichen dort gespeichert und so lange angezeigt,\nbis sie von neuen Zeichen überschrieben werden. Das bedeutet, dass wenn man z.B. in Zeile 1\neinen neuen Inhalt schreiben will, man nur diesen Zeileninhalt senden muss, die restlichen\nZeilen bleiben erhalten. Dass man das Display zeilenweise anspricht, ist aber eine sehr häufige\nAnwendungsform. Eine entsprechende Softwareunterstützung ist daher wünschenswert.\nEntsprechend dieser Forderung ist die hier vorgestellte Softwareunterstützung daher auch aufgebaut. Es ist eine Subroutine konzipiert worden, die drei Parameter als Eingabe erfordert: die\nZeilennummer und die Spaltennummer, ab der geschrieben werden soll, und ein Text von maximal 20 Zeichen. Das LCD03 kommt diesem Wunsch insofern entgegen, als dass es ein\nKommando anbietet, welches die Zeilen- und Spaltennummer adressiert (Kommando 310 =\nSet Cursor, line, column). Es sei nur am Rande gesagt, dass bei dieser Art der zeilenweisen\nAdressierung die Spaltennummer typischerweise immer „1“ sein wird.\nEs sollte an dieser Stelle noch erwähnt werden, dass es noch einen weiteren Grund gibt, die\nAusgabe auf das LCD03 zeilenweise zu organisieren. Je nach eingestellter Taktfrequenz des\nMikroprozessors ergibt sich nach einer Formel (siehe ATmega168 Description) eine Taktfrequenz auf dem I2C-Bus von mindestens ca. 100 KHz. Das ist schneller als das LCD03 Daten\nempfangen kann. Aus diesem Grunde werden die Empfangsdaten im LCD03 gepuffert. Der\nEmpfangspuffer ist nur 64 Bytes groß. Das bedeutet, dass wenn mehr als 64 Bytes gesendet\nwerden, die überschüssigen Bytes u.U. verloren gehen. Die hier vorgestellte Subroutine überträgt pro Aufruf 20 Zeichen für eine Leerzeile und dann unmittelbar danach bis zu 20 Zeichen\nText. Damit läge sie auf der sicheren Seite. Es ist natürlich möglich, dass diese Subroutine\nvier mal (für 4 Zeilen) unmittelbar hintereinander aufgerufen wird. Damit könnte der „Buffer\nOverflow“ theoretisch doch auftreten. Nun, in der Praxis ist dies bei der gewählten Mikroprozessor-Taktfrequenz nicht aufgetreten. Falls dies bei höheren Taktfrequenzen auftreten sollte\n(Symptom falsche Zeileninhalte), sollte am Ende der Subroutine eine „Waitms xx“ eingefügt\nEs folgt eine Beschreibung der Definitionen und Deklarationen für das LCD03.\nBeim ATmega168 sind die\nBusleitungen SDA und SCL\nhardwaremäßig auf Port C\nPin 4 bzw. Port C Pin 5 festgelegt (es besteht hier keine\nfreie Wahl). Dies wird hier\ndem Compiler mitgeteilt.\nDie noch vorzustellende\nSubroutine mit dem Namen\n„Lcd03_zeile_schreiben“ wird an dieser Stelle deklariert. Damit kann sie später im Ausführungsteil jederzeit mit einer „Call“-Anweisung aufgerufen werden.\nEs folgt die Definition der Konstanten für das LCD03. Was die Werte betrifft, siehe hierzu die\n„Technical Documentation“ des LCD03. Was die Definitionen für die Variablen betrifft, so\nwerden diese erst klarer werden, wenn der Inhalt der Subroutine „Lcd03_zeile_schreiben“ diskutiert werden wird.\nFür den Fall, dass unmittelbar nach „Power On/Reset“ eine „Good Morning“-Nachricht auf\ndas LCD03 geschrieben werden soll, ist zu beachten, dass das LCD03 eine gewisse Aufwärmzeit braucht. Dies ist hier\ndurch Waitms 1000 verwirklicht.\nEs folgt dann im Ausführungsteil nach „Power\nOn/Reset“ das Senden einer\nauf die 4 Zeilen des LCD03.\nDiese Variable wird mit\ndem aktuellen Text für die\njeweilige Zeile gefüllt.\nLcd03_xpos = 1\nLcd03_ypos = 1\nDiese Variablen werden mit der aktuellen gewünschten Position gefüllt.\nMit dieser Anweisung wird die noch zu diskutierende Subroutine „Call Lcd03_zeile_schreiben“ aufgerufen. Wenn die Subroutine ihr Ende erreicht hat (bei „Return“), kehrt der Programmablauf auf die nächste Anweisung nach dem „Call“ zurück.\nEs folgt die Vorstellung der Subroutine „Lcd03_zeile_schreiben“. Der Ablauf besteht aus\nzwei Schreib-Sequenzen zum LCD03, jeweils beginnend mit „I2cstart“ und endend mit\n„I2cstop“. Die erste Sequenz schreibt 20 „Blanks“ in die jeweilige Zeile, löscht sie also, und\ndie zweite Sequenz füllt die jeweilige Zeile mit dem gewünschten Text.\nAls „Master“ setzt der Mikroprozessor hiermit das\n„Start“-Signal auf die\nDas erste gesendete Byte\nenthält die Adresse des\nLCD03 und das SchreibKommando. Das LCD03\nhat immer die Adresse C616\noder 19810 . Es ist also nur\nein LCD03 am I2C-Bus\nDieses Byte adressiert das „Command Register 0“. Dieses Byte hat keine direkte Wirkung und\nwird laut „Technical Documentation“ ignoriert. Man sollte es aber nicht weglassen, denn das\nführt merkwürdigerweise zu Fehlern.\nMit diesem Byte wird das Kommando „3“ (Set Cursor, line, column) übertragen.\nDiese beiden folgenden Bytes enthalten (gewissermaßen als Parameter für das vorige Kommando) die Zeilen- bzw. Spaltenadresse.\nLcd03_textlength = Len(lcd03_text_leerzeile)\nFor Lcd03_textpointer = 1 To Lcd03_textlength Step 1\nLcd03_textbyte = Mid(lcd03_text_leerzeile , Lcd03_textpointer , 1)\nIn dieser „For“- „Next“-Schleife werden je nach Textlänge bis zu 20 Zeichen Text zum\nHiermit setzt der Mikroprozessor das „Stop“-Zeichen auf die „SCL“-Leitung. Die erste\nSchreib-Sequenz ist abgeschlossen.\nDie zweite Schreib-Sequenz hat denselben Ablauf wie die erste, nur, dass jetzt der auszugebende Text gesendet wird. Da der Cursor bei einer reinen Ausgabe keine Funktion hat, wird er\nmit einem entsprechenden Kommando am Ende der zweiten Schreib-Sequenz unsichtbar gemacht. Ferner wird, ebenfalls mit einem weiteren Kommando, das Hintergrund-Licht eingeschaltet.\nDa dieser Wechsel zwischen Daten und Kommandos ohne Umschalten so funktioniert, erhebt\nsich die Frage, wie das LCD03 diesen Unterschied erkennt. Die Erklärung kann der „Technical Documentation“ entnommen werden: Zeichen von 010 bis 2710 werden als Kommandos interpretiert, Zeichen von 3210 bis 25510 werden als Daten interpretiert.\nWas den Gesamtablauf des Programms „Programm_5_I2C_Display“ betrifft, so möge es der\nLeser selbst analysieren: Nach „Power On“ wird eine dreizeilige Nachricht auf das LED03\ngeschrieben. Dann kann man den Terminal-Emulator starten, indem der „Taster 1“ auf dem\nBoard kurz gedrückt wird. Dort erscheint ein kleines Menü, das eine Farbauswahl vorgibt. Je\nnach Wahl der Farbe wird die jeweilige LED zum Blinken gebracht bzw. die Farbwahl auf\ndem LED03 angezeigt.\nEine Uhr, die nicht stehen bleibt:\nMit diesem Programm soll nun ein weiterer Chip in Betrieb genommen werden, und das ist\ndie Echtzeituhr „DS1307“ von Dallas MAXIM.\nSie sollten jetzt auch das „Dallas MAXIM DS1307 I2C Real Time Clock Datasheet“ parat haben. Es findet sich unter http://www.sparkfun.com/datasheets/Components/DS1307.pdf.\nDiese Echtzeituhr ist speziell für den Betrieb an einem I2C-Bus ausgelegt und kann somit mit\nanderen Komponenten an diesem Bus kommunizieren, z.B. mit dem ATmega168. Die Uhr\nwird durch einen externen Quarz gesteuert. Bei entsprechendem Betrieb liefert die Uhr beim\nAuslesen ihrer Register die Sekunde, die Minute, die Stunde sowie den Tag, den Monat und\ndas Jahr., sowie den Tag der Woche. Sie unterstützt das Stundenformat von 12-hour als auch\n24-hour. Ferner unterstützt die Uhr automatisch die unterschiedlich langen Monate und sie berücksichtigt auch Schaltjahre bis zum Jahr 2100.\nEine Besonderheit dieser Uhr ist, dass sie in einer Schaltung über zwei Stromversorgungen\nbetrieben werden kann. Zum einen ist das die übliche +5V-Versorgung. Wenn die Uhr nur mit\ndieser Versorgungsoption betrieben wird, funktioniert die Uhr nur so lange korrekt wie die\nStromversorgung steht. Im Falle einer Stromabschaltung gehen die Einstellungen der Uhr verloren und müssen beim Wiederanlauf neu initiiert werden.\nDie Uhr kann aber zusätzlich über einen speziellen Anschluss mit einer 3V-Spannung versorgt werden. Dies gestattet die Versorgung mit einer 3V-Lithium-Knopfzelle. Die Schaltungslogik erkennt einen etwaigen Stromausfall an der +5V-Versorgung sofort und schaltet\nautomatisch auf die 3V-Versorgung um. Das ergibt in der Praxis mit einer Knopfzelle eine\nAusfallsicherheit von mehr als zehn Jahren.\nUm die nun folgenden Bascom-Deklarationen und Definitionen besser verstehen zu können,\nwollen wir uns die so genannten „Timerkeeper Registers“ des DS1307 näher ansehen. Wenn\nes um Kommunikation über den I2C-Bus mit dem DS1307 geht, wird der Inhalt dieser Register im Falle des Auslesens dem Master (ATmega168) zur Verfügung gestellt. Der Master\n(ATmega168) kann diese Register aber auch jederzeit beschreiben. Damit wird das Einstellen\nder Uhr auf neue Werte vollzogen.\nWie Sie sehen, sind die „Timekeeper Register“ byte-weise organisiert, und zwar so, dass pro\nByte jeweils in den ersten vier Bit die Zehnerstelle eines Wertes abgelegt ist, und in den zweiten vier Bit die Einerstelle. Man nennt diese Darstellungsform auch „Packed BCD“ , eine Darstellungsform, die heute immer weniger zur Anwendung kommt und daher manchem Anfänger unbekannt sein mag. Als Programmierer muss man sich diesen Umstand klarmachen, da\nes sonst leicht zu Fehlern kommt. Wir sind es gewohnt, dass eine Zahl z.B. als „Byte“ deklariert, die Zahlen von 0 bis 255 aufnehmen kann. Wollen wir diese Zahl z.B. auf einem Display\nausgeben, dann wandeln wir den Wert mit Str(Zahl) um und das Problem ist erledigt. Das\nwürde in diesem Fall der „Timekeeper Register“ zu falschen Werten führen, weil in dem Byte\nja zwei Zahlen enthalten sind, eine Zehner- und eine Einerstelle. Es muss also zunächst einmal dafür gesorgt werden, dass der Wert, sagen wir z.B. der Sekundenwert, in einen ein Byte\nlangen Integer-Wert umgewandelt wird. Hierfür ist Bascom bestens gerüstet, weil es speziell\nfür diesen Zweck eine Anweisung zur Verfügung stellt, und die lautet Makedec(Zahl). Erst\nnachdem wir diese Anweisung auf den gepackten BCD-Wert angewendet haben, können wir\nin gewohnter Weise mit diesem Wert weiterarbeiten.\nUmgekehrt ist es ähnlich: wenn wir einen Uhrzeitwert zum „Timerkeeper Register“ schicken\nwollen, werden wir diesen zunächst als „String“ von einem Eingabemedium lesen und diesen\nWert mit Val(Zahl) in einen Integer von einem Byte Länge verwandeln. Dieser Wert wird\ndann in einem zweiten Schritt mit der Anweisung Makebcd(Zahl) in das erforderliche Format umgewandelt.\nSo, nachdem ich auf diese Besonderheit beim DS1307 für den Anfänger hoffentlich ausreichend und für den Experten sicherlich langweilig, eingegangen bin, brauche ich auf die entsprechenden Stellen im Code nicht mehr besonders einzugehen. Der Rest ist simple Handarbeit.\nZeilen 125 - 132\nDiese Definitionen beinhalten die „Timekeeper Register“ in ihrer Reihenfolge von\nAdresse 0016 bis 0716. Im\nSinne der I2C-Kommunikation sind dies die benutzten\nVariablen, wenn der Mikroprozessor in die „Timekeeper Register“ hineinschreibt\nbzw. wenn diese vom Mikroprozessor\nZeilen 136 - 141\nDiese Definitionen beinhalten die „String“-Äquavalente der obigen Werte, wenn diese benötigt werden.\nZeilen 145 – 147\nDiese weiteren Definitionen werden bei der Programmierung des DS1307 benötiogt.\nZu den Definitionen für die Echtzeituhr DS1307 zählt ebenfalls noch eine Subroutine mit dem\nNamen „Datum_uhrzeit_lesen“, siehe den Original-Code.\nWir wollen die Beschreibung der Programmierunterstützung mit dieser Subroutine beginnen.\nDas Hauptprogramm ruft diese Subroutine immer dann auf, wenn es Datum und Uhrzeit aus\ndem DS1307 benötigt. Da das Hauptprogramm sonst keine eigene Uhrenfortschreibung vornimmt, kann dies sehr häufig vorkommen. Nach dem Aufruf legt die Subroutine die aktuellen\nWerte in den Variablen gemäß Zeilen 125 -132 nieder, zusätzlich als „String“-Äquivalente in\nden Variablen gemäß den Zeilen 136 – 141. Die Subroutine kann in zwei Teilen beschrieben\nwerden, dem Komminikationsteil und dem Umwandlungsteil.\nZum Start der Kommunikation setzt der ATmega168\nzunächst die Start-Bedingung auf die SCL-Leitung.\nDann wird als erstes Byte\ndie Adresse zum Schreiben\ndes DS1307 gesendet. Diese\nmuss D016 lauten. Da dies\nein Schreibbefehl ist, folgt\neine Adresse aus dem „Timekeeper Register“, und\nzwar die Adresse 00. Nun\nwill aber der ATmega168\nDaten aus dem DS1307 herauslesen. Er tut dies, indem\ner einen neuen Start-Befehl\nauf die SCL-Leitung setzt, dieses mal gefolgt von einer Adressierung zum Lesen (D116.) Der\nnächste gesendete Befehl ist dann ein Lese-Befehl, und der DS1307 überträgt den Inhalt von\n„Timekeeper Register 0“ zum ATmega168. Dieser sendet ein „ACK“ zur Bestätigung. Der\nnächste Lese-Befehl wird dann aus dem „Timekeeper Register 1“ bedient, und so fort bis zu\ndem Zeitpunkt wo der ATmega168 „NACK“ sendet zum Zeichen dafür, dass er alle Daten bekommen hat.\nMan beachte bitte, dass die Reihenfolge der Daten vom Programmierer nicht steuerbar ist.\nWissend, welche Daten zu erwarten sind, muss er dafür sorgen, dass die Daten in den richtigen Variablen abgelegt werden. Die Inkrementierung der „Timekeeper Register“ wird automatisch vom DS1307 vorgenommen. Mit dieser Sequenz sind alle Bestandteile von Datum\nund Uhrzeit auf dem ATmega168 angekommen.\nUm die gesendeten Zeichen,\ndie ja im gepackten BCDFormat vorliegen, z.B. auf\neinem Display sichtbar machen zu können, müssen in\neinem weiteren Schritt entsprechend nach „String“\nkonvertiert werden. Das geschieht in zwei Schritten.\nZuerst wird mit Makedec\n(Zahl) in einen Integer verwandelt, dann mit Str(Zahl)\nin der Format „String“ konvertiert. Es wird darauf geachtet, dass jeder Teilstring\nimmer aus zwei Bytes (evtl. mit führender Null) besteht.\nRoutine für das Einstellen von Datum und Uhrzeit\nNachdem Sie nun die „Timekeeper Registers“ des DS1307 kennengelernt haben und wissen,\ndass das Auslesen von Datum und Uhrzeit nichts weiteres ist als den Inhalt dieser Register\nzum ATmega168 zu übertragen, werden Sie sich leicht vorstellen können, das das Setzen der\nUhr ganz ähnlich ist, nur, dass die „Timekeeper Register“ jetzt vom ATmega168 beschrieben\nwerden müssen. Hierbei ist natürlich wiederum zu beachten, dass das spezielle gepackte\nBCD-Format sichergestellt sein muss, eine kleine Fleißarbeit für den Programmierer.\nAls Quelle für die Datum- und Uhrzeiteingabe dient uns ein Terminal-Emulator-Dialog. Er erfolgt, wie hier dargestellt, in drei Schritten, zuerst mit der Eingabe von Stunde, Minute, Sekunde (hhmmss) als sechsstelligem String (hhmmss). Dann folgt in einem zweiten Eingabeschritt die Eingabe des Jahres, des Monats und des Tages (JJMMTT), ebenfalls als sechstelligem String. Schließlich erfolgt die Eingabe der Tageszahl als zweistelliger String. Die Uhr\nläuft dann los, wenn mit einer weiteren Eingabe die ENTER-Taste verlangt wird.\nDer Leser sollte mittlerweile\nhaben, um nachvollziehen\nzu können, auf welchem\nWege die Informationen von\nder Eingabe her an die richtigen Stellen in den „Timekeeper Registern“ gelangen.\neinzelnen Werte jeweils vor\ndem Senden zum DS1307\nmit der Anweisung Makebcd(Zahl) in das gepackte BCD-Format umgewandelt werden.\nAnderes als beim Lesen sind\nwir beim Schreiben nicht an\neine bestimmte Reihenfolge\nder „Timekeeper Register“\ngebunden. Trotzdem muss\nder richtige Ort der Information natürlich sichergestellt\nDamit sollte die Echtzeituhr\nDS1307 hinreichend erklärt\nUnd selbstverständlich werden Datum und Uhrzeit in\ndiesem Programm auf dem\nLCD03 in Zeile 4 dargestellt.\nabgeleitet vom DS1307\nIm vorigen Programm hatten wir die Echtzeituhr DS1307 in Betrieb genommen. Diese Uhr,\ndie ja, wenn sie einmal vom Programmierer gestartet ist, ohne unserer Zutun von selbst läuft,\nmuss allerdings periodisch ausgelesen und zur Anzeige gebracht werden. Dies geschah im vorigen Programm in der Hauptschleife, und zwar jeweils nach Wartezeiten von einer Sekunde.\nHier soll nun eine alternative Methode vorgestellt werden. Diese Methode ist der „SekundenInterrupt“. Die Grundidee hierbei ist es, mittels irgend einer Zeitbasis dafür zu sorgen, dass im\nMikropozessor ein sekundlicher Interrupt ausgelöst wird. Dieser sekundliche Takt wird dann\nvom Programm benutzt, um periodisch sich wiederholende Dinge zu tun, wie z.B. das Anzeigen von Ergebnissen auf einem Display, das Abfragen von Status-Zuständen, das Update von\nZählern, usw. Häufig wird als Zeitbasis in diesem Falle ein Timer verwendet, der jeweils nach\neiner Sekunde einen Interrupt auslöst. Dies erfordert dann oft jeweils einen entsprechenden\nAbgleich mit der verwendeten Quarzfrequenz und die richtige Einstellung der so genannten\nDie hier verwendete Methode ist dagegen sehr einfach, wird uns doch gewissermaßen ein 1Sekundentakt vom DS1307 „frei Haus“ geliefert. Der DS1307 hat nämlich einen speziellen\nPin, an dem der Sekundentakt hardwaremäßig abgegriffen werden kann, und das ist der Pin 7\nSWQ/OUT. Mit einem Pullup-Widerstand abgeschlossen (extern!) liefert er ein TTL-kompatibles Signal, das direkt mit einem Input-Pin des ATmega168 verbunden werden kann. Wir\nwählen in unserem Fall den noch freien Pin INT0.\nDie Inbetriebnahme dieser Zeitbasis ist denkbar einfach. Hierfür ist das „Timekeeper Register“ mit der Adresse 0716 zuständig. Ein Schreiben des Inhaltes &B00010000 in das Register\n0716 setzt die Zeitbasis in Betrieb.\nWie man im nebenstehenden\nBeispiel einer SekundenRoutine sehen kann, wird\ndort einmal die LED periodisch zum Blinken gebracht, es wird alle Sekunde\ndie aktuelle Uhrzeit aus dem\nDS1307 ausgelesen und auf\ndem LCD03 zur Anzeige gebracht, und es wird ein Betriebs-Sekundenzähler hochgezählt, dessen Inhalt ebenfalls sekundlich auf dem\nLCD03 angezeigt wird.\nEin Speicher, der nicht vergisst:\nProgrammierung des I2C-Eeprom\nMit der Inbetriebnahme des AT24C16, eines I2C-Eeprom, wird nach dem LCD03 und der\nEchtzeituhr DS1307 der Reigen der Chips am I2C-Bus des ATmega168 vorerst abgeschlossen. Wie auch schon bei der Echtzeituhr, liegt auch hier der klare Vorteil dieses Chips in seiner Restart-Festigkeit, d.h. auf einmal in diesem Speicher abgelegte Werte kann wieder zugegriffen werden, auch wenn die Schaltung einen Stromausfall gehabt hat.\nDas Lesen vom Eeprom bzw. das Schreiben zum Eeprom ist an und für sich eine einfache Sache, indem ähnlich wie schon beim DS1307 der Chip mit einer Einheitenadresse adressiert\nwird und mit einem weiteren Byte die gewünschte Byte-Adresse angegeben wird. Es gibt aber\nbeim Umgang mit dieser Einheiten- und Byte-Adresse eine Spitzfindigkeit, die sehr leicht bei\nder Programmierung zu Fehlern führen kann. Haben Sie hierzu bitte die „Description“\nWie man der „Description“ entnehmen kann, verfügt der Eeprom über eine Einheitenadresse\nund eine dort so genannte „Word“-Adresse. Mit der „Word“-Adresse (von 8 Bit) kann man\n255 Bytes adressieren. Bei einem AT24C16 haben wir es jedoch mit 2048 Bytes zu tun. Hierfür wird, wie man sich leicht überzeugen kann, ein Adressraum von 11 Bit benötigt. Die fehlenden 3 Bit sind laut „Description“ mit in der Einheitenadresse enthalten. Leider ist es nun\nso, dass in der Einheitenadresse in dem LSB noch „Read/Write“ verschlüsselt ist. Man kann\nalso Einheiten- und „Word“-Adresse leider nicht als einen „Integer“, bestehend aus 2 Bytes,\nauffassen und diesen Wert beim Hochzählen der fortlaufenden Speicheradressen einfach inkrementieren.\nDas Beispiel hier gilt erst\nfür das nächste Programm,\naber es sei hier schon besprochen, weil es in diese\nThematik gehört. Beim\nblockweisen Schreiben bzw.\nLesen von Eeprom-Informationen, wird die fortlaufende\nEeprom-Adresse selbst im\nEeprom verwaltet und bei\nBedarf von dort geholt bzw.\nauch upgedatet. Da die\n„Word“-Adresse ja immer\nstimmt, brauchen wie als\nProgrammierer nur die Einheitenadresse zu „editieren“.\nDas geschieht mit Shift Eeprom_lfd_adresse_msb , Left , 1\nAnschluss der Prellunterdrückung\nvia Pin Change Interrupt\nMit dem Anschluss der Prellunterdrückung an das Board kommen wir unserem Ziel ein entscheidendes Stück näher, den Verbrauch eines Heizölbrenners zu erfassen und auszuwerten.\nIn der Sammlung der Schaltungskomponenten, die wir an das Board angeschlossen haben,\nfehlte ja bisher noch diejenige Komponente, die es gestattet, die Ein-und Ausschaltereignisse\ndes Heizölbrenners zu erfassen. Hierfür ist jetzt eine Schaltung mit dem Timer 555 vorgesehen.\nUrsprünglich war für die Übertragung des Ein/Aus-Signals des Heizölbrenners zum Mikroprozessor eine Funk-Übertragungsstrecke aus dem FS20-System der Firma ELV vorgesehen.\nDer erhoffte Vorteil war einerseits die perfekte galvanische Trennung des 230V-Signals vom\nMikroprozessor und andererseits die Möglichkeit, den Mikroprozessor auch außerhalb des\nKellerraum platzieren zu können.\nAllerdings stellte sich nach längerfristigen Tests auch nur innerhalb des Kellerraums heraus,\ndass offenbar auch auf dieser kurzen Übertragungsstrecke Signale verloren gingen. Das machte sich darin bemerkbar, dass die erfassten Betriebsstunden am Mikroprozessor und die erfassten Betriebsstunden an der Ölheizung auseinander drifteten mit der Tendenz, dass der Mikroprozessor mehr Betriebsstunden anzeigte als die Ölheizung. Da einerseits eine Diagnose des\nFunkverkehrs auf der Übertragungsstrecke im FS20-System nicht vorgesehen ist und andererseits das Funkprotokoll des FS20-Systems ohne Quittungen arbeitet (Simplex-Übertagung),\nwar eine eindeutige Fehlerfindung unmöglich.\nDie Fehlereingrenzung wurde durch eine Modifikation des Mikroprozessorprogramms herbeigeführt. Hierbei zeigte sich, dass auch in den Sommermonaten Brennerlaufzeiten erfasst wurden, die mehr als eine Betriebsstunde ausmachten, und dies völlig unregelmäßig, jedoch im\nDurchschnitt ca. alle drei Tage. Somit war die Unsicherheit dieser Funkübertragungsstrecke\nbewiesen. Der erhoffte Vorteil, die Funkübertragung auch nach außerhalb des Kellerraums\nvornehmen zu können, erwies sich ebenfalls als nicht gegeben.\nDeshalb wurde die Idee einer Funkübertragungsstrecke fallen gelassen und nach einer Alternative gesucht.\nDie hier beschriebene Lösung sieht eine transformatorische Trennung des 230V-Signals vom\nMikroprozessor vor durch den Einsatz eines USB-Netzteils. Hierbei wird die Primärseite des\nUSB-Netzteils an die geschaltete Brennerspannung gelegt und die Sekundärseite liefert ein\nEin-Aus-Signal im 5V-Bereich an den Mikroprozessor. Da auch der Verdacht bestand, dass\ndas 230V-Signal prellen könnte, wurde ein Timer 555 als Monoflop der Sekundärspannung\nnachgeschaltet, um Kontaktprellungen und damit eventuelle Mehrfachinterrupts zu eleminieren.\nMit der Einführung dieser Schaltung war das Problem der Fehlzählungen der Betriebsstunden\nDer Abgriff der geschalteten Brennerspannung macht einen Eingriff in das Heizungssystem erforderlich, den nur ein Fachmann vornehmen sollte. Wenn Sie nicht selbst autorisierter Fachmann sind, rate ich von einem persönlichen Eingriff ab !\nIhr Heizungsmonteur kann Ihnen ein Kabelende aus dem Heizungs-Schaltkasten herauslegen,\ndas die geschaltete Brennerspannung führt und an dem sich eine Schuko-Muffe befindet. Hier\nkann dann das USB-Netzteil bequem angesteckt werden.\nDie Schaltung für die Prellunterdrückung mit dem Timer 555\nWie bereits beschrieben, wird die Primärseite des USB-Netzteils an die geschaltete Brennerspannung gelegt und die Sekundärseite liefert ein Ein-Aus-Signal im 5V-Bereich an den Mikroprozessor. Da dieses Signal prellbehaftet sein könnte, wurde die folgende Schaltung entwickelt. Wenn der Eingang einmal auf „High“ gegangen ist, wird der Ausgang für eine Sekunde für jeden weiteren Wechsel gesperrt. Praxistests haben gezeigt, dass der Betriebsstundenzähler am Heizölbrenner und der mit dem Mikroprozessor realisierte Betriebsstundenzähler\njetzt auch langfristig synchron laufen.\nDie oben abgebildete Schaltung wurde mit dem Simulationsprogramm „Electronics Workbench“ Version 5.12 entwickelt. Es wird im folgenden unterstellt, dass der Leser mit Elektronik im allgemeinen und der Schaltungstechnik der Timer 55 im besonderen einigermaßen vertraut ist.\nZunächst zeigt die Abbildung zwei Eingangsspannungen V2 und V3. Hiervon ist V2 die allgemeine Spannungsversorgung, die in der Praxis von der Spannungsversorgung des Mikroprozessors bezogen wird. Mit der Spannungsquelle V3 und dem Schalter S1 werden die Ein37\nschaltvorgänge des Heizölbrenners simuliert. Beide Spannungsversorgungen haben eine gemeinsame Erde.\nWeiter zeigt die Abbildung insgesamt drei Timer 555. Von diesen drei Timern ist der mittlere\nmit der Bezeichnung U1 das eigentliche zeitbestimmende Glied. Dieser Timer ist als Monoflop geschaltet, das heißt, der Ausgang der Schaltung reagiert nicht auf jeden beliebigen\nWechsel am Eingang, sondern erst nach einer gewissen Zeit. Diese Totzeit ist in der vorliegenden Schaltung durch das RC-Glied R1C3 festgelegt. Laut Dimensionierung beträgt diese\nZeit eine Sekunde, das heißt, dass der Ausgang erst nach dem Ablauf von einer Sekunde auf\nerneute Wechsel am Eingang reagiert. Damit ist ein eventuelles eingangsseitiges Relais-Flattern wirkungsvoll eliminiert.\nDa der Eingang des Timers U1 als Auslösung ein „Active Low“ erwartet, anderseits aber das\nEinschaltsignal „Active High“ liefert, ist es erforderlich, das Eingangssignal zu invertieren.\nDeshalb muss in diesem Falle ein Inverter vorgeschaltet werden. Diese Funktion übernimmt\nder Timer U2.\nÄhnlich ist es beim Ausgang. Hier erwartet der Mikroprozessor ein „Active Low“ für einen\nEinschalt-Interrupt. Deshalb ist dem Monoflop U1 der Inverter U3 nachgeschaltet, um diese\nBedingung zu erfüllen.\nDas Oszillogramm zeigt das Ausgangssignal in Relation zum Ladezustand des RC-Gliedes.\nMit dem Schalter S1 wurde ein schneller Einschaltwechsel (unter einer Sekunde) simuliert.\nDas Ausgangssignal zeigt dabei, das auf diese schnellen Einschalt-Wechsel nicht reagiert\nwird. Die ebenfalls dargestellte Ladekurve des RC-Glieds zeigt, dass ein Wechsel an der Ausgangsseite erst dann erlaubt wird, wenn die Ladespannung am RC-Glied 2/3 der Spannungsversorgung erreicht hat.\nDie restliche Beschaltung mit den Kondensatoren C2 und C4 sowie dem Widerstand R2 dient\nder Unterdrückung der Aktivität des Timers U1 beim Einschalten der Versorgungsspannung\nDie folgende Abbildung ist stellt die Schaltung als konkreten Schaltplan dar. Dieser Schaltplan wurde mit dem Programm „Eagle Version 6 Light Edition“ erstellt.\nWie man sieht, wird hier der Baustein 556 eingesetzt. Er enthält zwei identische Timer 55 auf\neinem Chip. Die Stromversorgung wird von extern vom Mikroprozessor herbeigeführt. Der\nSignaleingang wird von dem USB-Netzteil herbeigeführt, welcher primärseitig mit dem Ölbrenner verbunden ist. Der Ausgang der Schaltung liegt direkt am Interrupt-Eingang des Mikroprozessors.\nDie folgende Abbildung zeigt die Realisierung der Schaltung auf einer so genannten Eurocard.\nDiese Eurocard hat ein Lötpunktraster von 2,54 mm. Als Verdrahtungsmethode wurde „wire\nwrap“ verwendet. Das setzt die Verwendung von Stiftsockeln voraus. Natürlich ist die Verdrahtungsmethode Geschmackssache und bleibt dem Nachbauer überlassen.\nWegen der „wire\nwrap“-Methode siehe auch den Anhang\nDer Pin-Change-Interrupt des Atmega168\nHaben Sie für dieses Kapitel bitte wiederum die „Description“ für den ATmega168 bereit.\nSiehe http://www.atmel.com/dyn/resources/prod_documents/doc2545.pdf , obwohl hier leider\ngesagt werden muss, dass die Beschreibung für den „Pin-Change-Interrupt“ alles andere als\neine Bettlektüre ist. Sage mir keiner mehr etwas Schlechtes über das Juristen-Deutsch, dieses\nTechniker-Englisch hier stellt das locker in den Schatten. Dieses Manko setzt sich übrigens\nfort im „Bascom-Help“, was den „Pin-Change-Interrupt“ mit keinem Wort erwähnt. Man ist\nhier völlig auf sich selbst gestellt. Ich habe neuere Veröffentlichungen hierüber nicht studiert,\nbessere Darstellungen wären hier wünschenswert. Aus diesem Grunde möchte ich hier den\nVersuch machen, eine kleine Beschreibung zu liefern, die halbwegs dem normalen Menschenverstand entspricht.\nSchauen Sie sich hierzu bitte zunächst einmal in der „Description“ auf Seite 2 die „Pin Configurations“, z.B. für das PDIP-Gehäuse genau an. Auf den ersten Blick ist alles ganz einfach:\nman kann leicht erkennen, welche Port-Pins welchem Gehäuse-Pin zugeordnet sind. Was jedoch vom Anfänger leicht übersehen wird, ist eine ganz fundamentale Eigenschaft der ATmega-Mikroprozessoren, dass nämlich die verschiedenen Pins für ganz verschiedene Funktionen\nverwendet werden können. Diese verschiedenen Funktionen werden im allgemeinen durch das\nLaden spezieller Register ermöglicht, was natürlich in der Obliegenheit des Programmierers\nliegt. Die Namen der alternativ möglichen Funktionen eines Pins sind in den „Pin-Configurations“ in Klammern dargestellt. So sehen Sie z.B., dass der Gehäuse-Pin 17, auf dem normalerweise Port B Pin 3 liegt (PB3), alternativ als „PCINT3“ fungieren kann. Der Name steht für\n„Pin-Change-Interrupt“. Diese Kenntnis der Nomenklatur dieser Begriffe wird von den Verfassern stillschweigend vorausgesetzt, wenn es um die Beschreibung des „Pin-Change-Interrupt“ in der „Description“ ab Seite 69 geht. Dies vorweg.\nNun wird sich der unbefangene Leser zunächst fragen, was das ganze Trara mit dem „PinChange-Interrupt“ denn eigentlich soll. Wir haben ja bereits zwei externe Interrupts des ATmega168 kennen gelernt, nämlich den „INT0“ auf Port D Pin 2 bzw. Gehäuse-Pin 4 und\n„INT1“ auf Port D Pin 3 bzw. Gehäuse-Pin 5, und die auch erfolgreich implementiert. Wenn\nes um weitere Interrupts gehen soll, sollte sich diese Systematik doch einfach auf weitere Pins\nerweitern. Dem ist aber nicht so. Die Begründung hierfür muss ich Ihnen schuldig bleiben. Ich\nkann hier nur vermuten, dass dieser Bruch mit der Kontinuität bzw. der Diskontinuität der\nEntwicklungsgeschichte dieser Mikroprozessoren zu tun hat. Für eine erfolgreiche Anwendung ist es aber unumgänglich zu wissen, dass es zwei verschiedene Sorten von Interrupts\nbeim ATmega168 gibt und dass diese unterschiedlich programmiert werden.\nDer „Pin-Change-Interrupt“, der jetzt behandelt werden soll, müsste eigentlich „LevelChange-Interrupt“ heißen, weil für ihn typisch ist, dass jede Änderung des Spannungspegels\nan dem betreffenden Pin, also von „Hi“ auf „Lo“ als auch von „Lo“ auf „Hi“ einen Interrupts\nerzeugt, was letztlich einen „Branch“ in die Vektortabelle des Mikroprozessors bedeutet. Das\nist aber nicht der entscheidende Unterschied zu den beiden externen Interrupts „INT0“ und\n„INT1“, denn die kann man durchaus auch so programmieren. Entscheidend ist die unterschiedliche Programmierung dieser neuen Interrupts mit anderen Registern, und diese Tatsache muss man wohl oder übel hinnehmen. Da lohnt kein „Philosophieren“.\nWeil das nun eben mal so ist, wenden wir uns der praktischen Frage zu, wie diese neuen Interrupt zu programmieren sind, und das läuft, wie bereits angedeutet, auf die Frage hinaus, welche Register wie geladen werden müssen, um z.B. aus dem Gehäuse-Pin 17 bzw. Port B Pin 3\neinen „Pin-Change-Interrupt“ zu machen und welcher Interrupt-Vektor in diesem Fall angesteuert wird. Allerdings, - und das sei hier hervor gehoben -, müssen wir uns als Programmierer darauf einstellen, dass wir bei jedem „Level-Change“ an dem betreffenden Pin einen Interrupt erwarten müssen, und das bedeutet für einen Impuls von „Hi“ auf „Lo“ und wieder zurück auf „Hi“ zwei Interrupts. Es gibt keine Möglichkeit, nur auf die steigende oder fallende\nFlanke des Impulses zu reagieren wie bei „INT0“ und „INT1“.\nFerner ist bei der Programmierung auch noch zu beachten, dass im Gegensatz zu „INT0“ und\n“INT1“ bei den „Pin-Change-Interrupts“ nicht mehr für jeden einzelnen Interrupt-Pin eine eigene Branch-Vektor-Adresse zur Verfügung steht. Die Branch-Vektor-Adressen beziehen sich\nauf einen ganzen Port, nicht auf einen einzelnen Pin. Das heißt für den Programmierer, dass er\nfür den Fall, dass mehrere Pins an einem Port als „Pin-Change-Interrupt“ definiert sind, programmiertechnisch sicherstellen muss, welcher Pin an dem betreffenden Port nun gerade den\nInterrupt ausgelöst hat (durch Auslesen des Ports).\nPin-Change-Interrupt in Bascom , Definitionsteil\nNach all der tiefschürfenden Theorie entpuppt sich die praktische Programmierung als schiere\nLeichtigkeit. Wir stellen uns zur Aufgabe, Port B Pin 0 bis Pin 3 für das Schaltmodul\n„FS20SM“ als „Pin-Change-Interrupt“ zur Verfügung zu stellen.\nHiermit werden die betreffenden Pins als Input konfiguriert.\nOn Pcint0 Portb_int_routine\nHier wird für den Branch-Vektor PCINT0 die Adresse der (noch zu schreibenden InterruptRoutine definiert.\nHiermit werden die Pull-up-Widerstände für die Pins aktiviert.\nPcmsk0 = &B00001111\nDiese Instruktion lädt das „Pin Change Mask Register 0“ auf einen Wert, so dass die Pins\nPCINT0, PCINT1, PCINT2 und PCINT3 „enabled“ werden. Siehe „Description“ Seite 70.\nDie Instruktion „enabled“ Interrupts auf der Branch-Adresse PCINT0. Siehe „Description“\nUnd das war es schon, was die Definitionen betrifft.\nPin-Change-Interrupt in Bascom , Interrupt-Routine\nZum besseren Verständnis des Aufbaus der Logik sei hier kurz rekapituliert, welche Situation\nder Programmierer hier behandeln muss. Wenn diese Routine angesteuert wird, hat sich ein\n„Level-Change“ an einem der Pins PCINT0, PCINT1, PCINT2 oder PCINT3 ereignet (es\nkönnen auch mehrere gleichzeitig gewesen sein).\nHinweis: In Bezug auf unsere Schaltung wird es zwar nur einen Interrupt geben, nämlich den\nan PCINT3 (denn wir haben nur einen Heizölbrenner), aber wir wollen diese Routine gleich\nso gestalten, dass später bis zu vier Interrupts gehandhabt werden können.\nDa wir zunächst nicht wissen, welcher Pin den Interrupt ausgelöst hat, müssen wir dies erst\neinmal durch Auslesen der Pins feststellen.\nWichtig: Hierbei soll gelten, dass ein „Level-Change“ von „Hi“ nach „Lo“ einen Einschaltvorgang bedeutet, und ein „Level-Change“ von „Lo“ nach „Hi“ einen Ausschaltvorgang.\nNeben dem aktuellen Level des Pins, den wir durch Auslesen ermitteln, müssen wir also auch\nden Level „vorher“ des Pins kennen. Da es ja mehrere Interrupts (nacheinander) geben kann,\nkann es passieren, dass z.B. ein gegebener Pin mehrfach auf „Lo“ ausgelesen werden kann,\nsich an diesem Pin aber keine Aktivität ereignet hat. Dieser „Vorher“-Level wird programmiertechnisch durch einen Schalter namens Pin_level_vorher (aufgeteilt in vier Bits), festgehalten und verwaltet. Mit Bezug auf die gesamte Programmstruktur kommen wir somit zu\neinem Konstrukt, in dem wir für jeden Pin feststellen können, ob es sich um einen Ein- oder\nDie Abbildung zeigt den\nTeil der Interrupt-Routine,\nder den Pin 3 für den aktuellen Heizölbrenner-Interrupt\nbehandelt. Hierbei ist die\nals Vehikel zu verstehen,\nmit dem dieses Interrupt-Ereignis auch außerhalb der\nwerden kann. Im vorliegenden Fall wird dies in der Sekunden-Routine verwendet,\ndamit man dort weiß, wann\nder Betriebs-Sekundenzähler erhöht werden muss. Der Rest sei dem Leser zum Selbststudium überlassen.\nHier wird das Zusammenspiel zwischen der Interrupt-Routine und der Sekunden-Routine\nmit Hilfe der Variablen\nZusammengefasst kann man\nalso festhalten, dass das Ereignis „Brenner ein“ zunächst in der Interrupt-Routine durch Analyse des PortZustandes erfasst wird, und\ndass dann das Hochzählender Brenner-Sekunden in der\nRoutine für den SekundenInterrupt\nwird. Entsprechend stoppt\ndas Ereignis „Brenner aus“\ndann wieder diesen Vorgang.\nDie vorliegende Struktur erlaubt dabei die gleichzeitige\nBehandlung von vier solchen\nMit Bezug auf unser praktisches Projekt „Erfassung der Einschaltzeiten eines Heizölbrenners“ könnte eine denkbare und nahe liegende Erweiterung die zusätzliche Erfassung der Einschaltzeiten der Kondensatpumpe sein (Brennwertkessel) bzw. die daraus errechenbare Menge\ndes abgeführten Kondensats. Ich denke, das könnte manche unangenehme Wahrheit über den\nWert von Brennwertkesseln an den Tag bringen, aber das steht hier nicht zur Diskussion.\nDas Projekt „Heizölverbrauch“,\ndie End-Version des Programms\nEinsatz der Prellunterdrückung mit Timer 555\nDieses Programm ist die komplette End-Version unseres Projektes „Heizölverbrauch“.\nGegenüber dem Programm Programm_9_Timer55 wird hier von der sekundenweisen Erfassung und Fortschreibung der Einschaltzeiten eine stundenweise Fortschreibung der Einschaltwerte eingeführt, was in der Praxis vollkommen ausreicht. Die bereits bestehende Programmstruktur ist ansonsten die gleiche geblieben, d.h. mit Ausnahme von kleineren Anpassungen\nwerden hier dieselben Routinen benutzt wie im Vorgänger-Programm.\nNeu hinzugekommen ist in diesem Programm die Erfassung und Fortschreibung des aktuellen Tankstandes auf dem Eeprom. Hierzu ist es erforderlich, dass die erfasste Zahl der Betriebsstunden in Heizölverbrauch in Litern umgerechnet werden muss. Natürlich hängt der\nVerbrauch einerseits von der Zahl der Betriebsstunden ab und andererseits von den Eigenschaften des Heizölbrenners, hier besonderes von der verwendeten Brennerdüse. Es gilt nun,\ndiesen Düsendurchsatz in Litern/Stunde zu ermitteln. Hierüber gibt im allgemeinen das Typenschild auf dem Heizölbrenner Auskunft. Hier ist der Brennerdurchsatz allerdings oft in\nkg/Stunde angegeben. Die Umrechnung erfolgt nach der Formel\nDurchsatz [cl /h]=100∗Durchsatz [kg / h]/ Heizöl [kg /l ]\nHierbei ist ρHeizöl = 0,86 [kg/l] die Dichte von Heizöl EL. Bei einem typischen Brennerdurchsatz von 1,7 kg/h für eine 17 kW-Heizungsanlage betrüge der Umrechnungsfaktor also 198\ncl/h, das heißt, nach jeder abgelaufenen Brenner-Betriebsstunde wären 198 Zentiliter vom aktuellen Tankinhalt abzuziehen, und das ist genau das, was in dem Programm verwirklicht ist.\nDer Umrechnungsfaktor kann durch Verändern der Konstante\nConst Tank_liter_pro_stunde = 198 [cl/h]\nangepasst werden. Zu den Gründen für die Wahl der Einheit „Zentiliter“ siehe den Kommentar im Quellcode.\nWeitere Änderungen und Ergänzungen betreffen hauptsächlich das Auswahlmenü, das vom\nTerminal-Emulator angesteuert werden kann. Im wesentlichen sind hier hinzu gekommen die\nOptionen für die Modifikation der Anfangswerte der Gesamt-Betriebsstunden wie auch des\naktuellen Tankinhaltes. Hinzugekommen ist auch die Erfassung des Heizölverbrauchs auf Tagesbasis und deren Fortschreibung auf Eeprom. Die erfassten Tagesverbräuche können z.B.\neinmal monatlich vom Eeprom gelesen werden und z.B. zur graphischen Darstellung einer\nExcel-Tabelle zugeführt werden. Hier können die Verbräuche z.B. mit entsprechenden Temperaturdaten korreliert werden.\nBei diesem Programm ist\nweiterhin eine der endgültigen\nentsprechende Modifikation der Anzeige auf dem\nI2C-Display vorgenommen worden.\nIn Zeile 1 werden jetzt\ndie Gesamt-Betriebsstunden angezeigt. In Zeile 2\nsteht jetzt der aktuelle\nTankinhalt in Litern, Zeile\n3 enthält den aktuellen\nVortages-Verbrauch, Zeile 4 zeigt den Betriebszustand des Brenners sowie die abgelaufenen\nBrenner-Sekunden pro Brennperiode an.\nEine Verdrahtungshilfe für „wire wrap“\nBei der wire wrap-Methode, zu deutsch „Wickelmethode“, werden die Leiterverbindungen einer Schaltung statt auf Leiterbahnen auf einer gedruckten Platine hier mit einem speziellen,\nisolierten Schaltdraht verwirklicht, dessen abisolierte Enden um speziell dafür gemachte Wickelpfosten herumgewickelt werden. In der Praxis werden diese Wickelpfosten durch spezielle wire wrap-Sockel realisiert, in die einerseits von der Bauteilseite her die ICs eingesteckt\nwerden können. Auf der Lötseite ragen die speziellen Pfosten weit genug über die Platine hinaus, so dass hier bis zu ca. drei Wickel für die Drahtverbindungen aufgebracht werden können. Die zugehörige Platine enthält also keine Leiterbahnen, sondern nur ein Lötpunktraster\nfür das Befestigen der IC-Sockel. Für die Herstellung der Wickel gibt es spezielle Wickelstifte, die eine perfekte Aufwicklung der Drahtenden gewährleisten. Auch der hierzu gehörige\nspezielle Wickeldraht ist auf diese Bedürftnisse abgestimmt.\nDie wire wrap-Methode stammt aus den 60er Jahren und wird heute nur noch sehr selten industriell angewendet. Da bei dieser Methode aber praktisch jede einzelne Verbindung auch im\nNachhinein verändert werden kann, ist sie insbesondere bei Einzelplatinen und Versuchsaufbauten nach wie vor interessant.\nDie Zuverlässigkeit der wire wrap-Methode\nSofern man beim wire wrap den dafür vorgesehenen Wickelstift, die dafür vorgesehenen Sockel und den dafür vorgesehenen Draht verwendet, ist die Wickelverbindung absolut perfekt.\nRichtig angewendet, werden zunächst ca. drei Windungen mit isoliertem Draht aufgewickelt\nund der Rest perfekt Windung für Windung auf den Stift gewickelt. Da die Sockelstifte Vierkante sind, wird der Draht an den Kanten nach Art einer Kaltschweißung „einschweißt“, und\nso kann sich die Verbindung normalerweise nicht lösen. Andererseits kann die Verbindung\nspielend leicht gelöst werden, wenn man mit dem anderen Ende des Wickelstiftes den Draht\nim entgegengesetzten Sinne löst. Dann lässt der Wickel sich nach ein paar Umdrehungen\nleicht nach oben abziehen.\nDie Unzuverlässigkeit und damit allgemeine Unbeliebtheit der Wickelmethode kommt allein\ndurch die manuelle Tätigkeit des Menschen ins Spiel. Er ist es, der den Wickeldraht auf die\nrichtige Länge abisolieren muss, er ist es, der die richtigen Sockelstifte für die Drahtverbindung auswählen muss. Wenn das Bild einigermaßen ordentlich sein soll, dann muss er die\nDrahtlänge so wählen, dass sie gerade reicht.\nDas Hauptproblem aber ist, dass beim Wickeln konsequenterweise die Lötseite der Platine\noben ist. Von der Schaltung her ist man es aber gewohnt, auf die Bauteilseite zu sehen. Die\nAnschlussstiftdarstellungen von ICs in der Literatur gelten immer von der Bauteilseite. Die\nLötseite aber, auf der gewickelt werden muss, ist das Spiegelbild der Bauteilseite. Dies erfordert ein „Umdenken“ und dies ist eine nicht zu unterschätzende Fehlerquelle.\nDie folgenden Bilder zeigen ein- und dieselbe Drahtverbindung, einmal von der Bauteilseite\ngesehen und einmal von der Lötseite gesehen.\nHier wird der Umdenkprozess deutlich, der erforderlich ist, wenn eine Drahtverbindung von\nder Lötseite gesehen realisiert werden muss.\nEine weitere Fehlerquelle ist die korrekte „Buchführung“ darüber, welche Verdrahtungen einer Schaltung bereits durchgeführt worden sind und welche nicht. Ferner wäre es auch wünschenswert, wenn die Länge des abzulängenden Drahtes bekannt wäre.\nGenau an dieser Stelle setzt die „Verdrahtungshilfe“ an. Sie gestattet es, jede einzelne Verdrahtung zu erfassen, zu verwalten und jede einzelne Verdrahtung nach Belieben sowohl von\nder Bauteilseite als auch von der Lötseite darzustellen.\nWenn man die Bauteile auf der Platine ein wenig gruppiert wie oben gezeigt, dann ist es erheblich leichter, den Wickelstift auf dem richtigen Pin anzusetzen, ohne die Pinbedeutung zu\nverinnerlichen. Die Verdrahtungshilfe zeigt die Von- und Zu- Pinbezeichnung allerdings auch\nzusätzlich an. Das folgende Beispiel eines Displays der Verdrahtungshilfe illustriert diese Situation.\nWie man sieht, ist für eine gegebene Drahtverbindung ist zugehörige Information dargestellt.\nDie Verdrahtunghilfe im einzelnen\nDie für die Verdrahtungshilfe erforderlichen Daten werden in einer Excel-Tabelle geführt. Für\ndie Erfassung und Verwaltung dieser Daten stehen Dialoge als Makros zur Verfügung, die in\nExcel-VBA geschrieben worden sind.\nDie Erfassung der Chip-Layouts\nZunächst werden die Chip-Layouts erfasst, die auf der Platine vorkommen. Diese Information\nwird benötigt, um später die IC-Sockel richtig darstellen zu können. Das folgende enthält hierfür ein selbst erklärendes Beispiel. Es ist hier die Situation dargestellt, in der einer bereits zum\nTeil existierenden Tabelle ein weiterer Eintrag hinzugefügt wird.\nMan sieht das Layout dieser Tabelle mit den verschiedenen notwendigen Angaben über die zu\nerfassenden Chip-Layouts sowie den Dialog, mit dem diese Angaben erfasst werden können.\nWenn nach der Eingabe eines Chip-Layouts auf die Taste „Speichern“ gedrückt wird, erscheinen die erfassten Daten an entsprechender Stelle in der Tabelle.\nDie Erfassung der Chip-Typen\nMit der Erfassung des Chip-Typs wird einmal der Name des Chip-Typs (z.B.NE556) festgelegt und zum anderen über eine Auswahl-Box ein Rückbezug auf die betreffende Chip-Layout\nEintragung vorgenommen. Mit Drücken von „Speichern“ erscheint der Eintrag in der Tabelle,\ndie im Hintergrund dargestellt ist. Auch hier ist die Situation einer bereits zum Teil existierenden Tabelle dargestellt.\nChip Id auf Eurocard\nMit diesem Dialog wird jeder einzelne Chip, der auf der Platine erscheinen soll, erfasst. Der\nChip muss einen eindeutigen Namen haben. Eine Auswahlbox gestattet den Rückbezug auf einen vorher eingegebenen Chip-Typ.\nAls Platine ist das Format einer Eurocard vorgesehen. Die anzugebenden Koordinaten auf der\nEurocard sind Lochkoordinaten. Lochkoordinaten zählen von oben links und beziehen sich in\nder Regel auf den linken oberen Pin von der Bauteilseite her gesehen. Ferner kann man die\nLage des Chips angeben, ob breit oder quer.\nNach Drücken der Taste „Speichern“ erscheint der Chip in der Tabelle.\nAuch hier ist die Situation einer zum Teil bereits existierenden Tabelle dargestellt.\nErfassung der Verdrahtungen\nDieser Dialog gestattet die Erfassung jeder einzelnen Verdrahtung. Hierbei gestatten Auswahl-Boxen den Rückbezug auf bereits erfasste Chips auf der Eurocard. Die Pin Nummern\nsind frei wählbar. Wenn auf „Speichern“ gedrückt wird, erscheint die Verdrahtung in der Tabelle. Auch hier ist die Situation einer zum Teil bereits existierenden Tabelle dargestellt.\nAn dieser Stelle sei ausdrücklich auf eine Gefahr hingewiesen, die dieses Konzept der Rückbezüge in sich birgt. Natürlich kann der Excel-Benutzer jederzeit selbst in die Tabellen eingreifen und z.B. Zeilen in den Tabellen hinzufügen bzw. löschen.\nHiermit wird jedoch die Rückbezüglichkeit zerstört.\nMan unterlasse dies bitte tunlichst und verwende nur die vorgesehenen Dialoge. Die Löschung von Verdrahtungen wird noch besprochen.\nDarstellung von der Lötseite\nDas obige Bild zeigt in diesem Beispiel die Darstellung der Verdrahtung Nr. 12 von der Lötseite. Oben sind die beteiligten Chips und Pins der Verdrahtung dargestellt, sowie die Drahtlänge. Aufgrund der Darstellung können die zu verdrahtenden Pins leicht lokalisiert werden.\nWie man sieht, ist der Status dieser Verdrahtung „erfasst“, das heißt, die Verdrahtung ist erfasst, aber noch nicht verdrahtet. Wenn man diese Verdrahtung vorgenommen hat, kann man\nihr mit der Taste „verdrahtet“ den Status „verdrahtet“ geben. So weiß man später, welche Verdrahtungen noch durchgeführt werden müssen.\nDarstellung von der Bauteilseite\nDas Bild zeigt die eben erfasste Verdrahtung Nr. 12 nun von der Bauteilseite. Man kann die\nExistenz dieser Verdrahtung nun z.B. mit dem Ohmmeter prüfen und ihr durch Drücken der\nTaste „geprüft“ den Status „geprüft“ geben.\nFalls man sich entschließt, dass diese individuelle Verdrahtung gelöscht werden soll, dann\ndrückt man die Taste „gelöscht“. In diesem Falle wird diese Verdrahtung nicht physisch aus\nder Tabelle gelöscht, sondern nur mit einem Kennzeichen versehen. Spätere Bezüge auf diese\nVerdrahtung bringen dann eine Meldung „gelöscht“.\nEs sei hier zum Schluss gesagt, dass diese Verdrahtungshilfe sicherlich keinen Anspruch auf\n„professionelle Software“ erhebt. Es mögen noch Fehler enthalten sein. Aber es hat sich in der\nPraxis gezeigt, dass die Verdrahtungshilfe von sehr großem Nutzen ist. Der Verfasser stellt sie\nauf Anfrage auf der Basis „as is“ gern zur Verfügung. Voraussetzung ist Microsoft Excel\n2003 oder höher. Die Makros sind in VBA geschrieben worden. VBA ist Bestandteil von Excel. Zur Verfügung gestellt wird eine ausgefüllte Beispieltabelle sowie eine Leertabelle für die\nVerdrahtungshilfe, deren Bestandteil das Makro Eurocard ist. Die Tabelle sollte in der hier\ndokumentierten Reihenfolge ausgefüllt werden, d.h. zuerst die Chip Layouts, dann der ChipTyp, usw. Dies ist wegen der Rückbezüge zwingend. Zum Ausfüllen sollten nur die DialogMakros verwendet werden. Spätere Hinzufügungen am Ende der Tabelle sind jederzeit mit\nHilfe der Dialog-Makros möglich. Der Rest ist selbsterklärend.\nEine Auswertung der gespeicherten Ölverbräuche\nund separat erfassten Außentemperaturen\nmit dem Excel Diagramm-Manager\nDie Außentemperaturen wurden mit dem Temperaturlogger TFD128 der Firma ELV erfasst.\nDa der TFD128 alle 5 Minuten eine Temperaturaufzeichnung macht, entsteht hier zunächst\nein „Datenfriedhof“ von ca. 8600 Einträgen pro Monat. Diese Daten werden daher mit einem\nExcel Makro auf je einen Durchschnittswert pro Tag und pro Nacht reduziert. Zu der entstandenen Excel-Tabelle wurden die gespeicherten Ölverbräuche vom Eeprom dieser Schaltung\nhinzu gemischt. Das Diagramm wurde mit dem Excel-Diagramm-Manager erstellt.


Analyse: Analyse-Flash: Cheuvreux belässt Porsche auf „Selected List“\nAnalyse Analyse-Flash: Cheuvreux belässt Porsche auf „Selected List“\nCheuvreux hat Porsche-Aktien nach Presseberichten über den Erhalt eines Kredits von Volkswagen (VW) mit einem Kursziel von 93,00 Euro auf der "Selected List" belassen.\n25.05.2009 - 14:12 Uhr\ndpa-afx FRANKFURT. Cheuvreux hat Porsche-Aktien nach Presseberichten über den Erhalt eines Kredits von Volkswagen (VW) mit einem Kursziel von 93,00 Euro auf der "Selected List" belassen. Eine Fusion oder Übernahme von VW und Porsche sei wahrscheinlicher als jemals zuvor, schrieb Analyst Alexander Neuberger in einer Studie vom Montag. Dabei sei es gleichgültig, ob es zu einem Zusammenschluss komme oder Porsche von VW übernommen werde. Neuberger sieht in beiden Szenarien Aufwärtspotenzial für die Porsche-Papiere. Der Wert des VW-Anteils bei Porsche liege beim aktuellen Kurs der VW-Vorzüge über dem Wert von Porsche.


Heizöl in Feldkirch günstig bestellen - aktuelle Heizölpreise\nHeizöl Feldkirch - aktuelle Heizölpreise\nAuf dieser Seite finden Sie den aktuellen Heizölpreis, Heizöl-Charts und weitere Informationen zu Heizöl in Feldkirch. Darüber hinaus haben Sie die Möglichkeit, Ihren individuellen Heizölpreis zu berechnen und sofort online zu bestellen.\nHeizölpreise in Feldkirch (PLZ: 6800)\nLieferfrist max. 21 Werktage (Mo-Fr) bis spät. 04.08.2022\nHeizölpreis-Tagesprognose für Feldkirch\nDie Ölpreise haben gestern zum Start in den US-Handel massive Verluste erlitten und sind in der Spitze teilweise um mehr als 10 Dollar pro Barrel eingebrochen. In Folge werden auch die Heizöl-Notierungen für Feldkirch mit starken Abschlägen in den heutigen Tag starten. ... weiterlesen\nHeizölpreise für Feldkirch (PLZ: 6800) bei unterschiedlichen Abnahmemengen\nHeizöl-Chart für Feldkirch\nHeizölpreise für Feldkirch bei verschiedenen Mengen für Standard-Qualität bei einer Lieferstelle inkl. MwSt.:\nHeizölpreise in der Umgebung von Feldkirch\nÜbersaxen\t 159,60 €\nSt. Gerold\t 159,60 €\nFrastanz\t 159,60 €\nMäder\t 159,60 €\nStand: 06.07.2022, 01:15 Uhr\nHöchst- und Tiefststände der Heizölpreise in Feldkirch\nIn den angezeigten bzw. berechneten Preisen für Feldkirch sind die Fahrt- bzw. Frachtkosten vom Standort unseres Partnerhändlers nach Feldkirch bereits einkalkuliert. Preisänderungen können sich dann ergeben, wenn Sie unterschiedliche Liefermengen eingeben, oder die Anzahl der Lieferstellen verändern.\nSchon gewusst? Wir liefern überall dorthin, wo unser Preisrechner auch einen Preis ermitteln kann. Sie können also jederzeit bei uns online Heizöl für Feldkirch bestellen und auch sichergehen, dass Sie zu den angebotenen Konditionen beliefert werden.\n© 2022 Heizöl in Feldkirch günstig bestellen - aktuelle Heizölpreise