Kanał - ATNEL tech-forum
Wszystkie działy
Najnowsze wątki



Teraz jest 12 lut 2025, o 19:38


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 14 ] 
Autor Wiadomość
PostNapisane: 13 maja 2017, o 21:17 
Offline
Użytkownik

Dołączył(a): 01 sty 2015
Posty: 31
Pomógł: 0

Bardzo proszę o pomoc w zrozumieniu poniższego kodu. Czytam o tych dziwnych nazwach jak: AHB1ENR, MODER ale dalej za wiele z tego nie rozumiem.

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Rozumiem, że przesunięcie bitowe służy tu do tego, żeby dać jakiś stan na porcie. Np pierwsza linijka ustaw mi stan wysoki na porcie nr 0 i 6 ? Co oznacz ta negacja przed przesunięciem bitowym.

Dalej tego: GPIOG->MODER |= (1<<(2*13)) | (1<<(2*14)); to za nic już nie rozumiem. Co za mnożenie skąd to i dlaczego ...

Jak czytać przykładową linijkę (jedną z powyższych) ?

Będę wdzięczny za pomoc bo grzebie w internecie ale ciężko cokolwiek pojąć w tej dziwnej architekturze ;(



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 14 maja 2017, o 08:59 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 08 lut 2017
Posty: 48
Pomógł: 4

Żeby nie podsyłać gotowców, prześlę Ci linka, który WSZYSTKO Ci wytłumaczy(jeśli znasz angielski).
Zerknąłem na niego i dobrze jest tam to opisane.

http://hertaville.com/stm32f0-gpio-tutorial-part-1.html


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 14 maja 2017, o 15:27 
Offline
Użytkownik

Dołączył(a): 01 sty 2015
Posty: 31
Pomógł: 0

Czyli jeżeli np. Chcę podpiąć przycisk do takiego mikrokontrolera, to potrzebuje ustawic sobie taki port jako wejscie.
Np. wybieram sobie ze przycisk podepne do portu G. Zatem żeby ustawic go jako wejscie musze zrobic cos takiego:

zgodnie z dokumentacja zeby ustawić na wejscie to dwa bity w pinie powinny być ustawione na 0. Powiedzmy ze wybrałem pin 13.

Tu dalej nie rozumiem tego zapisu jak to się ustawia. Ok 13 to mój numer pinu, ale ta 1,2 to co to numer bitu ? I co oznacza ta negacja w tym zapisie.
GPIOG->MODER |= (1<<(2*13))

Za cholere nie mam pojęcia po co mi te pozostałe piny w MODER. Bo np. MODER ma 16 pinów. Na co mi to jak ja jak coś ustawiam to tylko jeden pin potrzebuje.

Rozumiem, że nie ma znaczenia który wybiorę.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 14 maja 2017, o 16:31 
Offline
Użytkownik

Dołączył(a): 01 sty 2015
Posty: 31
Pomógł: 0

Jasne wszystko rozumiem z tego co jest tam napisane. Tylko mam co do tego pytania które zadałem w poprzednim poście i na które będę wdzięczny jak ktoś mi odpowie ;)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 14 maja 2017, o 21:51 
Offline
Użytkownik

Dołączył(a): 01 sty 2015
Posty: 31
Pomógł: 0

Ad 1. Nie wiem czy się zgodzę ;c

uzasadnienie: jak chcę ustawić pin jako wyście to zgodnie z dokumentacja pierwszy bit w tym pinie powinien mieć wartość 1 a drugi 0.

To co teraz napiszę będzie żałosne ale trudno. Dlaczego 0x00000001 ? Co oznacza taki zapis.
0x00000001 - to 8 bitowa liczba, czyli może przyjmować wartości 2^8 zgadza się ? a w tym przypadku to po prostu 1.
Dlaczego przed liczbą daje się 0x + liczba ?

W jakim systemie liczbowym jest to zapisywane w dziesiętnym tak ? bo np. jak sobie debuguje w IDE uVision to w rejestry też wyglądają w ten sposób, czyli np. R0 0x00000008 -> po wpisaniu 0x0008. Czy to oznacza, że rejestry są 8smio bitowe ?

