Struktura ta pochodzi bezpośrednio z biblioteki graficznej SPGL (napisanej w „czystym” C) i przechowuje informację na temat bitmap zawartych w pamięci Flash mikrokontrolera. Wygenerowanie odpowiednich struktur umożliwia narzędzie konwertera umożliwiającego tworzenie na podstawie plików graficznych plików wynikowych *.c zawierających definicję obrazków. Wszystkie wygenerowane bitmapy zawarte w projekcie znajdują się w pliku images.cpp, natomiast ich definicje zawarte są w pliku images.hpp, i zostały zawarte w przestrzeni nazw images.
Klasa nokia_display, implementuje fizyczną obsługę wyświetlacza graficznego z telefonu NOKIA-3310. Deklaracja klasy zawarta jest w pliku nokia_display.hpp (list. 3).
List. 3. Deklaracja klasy nokia_display
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
//Nokia display class class nokia_display { public: //Constructor nokia_display(); //Put char void put_char(char code); //Set position void set_position( unsigned x, unsigned y); //Put string void put_string( const char *str, unsigned x, unsigned y); //Put bitmap void put_bitmap( const images::img_def &image); //Clear display void clear(); private: inline void dc_pin( bool en); inline void res_pin( bool en); inline void sel_pin( bool en); void hw_init(); void hw_spi_write( unsigned char byte); void lcd_init(); void busy_delay( unsigned delay); }; |
Klasa zawiera metody zapewniające mechanizmy podstawowej obsługi wyświetlacza, takie jak wyświetlanie tekstu, wyświetlanie bitmap, czy ustawienie kursora wyświetlacza na zadanej pozycji. Konstruktor klasy (list. 4) jest odpowiedzialny za inicjalizację obiektu.
List. 4. Konstruktor klasy nokia_display odpowiedzialny za inicjalizację obiektu
1 2 3 4 5 6 7 8 |
//Display constructor nokia_display::nokia_display() { //Initialize hardware hw_init(); //Initialize LCD lcd_init(); } |
Wywołuje on metodę prywatną hw_init(), która jest odpowiedzialna za inicjalizację układów peryferyjnych mikrokontrolera (portów GPIO, oraz układu SPI1). Następnie wywoływana jest metoda prywatna lcd_init(), która jest odpowiedzialna za fizyczną inicjalizację wyświetlacza, oraz zerowanie pamięci obrazu.
Metoda put_char() (list. 5) odpowiada za wypisanie pojedynczego znaku na wyświetlaczu LCD.
List. 5. Metoda put_char()odpowiada za wyświetlenie pojedynczego znaku na LCD
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
//Write character at current position void nokia_display::put_char(char code) { std::size_t code_point; //Data dc_pin(1); //Char in array calculation code_point = static_cast<std::size_t>(code) * 6; //Write character. sel_pin(0); hw_spi_write(cg_rom[code_point++]); hw_spi_write( cg_rom[code_point++]); hw_spi_write( cg_rom[code_point++]); hw_spi_write( cg_rom[code_point++]); hw_spi_write( cg_rom[code_point++]); hw_spi_write( cg_rom[code_point]); //Write end sel_pin(1); } |
Kontroler wyświetlacza nie ma wbudowanego generatora znaków, dlatego tablica znaków została utworzone w kodzie programu, gdzie pojedynczy znak zajmuje 6 bajtów pamięci Flash. Na podstawie numeru porządkowego znaku wyznaczany jest początek znaku w tablicy znaków, a następnie poszczególne bajtu znaku przepisywane są do pamięci obrazu wyświetlacza. Wyświetlacz domyślnie skonfigurowany jest w trybie poziomym, więc zapisanie każdego bajtu powoduje zapalenie lub zgaszenie 8 pionowych pikseli. Ustawienie wyświetlania na zadanej pozycji umożliwia metoda set_position(unsigned x, unsigned y) – list. 6.
List. 6. Metoda set_position(unsigned x, unsigned y) służy do ustawienia początku wyświetlania w określonym punkcie
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
//Set cursor at selected pos (14 cols, 6 rows) void nokia_display::set_position( unsigned x, unsigned y) { x=x*6; //Write activation sel_pin(0); //Instr dc_pin(0); hw_spi_write(y|0x40); //set row position hw_spi_write(x|0x80); //set col position // Write stop sel_pin(1); dc_pin(1); } |