;************************************************************** ; Einführung in die Software und MC Programmierung (Teil 3) ;************************************************************** ' Im vorigen Teil der Mikrocontroller Einführung haben wir eine ' blinkende LED an einem Port-Pin realisiert und dabei die ' Befehle SETB, CLR, LJMP, LCALL, NOP, MOV und DJNZ kennen ' gelernt. Nun wollen wird ein Lauflicht programmieren und ' dabei weitere Befehle kennen lernen. Definition_des_Mikrocontrollers: ' Zuerst müssen wir wieder der Assembler Software mitteilen, ' welchen Mikrocontroller wir einsetzen: INCLUDE 89C2051.mc Die_Befehle_RR_A_und_RL_A: ' Bei diesen Befehlen werden die acht Bits im Akkumulator im ' Kreis rotiert. "RR A" steht für "Rotate accumulator right" ' und "RL A" steht für "Rotate accumulator left". ' Das bedeutet, das jedes Bit im Akkumulator um einen Platz ' verschoben wird, die Richtung bestimmen wir, indem wir ' entweder den Befehl "RR A" oder den Befehl "RL A" verwenden. ' Das letzte (herausgeschobene) Bit wird dabei an die Stelle ' des ersten gesetzt, so dass es einen ewigen Kreislauf ergeben ' könnte, ohne das Bits gänzlich verschwinden. ' Ein Beispiel für den Befehl RL A: ' Akku = FEh = 11111110 ' nach einem RL A ' Akku = FDh = 11111101 ' nach einem weiterem RL A ' Akku = FBh = 11111011 ' Ein Beispiel für den Befehl RR A: ' Akku = FEh = 11111110 ' nach einem RR A ' Akku = 7Fh = 01111111 ' nach einem weiterem RR A ' Akku = BFh = 10111111 ' Wenn wir uns nun die Wanderung der Nullen in den obigen ' Beispielen ansehen, so erkennt man eine gute Möglichkeit ' um damit ein Lauflicht aus 8 LED's zu realisieren. Wir ' legen den Wert des Akku's einfach nach dem Schiebevorgang ' (RL A bzw. RR A) an einen Port des Mikrocontrollers. Dann ' warten wir eine kurze Zeit ab, wiederholen das Schieben, ' das Warten und immer so weiter. ' Die Pausenroutine haben wir uns bereits im letzten Teil ' erarbeitet, hier soll sie nicht noch mal erklärt werden. ' Eine Anmerkung zur Hardware: Da die Portausgänge der MC's ' i.A. beim Low-Signal (GND/0 Volt/Masse) wesentlich mehr ' Strom liefern können (~15mA) als beim High Signal (<1mA), ' schliessen wir die Kathoden(-) der LED's an die Portpins ' und die Anoden(+) der LED's über geeignete Vorwiderstände ' an die positive Spannung. ' Ein Low Signal am Portpin führt dann zum Aufleuchten der ' LED, man kann dies als 'negative Logik' beschreiben. MOV A,#11111110b 'Setze den Akku auf 11111110 (binär) Lauflicht: MOV P1,A 'Schreibe den Wert des Akku's an den Port1 LCALL Pause 'Springe in die Pausenroutine RL A 'Rotiere die Bits im Akku LJMP Lauflicht 'Wiederhole den obigen Ablauf immer wieder Pause: 'Unterroutine MOV R0,#FFh 'R0=FFh Schleife1: MOV R1,#FFh 'R1=FFh Schleife2: NOP 'No Operation, 1 Maschinentakt NOP 'No Operation, 1 Maschinentakt DJNZ R1, Schleife2 'R1=R1-1: Wenn R1 > 0 dann springe zu Schleife2 DJNZ R0, Schleife1 'R0=R0-1: Wenn R0 > 0 dann springe zu Schleife1 RET 'Rückkehr zum Befehl nach dem letzten LCALL ' Und das ist schon alles! Ein einzelnes Bit im Akku wird ' auf Null gesetzt, der Inhalt des Akku's wird an den Port1 ' kopiert, es wird eine kurze Pause eingelegt, der Inhalt ' des Akku's um ein Bit nach Links geschoben und dann wieder- ' holt sich das Obige immer wieder. Die_Befehle_RRC_A_und_RLC_A: ' Diese Befehle bewirken fast dasselbe wie RR A und RL A, nur ' bei RRC A und RLC A werden die Bits nicht nur durch den ' Akkumulator geschoben, sondern auch gleich noch durch das ' Carry Bit. ' Das Carry Bit sitzt dabei links vom Akkumulator, beim ' Rechtsschieben gelangt das 7. Bit des Akkus also zuerst ' in das Carry Bit und erst beim nächsten Schieben wieder ' in das Bit 0 des Akkus. ' Ein Beispiel für den Befehl RLC A: ' Carry = 0, Akku = 11111110 ' nach einem RLC A ' Carry = 1, Akku = 11111100 ' nach einem weiterem RLC A ' Carry = 1, Akku = 111110011 ' Ein Beispiel für den Befehl RRC A: ' Carry = 0, Akku = 11111110 ' nach einem RRC A ' Carry = 0, Akku = 01111111 ' nach einem weiterem RRC A ' Carry = 1, Akku = 00111111 Der_Befehle_JB_bit,rel: 'Jump Bit' ' Bei diesen Befehlen wird der Inhalt eines Bits abgefragt und ' wenn dieser 1 ist, erfolgt ein Programmsprung. Ist der ' Inhalt 0 wird einfach der folgende Befehl ausgeführt. ' Der Programmsprung wird bei diesem Befehl relativ ausgeführt, ' d.h. es wird eine vorzeichenbehaftete Zahl zum Programmzähler ' addiert. Dabei kann der Zielbereich nur zwischen -128 bis ' +127 liegen, da die relative Sprungadresse mit nur einem ' Byte angegeben wird. Das 7 Bit gibt das Vorzeichen an, ist ' es eine 1 liegt eine negative Zahl vor. ' Einige Beispiele zur Erläuterung: ' Rel. Adressangabe 07h = 00000111b => Sprung 07h Bytes vor ' Rel. Adressangabe 87h = 10000111b => Sprung 07h Bytes zurück ' Rel. Adressangabe 6Eh = 01101110b => Sprung 6Eh Bytes vor ' Rel. Adressangabe EEh = 11101110b => Sprung 6Eh Bytes zurück ' Dabei muß man aber beachten, das der Programmzähler vor der ' Addition mit der rel. Adressangabe bereits auf den Wert des ' nächsten Befehls gesetzt wird. ' Aber keine Angst, dass obige brauchen wir uns für das ' Programmieren nur insoweit merken, das wir mit rel. Sprung- ' adressen maximal 128 Bytes zurück- bzw. 127 Bytes vorspringen ' können. Der Assembler nimmt uns auch hier wieder das aufwendige ' Berechnen ab. Wir können wie bei den LJMP und bei den LCALL ' Sprungbefehlen mit Labeln arbeiten. ' Mit diesem Befehl wollen wir nun unser Lauflicht um die ' Möglichkeit der Laufrichtungsumkehr erweitern. Wir fragen ' mit dem Befehl JB den Portpin 3.0 ab, an dem wir einen Taster ' und einen Pull-Down Widerstand (10kOhm) angeschlossen haben. ' Der Taster ist mit seinem anderem Kontakt an +5Volt ' angeschlossen, der Widerstand ist mit seinem anderem Pin ' an Masse angeschlossen (Pull-Down). ' Solange der Taster betätigt ist (High-Signal am Portpin 3.0), ' läuft das Lauflicht von Portpin 1.0 nach 1.7, sobald wir ihn ' loslassen läuft es anders herum. MOV A,#11111110b 'Setze den Akku auf 11111110 (binär) Lauflicht2: MOV P1,A 'Schreibe den Wert des Akku's an den Port1 LCALL Pause2 'Springe in die Pausenroutine JB P3.0,RichtungB 'Springe zu RichtungB, wenn Taster betätigt RL A 'Rotiere die Bits im Akku nach links LJMP Lauflicht2 'Wiederhole den obigen Ablauf immer wieder RichtungB: RR A 'Rotiere die Bits im Akku nach rechts LJMP Lauflicht2 'Wiederhole den obigen Ablauf immer wieder Pause2: 'Unterroutine MOV R0,#FFh 'R0=FFh Schleife3: MOV R1,#FFh 'R1=FFh Schleife4: NOP 'No Operation, 1 Maschinentakt NOP 'No Operation, 1 Maschinentakt DJNZ R1, Schleife4 'R1=R1-1: Wenn R1 > 0 dann springe zu Schleife4 DJNZ R0, Schleife3 'R0=R0-1: Wenn R0 > 0 dann springe zu Schleife3 RET 'Rückkehr zum Befehl nach dem letzten LCALL Der_Befehle_JNB_bit,rel: 'Jump Not Bit' ' Bei diesen Befehlen wird der Inhalt eines Bits abgefragt und ' wenn dieser 0 ist, erfolgt ein Programmsprung. Ist der ' Inhalt 1 wird einfach der folgende Befehl ausgeführt. ' Ansonsten entpricht er dem Befehl "JB bit,rel". '************************************************************** ' Weiter geht's mit "Einführung-4.asm"... '**************************************************************