Mail to Code: Tutorial

Lernt, wie man den Code für Rechenknechte schreibt.

English version English Version

Ports und Register

Register

Register sind Speicherbereiche für Daten, deren einzelne Bits zur Ansteuerung spezieller Funktionen in einem Mikrocontroller genutzt werden. In einem 8-Bit Mikroconroller umfasst ein Register in der Regel auch 8 Bit.

GPIOs sind gruppiert

Bislang haben wir GPIOs als alleinstehende Periperie zur Spannungsausgabe betrachtet. Hardwaretechnisch sind diese allerdings in Gruppen verschaltet. Bei einem 8-Bit Mikrocontroller sind 8 GPIOs zu einem Port zusammengefasst. Ein derartiger Port besitzt drei 8-Bit Register zur Ansteuerung der GPIOs. Diese haben die folgenden Funktionen:

DDRx

DDR steht für Data Direction Register, geben also die Richtung an, in der Daten verarbeitet werden. Kurz gesagt, wird über dieses Register festgelegt, ob ein Pin als Ein- oder Ausgabepin fungiert. Ist ein Bit dieses Registers auf logisch "1" gesetzt, so ist der damit verbundene GPIO im Modus Ausgabe. Logisch "0" bedeutet, dass der GPIO als Eingang geschaltet ist. Beim Start des Mikrocontrollers sind alls Bits der Register auf "0" gesetzt.
DDR können nicht nur geschrieben werden, um Pins auf Ein- oder Ausgang zu setzen. Diese Register können in einem Programm auch gelesen werden, um festzustellen, in welchem Modus sich die Pins befinden.

PORTx

Über dieses Register können die GPIOs auf logisch "0" und somit auf 0V Ausgangsspannung oder auf logisch "1", also +5V oder +3.3V, je nach Mikrocontroller-Typ gesetzt werden. Wie auch bei digitalWrite() gilt, dass ein Pin nur auf +5V gesetzt werden kann, wenn dieser zuvor als Ausgang gesetzt wurde. Das entsprechende Bit im DDR muss also auf "1" gesetzt sein.
Alle Bits dieses Registers sind beim Start des Mikrocontrollers auf "0" gesetzt. Wird ein GPIO über das DDR als Ausgang geschaltet, so ist die ausgegebene Spannung 0V. Wie die DDR, können die PORTs sowohl geschrieben als auch gelesen werden.

PINx

Wie über die PORT Register, können die logischen Spannungen, die aktuell an den GPIOs anliegen, auch über das PINx Register ausgelesen werden. Dieses Register läst Schreibvorgänge allerdings nicht zu!

Einige Ports des ATmega2560

Mit unter sind nicht alle Bits eines Ports auch über Pins nach außen geführt, also als GPIOs verfügbar. Beim ATmega2560 stehen die folgenden Ports vollständig als GPIOs zur Verfügung:

PORTA
DDRA
PINA
PORTA7
DDRA7
PINA7
Pin D29
PORTA6
DDRA6
PINA6
Pin D28
PORTA5
DDRA5
PINA5
Pin D27
PORTA4
DDRA4
PINA4
Pin D26
PORTA3
DDRA3
PINA3
Pin D25
PORTA2
DDRA2
PINA2
Pin D24
PORTA1
DDRA1
PINA1
Pin D23
PORTA0
DDRA0
PINA0
Pin D22


Wie in der Tabelle zu sehen, ist die Zuordnung der GPIOs zu den Bits 0-7 in den Registern bei PORT, DDR und PIN identisch, daher sind in den folgenden Tabellen nur die Pinnummern gelistet.

PORTB / DDRB / PINB
Pin D13 Pin D12 Pin D11 Pin D10 Pin D50 Pin D51 Pin D52 Pin D53


PORTC / DDRC / PINC
Pin D30 Pin D31 Pin D32 Pin D33 Pin D34 Pin D35 Pin D36 Pin D37


PORTF / DDRF / PINF
Pin D61
(A7)
Pin D60
(A6)
Pin D59
(A5)
Pin D58
(A4)
Pin D57
(A3)
Pin D56
(A2)
Pin D55
(A1)
Pin D54
(A0)


PORTK / DDRK / PINK
Pin D69
(A15)
Pin D68
(A14)
Pin D67
(A13)
Pin D66
(A12)
Pin D65
(A11)
Pin D64
(A10)
Pin D63
(A9)
Pin D62
(A8)


Beispiel Lauflicht per Register

Kombinieren wir unser Wissen zu Registern und Ports mit dem Kapitel zu Dualzahlen, so kann das Codebeispiel für ein Lauflicht aus 8 LEDs wesentlich vereinfacht werden:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
void setup() {
  // Set digital pins 22 - 29 to OUTPUT mode via DDR
  DDRA = 0b11111111;
}
 
void loop() {
  // When switching GPIOs via PORT, one line of code sets,
  // which of the 8 LEDs is ON an which LEDs are OFF;
 
  PORTA = 0b00000001;
 
  // Set pause time before next LED in sequence is switched on:
  delay(400);
 
  // With that, just one other line of code turns
  // LED on PIN 22 OFF and LED on Pin 23 ON
 
  PORTA = 0b00000010;
 
  // And of course wait until the sequence goes on:
  delay(400);
 
  // You should have understood the logic behind,
  // so here the remaining code for the running light
 
  PORTA = 0b00000100;
  delay(400);
 
  PORTA = 0b00001000;
  delay(400);
 
  PORTA = 0b00010000;
  delay(400);
 
  PORTA = 0b00100000;
  delay(400);
 
  PORTA = 0b01000000;
  delay(400);
 
  PORTA = 0b10000000;
  delay(400);
}
    






Du findest diese Seite klasse?

Gummibärchen als Nervennahrung beim Programmieren und der Betrieb dieses Servers verschlingen mein Geld.
Helft mit einer Motivationsspritze, dieses Projekt am Laufen zu halten.

Klick hier oder scan den QR Code, um eine Spende zu überweisen.



Vielen Dank!

Fragen? Anregungen? Fehler gefunden?
Kontakt per E-mail: question@h1i1.de