Ad 2. Też nie wiem czemu 0x00000004, czy to ma coś wspólnego z tym że na drugi pin to 2^2 .. ?

Ad 3. Jeżeli 0x001 przesunę o 2 to będę miał 0x100. Czyli na trzecim bicie będę miał jedynkę, a trzeci bit to jest pierwszy bit drugiego pinu i ustawiam mu jedynkę. Tak samo jak 1 << 0 to po prostu ustawiam jedynkę na pierwszym bicie, czyli bity w pierwszym pinie wyglądają tak 01.

Nie rozumiem do końca punktu 1,2 to i dalsze mi się posypały.

Bardzo Cię proszę, czy mógłbyś zejść o poziom niżej i mi to wytłumaczyć.
I proszę przeczytaj ten mój bełkot i odnieś się do niego, bardzo chciałbym to zrozumieć a nie mam tyle czasu niestety żeby zagłębiać się w podstawy ;c



Ostatnio edytowano 15 maja 2017, o 17:32 przez RideorDie, łącznie edytowano 1 raz

Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 14 maja 2017, o 23:06 
Offline
Użytkownik

Dołączył(a): 01 sty 2015
Posty: 31
Pomógł: 0

Jak byś znalazł czas żeby odpowiedzieć na resztę moich wątpliwości/pytań z postu powyżej to byłbym Ci bardzo wdzięczny.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 15 maja 2017, o 17:31 
Offline
Użytkownik

Dołączył(a): 01 sty 2015
Posty: 31
Pomógł: 0

Wydaje mi się że nie pokręciłem, bo pisząc
RideorDie napisał(a):
jak chcę ustawić pin jako wyście to zgodnie z dokumentacja pierwszy bit w tym pinie powinien mieć wartość 1 a drugi 0.


miałem na myśli pierwszy bit od prawej czyli byłoby to 01, tak jak napisałeś ;)

Także prosiłbym Cię o delikatne dokładniejsze wyjaśnienie tego, tzn o odpowiedź na moje pytania z postu o 21:51. Dzięki!



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 15 maja 2017, o 18:28 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 12 sie 2013
Posty: 230
Lokalizacja: Zabrze
Pomógł: 17

Widzę, że masz duże braki w podstawach arytmetyki i logiki bitowej i niestety systemach liczb. Musisz sobie to dobrze poznać - zanim weźmiesz się za coś więcej z mikrokontrolerów. To po pierwsze.
A teraz co do linijki: GPIOG->MODER |= (1<<(2*13)) | (1<<(2*14));
Mam nadzieję, że się nie rąbnę 8-) Należy rozumieć to tak:
Weź aktualną zawartość (wartość) rejestru MODER dla portu G. Następnie zrób na tym operację logicznego OR [czyli zeruj te bity (na odpowiadających sobie pozycjach), gdzie są jednocześnie zera, a ustaw w pozostałych przypadkach warość 1] z wyliczonym wyrażeniem (1<<(2*13)) | (1<<(2*14)).
To wyrażenie zaś liczymy następująco:
a) najpierw mnożymy 2*13 oraz 2*14 i otrzymujemy 26 i 28 <-są to prawe bity z dwubitowych wartości odpowiedzialnych za konfigurację wejść/wyjść 13 i 14 portu G (lewe bity domyślnie po resecie mikrokontrolera są zerami, więc ich nie trzeba ruszać - stąd wystarcza zapis 2*13 i 2*14). Mamy więc zapis (1<<26) | (1<<28)
b) teraz przesuwamy o 26 pozycji 1 i robimy logiczne OR z liczbą z 1 przesuniętą o 28 pozycji. Binarnie wygląda to tak:
(0000 0100 0000 0000 0000 0000 0000 0000)b OR (0001 0000 0000 0000 0000 0000 0000 0000)b
i otrzymujemy w wyniku binarnie: (0001 0100 0000 0000 0000 0000 0000 0000)b = 335544320 dziesiętnie = 0x14000000 szesnastkowo
c) i teraz wartość rejestru MODER traktujemy logicznym OR z tą liczbą. W Wyniku binarnie będziemy mieli zatem: (xx01 01xx xxxx xxxx xxxx xxxx xxxxx xxxxx)b (x oznacza poprzedni stan bitu, 0 to wartość jaka będzie, gdy rejestr miał stan po resecie, czyli na tych pozycjach były zera - gdyby były jedynki, to będzie tam 1, ale wtedy nie będzie to ustawienie linii portu na wyjście).


