Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

GPIO - GPIO Configuration

Tojmak 30 Gru 2014 22:06 900 18
  • #1 30 Gru 2014 22:06
    Tojmak
    Poziom 7  

    Witam,
    mam pewien problem jeśli chodzi o zrozumienie konfiguracji portów. Mam następujące linijki kodu :

    Kod: cpp
    Zaloguj się, aby zobaczyć kod

    no i tutaj rodzi mi się pytanie, co wprowadzają w tym przypadku znaki "&=" oraz "|=". Z tego co mi się wydaje są to operatory logiczne implikacji oraz alternatywy? Jak mam w takim razie to rozumieć/traktować? Proszę o pomoc. Nie mam problemu ze zrozumieniem co znaczyło by np. GPIOA ->CRL = 0xFFF00000;, ale nie mogę właśnie dojść do tego co przedstawia przedstawiona powyżej sytuacja. Przepraszam za kłopot, dziękuje za jakąkolwiek pomoc

    Pozdrawiam serdecznie

    0 18
  • #2 30 Gru 2014 22:17
    Steryd3
    Poziom 31  

    Wejdź na stronę: mikrokontrolery.blogspot.com tam to jest objaśnione pod hasłem: ustawianie i zerowanie bitów.

    0
  • #3 30 Gru 2014 22:22
    BlueDraco
    Specjalista - Mikrokontrolery

    Raczej iloczynu i sumy logicznej.

    Wiesz, to jest tak: jak ktoś się panicznie boi mikrokontrolera i nie ma odwagi zajrzeć do dokumentacji, w dodatku nie ma pojęcia, jak chce napisać program, to boi się nadać wartości jakimkolwiek bitom w jakichkolwiek rejestrach, żeby czegoś nie zepsuć, wtedy pisze coś na kształt "ten bit to ja chcę ustawić na 1, a o reszcie wolę nic nie wiedzieć" - i stąd zwykle biorą się takie magiczne operacje na rejestrach. Do tego jeszcze dochodzi obawa, że napisany program zajmie za mało pamięci i urządzenie będzie zbyt tanie, bo zamiast uC z 64 KiB można będzie w nim użyć wersji z 16 KiB. A tak od razu program wydłuża się czterokrotnie i wygląda poważnie.

    0
  • #4 30 Gru 2014 22:53
    Tojmak
    Poziom 7  

    Ok, czyli rozumiem, że przypisuje najpierw do portu A -> 0xFFF00000 (czyli bity
    1111 1111 1111 0000 0000 0000 0000 0000), a później dodaje do nich 0x00033333 (czyli 0000 0000 0000 0011 0011 0011 0011 0011), więc w sumie można by to zapisać jako -> FFF33333 (1111 1111 1111 0011 0011 0011 0011 0011). No i rozumiem, że zapisujemy to w takiej postaci gdy nie jesteśmy pewni w tym przypadku, jakie wartości chcemy przypisać tym ostatnim pięciu czwórką bitów?
    Sorry, że tak rozpisałem na binarny ale wolałem mieć już to czarno na białym.

    0
  • #5 31 Gru 2014 00:24
    BlueDraco
    Specjalista - Mikrokontrolery

    Jeśli nie jesteśmy pewni, co chcemy zapisać, to najlepiej jest nie zapisywać nic i nie pisać żadnych programów.

    A kod, o który pytasz, najpierw zeruje mniej znaczące bity rejestru nie ruszając bardziej znaczących, potem ustawia 20 najmniej znaczących bitów na 0x33333, również nie ruszając pozostałych, wskutek czego na 12 najbardziej znaczących bitach jest to, co było, a na 20 mniej znaczących - to co zapisał programista, który nie chce wiedzieć, co było i jest na tych 12-tu.

    0
  • #6 31 Gru 2014 10:09
    M. S.
    Poziom 34  

    Cytat:
    programista, który nie chce wiedzieć, co było i jest na tych 12-tu


    Z całym szacunkiem nie można piętnować tych, którzy nie chcą wiedzieć co było na pozostałej części bitów. Czasem wystarczy wiedzieć, że były tam właściwe dane. Poszczególne bity rejestrów - w szczególności portów - często są zmieniane w różnych miejscach programu i dopóki dzieje się to prawidłowo to nie musimy wnikać co tam jest.

    1
  • #7 31 Gru 2014 11:00
    Tojmak
    Poziom 7  

    Dobra, chyba rozumiem, posiedzę nad tym jeszcze i może rozwiąże mój problem :). Nie bardzo jeszcze wiem dlaczego i w jaki sposób określił, że jakieś dane są mniej bądź bardziej znaczące, ale wnioskuje, że przeoczyłem to w nocie katalogowej urządzenia, którego dotyczy napisana biblioteka? Wielkie dzięki po raz kolejny za pomoc. Każda informacja udzieliła mi przydatnych informacji.

    Pozdrawiam

    0
  • #8 31 Gru 2014 11:11
    BlueDraco
    Specjalista - Mikrokontrolery

    Nie "dane mniej znaczące", a bity (naj)bardziej lub (naj)mniej znaczące, czyli po angielsku "most significant"/"least significant", a w niepoprawnym i niechlujnym polskim slangu pseudoinformatycznym "najstarsze" i "najmłodsze". :)

    0
  • #9 31 Gru 2014 11:51
    Tojmak
    Poziom 7  

    Hmm... dobra, usiadłem jeszcze raz i w sumie to nie widzę (albo nie rozumiem jednak) sensu zapisywania tego działania w dwóch linijkach. Bity te są wysyłane do CRL, czy nie jest czasami w takim razie tak, że konfigurują piny portu A (w tym przypadku) na input/output no i tam odpowiednio floating, PP itp.? Nie prościej po prostu od razu napisać jak chce się mieć ustawiony dany pin?

    0
  • #10 31 Gru 2014 14:19
    szczywronek
    Poziom 27  

    Tojmak napisał:
    Nie prościej po prostu od razu napisać jak chce się mieć ustawiony dany pin?
    Dobrze myślisz - prościej. Ale wykonując operację:
    Kod: c
    Zaloguj się, aby zobaczyć kod
    musisz wiedzieć co chcesz mieć w całym rejestrze - jeżeli dysponujesz taką wiedzą to nie ma problemu.

    Ale jeżeli np.: piszesz funkcję konfigurującą UART i chcesz w niej skonfigurować wyprowadzenia mikrokontrolera związane z sygnałami TxD i RxD, to nie powinna obchodzić Cię konfiguracja pozostałych wyprowadzeń portu. Twoja funkcja musi sobie ustawić TxD i RxD wedle potrzeb, ale nie wolno jej zmieniać konfiguracji pozostałych pinów, które mogły już wcześniej zostać ustawione przez program. Użycie iloczynu i sumy logicznej pozwala kasować i ustawiać pojedyncze bity rejestru bez zmiany stanu pozostałych.

    0
  • #11 31 Gru 2014 15:01
    kemot55
    Poziom 30  

    Kolega patrzy na to tak, jakby porty ustawiało się raz i już. A to nie do końca tak musi być. Np. zmieniasz hardware i trzeba zamienić 2 linie portów - musisz praktycznie cały port przeliczyć jeszcze raz. Poza tym wartość rejestru po resecie to 0x44444444. Czyli to napisałeś na wstępie jest chyba najbardziej uniwersalnym sposobem zmiany wartości określonej części rejestru. Zobacz jak wygląda procedura konfiguracji portów kolegi FredieChopin'a i na marginesie możesz pomyśleć dlaczego (i po co) ją tak zrobił (chodzi mi o eliminowanie ustawiania rejestrów portowych metodą wpisywania jakiś magicznych wartości, które nic nie znaczą (dla programisty) już po kilku dniach (no, ale faktycznie program jest wtedy większy...)).

    0
  • #12 31 Gru 2014 18:40
    BlueDraco
    Specjalista - Mikrokontrolery

    Dodajmy jeszcze, że zapis typu:

    Kod: c
    Zaloguj się, aby zobaczyć kod
    Jest wysoce nieprofesjonalny, bo byle jaki programista może zobaczyć tę instrukcję w programie i będzie wiedział wszystko o każdej linii portu. Jeśli natomiast do konfiguracji portu użyjesz po parze instrukcji iloczynu i sumy logicznej (dla każdej linii portu oddzielnie), a konfiguracje poszczególnych linii rozsiejesz zgrabnie po pięciu modułach programu i dziesięciu procedurach, to za Chiny nikt, włączając w to Autora w 2 miesiące po napisaniu programu, nie będzie wiedział, jak jest skonfigurowany port - i o to w końcu chodzi w profesjonalnym programowaniu.
    ;)

    0
  • #13 31 Gru 2014 19:41
    nsvinc
    Poziom 35  

    BlueDraco napisał:
    Jest wysoce nieprofesjonalny, bo byle jaki programista może zobaczyć tę instrukcję w programie i będzie wiedział wszystko o każdej linii portu. Jeśli natomiast do konfiguracji portu użyjesz po parze instrukcji iloczynu i sumy logicznej (dla każdej linii portu oddzielnie), a konfiguracje poszczególnych linii rozsiejesz zgrabnie po pięciu modułach programu [...]

    Wyżywasz się na biednym początkującym koledze który miał tylko malutki i najmniej znaczący :D problemik ze zrozumieniem najbardziej znaczących podstawowych operacji logicznych ;]

    Więc przytoczę inny miły dla oka kwiatek (którego osobiście jestem autorem - bywam wredny ;D )
    Kod: C
    Zaloguj się, aby zobaczyć kod

    0
  • #14 02 Sty 2015 13:00
    Tojmak
    Poziom 7  

    Nsvinc, szczerze... to średnio rozumiem co napisałeś ;d (wybaczcie moją głupotę ;p). Ogólnie wydawało mi się, że w miarę już rozumiem co się dzieje. Jednak wychodzi na to, że może jednak nie dokońca, a mianowicie...
    Mam dokładnie taki kawałek kodu:

    Kod: cpp
    Zaloguj się, aby zobaczyć kod

    Pomijając ostatnich 5 linijek, analizując całą resztę wydawało mi się, że powinienem uzyskać 3 porty skonfigurowane na output open-drain, oraz 5 portów na output push-pull. Pracuję w keil u'vision. Tam po debbugowaniu w zakładce peripherals sprawdzam sobie stan pinów po skompilowaniu programu. Program pokazuje mi, że pierwszych 7 pinów jest skonfigurowanych na output push - pull, kolejny pin na analog input, kolejny na output open-drain i kolejnych 6 pinów na analog input. nie spodziewałem się takiego rezultatu, mógł by ktoś objaśnić czy coś źle zrozumiałem z tego kawałka kodu, czy jednak coś źle zrozumiałem z tych operacjii przypisywania bitów, czy jednak z tego kodu który wysłałem wynika to co myślałem, a co za tym idzie, coś się dzieje dziwnego w części kodu, której nie zamieściłem? Poza tym, nie rozumiem, dlaczego skonfigurowały się wszystkie 16 pinów, podczas gdy wydawało mi się, że konfiguruje jedynie pierwszych 8, a reszta zostanie w stanie początkowym - floating input. Ogólnie dziękuję wszystkim za zainteresowanie i wybaczcie, że sprawdzam tak mocno waszą cierpliwość :). Jestem świadom, że to o co pytam i z czym mam problemy to podstawy, podstaw, ale jednak mam problem i wytrwale proszę o wyprowadzenie z "dołka".

    Dzięki wszystkim i pozdrawiam ;d

    0
  • #15 02 Sty 2015 22:02
    BlueDraco
    Specjalista - Mikrokontrolery

    Pierwszy problem polega na tym, że nie napisałeś, o jaki mikrokontroler chodzi.

    0
  • #16 02 Sty 2015 22:10
    Tojmak
    Poziom 7  

    Wybacz ;d, Cortex m3, konkretnie pracuje na modelu plytki zl30arm, stm32f103cb.

    0
  • #17 03 Sty 2015 11:48
    kemot55
    Poziom 30  

    Tu masz "fajny" zapis

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Po kolei:
    po resecie CRH=0x4444 4444
    po AND: 0x4444 4444 & 0x0000 00F0 = 0x0000 0040
    po OR: 0x0000 0040 | 0x0000 0030 = 0x0000 0070
    Czyli: General purpose output Open-drain + Output mode, max speed 50 MHz.
    (dla niezerowej tetrady, reszta analogowa)
    Może daj sobie spokój z "kombinowaniem" i użyj przykładowego projektu.

    0
  • #18 03 Sty 2015 12:33
    nsvinc
    Poziom 35  

    Swoją drogą, po co te cyrki z operacjami bitowymi na tych SFRach? Przeciez piny konfiguruje sie przewaznie tylko raz, na init. Moze wystarczy wpisać bezposrednio liczbę do rejestru?...
    A jeśli nie wystarczy, to wypada zrobić sobie jeden lub wiele #define, np.

    Kod: C
    Zaloguj się, aby zobaczyć kod


    i w kodzie, wszędzie tu, gdzie przekonfigurowuje się pin, uzywać
    Kod: C
    Zaloguj się, aby zobaczyć kod


    O bitbandingu nie wspomnę; zeby niezaleznie przekonfigurować pin, wystarczy prosty zapis (jeden lub kilka)...

    0
  • #19 03 Sty 2015 16:02
    Tojmak
    Poziom 7  

    Ok, już zrozumiałem wszystko chyba co się tam dzieje. Bez Waszej pomocy jeszcze by trochę czasu minęło zanim bym to ogarnął więc na prawdę bardzo dziękuję. Nie rozwiązało to mojego problemu głównego, ale pośrednio bardzo pomogło. Dzięki raz jeszcze i pozdrawiam wszystkich. Temat do zamknięcia

    0