P: Czy poszczególne piny różnych portów mikrokontrolera można zmapować do rejestru i zmienić ich wartości podczas zmiany wartości rejestru?
Scenariusz: Zużyłem niektóre piny z każdego portu (8 bitów) mikrokontrolera. Teraz chcę interfejs urządzenia, które potrzebuje 8-bitowej magistrali (przypuśćmy, że D0 do D7 W SEKWENCJI), to znaczy, że potrzebuję 8 pinów od kontrolera, aby móc połączyć je jeden na jeden
portx0 -> D0 // x is the name of port followed by bit location on that port
portx1 -> D1
...
portx7 -> D7
ale nie mam całego portu 8 pinów, które mogę połączyć z tym urządzeniem, raczej mam kilka pinów z portx, niektóre z porty i niektóre z portz. Nowy scenariusz połączenia wygląda następująco (odpowiednio połączenie mikrokontrolera z urządzeniem)
portx0 -> D0
portx1 -> D1
portx2 -> D2
porty4 -> D3
porty5 -> D4
porty6 -> D5
porty7 -> D6
portz1 -> D7
W tym stanie, jeśli chcę wysłać wartość powiedz
unsigned char dataReg = 0xFA;
do mojego urządzenia z kontrolera muszę wykonać nieco mądre operacje na wartości, która ma zostać wysłana i ustawić każdy pin zgodnie z wartością w rejestrze indywidualnie. Na przykład
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 );
Teraz, przechodząc do głównego pytania, aby uniknąć tych indywidualnych obliczeń dla każdego bitu na różnych portach, czy poszczególne piny różnych portów mikrokontrolera mogą być mapowane na rejestr, a ich wartości można zmieniać przy zmianie wartości rejestru?
Odpowiedzi:
Wygląda na to, że twoje pytanie sprowadza się do posiadania 8-bitowej wartości w oprogramowaniu układowym oraz chęci odczytania i zapisania tego z dowolnej kolekcji pinów portu.
Nie ma na to bezpośredniego sposobu sprzętowego. Musisz napisać dwie procedury, jedną, aby odczytać wartość 8-bitową, a drugą, aby ją zapisać. Inni wspominali o stosowaniu związków, ale to zły pomysł. W związkach musisz poradzić sobie z każdym bitem osobno, a kod staje się zależny od kolejności bitów mikroprocesora. To może być i tak droga, jeśli wszystkie 8 bitów jest rozproszonych całkowicie niezależnie. Jeśli tak, niewiele możesz zrobić, ale stworzyć specjalny kod dla każdego bitu.
Lepszym sposobem na zrobienie tego, szczególnie jeśli możesz pogrupować bity w kilku ciągłych porcjach na fizycznych portach, jest użycie maskowania, przesunięcia i ORowania. Na przykład, jeśli trzy niskie bity bajtu wewnętrznego znajdują się na bitach <6-4> portu, przesuń tę wartość portu o 4, a ORAZ o 7, aby ustawić te bity w ich końcowej pozycji. Przesunięcie i maskowanie (lub maskowanie i przesunięcie) bitów z innych portów na miejsce i złożenie ostatniego 8-bitowego bajtu przez ORowanie w nim wyników.
Tego rodzaju kręcenie bitów niskiego poziomu jest łatwiejsze w asemblerze niż C. Prawdopodobnie umieściłbym procedury odczytu i zapisu bajtów w jednym module asemblera i sprawiłbym, że interfejs można wywoływać z C.
źródło
Zasadniczo nie jest to możliwe. O ile mi wiadomo, z PIC nie jest to możliwe.
Znam tylko jeden mikrokontroler, który może to zrobić, Cypress PSoC . Jest to wysoce konfigurowalny system na chipie. Spośród wielu rzeczy, które możesz zrobić, to dosłownie zdefiniować własny rejestr (1-8 bitów) i podłączyć go do dowolnych pinów, które lubisz, a nawet do obwodów wewnętrznych.
Na przykład tutaj utworzyłem 6-bitowy rejestr kontrolny. 5 bitów przechodzi prosto na piny, a 6 bit używam do XOR z wejściem z 7 pinu.
Na chipie mogę przypisać te piny do dowolnych dostępnych pinów GPIO. (To szare zdjęcie)
źródło
Możesz wypróbować następujące. Napisz własną strukturę, która mapuje odpowiednie piny 2 portów (które mają być użyte). Teraz aktualizacja wartości w tym rejestrze spowoduje ustawienie / zresetowanie pinów tych 2 portów. Spróbuj i daj nam znać, czy zadziałało !!
Jestem pewien, że to powinno zadziałać.
źródło
Jeśli poprawnie zrozumiałem pytanie, w C jest to dość łatwe:
Ogólna deklaracja typu, może być ponownie wykorzystana w dowolnym rejestrze:
Aby zdefiniować port, którym chcemy się zająć:
Aby bezpośrednio przekręcić pinezkę na tym porcie:
W kodzie:
Cały rejestr:
Warto przeczytać o strukturach, związkach, typach i enumie - wszystko to sprawia, że życie jest o wiele przyjemniejsze w osadzeniu i ogólnie!
źródło