Programmierung für Mikrocontroller: Mecrisp Forth auf dem Raspberry Pico

Seite 4: Rundblick

Inhaltsverzeichnis

Nicht schlecht für eine interaktive Sprache auf einem Mikrocontroller: Toggeln eines I/O_pins mit über 6 MHz.

Die meisten Mikrocontroller arbeiten Memory-mapped – sprich: man erreicht die diversen Register an definierten Speicheradressen. Und weil Forth von Hause aus sehr gute Gene mitbringt, um mit Speicheradressen und Bit-Manipulation zu arbeiten, werden wir die Pico-I/Os jetzt mal ansprechen.

$d0000000 constant SIO_BASE            \ IO_BASE in Hex 
SIO_BASE $010 + constant GPIO_OUT \ GPIO output value
SIO_BASE $014 + constant GPIO_OUT_SET \ GPIO output value set
SIO_BASE $018 + constant GPIO_OUT_CLR \ GPIO output value clear
SIO_BASE $01c + constant GPIO_OUT_XOR \ GPIO output value XOR
SIO_BASE $020 + constant GPIO_OE \ GPIO output enable
: setbit 1 swap lshift ; \ Wert für bit 0 (LSB) bis bit 31 (MSB)
25 setbit constant pin25 \ %1 25 x left shift => pin25
: blinky ( -- )
pin25 GPIO_OE ! \ pin25 als Output deklarieren
begin
pin25 GPIO_OUT_XOR ! \ pin25 mittels XOR toggeln
10000000 0 do loop \ Verzögerungsschleife
key? until \ bis eine Taste gedrückt wurde ;

gpio25 (pin25) ist hierbei die auf dem Board befindliche LED des Pico. Zum Anfang werden einige Speicheradressen als Konstanten definiert. setbit ist eine Hilfsfunktion, welche den Wert %01 x-mal nach links schiebt, das erledigt der ARM übrigens in einem Taktzyklus (mit see setbit zu überprüfen).

Es folgt ein sprechender Name für den GPIO-Pin 25, man hätte hier genauso gut int_led verwenden können. Gilt es einzig noch das „!“ innerhalb der Definition zu erklären. Dies steht für Store und erwartet zwei Parameter auf dem Stack: Den Wert und die Speicheradresse, an welche der Wert geschrieben werden soll. Die umgekehrte Richtung funktioniert mit „@“ = Fetch, dies erwartet eine Adresse und liest den Wert von dort auf den Stack. Mit Eingabe von blinky blinkt die Board-LED etwa im Sekundentakt, eine Taste beendet das Ganze. Da blinky den Pin25 in den Ausgabemodus versetzt hat, können wir mit diesem kleinen Programm auch im interaktiven Modus arbeiten. pin25 GPIO_OUT_CLR ! schaltet die LED aus.

: toggle ( pinno -- ) GPIO_OUT_XOR ! ;  \ Schaltet den Output um

Und noch etwas mehr Komfort und Lesbarkeit mit pin25 toggle . Im Folgenden werden Auszüge meiner eigenen Implementierung (playground.4th) verwendet, um zu zeigen, wie einfach und wiederverwendbar das nachher wird. Da diese mit über 250 Zeilen den Rahmen dieses Artikels sprengen würde und das auch sicher nicht jeder abtippen möchte, stelle ich diese gern auf https://cfulde.de/playground.4th zum Download bereit. Ebenfalls zu finden ist sie im rp2040-ra-Verzeichnis von Mecrisp-Stellaris.

Damit der Pi Pico diese Erweiterungen kennt, muss die Datei einmalig fehlerfrei innerhalb des Terminal-Fensters eingespielt werden. Mit TeraTerm unter Windows mit 20ms Verzögerung zwischen den Zeilen klappt das sehr gut über die Zwischenablage. Unter Linux hat sich für mich e4thcom als sehr stabil und benutzerfreundlich herausgestellt.

Werft mal einen Blick hinein, damit werden dann – siehe Bild von meinem Breadboard – solche Sachen möglich:

ADC2 .adcvolt 000000EC : 0,190 V  \ Analog 2 GPIO28 in Volt 
beep \ Speaker an GPIO12 piepen lassen
pin17 .pad ( SlewSlow Schmitt PullDown 4mA IE ) \ print Einstellg.
.pins \ Status aller Pins
pin12 input \ GPIO12 als Eingang schalten
pin12 SlewFast Schmitt or padOn \ Pad-Register Flags einschalten
pin12 PullDown Schmitt or padOff \ Pad-Register Flags ausschalten
pin17 4 %1010 !outbits \ Gib den Wert %1010 an pin17-pin20 aus
pin12 8 ?inbits \ Liest von pin12-pin19 gleichzeitig
pin25 toggle 10 times \ 5 Mal an 5 Mal aus
pin25 toggle many \ Solange wiederholen bis Taste gedrückt
\ Zähle vier LED’s binär
: countit 16 0 do pin17 4 i !outbits 200 ms loop pin17 4 0 !outbits ;

Bei der Definition von neuen Words sollte man sich angewöhnen, schon an ihrem Namen erkennen zu können, wozu sie dienen:

  • .pad / .adcvolt ("." für print-pad / print-adcvolt)
  • !outbits ("!" für store-outbits)
  • ?inbits ("?" für read-inbits)

Eine Anbindung des Raspberry Pi Pico direkt über die USB-Schnittstelle ist Arbeit. Damit würde dann der USB2Serial-Konverter entfallen und auch GPIO_0 und GPIO_1 wären nutzbar.

Wünschenswert wäre ein gegliedertes, öffentliches Forum für Mecrisp. Leider hat sich noch niemand gefunden, der die Ressourcen und vor allem die Moderation dafür zur Verfügung stellen kann. Allerdings findet eine rege Diskussion über die Weiterentwicklungen bereits in den Beiträgen von Sourceforge statt.Falls sich in meinen Tools noch Fehler finden, kann man mich unter mecrisp@cfulde.de erreichen. (cm)