logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

PIC32MX - Różnice między rejestrami LATx i PORTx w MPLAB X

cyber90 11 Paź 2014 13:32 2337 14
  • #1 14032784
    cyber90
    Poziom 15  
    Posty: 234
    Ocena: 8
    Witam,
    Mam problem z zrozumieniem tych portów, a w szczególności rejestru LATx i PORTx.
    Podaję poniżej makra dostępne w MPLAB X:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    są jeszcze makra mPORTBSetPinsDigitalOut(), mPORTBSetPinsDigitalIn(). Nie rozumiem w jaki sposób są powiązana rejestry LATx i PORTx. Jeżeli chcę odczytać jaki stan jest na pinie (np przez przycisk który może zwierać do masy bądź do Vcc) robię to w taki sposób.

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Niestety program nie działa prawidłowo, domyślałem się dlaczego ale inny zapis nie przyniósł spodziewanych efektów. Mógłby ktoś mi wytłumaczyć co robię źle i w jaki sposób są powiązane rejestry LATx i PORTx.
  • #2 14032861
    Konto nie istnieje
    Konto nie istnieje  
  • #3 14032919
    cyber90
    Poziom 15  
    Posty: 234
    Ocena: 8
    Używam PICKIT3 więc debugowanie raczej odpada. Więc tak do procka mam podpięte diody na pinach RD0 RD1 RD2. Po zaprogramowaniu powyższym kodem (także po zmianie na !=0) program nie działa prawidłowo.
    Linie jako wyjścia używam makro:

    mPORTDSetPinsDigitalOut(BIT_2 | BIT_1|BIT_0);

    Do tych pinów podpięte są diody. Aby ustawić pin jako wejście używam makra:

    mPORTDSetPinsDigitalIn(BIT_3);

    W przypadku gdy w if mam !=0 świecą się dwie diody RD1 i RD2. Gdy zwieram linie RD3 do masy bądź do Vcc albo do RD0 bo na tej linii jest również stan wysoki to nic się nie dzieje. Programowałem już procesory i najlepszym rozwiązaniem byłoby podciągnięcie wej do Vcc (pull-up) , ale nie znalazłem takiego makra Moje domysły polegały na tym że jest różnica pomiędzy:
    mPORTDReadBits(_bits) a mPORTDReadLatchBits(_bits) i jest napewno tylko nie wiem czy dobrze rozumiem. Pierwsze makro odczytuje stan w jaki skonfigurowane są PORTY w programie a drugie makro jaki jest rzeczywisty stan na danym pinie?
  • #4 14032944
    Konto nie istnieje
    Konto nie istnieje  
  • #5 14033279
    cyber90
    Poziom 15  
    Posty: 234
    Ocena: 8
    albertb
    Jak korzystać z debugera w tym środowisku jeszcze nie wiem. Skasowałem porty ale to również nie pomogło, więc postanowiłem tak zrobić i doszedłem do takich wniosków:
    Muszę przyznać że nie ma nic kompletnie w internecie na temat PIC32, ale walczę :) Jedyne info nt. portów I/O znalazłem tutaj:
    http://www.microchip.com/wwwproducts/Devices.aspx?product=PIC32MX575F512H#documentation
    Documentation and software =>Reference Manual => PIC32 Family Reference Manual, Sect. 12 I/O Ports

    Odnośnie podciągania pinów do Vcc jest taka informacja:
    • Change Notice Pull-up Enable (CNPUEx)
    • Change Notice Pull-down Enable (CNPDx)
    ale jak to użyć nie mam pojęcia.

    Wracając do programu:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Postanowiłem użyć tylko rejestrów i taki program działa. Dodam że linia wej jest podciągnięta przez zewnętrzny rezystor do Vcc. Gdy w if używam mPORTDReadBits(BIT_3) zamiast PORTDbits.RD3 program nie działa. Może mi ktoś wytłumaczyć dlaczego? I w jaki sposób użyć rejestru CNPUEx aby ustawić wewn. podciągnięcie pull-up?
  • #6 14033947
    Marico
    Poziom 20  
    Posty: 409
    Pomógł: 28
    Ocena: 60
    Jaki pic32 używasz? Pullupy są na pinach kontrolowanych przez rejestry CNx (Change Notice). Piny te mają funkcję generowania przerwania podczas zmiany ich stanu, stąd mają też funkcję pullup. Piny te zidentyfikujesz przez oznaczenie CN0, CN1, itd. zwróć uwagę, że pullupy nie są zgrupowane w całym (jednym) porcie (jak np. port B w pic18f|16f) ale są porozrzucane po różnych pinach w różnych portach.
    Aby włączyć pullap np. na pinie CN14 (w pic32mx4* jest to pin 5 portu D) możesz wykorzystać makro:

     ConfigCNPullups(CN14_PULLUP_ENABLE); 

    Jeśli chcesz też na pinie CN15:
     ConfigCNPullups(CN14_PULLUP_ENABLE|CN15_PULLUP_ENABLE|); 


    Proponuje nie robić testów na wejściach, które "wiszą" bez podciągnięcia bo będziesz miał nieoczekiwane wyniki.
  • #7 14033972
    cyber90
    Poziom 15  
    Posty: 234
    Ocena: 8
    Z tego co napisałeś mam rozumieć że nie na wszystkich cyfrowych portach mam możliwość włączenia na wej pull-up? Używam PIC32MX575F512H (http://www.microchip.com/wwwproducts/Devices.aspx?product=PIC32MX575F512H#documentation). Tak wiem o tym że na wejściach bez podciągnięcia mogę mieć nieoczekiwane wyniki.
  • Pomocny post
    #8 14034013
    Marico
    Poziom 20  
    Posty: 409
    Pomógł: 28
    Ocena: 60
    Sprawdź dokładnie w DS do tego układu, które porty. Poszukaj rejestrów CNPUX CNPDX (gdzie X to port A B C itd).
    Rejestr CNPUA to załączanie pull-up na pinach portu A (np. CNPUAbits.CNPUA0=1 włącza pullap na pinie 0 portu A). Rejestr CNPDA to analogiczna kontrola pull-down.
    Nie każdy pic32 posiada pull-downy (np. pic32mx440* nie posiada), stąd ważne aby dokładnie zapoznać się z dokumentacją.
    Z tego co widzę pic32mx575 ma pull-up tylko na porcie E natomiast nie posiada pull-downów.
    Przyznaję, że czasami dokumentacja do pic32 jest zbyt ogólna, dostępne rejestry w danym modelu układu możesz sobie poszukać w plikach nagłówkowych np. include/proc/p32mx575f512h.h

    Dodano po 17 [minuty]:

    Pytałeś jeszcze po co jest LAT i PORT. Rejestr LAT to ustawianie wartości pinu (latch'y wyjściowych) przy konfiguracji portu jako out. Poziom wyjściowy pinu kontrolujemy przez rejestr LAT, natomiast odczyt stanu pinu (gdy jest in) poprzez rejestr PORT.
    Poniżej cytat z dokumentacji po co wprowadzono dwa rejestry:
    Cytat:
    The LATx register associated with an I/O pin eliminates the problems that could occur with read-modify-write instructions. A read of the LATx register returns the values held in the port output latches, instead of the values on the I/O pins. A read-modify-write operation on the LAT register, associated with an I/O port, avoids the possibility of writing the input pin values into the port latches. A write to the LATx register has the same effect as a write to the PORTx register.
  • #9 14034071
    cyber90
    Poziom 15  
    Posty: 234
    Ocena: 8
    Ok dzięki już mi się coś rozjaśniło. Jednak dalej nie wiem dlaczego jak odczytuję makrem mPORTDReadBits(BIT_3) stan na linii RD3 to nie działa to jak powinno, a jak odczytuję PORTDbits.RD3 to działa to jak powinno.
  • Pomocny post
    #10 14034115
    Marico
    Poziom 20  
    Posty: 409
    Pomógł: 28
    Ocena: 60
    mPORTDReadBits(BIT_3) musi działać :). Jak pisał Albert pomyśl i przyjrzyj się makru dlaczego nie zadziała ==1 ;)
    Makro rozwija się tak:
    #define BIT_3                        (1 << 3)
    #define mPORTDReadBits(_bits)               (PORTD & (unsigned int)(_bits))


    pomyśl dlaczego if(mPORTDReadBits(BIT_3)==1) zawsze będzie FALSE.
  • #11 14034274
    cyber90
    Poziom 15  
    Posty: 234
    Ocena: 8
    ok rozumiem dzięki za wyjaśnienie. PS. Brawo Polacy !!! :)
  • #12 14035209
    cyber90
    Poziom 15  
    Posty: 234
    Ocena: 8
    Ostatnie pytanie dotyczące portów. PIC32MX posiada według noty katalogowej dwa rodzaje wyjść: push-pull i open drain. Jak to wygląda w środku, znalazłem takie dwa schematy:
    PIC32MX - Różnice między rejestrami LATx i PORTx w MPLAB X

    Wyjście open-drain: jeżeli chcemy mieć potencjał masy na wyjściu tranzystor musi przewodzić (czyli ustawiamy w konfiguracji mPORTDOpenDrainOpen(BIT_1) i
    mPORTDSetBits(BIT_1) ) i wtedy na wyjściu mamy stan "0" tak?
    A jeżeli chcemy mieć na wyjściu potencjał zasilania tranzystor nie przewodzi (czyli stawiamy w konfiguracji mPORTDOpenDrainOpen(BIT_1) i
    mPORTDClearBits(BIT_1) ) i wtedy na wyjściu mamy stan "1" tak?

    Dobrze to rozumuję? Odnośnie push-pull ustawiamy albo mPORTDClearBits(BIT_1) i mamy na wyjściu "0" albo mPORTDSetBits(BIT_1) i mamy na wyjściu "1" ?
    Jeżeli dobrze to zrozumiałem to proszę mi powiedzieć kiedy które typy wyjść się stosuje, w jakich przypadkach lepiej jest zastosować push-pull , a kiedy open-drain?
  • #13 14035376
    Marico
    Poziom 20  
    Posty: 409
    Pomógł: 28
    Ocena: 60
    Open drain najczęściej stosuje się, gdy chcesz wysterować urządzenie, które wymaga poziomu "1" o wyższym napięciu niż aktualne poziomy mcu np. 5V. Wtedy podciągasz takie wyście zewnętrznym rezystorem do +5V i konfigurujesz je jako open drain.
    BTW to jest Twój "pierwszy" mikrokontroler?
  • #14 14035889
    cyber90
    Poziom 15  
    Posty: 234
    Ocena: 8
    Jeszcze jedno co jest mi potrzebne do pełni szczęścia. Istnieje gotowa funkcja opóźniająca w MPLAB X typu _delay_ms(), _delay_us(). Czy raczej trzeba samemu wykorzystać jeden z timerów i napisać taką funkcję?
  • #15 14035944
    Marico
    Poziom 20  
    Posty: 409
    Pomógł: 28
    Ocena: 60
    Nie kojarzę gotowca w libach XC32, przykład najprostrzego delaya z wykorzystaniem core timera, musisz tylko zdefiniować Twój aktualny SYS_CLOCK:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

Podsumowanie tematu

LABEL_AI_GENERATED
W dyskusji poruszono różnice między rejestrami LATx i PORTx w mikrokontrolerach PIC32MX, szczególnie w kontekście użycia makr w MPLAB X. Użytkownik miał problemy z odczytem stanów pinów, co prowadziło do nieprawidłowego działania diod podłączonych do portów RD0, RD1 i RD2. Zwrócono uwagę na znaczenie rejestrów CNPU i CNPD do włączania podciągnięć (pull-up) na pinach, a także na różnice w działaniu makr mPORTDReadBits i PORTDbits. Użytkownik zrozumiał, że rejestr LAT służy do ustawiania wartości na pinach wyjściowych, podczas gdy PORT do odczytu stanów pinów. Poruszono również temat wyjść typu open-drain i push-pull oraz ich zastosowania. Na koniec zapytano o dostępność funkcji opóźniających w MPLAB X.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA