Kanał - ATNEL tech-forum
Wszystkie działy
Najnowsze wątki



Teraz jest 29 mar 2024, o 08:41


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 6 ] 

Jesteś zainteresowany/a kolejnymi artykułami z cyklu C++ dla AVR?
Tak 94%  94%  [ 289 ]
Nie 6%  6%  [ 17 ]
Liczba głosów : 306
Autor Wiadomość
PostNapisane: 11 lip 2013, o 23:19 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 07 kwi 2013
Posty: 418
Lokalizacja: Rzeszów
Pomógł: 102

Witam wszystkich bardzo serdecznie :)

Jako, że jest to mój pierwszy poradnik tego typu, z góry przepraszam za ewentualne nieścisłości lub niedociągnięcia oraz niekonsekwentne używanie form osobowych i nieosobowych - jeszcze się nie wprawiłem w pisaniu takich poradników ;).
Wszystkie kwestie formatowane kursywą są moimi spostrzeżeniami, które można pominąć :P.
Postaram się ten post często aktualizować, aby go ukończyć.

Moim celem jest przekonanie forumowiczów i nie tylko, do przerzucenia się na język C++ dla AVR. Przy tym chciałbym zaznaczyć, że nie mówię tutaj absolutnie o wyższości tego języka programowania nad innymi, a jedynie przedstawić nowatorskie rozwiązania znacznie umilające pracę programisty.

Osoby, które nie miały wcześniej styczności z programowaniem, lub nieużywające wcześniej języka C/C++ mogą nie w pełni wszystko zrozumieć, mimo iż będę się starał wykonywać wszystkie działania krok po kroku, dodając za każdym razem komentarze do kodu. Gdy coś będzie nie jasne bardzo proszę pisać najlepiej tutaj na forum, a nie na priv, gdyż ktoś może mieć podobny problem, a razem na pewno uda nam się go rozwiązać ;)

Dodatkowo zachęcam do wcześniejszego zapoznania się z językiem C, najlepiej z książki „Mikrokontrolery AVR Język C - Podstawy programowania”.

Na wstępie przystąpię do omówienia zalet i wad programowania zorientowanego obiektowo (C++ dla AVR):
+ hermetyzacja (enkapsulacja) - pełna kontrola nad zakresem widoczności pól (składowych klasy) oraz metod
+ możliwość podziału algorytmów na mniejsze składniki w pełni odzwierciedlające rzeczywistość oraz świat wirtualny (klasy, dziedziczenie)
+ pełne wsparcie dla programistów opierających swoje projekty o biblioteki innych osób (identyczne nazwy zmiennych i funkcji bez użycia mechanizmów zasięgu zmiennych oraz przeciążania funkcji - przestrzenie nazw)
+ nowe typy danych (m.in. bool - wartości logiczne: true, false; _Complex i _Imaginary - liczby zespolone: część rzeczywista i urojona)
+ nowe słowa kluczowe rozszerzające możliwości języka
+ prostsza alokacja pamięci (new, delete)
+ deklaracja zmiennych w dowolnym miejscu programu (nie ma konieczności deklarowania zmiennych na początku instrukcji blokowej)
+ szablony funkcji i klas - możliwe wywołanie funkcji z wartościami różnych typów (bez potrzeby przeciążania funkcji, czy też stosowania typu pustego void*)
+ przeciążanie operatorów - nadawanie nowych znaczeń dla istniejących operatorów
+ referencja, czyli alias dla zmiennej, funkcji…
+ oraz wiele, wiele więcej ;)

- trudniejsza składnia w stosunku do ANSI C
- brak obsługi wyjątków (try, catch, throw)
- nie wszystkie mechanizmy języka ujęte w standardzie działają w przypadku kompilatorów C++ dla AVR
- na chwilę obecną bardziej znaczących uchybień nie wychwyciłem, mam nadzieję, że ta lista wad będzie się z czasem skracać :P

Więcej szczegółów dotyczących różnic (nie koniecznie działających w kompilatorach C++ dla AVR) znajduje się tutaj.

Pierwszy projekt

Ze względu na to, iż używam środowiska AtmelStudio, to w nim prezentował będę pierwsze kroki przy tworzeniu nowego projektu w C++.
Nie używałem programu Eclipse, dlatego nie jestem w stanie umieścić zrzutów ekranowych z realizacji tych projektów. Jeśli zajdzie taka potrzeba bardzo proszę osoby bardziej biegłe ode mnie w programie Eclipse, do podzielenia się tą wiedzą.

Z menu „File->New” wybieramy „Project…” lub używamy skrótu „Ctrl+Shift+N”.
W tym momencie należy wybrać zakładkę „Installed Templates” oraz opcję „C/C++”, póxniej trzeba zaznaczyć pole „GCC C++ Executable Project”. Następnie nadajemy nazwę dla nowo tworzonego projektu oraz nazwę solucji, która domyślnie jest taka sama jak nazwa projektu. Można zrezygnować z tworzenia folderu dla nowej grupy projektów, odznaczając pole „Create directory for solution”. Jeśli do końca nie wiesz, co to oznacza to pozostaw to pole zaznaczone, dzięki czemu będzie możliwość dodania programów dla wielu procesorów w ramach jednego zbiorczego projektu, przy jednoczesnym utrzymaniu porządku w domyślnym folderze „Atmel Studio”.

Obrazek

Po zaakceptowaniu wprowadzonych zmian pojawia się kolejne okno do wyboru mikroprocesora, dla którego będziemy pisać program. Używając listę wyboru „rodziny urządzenia” mamy możliwość wstępnego przefiltrowania wyników tak dużej bazy mikrokontrolerów. Ja jednak użyję bardzo pomocnego pola wyszukiwarki „Search for device”, dzięki któremu wyszukam przykładowy procesor ATMega1284P, wpisując jedynie fragment nazwy:

Obrazek

Po zaznaczeniu odpowiedniego procesora i kliknięciu „OK” możemy wreszcie przystąpić do pisania kodu. Omówię w nim podstawowe zasady obiektowości oraz praktyczny przykład wykorzystania takiego „potworka” ;)

Pierwszy program w C++

Wbrew pozorom nie będzie to słynny „Hello World”, a coś bardziej praktycznego. Oczywiście nie z tego względu, że jest to zbyt błahy algorytm, a wręcz przeciwnie w przypadku mikroprocesorów nie jest tak łatwo, gdyż trzeba zaadaptować jakiś wyświetlacz. W tym celu najlepiej byłoby na początek użyć sposobu opisanego przez Mirka, lecz nawet to podejście wymaga podstawowej wiedzy na temat klas w języku C++, chcąc w pełni wykorzystać jego możliwości. Może nie do końca jasno się wyraziłem - naszym celem będzie utworzenie szeregu bibliotek w C++, tak aby w prosty sposób można było zarządzać różnymi urządzeniami I/O (wejścia/wyjścia).

Zajmiemy się tematem sterowania silników DC (możliwe również AC - wszystko zależy od modułów wykonawczych), tzn. zmiany kierunku oraz prędkości. Temat ten sukcesywnie będziemy rozszerzać o nowe możliwości tj. pomiar przebytej drogi, regulację położenia (PID) itd..

Nasz nowo utworzony program przedstawia się następująco:

Składnia: [ Pobierz ] [ Ukryj ]
język cpp
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Delikatnie go przerobię używając własnego stylu programistycznego, który oczywiście z pewnością nie jest tym najlepszym, ale dla mnie wygodniejszy i dużo bardziej przejrzysty.

Składnia: [ Pobierz ] [ Ukryj ]
język cpp
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Tą kosmetyczną zmianą jest jedynie usunięcie chwilowo zbędnych komentarzy, gdyż nie ma sensu ich za każdym razem przytaczać. Bardziej istotną modyfikacją jest zamiana stałej dosłownej na odpowiadającą jej wartość true. Może jestem pedantyczny i czepiam się szczegółów, ale w kodzie lubię mieć porządek i szczerze radzę takie podejście początkującym programistom, ponieważ jeśli nie dla Was to dla osób interpretujących taki kod będzie on łatwiejszy do zrozumienia.

Już w tym miejscu należy się zatrzymać i zastanowić, co to jest tak naprawdę true. Jest to nowe słowo kluczowe języka C++, które w raz z false i bool tworzą nowy typ danych, jakim jest typ logiczny.
Z wartościami logicznymi można było się spotkać również w języku C, ale tam były one widoczne w sposób niejawny, tj. wyrażenia logiczne w warunkach, pętlach, czy też obliczeniach z operatorami logicznymi. Pamiętając zasady związanie z operacjami logicznymi można powiedzieć, że każda wartość różna od zera jest interpretowana jako true, natomiast wartości równe zero to false. Tak więc zapis: bool a = true; oznacza to samo co uint8_t a = 1;, a bool b = false; to uint8_t b = 0;, bo faktycznie zmienne typu logicznego są utożsamiane z jednobajtową zmienną bez znaku. Ktoś może w takim razie powiedzieć: „Po co wprowadzać nowy typ danych, skoro jest to ten sam typ co używany dotychczas.”, a ja odpowiem „Dla odseparowania wartości logicznych od liczbowych.”. Podobnie używamy słowa kluczowego typedef dla przedefiniowywania typów, ale tego zagadnienia nie śmiem ponownie opisywać, przy tak wyczerpującym temat artykule mistrza ;).

Ale się rozpisałem na tak można powiedzieć prozaicznie jasny temat. Jeśli w ten dogłębny sposób będę opisywał każde zagadnienie to chyba nikt nie będzie w stanie doczytać do końca ;).

Kontynuujemy więc nasze rozważania i od razu bez zbędnego owijania w bawełnę przejdziemy do kodu:

Składnia: [ Pobierz ] [ Ukryj ]
język cpp
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Użyte zostało tutaj słowo kluczowe class definiujące klasę. Bez obaw nie jest to taka trudna kwestia, a już na pewno nie dla osób znających ideę struktur. Tak naprawdę klasę można formalnie zastąpić strukturą w języku C++, jednak nie jest to zalecany zabieg, gdy mamy do czynienia z bardziej złożonymi obiektami, które mogą być w bardziej czytelny sposób opisane za pomocą klas.
Najbardziej znaczącą różnicą między klasą, a strukturą jest domyślny operator widoczności (dla klasy jest to private, natomiast dla struktury public), o którym opowiem w dalszej części artykułu. Może być pewnie zaskoczeniem taka pełna zgodność wsteczna, ale zapewniam, że istnieje możliwość deklarowania funkcji tzw. metod w strukturze! O tym również dalej…

Dzięki klasie tworzymy pewien szablon (w tym przypadku silnika), który istnieje w rzeczywistości. Nie chodzi tutaj o jakiś konkretny silnik, ale ogólnie mówimy kompilatorowi, że istnieje coś takiego jak silnik. Podobnie jest w przypadku wszystkich typów danych - uint8_t jest pewnym wzorcem definiującym pewien zakres liczb, ale nie jest to jakaś konkretna zmienna tego typu, przechowująca konkretną wartość w danej chwili czasowej.
Teraz pewnie padnie pytanie, dlaczego taką dziwną nazwę nadałem naszej klasie. Jest to spowodowane tym, że w swojej pracy używam również języka Delphi (Object Pascal), w którym standardem stało się definiowanie nazw klas od literki „T”. Nie wiem do końca jak sprawa się ma w przypadku języka C++ (wiele razy czytałem, że tak samo, ale nie chcę tutaj bzdur pisać, jeśli to nie prawda), ale domyślam się, że tak samo. Oczywiście nazwa klasy nie podlega jakimś ścisłym regułom (oprócz tycz dotyczących nadawania nazw zmiennych - nie będę tutaj wszystkiego, aż tak dokładnie opisywał). Musi jednak być intuicyjna i od razu rozpoznawalna, dlatego dodałem angielskie słówko „Motor” oznaczające silnik. Jeśli się komuś taki zapis nie podoba i uważa, że Polak musi programować w języku polskim to nie ma problemu, każdy może nadać taką nazwę, jaka mu się podoba.