Autor postu otrzymał pochwałę

_________________
40-32:2=4!



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 15 maja 2017, o 20:26 
Offline
Użytkownik

Dołączył(a): 01 sty 2015
Posty: 31
Pomógł: 0

PJS napisał(a):
Weź aktualną zawartość (wartość) rejestru MODER dla portu G. Następnie zrób na tym operację logicznego OR [czyli zeruj te bity (na odpowiadających sobie pozycjach), gdzie są jednocześnie zera, a ustaw w pozostałych przypadkach warość 1] z wyliczonym wyrażeniem (1<<(2*13)) | (1<<(2*14))


Dobra do tego mam pytanie.

Mamy coś takiego
GPIOG->MODER |= (1<<(2*13)) | (1<<(2*14));

Po MODER mamy pierwsze or [ |= ] i pomiędzy (1<<(2*13)) i (1<<(2*14)) mamy drugie or [ | ]. Czyli pomimo tego że jest 2x or to wykonuje się tylko jedno or pomiędzy bitami z wyrażenia (1<<(2*13)) i bitami z wyrażenia (1<<(2*14)) -> i zapis wyniku do GPIOG -> MODER tak ?

Jeżeli tak, to czemu tego tak nie można zapisać GPIOG->MODER = (1<<(2*13)) | (1<<(2*14)); chodzi o składnie w C ?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 15 maja 2017, o 20:38 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 01 lis 2015
Posty: 1448
Lokalizacja: okolice Warszawa
Pomógł: 149

Witam,
Dlatego że przy takim zapisie wymusimy zera na pozostałych bitach.
A tak wpiszemy jedynki tylko w te wpisane. :)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 15 maja 2017, o 21:35 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 12 sie 2013
Posty: 230
Lokalizacja: Zabrze
Pomógł: 17

RideorDie napisał(a):
GPIOG->MODER |= (1<<(2*13)) | (1<<(2*14));

zapis ten jest równoważny z
GPIOG->MODER = (GPIOG->MODER) | ((1<<(2*13)) | (1<<(2*14)));
To taki skrótowy zapis w C.
RideorDie napisał(a):
Po MODER mamy pierwsze or [ |= ] i pomiędzy (1<<(2*13)) i (1<<(2*14)) mamy drugie or [ | ]. Czyli pomimo tego że jest 2x or to wykonuje się tylko jedno or pomiędzy bitami z wyrażenia (1<<(2*13)) i bitami z wyrażenia (1<<(2*14)) -> i zapis wyniku do GPIOG -> MODER tak ?

Jeżeli tak, to czemu tego tak nie można zapisać GPIOG->MODER = (1<<(2*13)) | (1<<(2*14)); chodzi o składnie w C ?

Nie wykonuje się jedno OR. Przecież pisałem, ale może niezbyt jasno: najpierw jest wyliczana prawa strona po |=, czyli mnożenia, przesunięcia i OR między tymi wartościami. Potem Wartość z MODER jest OR-owana z tym co wyliczone zostało po prawej stronie. I dopiero ten wynik jest zapisywany w MODER. Skrótowy zapis a|=b jest tym samym co a= a|b. Chodzi o to, co już przedpiśca podał, że gdyby zamiast |= było = to wtedy zawartość całego MODER została by zastąpiona wynikiem wyrażenia po prawej stronie, a nam chodzi tylko, aby ustawić bity 26 i 28 bez zmiany pozostałych bitów. Przykładowo, gdyby MODER był 4bitowy o wartości 0101b, i chcielibyśmy ustawić bit jeden (liczymy od zera od prawej, czyli bit drugi od prawej) na wartość 1 to zrobilibyśmy tak MODER |= (1<<1) i wtedy mamy jako wynik zapisany w MODER wartość 0111b. Natomiast gdybyśmy zrobili tak MODER = (1<<1) to wtedy w MODER byłoby 0010b. Jest różnica?
I poważnie poczytaj o operacjach bitowych. To podstawa!!


