MasterFun Napisano Październik 24, 2010 Udostępnij Napisano Październik 24, 2010 Witam! Mam następujący problem o ile można to nazwać problemem. Ostatnio zająłem się diodowym kursem dotyczącym C, i mam kilka pytań gdyż nie bardzo rozumiem pewnych zagadnień. (uC oczywiście atmega8 kompilator winavr i avr dude do wrzucania) Pierwsza rzecz to, wyobraźmy sobie sytuację: ustawiamy PORTC jako wejście czyli DDRC = 0x00; (do portu C będą podłączone przyciski - mikroswitche) No i później należałoby ustawić stan poszczególnych bitów na porcie C, o ile dobrze rozumiem można ustawić PORTC = 0x00 i wtedy switch trzeba podłączyć do nóżki uC i do VCC lub ustawić PORTC = 0xff i należy podłączyć switch do nóżki uC i do GND, dobrze rozumiem? Kolejna sprawa to funkcja if-else. W kursie wykonywanie warunku było pokazane w następujący sposób: If(PINC & 0x01) Powiedziane również było że funkcja & służy do „przysłonięcia pozostałych bitów” No ale w jaki sposób? Próbowałem sam do tego dojść podstawiając za 0x01 różne wartości i operując na poszczególnych bitach portu. Próbując różnych konfiguracji (tak jak opisałem to w problemie z portem C) raz działało dobrze a raz sprzecznie w odniesieniu do pierwszej próby… Jeśli mógłby ktoś mi to na bitach wytłumaczyć z różnymi przykładami tak aby 1 była w kilku miejscach. Aha i ostatnia rzecz wydaje mi się dość dziwna, otóż pisząc program z funkcją if-else który działał w sposób następujący: jeśli switch nie wciśnięty diody świecą się w konfiguracji 01010101 a jeśli wciśnięty 10111101 niby proste, ale odłączając kabelek od portu gdzie miał być podłączony switch zmieniał się stan (?) Później ponownie chcąc dotknąć kabelkiem do portu ze switchem stan też się zmieniał, najlepsze jest to że druga strona kabelka wisiała w powietrzu . Pozdrawiam i dziękuję za odpowiedź, jednocześnie przepraszam jeśli temat był poruszany na forum jednak nie znalazłem… Cytuj Link do komentarza Share on other sites More sharing options...
MirekCz Październik 24, 2010 Udostępnij Październik 24, 2010 1.Jak pin jest jako wejscie (odpowiedni bit DDRx ustawione na 0) to wtedy wartość analogicznego bitu PORTC oznacza czy podłączysz wewnętrzny pullup (jest to rezystor ok. 50k do VCC). Czyli bez tego rezystora musiałbyć na zewnątrz procesora dać rezystor do VCC i do tego mikroswitch do GND, albo rezystor do GND i mikroswitch do VCC. Korzystając z wewnętrznego pullupa (czyli odpowiedni bit PORTC na "1") nie musisz stosować rezystora do VCC, a tylko podłączasz microswitch do GND - mniej komponentów. 2.& to operacja AND. Jest to operacja, która ma taką tablicę stanów: A,B,wynik 0,0,0 0,1,0 1,0,0 1,1,1 Czyli 1 będzie tylko wtedy, gdy odpowiedni bit w PINC będzie 1 i bit do którego porównujesz będzie 1. Dla przypadku PINC&0x01 sprawdzasz pierwsze wejście portc i tylko jak na pinie PC0 jest "1" to warunek zwróci prawdę - wykona się część programu w warunku if. Trudniejszy przykład: Powiedzmy, że chcemy coś wykonać gdy na wejściu PA2 i PA4 jest stan 1. PA2 i PA4 to odpowiednio bit 3 i 5, binarnie możesz to zapisać jako 00010100b (z lewej najwyższy bit), w hexie jest to 0x14 (sprawdz kalkulatorem w windowsie - ustawienie programisty) Czyli warunek to: if ((PINA & 0x14) == 0x14) ... 3.Z wejściami mikrokontrolera jest tak, że mogą wejść w tzw. stan nieustalony. Zazwyczaj masz napisane, że np do 0,3VCC jest stan niski "0", a od 0,7VCC jest stan wysoki "1". Pomiędzy tym jest stan nieokreślony. Jak pinu nie podepniesz ani pod VCC, ani pod GND to on sobie swobodnie lata i robi różne dziwne rzeczy. JEST TO BARDZO ZŁA PRAKTYKA! Może to prowadzić do nadmiernego poboru prądu czy nawet zawieszania się procesora. Jak piny są nieużywane należy albo je podpiąć zewnętrznym rezystorem pod GND, albo użyć wewnętrznego pullupa i podpiąć pod VCC. PS. W zapisie liczb zazwyczaj jest tak: 123 - system dziesiętny 00110010b - bin (binarny) 0xFF - hex (szesnastkowo) Cytuj Link do komentarza Share on other sites More sharing options...
MasterFun Październik 24, 2010 Autor tematu Udostępnij Październik 24, 2010 1.Jak pin jest jako wejscie (odpowiedni bit DDRx ustawione na 0) to wtedy wartość analogicznego bitu PORTC oznacza czy podłączysz wewnętrzny pullup (jest to rezystor ok. 50k do VCC). Czyli bez tego rezystora musiałbyć na zewnątrz procesora dać rezystor do VCC i do tego mikroswitch do GND, albo rezystor do GND i mikroswitch do VCC. Korzystając z wewnętrznego pullupa (czyli odpowiedni bit PORTC na "1") nie musisz stosować rezystora do VCC, a tylko podłączasz microswitch do GND - mniej komponentów. Hmmm... bardzo ciekawe, otóż w żadnym kursie się z tym nie spotkałem i już chyba jasne jest dlaczego za każdym razem było połączenie do GND (wydawało mi się to dziwne bo gdyby było do VCC to program zawierałby mniej komplikacji a tak trzeba było używać negacji itd. ) 2.& to operacja AND. Jest to operacja, która ma taką tablicę stanów: A,B,wynik 0,0,0 0,1,0 1,0,0 1,1,1 Czyli 1 będzie tylko wtedy, gdy odpowiedni bit w PINC będzie 1 i bit do którego porównujesz będzie 1. Dla przypadku PINC&0x01 sprawdzasz pierwsze wejście portc i tylko jak na pinie PC0 jest "1" to warunek zwróci prawdę - wykona się część programu w warunku if. Trudniejszy przykład: Powiedzmy, że chcemy coś wykonać gdy na wejściu PA2 i PA4 jest stan 1. PA2 i PA4 to odpowiednio bit 3 i 5, binarnie możesz to zapisać jako 00010100b (z lewej najwyższy bit), w hexie jest to 0x14 (sprawdz kalkulatorem w windowsie - ustawienie programisty) Czyli warunek to: if (PINA & 0x14) ... Chciałbym się odnieść do trudniejszego przykładu, załóżmy że: PA2 ma stan 0 PA4 ma stan 1 i porównuje to do 00010100b (0x14) Czy oba bity do których porównuje muszą być w stanie 1 żeby dla całego warunku była wartość logiczna PRAWDA, nie do końca wiem jak to analizować, poszczególne bity do których porównuje czy cały stan portu po operacji &? 3.Z wejściami mikrokontrolera jest tak, że mogą wejść w tzw. stan nieustalony. Zazwyczaj masz napisane, że np do 0,3VCC jest stan niski "0", a od 0,7VCC jest stan wysoki "1". Pomiędzy tym jest stan nieokreślony. Jak pinu nie podepniesz ani pod VCC, ani pod GND to on sobie swobodnie lata i robi różne dziwne rzeczy. JEST TO BARDZO ZŁA PRAKTYKA! Może to prowadzić do nadmiernego poboru prądu czy nawet zawieszania się procesora. Jak piny są nieużywane należy albo je podpiąć zewnętrznym rezystorem pod GND, albo użyć wewnętrznego pullupa i podpiąć pod VCC. Rozumiem że rezystor jak w przypadku wyżej ma wartość ok 50k? Cytuj Link do komentarza Share on other sites More sharing options...
MirekCz Październik 24, 2010 Udostępnij Październik 24, 2010 2.& to operacja AND. Jest to operacja, która ma taką tablicę stanów: A,B,wynik 0,0,0 0,1,0 1,0,0 1,1,1 Czyli 1 będzie tylko wtedy, gdy odpowiedni bit w PINC będzie 1 i bit do którego porównujesz będzie 1. Dla przypadku PINC&0x01 sprawdzasz pierwsze wejście portc i tylko jak na pinie PC0 jest "1" to warunek zwróci prawdę - wykona się część programu w warunku if. Trudniejszy przykład: Powiedzmy, że chcemy coś wykonać gdy na wejściu PA2 i PA4 jest stan 1. PA2 i PA4 to odpowiednio bit 3 i 5, binarnie możesz to zapisać jako 00010100b (z lewej najwyższy bit), w hexie jest to 0x14 (sprawdz kalkulatorem w windowsie - ustawienie programisty) Czyli warunek to: if (PINA & 0x14) ... Chciałbym się odnieść do trudniejszego przykładu, załóżmy że: PA2 ma stan 0 PA4 ma stan 1 i porównuje to do 00010100b (0x14) Czy oba bity do których porównuje muszą być w stanie 1 żeby dla całego warunku była wartość logiczna PRAWDA, nie do końca wiem jak to analizować, poszczególne bity do których porównuje czy cały stan portu po operacji &? Mój błąd, poprawiłem w poście powyżej. Każda wartość >0 zostanie przez if przyjęta jako prawda. AND zwróci wartość 0x10 i w tym momencie zwykły if (PINC&0x14) zwróciłby prawdę. Poprawny kod to if ((PINC&0x14)==0x14) Zewnętrzny rezystor podciągający może mieć dowolną rozsądną wartość. Może to być 100k, 10k, 1k. Nie ma to większego znaczenia jak chcesz tylko ustalić stan wejściowy pina. 1 Cytuj Link do komentarza Share on other sites More sharing options...
Polecacz 101 Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Produkcja i montaż PCB - wybierz sprawdzone PCBWay! • Darmowe płytki dla studentów i projektów non-profit • Tylko 5$ za 10 prototypów PCB w 24 godziny • Usługa projektowania PCB na zlecenie • Montaż PCB od 30$ + bezpłatna dostawa i szablony • Darmowe narzędzie do podglądu plików Gerber Zobacz również » Film z fabryki PCBWay
MasterFun Październik 24, 2010 Autor tematu Udostępnij Październik 24, 2010 O taką odpowiedź mi chodziło 😉 Dzięki i oczywiście "pomógł" edit:\\ jeszcze takie pytanko wykonując negacje tak jak w przykładzie: PORTA = 0x03 if(!(PINA & 0x07)) otrzymam negacje tych bitów które porównuje do 0x07 czyli: 0000 0100b czy może cały port i będzie to wyglądać tak: 1111 1100b (inaczej mówiąc brane są pod uwagę tylko te bity gdzie w "masce" (0x07) mam wartość 1 czy może neguje cały wynik po operacji &? ) a i jeszcze jedno, tak dla pewności, zakładając że mam: DDRA = 0x00; //port a jest wejsciem PORTA = 0xff; // stan bitów na P. A to 1111 1111 (do portu A na linii 3 mam połączony mikro switch) po naciśnięciu go otrzymam: 1111 1011b, zgadza się? Cytuj Link do komentarza Share on other sites More sharing options...
MirekCz Październik 24, 2010 Udostępnij Październik 24, 2010 Ad1. Zgodnie z nawiasami skoro najpierw masz (PINA & 0x07) a dopiero przed tym ! to najpierw zrobi AND, a potem wynik zmieni na przeciwny (prawda na fałsz i odwrotnie, gdzie prawda to wszystko różne od 0). Natomiast negacja bitów to inny symbol "~". Różnica taka, że np !0xF0 da 0x00, a ~0xF0 da 0x0F. Przejrzyj stronę http://pl.wikibooks.org/wiki/C/Operatory Ad2. Tak Cytuj Link do komentarza Share on other sites More sharing options...
MasterFun Październik 24, 2010 Autor tematu Udostępnij Październik 24, 2010 Ok, przejrzałem dalszą część kursu i była wytłumaczona różnica między negacją na bitach a logiczną 😉 Twój link też się przydał... Generalnie zaczynam rozumieć istotę funkcji if z kilkoma różnymi bitami, po próbie zrozumienia przystąpiłem do testów, rozpisałem sobie bity na kartce i było tak jak się spodziewałem... 😉 No i miałem okazję sprawdzić to o co pytałem tzn: [...] Czy oba bity do których porównuje muszą być w stanie 1 żeby dla całego warunku była wartość logiczna PRAWDA, nie do końca wiem jak to analizować, poszczególne bity do których porównuje czy cały stan portu po operacji &? Niestety jednak nie wszyło tak jak mówiłeś: Każda wartość >0 zostanie przez if przyjęta jako prawda. AND zwróci wartość 0x10 i w tym momencie zwykły if (PINC&0x14) zwróciłby prawdę. Jeśli porównuję do dwóch różnych bitów to te dwa bity muszą zwrócić prawdę żeby wykonała się dalsza część programu po if. Pozdrawiam Cytuj Link do komentarza Share on other sites More sharing options...
MirekCz Październik 24, 2010 Udostępnij Październik 24, 2010 Podaj dokładny kod z informacją co jest w jakiej zmiennej... 1 Cytuj Link do komentarza Share on other sites More sharing options...
MasterFun Październik 24, 2010 Autor tematu Udostępnij Październik 24, 2010 #define F_CPU 1000000L #include <avr/io.h> int main(void) { DDRB = 0xff; PORTB = 0x00; DDRC = 0x00; PORTC= 0x07; for(;;) { if(!(PINC & 0x05)) { PORTB=0xaa; } else { PORTB=0x00; } } } PORT C0 i C2 to mikro switche PORT B0...B7 to Ledy Działa to w ten sposób że jeśli nacisnę 1 przycisk nic się nie dzieje, jeśli 2 to diody świecą tak jak było powiedziane w programie po if czyli AA hex Cytuj Link do komentarza Share on other sites More sharing options...
mactro Październik 24, 2010 Udostępnij Październik 24, 2010 Masz negację w złym miejscu. Powinno być: if(~(PINC) & 0x05) Pamiętaj, że stanem aktywnym switcha u Ciebie jest 0. Kiedy miałeś wciśnięty tylko jeden przycisk iloczyn PINC & 0x05 był 0x01 lub 0x04, czyli różny od 0, zatem po negacji warunek nie jest spełniony. Nie wiem czy jasno wytłumaczyłem, ale zaraz spać idę, więc... 😋 1 Cytuj Link do komentarza Share on other sites More sharing options...
MasterFun Październik 25, 2010 Autor tematu Udostępnij Październik 25, 2010 Zgadza się, mactro, zmieniłem kod i działa poprawnie... Dziękuję, aha i jeśli znalazłbyś chwilkę mógłbyś rozpisać na bitach tą operację z mojego przykładu i swojego poprawionego? Cytuj Link do komentarza Share on other sites More sharing options...
mactro Październik 25, 2010 Udostępnij Październik 25, 2010 Twój kod (dla uproszczenia tylko cztery bity): Jeden przycisk wciśnięty PINC x0x1 & 0101 !(0001)=0 Dwa przyciski: PINC x0x0 & 0101 !(0000)=1 U mnie, jeden przycisk: ~PINC x1x0 & 0101 0100 (różne od 0, zatem warunek if'a spełniony) Dwa przyciski: ~PINC x1x1 & 0101 0101 Proponuję, żebyś się zapoznał z działaniami na bitach np na tej stronie:link 1 Cytuj Link do komentarza Share on other sites More sharing options...
MasterFun Październik 25, 2010 Autor tematu Udostępnij Październik 25, 2010 Dzięki wielkie dla kolegi mactro, też leci pomógł... 😉)) Cytuj Link do komentarza Share on other sites More sharing options...
Pomocna odpowiedź
Dołącz do dyskusji, napisz odpowiedź!
Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!