Nur die wenigsten wissen, wie man solche Libraries erstellt. In diesem Tutorial geht es genau darum.
Als Sensor wurde der Temperatur-Sensor MAX6675 auserkoren, für den eine Library erstellt werden soll.
Vorwort
Dieses Tutorial existiert bereits als recht ausführliche Fassung dieses Tutorials. Daher wird hier nicht so tief ins Detail eingegangen.
Sondern nur grob der Ablauf beschrieben. Details sind dann dem Anhang MAX6675_Demo-zip zu entnehmen
MAX6675.jpg
Einführung
Ich denke, dass jeder hier mit dem Begriff Library (Bibliotheken) etwas anfangen kann.
Im Grunde werden sie mit dem Befehl $LIB "libname" eingebunden und hat damit dann eine gewisse Anzahl an zusätzlichen Befehlen, die in Bascom verwendet werden können.
Beispiele hierfür sind die TWI-Lib oder Display-Treiber. So funktioniert das bei Bibliotheken, die mit Bascom ausgeliefert werden.
Wenn man selbst solche Bibliotheken schreibt, kennt Bascom ja diese Befehle erst mal nicht. Weis also nicht, welche Routinen es gibt, und welche Parameter/Rückgabewerte mit dem Aufrufer (Hauptprogramm) und wie (Byval, ByStack etc.) ausgetauscht werden müssen.
Deshalb ist es erforderlich per Declare-Anweisung alle Routinen, also Sub's und Funktionen zu deklarieren. Das bringt es mit sich, dass man zur Bibliothek noch eine zusätzliche Include-Datei benötigt, in der das alles definiert wird.
Aus Anwendersicht bindet man dann also nicht die Bibliothek selber ein, sondern lediglich die Include-Datei welche dann die Bibliothek einbindet und die Deklarationen enthält.
Das führt dann zwangsläufig dazu, dass man für die Entwicklung ein Hauptproramm und eine Include-Datei benötigt. Später dann auch noch die eigentliche Lib-Datei.
Voraussetzungen
Hier soll eine Bibliothek entstehen für einen Temperatur-Sensor mit MAX6675.
Als Plattform habe ich einen Arduino-Uno verwendet. Den Sensor steckt man da einfach oben drauf.
Damit hat man keinen Verdrahtungsaufwand und braucht auch keinen Programmer.
Diese Hardware sollte man haben, wenn man das Tutorial verfolgen will. Es geht auch ohne Arduino, aber der Sensor ist Pflicht.
Eine weitere Voraussetzungen sind Assembler-Kenntnisse und das Wissen, wie Parameter zwischen Basic und Libraries ausgetauscht werden.
Hier empfehle ich die Bascom-Hilfe zu lesen. Stichworte: "$LIB", "Declare Sub", "Declare Function", "Stack".
Bezüglich Lib-Beispiel existiert im Lib-Verzeichnis von Bascom eine Datei namens "mylib.lib". Sie zeigt den typischen Aufbau einer Lib.
Hilfreich ist auch der Umgang mit dem Simulator. Damit lassen sich viele Fehler aufspüren.
Da mit mehreren Dateien gearbeitet wird, sollte auch der Umgang mit Bascom-Projekten klar sein.
Ansonsten im Anhang die Datei "Tutorial Lib-Erstellung.pdf" konsultieren. Dort ist alles ausführlicher erklärt.
Benötigte Quelldateien
Wir benötigen zur Entwicklung der Bibliothek einen Projekt-Order (Lib-MAX6675), in dem wir zunächst zunächst 2 Dateien anlegen:
Im Hauptprogramm wird dann die Include-Datei eingebunden und die Routinen aufgerufen.
Das ganze wird am besten als Projekt in einer Projekt-Datei (Demo_MAX6675.prj) zusammengefasst.
Das Hauptprogramm hat dann folgenden Inhalt
Alles anzeigen
Der Controller und der Systemtakt ergeben sich aus der Plattform (Arduino Uno).
Der Sensor wird an den Pins A0 bis A4 eingesteckt. Die Versorgungsspannung liefern die Controller-Pins. Siehe Main.bas.
Das sollte man mal kompilieren und schauen, das im Terminal eine korrekte Ausgabe "Hallo Welt!" geliefert wird. Dazu vorübergehend Zeile 34 auskommentieren.
Include-Datei: MAX6675.inc
Dann stellen wir das Gerüst für die Include-Datei zusammen.
Alles anzeigen
Ab Zeile 8 werden die benötigten Pins für den Sensor definiert. Danach erfolgt ab Zeile 15 die Deklaration den gewünschten Routinen.
Im Programm Main-bas wird die Zeile 34 wieder aktiviert, damit das Hauptprogramm auch die Include-Datei "MAX6675.inc" einbinden kann.
Wenn man jetzt versucht das Projekt zu compilieren, wird man eine Fehlermeldung wie etwa diese bekommen:
Die Aussage der Meldung ist, dass keine Sprungmarken zu diesen mit Declare definierten Routinen vorhanden sind.
Also legen wir diese Routinen gleich mit RET (Return) an. Mit Goto überspringen wir aber diese Routinen, damit die Programmausführung nicht in die Routinen läuft. Schließlich wird die Include-Datei ja vor der Hauptschleife eingebunden.
Nun sollte das Compilieren funktionieren.
Jetzt füllen wir die Routinen in der MAX6675.inc mit Anweisungen, damit sie das tun was sie sollen.
Ich kürze hier aber mal ab und zeige den fertigen Code für diese Datei.
Alles anzeigen
Hauptprogramm: Main.bas
Diese Lib-Routinen müssen jedoch noch aufgerufen und die Schnittstelle zum Sensor initialisiert werden.
Dafür passen wir die Main.bas nochmal wie folgt an:
Vor der Hauptschleife wird die Initialisierung "Call MAX6675_Init()" aufgerufen und in der Hauptschleife wird im Sekundentakt der Sensor ausgelesen und die berechnete Temperatur ans Bascom-Terminal gesendet.
Alles anzeigen
Jetzt haben wir erst mal eine funktionierende Include-Datei, die den Sensor ausliest und die Werte anzeigt.
Wenn es etwas zu schnell geht, ausführlich ist das alles in "Tutorial_Lib_Erstellung.pdf" erklärt (Angang).
Dieser Entwicklungs-Stand ist ebenfalls im Anhang unter "Demo_Stand-1.zip" zu finden.
Diese Include-Datei "MAX6675.inc" wäre jetzt schon im Grunde eine (Basic-)Bibliothek und könnte so auch in künftigen Projekten verwendet werden.
In dem Fall wären wir schon fertig.
Aber wir wollen ja eine richtige Bibliothek schreiben. Also geht es weiter.
Vorbereitung der Lib-Routinen für die Library
Einigen von euch ist vielleicht aufgefallen, dass in der Include-Datei einige Basic-Anweisungen stehen. Und die sind in Lib's nicht erlaubt.
Denn Lib's sind ausschließlich in Assembler programmiert. Das stimmt auch.
Aber die Bascom-Entwickler haben eine Hintertüre offen gelassen und die Anweisung "*Basic:" kreiert. Damit sind auch Basic-Anweisungen (vermutlich in begrenztem Umfang) in Bibliotheken möglich.
Damit wir die Assembleranweisungen aber in der IDE testen können müssen wir sie mit dem "!" Symbol als Assembler-Zeilen deklarieren und die Anweisung "*Basic:" anhängen. Erst dann folgt die Basic-Anweisung.
Das sieht dann wie folgt aus:
Alles anzeigen
Das muss man sich erst mal anschauen und durch den Kopf gehen lassen. Hat aber durchaus System.
Dieser Entwicklungs-Stand ist im Anhang unter "Demo_Stand-2.zip" zu finden.
Dieser Stand 2 mit den etwas merkwürdig scheinenden Codezeilen müsste jetzt fehlerfrei compilierbar sein.
Ein Test im Terminal belegt das auch.
Library: MAX6675.lib
Jetzt gilt es die Lib-Routinen (Zeile 32 bis 65) aus der Include-Datei in die Library-Datei, die wir "MAX6675.lib" nennen einzufügen.
Dafür legen wir eine leere Text-Datei im Lib-Verzeichnis von Bascom mit dem genannten Namen an.
Diese Lib-Datei laden wir dann auch in die Bascom-IDE als 3. Datei. So lässt sich das alles besser bearbeiten. zuvor sollte noch eine Einstellung in Bascom geändert werden.
In der "Tutorial_Lib-Erstellung.pdf" ist das alles viel ausführlicher beschrieben.
Es empfiehlt sich eine Einstellung in Bascom zu ändern, damit LIB-Dateien nicht von Bascom formatiert werden. Hier sollte im Eingabefeld "no reformat code" der Eintrag "LIB" hinzugefügt werden.
Option-1.PNG
Lib Dateien haben einen bestimmten Aufbau.
Dafür mal die Bascomhilfe "$LIB" ansehen und auch das Beispiel "mylib.lib" im Verzeichnis Lib.
Befehle werden normalerweise in Blöcken eingeschlossen, die mit [Blockname] beginnen und mit [End] enden. Dazwischen wird die Lib-Routine geschrieben.
Der Blockname entspricht dabei den Nanem der deklarierten Sub/Function.
Da wir jedoch nur 2 Routinen haben (Init und Read), können wir beide Lib Routinen in so einen Block schreiben bzw. von der Include-Datei da rein-schieben.
Den Blocknamen benennen wir sinniger weise um in "MAX6675".
Diese jetzt entstandene Bibliothek darf jetzt keine Basic-Anweisungen mehr enthalten. Außer es steht ein "*Basic:" davor.
Die Ausrufezeichen am Anfang der Zeilen müssen weg, die wurden nur in Basic (INC-Datei) gebraucht,damit der Compiler weis was danach kommt.
Die Library MAX6675.lib hat nun am Ende folgenden Inhalt:
Alles anzeigen
Da sich die Library im Lib-Verzeichnis befindet, kann sie mit dem Lib-Manager (Menu -> Tools) compiliert werden.
Im Lib-Manager die MAX6675.lib anwählen und auf "Compile" klicken. Ist das Compilieren erfolgreich passiert nix weiter.
Bei Fehler gibt's eine Meldung!
Anpassung der MAX6675.inc
Da jetzt eine Lib existiert und die Lib-Routinen nicht mehr in der Include-Datei MAX6675.inc" vorhanden sein sollten, kann das Goto entfallen, welcher die Routinen einst übersprang.
Dafür muss jetzt aber mit der Direktiven "$LIB" die Lib eingebunden werden. Weiterhin müssen mit der Direktiven "$External" die Blocknamen angegeben werden, die im Compilat eingebunden werden sollen. In unseren Lib-Beispiel gibt es nur einen Block mit Namen "MAX6675".
Die Include-Datei hat nun am Ende folgenden Inhalt:
Alles anzeigen
Das finale Programm, mit dem ausführlichen Tutorial kann im Anhang unter "MAX6675_Demo.zip" herunter geladen werden.
Zum Abschluss
Jetzt ist es an der Zeit etwas aufzuräumen.
Die einzelnen Dateien sind ja etwas verstreut. Die sollte man jetzt sammeln und in einem eigenes Lib-Verzeichnis unterbringen, damit man schnell die notwendigen Routinen und Infos findet. Wie ich das selbst ablege, könnt ihr im dem PDF "Tutorial_Lib-Erstellung.pdf" entnehmen.
Ich wünsche Viel Spaß beim ausprobieren.
Über Feedback würde ich mich freuen.
Mitch64 (2020)
Dieses Tutorial existiert bereits als recht ausführliche Fassung dieses Tutorials. Daher wird hier nicht so tief ins Detail eingegangen.
Sondern nur grob der Ablauf beschrieben. Details sind dann dem Anhang MAX6675_Demo-zip zu entnehmen
MAX6675.jpg
Einführung
Ich denke, dass jeder hier mit dem Begriff Library (Bibliotheken) etwas anfangen kann.
Im Grunde werden sie mit dem Befehl $LIB "libname" eingebunden und hat damit dann eine gewisse Anzahl an zusätzlichen Befehlen, die in Bascom verwendet werden können.
Beispiele hierfür sind die TWI-Lib oder Display-Treiber. So funktioniert das bei Bibliotheken, die mit Bascom ausgeliefert werden.
Wenn man selbst solche Bibliotheken schreibt, kennt Bascom ja diese Befehle erst mal nicht. Weis also nicht, welche Routinen es gibt, und welche Parameter/Rückgabewerte mit dem Aufrufer (Hauptprogramm) und wie (Byval, ByStack etc.) ausgetauscht werden müssen.
Deshalb ist es erforderlich per Declare-Anweisung alle Routinen, also Sub's und Funktionen zu deklarieren. Das bringt es mit sich, dass man zur Bibliothek noch eine zusätzliche Include-Datei benötigt, in der das alles definiert wird.
Aus Anwendersicht bindet man dann also nicht die Bibliothek selber ein, sondern lediglich die Include-Datei welche dann die Bibliothek einbindet und die Deklarationen enthält.
Das führt dann zwangsläufig dazu, dass man für die Entwicklung ein Hauptproramm und eine Include-Datei benötigt. Später dann auch noch die eigentliche Lib-Datei.
Voraussetzungen
Hier soll eine Bibliothek entstehen für einen Temperatur-Sensor mit MAX6675.
Als Plattform habe ich einen Arduino-Uno verwendet. Den Sensor steckt man da einfach oben drauf.
Damit hat man keinen Verdrahtungsaufwand und braucht auch keinen Programmer.
Diese Hardware sollte man haben, wenn man das Tutorial verfolgen will. Es geht auch ohne Arduino, aber der Sensor ist Pflicht.
Eine weitere Voraussetzungen sind Assembler-Kenntnisse und das Wissen, wie Parameter zwischen Basic und Libraries ausgetauscht werden.
Hier empfehle ich die Bascom-Hilfe zu lesen. Stichworte: "$LIB", "Declare Sub", "Declare Function", "Stack".
Bezüglich Lib-Beispiel existiert im Lib-Verzeichnis von Bascom eine Datei namens "mylib.lib". Sie zeigt den typischen Aufbau einer Lib.
Hilfreich ist auch der Umgang mit dem Simulator. Damit lassen sich viele Fehler aufspüren.
Da mit mehreren Dateien gearbeitet wird, sollte auch der Umgang mit Bascom-Projekten klar sein.
Ansonsten im Anhang die Datei "Tutorial Lib-Erstellung.pdf" konsultieren. Dort ist alles ausführlicher erklärt.
Benötigte Quelldateien
Wir benötigen zur Entwicklung der Bibliothek einen Projekt-Order (Lib-MAX6675), in dem wir zunächst zunächst 2 Dateien anlegen:
- ein Hauptprogramm (Main.bas)
- eine Include-Datei (MAX6675.inc)
Im Hauptprogramm wird dann die Include-Datei eingebunden und die Routinen aufgerufen.
Das ganze wird am besten als Projekt in einer Projekt-Datei (Demo_MAX6675.prj) zusammengefasst.
Das Hauptprogramm hat dann folgenden Inhalt
BASCOM-Quellcode: Main.bas
- ' Projekt: Lib-Erstellung für Sensor MAX6675
- ' Plattform: Arduino Uno
- ' Autor: Mitch64 2020
- ' Version: In Entwicklung
- ' Das Breakout Board mit MAX6675 wird am Arduino Uno an Pins A0 bis A4 eingesteckt
- ' Pin Sensor Pin Arduino Pin Mega328P
- ' SO an A0 (PC0)
- ' CS an A1 (PC1)
- ' SCK an A2 (PC2)
- ' VCC an A3 (PC3)
- ' GND an A4 (PC4)
- $regfile = "m328pdef.dat"
- $crystal = 16000000
- $hwstack = 50
- $swstack = 50
- $framesize = 50
- $Baud = 19200 ' Für Debug-Zwecke
- ' -------------------------------------
- ' Für Betriebsspannung am Sensor sorgen
- ' Ist jetzt nur wegen dem Aufstecken in den Arduino notwendig.
- ' -------------------------------------
- PIN_MAX6675_GND Alias PortC.4 ' Masse für MAX6675
- PIN_MAX6675_VCC Alias PortC.3 ' VCC für MAX6675
- Reset PIN_MAX6675_GND : Config PIN_MAX6675_GND = Output ' Masse an schalten
- Config PIN_MAX6675_VCC = Output ' dann am VCC Pin
- Set PIN_MAX6675_VCC ' die Spannung an
- Waitms 500 ' obligatorisch
- $Include "MAX6675.inc"
- ' ============================================================================
- ' Hauptschleife
- ' ============================================================================
- Do
- Waitms 1000
- Print „Hallo Welt!“
- Loop
Der Sensor wird an den Pins A0 bis A4 eingesteckt. Die Versorgungsspannung liefern die Controller-Pins. Siehe Main.bas.
Das sollte man mal kompilieren und schauen, das im Terminal eine korrekte Ausgabe "Hallo Welt!" geliefert wird. Dazu vorübergehend Zeile 34 auskommentieren.
Include-Datei: MAX6675.inc
Dann stellen wir das Gerüst für die Include-Datei zusammen.
BASCOM-Quellcode: MAX6675.inc
- ' Datei: MAX6675.inc
- ' Autor: Mitch64 2020
- ' Version: In Entwicklung
- ' Beschreibung:
- ' Include-Datei zur Einbindung der MAX6675.lib (Thermocouple Temperatur-Sensor)
- ' -------------------------
- ' Konfiguration Sensor-Pins
- ' -------------------------
- PIN_MAX6675_DO Alias PinC.0 ' Data-Out von MAX6675
- PIN_MAX6675_CS Alias PortC.1 ' CS von MAX6675
- PIN_MAX6675_SCK Alias PortC.2 ' Clock Input von Max6675
- ' --------------------------------
- ' Deklaration Sensor-Schnittstelle
- ' --------------------------------
- Declare Sub Max6675_Init() ' Initialisiert die Pins / IDLE-Pegel
- Declare Function Max6675_Read() as Integer ' Liest die Temperatur aus
Im Programm Main-bas wird die Zeile 34 wieder aktiviert, damit das Hauptprogramm auch die Include-Datei "MAX6675.inc" einbinden kann.
Wenn man jetzt versucht das Projekt zu compilieren, wird man eine Fehlermeldung wie etwa diese bekommen:
Quellcode: MAX6675.err
- Error : 61 Line : 40 Label not found [MAX6675_INIT] , in File : C:\Users\Michael\Documents\Projekte\Experimente\LibErstellung\Lib_Max6675\Firmware\Main.bas
- Error : 61 Line : 48 Label not found [MAX6675_READ] , in File : C:\Users\Michael\Documents\Projekte\Experimente\LibErstellung\Lib_Max6675\Firmware\Main.bas
Also legen wir diese Routinen gleich mit RET (Return) an. Mit Goto überspringen wir aber diese Routinen, damit die Programmausführung nicht in die Routinen läuft. Schließlich wird die Include-Datei ja vor der Hauptschleife eingebunden.
Nun sollte das Compilieren funktionieren.
Jetzt füllen wir die Routinen in der MAX6675.inc mit Anweisungen, damit sie das tun was sie sollen.
Ich kürze hier aber mal ab und zeige den fertigen Code für diese Datei.
BASCOM-Quellcode: MAX6675.inc
- ' Datei: MAX6675.inc
- ' Autor: Mitch64 2020
- ' Version: In Entwicklung
- ' Beschreibung:
- ' Include-Datei zur Einbindung der MAX6675.lib (Thermocouple Temperatur-Sensor)
- ' -------------------------
- ' Konfiguration Sensor-Pins
- ' -------------------------
- PIN_MAX6675_DO Alias PinC.0 ' Data-Out von MAX6675
- PIN_MAX6675_CS Alias PortC.1 ' CS von MAX6675
- PIN_MAX6675_SCK Alias PortC.2 ' Clock Input von Max6675
- ' --------------------------------
- ' Deklaration Sensor-Schnittstelle
- ' --------------------------------
- Declare Sub Max6675_Init() ' Initialisiert die Pins / IDLE-Pegel
- Declare Function Max6675_Read() as Integer ' Liest die Temperatur aus
- ' ============================================================================
- Goto MAX6675_Exit
- ' ============================================================================
- ' Hier beginnen die Routinen, die später in die LIB müssen
- ' ============================================================================
- Max6675_Init:
- Config PIN_MAX6675_SCK = Output
- Config PIN_MAX6675_CS = Output
- Set PIN_MAX6675_CS
- Reset PIN_MAX6675_SCK
- !RET
- Max6675_Read:
- Reset PIN_MAX6675_CS ' Chip Select Low
- !LDI r16,13 ' 13 Bit sollen eingelesen werden
- !CLR r20 ' R21:20 nehmen die Bits auf
- !CLR r21
- _read_max6675_loop:
- Set PIN_MAX6675_SCK ' SCK High
- !CLC ' Carry löschen
- If PIN_MAX6675_DO = 1 then !SEC ' Carry setzen, wenn DO=HIGH
- Reset PIN_MAX6675_SCK ' SCK Low
- !ROL r20 ' r21:20 1x links schieben
- !ROL r21
- !DEC r16
- !BRNE _read_max6675_loop
- Set PIN_MAX6675_CS ' Chip Select High
- ' jetzt sind alle notwendigen Bits eingelesen
- ' Daten an Aufrufer zurückgeben
- !LDD xl,y+0 ' Adresse Rückgabewert
- !LDD xh,y+1
- !ST x+,r20 ' Rückgabewert setzen
- !ST x,r21
- !RET
- ' ============================================================================
- ' Hier Enden die Lib-Routinen
- ' ============================================================================
- MAX6675_Exit:
- ' ============================================================================
Diese Lib-Routinen müssen jedoch noch aufgerufen und die Schnittstelle zum Sensor initialisiert werden.
Dafür passen wir die Main.bas nochmal wie folgt an:
Vor der Hauptschleife wird die Initialisierung "Call MAX6675_Init()" aufgerufen und in der Hauptschleife wird im Sekundentakt der Sensor ausgelesen und die berechnete Temperatur ans Bascom-Terminal gesendet.
BASCOM-Quellcode: Main.bas
- ' Projekt: Lib-Erstellung für Sensor MAX6675
- ' Plattform: Arduino Uno
- ' Autor: Mitch64 2020
- ' Version: In Entwicklung
- ' Das Breakout Board mit MAX6675 wird am Arduino Uno an Pins A0 bis A4 eingesteckt
- ' Pin Sensor Pin Arduino Pin Mega328P
- ' SO an A0 (PC0)
- ' CS an A1 (PC1)
- ' SCK an A2 (PC2)
- ' VCC an A3 (PC3)
- ' GND an A4 (PC4)
- $regfile = "m328pdef.dat"
- $crystal = 16000000
- $hwstack = 50
- $swstack = 50
- $framesize = 50
- $Baud = 19200 ' Für Debug-Zwecke
- ' -------------------------------------
- ' Für Betriebsspannung am Sensor sorgen
- ' Ist jetzt nur wegen dem Aufstecken in den Arduino notwendig.
- ' -------------------------------------
- PIN_MAX6675_GND Alias PortC.4 ' Masse für MAX6675
- PIN_MAX6675_VCC Alias PortC.3 ' VCC für MAX6675
- Reset PIN_MAX6675_GND : Config PIN_MAX6675_GND = Output ' Masse an schalten
- Config PIN_MAX6675_VCC = Output ' dann am VCC Pin
- Set PIN_MAX6675_VCC ' die Spannung an
- Waitms 500 ' obligatorisch
- ' --------------------
- ' Variablen definieren
- ' --------------------
- Dim Ergebnis as Integer
- Dim Temperature as Single
- $Include "MAX6675.inc" ' Die Include einbinden
- Call Max6675_Init() ' Sensor Initialisieren
- ' ============================================================================
- ' Hauptschleife
- ' ============================================================================
- Do
- Waitms 1000 ' Messen alle Sekunde
- Ergebnis = Max6675_Read() ' Sensor auslesen (Integer)
- Temperature = Ergebnis * 0.25 ' Berechnung °C
- Print Temperature ' Anzeige auf Termonal
- Loop
Jetzt haben wir erst mal eine funktionierende Include-Datei, die den Sensor ausliest und die Werte anzeigt.
Wenn es etwas zu schnell geht, ausführlich ist das alles in "Tutorial_Lib_Erstellung.pdf" erklärt (Angang).
Dieser Entwicklungs-Stand ist ebenfalls im Anhang unter "Demo_Stand-1.zip" zu finden.
Diese Include-Datei "MAX6675.inc" wäre jetzt schon im Grunde eine (Basic-)Bibliothek und könnte so auch in künftigen Projekten verwendet werden.
In dem Fall wären wir schon fertig.
Aber wir wollen ja eine richtige Bibliothek schreiben. Also geht es weiter.
Vorbereitung der Lib-Routinen für die Library
Einigen von euch ist vielleicht aufgefallen, dass in der Include-Datei einige Basic-Anweisungen stehen. Und die sind in Lib's nicht erlaubt.
Denn Lib's sind ausschließlich in Assembler programmiert. Das stimmt auch.
Aber die Bascom-Entwickler haben eine Hintertüre offen gelassen und die Anweisung "*Basic:" kreiert. Damit sind auch Basic-Anweisungen (vermutlich in begrenztem Umfang) in Bibliotheken möglich.
Damit wir die Assembleranweisungen aber in der IDE testen können müssen wir sie mit dem "!" Symbol als Assembler-Zeilen deklarieren und die Anweisung "*Basic:" anhängen. Erst dann folgt die Basic-Anweisung.
Das sieht dann wie folgt aus:
BASCOM-Quellcode: MAX6675.inc (Stand 2)
- ' Datei: MAX6675.inc
- ' Autor: Mitch64 2020
- ' Version: 1.00
- ' Beschreibung:
- ' Include-Datei zur Einbindung der MAX6675.lib (Thermocouple Temperatur-Sensor)
- ' -------------------------
- ' Konfiguration Sensor-Pins
- ' -------------------------
- PIN_MAX6675_DO Alias PinC.0 ' Data-Out von MAX6675
- PIN_MAX6675_CS Alias PortC.1 ' CS von MAX6675
- PIN_MAX6675_SCK Alias PortC.2 ' Clock Input von Max6675
- ' --------------------------------
- ' Deklaration Sensor-Schnittstelle
- ' --------------------------------
- Declare Sub Max6675_Init() ' Initialisiert die Pins / IDLE-Pegel
- Declare Function Max6675_Read() as Integer ' Liest die Temperatur aus
- $Lib "Lib\MAX6675.lib" ' Lib MAX6675 einbinden
- $External MAX6675 ' Code-Block einbinden
- ' ============================================================================
- ' Goto MAX6675_Exit
- ' ============================================================================
- ' Hier beginnen die Routinen, die später in die LIB müssen
- ' ============================================================================
- 'Max6675_Init:
- ' !*Basic:Config PIN_MAX6675_SCK = Output
- ' !*Basic:Config PIN_MAX6675_CS = Output
- ' !*Basic:Set PIN_MAX6675_CS
- ' !*Basic:Reset PIN_MAX6675_SCK
- ' !RET
- 'Max6675_Read:
- ' !*Basic:Reset PIN_MAX6675_CS ' Chip Select Low
- ' !LDI r16,13 ' 13 Bit sollen eingelesen werden
- ' !CLR r20 ' R21:20 nehmen die Bits auf
- ' !CLR r21
- '_read_max6675_loop:
- ' !*Basic:Set PIN_MAX6675_SCK ' SCK High
- ' !CLC ' Carry löschen
- ' !*Basic:If PIN_MAX6675_DO = 1 then !SEC ' Carry setzen, wenn DO=HIGH
- ' !*Basic:Reset PIN_MAX6675_SCK ' SCK Low
- ' !ROL r20 ' r21:20 1x links schieben
- ' !ROL r21
- ' !DEC r16
- ' !BRNE _read_max6675_loop
- ' !*Basic:Set PIN_MAX6675_CS ' Chip Select High
- ' ' jetzt sind alle notwendigen Bits eingelesen
- ' ' Daten an Aufrufer zurückgeben
- ' !LDD xl,y+0 ' Adresse Rückgabewert
- ' !LDD xh,y+1
- ' !ST x+,r20 ' Rückgabewert setzen
- ' !ST x,r21
- ' !RET
- ' ============================================================================
- ' Hier Enden die Lib-Routinen
- ' ============================================================================
- ' MAX6675_Exit:
- ' ============================================================================
Dieser Entwicklungs-Stand ist im Anhang unter "Demo_Stand-2.zip" zu finden.
Dieser Stand 2 mit den etwas merkwürdig scheinenden Codezeilen müsste jetzt fehlerfrei compilierbar sein.
Ein Test im Terminal belegt das auch.
Library: MAX6675.lib
Jetzt gilt es die Lib-Routinen (Zeile 32 bis 65) aus der Include-Datei in die Library-Datei, die wir "MAX6675.lib" nennen einzufügen.
Dafür legen wir eine leere Text-Datei im Lib-Verzeichnis von Bascom mit dem genannten Namen an.
Diese Lib-Datei laden wir dann auch in die Bascom-IDE als 3. Datei. So lässt sich das alles besser bearbeiten. zuvor sollte noch eine Einstellung in Bascom geändert werden.
In der "Tutorial_Lib-Erstellung.pdf" ist das alles viel ausführlicher beschrieben.
Es empfiehlt sich eine Einstellung in Bascom zu ändern, damit LIB-Dateien nicht von Bascom formatiert werden. Hier sollte im Eingabefeld "no reformat code" der Eintrag "LIB" hinzugefügt werden.
Option-1.PNG
Lib Dateien haben einen bestimmten Aufbau.
Dafür mal die Bascomhilfe "$LIB" ansehen und auch das Beispiel "mylib.lib" im Verzeichnis Lib.
Befehle werden normalerweise in Blöcken eingeschlossen, die mit [Blockname] beginnen und mit [End] enden. Dazwischen wird die Lib-Routine geschrieben.
Der Blockname entspricht dabei den Nanem der deklarierten Sub/Function.
Da wir jedoch nur 2 Routinen haben (Init und Read), können wir beide Lib Routinen in so einen Block schreiben bzw. von der Include-Datei da rein-schieben.
Den Blocknamen benennen wir sinniger weise um in "MAX6675".
Diese jetzt entstandene Bibliothek darf jetzt keine Basic-Anweisungen mehr enthalten. Außer es steht ein "*Basic:" davor.
Die Ausrufezeichen am Anfang der Zeilen müssen weg, die wurden nur in Basic (INC-Datei) gebraucht,damit der Compiler weis was danach kommt.
Die Library MAX6675.lib hat nun am Ende folgenden Inhalt:
BASCOM-Quellcode: Library: MAX6675.lib (Final)
- copyright = Mitch64
- www = www.bascomforum.de
- comment = library for MAX6675 temperature sensor
- libversion = 1.00
- date = 8th August 2020
- statement = Include the max6675.inc file to use the lib
- [MAX6675]
- Max6675_Init:
- *Basic:Config PIN_MAX6675_SCK = Output
- *Basic:Config PIN_MAX6675_CS = Output
- *Basic:Set PIN_MAX6675_CS
- *Basic:Reset PIN_MAX6675_SCK
- RET
- Max6675_Read:
- *Basic:Reset PIN_MAX6675_CS ' Chip Select Low
- LDI r16,13 ' 13 Bit sollen eingelesen werden
- CLR r20 ' R21:20 nehmen die Bits auf
- CLR r21
- _read_max6675_loop:
- *Basic:Set PIN_MAX6675_SCK ' SCK High
- CLC ' Carry löschen
- *Basic:If PIN_MAX6675_DO = 1 then !SEC ' Carry setzen, wenn DO=HIGH
- *Basic:Reset PIN_MAX6675_SCK ' SCK Low
- ROL r20 ' r21:20 1x links schieben
- ROL r21
- DEC r16
- BRNE _read_max6675_loop
- *Basic:Set PIN_MAX6675_CS ' Chip Select High
- ' jetzt sind alle notwendigen Bits eingelesen
- ' Daten an Aufrufer zurückgeben
- LDD xl,y+0 ' Adresse Rückgabewert
- LDD xh,y+1
- ST x+,r20 ' Rückgabewert setzen
- ST x,r21
- RET
- [End]
Im Lib-Manager die MAX6675.lib anwählen und auf "Compile" klicken. Ist das Compilieren erfolgreich passiert nix weiter.
Bei Fehler gibt's eine Meldung!
Anpassung der MAX6675.inc
Da jetzt eine Lib existiert und die Lib-Routinen nicht mehr in der Include-Datei MAX6675.inc" vorhanden sein sollten, kann das Goto entfallen, welcher die Routinen einst übersprang.
Dafür muss jetzt aber mit der Direktiven "$LIB" die Lib eingebunden werden. Weiterhin müssen mit der Direktiven "$External" die Blocknamen angegeben werden, die im Compilat eingebunden werden sollen. In unseren Lib-Beispiel gibt es nur einen Block mit Namen "MAX6675".
Die Include-Datei hat nun am Ende folgenden Inhalt:
BASCOM-Quellcode: Include-Datei: MAX6675.inc (Final)
- ' Datei: MAX6675.inc
- ' Autor: Mitch64 2020
- ' Version: 1.00
- ' Beschreibung:
- ' Include-Datei zur Einbindung der MAX6675.lib (Thermocouple Temperatur-Sensor)
- ' -------------------------
- ' Konfiguration Sensor-Pins
- ' -------------------------
- PIN_MAX6675_DO Alias PinC.0 ' Data-Out von MAX6675
- PIN_MAX6675_CS Alias PortC.1 ' CS von MAX6675
- PIN_MAX6675_SCK Alias PortC.2 ' Clock Input von Max6675
- ' --------------------------------
- ' Deklaration Sensor-Schnittstelle
- ' --------------------------------
- Declare Sub Max6675_Init() ' Initialisiert die Pins / IDLE-Pegel
- Declare Function Max6675_Read() as Integer ' Liest die Temperatur aus
- $Lib "Lib\MAX6675.lib" ' Lib MAX6675 einbinden
- $External MAX6675 ' Code-Block einbinden
Zum Abschluss
Jetzt ist es an der Zeit etwas aufzuräumen.
Die einzelnen Dateien sind ja etwas verstreut. Die sollte man jetzt sammeln und in einem eigenes Lib-Verzeichnis unterbringen, damit man schnell die notwendigen Routinen und Infos findet. Wie ich das selbst ablege, könnt ihr im dem PDF "Tutorial_Lib-Erstellung.pdf" entnehmen.
Ich wünsche Viel Spaß beim ausprobieren.
Über Feedback würde ich mich freuen.
Mitch64 (2020)
4.697 mal gelesen