BASCOM: Zeitbedarf bei Port-Befehlen

Atmega 328 mit BASCOM und FORTH programmieren
Antworten
Heinrichs
Beiträge: 185
Registriert: Do 21. Okt 2010, 18:31

BASCOM: Zeitbedarf bei Port-Befehlen

Beitrag von Heinrichs » Mi 19. Feb 2020, 17:28

Häufig möchte man einzelne Bits eines Ports ansprechen, sei es lesend oder auch schreibend. Mit BASCOM geht das z. B. beim Port D ganz einfach so:

Ausgang, schreibend: PortD.x = 1 ‘ oder auch 0

Eingang, lesend: Wert = PinD.x

Dabei kann x für eine Konstante, aber auch für eine Variable stehen.

Wie BASCOM beim Kompilieren dieser Befehle vorgeht, hängt wesentlich davon ab, ob x eine Konstante oder eine Variable darstellt. Handelt es sich um eine Konstante, dann kann es auf passende Assembler-Befehle zurückgreifen, z. B.:

sbi portd, k (set bit k in I/O-Register; k: Konstante zwischen 0 und 7)

bzw.

cbi portd, k (clear bit k in I/O-Register; k: Konstante zwischen 0 und 7)

Wesentlich komplizierter wird es, wenn es sich bei x und eine Variable handelt. Hierfür gibt es bei den AVR-Mikrocontrollern nämlich keinen passenden Maschinenbefehl und BASCOM muss hier einiges an Arbeit leisten, um sein Ziel zu erreichen. Das merkt man auch daran, dass die Ausführung eines solchen Port-Befehls nun deutlich länger braucht. Interessant ist auch: Die benötigte Zeit ist um so größer, je höher der Wert von x ist. Dies kann man leicht mit folgenden Programm testen:

Code: Alles auswählen

Dim I As Byte
Ddrd = 252
Portd = 0

For I = 2 To 7
  Portd.i = 1
  Portd.i = 0
Next I

End
An den Ausgängen D.2 bis D.7 erhält man damit folgende Signale:

portD_mit_var_i.jpg
Signalverlauf bei den Ports D.2 bis D.7
portD_mit_var_i.jpg (12.01 KiB) 22323 mal betrachtet

Mit bloßem Auge erkennt man: Die High-Phasen TH der einzelnen Ausgänge (Diese entsprechen jeweils der Zeit für die Ausführung des Ausschaltvorgangs!) sind unterschiedlich lang und werden mit zunehmenden Wert von I größer. Messungen ergeben: Gehen wir von einer Bit-Nummer zur nächsten über, so steigt der Zeitbedarf um einen konstanten Wert, in diesem Fall um 4 Taktzyklen.


Um das zu verstehen, muss man hinter die Kulissen schauen und sich überlegen, wie der Mikrocontroller mit den zur Verfügung stehenden Maschinen-Befehlen vorgehen kann. Die Idee ist dabei folgende:

Zunächst müssen wir in einem Register - wir nennen es maske - ein Byte mit dem Wert &B00001000 erzeugen; dabei soll die 1 an der Position k stehen, die in einem Register - wir nennen es k - gespeichert ist. Dazu lädt man zunächst den Wert 1 in das Register maske und schiebt das Bitmuster von maske anschließend k mal nach links.

Nun laden wir den Wert von PortD in ein weiteres Registers - wir nennen es pd. Die Werte von maske und pd verknüpfen wir durch ein logisches ODER und speichern den Wert wieder in pd ab; diesen Vorgang bezeichnet man auch als Maskieren. Das Bitmuster von pd hat dadurch den Wert 1 beim Bit k erhalten; die restlichen Bits sind unverändert geblieben. Nun wird der Wert von pd an PortD ausgegeben. Unser Ziel ist erreicht.

Je größer nun der Wert von k ist, desto mehr Schiebevorgänge müssen erfolgen und desto länger dauert es, bis der maskierte Wert an PortD ausgegeben wird.

Weitere Einzelheiten kann man der Anlage entnehmen. Hier wird auch ein ausführlich kommentiertes Assembler-Programm zu diesem Problem angegeben.

.
Dateianhänge
Zeitbedarf_bei_PortD_x_V2.pdf
Zeitbedarf bei PortD.x
(119.1 KiB) 2144-mal heruntergeladen

Antworten