ZL31ARM: implementacja funkcji graficznych 2D
Funkcja czyszcząca ekran przyjmuje jako parametr wartość koloru z palety BRG, strukturę wartości którego opisane wyżej, i wypełnia nim cały ekran. Ostatnia funkcja z danej biblioteki ustawia kontrast. W celu jej regulacji można wykorzystać następujący fragment kodu w pętli while i który sprawdza czy włączony jest przycisk JOY_UP lub JOY_DOWN i odpowiednio dostraja wartość:
Delay(0xFFFF); if(GPIO_ReadInputDataBit(JOY_PORT, JOY_UP) == 0) SetContrast(contrast == 63 ? contrast : ++contrast); else if(GPIO_ReadInputDataBit(JOY_PORT, JOY_DOWN) == 0) SetContrast(contrast == -64 ? contrast : --contrast);
Warto zauważyć, że zmienna contrast przekazywana jako parametr przyjmuje wartości z zakresu od (-64) do 63. Wynika to z budowy sterownika PCF8833 odpowiedzialnego za pracę wyświetlacza. Poniższy kod rysuje kilka punktów testowych na ekranie:
LCDSetPixel( 1, 1,0x00F);//GREEN LCDSetPixel(130, 1,0x0F0);//RED LCDSetPixel(130,130,0xF00);//BLUE LCDSetPixel( 1,130,0x000);//BLACK LCDSetPixel( 65, 65,0xFFF);//WHITE
W zależności od tego czym został wypełniony ekran funkcją LCDClearScreen(), niektóre kolory mogą być słabo widoczne/rozróżnialne na danym tle.
Rysowanie linii
W prezentowanym projekcie za początek układu współrzędnych OXY został przyjęty punkt centralny ekranu i w tym celu na początku pliku graphics.c umieszczono następującą definicję, którą będzie wykorzystywana w funkcjach rysujących opisanych w danym pliku:
#define DISPLAY_CENTER 132/2
W funkcjach rysujących zawartych w pliku graphics.c w przypadku podawania współrzędnych wartość powinna zawierać się w przedziale od -65 do 64 włącznie co pozwoli na prawidłowe wyświetlenie wszystkich punktów.
Pierwszą i elementarną funkcją w pliku graphics.c jest funkcja rysująca linię drawLine(). Wywołuje się ją z podaniem dwóch punktów końcowych i koloru linii, a jej struktura wygląda w następujący sposób:
void drawLine(int x1, int y1, int x2, int y2, unsigned int color)
{
//Wyznaczanie roznicy miedzy wspolrzednymi punktami
int dx = x2 - x1;
int dy = y2 - y1;
//Rysuj punkt poczatkowy
LCDSetPixel(x1+DISPLAY_CENTER, y1+DISPLAY_CENTER, color);
//Zmienna niezalezna jest x
if (abs(dx) >= abs(dy) || abs(dx) != 0){
float a = (float) dy / (float) dx; //Wyznaczenie wspolczynnika kierunkowego
float b = y1 - a*x1; //Wyznaczenie przesuniecia
dx = (dx < 0) ? -1 : 1; //W zaleznosci od tego ktory punkt znajduje
//sie "wyzej" rysowanie bedzie odbywac sie w
//kierunku dodatnich lub ujemnych wartosci
//Rysuj kolejne punkty dopoki nie osiagnieto punktu x2
while (x1 != x2){
x1 += dx;
LCDSetPixel(x1+DISPLAY_CENTER, lround(a*x1 + b)+DISPLAY_CENTER, color);
}
}
//Zmienna niezalezna jest y
else{
float a = (float) dx / (float) dy; //Wyznaczenie wspolczynnika kierunkowego
float b = x1 - a*y1; //Wyznaczenie przesuniecia
dy = (dy < 0) ? -1 : 1;
//Rusuj kolejne punkty dopoki nie osiagnieto punktu y2
while (y1 != y2){
y1 += dy;
LCDSetPixel(lround(a*y1 + b)+DISPLAY_CENTER, y1+DISPLAY_CENTER, color);
}
}
}
Cała procedura polega na wybraniu zmiennej niezależnej x (lub y) znalezieniu współczynników funkcji liniowej opisanej równaniem y=ax+b oraz narysowaniu punktów zgodnie z funkcją y=f(x) (lub x=f(y)) za pomocą wcześniej opisanej funkcji LCDSetPixel(). Przykład rysujący 3 przekątne linie:
drawLine(-65,-65, 64, 64, 0x00F);//GREEN drawLine(-65,-55, 54, 64, 0x0F0);//RED drawLine(-55,-65, 64, 54, 0xF00);//BLUE
Rysowanie prostokąta
Rysowanie danej figury jest realizowane na dwa sposoby, z których pierwszy (standardowy) wyświetla tylko same boki prostokąta (za pomocą funkcji LCDSetPixel()), a drugi wypełnia zadanym kolorem obszar wyznaczony przez tą figurę. Podobnie jak w przypadku linii należy podać 2 punkty (x,y) leżące na przekątnej prostokąta. Wybór między tymi sposobami jest dokonywany przez podanie parametru style (podanie 1 powoduje rysowanie „pełnego” prostokąta, w innym wypadku będzie on „pusty”). Struktura danej funkcji wygląda następująco:
void drawRectangle(int x1, int y1, int x2, int y2, unsigned int color,
unsigned char style){
unsigned char i, j;
//Wyznaczenie dlugosci bokow
int a = abs(x2 - x1);
int b = abs(y2 - y1);
switch(style){
//Rysuj pelny prostokata z wypelnieniem zadanym kolorem
case 1:{
for(i=0; i < a; i++){
for(j=0; j < b; j++){
LCDSetPixel(x1+DISPLAY_CENTER+i, y1+DISPLAY_CENTER+j, color);
}
}
break;
}
//Rysuj 4 boki prostokata z zadanym kolorem
default:{
drawLine(x1,y1,x1,y2,color);
drawLine(x1,y1,x2,y1,color);
drawLine(x1,y2,x2,y2,color);
drawLine(x2,y1,x2,y2,color);
break;
}
}
}
Przykład rysowania „pustych” i „pełnych” prostokątów:
//Rysowanie pustych prostokątów testowych drawRectangle(-50,-40,50,40,RED); drawRectangle(-40,-30,40,30,GREEN); drawRectangle(-30,-20,30,20,BLUE); //Rysowanie pelnych prostokątów testowych drawRectangle(-50,-40,50,40,RED,1); drawRectangle(-40,-30,40,30,GREEN,1); drawRectangle(-30,-20,30,20,BLUE,1);

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 



