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.

Język programowania C - jak zapisać?

mateusz19955 20 Sie 2013 16:22 2943 28
  • #1 20 Sie 2013 16:22
    mateusz19955
    Poziom 13  

    Witam,

    Ostatnio uczyłem się pisać w BASCOM-ie ale postanowiłem, że będę się jednak uczył w C.
    I mam problem w zrozumieniu tego warunku:

    Kod: cpp
    Zaloguj się, aby zobaczyć kod


    Próbowałem sam sobie wytłumaczyć i doszedłem do takiego wniosku:

    Jeżli PORTC mam skonfigurowany w ten sposób:

    Kod: cpp
    Zaloguj się, aby zobaczyć kod


    to w tej części tego warunku "PINC & 0x01" PINC jest równy 1 (bo taka była konfiguracja tego pinu) a 0x01 w przeliczeniu też jest równe 1.
    Czyli wynik mnożenia "PINC & 0x01" jest równe 1 (większe od zera) to całe wyrażenie (!(PINC & 0x01)) będzie wtedy równe zero (bo jest operator negacji na początku).
    Czyli z tego wychodzi, że aby ten warunek działał to w tym miejscu "(PINC & 0x01)" wartość musi być większa od zera?
    Tak samo i ten:
    Kod: cpp
    Zaloguj się, aby zobaczyć kod


    PINC = 1
    0x02 = 2, czyli z mnożenia wychodzi 2 (czyli jest większe od zera i też będzie wykonany warunek).
    Przyciski na płytce testowej mam podłączone do PC0 i PC1 i do masy.
    Czyli warunek ma reagować na stan niski.
    I dlatego tak jest operator negacji na początku?

    Dobrze to rozumiem?
    Czy nie?
    Może trochę niezrozumiale napisałem, ale myślę że zrozumiecie mnie.

    Pozdrawiam.

    0 28
  • #2 20 Sie 2013 16:31
    mickpr
    Poziom 39  

    Poczytaj o operatorach bitowych.
    Np. tutaj: http://guidecpp.cal.pl/cplus,operators-bits
    Operację

    Kod: c
    Zaloguj się, aby zobaczyć kod
    najprościej rozumieć można jako sytuację, gdy PIN nr 0 (jego wartość liczbowa w bajcie to 0x01) w Porcie C jest równy "0".

    0
  • #3 20 Sie 2013 16:36
    mateusz19955
    Poziom 13  

    To, że tak jest to ja wiem z BASCOM-a.
    A mi chodzi o to czy dobrze zrozumiałem ten warunek.

    0
  • #5 20 Sie 2013 16:40
    mateusz19955
    Poziom 13  

    Pomyłka w pisaniu.
    Chciałem napisać wejście ale z pośpiechu napisałem wyjście.

    0
  • #6 20 Sie 2013 16:55
    mickpr
    Poziom 39  

    W C++ jeśli wartość wyrażenia jest 0 - to jest ono fałszywe, w przeciwnym przypadku - jest prawdziwe (nawet jeśli wartość wyrażenia jest liczbą ujemną - co przy typach ze znakiem może wystąpić!!!).

    0
  • #7 20 Sie 2013 16:59
    mateusz19955
    Poziom 13  

    Nie rozumiem, wartość liczbowa w bajcie 0x01 to PINC.0?
    A z kąd to wiadomo?

    0
  • #9 20 Sie 2013 17:20
    mateusz19955
    Poziom 13  

    Ok, dzięki to już rozumiem o co chodzi z tym.
    Czyli następne bity będzią:
    0x02
    0x04
    0x08
    0x10
    0x20
    0x40
    0x80

    Tak?

    0
  • #10 20 Sie 2013 17:20
    tmf
    Moderator Mikrokontrolery Projektowanie

    Rozpisz sobie to na bity. Będzi ci łatwiej operować. Te warunki to operacje bitowe (a nie arytmetyczne). Porównywane są zawsze odpowiadające sobie bity. Np. operacja 0x03 & 0x02 da ci dwa, bo tylko bit nr 1 (o wartości liczbowej równej 2) jest ustawiony (ma wartość 1) w obu przypadkach.

    0
  • Pomocny post
    #11 20 Sie 2013 17:21
    BlueDraco
    Specjalista - Mikrokontrolery

    Nie, PINC.0 to najmniej znaczący bit 8-bitowej zawartości portu

    Wyrażenie PINC & 0x01 oblicza wartość 8-bitową powstającą przez odczyt 8 bitów portu i pozostawienie tylko najmniej znaczącego bitu, pozostałe bity są zerowane. Jeśli PINC.0 było zerem, to otryzmujesz bajt o wartości 0, jeśli PINC.0 było jedynką - otrzymasz bajt o wartości 1. Tak uzyskana wartość może być użyta w wyrażeniu logicznym - np. w warunku dla if().
    Operator ! neguje wartość logiczną. Jeśli jego argumentem było 0, zwróci 1; jeśli argument był różny od zera, zwróci 0.

    0
  • #12 20 Sie 2013 17:27
    mateusz19955
    Poziom 13  

    Właśnie o to mi chodziło BlueDarco.

    0
  • Pomocny post
    #13 20 Sie 2013 18:16
    mickpr
    Poziom 39  

    Przy operacjach bitowych dobrze czasem pomagać sobie przesunięciami
    Np.
    1 << 0 oznacza bit 0 (wartość 1 - szesnastkowo 0x01)
    1 << 1 oznacza bit 1 (wartość 2 - szesnastkowo 0x02)
    1 << 2 oznacza bit 2 (wartość 4 - szesnastkowo 0x04)
    ..
    1 << 31 oznacza bit 31 (wartość 2147483648 czyli szesnastkowo 0x80000000)

    Zamiast kombinować jaką wartość ma np. bit 26 - wystarczy wpisać wyrażenie (1<<26).
    Poza tym ułatwieniem, łatwo się taki kod czyta. Od razu wiadomo, że chodzi o bit 26.

    0
  • Pomocny post
    #14 20 Sie 2013 18:40
    tmf
    Moderator Mikrokontrolery Projektowanie

    Tylko, żeby nie było zaskoczenia, bo piszemy w dziale AVR, operacja 1 << 31 wcale nie przesunie wyniku o 31 bitów w lewo, za to wygeneruje ostrzeżenie, które jeśli zignorujemy to będzie dopiero zabawnie. Powinno być 1UL << 31.

    0
  • #15 20 Sie 2013 19:19
    mateusz19955
    Poziom 13  

    Po co są w tym kodzie te opertaory:
    &
    |
    ^

    Kod: cpp
    Zaloguj się, aby zobaczyć kod


    Może mi ktoś dokładnie napisać jak to się oblicza?
    Siedzę i nie mogę tego dojść.

    0
  • #16 20 Sie 2013 19:24
    dondu
    Moderator Mikrokontrolery Projektowanie

    mateusz19955 napisał:
    Po co są w tym kodzie te opertaory:
    &
    |
    ^

    Może mi ktoś dokładnie napisać jak to się oblicza?
    Siedzę i nie mogę tego dojść.

    Proszę bardzo - wiedza z przykładami oraz możliwością ćwiczenia w kompilatorze online: http://mikrokontrolery.blogspot.com/2011/02/kurs-jezyka-c-spis-tresci.html
    w szczególności rozdział: Operatory bitowe.

    Poćwicz solidnie, a później przeczytaj: http://mikrokontrolery.blogspot.com/2011/03/a...howComment=1375869639131#c3165447750334300977

    Tylko się przyłóż i nie wracaj z pytaniami po 2h, tylko po dwóch dniach, gdy już opanujesz podstawę :-)

    0
  • #17 20 Sie 2013 19:25
    mickpr
    Poziom 39  

    tmf napisał:
    Tylko, żeby nie było zaskoczenia, bo piszemy w dziale AVR, operacja 1 << 31 wcale nie przesunie wyniku o 31 bitów w lewo, za to wygeneruje ostrzeżenie, które jeśli zignorujemy to będzie dopiero zabawnie. Powinno być 1UL << 31.
    Mówisz o :
    Cytat:
    warning: left shift count >= width of type

    O tym (i o wszystkich innych warningach) należy pamiętać przy pisaniu w C/C++.
    Podobna pułapka czeka na programistów także innych dialektów C/C++, jeśli użyją literału o (domyślnie) zbyt małym/niezadeklarowanym rozmiarze - więc twoja uwaga nie tyczy się wyłącznie AVR.
    Jest oczywiście jak najbardziej słuszna :)

    0
  • #18 20 Sie 2013 22:12
    tmf
    Moderator Mikrokontrolery Projektowanie

    No właśnie literał liczbowy ma zawsze ściśle określony rozmiar - równy typowi int, chyba, że jawnie zadeklarujemy inaczej, np. dając sufiks UL. Problem w tym, że int intowi na różnych platformach nierówny. Np. na AVR operacja 1<<31 wygeneruje ostrzeżenie, bo int ma tylko 16 bitów, ale na ARM, gdzie int ma 32 bity już wszystko będzie ok. O tej domyślnej promocji typów często ludzie zapominają.

    0
  • #19 21 Sie 2013 19:06
    mateusz19955
    Poziom 13  

    Witam ponownie,

    Znów mam problem z tymi operatorami.
    Bawię się w zapałanie diódek i mam problem.

    Bo jak zapiszę taki warunek:

    Kod: cpp
    Zaloguj się, aby zobaczyć kod

    To działa.

    Ale jak zapiszę taki:
    Kod: cpp
    Zaloguj się, aby zobaczyć kod

    To już niedziała.

    Ja to sobie rozpisuję na bity i dla pierwszego wychodzi tak:

    1 1 1 1 0 0 0 0 - (0xF0)
    & 1 0 1 0 1 0 1 0 - (Maska?)
    = 1 0 1 0 1 0 1 0 - (0xAA)

    A dla drugiego mam tak:

    1 1 1 0 1 1 1 0 - (0xEE)
    & 1 1 1 1 1 0 1 1 - (Maska?)
    = 1 1 1 1 1 0 1 1 - (0xFB)

    I ten właśnie nie działa.
    Ale jak zrobię tak:
    Kod: cpp
    Zaloguj się, aby zobaczyć kod

    To działa.
    Co źle robię że z tym mnożeniem nie działa?

    Tylko troszkę się te bity w lewo przesunęły w tekście.

    0
  • #20 21 Sie 2013 19:29
    mickpr
    Poziom 39  

    mateusz19955 napisał:
    Bawię się w zapałanie diódek i mam problem.
    Napisz nam
    1. na jakich pinach
    2. w jakich portach i
    3. w jaki sposób
    masz te "diódki" podpięte.
    mateusz19955 napisał:
    Bo jak zapiszę taki warunek:

    Kod: c
    Zaloguj się, aby zobaczyć kod
    To powyżej to nie warunek, a instrukcja.
    Można ją rozwinąć do pełnej postaci:
    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • #21 21 Sie 2013 19:32
    tmf
    Moderator Mikrokontrolery Projektowanie

    Instrukcje warunkowego ustawiania bitów :) A warunek brzmi - abyna danej pozycji bit był równy jeden w obu bajtach na tej pozycji musi być jeden. Stąd też obliczenia kolegi mateusz19955 są błędne, gdyż 0xF0 & 0xAA to 0xA0.

    0
  • #22 21 Sie 2013 19:44
    mateusz19955
    Poziom 13  

    Nie rozumiem już tego.

    Chciałem sobie przeanalizować ten kod:

    Kod: cpp
    Zaloguj się, aby zobaczyć kod

    0
  • #23 21 Sie 2013 20:06
    tmf
    Moderator Mikrokontrolery Projektowanie

    Jak już ci wcześniej napisałem, rozbijaj bajty na bity. Operacje bitowe działają na bitach. Operacja & (AND) - powoduje, że żeby odpowiedni bit wyniku był równy 1 oba bity operandów muszą mieć 1. Jeśli którykolwiek z operandów na danej pozycji ma 0 to w wyniku na tej pozycji też musi być 0. Np.:
    0b0011
    &
    0b1101
    =
    0b0001
    Operacja | (OR) sumuje bity, czyli w wyniku uzyskasz jeden jeśli na danej pozycji w którymkolwiek z operandów jest 1, np. dla powyższego przykładu:
    0b0011
    &
    0b1101
    =
    0b1111

    0
  • #24 21 Sie 2013 20:07
    BlueDraco
    Specjalista - Mikrokontrolery

    A co tu jest do analizowania? Każda linijka jest dokładnie skomentowana, więc wiadomo dokładnie, co robi. Od 2 dni próbujemy Ci tłumaczyć operatory logiczne - to podstawy podstaw, dokładnie opisane w tysiącu miejsc. Nie przesadzasz?

    0
  • #25 21 Sie 2013 20:17
    mateusz19955
    Poziom 13  

    To jak to rozpisać:

    Kod: cpp
    Zaloguj się, aby zobaczyć kod


    Dlaczego jest tam | a nie &?
    Nie złoście się ale ja tego naprawdę nie mogę zrozumieć.
    Łatwiej mi jest się nauczyć jak ktoś mi to rozpisze i wytłumaczy.

    0
  • #26 21 Sie 2013 20:21
    tmf
    Moderator Mikrokontrolery Projektowanie

    Odpal sobie kalkulator w windowsie, wybierz tryb programisty i pobaw się tam operatorami bitowymi do znudzenia.
    I nie pytaj nas dlaczego ktoś w progrsamie napisał tak a nie inaczej - widać chciał, żeby PORTD po operacji OR miał wartość 0xFF, a nie 0x00.

    0
  • #27 21 Sie 2013 20:26
    mateusz19955
    Poziom 13  

    Dobra, macie rację że trochę przesadzam.
    Pouczę się jeszcze tego i może to zrozumiem.
    A jak nie to będę się uczył do tąd aż się nauczę.

    0
  • #28 21 Sie 2013 20:54
    BlueDraco
    Specjalista - Mikrokontrolery

    Zawsze możesz udać się na forum na literę A i poskarżyć na złych facetów z Elektrody, a zwłaszcza na mnie i kol. TMF. Wtedy wspaniałomyślny właściciel być może udzieli Ci korepetycji bez obowiązkowego w innych przypadkach wpisowego (czyli zakupu książki, zwanej skromnie "biblią").

    ;)

    A tak na poważnie - szukaj hasła "algebra Boole'a". To naprawdę podstawy podstaw.

    0
  • #29 21 Sie 2013 21:10
    zumek
    Poziom 39  

    mateusz19955 napisał:
    ...Pouczę się jeszcze tego i może to zrozumiem.
    A jak nie to będę się uczył dotąd, aż się nauczę.


    Tak zrób, bo temat zamykam - regulamin p. 3.1.17

    0