16.11.2015
[JAK NAPISAĆ DRIVER] STM32NUCLEO + mbed.org + graficzny LCD = druga aplikacja na STM32 w sieciowym środowisku programistycznym
Wyświetlanie znaków jest bardziej złożoną operacją podczas której z tablicy czytane są wartości pikseli (0 – wolny, 1 – zajęty). Przykładowy fragment takiej tablicy przedstawiono poniżej, a na rysunku 8 pokazano efekt wyświetlenia symbolu „1” zakodowanego przy pomocy 8 bajtów.
const unsigned char FONT6x8[97][8] = { 0x06,0x08,0x08,0x00,0x00,0x00,0x00,0x00, // columns, rows, num_bytes_per_char //[...] 0x03,0x06,0x0C,0x18,0x30,0x60,0x40,0x00, // / (forward slash) 0x3E,0x63,0x63,0x6B,0x63,0x63,0x3E,0x00, // 0 0x30 0x18,0x38,0x58,0x18,0x18,0x18,0x7E,0x00, // 1 0x3C,0x66,0x06,0x1C,0x30,0x66,0x7E,0x00, // 2 0x3C,0x66,0x06,0x1C,0x06,0x66,0x3C,0x00, // 3 //[...] };
Rys. 8. Symbol „1” zakodowany w tablicy; czcionka 6×8
void NokiaLCD::drawChar(char c, int x, int y, int size, unsigned int fgColor, unsigned int bgColor) { extern const unsigned char FONT6x8[97][8]; extern const unsigned char FONT8x8[97][8]; extern const unsigned char FONT8x16[97][16]; unsigned char *FontTable[] = {(unsigned char *)FONT6x8, (unsigned char *)FONT8x8, (unsigned char *)FONT8x16}; unsigned char *pChar; unsigned char *pFont; unsigned int color; unsigned char mask; unsigned int nBytes; unsigned int nCols; unsigned int nRows; unsigned char pixels; // Get pointer to the beginning of the selected font table pFont = (unsigned char *)FontTable[size]; // Get the nColumns, nRows and nBytes nCols = *pFont; nRows = *(pFont + 1); nBytes = *(pFont + 2); // Get pointer to the first byte of the desired character pChar = pFont + (nBytes * (c - 0x1F)); // Set column address range spi_writeCommand(CASET); spi_writeData(x); spi_writeData(x + nCols - 1); // Set row address range spi_writeCommand(PASET); spi_writeData(y); spi_writeData(y + nRows - 1); // Write memory spi_writeCommand(RAMWR); // Loop on each row, working from the top to the bottom for(int i = 0; i < nRows; ++i){ // Copy row of pixels from font table and then increment row pixels = *pChar++; // Set pixel mask mask = 0x80; // Loop on each pixel in the row, working from the left to the right for(int j = 0; j < nCols; ++j){ // If pixel bit is set, use foreground color; else use the background color if((pixels&mask) == 0) color = bgColor; else color = fgColor; mask >>= 1; // Write R[4:0] and G[5:3] spi_writeData( (color >> 8)&0xFF ); // Write G[2:0] and B[4:0] spi_writeData( color&0xFF ); } } spi_writeCommand(NOP); }
Pozostałe funkcje związane z wyprowadzaniem tekstu są bardzo intuicyjne:
/* ****************************** */ /* *** Text-related functions *** */ /* ****************************** */ void NokiaLCD::gotoXY(int x, int y) { text_x_last = text_x = x; text_y_last = text_y = y; } void NokiaLCD::setTextBGColor(unsigned int color) { text_bg_color = color; } void NokiaLCD::setTextFGColor(unsigned int color) { text_fg_color = color; } void NokiaLCD::setTextSize(int size) { text_size = size; } void NokiaLCD::writeChar(char c) { drawChar(c, text_x, text_y, text_size, text_fg_color, text_bg_color); } void NokiaLCD::writeCharAtXY(char c, int x, int y) { drawChar(c, x, y, text_size, text_fg_color, text_bg_color); } void NokiaLCD::writeString(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 + x_step*i++, text_y, text_size, text_fg_color, text_bg_color); } } void NokiaLCD::writeStringAtXY(char *s, int x, int y) { 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++, x + x_step*i++, y, text_size, text_fg_color, text_bg_color); } }
Jan Szemiet