[JAK OBIEKTOWO NAPISAĆ DRIVER] STM32NUCLEO + mbed.org + graficzny LCD = druga aplikacja na STM32 w sieciowym środowisku programistycznym
Możliwość przeciążania operatorów w języku C++ pozwala nie tylko na przypisanie nowych funkcji operatorom w zależności od typu przyjmowanych argumentów, ale także na skrócenie (i zwiększenie czytelności) kodu klienckiego jaki tworzy użytkownik. Tak na przykład, aby wyświetlić tekst, wartość, linię oraz prostokąt można użyć następujących komend:
lcd.gotoXY(10, 10); lcd << "Hello, World! " << 1234; lcd.setFGColor(LCD_RGB565_BLUE); lcd << line << rect;
zamiast:
lcd.gotoXY(10, 10);
lcd.writeString("Hello, World!");
lcd.gotoXY(120, 10);
lcd.writeString("1234");
lcd.drawLine(line, LCD_RGB565_BLUE)
lcd.drawRectangle(rect, LCD_RGB565_BLUE, 0)
Przykładowe implementacje przeciążonych operatorów przedstawia następujący listing:
/* ********************************** */
/* *** Graphics-related functions *** */
/* ********************************** */
NokiaLCD NokiaLCD::operator<<(const Line& line) {
drawLine(line, fg_color);
return *this;
}
NokiaLCD NokiaLCD::operator<<(const Rect& rect) {
drawRectangle(rect, fg_color, 0);
return *this;
}
/* ****************************** */
/* *** Text-related functions *** */
/* ****************************** */
NokiaLCD NokiaLCD::operator<<(const char c) {
int x_step(0);
switch(text_size){
case 0:{
x_step = 6;
break;
}
case 1: case 2:{
x_step = 8;
break;
}
default:{
x_step = 0;
break;
}
}
drawChar(c, text_x_last, text_y_last, text_size, text_fg_color, text_bg_color);
text_x_last += x_step;
return *this;
}
NokiaLCD NokiaLCD::operator<<(const char *s) {
int i(0), x_step(0);
switch(text_size){
case 0:{
x_step = 6;
break;
}
case 1: case 2:{
x_step = 8;
break;
}
default:{
x_step = 0;
break;
}
}
while(*s){
drawChar(*s++, text_x_last + x_step*i, text_y_last, text_size, text_fg_color, text_bg_color);
++i;
}
text_x_last += x_step*i;
return *this;
}
NokiaLCD NokiaLCD::operator<<(const int n) {
int i(0), x_step(0);
char text[16];
sprintf(text, "%d", n);
switch(text_size){
case 0:{
x_step = 6;
break;
}
case 1: case 2:{
x_step = 8;
break;
}
default:{
x_step = 0;
break;
}
}
while(text[i]){
drawChar(text[i], text_x_last + x_step*i, text_y_last, text_size, text_fg_color, text_bg_color);
++i;
}
text_x_last += x_step*i;
return *this;
}
Uzupełnienia wymaga jeszcze plik nagłówkowy z definicją klasy NokiaLCD:
class NokiaLCD {
private:
//[...]
public:
//[...]
// Graphics-related functions
NokiaLCD operator<<(const Line& line);
NokiaLCD operator<<(const Rect& rect);
//[...]
// Text-related functions
NokiaLCD operator<<(const char c);
NokiaLCD operator<<(const char *s);
NokiaLCD operator<<(const int n);
//[...]
};
Oczywiście przedstawiona realizacja sterownika wyświetlacza nie jest idealnie dopracowana, jednak pokazuje z grubsza specyfikę i możliwości programowania w języku C++, zwalniając nas z tworzenia nadmiernej ilości kodu oraz posługiwania się złożonymi wskaźnikami. W ramach prostych ćwiczeń można napisać pozostałe funkcje rysujące, zmodyfikować istniejące, a także nadać nowe znaczenia niektórym operatorom.
#include "mbed.h"
#include "Graphics.h"
#include "NokiaLCD.h"
DigitalIn button(USER_BUTTON);
int main() {
char c('a');
int contrast(50);
int dx(0), sign(1);
// Create NokiaLCD object and initialize LCD
NokiaLCD lcd(D10, D13, D11, D9);
// Set LCD contrast
lcd.setContrast(contrast);
// Clear LCD using white color
lcd.clear(LCD_RGB565_WHITE);
// Draw filled rectangles
lcd.fillRect(5, 5, 122, 80, LCD_RGB565_YELLOW);
lcd.fillRect(8, 8, 116, 28, LCD_RGB565_ORANGE);
lcd.fillRect(8, 38, 116, 10, LCD_RGB565_GRAY);
// Set background and foreground color for text
lcd.setTextBGColor(LCD_RGB565_ORANGE);
lcd.setTextFGColor(LCD_RGB565_BLACK);
// Set font: 8x8
lcd.setTextSize(1);
// Write text @ x=10, y=10
lcd.gotoXY(10, 10);
lcd.writeString("Nucleo-F334R8");
// Write text @ x=10, y=20
lcd.gotoXY(10, 20);
lcd.writeString(" + KAmodTFT2");
lcd.setFGColor(LCD_RGB565_BLACK);
Line line_1(17, 67, 23, 73);
Line line_2(23, 67, 17, 73);
Rect rect_1(10, 65, 20, 10);
lcd << line_1 << line_2 << rect_1;
// Set font: 6x8
lcd.setTextSize(0);
// Set background and foreground color for text
lcd.setTextBGColor(LCD_RGB565_GRAY);
lcd.setTextFGColor(LCD_RGB565_WHITE);
// Write text @ x=10, y=40
lcd.gotoXY(10, 40);
lcd << "Contrast: \0" << contrast << " ";
while(1){
// Wait 200 ms
wait(0.2);
// If button was pressed
if(!button){
// Increment contrast
if(++contrast > 63)
contrast = -64;
lcd.setContrast(++contrast);
// Write text @ x=10, y=40
lcd.gotoXY(10, 40);
lcd << "Contrast: \0" << contrast << " ";
}
// Increment character
if(++c > 'z')
c = 'a';
// Write characters
lcd.drawChar(c, 15, 90, 0, LCD_RGB565_RED, LCD_RGB565_WHITE);
lcd.drawChar(c, 35, 90, 0, LCD_RGB565_GREEN, LCD_RGB565_WHITE);
lcd.drawChar(c, 55, 90, 0, LCD_RGB565_BLUE, LCD_RGB565_WHITE);
lcd.drawChar(c, 75, 90, 0, LCD_RGB565_BLACK, LCD_RGB565_WHITE);
lcd.drawChar(c, 95, 90, 0, LCD_RGB565_WHITE, LCD_RGB565_BLACK);
lcd.drawChar(c, 15, 100, 0, LCD_RGB565_WHITE, LCD_RGB565_RED);
lcd.drawChar(c, 35, 100, 0, LCD_RGB565_WHITE, LCD_RGB565_GREEN);
lcd.drawChar(c, 55, 100, 0, LCD_RGB565_WHITE, LCD_RGB565_BLUE);
lcd.drawChar(c, 75, 100, 0, LCD_RGB565_WHITE, LCD_RGB565_BLACK);
lcd.drawChar(c, 95, 100, 0, LCD_RGB565_BLACK, LCD_RGB565_WHITE);
// Clear old objects
lcd.setFGColor(LCD_RGB565_YELLOW);
lcd << line_1 << line_2 << rect_1;
dx += sign;
if(dx >= 80)
sign = -1;
else if(dx <= 0)
sign = 1;
// Move objects
line_1.move(sign, 0);
line_2.move(sign, 0);
rect_1.move(sign, 0);
// Draw new objects
lcd.setFGColor(LCD_RGB565_BLACK);
lcd << line_1 << line_2 << rect_1;
}
}
Jan Szemiet

Technologie End of Life i bezpieczeństwo sieci – wyzwania Europy związane z tzw. długiem technologicznym
Najczęstsze błędy firm przy wyborze dostawcy energii i jak ich uniknąć
Fotorezystor, czyli czujnik światła dwojakiego działania. Przykład innowacji w automatyce i elektronice możliwej dzięki technologii fotooporników 



