ATNEL tech-forum https://forum.atnel.pl/ |
|
Przykład z książki: 5.5 LCD https://forum.atnel.pl/topic105.html |
Strona 1 z 1 |
Autor: | DidekxD [ 23 gru 2011, o 17:39 ] |
Tytuł: | Przykład z książki: 5.5 LCD |
Witam! Mam problem ze zrozumieniem kodu preprocesora z przykładu z książki pana Mirka. Nie wiem może już jestem zbyt przemęczony i dla tego nie rozumiem o co kaman ^^ Do rzeczy. rozdział "5.5 Wyświetlacz LCD (HD44780)" Kod: // Makra upraszczające dostęp do portów // *** PORT #define PORT(x) SPORT(x) #define SPORT(x) (PORT##x) // *** PIN #define PIN(x) SPIN(x) #define SPIN(x) (PIN##x) // *** DDR #define DDR(x) SDDR(x) #define SDDR(x) (DDR##x) Jaki tego jest wynik ? W sensie co preprocesor podstawia zamiast tego wyżej ? To pewnie błahe ale całkiem pomieszało mi w głowie. Skąd to 'x' ? Jaka zawartość słowa 'PORT' ? Z góry dziękuje i pozdrawiam |
Autor: | mirekk36 [ 23 gru 2011, o 17:50 ] |
Tytuł: | Re: Przykład z książki: 5.5 LCD |
No rzeczywiście, przede wszystkim to nie jest błahe i banalne więc rozumiem zawrót głowy. Bo i ja sam za każdym razem jak mam przypomnieć sobie jak to działa to muszę od początku świata sobie wszystko przypominać. No może poza samym faktem narodzin jak to działa? Kod: #define PORT(x) SPORT(x) #define SPORT(x) (PORT##x) Zakładamy, że w kodzie programu napisaliśmy coś takiego: Kod: #define LED_PORT D PORT( LED_PORT ) |= (1<<PD2); załóżmy że chcieliśmy wystawić stan wysoki na PD2 zatem pierwsza definicja: Kod: #define PORT(x) SPORT(x) spowoduje, że preprocesor przygotuje wyrażenie do dalszego tłumaczenia, które będzie wyglądało tak: SPORT( D ) zgadza się ? No bo parametrem x było #define LED_PORT D następnie preprocesor weźmie się dalej do roboty i widząc kolejną makrodefinicję Kod: #define SPORT(x) (PORT##x) podstawi w miejsce kodu słowo PORTD czyli wyjdzie cała linijka kodu tak, tzn zamiast: Kod: PORT( LED_PORT ) |= (1<<PD2); będzie Kod: PORTD |= (1<<PD2); Zgadza się ? Oczywiście ktoś mógłby zadać pytanie - ale zaraz hola hola, to po co takie podwójne makro skoro można byłoby niby prościej to napisać o tak np: Kod: #define PORT(x) (PORT##x) no nie ? Ale niestety - jeśli byś tak zrobił to w miejscu kodu, preprocesor rozwinąłby to nieszczęśliwie tak: PORTLED_PORT |= (1<<PD2); teraz jaśniej troszkę ? |
Autor: | DidekxD [ 23 gru 2011, o 18:04 ] |
Tytuł: | Re: Przykład z książki: 5.5 LCD |
I nastała jasność Świetnie wytłumaczone, prosto i jak dla laika. Dziękuje bardzo Teraz mogę ruszyć dalej ku nowym horyzontom ^^' |
Autor: | pisiorek [ 2 lip 2013, o 06:46 ] |
Tytuł: | Re: Przykład z książki: 5.5 LCD |
Witam, ja jeszcze mam jednak wątpliwości. Rozumiem w takim razie, że fragment kodu: Kod: #define PORT(x) SPORT(x) powoduje podstawienie do fragmentu:Kod: ...PORT(x)... jako parametru całej wcześniejszej definicji: Kod: #define LED_PORT D w konsekwencji wycięcie z niej tylko końcowego oznaczenia portu, czyli w tym przypadku litery "D", a fragment: Kod: ...SPORT(x)... zwraca już SPORT(D), co jest dalej przekazywane do dalszej obróbki we fragmencie Kod: #define SPORT(x) (PORT##x) a tam zostaje "wyłuskane" samo literowe oznaczenie portu "D" i połączone operatorem ## z np. portem DDRX w wyniku czego uzyskujemy wyrażenie DDR(D). Czy dobrze to rozumiem ? |
Autor: | mirekk36 [ 2 lip 2013, o 07:40 ] |
Tytuł: | Re: Przykład z książki: 5.5 LCD |
Dobrze rozumiesz tylko w tym miejscu mała nieścisłość: pisiorek napisał(a): w konsekwencji wycięcie z niej tylko końcowego oznaczenia portu, czyli w tym przypadku litery "D", a fragment: nie nastąpi żadne wycięcie - tylko podstawienie argumentu definicji preprocesora czyli tej literki D |
Autor: | pisiorek [ 2 lip 2013, o 08:59 ] |
Tytuł: | Re: Przykład z książki: 5.5 LCD |
Dziękuję za szybką odpowiedź, jeszcze ostatnia wątpliwość. Odnośnie fragmentu z pierwszego Twojego postu wyjaśniającego problem, oraz oTwojej odpowiedzi na mój poprzedni post: Cytuj: Oczywiście ktoś mógłby zadać pytanie - ale zaraz hola hola, to po co takie podwójne makro skoro można byłoby niby prościej to napisać o tak np: a w odpowoiedzi na mój post :Kod: #define PORT(x) (PORT##x) no nie ? Ale niestety - jeśli byś tak zrobił to w miejscu kodu, preprocesor rozwinąłby to nieszczęśliwie tak: PORTLED_PORT |= (1<<PD2); Cytuj: Dobrze rozumiesz tylko w tym miejscu mała nieścisłość: Cytuj: pisiorek napisał(a): w konsekwencji wycięcie z niej tylko końcowego oznaczenia portu, czyli w tym przypadku litery "D", a fragment: nie nastąpi żadne wycięcie - tylko podstawienie argumentu definicji preprocesora czyli tej literki D Skoro fragment kodu: Kod: (...)PORT(x)(...) radzi sobie z wyłuskaniem samego parametru "D", bo w SPORT(x) już zostaje SPORT(D), to teoretycznie zapis mógłby wyglądać tak: Kod: #define PORT(x) (PORT##x) dlaczego jednak nie można tego skrócić do takiej formy ? Czy to jest niedoskonałość preprocesora, czy jest jakiś inny powód ?
|
Autor: | mirekk36 [ 2 lip 2013, o 09:17 ] |
Tytuł: | Re: Przykład z książki: 5.5 LCD |
Cytuj: dlaczego jednak nie można tego skrócić do takiej formy ? Czy to jest niedoskonałość preprocesora, czy jest jakiś inny powód ? w książce niebieskiej starałem się to opisać, tu na forum też niejednokrotnie - i zawsze też proszę - nie dopatrywać się niedoskonałości w kompilatorach itp ... gdy się samemu jeszcze nie do końca coś rozumie bo to prowadzi ZAWSZE na manowce ale ok powtórzę to po raz kolejny nie można od razu zrobić tak jak piszesz ponieważ po takiej operacji: język c Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod. otrzymałbyś w wyniku sklejenia nazwę Cytuj: PORTLED_PORT zamiast oczekiwanego PORTD, rozumiesz - sklejenie działa od razu na przekazany argument którym jest LED_PORT, preprocesor nie ma możliwości rozwinięcia nazwy LED_PORT do literki D, i dlatego potrzebny jest kolejny krok żeby argument LED_PORT został zamieniony przez samą literkę D, która dopiero zostanie doklejona teraz będzie jaśniej ? |
Autor: | pisiorek [ 2 lip 2013, o 09:40 ] |
Tytuł: | Re: Przykład z książki: 5.5 LCD |
OK, teraz wszystko jasne. Dziękuję i pozdrawiam |
Autor: | rysiekm55 [ 9 lis 2013, o 17:06 ] |
Tytuł: | Re: Przykład z książki: 5.5 LCD |
Dziś po długiej analizie wreszcie zrozumiałem jak działają te makra. Jak w książce napisane skracają definicji portów w pliku nagłówkowym, zamiast pełnej nazwy wstawia się samą literę; A, B, C, D itd....A potem makra uzupełniają do pełnej postaci. |
Autor: | rafmodel [ 4 kwi 2014, o 13:41 ] |
Tytuł: | Re: Przykład z książki: 5.5 LCD |
Proszę o wybaczenie, ale nie rozumiem kompletnie tego makra ułatwiającego dostęp do portów.Siedzę nad LCD i w zasadzię działanie rozumiem (noty+bluebook+przykłady) i jakoś ogólnie to łapie. Ale teraz się wgryzam dokładnie linijka po linijka. Mamy takie makro język c Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod. to jest jasne nazwa makra SET_RS spowoduje ustawienie 1 na porcie LCD_RSPORT na miejscu LCD_RS bitu. wcześniej zdefiniowaliśmy w pliku nagłówkowym zarówno port A jak i który bit 0. i jest ok Ale przy tym makrze się rozkładam: język c Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod. definicję rozumiem ale skąd wiemy jakie jest x?? gdzie to jest przypisane? Oczywiście mam na myśli program wraz z biblioteką do LCD z płyty załączonej do BlueBook'a. Dziękuje za pomoc i pozdrawiam |
Autor: | majster [ 4 kwi 2014, o 13:59 ] |
Tytuł: | Re: Przykład z książki: 5.5 LCD |
bo e programie piszesz np PORT 6 i ten x jest zamieniany na 6 nie widze calego kodu i pisze z pamieci. ale zobacz na definicje portow lcd w pliku .h i bedzie wszystko jasne. Wysłane z telefonu |
Autor: | karolek [ 4 kwi 2014, o 14:07 ] |
Tytuł: | Re: Przykład z książki: 5.5 LCD |
wpisz do eclipsa napisz np PORT(C) i najedz myszka , jak sie pokaze "chmurka" to zjedz na nia myszka i strzaleczkami przesówaj w lewo lub w prawo bardzo ułatwia! |
Autor: | rafmodel [ 4 kwi 2014, o 14:42 ] |
Tytuł: | Re: Przykład z książki: 5.5 LCD |
Przepraszam, ale tak mam, jak czegoś nie mogę zrozumieć tzn, że się zaciąłem. Takie mamy definicje w .h. język c Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod. No dobra teraz już się zamotałem. Skoro w całym programie korzystamy z tych definicji czyli np LCD_D7PORT i LCD_D7. to po co nam te makra. Myślałem, że makra umożliwiają nam skrócenie czynności do minimum tak jak np w Visual Basic'u pod excela. , wiem, że załapie, Karolek a z tym wpisanie PORT(C) w eclipsie to nie za bardzo rozumiem, sorry |
Autor: | rezasurmar [ 4 kwi 2014, o 14:43 ] |
Tytuł: | Re: Przykład z książki: 5.5 LCD |
Po to właśnie by nie trzeba pisać całej nazwy portu tylko A, i numer Pinu. |
Autor: | rafmodel [ 4 kwi 2014, o 15:31 ] |
Tytuł: | Re: Przykład z książki: 5.5 LCD |
Karolku i wszystkim innym - już sobie poradziłem. Tylko jedno pytanie skąd kompilator wie, że raz za x ma podstawić literę a kiedy liczbę? Wynika to może z tego , że PORT i DDR to litery a PIN to liczby? Pozdrawiam i dziękuję za wyrozumiałość i pomoc |
Autor: | mirekk36 [ 4 kwi 2014, o 17:16 ] |
Tytuł: | Re: Przykład z książki: 5.5 LCD |
rafmodel napisał(a): Tylko jedno pytanie skąd kompilator wie, że raz za x ma podstawić literę a kiedy liczbę? Wynika to może z tego , że PORT i DDR to litery a PIN to liczby? jeszcze raz proszę przeczytaj uważnie to: post975.html#p975 i zobacz jak działają te makra |
Autor: | Arni [ 6 sie 2015, o 21:36 ] |
Tytuł: | Re: Przykład z książki: 5.5 LCD |
To ja muszę zadać pytanie. Proszę się trzymać. mirekk36 napisał(a): Oczywiście ktoś mógłby zadać pytanie - ale zaraz hola hola, to po co takie podwójne makro skoro można byłoby niby prościej to napisać o tak np: Kod: #define PORT(x) (PORT##x) no nie ? Ale niestety - jeśli byś tak zrobił to w miejscu kodu, preprocesor rozwinąłby to nieszczęśliwie tak: PORTLED_PORT |= (1<<PD2); teraz jaśniej troszkę ? Dlaczego on by tak to rozwinął? Przecież język c Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod. znaczy, że LED_PORT ma być podstawiane jako literka "D" w kodzie kompilowanego programu. Dlaczego kompilator przy sklejaniu bezpośrednio: język c Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod. chciałby pod 'x' podstawiać LED_PORT zamiast 'D'? LED_PORT znaczy przecież 'D' bo tak to wcześniej zdefiniowaliśmy, czy nie? Ja rozumiem, że to pytanie trochę o to dlaczego czerwone jest czerwone (co jak się okazuje nie jest takie jednoznaczne i oczywiste ale to temat na inną dyskusję ). Zastanawia mnie jednak jak preprocesor interpretuje 'parametry', które podajemy mu w nawiasach i dlaczego przy makrze dwupoziomowym podstawi 'D' zamiast LED_PORT, a przy jednopoziomowym stanie na LED_PORT. |
Autor: | mirekk36 [ 6 sie 2015, o 22:03 ] |
Tytuł: | Re: Przykład z książki: 5.5 LCD |
Arni napisał(a): chciałby pod 'x' podstawiać LED_PORT zamiast 'D'? LED_PORT znaczy przecież 'D' bo tak to wcześniej zdefiniowaliśmy, czy nie? Nie ... eeeeh jeszcze raz ... sprawdź sobie bo można to sprawdzić nawet bez kompilacji w eclipse i bez wgrywania do procka. Zrób taką definicję: język c Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod. a później zrób tak język c Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod. okaże się, że w związku z tym iż jest zdefiniowana STAŁA o nazwie MUCHA to ten fragment kodu będzie biały i da się skompilować - zgadza się a teraz zmień na górze definicję tak: język c Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod. zobaczysz że Eclipse zaznaczy na szaro to co znajduje się w warunku #ifdef - zgadza się ? zgadza no bo preprocesor nie widzi już nazwy MUCHA a teraz uważaj dokładnie, teraz zrób taką definicję na górze język c Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod. Jak myślisz - zanim to zrobisz - zadziała warunek czy nie ? heeee ... i tu cię mam - zobacz warunek zadziała jeśli tego nie wiedziałeś i nie rozumiesz to zapamiętaj sobie że DEFINICJA STAŁEJ PREPROCESORA liczy się tylko do pierwszej spacji - reszta jest pomijana - jeśli nie definiujemy WYRAŻENIA w tym miejscu ... a więc preprocesor widzi tylko stałą o nazwie MUCHA a nie MUCHA D - rozumiesz ? dlatego odpowiedziałem NIE na twoje powyższe pytanie teraz już to chyba zapamiętasz co ? |
Autor: | Arni [ 6 sie 2015, o 22:54 ] |
Tytuł: | Re: Przykład z książki: 5.5 LCD |
Hmmm... Nie o pamiętanie chodzi a o rozumienie i z tym mam cały czas problem. Skoro preprocesor ignoruje zapis po pierwszej spacji to po co jest tam to 'D'? Skąd on później wie, że do PORT ma dokleić D? język c Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod. Cały czas myślałem, że powyższy zapis mówi preprocesorowi, że LED_PORT znaczy 'D'... Ja wiem, że to działa, ale chcę wiedzieć jak. Jeśli zrozumiem, to nie będę musiał pamiętać |
Autor: | mirekk36 [ 6 sie 2015, o 23:08 ] |
Tytuł: | Re: Przykład z książki: 5.5 LCD |
po to jest to D żeby właśnie przekazać do drugiego makra jako argument, dopiero na poziomie drugiego makra - preprocesor podstawi sobie D Na pierwszym poziomie język c Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod. preprocesor zobaczy tylko nieszczęsny LED_PORT REASUMUJĄAC, gdy najpierw będzie tak: język c Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod. to do makra SPORT zostanie przekazana nazwa stałej LED_PORT język c Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod. a tutaj już sobie LED_PORT zamieni na D bo zobaczy, że stałej o nazwie LED_PORT przypisana jest wartość D |
Autor: | Arni [ 6 sie 2015, o 23:20 ] |
Tytuł: | Re: Przykład z książki: 5.5 LCD |
Czyli mogę rozwinąć to tak? język c Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod. Jeśli tak, to zaczynam to rozumieć. Jeśli nie, to stracę resztę włosów, która mi została na głowie. Może Pan polecić jakieś rzetelne źródło informacji (książka, artykuł) na temat działania preprocesora? |
Autor: | mirekk36 [ 6 sie 2015, o 23:21 ] |
Tytuł: | Re: Przykład z książki: 5.5 LCD |
Arni napisał(a): Jeśli tak No DOKŁADNIE tak ... dokładnie i nie inaczej - widzisz w końcu zaskoczyłeś |
Autor: | Parser [ 14 sty 2017, o 19:40 ] |
Tytuł: | Re: Przykład z książki: 5.5 LCD |
Głęboka cześć tym co czytają ... Właśnie przemęczam te makra upraszczające z BB-ka, strona 218-220. Opisuję przykład z książki. Lewą stronę rozumiem . ( Dla mnie te makra po prostu likwidują nawias przekształcając ciąg znaków PORT(X) w PORTX ) W inicjacji DDR (LCD_D7PORT) |= ( 1<<LCD_D7): Makra + definicja : #define LCD_D7PORT C powodują, że zapis : DDR (LCD_D7PORT) przechodzi w DDRC OK. Ale co ze stroną prawą tej inicjacji ? skoro mamy port C i była definicja : #define LCD_D7 5 to wychodzi mi |= (1<<5 ) a powinno być |= (1<<PC5) dlaczego 5 zamiast PC5 ? Chwała temu kto mi to wyjaśni, bo też nie daje mi to spokoju ... |
Autor: | Daro69 [ 14 sty 2017, o 21:12 ] |
Tytuł: | Re: Przykład z książki: 5.5 LCD |
witam, Sprawa prosta. PC5 to makro 5. (to jest to samo) ------------------------ [ Dodano po: 4 minutach ] Zauważ że wpisując PC5 zamiast PD5 lub odwrotnie, uzyskasz identyczne zachowanie programu. Będzie tylko mniej czytelny dla nas i Ciebie. PA5,PB5,PC5... to jest wartość 5. To samo dla PA0,PB0,PC0...to 0. |
Autor: | kicajek [ 14 sty 2017, o 21:26 ] |
Tytuł: | Re: Przykład z książki: 5.5 LCD |
Witam Daro69 napisał(a): Sprawa prosta. PC5 to makro 5. (to jest to samo) bo: iom8.h napisał(a): /* PORTC */ #define PC6 6 #define PC5 5 #define PC4 4 #define PC3 3 #define PC2 2 #define PC1 1 #define PC0 0 Pozdr. |
Autor: | Parser [ 14 sty 2017, o 21:46 ] |
Tytuł: | Re: Przykład z książki: 5.5 LCD |
Dzięki wielkie koledzy. Rozwinięcie iom8.h oświeciło mnie ! |
Autor: | boryshoroneskul [ 4 lut 2018, o 12:36 ] |
Tytuł: | Re: Przykład z książki: 5.5 LCD |
Przepraszam, że poruszam może przebrzmiały temat. Takie coś znalazłem, może to komuś coś rozjaśni. __CONCAT to jest makro które przyjmuje nie tylko tokeny jako argumenty, a tak wydaje mi się, mają makra bezpośrednio używające ## (Tak?) Jestem początkujący, z góry przepraszam za błędy. |
Autor: | 11jacekj [ 18 lut 2018, o 21:11 ] |
Tytuł: | Re: Przykład z książki: 5.5 LCD |
Zainteresowałem się dwustopniowym makro bo doszedłem w BB do rozdziału o wyświetlaczu LCD. Przeczytałam rozdział już dwa razy teraz czytam trzeci bo nie ogarniam tego do końca. Przyznam szczerze że czytam też ten wątek na forum bo muszę to zrozumieć w końcu, nie całkiem rozumiem co tu piszecie więc zacząłem kombinować po swojemu. I tu mam prośbę, gdyby ktoś poświęcił mi chwilę przeczytał moje wypociny i skomentował ewentualnie poprawił moje rozumowanie to bardzo by mi pomógł. Mamy taki fragment kodu: język c Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod. Po napotkaniu w kodzie linijki język c Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod. C jako argument zostanie przekazana do dyrektyw język c Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod. które jak dla mnie działają od końca. W linii najpierw C zostanie sklejone ze słowem PORT, otrzymamy PORTC. W tej samej linii SPORT(C) ostanie zastąpione słowem PORTC. Następnie przejdziemy linię wyżej i suma sumarum w tej linii otrzymamy słowo PORTC. A następnie PORTC zostanie wstawione miejscu gdzie kompilator napotkał PORT(LCD_RSPORT). |
Autor: | mirekk36 [ 19 lut 2018, o 00:11 ] |
Tytuł: | Re: Przykład z książki: 5.5 LCD |
ktoś by ci poświęcił pewnie czas ale gdybyś nie bawił się w archeologa i nie doklejał się do starych wątków - masz pytanie zakładaj nowy wątek. Nie wiem czy byś chciał wchodzić na forum na którym byś widział jeden GIGA WĄTEK i wszyscy by się do niego doklejali - jest sens ? forum jest po to aby zadawać pytania w nowych wątkach ... dlatego blokuję ten wątek |
Strona 1 z 1 | Strefa czasowa: UTC + 1 |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |