poniedziałek, 30 grudnia 2013

Wyświetlacz przede wszystkim.


Ku pamięci: ctrl + shift + l najprzydatniejszy skrót do wszystkich skrótów ;]

         Odpowiedź na dawno zadane pytanie jest banalna – nigdy nie wiadomo kiedy na gwałtu rety trzeba będzie odkopać dawno zapomniany, czasem nawet trywialny, kawałek działającego kodu. Trzeba będzie dać tylko parę, może nawet jedną, malutką zmianę.
Przy dobrze napisanym kodzie – nie ma problemu, są komentarze, napisane czytelnie, a może nawet w celu utrzymania czytelnego kodu odrobinę nadmiarowo. Przy kiepsko napisanym kodzie jest po prostu na odwrót :)
Najprostszym chyba przykładem jest nie stosowanie makr z avr/io.h skoro wiemy że REFS1 ma numer 7 w rejestrze to zamiast pisać _bv(REFS1) można napisać _bv(7) efekt ten sam. Osobiście nie lubię makra _bv – stąd moim zboczeniem jest albo pisanie własnego makra do bit-write'u albo pisanie po prostu (1<<REFS1) wiem że jest tam ładne przesunięcie bitowe o wartość makra REFS1. ( Przed nim zawsze widnieje jedno z trzech &=~ lub |= lub =^ które jak tłumaczyłem młodszemu bratu ( podstawówka ) zerują wskazane miejsce, ustawiają to miejsce, lub zmieniają to miejsce na odwrotne. )
 
Żeby nie było że jestem gołosłowny: pewnego pięknego dnia zdarzyło mi się pisać parę linijek „na zaraz” które od razu miały wywędrować w świat. Miałem przy sobie kawałek działającego kodu i jedną z popularnych książek – w której w moim egzemplarzu w przykładowym kodzie akurat był błąd w krytycznym dla działania miejscu. Z tej samej książki na szczęście nauczyłem się że warto pisać ładny kod – tak więc mimo że przedsięwzięcie nie było specjalnie udane, to nie było to z winy mojej marnej pisaniny.


A teraz do rzeczy, bo w końcu miał tu pojawić się kawałek kodu!
U siebie na płytce testowej używam wyświetlacza od noki 5110 – jest tani, pancerny i prosty w obsłudze. Tani (~10zł) , czyli tańszy od popularnych alfanumerycznych na x znaków i y linijek, pancerny bo w końcu był w starej nokii i wreszcie prosty w obsłudze bo wykorzystuje SPI w najprostszej postaci ( Serial Perypherial Interface ).

Żeby za dużo nie pisać opiszę co zrobić by napisać „I love Ken!” na wyświetlaczu krok po kroku.
Na koniec okaże się że jeśli nic się na razie nie rozumie, to i tak wystarczy wiedzieć jak działają podstawowe funkcje: lcd_init, lcd_place, lcd_clear, lcd_string, lcd_int – nie trudno się domyślić że init to inicjalizacja wyświetlacza, potem place to ustawienie w którym miejscu chcemy wyświetlać, następnie clear to wyczyszczenie zawartości wyświetlacza, string wypisze nam tekst a int wypisze nam liczbę na ekran. Ważne tylko by nie pomylić int z init :P
Zakładam że stworzyliśmy nowy projekt. Zawsze jest w nim już plik main.c który będzie zawsze naszym plikiem głównym – jak sama nazwa wskazuje.
Mamy zaznaczony projekt w drzewie wyboru po prawej stronie i jest otwarty. Klikamy: ctrl + n by otworzyło nam się okno dodania nowego pliku. Wybieramy typ C/C++ file → header file i klikamy next, dalej dajemy mu nazwę: ansii.h . Następnie identycznie tworzymy n5510.h . Oraz prawie identycznie n5510.c , z tą tylko zmianą że zamiast wybrać header file wybieramy source file .
Mamy więc 3 nowe pliki bez wnętrza.
Najprościej jest ściągnąć teraz moje pliki i przekopiować zawartości. Program wyświetlający „I love Ken!” wygląda tak:

/* Dołączamy biblioteki */
#include <avr/io.h> // Generalna biblioteka do avr
#include <util/delay.h> // Biblioteka do opóźnień
#include "ascii.h" // Biblioteka z znakami ASCII
#include "spi.h" // Biblioteka z komunikacją SPI
#include "n5110.h" // Biblioteka od działania wyświetlacza


int main()
{
spi_init(); // inicjalizacja SPI
lcd_init(); // inicjalizacja LCD

while(1) // Główna pętla
{
lcd_clear(); // wyczyszczenie wyświetlacza
lcd_place(0,0); // wybranie miejsca na wyświetlaczu
lcd_string("I <3 Ken!"); // wyświetlenie tekstu
_delay_ms(300); // pauza 300 ms
}
}

Samo wyświetlanie jest w głównej pętli programu, by pokazać jak może wyglądać ciągłe generowanie tekstu ( w końcu co 300ms odświeża się on :) )

Użytkowanie jak widać bardzo proste. W n5510.h można zmienić podłączone piny do wyświetlacza, nie jest to w spi.h, gdzie jest właściwie tylko dlatego że używam więcej niż jednego urządzenia na spi i wolę mieć każdy pin urządzenia opisany headerze właśnie tego urządzenia.

Trzeba jeszcze pamiętać żeby wyświetlacz podłączyć :P SCE i DC można zmieniać dowolnie.

#define SCE PD7 // ta nóżka „wybiera” użądzenie na magistrali SPI
#define RES PD4 // Reset na SPI
#define DC PD5 // linia wyboru „rodzaju danych” wyświetlacza
#define SDIN PB3 // MOSI
#define SCKL PB5 // CLCK

To tyle. Dalej w przyszłości przybliżę może pobieżnie działanie wyświetlacza oraz działanie funkcji tej prostej biblioteki. Na największą uwagę zasługuje chyba lcd_string(), choćby dlatego że był to pierwszy raz gdy łatwiej było napisać program w taki właśnie sposób :P

W ramach ćwiczenia polecam samemu przepisać kod ;] Pomaga zwłaszcza gdy samemu chce się coś dodać.

Czemu akurat ten kod chciałbym mieć  zanim na dobre zacząłem coś robić? Ponieważ podczas pisania programu który ma wykonywać coś sensownego najprościej jest pisać go kawałkami i sprawdzać na bieżąco. Możemy sprawdzić czy rejestry dobrze się ustawiają, czy komunikacja działa tak jak nam się wydaje że powinna, w którym miejscu działania programu on nagle się zawiesza.
Jeśli miałbym się uczyć jeszcze raz programowania, to ten kod chciałbym mieć od razu dostępny przed pierwszym rozdziałem z instrukcją: skompletuj zestaw, skompiluj całość, wrzuć → działa? To super! Będzie przydawać Ci się non stop. Nie działa? To musiałeś coś zrobić naprawdę bardzo, bardzo źle...

niedziela, 22 grudnia 2013

IDE ide ide ...


IDE to piękna rzecz, jednak używając je warto pamiętać że to nie jest zwykły edytor tekstu. W porównaniu daje nam ładne pokazywanie składni, zwalnia nas z pisania makefile i odbębnia za nas wszystko to, co mieli byśmy wklepać w terminalu by skompilować program.
Tylko czy to wszystko? Nie. IDE daje nam przede wszystkim narzędzia do zarządzania projektem oraz do edycji programu. Jego zadaniem jest utrzymanie porządku w projektach i usprawnianie naszej pracy.
By dobrze poruszać się po projekcie warto znać 8 podstawowych (z ponad 90) skrótów klawiszowych które znacznie przyspieszają pracę i ułatwiają życie.

Ctrl + space – uzupełnienie, mój ulubiony!
F2                    – pokazuje co jest w definicji.
F3                    – przejście do definicji (funkcji/zmiennej/klasy/czegokolwiek)
ctrl + o          – pokazuje układ programu i pozwala przeskoczyć do miejsca
                           gdzie chcemy edytować
ctrl + b            – Build
ctrl + alt +u   – upload
ctrl + shift +F7 – zmiana zakładki
Alt + shift + r  – zmiana nazwy w całym pliku (można to zrobić też okienkowo :) )

To tylko parę przydatnych skrótów. (Wszystkie skróty do eclipse są tutaj: ctrl + shift + l ;] )
Po co ich tyle? Żeby nie musieć odrywać łapek od klawiatury – w końcu im mniej myszki tym lepiej ;]

Myślałem że w święta będzie więcej czasu – nie da się bardziej pomylić ;] Tak więc zapowiadany długi post dzielę na mniejsze. (Może dzięki temu bardziej strawne :) ) Kawałki! Enjoy!

niedziela, 15 grudnia 2013

II Tygodnie

No i pierwszy przestój w przykrótkawej historii bloga :)
Na usprawiedliwienie się mam tylko nawał zaliczeń i kolokwiów na dwóch kierunkach na raz, a potem nawał lenistwa silniej potrzeby odpoczynku. Działo się sporo ~10 zaliczeń, w 2 tygodnie.
Szczęśliwie przed świętami jeszcze tylko jedno kolokwium, a więc zdążę przed nimi napisać coś treściwego - a w najbliższym odcinku trochę o wszystkim: o projekcie w eclipse i o tym dla czego warto pisać programy tak, by za każdym razem po przerwie nie musieć analizować co autor miał na myśli przy odczytywaniu... własnego kodu ;]
Wreszcie w następnym odcinku natrafi się kawałek działającego kodu, gdybym chciał jeszcze raz rozpoczynać naukę programowania, to właśnie ten kod chciałbym mieć już gotowy pod ręką!

poniedziałek, 2 grudnia 2013

Projekt w eclipse!

Z delikatną obsuwą, tworzymy projekt od rozpoczęcia go, do wrzucenia na AVR'kę.

Zaraz po instalacji eclipse mamy wciąż włączony domyślny widok, który mało ma się do widoku programistycznego w c pod AVR. By to zmienić wchodzimy Window → Open perspective → Other gdzie wybieramy perspektywę C/C++.

Obrazek 1:
File → New → C project 

  
Obrazek 2:
  1. Dajemy nazwę projektowi (w naszym folderze workspace zostanie utworzony folder o tej nazwie z plikami projektu)
  2. Wybieramy projekt AVR Cross Target Application → Empty project
  3. Wybieramy AVR GCC toolchain który już dawno zainstalowaliśmy ;)
    Jeśli tego nie zrobiliśmy... To wyłączamy eclipse i wracamy do pierwszego posta na blogu :P
  4. Wybieramy next, w rzadnym wypadku finish.


Obrazek 3:
USBasp nie dostarcza debbugera, jednak warto pisać w tym trybie – eclipse na bieżąco będzie „stawiał nam robaczki” przy linijkach które mają błędy z ostrzeżeniami, inaczej robi to dopiero przy kompilacji (czyt. Kliknięciu młotka ). By mieć jednak plik do wysłania na AVR'kę musimy mieć Release. (Praktycznie) nie poruszamy tu debuggera – więc go odhaczamy.
  1. Pamiętamy by dać NEXT



Obrazek 4:
W MCU type wybieramy nasz procesorek, w moim przypadku najczęściej jest to Atmega 8. Chyba nie widziałem jeszcze projektu w którym jej możliwości były by wykorzystane do granic. Wiadomo że nie nadaje się do wszystkiego, natomiast przy prostych projektach dawanie większego procka to jak używanie Arduino do mrugania diodą ;]
W MCU Frequency wybieramy częstotliwość taktowania. Pamiętam że w notatniku etc gdzieś dawało się definicję F_CPU etc... używając eclipse możemy o tym szczęśliwie zapomnieć.
Wreszcie dajemy FINISH!

Obrazek 5:
  1. Klikamy prawym klawiszem myszy na nasz projekt.
  2. Dodajemy plik źródłowy (ku pamięci źródłowe *.c headery *.h )

Obrazek 6:
Nadajemy odpowiednią nazwę i klikamy finish.

Obrazek 7:
Po stworzeniu main.c automatycznie zostanie on otworzony (widać go też w drzewie projektu po lewej). Tu trzeba po prostu wspomnieć o jednym z błogosławieństw IDE – czy warto klepać setki literek i pamiętać dokładnie każdą zmienną? Nie warto! Czy warto narażać się na literówki? Też nie! Tak więc zapamiętujemy ctrl+space które pozwala nam na przebieranie w zdefiniowanych już nazwach. Co to oznacza? Chcąc dołączyć avr/io.h wpisujemy pierwszą literkę (a) używamy skrótu klawiszowego i pokazują nam się odpowiedzi. Możemy teraz je wybrać strzałkami góra dół (tak pewnie zrobił by każdy) lub myszką (masochizm). Po zdefiniowaniu własnej nazwy robimy tak samo, czy to jest definicja nazwy funkcji, czy definicja zmiennej, czy definicja preprocesora #define.
Jeśli jeszcze Cię nie przekonałem – przekonasz się już wkrótce sam jakie to wygodne :)

Obrazek 8:
Tu program do mrugania Ledką. Co do samego programowania jest mnóstwo książek i tutoriali, starał się będę więc pisać nie „jak się programuje” bo o tym można przeczytać wszędzie, ale zwracał uwagę będę „jak programować”.
Lekcja na dziś: I) piszemy komentarze, im bardziej jesteśmy początkujący tym więcej, nie zwiększają one kodu, mogą w drastycznych przypadkach nawet zmniejszać jego estetykę, ale naprawdę pomagają w nauce. II) Puki możemy piszemy maksymalnie ładny kod, nie waży zwykle dużo więcej, a przynajmniej wiemy o co w nim chodzi. Btw. Możemy prawie zawsze, choć nie zawsze nam się chce ;) III) Warto zrobić folder na komputerze gdzie będziemy mieli folder z plikami z działającym kodem i folder z dokumentacją. Poważniejszy kod = bardzo dużo komentarzy, albo dokumentacja.


Obrazek 9:
Znów klikamy prawym na nasz projekt, tym razem żeby zmienić jego Properties.
Oczywiście można szybciej : Alt+Enter .

Obrazek 10:
Rozwijamy listę AVR.
  1. Dodajemy nasz programator.

Obrazek 11:
  1. Nadajemy nazwę naszej konfiguracji
  2. Wybieramy USBasp, jeśli przespaliśmy post z dodaniem reguł udev to po skończeniu przerabiania tego posta, cofamy się o 1 i wykonujemy najszybsze dodanie reguły do USBasp jakie istnieje :)
  3. Pamiętamy by kliknąć OK.


Obrazek 12:
Pamiętamy by wybrać nasz dodany przed chwilą programator. Inaczej nie użyjemy go w projekcie z poziomu eclipse. A dopiero zobaczysz jakie to wygodne.


Obrazek 13:
W AVR możemy zmienić jeszcze w zakładce Target Hardware nasz procesor i taktowanie procesora. Jak widać u mnie jest to 12MHz, co wymaga już kwarcu. 
 
Obrazek 14:
W AVR → AVRDude → Fuses Możemy wybrać sobie Fuse Bity, dla początkujących: tu naprawdę można nabroić, więc nie włączamy czegoś jeśli nie wiemy o co z tym chodzi! (By wiedzieć o co chodzi najczęściej wystarczy przeczytać notę aplikacyjną //Datasheet atmegi8. Dla kwarcu 12MHz wpisujemy po prostu FF i C9 tak jak jest to na screenie. Same „wybory” pokazywane są i opisywane w oknie niżej – więc dokładnie wiemy co tak naprawdę włączamy. Ustawione bity są ciemno szare, a nie ustawione jasno szare – pod tym względem autorzy skopali sprawę ;]

Obrazek 15:
Budujemy projekt młotkiem. (Jeśli wybraliśmy debug musimy „rozwinąć młotek” i wybrać że chcemy budować Release.) A następnie wrzucamy go zielonym (liściem?) guzikiem AVR. 
 



Wyszło dużo tekstu – mam nadzieję że czytelnego, a przede wszystkim pomocnego. Staram się pisać tak by nawet mój młodszy brat nie miał problemu z wykonaniem tego co tu zawarłem, stąd może się wydawać to wszystko mocno nadmiarowe. Sam jednak chciałbym czytać same blogi (i książki) które wykładają o rzeczach „jak krowie na rowie” ;]