Skocz do zawartości

[Programowanie] Konfiguracja i algorytm linefollowera w C - dla początkujących i nie tylko


Pomocna odpowiedź

Kawał dobrej roboty!!!

Wybrałeś chyba napotrzebniejszy temat z wszystkich możliwych. Skupiłeś masę wiedzy w jednym miejscu.

Możliwe że dzięki Tobie zniknie cała masa pytań o podstawowe sprawy!

Dzięki, dzięki dzięki! Tym artykułem rozwiałeś wszystkie moje wątpliwości co do programowania w c oraz algorytmów LF. Jeszcze raz dzięki! Mam nadzieję że wygrasz ten konkurs 😉

Edit!

Masz może pliki eagle tego schematu? Bardzo by się przydal 🙂

Do napisania artykułu skłoniły mnie głównie powtarzające się pytania wszelkiej maści właśnie w tematyce AVRów/LFów programowanych w C. Cieszę się bardzo, że pomogę kilku osobom w zgłębieniu tego tematu.

tidzu, niestety projektu z eagle'a nie mogę teraz znaleźć. Nie jestem też jego autorem, także najlepiej jeśli zgłosisz się do ojebejbe, z pewnością Ci pomoże, bo to dobry chłopak jest.

Opis fajny i pouczający ale proponuje nie uczyć takiej techniki jak przy odczycie czujników to:

ADMUX &= 0b11100000; // zerujemy bity MUX odpowiedzialne za wybór kanału (s. 255 w DS)

ADMUX |= i; // wybieramy kanał przetwornika

działa tylko dlatego że czujników jest 5. Gdy pętla była dłuższa to zamazaniu uległy by bity REFS0 i ADLAR rejestru ADMUX i byłby problem i to trudny do znalezienia.

Makro REGISTER_BIT jest naprawdę fajne 🙂

Pozdrawiam

Czujników jest 7 😉

Prawdę mówiąc nie widzę problemu.. Jest sprawą dość oczywistą, że nie wpisujemy tam wartości większej niż 7, bo numery kanałów przetwornika mieszczą się w zakresie [0;7]. Więcej niż ośmiu czujników nie będzie, bo nie byłoby jak ich podłączyć - więc nie ma też celu tworzenie dłuższej pętli.

Jakby nie patrzeć, zawsze warto chwilę się zastanowić przy pisaniu kodu, żeby nie zrobić czegoś głupiego, a tu akurat tak się da.

Dla absolutnego spokoju ducha można tę linijkę lekko poprawić:

ADMUX |= i & 0b00001111;

I już nic złego się nigdy nie stanie.

A REGISTER_BIT faktycznie jest bardzo przyjemne 🙂

PS. Teraz zauważyłem taki malutki błąd, który niczego nie psuje, ale może konfundować:

zamiast:
ADMUX &= 0b11100000;
powinno być:
ADMUX &= 0b11110000; ( jedynka zamiast 4. zera - zerować trzeba 4 ostatnie bity )

Od razu lepiej.

Nie żebym się czepiał ale powinno być:

ADMUX |= i & 0b00000111;

MUX3 i 4 określa wzmocnienie dla kanałów różnicowych 🙂

Jeszcze raz gratuluje świetnego opisu.

  • 4 tygodnie później...

Mam pytanie. W artykule piszesz

TCCR1A |= _BV(COM1A1) | _BV(COM1B1)

i później gdy podsumowujesz wszystko razem to nie ma już tej kreski | przed znakiem =. Dlaczego?

TCCR1A = _BV(COM1A1) | _BV(COM1B1) | _BV(WGM10);
TCCR1B = _BV(CS10) | _BV(WGM12);

Prawdę mówiąc nie wiem za bardzo od której strony zabrać się za odpowiedź na to pytanie, więc może wszystko po kolei.

Pionowa "pałka" w C to operator sumy logicznej. Jeśli w którymś z dwóch argumentów na danym miejscu wystąpi jedynka - w wyniku na tym miejscu również powstanie jedynka. Dlatego też za pomocą tego operatora można "dopisać" konkretne bity do zmiennej.

Dlaczego zapisy się różnią?

We wszystkich przypadkach w tekście, gdy piszę o ustawieniu jakiegoś konkretnego bitu, zakładam że w rejestrze mogą znajdować się już jakieś dane. Dlatego też, aby ich nie utracić, konieczne jest wykorzystanie operatora |=.

W podsumowaniu natomiast zawarta jest całościowa konfiguracja danego układu, dlatego też można rejestr konfiguracyjny zapisać od nowa.

Czy można inaczej?

Oczywiście tak. Można w pierwszej zaznaczonej przez Ciebie linijce (jako że jest to pierwsze odwołanie się do danego rejestru) użyć operatora =, a dopiero w kolejnych linijkach "dopisywać" bity za pomocą |=. Można też we wszystkich linijkach podsumowujących (Twój drugi cytat) użyć |=, gdyż domyślnie bity w tych rejestrach są równe 0.

Niestety nie jestem w stanie tego logiczniej przedstawić w piśmie ale mam nadzieję, że chociaż trochę pomogłem 😉 Myślę, że dokładne zrozumienie działania operatora |= to klucz to ogarnięcia tej kwestii.

  • 1 miesiąc później...
A gdzie znajdę rzeczone "io_cfg.h"? 🙂

To po prostu makro:

#define REGISTER_BIT(rg,bt) ((volatile _io_reg*)&rg)->bit##bt

😉

Potem sobie robisz tak jak opisano w artykule, np:

#define LED_DIR                REGISTER_BIT(DDRB,0)
#define LED                    REGISTER_BIT(PORTB,0)
Oprócz tego makra jest tam jeszcze prosta struktura.

Plik w całości znajduje się w paczce z kodem źródłowym.

A, przepraszam, nie oglądałem paczki, a zalozylem, ze tego pliku tan nie ma, skorup pytał bobby o to;)

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...