Ja jednak będę kontynuował wszystkie zapisy w języku angielskim i to nie z tego powodu, aby pokazać jaki to biegły i obeznany jestem w tym języku, bo wręcz przeciwnie, a dlatego że zdecydowanie lepiej pisze mi się przy użyciu prostych wyrażeń angielskich, niż odmian i znaków diakrytycznych (które zdecydowanie odradzam, mimo iż kompilatory jej coraz bardziej wspierają - nie zalicza się jednak do nich AtmelStudio ;)) w języku polskim.

Bardzo ważna jest sama konstrukcja klasy. W tak prostej i schematycznej formie, zapis sprowadza się do słowa kluczowego class, po który następuje nazwa klasy oraz nawiasy klamrowe, koniecznie zakończone średnikiem. Co prawda nie jest wymagane podanie nazwy klasy (klasa anonimowa) przy jednoczesnej deklaracji zmiennej obiektowej, ale nie jest to zalecane podejście. Chcąc zachować zasady dobrego stylu programowania w przyszłości będziemy dzielić kod na odrębne pliki, co wyklucza takie „laurkowe” sposoby.

Co więcej będziemy tworzyć i posługiwać się wskaźnikami na obiekt danej klasy, gdzie niezbędne jest wywołanie konstruktora, który nosi taką samą nazwę jak klasa (jeśli klasa nie posiada nazwy to nie jest możliwe wywołanie jej konstruktora).
Powyższe zdanie może wywołać u początkujących dreszczyk emocji i zniechęcenie do dalszego czytania, dlatego zdecydowałem się je obarczyć kursywą :P. Spokojnie wszystko się wyjaśni w dalszej części - gwarantuję, że po przeczytaniu ze zrozumieniem całego artykułu to zdanie okaże się śmiesznie proste ;).


Może nie jest to do końca najlepszy moment, gdyż klasa jest zupełnie pusta tzn. nie zawiera żadnego interfejsu i struktury (pól, atrybutów); ale utworzymy obiekt tej klasy tzw. instancję klasy.
Chciałbym w tym miejscu usystematyzować wiedzę na temat tych dwóch pojęć w sposób obrazowy:
Klasa - np. samochód - wiadomo, że ma cztery koła, kierownicę i jeszcze kilka niezbędnych drobiazgów ;))
Obiekt - konkretny pojazd danej marki, modelu oraz wersji

Zasady deklaracji zmiennych strukturalnych i obiektowych w C++ są mniej uciążliwe niż w „czystym” języku C, dlatego też nie jest wymaganie użycie słów kluczowych struct oraz class, a jedynie nazwy typu i zmiennej. Nie ma więc potrzeby przedefiniowywania typów (nadawania aliasów), co wcale nie wyklucza sensu stosowania typedef.

CDN...

Postaram się rozbudowywać ten artykuł w miarę możliwości czasowych.


Dyskusję na temat tego poradnika proszę prowadzić w oddzielnym wątku: topic3516.html



Ostatnio edytowano 12 lip 2013, o 00:34 przez atmel, łącznie edytowano 1 raz

Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 13 lip 2013, o 09:13 
Offline
Moderator
Avatar użytkownika

Dołączył(a): 03 paź 2011
Posty: 27212
Lokalizacja: Szczecin
Pomógł: 1041

