⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 grlcd.c

📁 Graphical lcd library, you can port to many mcu.
💻 C
字号:
#include "GrLCD.h"
#include "Font8.h"
#include "Font16.h"

#define CONTRAST    48      // user contrast value - you will need to experiment to
                            // find best value, or write code to let user change it.

/***************************************
    lcd display constants
***************************************/
#define NR_COLS     128
#define NR_ROWS     64
#define NR_PAGS     8
#define DISP_COLL   0
#define DISP_COLH   0x10
#define DISP_VRR    0x20    // resistor ratio set
#define DISP_PWR    0x28    // voltage converter control
#define DISP_LIN    0x40    // starting line set
#define DISP_EVS    0x81    // electronic volume set (follow with value 0-63)
#define DISP_ADC    0xA1    // column address reverse direction
#define DISP_APT    0xA5    // all points on
#define DISP_NRM    0xA6    // normal
#define DISP_REV    0xA7    // reverse
#define DISP_OFF    0xAE
#define DISP_ON     0xAF
#define DISP_PAG    0xB0    // page set
#define DISP_COM    0xC0    // common scan dir
#define DISP_RST    0xE2    // soft reset
#define DISP_NOP    0xE3

#ifdef RMW_USED             // if RMW support enabled
#define DISP_RMW    0xE0    // read/modify/write mode
#define DISP_END    0xEE    // end of RMW mode
#endif

#ifdef SED1565              // Epson SED1565 controller series
#define DISP_BIA    0xA2    // bias setting
#define GR_FIX      0
#endif

#ifdef KS1713               // Samsung KS0713/1713 series
#define DISP_BIA    0xA3    // bias setting
#define GR_FIX      4       // column offset for KS0713 controller
#endif

#define CMD_DELAY   0xFE    // do a 10 mS delay during init
#define INIT_END    0xFF

static const BYTE JustTbl[8] = {
        0, NR_COLS/4,                   // L00J,L25J
        NR_COLS/3, NR_COLS/2,           // L33J,C50J
        (NR_COLS*2)/3, (NR_COLS*3)/4,   // R66J,R75J
        NR_COLS, 0                      // R100J,ABSJ
};

BYTE invertflg = 0;         // normally 0, to invert data set to 0xFF
BYTE CJ_code = 0;           // control/justify code for text display
BYTE contrast = CONTRAST;   // user contrast setting
BYTE startcol;              // save starting col for later use
BYTE column;                // current col
BYTE pagenr;

static const BYTE GrLCDIni[21] = {
        DISP_RST,           // soft reset
        CMD_DELAY,          // delay
        DISP_ADC,           // normal column dir
        DISP_COM,           // normal common mode
        DISP_BIA,           // bias
        DISP_NRM,           // normal video
        DISP_VRR+6,         // evolume resistor ratio
        DISP_EVS,           // set evolume
        0x20,               // arbitrary initial contrast
        DISP_PWR+4,         // charge pumps on
        CMD_DELAY,          // delay
        DISP_PWR+6,         // voltage reg on
        CMD_DELAY,          // delay
        DISP_PWR+7,         // follower on
        CMD_DELAY,          // delay
        DISP_ON,            // display on
        DISP_LIN,           // set starting line
        DISP_PAG,           // set page 0
        DISP_COLL,          // set column 0
        DISP_COLH,
        INIT_END
};

/***********************************************************
    Check LCD controller busy status. Most graphic controllers
    are fast enough that this function is not necessary.
***********************************************************/

static void LCDBusy(void)
{
    // here set your LCD data bus port to inputs

    LCD_CTRL(RW, 1);            // set for read
    LCD_CTRL(RS, 0);            // set for status
    LCD_CTRL(E, 1);             // assert enable

    while(LCD_DATA & 0x80);     // wait for busy bit to go low

    LCD_CTRL(E, 0);             // de-assert enable
    LCD_CTRL(RW, 0);            // set for write

    // here set your LCD data bus port to outputs
}

/***********************************************************
    Write command byte to LCD controller
***********************************************************/

void GrLCDCmd(BYTE arg)
{
    LCDBusy();                  // wait til not busy, if necessary
    LCD_CTRL(RS, 0);            // select command entry
    LCD_DATA = arg;             // put byte on the bus
    LCD_CTRL(E, 1);             // assert enable
    LCD_CTRL(E, 0);             // de-assert enable
}

/***********************************************************
    Write data byte to LCD controller
***********************************************************/

