Porterweiterung - Darf's ein Port mehr sein?

 

Materialbedarf

 

Anz. Bezeichnung Datenblatt
1 Batterie/Spannungsquelle 9V  
1 Spannungsregler 7805
1 ATMega8 AVR-Prozessor
1 74HC164
2 74HC175
8 Widerstand 220 Ohm  
1 Widerstand 10 kOhm  
1 Elektrolytkondensator 100 µF/16V  
1 Kondensator 100nF  
8 Standard-Leuchtdiode 3mm oder 5mm 3mm, 5mm

 

 

Wenn die Ports nicht reichen

 

Man ist intensiv dabei sein neues Projekt zu planen. Kern des Gerätes soll ein ATmega8 sein. Aber nach kurzer Planungsphase der Hardware muss man feststellen, dass man nicht alle Ein- und Ausgabeelemente an den vorhanden Ports angeschlossen bekommt. Die Anzahl der Ports reichen vorne und hinten nicht. Die Lösung ist relativ einfach. Man muss die Ports um Weitere ergänzen. Wie ist dies möglich?

 

Dazu schauen wir uns einmal an, was so ein Port eigentlich ist. Die Ports des AVR können als Ausgang und als Eingang arbeiten. Wenn Sie als Ausgang arbeiten, werden interne Daten-FlipFlops zum Pin durchgeschaltet. Diese Daten-FlipFlops werden mit einer Zuweisung mit den gewünschten Daten gefüllt (In Bascom mit Portx = Wert). Dann werden die Daten zu den Pins durchgeschaltet.

 

Soll der Port als Eingang arbeiten, werden einfach nur die Eingänge an den internen Datenbus des AVR gelegt wo sie dann weiter verarbeitet werden.

 

 

Ergänzung von Ausgangsports durch Daten-Register

 

Will man weitere Ausgangsports haben, ist es das Einfachste man klemmt weitere Daten-Register an den AVR. Nun muss man nur noch die externen Register mit Daten füllen.

 

 

Um dies einmal zu verdeutlichen, wurden hier 2 Daten-Latches an den AVR angeschlossen. Es wurden 4-Bit-Versionen verwendet. Wer 8 Bit haben möchte sollte den 74HC573 einsetzen.

Um jetzt den entsprechenden Latch zu füllen, muss man nun am Port D die gewünschten Daten anlegen. Jetzt muss nur noch der Steuereingang CP des entsprechenden Registers kurz auf 1 gelegt werden.

Für Latch 1 liegt der CP-Eingang auf Port C Bit 0 und für das zweite Latch auf Üprt C Bit 1.

Wurde ein kurzes 1-Signal an das entsprechende Latch abgegeben, werden die Daten übernommen, was dann die Leuchtdioden D1-D4, für Latch 1, bzw. D5-D8, für Latch 2, anzeigen.

Um dies nun zu testen gibt es ein kleines Programm:

 

$regfile "m8def.dat"
$crystal = 1000000

Config Portc.0 = Output
Config Portc.1 = Output
Config Portd = Output
 

Portd = &B00001001

Portc.0 = 1 : Portc.0 = 0

Portd = &B00001010

Portc.1 = 1 : Portc.1 = 0
Stop

 

Zu dem Programm muss nicht allzu viel gesagt werden. Erst legen wir mit

 

Portd = &B00001001

 

ein Bitmuster an Port D, welches wir ins 1. Latch übernehmen wollen. Damit dieses das tut, müssen wir den CP-Eingang des ICs kurz auf 1 legen. Wie wir wissen, liegt CP von Latch 1 auf Port C Bit 0. Somit brauchen wir nur 2 einfache Anweisungen:

 

Portc.0 = 1 : Portc.0 = 0

 

Nun leuchten D1 und D4 auf.

 

Für das zweite Latch läuft das Ganze ähnlich ab. Nur müssen wir hier nun das Bit 1 von Port C kurz auf 1 setzen.

 

Als nächstes schreiben wir einmal ein kleines Programm, welches auf den beiden Latches unterschiedliche Lichtmuster ausgeben. Auf Latch 1 wird ein 4 Bit Binärzähler dargestellt. Latch 2 zeigt hier ein kleines Lauflicht.

 

$regfile "m8def.dat"
$crystal = 1000000

Dim Reg1 As Byte
Dim Reg2 As Byte

Config Portc.0 = Output
Config Portc.1 = Output
Config Portd = Output

Reg2 = 1

Do
  Portd = Reg1
  Portc.0 = 1 : Portc.0 = 0
  Incr Reg1
  Portd = Reg2
  Portc.1 = 1 : Portc.1 = 0
  Shift Reg2 , Left : If Reg2 = 16 Then Reg2 = 1
  Waitms 300
Loop

 

Mit Hilfe von Latches kann man also die Ports des AVR schon massiv erweitern. Nehmen wir einmal an, es sind 2 Latches mit 8 Bit angeschlossen, so benötigen wir 10 Portpins um 16 Ausgänge zu steuern. Verwenden wir 3 Latches, benötigen wir 11 Port-Pins und uns stehen schon 24 Ausgänge zur Verfügung.

 

 

Weitere Ausgangsports durch Schieberegister

 

Obwohl es mit Latches schon sehr gut möglich ist, die Anzahl der Ausgänge des AVR zu erhöhen, sind freie Port-Pins trotzdem noch Mangelware. Es gibt aber eine Möglichkeit, wo wir mit 3 oder 4 Port-Pins auskommen und dadurch den AVR theoretisch unendlich viele Ausgänge verpassen können.

 

 

Um dies zu erreichen, müssen wir Schieberegister verwenden, welche einen parallelen Ausgang besitzen.

Den Reset-Eingang (MR=Master Reset) des Schieberegisters wird an Port D Bit 0 angeschlossen. Schieberegister benötigen noch ein Taktsignal, welches hier CP genannt wurde, dieses hängt an Bit 1 des Ports D. Der 74HC164 besitzt 2 Dateneingänge, welche aber durch eine Und-Funktion miteinander verknüpft sind, so dass wir nur Da an Port D Bit 2 des AVR klemmen. Db wird dauerhaft an + gelegt.

Die Ansteuerung eines Schieberegisters ist leider etwas komplizierter.

Bevor es mit Daten gefüllt wird, sollte es erst einmal zurückgesetzt werden. MR muss kurzzeitig auf 0 gesetzt werden. Im Normalbetrieb befindet sich dieser Eingang auf 1-Signal. Als Nächstes muss man das 1. Bit, welches in das Schieberegister hinein geschoben werden soll an Da anlegen. Nun muss man CP kurz auf 1 legen. Jetzt ist das 1. Bit im Register. Nun kann das 2. Bit an Da angelegt werden. Wieder CP kurz auf 1 legen. Das 1. Bit 'wandert' eine Stufe hoch und das 2. Bit wird hinein geschoben. Dies wird nun so lange wiederholt bis das Register gefüllt ist. Da wir hier nur 4 Ausgänge verwenden, muss das Ganze 4 mal wiederholt werden.

Das diese Routine nicht ganz so einfach ist, wie beim parallelem Latch zeigt das entsprechende Testprogramm:

 

$regfile "m8def.dat"
$crystal = 1000000

Dim Reg As Byte
Dim Save As Byte
Dim Outbit As Boolean
Dim Cnt As Byte

Config Portd.0 = Output
Config Portd.1 = Output
Config Portd.2 = Output

Portd.1 = 0

Do
  Save = Reg : Portd.0 = 0 : Portd.0 = 1
  For Cnt = 1 To 4
    Outbit = Save And 1 : Portd.2 = Outbit
    Portd.1 = 1 : Portd.1 = 0
    Shift Save , Right
  Next Cnt
  Incr Reg : Waitms 300
Loop

 

Mit diesem Programm realisieren wir wieder einen kleinen 4 Bit Binärzähler.

 

Bevor wir etwas ins Schieberegister schreiben können, müssen wir als erstes unsere Zählvariable sichern. Hierzu wurde die Variable 'Save' definiert. Dies ist notwendig da diese Variable im Laufe der Datenübertragung verändert wird. Dann sollte das Schiebergister zurück gesetzt werden.

 

Save = Reg : Portd.0 = 0 : Portd.0 = 1

 

Wie weiter oben schon erwähnt, wollen wir nur 4 Bit übertragen. Daher hat die folgende For-Next-Schleife auch nur 4 Durchläufe.

 

Als ersten Befehl innerhalb der Schleife maskieren wir das kleinste Bit unseres zu übertragenen Wertes aus und legen das Ergebnis an den Datenport:

 

Outbit = Save And 1 : Portd.2 = Outbit

 

Der Einfachheit halber nehmen wir das unterste Bit. Da dieses Bit im Schieberegister aber später nach oben geschoben wird, kommt es am Schieberegisterausgang zu einer Spiegelung. Aber das Prinzip dürfte trotzdem verstanden werden.

 

Nun wo das Datenbit an Da anliegt, müssen wir dem Schieberegister noch den Befehl zur Übernahme geben. Dies wird ja erreicht durch ein kurzes anlegen des 1-Signal am CP des ICs:

 

Portd.1 = 1 : Portd.1 = 0

 

Jetzt ist das Bit in das Schieberegister übertragen worden. Nun müssen wir noch dafür sorgen, dass beim nächsten Schleifendurchgang das nächste Bit übertragen wird:

 

Shift Save , Right

 

Hier schieben wir jetzt das ganze Variablenbyte um eine Stelle nach rechts. Das bereits übertragene Bit wird dann jeweils 'vergessen'.

 

Zum Abschluss schließen wir die For-Next-Schleife noch ab. So werden nun die unteren 4 Bit unserer Zählvariable ans Schieberegister übertragen und wir können den Wert an den Leuchtdioden ablesen. Aber eben nur die unteren 4 Bit. Die oberen 4 Bit der Zählvariable werden in diesem Beispiel ignoriert.

 

Jetzt muss noch die Zählvariable durch 'Incr Reg' um 1 erhöht werden. Und, damit wir den Wert an den LEDs auch ablesen können, wurde eine Wartezeit eingefügt.

 

Das Schöne an Schieberegistern ist, das man diese wunderbar kaskadieren, also hintereinander schalten kann. Hierzu müssen wir nur den letzten Registerausgang nur an den Dateneingang des nächsten Schieberegisters hängen. Die Steuerleitungen CP und MR werden einfach durch verbunden.

Somit ist es möglich, rein theoretisch, unendlich viele Ausgänge mit nur wenigen Ports zu realisieren.

Ein großer Nachteil dieser Methode soll aber nicht verschwiegen werden. Da jedes Bit, welches zusätzlich in eine Schieberegister-Kette geschoben werden soll, relativ viel Rechenzeit benötigt, können Schieberegister nicht für Anwendungen genutzt werden, wo hohe Ausgangsfrequenzen benötigt werden. Da dies aber selten vorkommt, ist es wohl weniger ein Problem.

 

 

Zurück zur Auswahlseite            Zur Hauptseite