LinkedIn YouTube Facebook
Szukaj

Newsletter

Proszę czekać.

Dziękujemy za zgłoszenie!

Wstecz
Artykuły

[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

Autor: Jan Szemiet