//Listing 7. Definicja nowego typu danych odpowiedzialnego za przechowywanie parametrów bieżącej czcionki ekranowej. typedef struct { uint8_t Width; //Current font widht (px) uint8_t Height; //Current font height (px) uint8_t Interspace; //Font interspace (px) uint8_t BytesPerChar; //Bytes per char definition uint8_t FirstCharCode; //First char ASCII code const uint8_t *Bitmap; //Pointer to the font table } fontDescription; //Listing 8. Funkcja odpowiedzialna za ustawienie bieżącej czcionki ekranowej. void TFTsetFont(const fontDescription *Font) { CurrentFont.Width = pgm_read_byte(&Font->Width); CurrentFont.Height = pgm_read_byte(&Font->Height); CurrentFont.Interspace = pgm_read_byte(&Font->Interspace); CurrentFont.BytesPerChar = pgm_read_byte(&Font->BytesPerChar); CurrentFont.FirstCharCode = pgm_read_byte(&Font->FirstCharCode); CurrentFont.Bitmap = (uint8_t*)pgm_read_word(&Font->Bitmap); } //Listing 9. Funkcja odpowiedzialna za rysowanie znaków, przy użyciu bieżącej czcionki ekranowej void TFTdrawChar(uint16_t X1, uint8_t Y1, char Character, const uint8_t Transparency) { register uint8_t widthIndex, heightIndex, readByte, pixelsNr, i; const uint8_t *dataPointer; if(Transparency != TRANSPARENT_TEXT) { //We define display active area to simplify writing TFTsetActiveWindow(X1, Y1, X1+CurrentFont.Width-1, Y1+CurrentFont.Height-1); //We start memory writing writeCommand(CMD_MEMORY_WRITE); } //Now we calculate start address of the current character definition dataPointer = &CurrentFont.Bitmap[(CurrentFont.BytesPerChar*(Character-CurrentFont.FirstCharCode))]; for(heightIndex = 0; heightIndex < CurrentFont.Height; heightIndex++) { for(widthIndex = 0; widthIndex < CurrentFont.Width; widthIndex += 8) { //We read character definition byte by byte readByte = pgm_read_byte(dataPointer++); //For fonts which width is not a multiple of 8 we need to calculate useful number of pixels to be sent pixelsNr = widthIndex+8 <= CurrentFont.Width ? 8 : CurrentFont.Width - widthIndex; for(i=0; i> 8); writeData(Colour & 0xFF); } } else { //Pixel color depends on the pixel presence if(readByte & 0x80) {writeData(Colour >> 8); writeData(Colour & 0xFF);} else {writeData(Background >> 8); writeData(Background & 0xFF);} } readByte<<=1; } } } } //Listing 10 Funkcje umożliwiające wyświetlenie ciągu znaków z pamięci RAM, jak i pamięci programu (Flash) void TFTdrawString(uint16_t X1, uint8_t Y1, char *String, const uint8_t Transparency) { while(*String) { TFTdrawChar(X1, Y1, *String++, Transparency); X1 += CurrentFont.Width + CurrentFont.Interspace; } } void TFTdrawString_P(uint16_t X1, uint8_t Y1, const char *String, const uint8_t Transparency) { register char Character; while((Character = pgm_read_byte(String++))) { TFTdrawChar(X1, Y1, Character, Transparency); X1 += CurrentFont.Width + CurrentFont.Interspace; } } //Listing 11. Funkcja pozwalająca na wyświetlenie liczby typu Integer (zakres 0...999) void TFTdrawInteger(uint16_t X1, uint8_t Y1, uint16_t Integer, uint8_t Digits, uint8_t Effects) { register uint8_t Digit1, Digit2; register uint8_t dotPos = Effects & DOT_MASK; //Bits: 7..6 register uint8_t Interspace = Effects & INTERSPACE_MASK; //Bits: 5..0 register uint8_t fontStep = CurrentFont.Width + CurrentFont.Interspace; if((Digit1 = Integer/1000)) Integer -= Digit1*1000; if(Digits == 4) { if(Digit1 || (dotPos == DOT_POS3)) Digit1 += ‚0’; else Digit1 = ‚ ‚; TFTdrawChar(X1, Y1, Digit1, SOLID_TEXT); X1 += fontStep; if(dotPos == DOT_POS3) X1 += Interspace; } if((Digit2 = Integer/100)) Integer -= Digit2*100; if(Digits > 2) { if(Digit2 || (Digit1 != ‚ ‚ && Digits == 4) || (dotPos >= DOT_POS2)) Digit2 += ‚0’; else Digit2 = ‚ ‚; TFTdrawChar(X1, Y1, Digit2, SOLID_TEXT); X1 += fontStep; if(dotPos == DOT_POS2) X1 += Interspace; } Digit1 = Integer/10; if(Digits >1) { if(Digit1 || (Digit2 != ‚ ‚ && Digits > 2) || (dotPos >= DOT_POS1)) Digit1 += ‚0’; else Digit1 = ‚ ‚; TFTdrawChar(X1, Y1, Digit1, SOLID_TEXT); X1 += fontStep; if(dotPos == DOT_POS1) X1 += Interspace; } TFTdrawChar(X1, Y1, ‚0’+Integer%10, SOLID_TEXT); } //Listing 12. Funkcja odpowiedzialna za wyświetlanie skompresowanych obrazków na ekranie wyświetlacza TFT void TFTdrawCompressedPicture(uint16_t X1, uint8_t Y1, const uint16_t *Picture) { register uint16_t pixelsToSend, pixelA, pixelB; register uint8_t Width, Height; //We read the first word that holds the picture width and height (MSB and LSB) pixelA = pgm_read_word(Picture++); //We calculate the picture width and height Width = pixelA >> 8; Height = pixelA & 0xFF; //We calculate how many pixels we need to send pixelsToSend = Width * Height; //We define display active area to simplify writing TFTsetActiveWindow(X1, Y1, X1+Width-1, Y1+Height-1); //We start memory writing writeCommand(CMD_MEMORY_WRITE); while(pixelsToSend) { //We read pixel n and n+1 pixelA = pgm_read_word(Picture++); pixelB = pgm_read_word(Picture); //If the pixel n is different than the pixel n+1 or if it is the last pixel we send it to the TFT if(pixelA != pixelB || pixelsToSend == 1) { writeData(pixelA >> 8); writeData(pixelA & 0xFF); pixelsToSend--; } else { //Otherwise we read how many the same pixels we need to send (third word) pixelB = pgm_read_word(++Picture); pixelsToSend -= pixelB; Picture++; //We sent them to the TFT while(pixelB--) {writeData(pixelA >> 8); writeData(pixelA & 0xFF);} } } }