F: Können einzelne Pins verschiedener Ports eines Mikrocontrollers einem Register zugeordnet und ihre Werte beim Ändern des Registerwerts geändert werden?
Szenario: Ich habe einige Pins von jedem Port (8-Bit) des Mikrocontrollers belegt. Jetzt möchte ich ein Gerät anschließen, das einen 8-Bit-Bus benötigt (angenommen, D0 bis D7 IN SEQUENCE), das heißt, ich benötige 8 Pins vom Controller, damit ich sie eins zu eins anschließen kann
portx0 -> D0 // x is the name of port followed by bit location on that port
portx1 -> D1
...
portx7 -> D7
aber ich habe nicht einen ganzen Port mit 8 Pins, den ich mit diesem Gerät verbinden kann, sondern ich habe einige Pins von portx, einige von porty und einige von portz. Das neue Verbindungsszenario ist wie folgt: (Verbindung vom Mikrocontroller zum Gerät)
portx0 -> D0
portx1 -> D1
portx2 -> D2
porty4 -> D3
porty5 -> D4
porty6 -> D5
porty7 -> D6
portz1 -> D7
In diesem Zustand, wenn ich einen Wert senden möchte, sagen
unsigned char dataReg = 0xFA;
An meinem Gerät vom Controller muss ich bitweise Operationen an dem zu sendenden Wert durchführen und jeden Pin gemäß dem Wert im Register einzeln einstellen. Beispielsweise
portx0 = ((dataReg & 0x01) >> 0 ); // Masking and shifting as bit position
portx1 = ((dataReg & 0x02) >> 1 );
portx2 = ((dataReg & 0x04) >> 2 );
porty4 = ((dataReg & 0x08) >> 3 );
porty5 = ((dataReg & 0x10) >> 4 );
porty6 = ((dataReg & 0x20) >> 5 );
porty7 = ((dataReg & 0x40) >> 6 );
portz1 = ((dataReg & 0x80) >> 7 );
Kommen wir nun zur Hauptfrage, um diese individuellen Berechnungen für jedes Bit an verschiedenen Ports zu vermeiden. Können einzelne Pins verschiedener Ports eines Mikrocontrollers auf ein Register abgebildet und ihre Werte beim Ändern des Registerwerts geändert werden?
Antworten:
Es scheint, dass Ihre Frage darauf hinausläuft, einen 8-Bit-Wert in der Firmware zu haben und diesen von und zu einer beliebigen Sammlung von Port-Pins lesen und schreiben zu wollen.
Es gibt keine direkte Hardware-Möglichkeit, dies zu tun. Sie müssen zwei Routinen schreiben, eine zum Lesen des 8-Bit-Werts und eine zum Schreiben. Andere haben die Verwendung von Gewerkschaften erwähnt, aber das ist eine schlechte Idee. Bei Gewerkschaften muss jedes Bit separat behandelt werden, und der Code hängt von der Bitreihenfolge des Mikros ab. Dies könnte sowieso der Weg sein, wenn alle 8 Bits völlig unabhängig voneinander verstreut sind. In diesem Fall können Sie nur für jedes Bit einen speziellen Code erstellen.
Die bessere Möglichkeit, dies zu tun, besteht insbesondere dann, wenn Sie die Bits in ein paar zusammenhängenden Blöcken auf den physischen Ports gruppieren können, darin, Maskierung, Verschiebung und ODER-Verknüpfung zu verwenden. Wenn sich die unteren drei Bits des internen Bytes beispielsweise auf den Bits <6-4> eines Ports befinden, verschieben Sie diesen Portwert nach rechts um 4 und UND mit 7, um diese Bits an ihre endgültige Position zu bringen. Verschieben und maskieren (oder maskieren und verschieben) Sie Bits von anderen Ports an die richtige Stelle und setzen Sie das letzte 8-Bit-Byte durch ODER-Verknüpfung der Ergebnisse zusammen.
Diese Art von Bit-Twiddling auf niedriger Ebene ist in Assembler einfacher als in C. Ich würde wahrscheinlich die Lese- und Schreibroutinen für Bytes in ein einziges Assembler-Modul schreiben und die Schnittstelle von C aus aufrufbar machen.
quelle
Im Allgemeinen ist dies nicht möglich. Soweit ich weiß, ist das mit PICs nicht möglich.
Es gibt nur einen mir bekannten Mikrocontroller, den Cypress PSoC . Es ist ein hoch konfigurierbares System auf dem Chip. Unter den vielen Möglichkeiten können Sie buchstäblich Ihr eigenes Register (1-8 Bit) definieren und es mit beliebigen Pins oder sogar mit internen Schaltkreisen verbinden.
Zum Beispiel habe ich hier ein 6-Bit-Steuerregister angelegt. 5 der Bits gehen direkt zu den Pins, während das 6. Bit, das ich verwende, mit der Eingabe von einem 7. Pin zu XOR.
Auf dem Chip kann ich diese Pins jedem der verfügbaren GPIO-Pins zuweisen. (Es sind die Grauen das Bild)
quelle
Sie können Folgendes versuchen. Schreiben Sie eine eigene Struktur, die den jeweiligen Pins der 2 Ports (die verwendet werden sollen) zugeordnet ist. Wenn Sie nun den Wert in diesem Register aktualisieren, werden die Pins dieser 2 Ports gesetzt / zurückgesetzt. Versuchen Sie einfach und lassen Sie uns wissen, ob es funktioniert hat !!
Ich bin zuversichtlich, dass dies funktionieren sollte.
quelle
Wenn ich die Frage richtig verstanden habe, ist es in C einfach genug:
Generische Typdeklaration, kann für jedes Register wiederverwendet werden:
Um einen Port zu definieren, den wir ansprechen möchten:
Und um direkt einen Pin an diesem Port zu drehen:
In Code:
Gesamtes Register:
Es lohnt sich, sich über Strukturen, Gewerkschaften, Typedefs und Aufzählungen zu informieren - all dies macht das Leben im Embedded- und im Allgemeinen so viel schöner!
quelle