Może w tym miejscu jako uzupełnienie pokażę jak rozpoczynać taki sam projekt C++ ale w środowisku Eclipse:

Wybieramy opcję tworzenia nowego projektu ale tym razem C++ (a nie tak jak wcześniej C)
Obrazek

wprowadzamy nazwę projektu - może być dowolna, ja przypadkowo użyłem tu w nazwie na końcu _cpp (nie jest to konieczne)
Obrazek

jak zwykle odptaszkowujemy profil Debug
Obrazek

możemy tu wybrać procka i taktowanie, ale ja zwykle wolę to później zrobić we właściwościach projektu bo łatwiej:
Obrazek

i tworzymy także z Menu File-->New--> C Source file
Obrazek
ale tym razem Uwaga! koniecznie nadajemy plikom źródłowym rozszerzenie *.cpp

i wtedy możemy zaczynać tak jak kolega pisze w poradniku:
Obrazek
Jak widać projekt ładnie się skompilował - a Eclipse mam z AtmelTolchain'em

_________________
zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 24 sty 2014, o 23:16 
Offline
Nowy

Dołączył(a): 10 sty 2014
Posty: 2
Pomógł: 0

Znalazłem kilka błędów w tym poradniku i są to bardzo znaczące błędy:
Z tego co mi wiadomo to:
1. Obsługa wyjątków została wprowadzona dopiero w języku C++ (nie ma jej w "czystym" C), czyli chodzi o słowa kluczowe try, throw, catch
2. Referencje do zmiennej są również w C więc nie jest to jako zaleta C++ w stosunku do C
3. Typ BOOL jest również w C.

Jeżeli ktoś chce poznać język C ale w jego czystej postaci ANSI C to zalecam książkę "Język C - B.W. Keringhan, D.M. Ritchie" gdyż jest to książka napisane przez twórcę tego języka. Jednak nie ma tam nic o mikrokontrolerach ale ksiązka ukazuje standard C.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 maja 2014, o 13:19 
Offline
Nowy

Dołączył(a): 19 lip 2013
Posty: 19
Pomógł: 0

Przepraszam, że odkopuję wątek, ale:
1. Nie będziesz używał wyjątków na mikrokontrolerach, bo są wolne. W czystym C ich nie ma fakt, bo C nie programuje obiektowo.
2. NIE MA REFERENCJI W C. Możesz używać wskaźników ale nie referencji jako takich jakie są w języku C++.
3. Język C nie ma wbudowanego typu bool. Jest to dodane w w bibliotekach, ale wbudowanych typów boolean'owych nie ma.
4. ANSI C to nie K&R C To są 2 różne standardy i K&R C jest starszy. Bardzo dobrą książką do C jest C. Szkoła programowania Stephena Praty albo jak ktoś dokładnie chce poznać ten język (bardzo dokładnie) to C Refference Manual.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 20 lip 2018, o 12:40 
Offline
Nowy

Dołączył(a): 27 maja 2016
Posty: 1
Pomógł: 0

Jest możliwość dokończenia tego kursu? ewentualnie wskazania w sieci innego kursu na jakim można oprzeć naukę programowania AVR?. Sam c++ znam, jednak wykorzystanie go do pisania programów dla AVR z biblioteka atmela to trochę inna bajka :)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 20 lip 2018, o 21:12 
Offline
Użytkownik

Dołączył(a): 25 lip 2013
Posty: 2561
Pomógł: 126

Kolega to pierwszy post i od razu złota łopatka :)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
Wyświetl posty nie starsze niż:  Sortuj wg  
Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 6 ] 

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 0 gości


Nie możesz rozpoczynać nowych wątków
Nie możesz odpowiadać w wątkach
Nie możesz edytować swoich postów
Nie możesz usuwać swoich postów
Nie możesz dodawać załączników

Szukaj:
Skocz do:  
cron
Sitemap
Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
phpBB SEO