Programowanie. Elektronika dla Wszystkich 25. Rozwiązania zadań z ostatniego odcinka Tematem pierwszego zadania było wygenerowanie
|
|
- Alina Dziedzic
- 6 lat temu
- Przeglądów:
Transkrypt
1 Kurs AVR lekcja 9 Rozwiązania zadań z ostatniego odcinka Tematem pierwszego zadania było wygenerowanie na nóżce mikrokontrolera częstotliwości n-razy niższej niż występująca na innej nóżce. Aby program zależał od podawanej z zewnątrz częstotliwości, można wykorzystać funkcję taktowania timera zewnętrznym sygnałem. Załóżmy, że wykorzystamy Timer0. Aby był on taktowany zewnętrznym zegarem, trzeba ustawić bity CS1 i CS2 w rejestrze TCCR0, zgodnie z opisem w lekcji 3. Potrzebujemy też przerwania co określoną liczbę taktów timera. Tutaj użyć można funkcji Output Compare, również znanej z lekcji 3. Wymaga ona ustawienia bitu WGM01, również w rejestrze TCCR0. Cały kod pokazuje listing 1. Nóżką przyjmującą sygnał jest PB0. Sygnał wyjściowy może być generowany na DDRB = _BV(DDB1); TCCR0 = _BV(CS02) _BV(CS01) _BV(WGM01); TIMSK = _BV(OCIE0); OCR0 = 4; while(1) ISR(TIMER0_COMP_vect) static uint8_t state = 0; if (state) PORTB = _BV(PORTB1); else PORTB &= ~_BV(PORTB1); state =!state; Listing 1 dowolnym pinie, tutaj jest to PB1. W funkcji obsługi przerwania przestawiany jest stan pinu w zależności od zmiennej state, uint8_t dispdigits[4] = 0, 0, 0, 0; TCCR0 = _BV(CS00) _BV(CS01); // CLK/64 DDRA = 0xff; DDRB = _BV(PB3) _BV(PB2) _BV(PB1) _BV(PB0); DDRB = _BV(PB6); dispdigits[1] = 0b ; // cyfra 3 na wyświetlaczu DISP2 while (1) PORTB = _BV(PB6); PORTB &= ~_BV(PB6); ISR(TIMER0_OVF_vect) static uint8_t dispnum = 0; PORTB = 0x0f; PORTB &= ~_BV(dispNum); PORTA = ~dispdigits[dispnum]; dispnum++; dispnum %= 4; Listing 2 która za każdym przerwaniem ma przestawianą wartość na przeciwną. Jest to zmienna statyczna, czyli zachowująca swoją wartość pomiędzy wywołaniami funkcji. Wartość wpisywana do rejestru OCR0, będącego rejestrem funkcji Output Compare, wyznacza stopień podziału. Liczba 4 da podział przez 10, ponieważ przerwanie będzie generowane co 5 taktów, a każda zmiana stanu pinu wyznacza początek jednego półokresu. Z kolei np. podział przez 20 będzie wymagał liczby 9. Maksymalny podział to 512, ponieważ rejestry Timer0 są 8-bitowe. Dla większych stopni podziału można sięgnąć po 16-bitowy Timer1 lub wykorzystać dodatkową zmienną zliczającą przerwania. Zadanie drugie polegało na generowaniu dwóch niezależnych częstotliwości. Funkcję tę zrealizować można za pomocą dwóch timerów i ich przerwań, pochodzących z przepełnienia lub Output Compare. W przypadku jednego timera można zliczać przerwania za pomocą zmiennej i np. jeden pin przestawiać co 3 przerwania, a drugi co pięć. Trudniej jednak w takim przypadku będzie mówić o niezależności częstotliwości. Sterowanie wyświetlaczem LED Wiemy już, jak działają przerwania i poznaliśmy niektóre niuanse związane z ich obsługą. Naszą wiedzę wykorzystaliśmy do prostego odmierzania czasu i migania LED-ami. Czas na wykorzystanie przerwań do czegoś bardziej praktycznego. Na naszej płytce testowej znajdują się cztery wyświetlacze 7-segmentowe LED, tworząc jeden duży wyświetlacz czterocyfrowy. Pojedynczym wyświetlaczem sterowaliśmy już w lekcji 2. Sterowanie jednak wszystkimi naraz wymaga multipleksowania ze względu na ograniczoną liczbę pinów mikrokontrolera. Sterowanie multipleksowe polega na tym, że aktywujemy jeden wyświetlacz i włączamy odpowiednie jego segmenty. Następnie wyłączamy go i włączamy segmenty drugiego wyświetlacza. Robimy tak też z wyświetlaczem trzecim i czwartym, a następnie zaczynamy od początku. W danej chwili świecą segmenty tylko jednego wyświetlacza, ale jeśli będziemy przełączać się między wyświetlaczami odpowiednio szybko, oko ludzkie tego nie wychwyci i wrażenie będzie takie, jakby wszystkie wyświetlacze działały jednocześnie, bez migotania. Do sterowania czterema wyświetlaczami wystarczy 12 pinów mikrokontrolera: osiem dla segmentów (razem z kropką) oraz 4 do włączania wyświetlaczy. Na naszej płytce testowej dostępne jest złącze LED_DISP, które ma właśnie 12 pinów pozwalających na sterowanie wyświetlaczami LED. Segmenty (katody) połączone są z pinami oznaczonymi literami A G oraz kropką. Z kolei tranzystory PNP podłączające anody do plusa zasilania są dostępne na pinach 1 4. Aby włączyć dany segment danego wyświetlacza, trzeba ustawić niski stan logiczny na pinie tego segmentu oraz niski stan logiczny na pinie wyświetlacza. Przykładowo zaświecenie środkowego poziomego segmentu na wyświetlaczu drugim od lewej (DISP3) wymaga podania zera (czyli zwarcia do masy) pinów G i 3. Jak wspomnieliśmy, sterowanie multipleksowe wymaga szybkiego przełączania wyświetlaczy. Jest to trudne do zrealizowania, jeśli mikrokontroler zajmuje się jednocześnie innymi rzeczami. Tutaj z pomocą przychodzą właśnie przerwania. Konfigurując odpowiednio częste przerwanie w timerze, możemy sterować wyświetlaczem LED niezależnie od reszty programu. Popatrzmy na prosty przykład, pokazany na listingu 2. Do sterowania wyświetlaczem wykorzystujemy Timer0. Taktowany jest on częstotliwością mikrokontrolera podzieloną przez 8. Przerwanie generowane jest w momencie przepełnienia licznika, czyli z częstotliwością / 8 / 256 = 7812,5Hz. Może się ona wydawać zbyt duża, ale przy tych ustawieniach timera migotanie nie będzie widoczne, nawet jeśli zmniejszymy taktowanie mikrokontrolera z 16 MHz na 1 MHz. Do sterowania segmentami wyświetlaczy wykorzystany jest port A, natomiast do wyboru wyświetlacza wykorzystywane są piny 0 3 portu B. Zarówno włączenie/wybór wyświetlacza, jaki włączenie segmentu wykonywane są niskim stanem logicznym. Wynika to z tego, że wyświetlacze na płytce testowej są wyświetlaczami ze wspólną anodą i sterowane są od strony katod. Z kolei anody dołączane są do plusa przez tranzystory PNP włączane logicznym zerem. W funkcji obsługującej przerwanie zadeklarowana jest statyczna zmienna dispnum przechowująca numer aktualnego wyświetlacza. W zależności od jej wartości na odpowiednim pinie ustawiane jest zero. Wcześniej na pozostałych 4 pinach sterujących wyświetlaczem ustawiane są jedynki, aby wyłączyć ewentualnie włączone wyświetlacze. Następnie Elektronika dla Wszystkich 25
2 void leddispnumber(float num, char format[], uint8_t shift) uint8_t dispnum = 3 - shift; char buff[6]; snprintf(buff, sizeof(buff), format, num); buff[sizeof(buff) - 1] = 0; for (uint8_t i = 0; i < strlen(buff); i++) char ch = buff[i]; if (ch >= '0' && ch <= '9') dispdigits[dispnum] = segments[ch - '0']; if (ch == '-') dispdigits[dispnum] = segments[led_minus]; if (ch == '.') dispdigits[dispnum + 1] = segments[led_dot]; else if (dispnum > 0) dispnum--; else return; Listing 3 z globalnej tablicy dispdigits wybierany jest bieżący element i wystawiany na porcie A w postaci zanegowanej, ze względu na sterowanie od strony katod. Gdy już odpowiednie segmenty są wysterowane, zwiększana jest zmienna z numerem aktualnego wyświetlacza. Gdy osiągnie wartość 4, jest zerowana. Stosowany jest tutaj operator modulo, czyli reszta z dzielenia, mający w języku C symbol %. W głównym programie tablica dispdigits inicjowana jest zerami, a następnie do elementu drugiego (z numerem 1) wpisywany jest bajt z bitami odpowiadającymi zaświeconym segmentom układającym się na wyświetlaczu w cyfrę 3. W głównej pętli miga dioda. Wyświetlacz odświeżany jest niezależnie, pobiera tylko wartości z dispdigits. Warto zauważyć, że tablica dispdigits jest swego rodzaju interfejsem pomiędzy głównym programem a kodem obsługującym wyświetlacz. Pomijając kwestię inicjalizacji, sterowanie wyświetlaczem odbywa się bez wywoływania funkcji, tylko przez zapis do tablicy. Docelowo jednak tego typu interfejs nie zawsze jest pożądany, uzasadnienie poznamy w dalszej części lekcji. Aby przetestować omawiany przykład, należy utworzyć w Atmel Studio nowy projekt i wkleić kod do main.c. Oczywiście jak zwykle nie zapominamy o zdefiniowaniu makra F_CPU o wartości odpowiadającej aktualnie ustawionej fusebitami częstotliwości taktowania mikrokontrolera. Kolejne piny portu A łączymy z kolejnymi pinami segmentów na złączu LED_DISP, czyli piny 0 6 portu z pinami A G złącza LED_DISP i pin 7 z pinem oznaczonym kropką. Z kolei piny 0 3 portu B łączymy z pinami podpisanymi cyframi 1 4 na złączu LED-DISP. Wyświetlanie liczb Napisany przez nas program jest prostą demonstracją sterowania multipleksowego wyświetlaczem LED. Jeśli chcielibyśmy wykorzystać go np. do napisania zegara, konieczna będzie jego rozbudowa o funkcje do wygodnego wyświetlania pojedynczych cyfr oraz całych liczb. Teraz w naszym przykładzie, aby wyświetlić cyfrę 3, ustawiliśmy bezpośrednio określone bity tak, aby odpowiadające im segmenty ułożone były w kształt cyfry 3. Aby ułatwić sobie życie i nie musieć wgłębiać się w układanie segmentów, możemy skorzystać ze sposobu z lekcji 2, czyli tablicy zawierającej definicje segmentów dla wszystkich 10 cyfr. Przypomnijmy jak wyglądała ta tablica: const uint8_t segments[10] = 0b , 0b , 0b , 0b , 0b , 0b , 0b , 0b , 0b , 0b ; Za jej pomocą wyświetlenie cyfry 3 na drugim wyświetlaczu możemy zrealizować w wygodniejszy sposób: dispdigits[1] = segments[3]; Wyświetlacze 7-segmentowe mają ograniczone możliwości prezentowania symboli innych niż cyfry. Mimo to da się wyświetlić m.in. takie znaki jak kropka, minus, podkreślenie czy niektóre litery: A, b, c, C, d, E, F, h, H, J, L, Ł, n, o, P, q, r, S, u, U, y. Dla pozostałych liter trudno jest znaleźć takie układy segmentów, które byłyby wystarczająco czytelne oraz nie myliłyby się z cyframi (np. l, I, 1). W każdym razie naszą 10-elementową tablicę możemy rozszerzyć o potrzebne nam symbole. Dodajmy np. minus oraz kropkę, dopisując na końcu, przed nawiasem zamykającym, dwie linijki: 0b , 0b Ponieważ tablica będzie miała teraz 12 elementów, w jej deklaracji trzeba zmienić rozmiar z 10 na 12 lub po prostu nawiasy kwadratowe zostawić puste. Symbol minus otrzymał indeks 10, a kropka 11. Aby nie musieć pamiętać indeksów, możemy stworzyć makra: #define LED_MINUS 10 #define LED_DOT 11 Załóżmy, że chcemy wyświetlić liczbę 2,5. Zrobimy to w następujący sposób: dispdigits[3] = segments[led_minus]; dispdigits[2] = segments[2]; dispdigits[1] = segments[led_dot]; dispdigits[0] = segments[5]; W ten sposób wyświetlona liczba nie wygląda jednak zbyt dobrze, bo jest duży odstęp między dwójką a kropką. Byłoby estetyczniej, gdyby włączona była kropka na tym samym wyświetlaczu co dwójka, a nie w kolejnym. Trzeba więc w danym wyświetlaczu włączyć segmenty zarówno od dwójki, jak i od kropki: dispdigits[3] = 0; dispdigits[2] = segments[led_minus]; dispdigits[1] = segments[2] segments[led_dot]; dispdigits[0] = segments[5]; W ten sposób skrajny lewy wyświetlacz jest wygaszony, na drugim wyświetlaczu jest minus, na trzecim dwójka wraz z kropką, a na czwartym cyfra 5. Mamy opanowane wyświetlanie symboli na poszczególnych wyświetlaczach, nadal jednak nie mamy prostego sposobu na wygodne wyświetlanie całych liczb ze zmiennych typu int czy float. Z pomocą przyjść może znana już nam funkcja sprintf(), dzięki której liczbę możemy zmienić na ciąg znaków. Na podstawie uzyskanych znaków możemy następnie włączać odpowiednie segmenty wyświetlaczy. Na listingu 3 znajduje się przykładowa implementacja funkcji wyświetlającej liczby. Funkcja leddispnumber() przyjmuje trzy parametry: liczbę do wyświetlenia, format oraz przesunięcie mówiące, od którego miejsca od lewej ma się rozpocząć wyświetlanie. Jako liczbę do wyświetlenia przekazujemy float, ale może być to też typ całkowity, konwersja odbędzie się automatycznie. Format to ciąg znaków określający, jak ma wyglądać liczba, np. ile ma mieć pozycji po przecinku. Zasady tworzenia tych ciągów poznaliśmy w lekcji 6. Dla wyświetlacza LED najbardziej przydatny będzie ciąg %g. Dla liczb całkowitych zachowuje się jak %d, zwracając ewentualny znak minus oraz cyfry części całkowitej. Dla liczb ułamkowych dodaje też kropkę dziesiętną i cyfry części ułamkowej (tabela 1). Parametr shift wynoszący zero oznacza wyświetlanie od pierwszego wyświetlacza z lewej strony na płytce testowej, czyli od DISP4. Ponieważ w naszym kodzie wyświetlacze numerowane są od zera od prawej strony, aby uzyskać numer początkowego wyświetlacza, parametr shift odejmowany jest od liczby 3. Przekazana liczba jest konwertowana na ciąg znaków za pomocą funkcji snprintf(), która działa jak sprintf(), ale pobiera rozmiar tablicy wynikowej, co pozwala uniknąć jej przepełnienia. Ponieważ mamy 4 wyświetlacze, razem z kropką możemy przetworzyć 5 znaków. Tablica buff deklarowana jest jako 6-elementowa ze względu na zero kończące ciąg. Główna część naszej funkcji to pętla iterująca po kolejnych znakach ciągu. Jeśli znak jest cyfrą, wyświetlamy go 26 Elektronika dla Wszystkich
3 Tabela 1 void ledinit() TCCR0 = _BV(CS01); // Timer0 CLK/8 Listing 4 DDRA = 0xff; DDRB = _BV(PB3) _BV(PB2) _BV(PB1) _BV(PB0); Listing 5 TCCR0 = _BV(CS01); // Timer0 CLK/8 LED_SEG_DDR = 0xff; LED_DISP_DDR = _BV(LED_DISP4_PIN) _BV(LED_DISP3_PIN) _BV(LED_DISP2_PIN) _BV(LED_DISP1_PIN); na bieżącym wyświetlaczu. W tym celu z tablicy segments wybierany jest układ segmentów danej cyfry i wpisywany do tablicy dispdigits pod indeksem bieżącego wyświetlacza. Od znaku (jego kodu ASCII) odejmowany jest kod ASCII cyfry 0, aby w ten sposób skonwertować cyfrę (znak) na liczbę 0 9. Jeśli znak nie był cyfrą, ale znakiem minus, włączany jest odpowiedni segment. Natomiast w przypadku kropki włączany jest segment kropki poprzedniego wyświetlacza (mającego wyższy numer, stąd dispnum + 1). Jeśli wyświetlony znak nie był kropką i nie był to ostatni wyświetlacz, przechodzimy do następnego, dekrementując zmienną dispnum. Jak używać naszej funkcji? Nie jest to trudne: leddispnumber(-2.5, "%g", 0); Powyższa przykładowa linijka spowoduje wyświetlenie liczby 2,5, począwszy od pierwszego (lewego) wyświetlacza. Na pierwszym wyświetlaczu będzie minus, na drugim dwójka z kropką, na trzecim piątka, a ostatni będzie pusty. Jeśli trzecim parametrem będzie 1, a nie 0, cała liczba zostanie przesunięta w prawo i będzie zaczynać się od drugiego wyświetlacza. Rys. 1 Rys. 2 Tak przynajmniej jest w teorii. Kompilujemy kod, programujemy mikrokontroler i nic. Program działa, bo miga LED, ale wyświetlacz jest pusty. Co może być nie tak? Nasza funkcja opiera się na wywołaniu funkcji snprintf(), może tutaj jest coś nie tak? Korzystając z JTAG-a ustawiamy punkt przerwania (breakpoint) na wywołaniu tej funkcji i uruchamiamy program. Gdy wykonanie zatrzyma się na punkcie przerwania, sprawdzamy parametry format i num. Okazują się one w porządku. Z kolei przekazywana tablica buff ma odpowiedni rozmiar. Naciskamy F10, aby funkcja snprintf() się wykonała i aby program zatrzymał się na następnej linijce. Zaglądamy do tablicy buff (rysunek 1). W pierwszym jej elemencie jest wartość 63 (kod ASCII znaku zapytania), potem zera i inne wartości. Jako że zero kończy ciąg, buff przechowuje de facto jednoznakowy napis?. Co mogliśmy zrobić źle? snprintf() nie powinien zwracać czegoś takiego. Otóż problem wcale nie leży w naszym kodzie. Nie działa on, ponieważ domyślnie linkowane biblioteki nie zawierają funkcji obsługujących liczby zmiennoprzecinkowe. W związku z tym musimy zmienić ustawienia linkera. Wchodzimy w tym celu do właściwości naszego projektu, do sekcji Toolchain -> AVR/GNU Linker -> Miscellaneous (rysunek 2). Mamy tam pole, do którego możemy wpisać dodatkowe parametry dla linkera. Wpisujemy: -Wl,-u,vfprintf -lprintf_flt Kompilujemy kod, programujemy mikrokontroler i tym razem wszystko działa poprawnie, liczba jest widoczna na wyświetlaczu. O dodaniu tych parametrów trzeba pamiętać także przy wykorzystaniu snprintf() czy printf() do obsługi LCD, gdy wyświetlane mają być liczby zmiennoprzecinkowe. Biblioteka wyświetlacza LED Zanim przejdziemy dalej, wydzielmy nasz kod obsługujący wyświetlacz LED do oddzielnego pliku. Zyskamy porządek i większą kontrolę nad kodem. W tym celu stwórzmy plik led.c oraz plik nagłówkowy led.h. Do pliku led.c przenieśmy funkcje leddispnumber() oraz ISR(TIMER0_OVF_vect). Dobrze byłoby też stworzyć funkcję inicjalizującą nasz sterownik wyświetlacza LED. Umieścimy tam konfigurację timera, inicjalizację przer wania oraz konfigurację wykorzystywanych pinów. W pierwszym podejściu funkcja inicjalizująca może wyglądać jak na listingu 4. Dobrze byłoby jednak, aby można było łatwo zmieniać porty, do których podłączony jest wyświetlacz, tak jak było to w przypadku LCD i klawiatury. Stwórzmy więc odpowiednie makra, analogicznie jak wtedy: #define LED_DISP_PORT PORTB #define LED_SEG_PORT PORTA #define LED_DISP_DDR DDRB #define LED_SEG_DDR DDRA #define LED_DISP1_PIN PB0 #define LED_DISP2_PIN PB1 #define LED_DISP3_PIN PB2 #define LED_DISP4_PIN PB3 W ten sposób możemy przepisać naszą funkcję inicjalizacyjną, jak na listingu 5. A co z resztą biblioteki? Odwołania do portów mamy jeszcze w funkcji obsługi przerwania. Nasze makra się tam nie przydadzą, bo obecnie funkcja ta zakłada, że sterowane będą cztery młodsze piny portu, a nie dowolne. Co prawda zdefiniowaliśmy makra pinów jako PB0, PB1, PB2 i PB3, ale to tylko przykład. Moglibyśmy potrzebować wykorzystać np. PB2, PB4, PB6 i PB7. Co wtedy? Do przepisania mamy dwie linijki: PORTB = 0x0f; PORTB &= ~_BV(dispNum); Pierwsza wyłącza wszystkie wyświetlacze, a druga włącza wyświetlacz bieżący. Wyłączenie wyświetlaczy to wpisanie jedynek na sterujących nimi pinach, jest więc proste: LED_DISP_PORT = _BV(LED_DISP4_PIN) _BV(LED_DISP3_PIN) _BV(LED_DISP2_PIN) _BV(LED_DISP1_PIN); Z drugą linijką jest gorzej, ponieważ nie możemy zakładać, że numer pinu będzie taki sam jak numer wyświetlacza przechowywany w zmiennej dispnum. Potrzebujemy więc tablicy, która zmapuje nam numer wyświetlacza na numer pinu: const uint8_t disppin[] = LED_DISP1_PIN, LED_DISP2_PIN, LED_DISP3_PIN, LED_DISP4_PIN; Dzięki temu aktywację wyświetlacza możemy zapisać w ten sposób: LED_DISP_PORT &= ~_BV(dispPin[dispNum]); Elektronika dla Wszystkich 27
4 Z kolei modyfikacja w linijce sterującej segmentami będzie już tylko prostym podstawieniem makra w miejsce konkretnego portu: LED_SEG_PORT = ~dispdigits[dispnum]; To, co nam pozostało do przeniesienia do biblioteki, to deklaracje tablic dispdigits oraz segments, a także definicje makr LED_MINUS i LED_DOT. Deklaracje tablic umieszczamy w led.c, deklaracje makr w led.h. W led.h powinny się też znaleźć nagłówki funkcji ledinit() i led- DispNumber(). Na początku pliku led.c trzeba też umieścić dyrektywy #include dołączające potrzebne pliki nagłówkowe: #include <stdio.h> #include <string.h> Nasza biblioteka jest już gotowa do użytku. Możemy ją przetestować za pomocą poniższego pliku main.c: ledinit(); DDRB = _BV(PB6); leddispnumber(-3, "%g", 1); while (1) PORTB = _BV(PB6); PORTB &= ~_BV(PB6); Widoczność tablicy sterującej wyświetlaczem W powyższym przykładzie wykorzystaliśmy funkcję leddispnumber() do wyświetlenia liczby. Co się jednak stało z bezpośrednim sterowaniem segmentami wyświetlaczy? Czy możemy odwołać się do tablicy dispdigits z poziomu pliku main.c? Spróbujmy np. wyświetlić minus na drugiej pozycji, umieszczając poniższą linijkę przed pętlą while: dispdigits[1] = segments[led_minus]; Niestety otrzymamy błąd: Error 'dispdigits' undeclared (first use in this function) Wyświetlony będzie też taki sam błąd w stosunku do tablicy segments. Nie mamy bowiem deklaracji tablic dispdigits i segments w pliku main.c, są one zadeklarowane w led.c. Umieśćmy więc w main.c, pod dyrektywami #include następujące deklaracje: extern uint8_t dispdigits[4]; extern const uint8_t segments[]; Sprawdźmy program kompiluje się poprawnie. Rozwiązaliśmy więc problem, ale czy na pewno nasz program ma właściwą strukturę? Dobre praktyki mówią, że sterownik/ biblioteka nie powinien dawać dostępu do swoich wewnętrznych struktur. Nasz kod jest stosunkowo prosty i ta zasada może się wydawać pozbawiona sensu. Jednak przy bardziej rozbudowanych projektach pozwala zabezpieczyć się przed przypadkowym zmodyfikowaniem pamięci używanej przez bibliotekę w sposób, który uniemożliwi lub zakłóci jej prawidłowe działanie. Wprowadza też większy porządek w kodzie. Ponadto zauważmy, że bezpośrednie pisanie do tablicy dispdigits nie jest zbyt wygodne, gdyż wymaga odwoływania się do tablicy segments. Użytkownik biblioteki obsługującej wyświetlacz zainteresowany jest tym, jaki symbol chce wyświetlić, zwykle cyfrę, oraz na której pozycji. Dopóki nie będzie chciał definiować nowych symboli (układów segmentów), nie powinien mieć konieczności odwoływania się do tablicy segments. Z wyżej wymienionych powodów tablice dispdigits oraz segments powinny być schowane wewnątrz biblioteki i nie być dostępne na zewnątrz. Dobrze jest nawet ich deklaracje poprzedzić słowem kluczowym static, dzięki temu przestaną być widoczne w main.c, nawet jeśli umieścimy tam ich deklaracje ze słowem kluczowym extern. Natomiast aby była możliwość wyświetlania pojedynczych symboli, zdefiniujemy funkcje jak na listingu 6: Pierwsza z nich służy do wyświetlania symboli zdefiniowanych w tablicy symbols. Za pomocą instrukcji if sprawdzane jest, czy przekazane parametry nie mają przypadkiem zbyt dużych wartości. W przeciwnym wypadku przekroczony zostałby zakres tablic i program odwołałby się do przypadkowego miejsca w pamięci. Druga funkcja pozwala włączyć dowolne symbole na wybranej pozycji wyświetlacza. Popatrzmy na przykładowy program: ledinit(); leddispnumber(-5, "%g", 1); leddispsymbol(led_minus, 3); while (1) leddispraw(0b , 0); leddispraw(0b , 0); leddispraw(0b , 0); leddispraw(0b , 0); void leddispsymbol(uint8_t symbol, uint8_t position) if (symbol < sizeof(segments) && position < sizeof(dispdigits)) dispdigits[position] = segments[symbol]; Listing 6 void leddispraw(uint8_t seg, uint8_t position) if (position < sizeof(dispdigits)) dispdigits[position] = seg; Tutaj zamiast migającej diody w głównej pętli wyświetlana jest prosta animacja na pierwszym wyświetlaczu od prawej, mająca postać biegającej dookoła kreski. Na wyświetlaczach 3 i 4 od prawej wyświetlane są minusy, a na wyświetlaczu drugim cyfra 5. Brakuje nam jeszcze funkcji czyszczącej wyświetlacz. Możemy ją zrealizować następująco: void ledclear() memset(dispdigits, 0, sizeof(dispdigits)); Wykorzystana została tutaj funkcja memset() z biblioteki stdio.h. Tablicę wskazaną w pierwszym parametrze wypełnia ona wartością wskazaną w parametrze drugim. Czyli tablica dispdigits zostanie wypełniona zerami. Ostatni parametr to rozmiar obszaru do wypełnienia. Ponieważ wyzerować chcemy całą tablicę, podajemy jej rozmiar pobierany operatorem sizeof. int readnumber(uint8_t position, uint8_t maxlength) // walidacja parametrów if (position > 3) position = 3; if (maxlength > 4) maxlength = 4; if (position + maxlength > 4) maxlength = 4 - position; uint8_t dispnum = 3 - position; char input[5]; uint8_t inputindex = 0; uint8_t lastdigit = 0; while(1) uint8_t key = 0; key = getkey(); if (key == 15) // obsługa Backspace if (inputindex > 0) if (lastdigit) leddispraw(0, dispnum); lastdigit = 0; else inputindex--; leddispraw(0, ++dispnum); continue; if (key < 10) input[inputindex] = '0' + key; if (key == 10) input[inputindex] = '0'; if (key == 16) input[inputindex + 1] = 0; break; // wyświetl cyfrę leddispsymbol(key < 10? key : 0, dispnum); // dla cyfr przed limitem długości if (inputindex < maxlength - 1) inputindex++; if (dispnum > 0) dispnum--; else // dla ostatniej cyfry lastdigit = 1; return atoi(input); Listing 7 28 Elektronika dla Wszystkich
5 Wpisywanie liczb Tak jak w przypadku LCD, tak i teraz chcielibyśmy mieć możliwość wpisywania liczb z klawiatury z jednoczesnym ich wyświetlaniem. Posłużymy się tutaj funkcją readnumber(), którą napisaliśmy dla LCD. Na listingu 7 przykładowa modyfikacja dla wyświetlacza LED: Funkcja jest dosyć długa, ale jej analiza nie powinna być trudna, szczególnie po zapoznaniu się z lekcjami 6 i 7. Do funkcji przekazywane są dwa parametry: position oraz maxlength. Pierwszy mówi, od którego wyświetlacza ma się rozpocząć wyświetlanie wpisywanej liczby. Jest to przydatne, gdybyśmy chcieli wpisać obok siebie dwie różne liczby, np. godzinę i minutę. Drugi parametr to maksymalna liczba cyfr. Przykładowo jeśli jako max- Length podamy 2, użytkownik będzie mógł wpisać liczbę maksymalnie dwucyfrową. W pierwszych trzech linijkach sprawdzamy, czy przekazane parametry nie są zbyt duże i jeśli tak, zostają odpowiednio zmniejszone. W głównej pętli wczytywany jest klawisz i sprawdzany jest jego numer. Dla numerów klawiszy poniżej 10 zapamiętywany jest ich numer jako cyfra w tablicy znakowej input. Klawisz 10 powoduje zapamiętanie cyfry 0. Ostatni klawisz, noszący numer 16, działa jako Enter i powoduje wyjście z pętli. Klawisz przedostatni, z numerem 15, działa jak Backspace. Rozróżnia on dwa przypadki, zależnie od tego, czy użytkownik wpisał już wszystkie cyfry, jakie mógł wpisać, np. dwie cyfry liczby dwucyfrowej. W obu przypadkach zostanie wyczyszczona ostatnia wpisana cyfra i dla użytkownika wygląda to tak samo, jednak w kodzie jest to obsługiwane różnie z uwagi na to, że po wpisaniu ostatniej cyfry przestaje zwiększać się zmienna inputindex wskazująca na aktualne miejsce w tablicy input oraz przestaje zmniejszać się zmienna aktualnego wyświetlacza. Wykorzystywana jest tutaj zmienna pomocnicza lastdigit, ustawiana na 1, gdy użytkownik wpisał ostatnią cyfrę. Wpisane cyfry są wyświetlane funkcją leddispsymbol(). Pobierany jest tutaj bezpośrednio numer klawisza z wyjątkiem klawisza 10, dla którego wyświetlane jest 0. Został tutaj użyty operator warunkowy. Sprawdza on, czy wyrażenie przed znakiem zapytania jest prawdą. Jeśli tak, zwraca to, co jest przed dwukropkiem (wartość zmiennej key), w przeciwnym razie zwraca to, co jest po dwukropku (liczbę zero). Jeśli użytkownik wpisał cyfrę, a nie była to ostatnia cyfra, zwiększany jest licznik cyfr. Jeśli wpisał ostatnią, ustawiana jest zmienna lastdigit dla obsługi Backspace. Wartość końcowa obliczana jest funkcją atoi(), która tworzy liczbę na podstawie wpisanych cyfr (znaków). Przykładowe wywołanie funkcji readnumber(): int n = readnumber(2, 2); Wczytana zostanie liczba dwucyfrowa, przy czym wpisywane cyfry pojawią się na 3. i 4. pozycji od lewej. W materiałach dodatkowych znajduje się kompletny projekt zawierający obsługę wyświetlacza LED oraz klawiatury z funkcją wyświetlania cyfr podczas wpisywania liczb. Zadania Jak zwykle zachęcam do pisania jak największej liczby własnych programów, choćby najprostszych. Aby przećwiczyć wiadomości z tego odcinka, proponuję napisać: 1. Zegar wyświetlający godziny i minuty, z możliwością ustawienia czasu 2. Zegar z migającą kropką na drugim wyświetlaczu od lewej, oddzielającą godziny od minut 3. Kostkę do gry gdy wciśnięty jest przycisk, program bardzo szybko odliczać liczby 1 6, po puszczeniu przycisku odliczanie jest przerywane i wyświetlana jest ostatnia wylosowana w ten sposób liczba Grzegorz Niemirowski grzegorz@grzegorz.net Extern dla dociekliwych W jednym z przykładów użyliśmy słowa kluczowego extern. Jaka jest dokładnie jego rola? Otóż tworzenie wynikowego kodu wykonywalnego, który wpisujemy do pamięci Flash mikrokontrolera, składa się z trzech głównych etapów: przetwarzania kodu źródłowego przez preprocesor, kompilacji oraz linkowania. Często potocznie kompilacją nazywa się cały proces, ale lepiej mówić o budowaniu. Stąd w Atmel Studio mamy menu oraz polecenia Build. Kompilacja to tłumaczenie kodu źródłowego na kod wykonywalny, przy czym odbywa się ona plik po pliku. Kompilator, przetwarzając dany plik, musi znać podstawowe dane o wszystkich występujących w nim symbolach, bo nie wie o innych plikach, chyba że są to pliki.h, które dołączyliśmy dyrektywą #include. Stosując słowo kluczowe extern, przekazujemy właśnie tylko te niektóre informacje, m.in. o typie zmiennej. Natomiast jej zawartość początkowa i ewentualnie rozmiar będą określone w innym pliku. Przy kompilacji tamtego pliku kompilator zadba o dodanie kodu rezerwującego pamięć dla tej zmiennej oraz inicjującego jej wartość. Nie możemy w jednym pliku napisać int a = 5; a w drugim extern int a = 5; ponieważ kod inicjalizujący zmienną może być tylko jeden. Z punktu widzenia architektury kodu extern oznacza chcę użyć zmiennej globalnej zdefiniowanej w innym pliku. Natomiast z punktu widzenia zarządzania pamięcią oznacza nie chcę używać nowego obszaru pamięci, ale odwołać się do obszaru zajmowanego przez zmienną zdefiniowaną w innym pliku. Tak więc extern nie tworzy nowej zmiennej i przy kompilacji danego pliku nie są tworzone odwołania do odpowiedniego miejsca w pamięci. Te odwołania zostaną uzupełnione na etapie linkowania, gdy linker będzie miał już skompilowane wszystkie pliki i będzie je łączył w jedną całość. Należy pamiętać, że extern jest niejako domyślne. Jeśli w dwóch plikach będą zadeklarowane zmienne globalne o tych samych nazwach, to będzie to jedna, wspólna zmienna. Aby zmienne te były niezależne, trzeba nadać im różne nazwy lub użyć słowa kluczowego static. Dlatego jeśli deklarujemy zmienną globalną, która ma być używana tylko w jednym pliku, zadeklarujmy ją jako static. Uchroni nas to przed przypadkowym odwołaniem do niej z innego pliku. Natomiast jeśli ma być dostępna z innych plików, to w tych plikach zadeklarujmy ją jako extern, pozostawiając ją bez extern i bez static w jej głównym pliku. Przedstawione informacje tyczą się zmiennych globalnych, niezwiązanych z żadną funkcją, deklarowanych zwykle na początku pliku.c. Zaś słowo kluczowe static dla zmiennej wewnątrz funkcji oznacza, że jej wartość jest zapamiętywana pomiędzy wywołaniami funkcji. Wynika to z tego, że umieszczona jest w tym samym obszarze co zmienne globalne, które żyją przez cały czas działania programu. Widoczna jest jednak tylko w swojej funkcji, nie jest globalna. Elektronika dla Wszystkich 29
Cwiczenie nr 1 Pierwszy program w języku C na mikrokontroler AVR
Cwiczenie nr 1 Pierwszy program w języku C na mikrokontroler AVR Zadanie polega na napisaniu pierwszego programu w języku C, jego poprawnej kompilacji i wgraniu na mikrokontroler. W tym celu należy zapoznać
1 Podstawy c++ w pigułce.
1 Podstawy c++ w pigułce. 1.1 Struktura dokumentu. Kod programu c++ jest zwykłym tekstem napisanym w dowolnym edytorze. Plikowi takiemu nadaje się zwykle rozszerzenie.cpp i kompiluje za pomocą kompilatora,
METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02
METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE Wykład 02 NAJPROSTSZY PROGRAM /* (Prawie) najprostszy przykład programu w C */ /*==================*/ /* Między tymi znaczkami można pisać, co się
Poradnik programowania procesorów AVR na przykładzie ATMEGA8
Poradnik programowania procesorów AVR na przykładzie ATMEGA8 Wersja 1.0 Tomasz Pachołek 2017-13-03 Opracowanie zawiera opis podstawowych procedur, funkcji, operatorów w języku C dla mikrokontrolerów AVR
Instytut Teleinformatyki
Instytut Teleinformatyki Wydział Fizyki, Matematyki i Informatyki Politechnika Krakowska Mikroprocesory i Mikrokontrolery Dostęp do portów mikrokontrolera ATmega32 język C laboratorium: 10 autorzy: dr
Programowanie strukturalne i obiektowe
Programowanie strukturalne i obiektowe Język C część I Opracował: Grzegorz Flesik Literatura: A. Majczak, Programowanie strukturalne i obiektowe, Helion, Gliwice 2010 P. Domka, M. Łokińska, Programowanie
Wskaźniki a tablice Wskaźniki i tablice są ze sobą w języku C++ ściśle związane. Aby się o tym przekonać wykonajmy cwiczenie.
Część XXII C++ w Wskaźniki a tablice Wskaźniki i tablice są ze sobą w języku C++ ściśle związane. Aby się o tym przekonać wykonajmy cwiczenie. Ćwiczenie 1 1. Utwórz nowy projekt w Dev C++ i zapisz go na
Podstawy programowania skrót z wykładów:
Podstawy programowania skrót z wykładów: // komentarz jednowierszowy. /* */ komentarz wielowierszowy. # include dyrektywa preprocesora, załączająca biblioteki (pliki nagłówkowe). using namespace
1 Podstawy c++ w pigułce.
1 Podstawy c++ w pigułce. 1.1 Struktura dokumentu. Kod programu c++ jest zwykłym tekstem napisanym w dowolnym edytorze. Plikowi takiemu nadaje się zwykle rozszerzenie.cpp i kompiluje za pomocą kompilatora,
Tablice (jedno i wielowymiarowe), łańcuchy znaków
Tablice (jedno i wielowymiarowe), łańcuchy znaków wer. 8 z drobnymi modyfikacjami! Wojciech Myszka Katedra Mechaniki i Inżynierii Materiałowej 2017-04-07 09:35:32 +0200 Zmienne Przypomnienie/podsumowanie
Systemy wbudowane. Uniwersytet Łódzki Wydział Fizyki i Informatyki Stosowanej. Witold Kozłowski
Uniwersytet Łódzki Wydział Fizyki i Informatyki Stosowanej Systemy wbudowane Witold Kozłowski Zakład Fizyki i Technologii Struktur Nanometrowych 90-236 Łódź, Pomorska 149/153 https://std2.phys.uni.lodz.pl/mikroprocesory/
Pętle i tablice. Spotkanie 3. Pętle: for, while, do while. Tablice. Przykłady
Pętle i tablice. Spotkanie 3 Dr inż. Dariusz JĘDRZEJCZYK Pętle: for, while, do while Tablice Przykłady 11/26/2016 AGH, Katedra Informatyki Stosowanej i Modelowania 2 Pętla w największym uproszczeniu służy
znajdowały się różne instrukcje) to tak naprawdę definicja funkcji main.
Część XVI C++ Funkcje Jeśli nasz program rozrósł się już do kilkudziesięciu linijek, warto pomyśleć o jego podziale na mniejsze części. Poznajmy więc funkcje. Szybko się przekonamy, że funkcja to bardzo
Programowanie w języku Python. Grażyna Koba
Programowanie w języku Python Grażyna Koba Kilka definicji Program komputerowy to ciąg instrukcji języka programowania, realizujący dany algorytm. Język programowania to zbiór określonych instrukcji i
Pętle. Dodał Administrator niedziela, 14 marzec :27
Pętlami nazywamy konstrukcje języka, które pozwalają na wielokrotne wykonywanie powtarzających się instrukcji. Przykładowo, jeśli trzeba 10 razy wyświetlić na ekranie pewien napis, to można wykorzystać
Programowanie mikrokontrolerów AVR z rodziny ATmega.
Programowanie mikrokontrolerów AVR z rodziny ATmega. Materiały pomocnicze Jakub Malewicz jakub.malewicz@pwr.wroc.pl Wszelkie prawa zastrzeżone. Kopiowanie w całości lub w częściach bez zgody i wiedzy autora
Stałe, znaki, łańcuchy znaków, wejście i wyjście sformatowane
Stałe, znaki, łańcuchy znaków, wejście i wyjście sformatowane Stałe Oprócz zmiennych w programie mamy też stałe, które jak sama nazwa mówi, zachowują swoją wartość przez cały czas działania programu. Można
Zmienne, stałe i operatory
Zmienne, stałe i operatory Przemysław Gawroński D-10, p. 234 Wykład 2 4 marca 2019 (Wykład 2) Zmienne, stałe i operatory 4 marca 2019 1 / 21 Outline 1 Zmienne 2 Stałe 3 Operatory (Wykład 2) Zmienne, stałe
Niezwykłe tablice Poznane typy danych pozwalają przechowywać pojedyncze liczby. Dzięki tablicom zgromadzimy wiele wartości w jednym miejscu.
Część XIX C++ w Każda poznana do tej pory zmienna może przechowywać jedną liczbę. Jeśli zaczniemy pisać bardziej rozbudowane programy, okaże się to niewystarczające. Warto więc poznać zmienne, które mogą
Podstawy techniki mikroprocesorowej
Podstawy techniki mikroprocesorowej Temat 2 Obsługa wyświetlaczy v.1.0 Uniwersytet Pedagogiczny, Instytut Techniki Dominik Rzepka, dominik.rzepka@agh.edu.pl, 2014 1. Obsługa pinów mikroprocesora i wyświetlacze
Wstęp do programowania INP003203L rok akademicki 2018/19 semestr zimowy. Laboratorium 2. Karol Tarnowski A-1 p.
Wstęp do programowania INP003203L rok akademicki 2018/19 semestr zimowy Laboratorium 2 Karol Tarnowski karol.tarnowski@pwr.edu.pl A-1 p. 411B Plan prezentacji Komentarze Funkcja printf() Zmienne Łańcuchy
JĘZYKI PROGRAMOWANIA Z PROGRAMOWANIEM OBIEKTOWYM. Wykład 6
JĘZYKI PROGRAMOWANIA Z PROGRAMOWANIEM OBIEKTOWYM Wykład 6 1 SPECYFIKATOR static Specyfikator static: Specyfikator ten powoduje, że zmienna lokalna definiowana w obrębie danej funkcji nie jest niszczona
Wprowadzenie do podstaw programowania AVR (na przykładzie mikrokontrolera ATmega 16 / 32)
Wprowadzenie do podstaw programowania AVR (na przykładzie mikrokontrolera ATmega 16 / 32) wersja 0.4 (20 kwietnia 2015) Filip A. Sala W niniejszym, bardzo krótkim opracowaniu, postaram się przedstawić
Widoczność zmiennych Czy wartości każdej zmiennej można zmieniać w dowolnym miejscu kodu? Czy można zadeklarować dwie zmienne o takich samych nazwach?
Część XVIII C++ Funkcje Widoczność zmiennych Czy wartości każdej zmiennej można zmieniać w dowolnym miejscu kodu? Czy można zadeklarować dwie zmienne o takich samych nazwach? Umiemy już podzielić nasz
Podstawy Programowania Podstawowa składnia języka C++
Podstawy Programowania Podstawowa składnia języka C++ Katedra Analizy Nieliniowej, WMiI UŁ Łódź, 3 października 2013 r. Szablon programu w C++ Najprostszy program w C++ ma postać: #include #include
Po uruchomieniu programu nasza litera zostanie wyświetlona na ekranie
Część X C++ Typ znakowy służy do reprezentacji pojedynczych znaków ASCII, czyli liter, cyfr, znaków przestankowych i innych specjalnych znaków widocznych na naszej klawiaturze (oraz wielu innych, których
Mikrokontroler ATmega32. Język symboliczny
Mikrokontroler ATmega32 Język symboliczny 1 Język symboliczny (asembler) jest językiem niskiego poziomu - pozwala pisać programy złożone z instrukcji procesora. Kody instrukcji są reprezentowane nazwami
1. Pierwszy program. Kompilator ignoruje komentarze; zadaniem komentarza jest bowiem wyjaśnienie programu człowiekowi.
1. Pierwszy program // mój pierwszy program w C++ #include using namespace std; cout
2 Przygotował: mgr inż. Maciej Lasota
Laboratorium nr 2 1/7 Język C Instrukcja laboratoryjna Temat: Wprowadzenie do języka C 2 Przygotował: mgr inż. Maciej Lasota 1) Wprowadzenie do języka C. Język C jest językiem programowania ogólnego zastosowania
TECHNIKA MIKROPROCESOROWA II
Akademia Górniczo Hutnicza im. Stanisława Staszica w Krakowie Wydział IEiT Katedra Elektroniki TECHNIKA MIKROPROCESOROWA II LAB 2 Human-Machine Interface, czyli obsługa wyświetlacza slcd Sebastian Koryciak
Nazwa implementacji: Nauka języka Python wyrażenia warunkowe. Autor: Piotr Fiorek. Opis implementacji: Poznanie wyrażeń warunkowych if elif - else.
Nazwa implementacji: Nauka języka Python wyrażenia warunkowe Autor: Piotr Fiorek Opis implementacji: Poznanie wyrażeń warunkowych if elif - else. Nasz kalkulator umie już liczyć, ale potrafi przeprowadzać
Wykład VII. Programowanie. dr inż. Janusz Słupik. Gliwice, 2014. Wydział Matematyki Stosowanej Politechniki Śląskiej. c Copyright 2014 Janusz Słupik
Wykład VII Wydział Matematyki Stosowanej Politechniki Śląskiej Gliwice, 2014 c Copyright 2014 Janusz Słupik Kompilacja Kompilator C program do tłumaczenia kodu źródłowego na język maszynowy. Preprocesor
Podstawy programowania, Poniedziałek , 8-10 Projekt, część 1
Podstawy programowania, Poniedziałek 30.05.2016, 8-10 Projekt, część 1 1. Zadanie Projekt polega na stworzeniu logicznej gry komputerowej działającej w trybie tekstowym o nazwie Minefield. 2. Cele Celem
Współpraca mikrokontrolera z wyświetlaczami: ciekłokrystalicznym i siedmiosegmentowym
Instrukcja do ćwiczenia: Współpraca mikrokontrolera z wyświetlaczami: ciekłokrystalicznym i siedmiosegmentowym Materiał do samodzielnego opracowania: elementy języka C: typy danych i ich deklarowanie,
Jak zawsze wyjdziemy od terminologii. While oznacza dopóki, podczas gdy. Pętla while jest
Pętle Pętla to pewien fragment kodu, który jest wykonywany wielokrotnie. Wyobraź sobie taką sytuację. Piszesz program do szyfrowania danych. Dane są szyfrowane kolejno bajt po bajcie. Załóżmy, że plik
Wstęp do Programowania, laboratorium 02
Wstęp do Programowania, laboratorium 02 Zadanie 1. Napisać program pobierający dwie liczby całkowite i wypisujący na ekran największą z nich. Zadanie 2. Napisać program pobierający trzy liczby całkowite
Programowanie mikrokontrolerów AVR
Programowanie mikrokontrolerów AVR Czym jest mikrokontroler? Mikrokontroler jest małym komputerem podłączanym do układów elektronicznych. Pamięć RAM/ROM CPU wykonuje program Układy I/O Komunikacje ze światem
Systemy wbudowane. Uniwersytet Łódzki Wydział Fizyki i Informatyki Stosowanej. Witold Kozłowski
Uniwersytet Łódzki Wydział Fizyki i Informatyki Stosowanej Systemy wbudowane Witold Kozłowski Zakład Fizyki i Technologii Struktur Nanometrowych 9-236 Łódź, Pomorska 49/53 https://std2.phys.uni.lodz.pl/mikroprocesory/
Modelowanie liczników w języku Verilog i ich implementacja w strukturze FPGA
Modelowanie liczników w języku Verilog i ich implementacja w strukturze FPGA Licznik binarny Licznik binarny jest najprostszym i najpojemniejszym licznikiem. Kod 4 bitowego synchronicznego licznika binarnego
Inż. Kamil Kujawski Inż. Krzysztof Krefta. Wykład w ramach zajęć Akademia ETI
Inż. Kamil Kujawski Inż. Krzysztof Krefta Wykład w ramach zajęć Akademia ETI Metody programowania Assembler Język C BASCOM Assembler kod maszynowy Zalety: Najbardziej efektywny Intencje programisty są
Uwagi dotyczące notacji kodu! Moduły. Struktura modułu. Procedury. Opcje modułu (niektóre)
Uwagi dotyczące notacji kodu! Wyrazy drukiem prostym -- słowami języka VBA. Wyrazy drukiem pochyłym -- inne fragmenty kodu. Wyrazy w [nawiasach kwadratowych] opcjonalne fragmenty kodu (mogą być, ale nie
Warto też w tym miejscu powiedzieć, że w C zero jest rozpoznawane jako fałsz, a wszystkie pozostałe wartości jako prawda.
Nazwa implementacji: Nauka języka C wyrażenia warunkowe if- Autor: Piotr Fiorek Opis implementacji: Poznanie struktury oraz zastosowania wyrażeń warunkowych if- w języku C. W programie realizującym jakiś
Warsztaty AVR. Instalacja i konfiguracja środowiska Eclipse dla mikrokontrolerów AVR. Dariusz Wika
Warsztaty AVR Instalacja i konfiguracja środowiska Eclipse dla mikrokontrolerów AVR Dariusz Wika 1.Krótki wstęp: Eclipse to rozbudowane środowisko programistyczne, które dzięki możliwości instalowania
Tablice deklaracja, reprezentacja wewnętrzna
Tablice deklaracja, reprezentacja wewnętrzna Tablica jest zmienną złożoną z elementów tego samego typu. Obejmuje ona ciągły obszar pamięci operacyjnej dokładnie tak duży, aby zmieścić wszystkie jej elementy.
lekcja 8a Gry komputerowe MasterMind
lekcja 8a Gry komputerowe MasterMind Posiadamy już elementarną wiedzę w zakresie programowania. Pora więc zabrać się za rozwiązywanie problemów bardziej złożonych, które wymagają zastosowania typowych
Część 4 życie programu
1. Struktura programu c++ Ogólna struktura programu w C++ składa się z kilku części: część 1 część 2 część 3 część 4 #include int main(int argc, char *argv[]) /* instrukcje funkcji main */ Część
przedmiot kilka razy, wystarczy kliknąć przycisk Wyczaruj ostatni,
Baltie Zadanie 1. Budowanie W trybie Budowanie wybuduj domek jak na rysunku. Przedmioty do wybudowania domku weź z banku 0. Zadanie 2. Czarowanie sterowanie i powtarzanie W trybie Czarowanie z pomocą czarodzieja
Jak napisać program obliczający pola powierzchni różnych figur płaskich?
Część IX C++ Jak napisać program obliczający pola powierzchni różnych figur płaskich? Na początku, przed stworzeniem właściwego kodu programu zaprojektujemy naszą aplikację i stworzymy schemat blokowy
Podstawy Programowania C++
Wykład 3 - podstawowe konstrukcje Instytut Automatyki i Robotyki Warszawa, 2014 Wstęp Plan wykładu Struktura programu, instrukcja przypisania, podstawowe typy danych, zapis i odczyt danych, wyrażenia:
W dowolnym momencie można zmienić typ wskaźnika.
c++ Wskaźniki mają jeszcze jedną przydatną cechę. W dowolnym momencie można zmienić typ wskaźnika. Robi się to za pomocą operatora rzutowania. Najpierw zdefiniujemy sobie wsk_uniwersalny mogący pokazywać
Programowanie mikrokontrolerów - laboratorium
Państwowa Wyższa Szkoła Zawodowa w Nowym Sączu Instytut Techniczny Programowanie mikrokontrolerów- laboratorium Nazwisko i imię 1. 2. Data wykonania ćwiczenia: Grupa: Ocena sprawozdania Zaliczenie: Symbol:
Wstęp do programowania INP003203L rok akademicki 2018/19 semestr zimowy. Laboratorium 3. Karol Tarnowski A-1 p.
Wstęp do programowania INP003203L rok akademicki 2018/19 semestr zimowy Laboratorium 3 Karol Tarnowski karol.tarnowski@pwr.edu.pl A-1 p. 411B Plan prezentacji Dyrektywy preprocesora #include #define Interakcja
Ćwiczenie 2. Siedmiosegmentowy wyświetlacz LED
Ćwiczenie 2 Siedmiosegmentowy wyświetlacz LED 2-1. Cel ćwiczenia Celem ćwiczenia jest zapoznanie się studentów ze sposobem obsługi wielopozycyjnego 7-segmentowego wyświetlacza LED multipleksowanego programowo
Wskaźniki w C. Anna Gogolińska
Wskaźniki w C Anna Gogolińska Zmienne Zmienną w C można traktować jako obszar w pamięci etykietowany nazwą zmiennej i zawierający jej wartość. Przykład: kod graficznie int a; a a = 3; a 3 Wskaźniki Wskaźnik
PROE wykład 2 operacje na wskaźnikach. dr inż. Jacek Naruniec
PROE wykład 2 operacje na wskaźnikach dr inż. Jacek Naruniec Zmienne automatyczne i dynamiczne Zmienne automatyczne: dotyczą kontekstu, po jego opuszczeniu są usuwane, łatwiejsze w zarządzaniu od zmiennych
Języki i metodyka programowania. Typy, operatory, wyrażenia. Wejście i wyjście.
Typy, operatory, wyrażenia. Wejście i wyjście. Typy, operatory, wyrażenia Zmienna: [] [ '[' ']' ] ['=' ]; Zmienna to fragment pamięci o określonym
Wiadomości wstępne Środowisko programistyczne Najważniejsze różnice C/C++ vs Java
Wiadomości wstępne Środowisko programistyczne Najważniejsze różnice C/C++ vs Java Cechy C++ Język ogólnego przeznaczenia Można programować obiektowo i strukturalnie Bardzo wysoka wydajność kodu wynikowego
Temat 1: Podstawowe pojęcia: program, kompilacja, kod
Temat 1: Podstawowe pojęcia: program, kompilacja, kod wynikowy. Przykłady najprostszych programów. Definiowanie zmiennych. Typy proste. Operatory: arytmetyczne, przypisania, inkrementacji, dekrementacji,
PRUS. projekt dokumentacja końcowa
Adrian Antoniewicz Marcin Dudek Mateusz Manowiecki 17.01.2007 PRUS projekt dokumentacja końcowa Temat: Układ zdalnego sterowania (za pomocą interfejsu RS-232) wyświetlaczem LCD. Spis treści: 1. 2. 3. 4.
Programowanie w C++ Wykład 2. Katarzyna Grzelak. 4 marca K.Grzelak (Wykład 1) Programowanie w C++ 1 / 44
Programowanie w C++ Wykład 2 Katarzyna Grzelak 4 marca 2019 K.Grzelak (Wykład 1) Programowanie w C++ 1 / 44 Na poprzednim wykładzie podstawy C++ Każdy program w C++ musi mieć funkcję o nazwie main Wcięcia
Podstawy programowania w języku C i C++
Podstawy programowania w języku C i C++ Część czwarta Operatory i wyrażenia Autor Roman Simiński Kontakt roman.siminski@us.edu.pl www.us.edu.pl/~siminski Niniejsze opracowanie zawiera skrót treści wykładu,
długo. W tym celu w czasie przeczesywania if (key) {
Kurs AVR lekcja 3 Rozwiązania zadań z ostatniego odcinka Tradycyjnie odcinek zaczynamy od analizy zadania z poprzedniego numeru. Celem było wygenerowanie dźwięku o wysokości zależnej od wciśniętego przycisku.
1. Wprowadzanie danych z klawiatury funkcja scanf
1. Wprowadzanie danych z klawiatury funkcja scanf Deklaracja int scanf ( const char *format, wskaźnik, wskaźnik,... ) ; Biblioteka Działanie stdio.h Funkcja scanf wczytuje kolejne pola (ciągi znaków),
W przeciwnym wypadku wykonaj instrukcję z bloku drugiego. Ćwiczenie 1 utworzyć program dzielący przez siebie dwie liczby
Część XI C++ W folderze nazwisko36 program za każdym razem sprawdza oba warunki co niepotrzebnie obciąża procesor. Ten problem można rozwiązać stosując instrukcje if...else Instrukcja if wykonuje polecenie
Podstawy języka C++ Maciej Trzebiński. Instytut Fizyki Jądrowej Polskiej Akademii Nauk. Praktyki studenckie na LHC IVedycja,2016r.
M. Trzebiński C++ 1/14 Podstawy języka C++ Maciej Trzebiński Instytut Fizyki Jądrowej Polskiej Akademii Nauk Praktyki studenckie na LHC IVedycja,2016r. IFJ PAN Przygotowanie środowiska pracy Niniejsza
Programowanie w języku C++ Grażyna Koba
Programowanie w języku C++ Grażyna Koba Kilka definicji: Program komputerowy to ciąg instrukcji języka programowania, realizujący dany algorytm. Język programowania to zbiór określonych instrukcji i zasad
Celem tego projektu jest stworzenie
Prosty kalkulator Celem tego projektu jest stworzenie prostego kalkulatora, w którym użytkownik będzie podawał dwie liczby oraz działanie, które chce wykonać. Aplikacja będzie zwracała wynik tej operacji.
interfejs szeregowy wyświetlaczy do systemów PLC
LDN SBCD interfejs szeregowy wyświetlaczy do systemów PLC SEM 08.2003 Str. 1/5 SBCD interfejs szeregowy wyświetlaczy do systemów PLC INSTRUKCJA OBSŁUGI Charakterystyka Interfejs SBCD w wyświetlaczach cyfrowych
Niektóre piny mogą pełnić różne role, zależnie od aktualnej wartości sygnałów sterujących.
Podłączenie mikrokontrolera ATmega8: zasilanie 8 i 22
Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1
Podstawy programowania. Wykład Funkcje Krzysztof Banaś Podstawy programowania 1 Programowanie proceduralne Pojęcie procedury (funkcji) programowanie proceduralne realizacja określonego zadania specyfikacja
Programowanie komputerowe. Zajęcia 1
Programowanie komputerowe Zajęcia 1 Code::Blocks - tworzenie projektu Create New Project Console Application -> C++ Wybierz nazwę projektu Stworzy się nowy projekt z wpisaną funkcją main Wpisz swój program
Rozdział 4 KLASY, OBIEKTY, METODY
Rozdział 4 KLASY, OBIEKTY, METODY Java jest językiem w pełni zorientowanym obiektowo. Wszystkie elementy opisujące dane, za wyjątkiem zmiennych prostych są obiektami. Sam program też jest obiektem pewnej
Nazwa implementacji: Nauka języka Python pętla for. Autor: Piotr Fiorek
Nazwa implementacji: Nauka języka Python pętla for Autor: Piotr Fiorek Opis implementacji: Poznanie innego rodzaju pętli, jaką jest pętla for w języku Python. Składnia pętli for jest następująca: for
Instrukcja do ćwiczeń nr 4 typy i rodzaje zmiennych w języku C dla AVR, oraz ich deklarowanie, oraz podstawowe operatory
Instrukcja do ćwiczeń nr 4 typy i rodzaje zmiennych w języku C dla AVR, oraz ich deklarowanie, oraz podstawowe operatory Poniżej pozwoliłem sobie za cytować za wikipedią definicję zmiennej w informatyce.
PROE wykład 3 klasa string, przeciążanie funkcji, operatory. dr inż. Jacek Naruniec
PROE wykład 3 klasa string, przeciążanie funkcji, operatory dr inż. Jacek Naruniec Przypomnienie z ostatnich wykładów Konstruktory/destruktory i kolejność ich wywołania w złożonej klasie. Referencja Obiekty
Laboratorium Podstaw Informatyki. Kierunek Elektrotechnika. Ćwiczenie 1. Podstawy. Wprowadzenie do programowania w języku C. Katedra Metrologii AGH
Laboratorium Podstaw Informatyki Kierunek Elektrotechnika Ćwiczenie 1 Podstawy Wprowadzenie do programowania w języku C Kraków 2010 Twój pierwszy program w C Program w języku C, jak i w wielu innych językach
Pytania sprawdzające wiedzę z programowania C++
Pytania sprawdzające wiedzę z programowania C++ Wstęp 1. Zaprezentuj mechanikę tworzenia programu napisanego w języku C++. 2. Co to jest kompilacja? 3. Co to jest konsolidacja? 4. Co to jest kod wykonywalny?
Szkolenia specjalistyczne
Szkolenia specjalistyczne AGENDA Programowanie mikrokontrolerów w języku C na przykładzie STM32F103ZE z rdzeniem Cortex-M3 GRYFTEC Embedded Systems ul. Niedziałkowskiego 24 71-410 Szczecin info@gryftec.com
/* dołączenie pliku nagłówkowego zawierającego deklaracje symboli dla wykorzystywanego mikrokontrolera */ #include <aduc834.h>
Szablon programu: /* dołączenie pliku nagłówkowego zawierającego deklaracje symboli dla wykorzystywanego mikrokontrolera */ #include /* opcjonalne: deklaracja typów o rozmiarze jednego i dwóch
Wyświetlacz alfanumeryczny LCD zbudowany na sterowniku HD44780
Dane techniczne : Wyświetlacz alfanumeryczny LCD zbudowany na sterowniku HD44780 a) wielkość bufora znaków (DD RAM): 80 znaków (80 bajtów) b) możliwość sterowania (czyli podawania kodów znaków) za pomocą
Laboratorium Napędu robotów
WYDZIAŁ ELEKTRYCZNY INSTYTUT MASZYN, NAPĘDÓW I POMIARÓW ELEKTRYCZNYCH Laboratorium Napędu robotów INS 5 Ploter frezująco grawerujący Lynx 6090F 1. OPIS PRZYCISKÓW NA PANELU STEROWANIA. Rys. 1. Przyciski
Podstawy programowania Laboratorium. Ćwiczenie 2 Programowanie strukturalne podstawowe rodzaje instrukcji
Podstawy programowania Laboratorium Ćwiczenie 2 Programowanie strukturalne podstawowe rodzaje instrukcji Instrukcja warunkowa if Format instrukcji warunkowej Przykład 1. if (warunek) instrukcja albo zestaw
Część XV C++ Ćwiczenie 1
Część XV C++ Instrukcja break przerywa działanie tylko tej pętli, w ciele której została wywołana. Jeśli więc wywołamy break w pętli zagnieżdżonej w innej pętli, zostanie przerwane działanie tylko tej
Laboratorium Wstawianie skryptu na stroną: 2. Komentarze: 3. Deklaracja zmiennych
1. Wstawianie skryptu na stroną: Laboratorium 1 Do umieszczenia skryptów na stronie służy znacznik: //dla HTML5 ...instrukcje skryptu //dla HTML4 ...instrukcje
i w przypadku wciśnięcia odpowiedniego klawisza przejść do ponownego wczytywania czasu. Nasz program przez zdecydowa-
Kurs AVR lekcja 8 Rozwiązania zadań i w przypadku wciśnięcia odpowiedniego z ostatniego odcinka klawisza przejść do ponownego wczytywania czasu. Nasz program przez zdecydowa- Tematem pierwszego zadania
Mikrokontrolery AVR Wprowadzenie
Mikrokontrolery AVR Wprowadzenie Komunikacja z otoczeniem mikrokontrolera Każdy z mikrokontrolerów posiada pewna liczbę wyprowadzeń cyfrowych które służą do wprowadzania i odbierania informacji z mikrokontrolera.
Język C, tablice i funkcje (laboratorium, EE1-DI)
Język C, tablice i funkcje (laboratorium, EE1-DI) Opracował: Tomasz Mączka (tmaczka@kia.prz.edu.pl) Wstęp (tablice) Tablica to uporządkowany ciąg elementów tego samego typu, zajmujących ciągły obszar pamięci.
ZASOBY ZMIENNYCH W STEROWNIKACH SAIA-BURGESS
ZASOBY ZMIENNYCH W STEROWNIKACH SAIA-BURGESS Autorzy Wydanie Data : : : Zespół SABUR Sp. z o.o. 3.00 Sierpień 2013 2013 SABUR Sp. z o. o. Wszelkie prawa zastrzeżone Bez pisemnej zgody firmy SABUR Sp. z
TECHNIKA MIKROPROCESOROWA II
Akademia Górniczo Hutnicza im. Stanisława Staszica w Krakowie Wydział IEiT Katedra Elektroniki TECHNIKA MIKROPROCESOROWA II LAB 2 Human-Machine Interface, czyli obsługa wyświetlacza slcd Sebastian Koryciak
W języku C/C++ pomiędzy wskaźnikami a tablicami istnieje bardzo ścisły związek. Do onumerowania elementów w tablicy służą tzw. INDEKSY.
LEKCJA 12. Wskaźniki i tablice w C i C++. W czasie tej lekcji: 1. Dowiesz się więcej o zastosowaniu wskaźników. 2. Zrozumiesz, co mają wspólnego wskaźniki i tablice w języku C/C++. WSKAŹNIKI I TABLICE
Wstęp do programowania INP003203L rok akademicki 2016/17 semestr zimowy. Laboratorium 1. Karol Tarnowski A-1 p.
Wstęp do programowania INP003203L rok akademicki 2016/17 semestr zimowy Laboratorium 1 Karol Tarnowski karol.tarnowski@pwr.edu.pl A-1 p. 411B Na podstawie: G. Perry, D. Miller, Język C Programowanie dla
Część XVII C++ Funkcje. Funkcja bezargumentowa Najprostszym przypadkiem funkcji jest jej wersja bezargumentowa. Spójrzmy na przykład.
Część XVII C++ Funkcje Funkcja bezargumentowa Najprostszym przypadkiem funkcji jest jej wersja bezargumentowa. Spójrzmy na przykład. 2 3 Tworzymy deklarację i definicję funkcji o nazwie pobierzln() Funkcja
Programowanie mikrokontrolerów AVR z rodziny ATmega.
Programowanie mikrokontrolerów AVR z rodziny ATmega. Materiały pomocnicze Jakub Malewicz jakub.malewicz@pwr.wroc.pl Wszelkie prawa zastrzeżone. Kopiowanie w całości lub w częściach bez zgody i wiedzy autora
Zmienne i struktury dynamiczne
Zmienne i struktury dynamiczne Zmienne dynamiczne są to zmienne, które tworzymy w trakcie działania programu za pomocą operatora new. Usuwa się je operatorem delete. Czas ich występowania w programie jest
Laboratorium Systemów wbudowanych Wyższa Szkoła Zarządzania i Bankowości, Informatyka studia inżynierskie
Laboratorium Systemów wbudowanych Wyższa Szkoła Zarządzania i Bankowości, Informatyka studia inżynierskie Ćwiczenie nr l Podstawy programowania mikrokontrolerów rodziny AVR8 opracował dr inż. Wojciech
Laboratorium 1 Temat: Przygotowanie środowiska programistycznego. Poznanie edytora. Kompilacja i uruchomienie prostych programów przykładowych.
Laboratorium 1 Temat: Przygotowanie środowiska programistycznego. Poznanie edytora. Kompilacja i uruchomienie prostych programów przykładowych. 1. Przygotowanie środowiska programistycznego. Zajęcia będą
Układy VLSI Bramki 1.0
Spis treści: 1. Wstęp... 2 2. Opis edytora schematów... 2 2.1 Dodawanie bramek do schematu:... 3 2.2 Łączenie bramek... 3 2.3 Usuwanie bramek... 3 2.4 Usuwanie pojedynczych połączeń... 4 2.5 Dodawanie
Programowanie. Elektronika dla Wszystkich 29
Kurs AVR lekcja 6 lcdstring("elektronika dla wszystkich"); Rozwiązania zadań z ostatniego odcinka W zadaniu numer 1 mieliśmy wykonać przesuwanie tekstu na wyświetlaczu. Służy do tego funkcja Cursor or
Języki i metodyka programowania. Wprowadzenie do języka C
Literatura: Brian W. Kernighan, Dennis M. Ritchie Język Ansi C, Wydawnictwa Naukowo - Techniczne, 2007 http://cm.bell-labs.com/cm/cs/cbook/index.html Scott E. Gimpel, Clovis L. Tondo Język Ansi C. Ćwiczenia
Podział programu na moduły
Materiały Podział programu na moduły Informatyka Szczegółowe informacje dotyczące wymagań odnośnie podziału na moduły: http://www.cs.put.poznan.pl/wcomplak/bfiles/c_w_5.pdf Podział programu na moduły pozwala