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

📄 lcd.c

📁 真正实现完美应用的以LCD12864为显示终端的四行多级菜单源码(完整版)
💻 C
字号:
/*********************************************************************************************************
*                                            LCD_12864 driver
*                                               QiZhao,2007
*                                           All Rights Reserved
* File      : lcd.c
* By        : QiZhao
* Contact   : zq1987731@163.com
*
* Version   : V2.0 β
* Corrector : QiZhao
* Date      : 2008.2.10 (Last modified)
*
* Remarks   : LCD_initial();
*             DIS_LCD(X,Y,Address,Length);    SELECT_LINE(Line-1~4);  CLEAR_DIS();
*             GRAPH_BMP(*STR);     CLEAR_SCREEN();     CLEAR_HALF_SCREEN(0-L/1-R);
*             LCDLineXY(X1,Y1,X2,Y2,0-Clr/1-Set);    GRAPH_POINT(X,Y,0-Clr/1-Set);
*
*********************************************************************************************************/

    #include "lcd.h"

/*********************************************************************************************************
*
*                                             LCD Initial
*
*********************************************************************************************************/

    extern void LCD_initial (void)
    {
        W_LCD (0x30, 0);
        W_LCD (0x06, 0);
        W_LCD (0x0C, 0);

        W_LCD (0x01, 0);       //Clear DDRAM
        delayms (5);
    }

/*********************************************************************************************************
*
*                                             LCD Port Write
*
*********************************************************************************************************/

    #if PSB
        // Parallel
        static void W_LCD (uchar DATA, bit RS)
        {
                uchar temp;

                LCD_RW = 0;
                if (RS)
                    LCD_RS = 1;        //Data
                else
                    LCD_RS = 0;        //Control
                Data_Port = DATA;

                NOP
                NOP

                LCD_E = 1;
                NOP
                NOP
                LCD_E = 0;

                do                      // wait
                {
                    temp = R_LCD (0);
                    temp &= 0x80;
                }while (~temp);
        }

    #else
        // Series
        static void S_SEND_BYTE(uchar S_DATA)
        {
            uchar i;

            for(i = 8; i != 0; i--)
            {
                LCD_SID=(bit)(S_DATA & 0x80);
                NOP

                LCD_SCLK = 1;
                S_DATA <<= 1;
                LCD_SCLK = 0;
            }
        }

        static void W_LCD (uchar DATA, bit RS)
        {
            uchar temp;
            LCD_SID = 0;
            LCD_SCLK = 0;

            if (RS)
                S_SEND_BYTE (0xFA);
            else
                S_SEND_BYTE (0xF8);

            S_SEND_BYTE (DATA & 0xF0);
            S_SEND_BYTE ((DATA << 4) & 0xF0);

            do                          // wait
            {
                temp = R_LCD (0);
                temp &= 0x80;
            }while (~temp);
        }

    #endif

/*********************************************************************************************************
*
*                                             LCD Port Read
*
*********************************************************************************************************/

    #if PSB
        // Parallel
        static uchar R_LCD (bit RS)
        {
            LCD_RW = 1;
            if (RS)
                LCD_RS = 1;         // RAM
            else
                LCD_RS = 0;         // Busy & AC
            Data_Port = 0xFF;       // Read

            NOP

            LCD_E = 1;
            NOP
            NOP
            LCD_E = 0;

            return Data_Port;
        }

    #else
        // Series
        static uchar S_READ_BYTE(void)
        {
            uchar i, SCAN_BYTE = 0x80, S_BYTE = 0;

            for(i = 8; i != 0; i--)
            {
                LCD_SCLK = 1;

                if(LCD_SID)
                    S_BYTE |= SCAN_BYTE;
                else
                    S_BYTE &= ~SCAN_BYTE;
                SCAN_BYTE >>= 1;

                LCD_SCLK = 0;
            }

            return S_BYTE;
        }

        static uchar R_LCD (bit RS)
        {
            uchar temp;
            LCD_SID = 0;
            LCD_SCLK = 0;

            if (RS)
                S_SEND_BYTE (0xFE);
            else
                S_SEND_BYTE (0xFC);

            LCD_SID = 1;                // Read

            temp = S_READ_BYTE ();
            temp |= (S_READ_BYTE () >> 4);

            return temp;
        }

    #endif

/*********************************************************************************************************
*
*                                            LCD_Display_Char & Word
*
*********************************************************************************************************/

    extern void DIS_LCD (uchar x, uchar y, char *str, uchar z)
    {
        uchar addr;
        char temp;

        W_LCD (0x30, 0);
        switch (x)
        {
            case 1:
                addr = (0x7F + y);
                break;
            case 2:
                addr = (0x8F + y);
                break;
            case 3:
                addr = (0x87 + y);
                break;
            case 4:
                addr = (0x97 + y);
                break;
        }
        W_LCD (addr, 0);

        for ( ; z > 0; z--)
        {
            temp = *str;
            str++;
            W_LCD (temp, 1);
        }

    }

/*********************************************************************************************************
*
*                                             Select A Line
*
*********************************************************************************************************/

    extern void SELECT_LINE (uchar x)
    {
        DIS_LCD (1,1,"  ",2);
        DIS_LCD (2,1,"  ",2);
        DIS_LCD (3,1,"  ",2);
        DIS_LCD (4,1,"  ",2);

        DIS_LCD (x,1,"->",2);
    }

/*********************************************************************************************************
*
*                                               CLEAR_DDRAM
*
*********************************************************************************************************/

    extern void CLEAR_DIS (void)
    {
        W_LCD (0x01, 0);
        delayms (5);
    }

/*********************************************************************************************************
*
*                                             LCD Graph Point
*
*********************************************************************************************************/

    extern void GRAPH_POINT (uchar x, uchar y, bit z)
    {
        uchar xx,yy;
        uint dd;

        W_LCD (0x34, 0);
        W_LCD (0x36, 0);

        xx = x / 16;
        yy = 63 - y;

        if (yy >= 32)
        {
            xx = xx + 8;
            yy -= 32;
        }

        W_LCD (0x80 + yy, 0);
        W_LCD (0x80 + xx, 0);

        dd = (uint)R_LCD (1);
        dd <<= 8;
        dd |= (uint)R_LCD (1);

        if (z)
            dd |=   0x8000 >> (x % 16);
        else
            dd &= ~(0x8000 >> (x % 16));

        W_LCD (0x80 + yy, 0);
        W_LCD (0x80 + xx, 0);

        W_LCD (dd >> 8, 1);
        W_LCD (dd, 1);
    }

/*********************************************************************************************************
*
*                                            LCD Graph BMP
*
*********************************************************************************************************/

    extern void GRAPH_BMP (uchar *str)
    {
        uint x=0;
        uchar i,j;

        W_LCD (0x34, 0);
        W_LCD (0x36, 0);

        for (i=0; i<32; i++)            // Above half
        {
            W_LCD (0x80 | i, 0);        // Abscissa set (y)
            W_LCD (0x80, 0);            // Ordinate set (x)

            for (j = 16; j != 0; j--)
            {
                W_LCD (str[x], 1);
                x++;
            }
        }// for

        for (i=0; i<32; i++)            // Below half
        {
            W_LCD (0x80 | i, 0);
            W_LCD (0x88, 0);

            for (j = 16; j != 0; j--)
            {
                W_LCD (str[x], 1);
                x++;
            }
        }// for
    }

/*********************************************************************************************************
*
*                                             Clear CGRAM
*
*********************************************************************************************************/

    extern void CLEAR_SCREEN (void)
    {
        uchar i,j;
        W_LCD (0x34, 0);
        W_LCD (0x36, 0);

        for (i=0; i<32; i++)
        {
            W_LCD (0x80 | i, 0);
            W_LCD (0x80, 0);

            for (j = 0; j < 32; j++)
            {
                W_LCD (0, 1);
            }
        }// for
    }

/*********************************************************************************************************
*
*                                          Clear HALF CGRAM
*                              LR=0 Clear left-screen, LR=1 Right-screen
*
*********************************************************************************************************/

    extern void CLEAR_HALF_SCREEN (bit LR)
    {
        uchar i,j,x;
        W_LCD (0x34, 0);
        W_LCD (0x36, 0);

        if (LR)         // Choose left or right
            x = 0x84;
        else
            x = 0x80;

        for (i = 0; i < 32; i++)
        {
            W_LCD (0x80 | i, 0);
            W_LCD (x, 0);

            for ( j= 8; j != 0; j--)
            {
                W_LCD (0, 1);
            }
        }

        for (i = 0; i < 32; i++)
        {
            W_LCD (0x80 | i, 0);
            W_LCD (x+8, 0);

            for (j = 8; j != 0; j--)
            {
                W_LCD (0, 1);
            }
        }
    }

/*********************************************************************************************************
*
*                                            LCD Graph Line
*                                 (x,y) to (x1,y1),z=1 Draw ,z=0 Clear
*
*********************************************************************************************************/

    extern void LCD_Line (uchar x, uchar y, uchar x1, uchar y1, bit z)
    {
        uchar i, a, b, c;
        uint  a1, b1;
        char  d = 1, e = 1;
        bit   f = 0;

        if (x1 > x)
        {
            a = (x1 - x);
            d = -1;
        }
        else
            a = (x - x1);

        if (y1 > y)
        {
            b = (y1 - y);
            e = -1;
        }
        else
            b = (y - y1);

        a1 = a;
        b1 = b;

        if (b > a)
        {
            c = b;
            b = a;
            b = c;
            f = 1;
        }

        if (f == 0)    //a>b
        {
            for (i = 0; i <= a; i++)
            {
                x1 = x;
                y1 = y;
                x = x - d * i;
                y = y - (b1 * i / a1) * e;
                GRAPH_POINT(x, y, z);
                x = x1;
                y = y1;
            }// for
        }// if

        if (f == 1)    //a<b
        {
            for (i = 0; i <= b; i++)
            {
                x1 = x;
                y1 = y;
                y = y - e * i;
                x = x - (a1 * i / b1) * d;
                GRAPH_POINT (x, y, z);
                x = x1;
                y = y1;
            }// for
        }// if
    }

⌨️ 快捷键说明

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