Happen von C-Code
C-Routinen, die immer wieder nützlich sind. Die Schnippsel finden zwar Einsatz auf Mikrocontrollern der AVR-Familie, aber die wesentlichen Teile sind hardware-unabhängig formuliert und ISO-C99 oder GNU-C konform.
Die Quellen sind in mehreren meiner Projekte im Einsatz. Für die grundlegenden Aufgaben haben sich über die Zeit Quellen herauskristallisiert, die einen gewissen Grad an Allgemeingültigkeit erlangt haben und die ich nicht mehr zur konkreten Verwendung anpassen muss. Daher stelle ich sie auf diese Seite, weil vielleicht noch andere etwas damit anfangen können oder in ihnen Anregungen finden.
Lösungen der vorgestellten Aufgaben wirst du auch an anderen Stellen im Internet finden. Meine Ansätze enthalten weder revolutionär Neues oder spektakuläre Tricks. Bei der Programmierung habe ich allerdings auf ein paar Punkte geachtet, die sich teilweise anscheinend widersprechen:
- Allgemeingültigkeit
-
Auf Quellebene: Die verwendeten Verfahren sollen in unterschiedlichen Projekten und unterschiedlichen µ-Controllern einsetzbar sein. So arbeitet der Countdown-Zähler mit unveränderter Quelle in verschiedenen Projekten, obwohl die Zähl-Slots erst im Projekt selbst definiert werden, oder der Dreh-Impulsgeber codiert für wählbare I/O-Ports wo er angeschlossen werden kann.
Auf Ausführungsebene: Die Programmteile sollen die Gesamtanwendung möglichst wenig beeinflussen. Warteschleifen sind zum Beispiel Tabu, weil diese je nach Umfeld, in dem diese später zum Einsatz kommen, andere Anwendungsteile lahmlegen oder zu Fehlfunktionen führen könnten. Ein RC5-Decoder, der in nach dem Prinzip "Auf RC5-Kommando warten und dann auswerten" arbeitet, ist als Standalone vielleicht ganz nett, aber diese Implementierung würde das Abarbeiten anderer Aufgaben behindern. - Effizienz
-
Für ein konkretes Projekt ist es egal, ob der verfügbare Speicher zu 99% belegt wird oder nur zu 10%. Für ein projektübergreifendes Teilmodul ist dies aber anders, denn zur Zeit der Implementierung weiß man noch nicht, wo es letztendlich eingesetzt werden wird und wie viel Splatz dann noch übrig ist. Bei der Programmierung sollte man also auch auf die Effizienz – das heißt Verbrauch an Programmspeicher, Datenspeicher, Laufzeit und Verwendung von Hardware – achten und resourcenschonend implementieren; insbesondere dann, wenn die Software auf einem System mit sehr begrenzten Resourcen wie einem kleinen µ-Controller zum Einsatz kommen soll.
Diese Forderung steht offenbar im Kontrast zur Allgemeingültigkeit, und daher gibt es bei letzterer auch ein paar Abstriche. So sind viele Variablen als 8-Bit-Werte angelegt, weil meine bevorzugte Zielhardware AVR eine 8-Bit-Maschine ist. Der Code wird zwar auch für einen 32-Bit'ter übersetzen und dort laufen, aber 8-Bit-Zugriffe sind dort in der Regel nicht optimal.
Module wie zum Beispiel ein RC5-Decoder brauchen eine Zeitbasis, die nur hardware- und compilerabhängig beschrieben werden kann. Diese Abhängigkeiten wurden jedoch nicht in die eigentlichen Routinen eingewoben, sondern werden ausserhalb ein einem hardwareabhängigen Teil abgehandelt. Durch Anpassen dieses hardwareabhängigen Teils kann man also einfach auf andere AVR-Derivate oder gänzlich verschiedene Controller portieren wie PIC, 8051, Z80, MSP430, XC16x, ... - Bibliothek oder Quellarchiv?
-
Üblicherweise werden Programmteile, die in unterschiedlichem Zusammenhang wiederverwendet werden sollen, in Bibliotheken verfügbar gemacht. Diese Bibliotheken mussen dann nur noch zu der Anwendung hinzugebunden, jedoch nicht mehr übersetzt (compiliert) werden. Dadurch sind Bibliotheken einfach verwendbar. Allerdings muss eine Bibliothek für einen bestimmten Controller/Prozessor erzeugt werden, und der Programmcode der in die Bibliothen enthaltenen Funktionen und Prozeduren ist bis auf Adresszuordnungen unveränderlich.
Ein Stück Quellcode ist also wesentlich allgemeiner, weil es nicht auf einen bestimmten Prozessor zugeschnitten sein muss. Selbst wenn es Hardwareabhängigkeiten gibt, können diese aus der Quelle herausparametrisiert werden. Aus diesem Grund – und weil es sich hier immer nur um sehr kleine Prokejte handelt, die Zeit zum Compilieren der Module also nicht ins Gewicht fällt – verwende ich direkt die Quellen der Programmteile.
Dazu werden die gewünschten Code-Schnippsel zu Beginn des Build-Prozesses zu den Projekt-Quellen hinzukopiert und ganz normal übersetzt und gelinkt. Das spart nicht nur die Verwaltung von Bibliotheken für unterschiedliche Controller, sondern vereinfacht auch die Handhabung, da der Code in Quellform noch (zB durch Includes wie avr/io.h oder Defines wie F_CPU) veränderbar und parametrisierbar ist. Zudem kann ein Compiler, da er mehr Kenntnisse hat, besseren Code erzeugen.
- Taster abfragen
- Einen Taster abzufragen und zu entprellen gehört zu den Standardaufgaben. Für jeden angeschlossenen Taster kann ein eigener Betriebsmodus gewählt werden: jeder Taster liefert einfach einen Tastendruck, oder kann wahlweise unterscheiden zwischen kurzem/langem Tastendruck oder eine Auto-Repeate-Funktion haben.
- RC5-Decoder
- Eine RC5-Decoder-Routine, um mit einer handelsüblichen Infrarot-Fernbedienung Kommandos an einen Mikrocontroller zu schicken. Billiger und platzsparender als Taster, allerdings etwas komplizierter in der Umsetzung.
- Dreh-Impulsgeber
- Auswertung eines Dreh-Impulsgebers.
- Countdown
-
Ein Countdown-Zähler in C. Simpel, aber universell und weitreichend. Er erlaubt es, ein Programm *ohne* Warteschleifen aufzubauen! Überleg Dir einfach, wie Du ein Programm schreiben würdest, daß eine LED im Sekundenkakt blinkt und eine zweite im Takt von 1.1 Sekunden...
Im Header werden die benötigten Countdown-Zähler in eine Struktur eingetragen. In der Struktur gibt es einen Bereich, dessen Einträge alle 10 Millisekunen (1/100 Sekunde) herabgezählt werden, einen Bereich für die Sekunden und einen für Minuten. Die C-Quelle bleibt immer gleich und braucht nicht darauf angepasst zu weden. - FIFO: Warteschlange
- Eine FIFO-Implementierung, also eine Warteschlange für Bytes.
- DCF77-Decoder
-
Auswertung des DCF77-Zeitsignals, das Funkuhren zum Zeitabgleich verwenden. Die Routine wird alle 10 Millisekunden aufgerufen
und wird mit dem vom DCF-Empfänger gelieferten Wert gefüttert.
Mit avr-gcc übersetzt, belegt die Routine etwa 270 Byte an Programmspeicher; aber der Code funktioniert natürlich auch auf einem PC. Die alte Version ist umständlicher und belegt mehr Speicher.
JavaScript-Rechner
Für kleinere Rechenaufgaben bietet sich JavaScript an. Man braucht dann keine komplexe Programmierumgebung verfügbar zu haben und man kann von überall auf die Programme zugreifen. Alles was man braucht ist ein Internet-Zugang und ein Browser.
Den Code kannst du anzeigen mit "rechter Maustatze → Quelltext anzeigen", oder du kannst den Code abspeichern, deinen Erfordernissen anpassen und dann verwenden.
- AVR-UART-Rechner
- Ein Rechner, um den Wert für das Baudraten-Register der USART-Einheit eines AVR zu berechnen. Vor allem dann praktisch, wenn die bei der Berechnung auftretenden Quotienten nicht aufgehen und die beste Rundung gefragt ist.
- Linearregler trimmen
- Berechnet die Trimmwiderstände an einem Linearregler wie LM317, VB408, etc.
- Spannungsteiler mit E-Werten aus Normreihe
- Berechnet die Widerstände für einen Spannungsteiler. Dabei werden die besten Werte berechnet, die mit Widerständen aus der Standard E12- bzw. E24-Normreihe möglich sind.
- Widerstandsberechnung für HV-Netzteil
- Ein Rechner zum Bestimmen der Abgleich-Widerstände im HV-Netzteil meiner Nixie-Uhr.
- Rechnung aufdröseln
- Teilt bei einer Rechnung die Kosten auf. Fixkosten (zB Porto, Fräskosten bei Leiterplattenherstellung) werden pro Teil umgeschlagen während die Restkosten anteilig berechnet werden (zB nach Platinenfläche, Wert, ...).
- Sonderzeichen von/nach HTML konvertieren
- Nix großartiges, einfach Sonderzeichen, wie sie zum Beispiel in C-Quellen auftauchen, in HTML-Codes übersetzen.
- Text-Mixer
- Wedern in eienm Txet die Butecbahsn der enizlneen Wtroe so ducrhenaendirgrwüeflet, daß die esretn und lzetten Btuaehcbsn jeeliws an iehrm Ptalz blbeien, dnan beiblt der Txet tredtozm rhcet gut lasebr. Gnurd dfaür ist, daß wir ein Wrot nhict als Fgloe von Btuhabcsen eerenknn, sdrenon als Eieinht wie bei eienm Blid.
- Approximation durch kubische Bézierkurven und quadratische Bézierkurven.
- Bézierkurven werden in vielem Graphikprogrammen verwendet, um gekrümmte Kuven darzustellen — so auch in SVG. Dieses kleine Tool berechnet anhand der Funktionsgleichung eine Näherung der Funktion durch Bézierkurven. Die kubischen Béziers sind momentan besser ausgebaut als die quadratischen.
- Der kleine Online-Rechner für SVG-Transformationen
- Mit diesem Rechner können Transformationen für SVG-Dateien umgestellt oder in elementare Transformationen zerlegt werden.
- Newton-Verfahren
- Newton quick and dirty: Das Newton-Verfahren zum Annähern einer Nullstelle für eine reellwertige, gutmütige Funktion in einer Unbekannten.