To forum jest dla wszystkich pasjonatów mikrokontrolerów AVR Atmela. Wymiana doświadczeń i pomoc dla początkujących w pisaniu programów zarówno w C, Asemblerze jak i BASCOM. Zapraszam znawców tematu, aby pomogli wszystkim początkującym!
-
adi19887
- -
- Posty: 52
- Rejestracja: 22 mar 2010, 23:48
- Lokalizacja: Poznań
Post
autor: adi19887 » 20 sie 2013, 21:04
Jako, że nie znalazłem wyczerpującej dla mnie odpowiedzi zamieszczam pytanie tutaj. Mam podany niżej kod w C:
Wiem co to robi jednak mnie interesuje jak to przebiega. Dla mnie znaczy to tyle:
Dopóki RXC jest jedynką to czekaj. No ale coś tutaj nie gra bo wg. opisu autora kod ten ma czekać na 0 w bicie RXC. Proszę o wytłumaczenie ponieważ odchodzę już od zmysłów przy tak prostych poniekąd rzeczach.
Pozdrawiam.
-
leech10
- Użytkownik
- Posty: 546
- Rejestracja: 24 mar 2011, 20:34
- Lokalizacja: Katowice
Post
autor: leech10 » 21 sie 2013, 8:18
Hej
No calosc jest spelniona wtedy gdy UCSR1A = 0 , _BV(RXC) = 0 albo obydwa sa rowne 0. Wtedy petla dostanie 1 i ruszy). Nie umiem programowac mikrokontrolerow wiec nie powiem Ci czy calosc jest dobra. Ale gdy bit RCX=1 UCSR1A =0 to warunek tez jest spelniony tyle ze nie wiem czy np UCSR1A nie ma zawsze wartosci = 1 ale wtey zas nie trzeba by tej petli tak zapisywac bo i po co. wystarczylo by while( _BV(RXC != 1) albo while( _BV(RXC ==0)
Pozdrawiam
Piotrek
-
adi19887
- -
- Posty: 52
- Rejestracja: 22 mar 2010, 23:48
- Lokalizacja: Poznań
Post
autor: adi19887 » 21 sie 2013, 8:42
Makrodefinicja _BV () tworzy maskę bitową za mnie - bardzo wygodne. Jednak ja dochodzę do takiego samego wniosku jak kolega wyżej, że ten warunek jest ciągle spełniony.
-
leech10
- Użytkownik
- Posty: 546
- Rejestracja: 24 mar 2011, 20:34
- Lokalizacja: Katowice
Post
autor: leech10 » 21 sie 2013, 10:49
Hej
No niespelniony jest tylko wtedy gdy sa 2 jedynki ale skoro ma sprawdzac tylko RCX to po co w warunku byloby UCSR1A?
Z punktu widzenia C- bez sensu ale najlepiej niech sie wypowie ktos z mikrokontolerow bo skoro piszesz ze petla jest dobra to po cos musi to tam byc
pozdrawiam
Piotrek
-
adi19887
- -
- Posty: 52
- Rejestracja: 22 mar 2010, 23:48
- Lokalizacja: Poznań
Post
autor: adi19887 » 21 sie 2013, 16:24
Zatem proszę osobę mającą rozeznanie w tym zapisie o wytłumaczenie go mnie - mniej kumatemu
Makrodefinicja _BV(n) to to samo co (1<<n) natomiast operator iloczynu bitowego & mówi, że gdy bit n będzie równy 0 to w bajcie (w tym wypadku UCSR) na miejscu n znajdzie się 0 (operacja zerowania).
Jeżeli źle piszę to proszę o poprawkę. Mnie się rozchodzi dlaczego użyty jest tutaj znak (!)i jak on działą.
-
keruseykaryu
Post
autor: keruseykaryu » 21 sie 2013, 17:56
To proste jest. Nawiasy są, zatem nie trzeba pamiętać o prirytetach działań:
1. _BV(RXC) to (1 << RXC) czyli (0b00000001 << 7) czyli 0b10000000
2. UCSR1A & _BV(RXC) daje 0b10000000, zatem większe niż zero czyli PRAWDA jak RXC będzie 1, daje 0b00000000, równe zero czyli FAŁSZ jak RXC będzie 0
3. !(UCSR1A & _BV(RXC)) daje FAŁSZ bo NIE PRAWDA = FAŁSZ jak RXC będzie 1, a daje PRAWDA bo NIE FAŁSZ = PRAWDA jak RXC będzie 0
4. while(!(UCSR1A & _BV(RXC))) zaczeka aż wyrażenie będzie PRAWDA a ta będzie jak RXC będzie 0
Wot cała Filo Zofia. Po prostu co innego to "~" negacja bitowa, a co innego "!" negacja przy logice PRAWDA/FAŁSZ.
-
adi19887
- -
- Posty: 52
- Rejestracja: 22 mar 2010, 23:48
- Lokalizacja: Poznań
Post
autor: adi19887 » 21 sie 2013, 20:34
No właśnie odpowiedź wyczerpująca. Dziękuję.
-
dondu
- Użytkownik
- Posty: 211
- Rejestracja: 24 maja 2005, 9:47
- Lokalizacja: Śląskie
-
Kontakt:
Post
autor: dondu » 24 sie 2013, 8:55
A na przyszłość stosuj po prostu przesunięcie bitowe zamiast makro _BV(), czyli zgodnie z tym co napisał keruseykaryu Twój kod powinien wyglądać tak:
i nie będziesz miał już nigdy wątpliwości, a kod będzie kompilował się także z innymi kompilatorami, co jest istotne gdy tworzy się biblioteki ogólne, do czego zachęcam.
Zauważ, że ilość znaków jest dokładnie taka sama
