Z80MBC2 : Wie funktioniert der GPIO Header in BASIC?

    • Official Post

    Hallo Allerseits!


    Im Hackaday Archiv ist ein Beispiel, wie man in MBASIC eine am GPIO angeschlossene LED zum blinken bringt.

    Es funktioniert bei mir einwandfrei, jetzt will ich verstehen, warum es tut, was es tut. Vielleicht kann jemand besser als ich nachvollziehen wie die Funktionsweise ist?


    Eigentlich verstehe ich fast keine Zeile, wo OUT vorkommt.


    Warum manchmal OUT 0,... und manchmal OUT 1,...?


    Code
    50 OUT 1,IODIRA : OUT 0,0 : REM Set all GPAx as output (IODIRA=0x00)

    OK, OUT1,IODIRA setzt alle GPAx als Ausgabeport. Aber was macht Out 0,0? Und wie würde ich schreiben, wenn ich einen zum Lesen und einen zu Schreiben deklarieren wollen würde?

    Code
    70 OUT 1,GPIOA : OUT 0,32 : REM Set GPA5=1, GPAx=0 (GPIOA=B00100000=32)


    Zu Zeile 70 hab ich keinen Plan, was da gemacht wird....Ist das ein Typo? Wollte er eigentlich "Set GPA8 schreiben"? die LED ist an Pin 8... Schaltet diese Zeile die LED an?

    Code
    90 OUT 1,GPIOA : OUT 0,0 : REM Clear all pins GPAx (MCP23017)

    Das scheint die LED wieder auszuschalten... Soll das heißen, wenn ich den Status eines Output Ports ändern will, muss ich zuerst OUT1,3 schreiben und in OUT0,X kommt dann der Wert?


    Hmmm. Also in OUT1,xxx kommt ein Befehl und OUT0,xxx der Operand?


    Hier nochmal das komplette Programm:


    • Official Post

    Die Daten gehen an die angegebene Portadresse (OUT Adresse,Daten).

    Der MCP liegt offenbar an den Ports 0 und 1 (und evtl. weitere, ich kenne das Teil nicht).


    EDIT: Das Programm erweckt den Eindruck, daß der MCP ein Befehlsregister an Port 1 und ein Datenregister an Port 0 hat.

    Um damit klarzukommen, muß man wissen, wie das Befehlsregister funktioniert, also RTFM.

  • Das sieht deutlich so aus, als ob man auf Port 1 ein "Register Select" macht, also ein Register des MPC23017 auswählt. Nachfolgende Aus-/Eingaben auf Port 0 lesen/beschreiben dann das mit Port 1 ausgewählte Register.


    Dazu braucht man die Tabellen aus dem Datenblatt, die sagt, was denn die Register eigentlich machen:


    IODIRA legt fest, ob die Pins EIn- oder Ausgänge sind. "0" ist ein Ausgang, "1" ein Eingang


    Code
    50 OUT 1,IODIRA : OUT 0,0 : REM Set all GPAx as output (IODIRA=0x00)

    wählt erst IODIRA als zu beharkendes Register aus, und schreibt mit OUT 0,0 eine NULL rein


    Wolltest du die unteren 4 Bits als Eingang, hieße das passende Kommando;


    Code
    50 OUT 1,IODIRA : OUT 0,15 : REM Split GPa for input/output (IODIRA=0xf)

    Die Zeile 70

    Code
    70 OUT 1,GPIOA : OUT 0,32 : REM Set GPA5=1, GPAx=0 (GPIOA=B00100000=32)

    Wählt demnach das Datenregister an, und setzt dort Bit 5 (das ein Ausgang ist) auf "1"

  • Auch wenn das nicht ganz hierhin passt möchte ich auf RomWBW verlinken.

    Vielleicht inspiriert das ein wenig.


    https://github.com/wwarthen/RomWBW


    RomWBW provides a complete software system for a wide variety of hobbyist Z80/Z180 CPU-based systems produced by these developer communities:

    General features include:

    • Banked memory services for several banking designs
    • Disk drivers for RAM, ROM, Floppy, IDE, CF, and SD
    • Serial drivers including UART (16550-like), ASCI, ACIA, SIO
    • Video drivers including TMS9918, SY6545, MOS8563, HD6445
    • Real time clock drivers including DS1322, BQ4845
    • Multiple OS support including CP/M 2.2, ZSDOS, CP/M 3, ZPM3
    • Built-in VT-100 terminal emulation support

    Mit freundlichen Grüßen


    fritz