Autor postu otrzymał pochwałę

_________________
40-32:2=4!



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 15 maja 2017, o 21:46 
Offline
Użytkownik

Dołączył(a): 01 sty 2015
Posty: 31
Pomógł: 0

Daro69 napisał(a):
Dlatego że przy takim zapisie wymusimy zera na pozostałych bitach.


Czyli jeżeli wcześniej ustawiłem sobie na pinie 12 w rejestrze MODER portu G wyjście i teraz ustawiam sobie na pinie 13 wyjście w MODER rejestru G to to jak przy drugiej operacji nie zrobię "or" to ustawię na bity w pinie 12 zera tak ? mimo tego że jeden bit miał wartość 1 ?

I czemu jest tyle pinów rejestrze MODER ? po co mi to ?
Jedyne co przychodz mi do głowy to to że dzięki temu mogę np ustawić żeby dany port np. G zachowywał się jako wejście albo jako wyjście jednocześnie mhh ?

edit: napisałem ten post nie widząc poprzedniego komentarza, który chyba wyczerpał temat or ;D



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 15 maja 2017, o 22:14 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 12 sie 2013
Posty: 230
Lokalizacja: Zabrze
Pomógł: 17

RideorDie napisał(a):
I czemu jest tyle pinów rejestrze MODER ? po co mi to ?

Ponieważ w tym mikrokontrolerze możesz każdą linię (pin, nóżkę) portu G (a także innych portów) ustawić indywidualnie, tzn. pin0 portu może być wejściem, pin1 wyjściem, pin2 mieć funkcję alternatywną (np. wejście analogowe) itd. Możesz prawie dowolnie wszystko ustawić. Dla twojego przykładu port G ma 16 pinów, każdy ma osobne ustawiania wejście/wyjście/alternatywna funkcja, co daje trzy kombinacje, czyli minimalnie potrzeba 2 bitów, by to zakodować, a to dla 16 pinów daje 16*2=32 bity. I tak jest dla każdego portu. Mało tego są też inne rejestry związane z portami. Każdy peryferial (timery, przetworniki itd.) też mają swoje rejestry.


Autor postu otrzymał pochwałę

_________________
40-32:2=4!



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 16 maja 2017, o 06:55 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 01 lis 2015
Posty: 1448
Lokalizacja: okolice Warszawa
Pomógł: 149

RideorDie napisał(a):
Czyli jeżeli wcześniej ustawiłem sobie na pinie 12 w rejestrze MODER portu G wyjście i teraz ustawiam sobie na pinie 13 wyjście w MODER rejestru G to to jak przy drugiej operacji nie zrobię "or" to ustawię na bity w pinie 12 zera tak ? mimo tego że jeden bit miał wartość 1 ?

Dokładnie tak.
Jezeli spojrzysz na zapis binarny.
Przy zapisie "="
Lewa strona wyrażenia przyjmie wartość z prawie,
Przy zapisie "|="
Do lewej strony zostaną dopisane jedynki znajdujące sie z prawej.
Oczywiście każdy bit w miejsce swojej wagi (liczysz od prawej. 1,2,4,8,16...)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
Wyświetl posty nie starsze niż:  Sortuj wg  
Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 14 ] 

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 1 gość


Nie możesz rozpoczynać nowych wątków
Nie możesz odpowiadać w wątkach
Nie możesz edytować swoich postów
Nie możesz usuwać swoich postów
Nie możesz dodawać załączników

Szukaj:
Skocz do:  
cron
Sitemap
Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
phpBB SEO