mielibyśmy więcej niż 5 układów, trzeba dopisać kod zapewniający prawidłowe rejestrów układu MCP Warto byłoby
|
|
- Krystian Czech
- 6 lat temu
- Przeglądów:
Transkrypt
1 32 Kurs AVR lekcja 15 Rozwiązania zadań mielibyśmy więcej niż 5 układów, trzeba dopisać kod zapewniający prawidłowe z ostatniego odcinka W poprzednim odcinku pierwsze zadanie wyświetlanie listy znalezionych układów domowe polegało na napisaniu wyszukiwarki układów I2C. Ponieważ na linii I2C i przewijanie jej np. za pomocą klawiatury. Celem drugiego zadania domowego było napisanie zegara z kalendarzem, może znajdować się do 127 układów, możemy po prostu odpytywać kolejne adresy. z podtrzymaniem bateryjnym. Zacznijmy Jeśli po wysłaniu adresu odbierzemy bit od wyświetlania aktualnego czasu. ACK, będzie to świadczyło o tym, że mamy W poprzedniej lekcji napisaliśmy kod podłączony układ slave o tym adresie. Nasz wyświetlający sekundy, wystarczy więc program będzie więc bardzo prosty (listing rozszerzyć go o odczyt pozostałych rejestrów czasu. Najpierw jednak zajmijmy się 1). #include <avr/io.h> uporządkowaniem kodu. Mamy bowiem #include "i2c.h" napisane cztery funkcje do zapisu i odczytu #include "lcd.h" rejestrów układu MCP Warto byłoby int main(void) { i2cinit(); umieścić je w oddzielnej bibliotece stworzonej specjalnie dla tej kostki. Znalazłyby lcdinit(); lcdinitprintf(); się tam również funkcje do zarządzania for (uint8_t i = 1; i < 128; i++) { i2cstart(); nią, w tym do odczytywania i zapisywania if (i2csendaddress(i << 1) == I2C_OK) { czasu. Utwórzmy więc pliki MCP79410.c printf("%d ", i); i MCP79410.h. Do pliku.c przenieśmy i2cstop(); nasze funkcje do zarządzania rejestrami, while(1){ a do pliku.h ich nagłówki. Definicje makr z adresami MCP79410 także przeniesiemy Przed wysłaniem każdego adresu wysyłany do pliku nagłówkowego. jest sygnał START, a po wysłaniu wszystkich adresów wysyłany jest sygnał STOP. rejestru (RTCSEC). Aby mieć pełne dane Sekundy odczytywaliśmy z pierwszego Gdy adres zostanie wysłany, sprawdzamy, o czasie i dacie, potrzebujemy także sześciu czy odebrany został bit ACK. Jeśli tak, kolejnych rejestrów. Możemy je wczytać do funkcja i2csendaddress() zwraca status tablicy bajtów: I2C_OK i adres zostaje wyświetlony na LCD. Ponieważ funkcja i2csendaddress() pobiera adres w notacji 8-bitowej, standardowy adres 7-bitowy jest przesuwany o 1 bit w lewo za pomocą operatora <<. Najmłodszy bit zostaje tym samym wyzerowany i wysyłane adresy stają się adresami do zapisu. Jeśli do mikrokontrolera mamy podłączony znajdujący się na płytce testowej układ MCP79410, na wyświetlaczu zobaczymy liczby 87 i 111. Jak pamiętamy z poprzedniej lekcji, jest on dostępny do zapisu pod 8-bitowymi adresami DEh (RTC) i AEh (EEPROM). Czy wyświetlone wartości są więc poprawne? Zamieńmy adresy 87 i 111 na 8-bitową postać adresów I2C. Przesunięcie o jeden bit w lewo jest równoznaczne z pomnożeniem przez 2, otrzymamy więc liczby 174 i 222. Szesnastkowo to AEh i DEh, a więc wszystko się zgadza. Adresy możemy wyświetlić od razu w postaci 8-bitowej, szesnastkowej. Wystarczy, że wywołanie funkcji printf() będzie miało postać: printf("%x ", i << 1); Wtedy na wyświetlaczu pojawi się napis AE DE potwierdzający poprawne działanie programu. Uwaga: nasz program nie uwzględnia zawijania linijek tekstu na LCD i przewijania listy, nie wyświetli więc poprawnie więcej niż 5 układów I2C. Jeśli uint8_t registers[7]; rtcreadregisters(mcp79410_rtcsec, registers, sizeof(registers)); a następnie odwoływać się do nich za pomocą indeksów, np. registers[3], aby uzyskać dostęp do dnia tygodnia. Dla ułatwienia można sobie stworzyć makra dla indeksów, aby do odebranych rejestrów odwoływać się w sposób bardziej czytelny (registers[mcp79410_rtcmth]). Należy zwrócić uwagę, że w omawianym przypadku odczytujemy rejestry od pierwszego, mającego indeks 0. Jeśli zaczynalibyśmy od innego rejestru, to elementy tablicy miałyby przesunięte indeksy względem indeksów rejestrów i nie moglibyśmy używać tych samych makr. Np. rozpoczynając odczyt od RTCMTH, wartość tego rejestru otrzymalibyśmy w registers[0], co nie byłoby już równoważne registers[mcp79410_rtcmth], bo makro MCP79410_RTCMTH zdefiniowane byłoby jako 5. Inny sposób to wykorzystanie zmiennej strukturalnej, w której zadeklarowane zostaną pola odpowiadające poszczególnym rejestrom. Jak każda zmienna jest ona de facto tablicą bajtów i można jej adres przekazać do funkcji rtcreadregisters(), aby została wypełniona wartościami z rejestrów układu MCP Lipiec 2017 Zadeklarujmy więc w pliku MCP79410.h typ strukturalny: struct RtcDateTimeRegisters { uint8_t RTCSEC; uint8_t RTCMIN; uint8_t RTCHOUR; uint8_t RTCWKDAY; uint8_t RTCDATE; uint8_t RTCMTH; uint8_t RTCYEAR; ; Jest to znany już, klasyczny sposób deklaracji typu strukturalnego, gdzie po słowie kluczowym struct podajemy nazwę naszego nowego typu strukturalnego, a następnie w nawiasach klamrowych definiujemy pola struktury. Po nawiasach można jeszcze podać nazwę zmiennej, wtedy od razu oprócz definicji strutkury będziemy mieć też utworzoną zmienną tego typu. Zwykle jednak się tego nie stosuje, bo oddziela się definicję typu od deklaracji zmiennej. Nasza definicja struktury jest w porządku, ale warto tutaj wspomnieć o możliwościach, jakie daje słowo kluczowe typedef. Służy ono do definiowania nowych typów danych na podstawie już istniejących. Dzięki niemu możemy np. używać typu uint8_t, który normalnie w języku C nie występuje, a został utworzony na podstawie typu unsigned char. W przypadku struktur słowo kluczowe typedef pozwala usunąć pewną uciążliwość: konieczność stosowania słowa kluczowego struct. Używamy go bowiem, nie tylko definiując strukturę, ale też deklarując zmienne strukturalne i funkcje operujące na nich. Zmodyfikujmy definicję naszej struktury: typedef struct { uint8_t RTCSEC; uint8_t RTCMIN; uint8_t RTCHOUR; uint8_t RTCWKDAY; uint8_t RTCDATE; uint8_t RTCMTH; uint8_t RTCYEAR; RtcDateTimeRegisters; Definiujemy tutaj strukturę bez nazwy, po słowie kluczowym struct od razu zaczyna się definicja jej pól. Następnie za pomocą słowa kluczowego typedef staje się ona nowym typem o nazwie RtcDateTimeRegisters. Zmienną strukturalną zadeklarujemy następująco: RtcDateTimeRegisters rtcdatetimeregisters; Nie musimy już tutaj pisać struct. W tym przykładzie zmienna została nazwana tak jak typ, z wyjątkiem małej litery na początku, ale oczywiście nazwa może być inna. Pozostaje jeszcze sprawa przekazywania struktury do funkcji. Przykładowo funkcja rtcreadregisters() oczekuje typu uint8_t *, czyli wskaźnika na typ uint8_t, operuje bowiem na tablicy bajtów. Musimy więc wykonać rzutowanie: rtcreadregisters(mcp79410_rtcsec, (uint8_t *) &rtcdatetimeregisters, sizeof(rtcdatetimeregisters)); Operatorem & pobierany jest adres zmiennej rtcdatetimeregisters, a następnie Elektronika dla Wszystkich
2 przekazywany do funkcji, jakby był adresem zmiennej typu uint8_t. Bez podania typu docelowego w nawiasach kompilator zgłosiłby ostrzeżenie o niezgodności typów. Co prawda ostrzeżenie to nie błąd, a więc kompilator kontynuuje swoją pracę i otrzymujemy skompilowany kod, ale niezgodność typów świadczy często jeśli nie o błędzie, to o sytuacji potencjalnie niebezpiecznej. Tutaj np. funkcja otrzymuje w parametrze typ danych, którego się nie spodziewa. Wykonując rzutowanie przez wstawienie nawiasu z typem docelowym, w pewnym sensie potwierdzamy, że wiemy, co robimy i zadbaliśmy o prawidłowe wywołanie funkcji. Tutaj zadbanie polega na pobraniu rozmiaru struktury operatorem sizeof, dzięki czemu pobierzemy tyle bajtów, ile zajmuje struktura. Jeśli odczytalibyśmy więcej, nadmiarowe bajty zostałyby zapisane poza obszarem struktury, co miałoby nieprzewidziane skutki dla działania programu. Odczyt rejestrów daty i czasu można sobie opakować w funkcję, która będzie pobierać tylko adres struktury: void readdatetimeregisters(rtcdatetimeregisters * rtcdatetimeregisters) { rtcreadregisters(mcp79410_rtcsec, (uint8_t *) &rtcdatetimeregisters, sizeof(rtcdatetimeregisters)); Należy zwrócić tutaj uwagę, że operatorem sizeof() pobierany jest rozmiar typu, a nie zmiennej. W tej funkcji mamy bowiem tylko zmienną wskaźnikową, czyli adres miejsca w pamięci, i ma on oczywiście inny rozmiar niż zmienna, na którą wskazuje. Jako że zmienna docelowa nie jest w tej funkcji widoczna, pobierany jest rozmiar typu. Wynosi on tyle samo co rozmiar zmiennej tego typu. Gdy mamy odczytane rejestry, możemy wyświetlić je na LCD. Jednak jak pamiętamy, zapisane w nich liczby są w formacie BCD, a więc podzielone są na dziesiątki i jedności. Można co prawda obsługiwać je tak jak w przykładzie z ostatniej lekcji, wygodniej jednak będzie najpierw skonwertować je do normalnej postaci. Szczególnie że dobrze byłoby mieć funkcję zwracającą te wartości do dalszego przetwarzania, a nie tylko wyświetlającą je na wyświetlaczu. Sprawy nie ułatwia fakt, że rejestry daty i godziny zawierają różne inne bity. Przed konwersją z formatu BCD trzeba je więc najpierw wyczyścić za pomocą masek bitowych. Pomocna tutaj będzie tabela 4 z poprzedniej lekcji. Zastosujemy operację logiczną AND i maski zerujące wszystko, co nie dotyczy czasu. Przykładowo wyrażenie pobierające sekundy będzie miało postać: rtcdatetimeregisters.rtcsec & 0b Zwróconą przez nie wartość będzie można poddać konwersji z formatu BCD. Konwersję ułatwia nam to, że wszystkie rejestry przechowujące cyfrę dziesiątek mają ją zapisaną na czterech najstarszych bitach. Można więc napisać jedną funkcję konwertującą z BCD: uint8_t frombcd(uint8_t reg) { return ((reg & 0b ) >> 4) * 10 + (reg & 0b ); Dziesiątki zapisane są na 4 starszych bitach. Pobieramy je więc, zerując bity jednostek i przesuwając bity dziesiątek na swoje normalne miejsce. W tym momencie mamy liczbę dziesiątek, jaka jest w docelowej wartości. Jako że są to dziesiątki, musimy pomnożyć je przez 10, aby móc uzyskać wartość docelową. Pozostają jeszcze jedności. Pobieramy je z bajtu, zerując bity dziesiątek. Otrzymaną liczbę dodajemy do pomnożonych dziesiątek. W ten sposób z zapisu BCD odzyskiwania jest oryginalna liczba. Możemy już napisać kod odczytujący aktualny czas. Jednak aby kod ten był użyteczny, powinien mieć postać funkcji zwracającej w jakiś sposób odczytane dane. Ponieważ potrzebujemy zwrócić kilka liczb, nie możemy zwrócić ich przez return. Z tym problemem zetknęliśmy się już w lekcji 7, kiedy również zwracaliśmy czas, z tym że nie pochodził on z RTC, ale był wczytywany z klawiatury. Wówczas funkcja pobierała trzy wskaźniki: na godziny, minuty i sekundy. Dzięki wskaźnikom mogliśmy zmodyfikować przekazywane zmienne i w ten sposób zwrócić kilka wartości jednocześnie. Tutaj jednak mamy jeszcze datę i dzień tygodnia, co daje 7 wartości. Oczywiście możemy stworzyć funkcję z siedmioma parametrami, ale nie będzie to zbyt eleganckie. Jako że są to wszystko dane powiązane ze sobą, dotyczące bieżącego czasu, nasuwa się użycie struktury. Jednak przed chwilą zdefiniowaliśmy taką strukturę, czy nie moglibyśmy z niej skorzystać? Ogólnie mówiąc, tak. Moglibyśmy też zamiast struktur posługiwać się tablicami typu uint8_t. Jednakże w programowaniu chodzi nie tylko o to, żeby kod działał, ale też żeby był czytelny, uporządkowany oraz void rtcreaddatetime(datetime * datetime) { Listing 3 RtcDateTimeRegisters rtcdatetimeregisters; rtcreadregisters(mcp79410_rtcsec, (uint8_t *) &rtcdatetimeregisters, sizeof(rtcdatetimeregisters)); datetime->seconds = frombcd(rtcdatetimeregisters.rtcsec & 0b ); datetime->minutes = frombcd(rtcdatetimeregisters.rtcmin & 0b ); datetime->hours = frombcd(rtcdatetimeregisters.rtchour & 0b ); datetime->dayofweek = frombcd(rtcdatetimeregisters.rtcwkday & 0b ); datetime->dayofmonth = frombcd(rtcdatetimeregisters.rtcdate & 0b ); datetime->month = frombcd(rtcdatetimeregisters.rtcmth & 0b ); datetime->year = frombcd(rtcdatetimeregisters.rtcyear & 0b ); łatwy w utrzymaniu i rozwoju. Struktura, którą zdefiniowaliśmy, opisuje fizyczne rejestry kostki MCP Tymczasem w głównym fragmencie kodu chcielibyśmy skupić się bardziej na samych danych niż na organizacji rejestrów w MCP Zdefiniujmy więc nową strukturę dla danych o czasie: typedef struct { uint8_t seconds; uint8_t minutes; uint8_t hours; uint8_t dayofweek; uint8_t dayofmonth; uint8_t month; uint16_t year; DateTime; Nasz nowy typ strukturalny przypomina poprzedni, ale służy do przechowywania czasu w normalnej postaci, a nie do komunikacji z układem RTC. Nazwy pól są więc bardziej naturalne i przeznaczone do przechowywania liczb w zwykłej formie zamiast BCD. Pole roku zostało rozszerzone do 16 bitów, aby mogło przechowywać rok czterocyfrowy. Mając definicję nowej struktury, możemy zakończyć pisanie funkcji pobierającej aktualny czas. Będzie ona wyglądała jak na listingu 3. Dzięki niej możemy napisać kod wyświetlający aktualny czas (listing 4). Jest on dosyć prosty. Deklarujemy na początku zmienną strukturalną dla czasu i przekazujemy ją do naszej funkcji pobierającej czas z RTC. Następnie wyświetlamy poszczególne pola na LCD: czas na pierwszej linii, datę z dniem tygodnia na drugiej. Jak wyświetlany jest dzień tygodnia? Korzystamy z tablicy wskaźników na ciągi: const char * WeekDays[] = {" ", "pn", "wt", "sr", "cz", "pt", "so", "nd"; W ten sposób w ostatniej linijce poprzedniego kodu możemy zaindeksować tablicę WeekDays i pobrać z niej wskaźnik na ciąg odpowiadający bieżącemu dniowi tygodnia, a następnie przekazać go do funkcji printf(). Tablica zawiera stałe, więc deklarujemy ją jako const. Oczywiście dwuliterowe skróty są tylko przykładem, można użyć np. pełnych słów. Jeśli chcemy użyć polskich liter, musimy zdefiniować je w pamięci wyświetlacza, zgodnie z opisem w lekcji 6. Pierwszy element tablicy zawierający spacje pełni funkcję wypełniacza. Nie będziemy go używać, bo nasz RTC jako dni tygodnia przyjmuje liczby 1 7, ale musi on istnieć, bo tablica musi zawierać element o indeksie zero. DateTime datetime; Listing 4 rtcreaddatetime(&datetime); lcdgotoxy(0, 0); printf("%02d:%02d:%02d", datetime.hours, datetime.minutes, datetime.seconds); lcdgotoxy(0, 1); printf("%02d-%02d-%4d", datetime.dayofmonth, datetime.month, datetime.year); printf(" %s", WeekDays[dateTime.dayOfWeek]); Elektronika dla Wszystkich Lipiec
3 Nasz zegar musi mieć możliwość ustawiania czasu i daty. Wczytywanie tych danych z klawiatury przerabialiśmy w lekcji 7. Wczytywaliśmy wtedy tylko godzinę, minutę i sekundę, teraz natomiast potrzebujemy też daty. W tym celu możemy rozszerzyć tamtą funkcję o datę. Możemy też napisać prawie identyczną funkcję do wczytywania daty. Nie są to jednak najlepsze rozwiązania, są mało elastyczne i mało uniwersalne. Dobrze byłoby napisać funkcję służącą do wczytywania danych rozdzielonych separatorami (np. dwukropkami dla czasu i myślnikami dla daty). Byłaby ona przydatna nie tylko do wczytywania daty i godziny, ale też np. adresów IP czy MAC. Przykład takiej funkcji przedstawiono na listingu 5. Jest to rozbudowana wersja funkcji readtime() z lekcji 7. Funkcja pobiera trzy parametry: listę rozmiarów pól, liczbę elementów listy oraz tablicę zwracanych wartości. Jeśli będziemy wczytywać datę lub godzinę, w obu przypadkach użytkownik będzie void readseparatednumbers(const uint8_t fieldssizes[], uint8_t fieldsnumber, uint16_t numbers[]) { if (!fieldsnumber) return; //oblicz długość ciągu wejściowego uint8_t inputstringlength = 0; Listing 5 for (uint8_t i = 0; i < fieldsnumber; i++) { inputstringlength += fieldssizes[i]; inputstringlength += 1; //oblicz pozycje separatorów uint8_t lastseparatorposition = 0; uint8_t separatorspositions[fieldsnumber - 1]; for (uint8_t i = 0; i < sizeof(separatorspositions); i++) { separatorspositions[i] = lastseparatorposition + fieldssizes[i]; lastseparatorposition = separatorspositions[i] + 1; //wypełnij ciąg spacjami char input[inputstringlength]; for (uint8_t i = 0; i < sizeof(input); i++) input[i] = ' '; uint8_t inputindex = 0; uint8_t key = 0; while(1) { key = getkey(); if (key == 15) { if (inputindex > 0) { if (inputindex == sizeof(input) - 2) { printf("%c", ' '); lcdwritecommand(lcd_command_shift LCD_PARAM_SHIFT_LEFT); inputindex--; for (uint8_t i = 0; i < sizeof(separatorspositions); i++) { if (inputindex == separatorspositions[i]) { lcdwritecommand(lcd_command_shift LCD_PARAM_SHIFT_LEFT); inputindex--; lcdwritecommand(lcd_command_shift LCD_PARAM_SHIFT_LEFT); printf("%c", ' '); lcdwritecommand(lcd_command_shift LCD_PARAM_SHIFT_LEFT); continue; if (key < 10) input[inputindex] = '0' + key; if (key == 10) input[inputindex] = '0'; if (key == 16) { break; printf("%c", input[inputindex]); if (inputindex < sizeof(input) - 2) { inputindex++; else { lcdwritecommand(lcd_command_shift LCD_PARAM_SHIFT_LEFT); for (uint8_t i = 0; i < sizeof(separatorspositions); i++) { if (inputindex == separatorspositions[i]) { lcdwritecommand(lcd_command_shift LCD_PARAM_SHIFT_RIGHT); inputindex++; //wpisane ciągi cyfr skonwertuj do liczb uint8_t offset = 0; for (uint8_t i = 0; i < fieldsnumber; i++) { numbers[i] = atoi(input + offset); offset += fieldssizes[i] + 1; 34 wprowadzał trzy wartości. Będą one dwucyfrowe z wyjątkiem roku, który będzie czterocyfrowy. Podobnie jak w funkcji readtime() wciśnięte cyfry zapisujemy do tablicy o nazwie input. Tym razem jednak zapamiętywane są kody ASCII cyfr, a nie same liczby. Otrzymujemy więc na koniec w tablicy input ciągi znaków oddzielone spacjami, przedstawiające liczby, np Łatwo je wtedy skonwertować do liczb funkcją atoi(). Ponieważ przed wywołaniem funkcji mamy już wyświetlone separatory, np. dwukropki oddzielające godziny od minut i minuty od sekund, nasza funkcja musi je omijać. Tak jak w funkcji readtime() wykonujemy to, przesuwając kursor, ale dodatkowo też przeskakując bajty w tablicy input. Żeby to zrobić, musimy znać pozycje separatorów na wyświetlaczu a tym samym też te spacje w tablicy input, których nie chcemy nadpisać, bo mają oddzielać liczby. W tym celu obliczane są pozycje separatorów i zapamiętywane w tablicy separatorspositions. Aby ustawić czas w RTC, musimy zapisać rejestry przechowujące czas za pomocą funkcji odwrotnej do rtcreaddatetime(). Można ją obejrzeć na listingu 6. Najpierw zerujemy rejestr RTCSEC, aby wyzerować bit ST i zatrzymać RTC. Potem przygotowywane są wartości rejestrów z pól struktury daty i czasu pobierane są wartości i konwertowane do BCD. Przy okazji ustawiany jest bit VBATEN, aby włączyć podtrzymanie bateryjne. Po zapisaniu rejestrów zapisujemy jeszcze raz rejestr RTCSEC, tym razem z ustawionym bitem ST, aby wznowić odmierzanie czasu. Konwersja do BCD jest bardzo prosta. Dana liczba jest dzielona przez 10, aby uzyskać dziesiątki. Są one umieszczane na 4 starszych bitach. Następnie operatorem modulo wyciągane ją jedności i umieszczane Lipiec 2017 na 4 młodszych bitach. Funkcja wygląda następująco: uint8_t tobcd(uint8_t val) { return ((val / 10) << 4) (val % 10); Omówiliśmy wczytywanie danych z klawiatury i ich zapis do RTC. Jak jednak połączone są funkcje readseparatednumbers() i rtcwritedatetime()? Przedstawia to funkcja setdatetime(), która wszystko spina razem (listing 7). Najpierw komendą on/off włączamy kursor i wyświetlacz. Co prawda wyświetlacz był już włączony nieustawienie bitu włączenia wyświetlacza spowodowałoby jego wyłączenie. Zaczynamy przygotowanie do wczytania czasu. W pierwszej linii wyświetlacza wyświetlone zostają dwukropki, pomiędzy którymi użytkownik będzie wpisywał godzinę, minutę i sekundę. Deklarowana jest tablica mówiąca, że wczytane zostaną 3 liczby dwucyfrowe. Wczytujemy je funkcją readseparatednumbers() i trafiają one do tablicy time. Analogicznie robimy z datą, ale wyświetlana jest ona w drugiej linijce. Na koniec dane z tablic time i date trafiają do struktury, którą potem przekazujemy do funkcji rtcwritedatetime() zapisującej nowy czas i datę do rejestrów RTC. A skąd bierze się dzień tygodnia? Nie ma potrzeby, aby użytkownik wpisywał go ręcznie, może zostać obliczony. Jest wiele sposobów obliczania dnia tygodnia, został wykorzystany jeden z wielu gotowych kodów dostępnych w Internecie. Kto ma ochotę, może przeanalizować jego działanie (listing 8). Po uruchomieniu program wyświetla aktualny czas. Jeśli RTC byłby zatrzymany lub wyzerowany, trzeba wcisnąć dowolny klawisz i ustawić czas. Jeśli mamy ustawiony czas i włożoną baterię do oprawki na płytce testowej, to możemy odłączyć zasilanie płytki i po ponownym włączeniu zegar powinien nadal działać i pokazywać poprawny czas (rysunek 1). Wyjście MFP Kostka MCP79410 ma nóżkę MFP, która w zależności od konfiguracji może pełnić różne funkcje: Wyjście ogólnego przeznaczenia Sygnalizacja alarmu Źródło sygnału zegarowego MFP jest wyjściem z otwartym drenem i wymaga podciągnięcia do plusa za pomocą rezystora 10k Jeśli nóżka działa jako ogólne wyjście, możemy sterować jej stanem logicznym, ustawiając Rys. 1 Elektronika dla Wszystkich
4 void setdatetime() { //włącz kursor lcdwritecommand (LCD_COMMAND_ON_OFF LCD_PARAM_ON_OFF_CURSOR LCD_PARAM_ON_OFF_DISPLAY); //wczytaj czas lcdgotoxy(0, 0); printf(" : : "); lcdgotoxy(0, 0); const uint8_t timefieldssizes[] = {2, 2, 2; uint16_t time[3]; readseparatednumbers(timefieldssizes, 3, time); //wczytaj datę lcdgotoxy(0, 1); printf(" - - "); lcdgotoxy(0, 1); const uint8_t datefieldssizes[] = {2, 2, 4; uint16_t date[3]; readseparatednumbers(datefieldssizes, 3, date); DateTime newdatetime; newdatetime.hours = time[0]; newdatetime.minutes = time[1]; newdatetime.seconds = time[2]; newdatetime.dayofmonth = date[0]; newdatetime.month = date[1]; newdatetime.year = date[2]; newdatetime.dayofweek = getweekday(&newdatetime); //zapisz nowy czas i datę rtcwritedatetime(&newdatetime); //wyłącz kursor lcdwritecommand(lcd_command_on_off LCD_PARAM_ON_OFF_DISPLAY); odpowiednią wartość bitu OUT w rejestrze CONTROL (rejestr numer 07h). Stan na nóżce MFP może być też ustawiany automatycznie i Tabela 1 sygnalizować Listing 7 Tabela 2 wystąpienie alarmu (włączenie się budzika). Wreszcie na MFP można wyprowadzić podzielony sygnał zegarowy (32768Hz). Stopień podziału wyznaczają bity SQWFS1..0 z rejestru CONTROL zgodnie z tabelą 1. Sygnał zegarowy można wykorzystać do taktowania innych układów scalonych, take mikrokontrolera. Jak pamiętamy z lekcji 4, Timer1 może być taktowany zewnętrznym sygnałem podawanym na nóżki T0 i T1 (PB0 i PB1). Mając RTC, możemy więc nie tylko zwolnić mikrokontroler z odmierzania czasu, ale też w niektórych sytuacjach zapewnić stabilny sygnał zegarowy dla innych operacji związanych z czasem, co pozwoli np. zrezygnować z rezonatora kwarcowego dla mikrokontrolera. Konfigurację nóżki MFP wyznaczają bity SQWEN, uint8_t getweekday(datetime * datetime) { int d = datetime->dayofmonth; int m = datetime->month; int y = datetime->year; uint8_t weekday = (d += m < 3? y-- : y - 2, 23*m/9 + d y/4- y/100 + y/400)%7; if (!weekday) weekday = 7; Listing 8 return weekday; ALM1EN i ALM0EN z rejestru CONTROL. Ogólnie, jeśli nie jest włączone generowanie sygnału zegarowego ani żaden z dwóch alarmów, to nóż ka działa jako wyjście dowolnego przeznaczenia. Jeśli włączony jest co najmniej jeden alarm, to wówczas nóżka kontrolowana jest przez funkcję alarmu. Natomiast przy włączonym wyprowadzeniu sygnału zegarowego na MFP jest właśnie sygnał zegarowy, niezależnie od konfiguracji alarmów. Opcje konfiguracji zebrane są w tabeli 2. Z kolei tabela 3 przedstawia bity rejestru CONTROL. Przy podtrzymaniu bateryjnym nóżka MFP działa tylko jako wyjście alarmowe. Działanie jako wyjście ogólnego przeznaczenia lub jako źródło sygnału zegarowego wymaga normalnego zasilania. Alarmy Jak wspomniano wyżej, nasz układ RTC potrafi nie tylko odmierzać czas, ale może też generować alarmy w określonych momen- Tabela 3 void rtcwritedatetime(datetime * datetime) { rtcwriteregister(mcp79410_rtcsec, 0); RtcDateTimeRegisters rtcdatetimeregisters; rtcdatetimeregisters.rtcsec = tobcd(datetime->seconds); rtcdatetimeregisters.rtcmin = tobcd(datetime->minutes); rtcdatetimeregisters.rtchour = tobcd(datetime->hours); rtcdatetimeregisters.rtcwkday = tobcd(datetime->dayofweek) _BV(MCP79410_VBATEN); rtcdatetimeregisters.rtcdate = tobcd(datetime->dayofmonth); rtcdatetimeregisters.rtcmth = tobcd(datetime->month); rtcdatetimeregisters.rtcyear = tobcd(datetime->year ); Listing 6 rtcwriteregisters(mcp79410_rtcsec, (uint8_t *) &rtcdatetimeregisters, sizeof(rtcdatetimeregisters)); rtcwriteregister(mcp79410_rtcsec, rtcdatetimeregisters.rtcsec _BV(MCP79410_ST)); tach. Jak to działa? Alarmy są dwa i konfigurujemy je za pomocą rejestrów bardzo podobnych do rejestrów bieżącego czasu. Ustawiamy więc sekundy, minuty, godziny, dzień tygodnia, dzień miesiąca i miesiąc. Nie ma rejestru roku. Tabela 4 przedstawia rejestry alarmu pierwszego. Drugi alarm ma analogiczne rejestry pod adresami 11 16h. Różnią się one tylko oznaczeniami, zamiast cyfry 0 mają w nazwach cyfrę 1. To samo dotyczy bitów: rejestr ALM1WK- DAY ma bity ALM1MSK2, ALM1MSK1, ALM1MSK0 i ALM1IF w miejscu bitów ALM0MSK2, ALM0MSK1, ALM0MSK0 i ALM0IF. Ogólnie zasada działania jest taka, że alarm następuje gdy bieżący czas stanie się zgodny z czasem ustawionym w rejestrach danego alarmu. Aby jednak alarm nie wypadał tylko raz w roku, możliwe jest maskowanie niektórych składowych czasu. Definiują to bity ALM0MSK2, ALM0MSK1 i ALM0MSK0 dla pierwszego alarmu i analogiczne bity dla drugiego alarmu. Moż- Tabela 5 liwe kombinacje przedstawia tabela 5. Jak widać, możliwości są tutaj ograniczone. Podczas gdy niektóre układy RTC mają oddzielne bity maskujące dla każdej składowej czasu, co pozwala tworzyć różne kombinacje, w MCP79410 można wybrać tylko pojedyncze składowe (i to z wyjątkiem miesiąca) albo wszystkie. Założeniem producenta było łatwe tworzenie alarmów okresowych. Przykładowo wartość 000 da alarm co minutę, a 010 co dobę. Jeśli natomiast chcielibyśmy mieć alarm codziennie o 07.15, mamy dwa wyjścia. Jedno to wpisanie liczby 15 do rejestru ALMxMIN i wybranie maski 001. Alarm będzie występował co godzinę, 15 minut po pełnej godzinie. Za każdym wystąpieniem alarmu trzeba będzie sprawdzać, czy bieżąca godzina to 7. Jeśli tak, wówczas podjąć określoną akcję. Drugie rozwiązanie to maska 111 i ustawienie czasu alarmu na 07:15:00 oraz datę najbliższego alarmu (bieżący dzień, jeśli jest przed 7.15, kolejny, jeśli już minęła). Wówczas przy każdy wyzwoleniu alarmu trzeba przestawiać jego datę na kolejny dzień. Ewentualnie można też ustawić maskę 000, aby alarm wyzwalał się co minutę i całą obsługę zrobić już po stronie mikrokontrolera. Wtedy alarm z RTC będzie de facto źródłem sygnału 1/60 Hz, a całą logikę alarmów będziemy musieli zawrzeć w naszym Tabela 4 Elektronika dla Wszystkich Lipiec
5 Wyrównanie pól struktury W tej lekcji oraz poprzedniej korzystaliśmy ze struktur, które odwzorowywały rejestry w podłączanych układach. Wskaźniki na te struktury były potem traktowane jako wskaźniki na tablice bajtów. Dzięki temu można było wygodnie przesyłać zmienne strukturalne z/do mikrokontrolera. Na naszym 8-bitowym mikrokontrolerze nie sprawia to problemów, ale jeśli przyjdzie nam pisać kod na komputer PC lub mikrokontroler ARM, sprawa będzie nieco bardziej złożona. Na tych architekturach kompilator rozkłada pola struktury tak, aby znalazły się w pamięci pod adresami podzielnymi przez ich rozmiar. Rozważmy poniższą strukturę: struct s1 { uint32_t x; uint8_t y; Pole x znajdzie się pod adresem A, natomiast pole y pod adresem A + 4, zaraz za 4-bajtowym polem x. Rozłóżmy jednak pola odwrotnie: struct s2 { uint8_t y; uint32_t x; Pole y zostało przesunięte na początek, więc to ono znajdzie się pod początkowym adresem A. Do tego miejsca nie ma niespodzianek. Co się jednak stanie z polem x? Trafi ono pod adres A + 4, mimo że poprzedzające je pole y zajmuje tylko 1 bajt. Kompilator wyrównując (ang. alignment) położenie 4-bajtowego pola x, wprowadzi 3-bajtową dziurę (ang. padding) między polami x i y. W ten sposób struktura s1 zajmie w pamięci 5 bajtów, a struktura s2 osiem, mimo że zawierają takie same pola. Programując mikrokontrolery AVR, nie musimy się tym przejmować, ale o wyrównaniu pól trzeba pamiętać, aby uniknąć niemiłych niespodzianek przy programowaniu innych mikrokontrolerów lub pod Windows/Linuksem. Jeśli wówczas będzie nam potrzebne wyłączenie wyrównania, trzeba skorzystać z tzw. pakowania struktur. W przypadku użycia kompilatora GCC używa się atrybutu packed: struct attribute (( packed )) s2 { uint8_t y; uint32_t x; Ta struktura zajmie 5 bajtów. kodzie. Wybór danego rozwiązania będzie zależał już od konkretnych okoliczności i funkcji, jakie będzie miał mieć nasz program. Uwaga! RTC sprawdza warunek wystąpienia alarmu co sekundę i uruchamia go za każdym razem gdy warunek jest spełniony. W związku z tym alarm ustawiony np. na daną minutę wyzwoli się 60 razy podczas trwania tej minuty. Trzeba to uwzględnić w programie korzystającym z alarmów RTC. Alarmy włączamy za pomocą bitów ALM0EN i ALM1EN w rejestrze CON- TROL. Jak pamiętamy, jeśli nie jest włączona funkcja sygnału zegarowego, wówczas włączenie przynajmniej jednego alarmu powoduje przejęcie kontroli nad nóżką MFP. Za pomocą bitów ALMPOL w rejestrze ALMxWKDAY ustawiamy, jaki stan logiczny ma pojawić się na tym wyprowadzeniu w momencie alarmu. 0 oznacza stan niski, 1 stan wysoki. Stan alarmu możemy w każdej chwili sprawdzić, odczytując bity ALM0IF i ALM1IF. Jedynka oznacza wystąpienie alarmu. R E K L A M A Po zgłoszeniu alarmu na danym bicie mikrokontroler powinien go wyzerować, aby mógł być ustawiony przy kolejnym alarmie. Przy tym nie trzeba konkretnie ustawiać go na zero, każdy bowiem zapis do rejestru ALMxWKDAY spowoduje wyzerowanie flagi alarmu. Jak zachowa się nóżka MFP, jeśli włączone są dwa alarmy? Alarmy są przecież niezależne i w danej chwili może np. uaktywnić się tylko jeden z nich. Czy nóżka powiadomi wtedy o alarmie? Tak, wystarczy tylko jeden aktywny alarm, aby nóżka była w stanie wskazującym na wystąpienie alarmu. Jeśli ALMPOL = 0, wówczas przy braku alarmu na MFP będzie 1, a wystąpienie przynajmniej jednego alarmu da 0. Natomiast przy ALMPOL = 1 w spoczynku na nóżce MFP będzie 0, a po wystąpieniu przynajmniej jednego alarmu pojawi się 1. W tym momencie uważny Czytelnik powie: chwila, przecież bity Tabela 6 ALMPOL są dwa! Który będzie więc brany pod uwagę? Otóż tak naprawdę jest tylko jeden bit ALMPOL, w rejestrze pierwszego alarmu. W rejestrze drugiego alarmu jest jego kopia tylko do odczytu. Stan, jaki ma wystąpić na nóżce MFP w przypadku alarmu, konfiguruje się więc tylko w jednym miejscu. Kopiami są również bity 12/24, zawierają wartość analogicznego bitu z rejestru RTCHOUR. Timestamp zaniku/powrotu zasilania Ciekawą funkcją układu MCP79410 jest zapisywanie momentu (timestampu) zaniku zasilania oraz jego powrotu. Oczywiście, aby ta funkcja działała, konieczne jest podtrzymanie bateryjne. Gdy odłączone zostanie główne zasilanie, bieżący czas zostaje zapisany w rejestrach PWRDNMIN, PWRDNHOUR, PWRDN- DATE i PWRDNMTH znajdujących się po adresami 18h 1Bh. Analogicznie ponowne podłączenie zostanie zapisane w rejestrach PWRUPMIN, PWRUPHO- UR, PWRUPDATE i PWRUPMTH, które znajdziemy pod adresami 1Ch 1Fh. Rejestry dla odłączenia zasilania przedstawiono w tabeli 6. Rejestry dla powrotu zasilania mają identyczną strukturę. Fakt zaniku zasilania odnotowywany jest w bicie PWRFAIL rejestru RTCWKDAY (adres 03h). Gdy włączone zostanie główne zasilanie i swoją pracę rozpocznie mikrokontroler, powinien on sprawdzić stan tego bitu i wyzerować go, aby funkcja mogła zadziałać kolejny raz. Oczywiście jest to zbędne, gdy nie zamierzamy korzystać z funkcji timestampu zaniku zasilania. Elektronika dla Wszystkich
6 Tabela 7 Pamięć SRAM Jeśli zaadresujemy kostkę MCP79410 jako RTC, wówczas oprócz rejestrów związanych z odmierzaniem mamy też dostęp do 64 bajtów pamięci SRAM. Adresacja, odczyt i zapis przeprowadzane są tak samo jak rejestrów RTC, możemy więc korzystać z naszych funkcji takich jak rtcread- Registers() czy rtcwriteregisters(). Jedyna różnica jest taka, że komórki SRAM nie są związane z odmierzaniem czasu i można je wykorzystać zupełnie dowolnie. Obszar pamięci SRAM znajduje się pod adresami 20h 5Fh. Jako że jest to pamięć RAM, jest to pamięć ulotna, ale może ona korzystać z podtrzymania bateryjnego i zachowa ona swoją zawartość tak długo jak bateria będzie podłączona i ustawiony będzie bit VBATEN. Pamięć EEPROM W przypadku gdy MCP79410 zostanie zaadresowany jako EEPROM, mamy do dyspozycji 128 bajtów nieulotnej pamięci EEPROM pod adresami 00h 7Fh, 8 bajtów chronionej pamięci EEPROM pod adresami F0h F7h oraz rejestr STATUS pod adresem FFh. Główna pamięć EEPROM, mająca rozmiar 128 bajtów, podzielona jest na 8-bajtowe strony. Co to oznacza? W przypadku odczytu nic. Możemy odczytywać EEPROM tak samo jak SRAM czy rejestry RTC, pobierając jeden lub więcej kolejnych bajtów. W przypadku zapisu sytuacja jest już nieco inna. W pamięci EEPROM oraz bardzo podobnej do niej pamięci Flash nie można zapisywać sobie dowolnych komórek w dowolnym momencie. Ze względu na sposób działania tych pamięci trzeba najpierw wykasować cały obszar zwany stroną i dopiero wtedy można coś w nim zapisać. W przypadku naszej kostki sytuacja wygląda trochę inaczej, ponieważ w jej przypadku nie ma specjalnych komend wykonujących jakąś akcję, jest tylko zapis i odczyt rejestrów/komórek pamięci. Rozwiązano to w ten sposób, że wysyłane przez mikrokontroler bajty trafiają do bufora. Gdy mikrokontroler wyśle na koniec transmisji na szynie I2C sygnał STOP, układ MCP79410 kasuje stronę EEPROM-u właściwą dla aktualnego adresu i zapisuje do niej zawartość bufora. Jeśli będziemy zapisywać pojedynczy bajt, wszystko odbędzie się automatycznie i zapis będzie wyglądał tak samo, jak zapis komórki SRAM czy rejestru. W przypadku zapisu większej liczby bajtów ogranicza nas rozmiar strony: nie możemy za jednym razem zapisać więcej niż 8 bajtów. Ponadto dany zapis nie może obejmować więcej niż jednej strony. Oznacza to, że możemy zapisać 8 bajtów od adresu 00h do 07h, ale nie możemy zapisać ich od adresu 01h do 08h. Ostatni bajt wypada bowiem już na kolejnej stronie, a MCP79410 nie może skasować i zapisać więcej niż jednej strony w danym cyklu. Co się więc stanie z wystającymi bajtami? Czy zostaną utracone? Otóż gdy wysyłamy kolejne bajty do zapisu, nasz układ po każdym bajcie zwiększa wskaźnik (indeks) w swoim wewnętrznym buforze. W ten sposób kolejne bajty trafiają w kolejne komórki bufora. Gdy zostanie zapisana ostatnia, ósma komórka bufora, wskaźnik zostaje zresetowany i pokazuje na pierwszą komórkę strony. Zatem w przypadku zapisu ośmiu bajtów pod adresy 01h 08h ostatni bajt trafi pod adres 00h, a komórka o adresie 08h pozostanie nienaruszona. Jeśli więc potrzebujemy zapisać dane na obszarze obejmującym więcej niż jedną stronę, musimy zrobić to etapami. Uwaga! Zapis do pamięci EEPROM zajmuje trochę czasu. Nasz układ musi bowiem skasować stronę pamięci i zapisać do niej zawartość bufora. Potrzebuje na to znacznie więcej czasu niż na zapis do pamięci SRAM, który następuje praktycznie natychmiastowo i nie wymaga większej uwagi. Gdy trwa zapis do EEPROM-u nie możemy wykonywać żadnych operacji na tej pamięci. Działa natomiast część RTC układu MCP79410 i trwający zapis EEPROM-u nie przeszkadza w dostępie do rejestrów RTC. Jeśli jednak chcemy coś zapisać lub odczytać z EEPROM-u, musimy poczekać na koniec zapisu. Mamy więc tutaj sytuację podobną jak w lekcji 13, gdy czekaliśmy na zakończenie pomiaru temperatury przez układ DS18B20. Tak jak wtedy mamy dwa wyjścia: dodać w naszym programie odpowiednio duże opóźnienie lub też odpytywać okresowo układ, czy zakończył swoje wewnętrzne operacje. Producent nie podaje, jak długo może maksymalnie trwać zapis, ale eksperymenty pokazują, że opóźnienie wynoszące 5 milisekund powinno wystarczyć. Natomiast aby sprawdzić, czy zapis jeszcze trwa, możemy wysłać sygnał START i adres do zapisu. Jeśli kostka odpowie bitem ACK, oznacza to, że zapis się już zakończył i jest gotowa do wymiany danych. W przypadku braku ACK należy spróbować później, np. po milisekundzie. Przykładowa funkcja sprawdzająca, czy układ jest zajęty, może wyglądać następująco: uint8_t eepromisbusy(void) { i2cstart(); uint8_t status = i2csendaddress(mcp79410_eeprom_write_address); i2cstop(); return status!= I2C_OK; Funkcja zwraca 1, jeśli funkcja wysyłająca adres zwróciła status różny niż I2C_OK. Oczekiwanie na koniec zapisu będzie wyglądało tak: while (eepromisbusy()) _delay_ms(1); Wspomnieliśmy na początku, że w obszarze adresowym EEPROM-u znajduje się rejestr STATUS. Jego nazwa jest nieco myląca, bo służy on do zabezpieczania EEPROM-u przed zapisem. Domyślnie ochrony nie ma. Możemy jednak ją włączyć dla ¼, ½ lub całej pamięci, zgodnie z tabelą 7. Ponieważ rejestr STATUS ma aktywne tylko dwa bity: BP1 i BP0, znajdujące się na pozycjach 3 i 2, zarządzanie ochroną sprowadza się do wyboru jednej z 4 wartości: 00h, 04h, 08h lub 0Ch. Oprócz tego, że możemy w pewnym stopniu chronić główną pamięć EEPROM, układ MCP79410 ma jedną stronę (8 bajtów) z jeszcze większym stopniem ochrony przed zapisem. Strona ta zajmuje obszar o adresach F0h F7h. Żeby do niej zapisać, musimy wpisać specjalne wartości do rejestru EEUNLOCK, który jest rejestrem RTC o adresie 09h. Te wartości to 55h i AAh. A więc procedura zapisu polega na zaadresowaniu kostki MCP79410 jako RTC, zapisu bajtu 55h do rejestru 09h, następnie znów zaadresowania jako RTC i zapisu bajtu AAh do tego samego rejestru, następnie zaadresowaniu kostki jako EEPROM i wpisaniu żądanych wartości do komórek F0h F7h. Wygląda to skomplikowanie, ale kod zapisujący chroniony obszar będzie bardzo prosty: void eepromwriteprotected(uint8_t reg, uint8_t * data, uint8_t size) { rtcwriteregister(mcp79410_eeunlock, 0x55); rtcwriteregister(mcp79410_eeunlock, 0xAA); eepromwritebytes(reg, data, size); Zadania W tym odcinku proponuję zastanowić się nad następującymi zadaniami: 1. Zegar z budzikiem, wykorzystać alarm RTC 2. Tester pamięci SRAM 3. Tester pamięci EEPROM W materiałach dodatkowych znajduje się listing 1 oraz kompletny projekt zegara RTC z podtrzymaniem bateryjnym. Grzegorz z Niemirowski grzegorz@grzegorz.net Elektronika dla Wszystkich Lipiec
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
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
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
Dr inż. Grażyna KRUPIŃSKA. D-10 pokój 227 WYKŁAD 7 WSTĘP DO INFORMATYKI
Dr inż. Grażyna KRUPIŃSKA Grazyna.Krupinska@fis.agh.edu.pl D-10 pokój 227 WYKŁAD 7 WSTĘP DO INFORMATYKI Wyrażenia 2 Wyrażenia w języku C są bardziej elastyczne niż wyrażenia w jakimkolwiek innym języku
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ć
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
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ć
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.
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ą
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ę
INSTRUKCJA OBSŁUGI. Przekaźnik czasowy ETM ELEKTROTECH Dzierżoniów. 1. Zastosowanie
INSTRUKCJA OBSŁUGI 1. Zastosowanie Przekaźnik czasowy ETM jest zadajnikiem czasowym przystosowanym jest do współpracy z prostownikami galwanizerskimi. Pozwala on załączyć prostownik w stan pracy na zadany
MODBUS RTU wersja M1.14 protokół komunikacyjny wyświetlaczy LDN
MODBUS RTU wersja M1.14 protokół komunikacyjny do wyświetlaczy SEM 04.2010 Str. 1/5 MODBUS RTU wersja M1.14 protokół komunikacyjny wyświetlaczy LDN W wyświetlaczach LDN protokół MODBUS RTU wykorzystywany
Opis procedur asemblera AVR
Piotr Kalus PWSZ Racibórz 10.05.2008 r. Opis procedur asemblera AVR init_lcd Plik: lcd4pro.hvr Procedura inicjuje pracę alfanumerycznego wyświetlacza LCD za sterownikiem HD44780. Wyświetlacz działa w trybie
Informatyka I: Instrukcja 4.2
Informatyka I: Instrukcja 4.2 1 Wskaźniki i referencje - bezboleśnie Nauczyliśmy się do tej pory, że funkcje w języku C mogą zwracać wartość. Co jednak, gdybyśmy chcieli napisać funkcję, która rozwiąże
Lab 9 Podstawy Programowania
Lab 9 Podstawy Programowania (Kaja.Gutowska@cs.put.poznan.pl) Wszystkie kody/fragmenty kodów dostępne w osobnym pliku.txt. Materiały pomocnicze: Wskaźnik to specjalny rodzaj zmiennej, w której zapisany
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ś
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:
Konwersje napis <-> liczba Struktury, unie Scanf / printf Wskaźniki
Konwersje napis liczba Struktury, unie Scanf / printf Wskaźniki Konwersje liczba napis Ćwiczenia 1. Napisz aplikację, która na wejściu dostaje napis postaci W Roku Pańskim 1345, władca Henryk 12,
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ć
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ą
Uniwersytet Zielonogórski Instytut Sterowania i Systemów Informatycznych. Ćwiczenie 3 stos Laboratorium Metod i Języków Programowania
Uniwersytet Zielonogórski Instytut Sterowania i Systemów Informatycznych Ćwiczenie 3 stos Laboratorium Metod i Języków Programowania Celem ćwiczenia jest zapoznanie studentów z najprostszą dynamiczną strukturą
3.2. Zegar/kalendarz z pamięcią statyczną RAM 256 x 8
3.2. Zegar/kalendarz z pamięcią statyczną RAM 256 x 8 Układ PCF 8583 jest pobierającą małą moc, 2048 bitową statyczną pamięcią CMOS RAM o organizacji 256 x 8 bitów. Adresy i dane są przesyłane szeregowo
/* 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
WEJŚCIE W TRYB PROGRAMOWANIA
WEJŚCIE W TRYB PROGRAMOWANIA Należy wcisnąć przycisk PROGR a następnie kod serwisowy 8 7 1 0 2 1. Pomiędzy kolejnymi wciśnięciami nie może upłynąć czas dłuższy niż 5s. Na wyświetlaczu pojawią się dwa myślniki
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
na w inny sposób. Można się tutaj wzorować na zmierzchowym wyłączniku światła względu na ograniczoną ilość miejsca nie
Programowanie Kurs AVR lekcja 14 Rozwiązania zadań na w inny sposób. Można się tutaj wzorować na zmierzchowym wyłączniku światła z ostatniego odcinka Zadania domowe z ostatniej lekcji dotyczyły z lekcji
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,
Operatory AND, OR, NOT, XOR Opracował: Andrzej Nowak Bibliografia:
Operatory logiczne Komputery i ich logika AND - && Podstawy programowania w C++ Operatory AND, OR, NOT, XOR Opracował: Andrzej Nowak Bibliografia: CPA: PROGRAMMING ESSENTIALS IN C++ https://www.netacad.com
Dla człowieka naturalnym sposobem liczenia jest korzystanie z systemu dziesiętnego, dla komputera natomiast korzystanie z zapisu dwójkowego
Arytmetyka cyfrowa Dla człowieka naturalnym sposobem liczenia jest korzystanie z systemu dziesiętnego, dla komputera natomiast korzystanie z zapisu dwójkowego (binarnego). Zapis binarny - to system liczenia
1 Wskaźniki i zmienne dynamiczne, instrukcja przed zajęciami
1 Wskaźniki i zmienne dynamiczne, instrukcja przed zajęciami Celem tych zajęć jest zrozumienie i oswojenie z technikami programowania przy pomocy wskaźników w języku C++. Proszę przeczytać rozdział 8.
Odczyt zegara ze sterownika do panelu serii TIU z możliwością korekty ustawień zegara w sterowniku
Informator Techniczny nr 12 -- styczeń 2001 -- INFORMATOR TECHNICZNY GE FANUC Odczyt zegara ze sterownika do panelu serii TIU z możliwością korekty ustawień zegara w sterowniku Program w sterowniku W sterowniku
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
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
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ą
Konfiguracja parametrów pozycjonowania GPS 09.05.2008 1/5
Konfiguracja parametrów pozycjonowania GPS 09.05.2008 1/5 Format złożonego polecenia konfigurującego system pozycjonowania GPS SPY-DOG SAT ProSafe-Flota -KGPS A a B b C c D d E e F f G g H h I i J j K
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,
Architektura systemów komputerowych Laboratorium 13 Symulator SMS32 Operacje na bitach
Marcin Stępniak Architektura systemów komputerowych Laboratorium 13 Symulator SMS32 Operacje na bitach 1. Informacje Matematyk o nazwisku Bool wymyślił gałąź matematyki do przetwarzania wartości prawda
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
Typy wyliczeniowe Konwersje napis <-> liczba Struktury, unie Scanf / printf Wskaźniki
Typy wyliczeniowe Konwersje napis liczba Struktury, unie Scanf / printf Wskaźniki Typy wyliczeniowe Służą do łatwiejszej kontroli nad stałymi Ustawianie parametrów o ściśle określonym zbiorze wartości
1. Operacje logiczne A B A OR B
1. Operacje logiczne OR Operacje logiczne są operacjami działającymi na poszczególnych bitach, dzięki czemu można je całkowicie opisać przedstawiając jak oddziałują ze sobą dwa bity. Takie operacje logiczne
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
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
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
PAMIĘCI. Część 1. Przygotował: Ryszard Kijanka
PAMIĘCI Część 1 Przygotował: Ryszard Kijanka WSTĘP Pamięci półprzewodnikowe są jednym z kluczowych elementów systemów cyfrowych. Służą do przechowywania informacji w postaci cyfrowej. Liczba informacji,
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
Logiczny model komputera i działanie procesora. Część 1.
Logiczny model komputera i działanie procesora. Część 1. Klasyczny komputer o architekturze podanej przez von Neumana składa się z trzech podstawowych bloków: procesora pamięci operacyjnej urządzeń wejścia/wyjścia.
Elektroniczny Termostat pojemnościowych ogrzewaczy wody
Elektroniczny Termostat pojemnościowych ogrzewaczy wody ETE-1 Instrukcja obsługi Załącznik do Instrukcji obsługi i użytkowania elektrycznego pojemnościowego ogrzewacza wody typ WJ-Q i WJW-Q Zakład Urządzeń
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
Przykłady zastosowań funkcji tekstowych w arkuszu kalkulacyjnym
S t r o n a 1 Bożena Ignatowska Przykłady zastosowań funkcji tekstowych w arkuszu kalkulacyjnym Wprowadzenie W artykule zostaną omówione zagadnienia związane z wykorzystaniem funkcji tekstowych w arkuszu
OPIS PROGRAMU USTAWIANIA NADAJNIKA TA105
OPIS PROGRAMU USTAWIANIA NADAJNIKA TA105 Parametry pracy nadajnika TA105 są ustawiane programowo przy pomocy komputera osobistego przez osoby uprawnione przez operatora, które znają kod dostępu (PIN).
Spis treœci. Co to jest mikrokontroler? Kody i liczby stosowane w systemach komputerowych. Podstawowe elementy logiczne
Spis treści 5 Spis treœci Co to jest mikrokontroler? Wprowadzenie... 11 Budowa systemu komputerowego... 12 Wejścia systemu komputerowego... 12 Wyjścia systemu komputerowego... 13 Jednostka centralna (CPU)...
ĆWICZENIE 7. Wprowadzenie do funkcji specjalnych sterownika LOGO!
ćwiczenie nr 7 str.1/1 ĆWICZENIE 7 Wprowadzenie do funkcji specjalnych sterownika LOGO! 1. CEL ĆWICZENIA: zapoznanie się z zaawansowanymi możliwościami mikroprocesorowych sterowników programowalnych na
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.
Zajęcia nr 2 Programowanie strukturalne. dr inż. Łukasz Graczykowski mgr inż. Leszek Kosarzewski Wydział Fizyki Politechniki Warszawskiej
Zajęcia nr 2 Programowanie strukturalne dr inż. Łukasz Graczykowski mgr inż. Leszek Kosarzewski Wydział Fizyki Politechniki Warszawskiej Pętla while #include using namespace std; int main ()
Podstawy programowania. Wykład 7 Tablice wielowymiarowe, SOA, AOS, itp. Krzysztof Banaś Podstawy programowania 1
Podstawy programowania. Wykład 7 Tablice wielowymiarowe, SOA, AOS, itp. Krzysztof Banaś Podstawy programowania 1 Tablice wielowymiarowe C umożliwia definiowanie tablic wielowymiarowych najczęściej stosowane
Pliki. Informacje ogólne. Obsługa plików w języku C
Pliki Informacje ogólne Plik jest pewnym zbiorem danych, zapisanym w systemie plików na nośniku danych (np. dysku twardym, pendrive, płycie DVD itp.). Może posiadać określone atrybuty, a odwołanie do niego
utworz tworzącą w pamięci dynamicznej tablicę dwuwymiarową liczb rzeczywistych, a następnie zerującą jej wszystkie elementy,
Lista 3 Zestaw I Zadanie 1. Zaprojektować i zaimplementować funkcje: utworz tworzącą w pamięci dynamicznej tablicę dwuwymiarową liczb rzeczywistych, a następnie zerującą jej wszystkie elementy, zapisz
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
C-struktury wykład. Dorota Pylak
C-struktury wykład Dorota Pylak C-struktury W języku C++, jak w każdym języku obiektowym, mamy możliwość definiowania własnych typów danych, wraz z określeniem operacji, jakie na tych danych można wykonywać.
Wskaźniki i dynamiczna alokacja pamięci. Spotkanie 4. Wskaźniki. Dynamiczna alokacja pamięci. Przykłady
Wskaźniki i dynamiczna alokacja pamięci. Spotkanie 4 Dr inż. Dariusz JĘDRZEJCZYK Wskaźniki Dynamiczna alokacja pamięci Przykłady 11/3/2016 AGH, Katedra Informatyki Stosowanej i Modelowania 2 Wskaźnik to
Dokumentacja programu. Zoz. Uzupełnianie kodów terytorialnych w danych osobowych związanych z deklaracjami POZ. Wersja
Dokumentacja programu Zoz Uzupełnianie kodów terytorialnych w danych osobowych związanych z deklaracjami POZ Wersja 1.40.0.0 Zielona Góra 2012-02-29 Wstęp Nowelizacja Rozporządzenia Ministra Zdrowia z
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
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
12. Wprowadzenie Sygnały techniki cyfrowej Systemy liczbowe. Matematyka: Elektronika:
PRZYPOMNIJ SOBIE! Matematyka: Dodawanie i odejmowanie "pod kreską". Elektronika: Sygnały cyfrowe. Zasadę pracy tranzystorów bipolarnych i unipolarnych. 12. Wprowadzenie 12.1. Sygnały techniki cyfrowej
Warsztaty dla nauczycieli
WPROWADZENIE Wyprowadzanie danych: Wyprowadzanie na ekran komunikatów i wyników umożliwia instrukcja wyjścia funkcja print(). Argumentami funkcji (podanymi w nawiasach) mogą być teksty, wyrażenia arytmetyczne
OPROGRAMOWANIE FIRMWARE INTERFEJSU ETHERNETOWEGO UNIV
OPROGRAMOWANIE FIRMWARE INTERFEJSU ETHERNETOWEGO 1. Cechy Oprogramowanie firmware dla Interfejsu ethernetowego UNIV 3.102.0.x. Moduł jest przeźroczysty dla wszystkich wiadomości transmitowanych z magistrali
Deklaracja struktury w C++
Struktury to złożone typy danych pozwalające przechowywać różne informacje. Za pomocą struktur możliwe jest grupowanie wielu zmiennych o różnych typach w jeden obiekt. Strukturę można nazywać obiektem
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
ZASADY PROGRAMOWANIA KOMPUTERÓW
POLITECHNIKA WARSZAWSKA Instytut Automatyki i i Robotyki ZASADY PROGRAMOWANIA KOMPUTERÓW Język Język programowania: C/C++ Środowisko programistyczne: C++Builder 6 Wykład 9.. Wskaźniki i i zmienne dynamiczne.
MIERNIK T-SCALE BWS 1
MIERNIK T-SCALE BWS 1 2 Spis treści 1. WSTĘP... 4 2. OPIS KLAWIATURY... 4 3. PODSTAWOWE OPERACJE... 5 Zerowanie... 5 Tarowanie... 5 Ważenie przedmiotu... 5 4. WAŻENIE KONTROLNE... 6 Ustawianie limitów...
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?
Architektura systemów komputerowych Laboratorium 14 Symulator SMS32 Implementacja algorytmów
Marcin Stępniak Architektura systemów komputerowych Laboratorium 14 Symulator SMS32 Implementacja algorytmów 1. Informacje Poniższe laboratoria zawierają podsumowanie najważniejszych informacji na temat
instrukcja użytkownika terminala ARGOX PA-20 SYSTEMY AUTOMATYCZNEJ IDENTYFIKACJI
instrukcja użytkownika terminala ARGOX PA-20 SYSTEMY AUTOMATYCZNEJ IDENTYFIKACJI SPIS TREŚCI 04 Opis opcji terminala 05 SKANOWANIE 06 Skanowanie kod 07 Skanowanie kod ilość 08 Skanowanie kod ilość cena
dokument DOK 02-05-12 wersja 1.0 www.arskam.com
ARS3-RA v.1.0 mikro kod sterownika 8 Linii I/O ze zdalną transmisją kanałem radiowym lub poprzez port UART. Kod przeznaczony dla sprzętu opartego o projekt referencyjny DOK 01-05-12. Opis programowania
Programowanie Mikrokontrolerów
Programowanie Mikrokontrolerów Wyświetlacz alfanumeryczny oparty na sterowniku Hitachi HD44780. mgr inż. Paweł Poryzała Zakład Elektroniki Medycznej Alfanumeryczny wyświetlacz LCD Wyświetlacz LCD zagadnienia:
3. Opracować program kodowania/dekodowania pliku tekstowego. Algorytm kodowania:
Zadania-7 1. Opracować program prowadzący spis pracowników firmy (max.. 50 pracowników). Każdy pracownik opisany jest za pomocą struktury zawierającej nazwisko i pensję. Program realizuje następujące polecenia:
KOMUNIKACJA Z OTOCZENIEM MIKROKONTROLERA
Mikrokontrolery AVR KOMUNIKACJA Z OTOCZENIEM MIKROKONTROLERA Wyprowadzenia Każdy z mikrokontrolerów posiada pewną liczbę wyprowadzeń cyfrowych które służą do wprowadzania i odbierania informacji z mikrokontrolera.
Argumenty wywołania programu, operacje na plikach
Temat zajęć: Argumenty wywołania programu, operacje na plikach Autor: mgr inż. Sławomir Samolej Zagadnienie 1. (Zmienne statyczne) W języku C można decydować o sposobie przechowywania zmiennych. Decydują
Komunikacja w mikrokontrolerach Laboratorium
Laboratorium Ćwiczenie 4 Magistrala SPI Program ćwiczenia: konfiguracja transmisji danych między mikrokontrolerem a cyfrowym czujnikiem oraz sterownikiem wyświetlaczy 7-segmentowych przy użyciu magistrali
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
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
7. Pętle for. Przykłady
. Pętle for Przykłady.1. Bez użycia pętli while ani rekurencji, napisz program, który wypisze na ekran kolejne liczby naturalne od 0 do pewnego danego n. 5 int n; 6 cin >> n; 8 for (int i = 0; i
Budowa i generowanie planszy
Gra Saper została napisana w. Jest dostępna w każdej wersji systemu Windows. Polega na odkrywaniu zaminowanej planszy tak, aby nie trafić na minę. Gra działa na bardzo prostej zasadzie i nie wymaga zaawansowanego
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/
Przedrostkowa i przyrostkowa inkrementacja i dekrementacja
Część VIII C++ Przedrostkowa i przyrostkowa inkrementacja i dekrementacja W poprzednim ćwiczeniu operatory inkrementacji i dekrementacji występowały w wersji przyrostkowej. Istnieje inny sposób zapisu
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.
Struktury, unie, formatowanie, wskaźniki
Struktury, unie, formatowanie, wskaźniki 1. Napisz aplikację, która na wejściu dostaje napis postaci W Roku Pańskim 1345, władca Henryk 12, na rzecz swoich 143209 poddanych uchwalił dekret o 20 procentowej
Organizacja pamięci VRAM monitora znakowego. 1. Tryb pracy automatycznej
Struktura stanowiska laboratoryjnego Na rysunku 1.1 pokazano strukturę stanowiska laboratoryjnego Z80 z interfejsem częstościomierza- czasomierz PFL 21/22. Rys.1.1. Struktura stanowiska. Interfejs częstościomierza
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
asix4 Podręcznik użytkownika DMS500 - drajwer protokołu analizatorów DURAG DMS 500 Podręcznik użytkownika
asix4 Podręcznik użytkownika DMS500 - drajwer protokołu analizatorów DURAG DMS 500 Podręcznik użytkownika Dok. Nr PLP4021 Wersja: 04-10-2005 Podręcznik użytkownika asix4 ASKOM i asix to zastrzeżone znaki
Programowanie w językach asemblera i C
Programowanie w językach asemblera i C Mariusz NOWAK Programowanie w językach asemblera i C (1) 1 Dodawanie dwóch liczb - program Napisać program, który zsumuje dwie liczby. Wynik dodawania należy wysłać
4 Transmisja szeregowa na przykładzie komunikacji dwukierunkowej z komputerem PC, obsługa wyświetlacza LCD.
13 4 Transmisja szeregowa na przykładzie komunikacji dwukierunkowej z komputerem PC, obsługa wyświetlacza LCD. Zagadnienia do przygotowania: - budowa i działanie interfejsu szeregowego UART, - tryby pracy,
Wyrażenie include(sciezka_do_pliku) pozwala na załadowanie (wnętrza) pliku do skryptu php. Plik ten może zawierać wszystko, co może się znaleźć w
Wyrażenie include(sciezka_do_pliku) pozwala na załadowanie (wnętrza) pliku do skryptu php. Plik ten może zawierać wszystko, co może się znaleźć w obrębie skryptu. Wyrażenia include() i require() są niemal
Instrukcja do programu BASIC PR-02
Instrukcja do u BASIC PR-02 Wojciech Pietkiewicz 22.03.2000 1 Wprowadzenie BASIC jest językiem owania wyższego rzędu, który umożliwia w łatwy i czytelny sposób sterować robotem PR-02 bezpośrednio z komputera.
1 Wskaźniki. 1.1 Główne zastosowania wskaźników
1 Wskaźniki Wskaźnik (ang. pointer) jest obiektem (zmienną) przechowującym adres pamięci. Definiowanie wskaźników: typ *nazwa wskaznika; np.: int *wsk na x;, double *xxx;, char *znak;. Aby można było pracować
wersja dokumentacji 1.00 Opis programu TeleTokenEdit
wersja dokumentacji 1.00 Opis programu TeleTokenEdit Spis treści INFORMACJE WSTĘPNE...1 ROZPOCZĘCIE PRACY Z PROGRAMEM...1 FORMATOWANIE TELETOKENU...2 PROGRAMOWANIE TELETOKENU...4 ZAKŁADKI W PROGRAMIE...5
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ć
Podstawy algorytmiki i programowania - wykład 4 C-struktury
1 Podstawy algorytmiki i programowania - wykład 4 C-struktury Treści prezentowane w wykładzie zostały oparte o: S. Prata, Język C++. Szkoła programowania. Wydanie VI, Helion, 2012 www.cplusplus.com Jerzy
Zewnętrzne układy peryferyjne cz. 1 Wykład 12
Zewnętrzne układy peryferyjne cz. 1 Wykład 12 Wyświetlacz LCD zgodny z HD44780 Wyświetlacz LCD zgodny z HD44780 2 HD44780 Standardowy sterownik alfanumerycznych wyświetlaczy LCD opracowany przez firmę