void GrLCDData(BYTE arg)
{
    LCDBusy();                  // wait til not busy, if necessary
    LCD_CTRL(RS, 1);            // select data entry

#ifdef RMW_USED             // if RMW support enabled
    if (CJ_code & USERMW)       // if using RMW mode
    {
        // here set your LCD data bus port to inputs

        LCD_CTRL(RW, 1);        // set for data read

        LCD_CTRL(E, 1);         // assert enable for dummy read
        LCD_CTRL(E, 0);         // de-assert enable

        LCD_CTRL(E, 1);         // assert enable for actual read
        arg |= LCD_DATA;        // read display byte
        LCD_CTRL(E, 0);         // de-assert enable

        // here set your LCD data bus port to outputs

        LCD_CTRL(RW, 0);        // set for write
    }
#endif

    LCD_DATA = arg ^ invertflg; // put byte on the bus
    LCD_CTRL(E, 1);             // assert enable for write
    LCD_CTRL(E, 0);             // de-assert enable
}

/***********************************************************
    Initialize display
***********************************************************/

void GrLCDInit(void)
{
    const BYTE *bp;

    LCD_CTRL(RESET, 1);     // assert hardware reset
    Sleep(1);
    LCD_CTRL(RESET, 0);     // de-assert reset

    bp = GrLCDIni;          // point to init table

    while (*bp != INIT_END) // check for end of list
    {
        if (*bp == CMD_DELAY)
        {
            Sleep(10);
        }
        else
        {
            GrLCDCmd(*bp);  
        }
        bp++;
    }

    GrLCDClear();           // clear data mamory
    Sleep(10);              // let voltage charge pump settle
    GrLCDCmd(DISP_EVS);
    GrLCDCmd(contrast);     // set user contrast value
}

/***********************************************************
    Clear the display data RAM
***********************************************************/

void GrLCDClear(void)
{
    BYTE page, col;

    invertflg = 0;          // don't invert data
    CJ_code = 0;            // rmw disabled

    for (page = 0; page < NR_PAGS; page++)
    {
        GrLCDCmd(DISP_PAG + page);  // set page number
        GrLCDCmd(DISP_COLH);        // set column 0
        GrLCDCmd(DISP_COLL);        // set column 0

        for (col = 0; col < NR_COLS + GR_FIX; col++)
        {
            GrLCDData(0);       // write blanx to display
        }
    }
}

/***********************************************************
    Write blank columns to display. Used to clear an area to
    update with string of different length, or to blink.
    page = starting page
    col = starting column
    len = number of columns
    font = font size (0 = small (1 page), >0 = large (2 page)
***********************************************************/

void GrLCDBlank(BYTE page, BYTE col, BYTE len, BYTE font)
{
    BYTE a;

    invertflg = 0;          // don't invert data
    CJ_code = 0;            // rmw disabled

    GrLCDSetPage(page);
    GrLCDSetCol(col);

    for (a = 0; a < len; a++)
    {
        GrLCDData(0);       // write blanx to display
    }

    if (font)
    {
        GrLCDSetPage(page + 1);
        GrLCDSetCol(col);

        for (a = 0; a < len; a++)
        {
            GrLCDData(0);       // write blanx to display
        }
    }

    column = col + len;     // update current column
}

/***********************************************************
    Write a list of strings to the display, list terminated
    with a null pointer.
    list = pointer to list of String_T pointers
***********************************************************/

void GrLCDList(String_T **list)
{
    while (*list != EOL)
    {
        if (*list == CLEAR) // request to clear display
        {
            GrLCDClear();   // first in list, if used
        }
        else
        {
            GrLCDText(*list);   // display the text       
        }
        list++;
    }
}

/***********************************************************
    Write text string to display.
    Sample: String_T str1 = { 2, C50J+FONT16, 0, "Hello World" };

    strg = pointer to String_T structure
***********************************************************/

void GrLCDText(String_T *strg)
{
    BYTE a, b;
    char *cp;

    pagenr = strg->page;            // save page number
    CJ_code = strg->cj_code;        // save CJ code
    b = CJ_code & JUSTIFY;          // isolate justify code

    if (b == L00J)
    {
        column = 0;
    }
    else if (b == ABSJ)
    {
        column = strg->abs;
    }
    else
    {
        a = GrLCDPixLen(strg->text);// get display length in pixels
        if (b != R100J)             // if not right justify
        {
            a /= 2;                 // use half length for centering
        }
        column = JustTbl[b] - a;    // set starting column
    }

    if (column >= NR_COLS)          // if over/underflow
    {
        column = 0;                 // use left justify
    }
    startcol = column;              // save start column
    cp = strg->text;                // get pointer to the text

    while (*cp)
    {
        if (CJ_code & FONT16)       // large font
        {
            GrLCDLgChar(*cp++);
        }
        else                        // small font
        {
            GrLCDSmChar(*cp++);
        }
    }
}

/***********************************************************
    Write large font character bitmap to display.
***********************************************************/

void GrLCDLgChar(char chr)
{
    BYTE len, a;
    WORD *bits;

    if (chr < firstchr_L) return;   // char code out of range
    a = chr - firstchr_L;
    if (a >= nr_chrs_L) return;     // char code out of range

    len = lentbl_L[a];              // number of columns
    bits = chrtbl_L[a];             // bitmap data pointer

	if (len == 0) return;

    GrLCDSetPage(pagenr);           // set page for first half
    GrLCDSetCol(column);            // set starting column

#ifdef RMW_USED             // if RMW support enabled
    if (CJ_code & USERMW)
    {
        GrLCDCmd(DISP_RMW);         // enter RMW mode if needed
    }
#endif

    for (a = 0; a < len; a++)       // do upper half of char
    {
        GrLCDData(*(bits + a) & 0xFF);  // use lower byte of bitmap word
    }

    if (! (CJ_code & NOSPC))
    {
        GrLCDData(0);               // blank pixel column between chars
    }

#ifdef RMW_USED             // if RMW support enabled
    if (CJ_code & USERMW)
    {
        GrLCDCmd(DISP_END);         // exit RMW mode
    }
#endif

    GrLCDSetPage(pagenr + 1);       // set page for 2nd half
    GrLCDSetCol(column);            // set starting column

#ifdef RMW_USED             // if RMW support enabled
    if (CJ_code & USERMW)
    {
        GrLCDCmd(DISP_RMW);         // enter RMW mode if needed
    }
#endif

    for (a = 0; a < len; a++)       // do lower half of char
    {
        GrLCDData(*(bits + a) >> 8);    // upper byte of bitmap word
    }

    if (! (CJ_code & NOSPC))
    {
        GrLCDData(0);               // blank pixel column between chars
    }

#ifdef RMW_USED             // if RMW support enabled
    if (CJ_code & USERMW)
    {
        GrLCDCmd(DISP_END);         // exit RMW mode
    }
#endif

    column += len;                  // update current column

    if (! (CJ_code & NOSPC))
    {
        column++;                   // include blank between chars
    }
}

/***********************************************************
    Write small font character bitmap to display.
***********************************************************/

void GrLCDSmChar(char chr)
{
    BYTE len, a;
    BYTE *bits;

    if (chr < firstchr_S) return;   // char code out of range
    a = chr - firstchr_S;
    if (a >= nr_chrs_S) return;     // char code out of range

    len = lentbl_S[a];              // number of columns
    bits = chrtbl_S[a];             // bitmap data pointer

	if (len == 0) return;

    GrLCDSetPage(pagenr);           // set page for first half
    GrLCDSetCol(column);            // set starting column

#ifdef RMW_USED             // if RMW support enabled
    if (CJ_code & USERMW)
    {
        GrLCDCmd(DISP_RMW);         // enter RMW mode if needed
    }
#endif

    for (a = 0; a < len; a++)
    {
        GrLCDData(*(bits + a));     // bitmap data
    }

    if (! (CJ_code & NOSPC))
    {
        GrLCDData(0);               // blank pixel column between chars
    }

#ifdef RMW_USED             // if RMW support enabled
    if (CJ_code & USERMW)
    {
        GrLCDCmd(DISP_END);         // exit RMW mode
    }
#endif

    column += len;                  // update current column

    if (! (CJ_code & NOSPC))
    {
        column++;                   // include blank between chars
    }
}

/***********************************************************
    Write page address to controller
***********************************************************/

void GrLCDSetPage(BYTE page)
{
    GrLCDCmd(DISP_PAG + page);
}

/***********************************************************
    Write column address to controller
***********************************************************/

void GrLCDSetCol(BYTE col)
{
    GrLCDCmd(DISP_COLH + ((col + GR_FIX) >> 4));
    GrLCDCmd(DISP_COLL + ((col + GR_FIX) & 0xF));
}

/***********************************************************
    Get length of display text, in pixels
***********************************************************/

BYTE GrLCDPixLen(char *chr)
{
    BYTE len, first, nrc, *lentbl;

    if (CJ_code & FONT16)       // large font
    {
        first = firstchr_L;
        lentbl = lentbl_L;
		nrc = nr_chrs_L;
    }
    else                        // small font
    {
        first = firstchr_S;
        lentbl = lentbl_S;
		nrc = nr_chrs_S;
    }

    len = 0;

    while (*chr)
    {
		if (*chr >= first && ((*chr) - first) < nrc)
		{
			len += *(lentbl + (*chr) - first);

			if (! (CJ_code & NOSPC))
			{
				len++;                  // include blank between chars
			}
		}
        chr++;
    }
    return len;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -